Skip to content

Commit c2533d1

Browse files
committed
Finally a fully working bounding box that respects scale and rotation - the "in camera" check is now 100% accurate :)
1 parent c5f6817 commit c2533d1

8 files changed

Lines changed: 446 additions & 634 deletions

File tree

Phaser/components/Transform.ts

Lines changed: 117 additions & 93 deletions
Large diffs are not rendered by default.

Phaser/renderers/CanvasRenderer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ module Phaser {
221221
return true;
222222
}
223223

224-
return RectangleUtils.intersects(sprite.cameraView, camera.screenView);
224+
return true;
225+
//return RectangleUtils.intersects(sprite.cameraView, camera.screenView);
225226

226227
}
227228

Phaser/utils/SpriteUtils.ts

Lines changed: 17 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ module Phaser {
4040
// If the sprite is rotated around its center we can use this quicker method:
4141
if (sprite.transform.origin.x == 0.5 && sprite.transform.origin.y == 0.5)
4242
{
43-
SpriteUtils._sin = Math.sin((sprite.rotation + sprite.transform.rotationOffset) * GameMath.DEG_TO_RAD);
44-
SpriteUtils._cos = Math.cos((sprite.rotation + sprite.transform.rotationOffset) * GameMath.DEG_TO_RAD);
43+
SpriteUtils._sin = sprite.transform.sin;
44+
SpriteUtils._cos = sprite.transform.cos;
4545

4646
if (SpriteUtils._sin < 0)
4747
{
@@ -60,8 +60,23 @@ module Phaser {
6060
}
6161
else
6262
{
63+
//var left:Number = Math.min(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x);
64+
//var top:Number = Math.min(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y);
65+
//var right:Number = Math.max(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x);
66+
//var bottom:Number = Math.max(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y);
67+
//return new Rectangle(left, top, right - left, bottom - top);
6368

69+
var minX: number = Math.min(sprite.transform.upperLeft.x, sprite.transform.upperRight.x, sprite.transform.bottomLeft.x, sprite.transform.bottomRight.x);
70+
var minY: number = Math.min(sprite.transform.upperLeft.y, sprite.transform.upperRight.y, sprite.transform.bottomLeft.y, sprite.transform.bottomRight.y);
71+
var maxX: number = Math.max(sprite.transform.upperLeft.x, sprite.transform.upperRight.x, sprite.transform.bottomLeft.x, sprite.transform.bottomRight.x);
72+
var maxY: number = Math.max(sprite.transform.upperLeft.y, sprite.transform.upperRight.y, sprite.transform.bottomLeft.y, sprite.transform.bottomRight.y);
6473

74+
// (min_x,min_y), (min_x,max_y), (max_x,max_y), (max_x,min_y)
75+
76+
sprite.cameraView.x = minX;
77+
sprite.cameraView.y = minY;
78+
sprite.cameraView.width = maxX - minX;
79+
sprite.cameraView.height = maxY - minY;
6580

6681
/*
6782
// Useful to get the maximum AABB size of any given rect
@@ -87,90 +102,6 @@ module Phaser {
87102

88103
}
89104

90-
static getCornersAsPoints(sprite: Sprite): Phaser.Point[] {
91-
92-
var out: Phaser.Point[] = [];
93-
94-
var sin = Math.sin((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
95-
var cos = Math.cos((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
96-
97-
// Upper Left
98-
out.push(new Point(sprite.x + (sprite.width / 2) * cos - (sprite.height / 2) * sin, sprite.y + (sprite.height / 2) * cos + (sprite.width / 2) * sin));
99-
100-
// Upper Right
101-
out.push(new Point(sprite.x - (sprite.width / 2) * cos - (sprite.height / 2) * sin, sprite.y + (sprite.height / 2) * cos - (sprite.width / 2) * sin));
102-
103-
// Bottom Left
104-
out.push(new Point(sprite.x + (sprite.width / 2) * cos + (sprite.height / 2) * sin, sprite.y - (sprite.height / 2) * cos + (sprite.width / 2) * sin));
105-
106-
// Bottom Right
107-
out.push(new Point(sprite.x - (sprite.width / 2) * cos + (sprite.height / 2) * sin, sprite.y - (sprite.height / 2) * cos - (sprite.width / 2) * sin));
108-
109-
return out;
110-
111-
}
112-
113-
static getCornersAsPoints2(sprite: Sprite): Phaser.Point[] {
114-
115-
var out: Phaser.Point[] = [];
116-
117-
var sin = Math.sin((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
118-
var cos = Math.cos((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
119-
120-
// This = the center point
121-
var cx = sprite.x + (sprite.width / 2) * cos - (sprite.height / 2) * sin;
122-
var cy = sprite.y + (sprite.height / 2) * cos + (sprite.width / 2) * sin;
123-
124-
// Upper Left
125-
out.push(new Point(cx + (sprite.width / 2) * cos - (sprite.height / 2) * sin, cy + (sprite.height / 2) * cos + (sprite.width / 2) * sin));
126-
127-
// Upper Right
128-
out.push(new Point(cx - (sprite.width / 2) * cos - (sprite.height / 2) * sin, cy + (sprite.height / 2) * cos - (sprite.width / 2) * sin));
129-
130-
// Bottom Left
131-
out.push(new Point(cx + (sprite.width / 2) * cos + (sprite.height / 2) * sin, cy - (sprite.height / 2) * cos + (sprite.width / 2) * sin));
132-
133-
// Bottom Right
134-
out.push(new Point(cx - (sprite.width / 2) * cos + (sprite.height / 2) * sin, cy - (sprite.height / 2) * cos - (sprite.width / 2) * sin));
135-
136-
return out;
137-
138-
}
139-
140-
static getCornersAsPoints3(sprite: Sprite): Phaser.Point[] {
141-
142-
var out: Phaser.Point[] = [];
143-
144-
var sin: number = sprite.transform.sin;
145-
var cos: number = sprite.transform.cos;
146-
147-
//var sin = Math.sin((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
148-
//var cos = Math.cos((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
149-
150-
// This = the center point
151-
//var cx = sprite.x + sprite.transform.distance * Math.cos((sprite.transform.rotation * Math.PI / 180) + sprite.transform.angleToCenter);
152-
//var cy = sprite.y + sprite.transform.distance * Math.sin((sprite.transform.rotation * Math.PI / 180) + sprite.transform.angleToCenter);
153-
154-
var cx: number = sprite.transform.centerX;
155-
var cy: number = sprite.transform.centerY;
156-
157-
// Upper Left
158-
out.push(new Point(cx + sprite.transform.halfWidth * cos - sprite.transform.halfHeight * sin, cy + sprite.transform.halfHeight * cos + sprite.transform.halfWidth * sin));
159-
160-
// Upper Right
161-
out.push(new Point(cx - sprite.transform.halfWidth * cos - sprite.transform.halfHeight * sin, cy + sprite.transform.halfHeight * cos - sprite.transform.halfWidth * sin));
162-
163-
// Bottom Left
164-
out.push(new Point(cx + sprite.transform.halfWidth * cos + sprite.transform.halfHeight * sin, cy - sprite.transform.halfHeight * cos + sprite.transform.halfWidth * sin));
165-
166-
// Bottom Right
167-
out.push(new Point(cx - sprite.transform.halfWidth * cos + sprite.transform.halfHeight * sin, cy - sprite.transform.halfHeight * cos - sprite.transform.halfWidth * sin));
168-
169-
return out;
170-
171-
}
172-
173-
174105
static getAsPoints(sprite: Sprite): Phaser.Point[] {
175106

176107
var out: Phaser.Point[] = [];

Tests/misc/point1.js

Lines changed: 27 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,21 @@
33
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
44
function init() {
55
game.load.image('box2', 'assets/tests/320x200.png');
6-
game.load.image('box1', 'assets/sprites/oz_pov_melting_disk.png');
7-
game.load.image('box', 'assets/sprites/bunny.png');
6+
game.load.image('box', 'assets/sprites/oz_pov_melting_disk.png');
7+
game.load.image('box1', 'assets/sprites/bunny.png');
88
game.load.start();
99
}
1010
var sprite;
1111
var rotate = false;
1212
function create() {
1313
game.stage.backgroundColor = 'rgb(0,0,0)';
14-
game.stage.disablePauseScreen = true;
1514
sprite = game.add.sprite(game.stage.centerX, game.stage.centerY, 'box');
1615
//sprite.transform.scale.setTo(0.5, 0.5);
17-
sprite.transform.origin.setTo(0.3, 0.3);
16+
sprite.transform.origin.setTo(0, 0);
17+
//sprite.transform.origin.setTo(0.5, 0.5);
1818
game.input.onTap.add(rotateIt, this);
19-
game.add.tween(sprite.transform.scale).to({
20-
x: 0.5,
21-
y: 0.5
22-
}, 2000, Phaser.Easing.Linear.None, true, 0, true);
23-
points = [
24-
new Phaser.Point(),
25-
new Phaser.Point(),
26-
new Phaser.Point(),
27-
new Phaser.Point()
28-
];
29-
}
19+
//game.add.tween(sprite.transform.scale).to({ x: 0.5, y: 0.5 }, 2000, Phaser.Easing.Linear.None, true, 0, true);
20+
}
3021
function rotateIt() {
3122
if(rotate == false) {
3223
rotate = true;
@@ -39,59 +30,29 @@
3930
sprite.rotation++;
4031
}
4132
}
42-
var points;
4333
function render() {
44-
/*
45-
points = Phaser.SpriteUtils.getCornersAsPoints3(sprite);
46-
47-
game.stage.context.fillStyle = 'rgb(255,255,0)';
48-
game.stage.context.fillRect(points[0].x, points[0].y, 2, 2);
49-
game.stage.context.fillRect(points[1].x, points[1].y, 2, 2);
50-
game.stage.context.fillRect(points[2].x, points[2].y, 2, 2);
51-
game.stage.context.fillRect(points[3].x, points[3].y, 2, 2);
52-
*/
53-
var originX = sprite.transform.origin.x * sprite.width;
54-
var originY = sprite.transform.origin.y * sprite.height;
55-
var centerX = 0.5 * sprite.width;
56-
var centerY = 0.5 * sprite.height;
57-
var distance = Math.sqrt(((originX - centerX) * (originX - centerX)) + ((originY - centerY) * (originY - centerY)));
58-
var originAngle = Math.atan2(centerY - originY, centerX - originX);
59-
var sin = Math.sin((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
60-
var cos = Math.cos((sprite.transform.rotation + sprite.transform.rotationOffset) * Phaser.GameMath.DEG_TO_RAD);
61-
//var px = sprite.x + distance * Math.cos((sprite.transform.rotation * Math.PI / 180) + originAngle);
62-
//var py = sprite.y + distance * Math.sin((sprite.transform.rotation * Math.PI / 180) + originAngle);
63-
// WORKS
64-
//var px = sprite.x + sprite.transform.distance * Math.cos((sprite.transform.rotation * Math.PI / 180) + sprite.transform.angleToCenter);
65-
//var py = sprite.y + sprite.transform.distance * Math.sin((sprite.transform.rotation * Math.PI / 180) + sprite.transform.angleToCenter);
66-
// Upper Left
67-
//points[0].setTo(px + (sprite.width / 2) * cos - (sprite.height / 2) * sin, py + (sprite.height / 2) * cos + (sprite.width / 2) * sin);
68-
// Upper Right
69-
//points[1].setTo(px - (sprite.width / 2) * cos - (sprite.height / 2) * sin, py + (sprite.height / 2) * cos - (sprite.width / 2) * sin);
70-
// Bottom Left
71-
//points[2].setTo(px + (sprite.width / 2) * cos + (sprite.height / 2) * sin, py - (sprite.height / 2) * cos + (sprite.width / 2) * sin);
72-
// Bottom Right
73-
//points[3].setTo(px - (sprite.width / 2) * cos + (sprite.height / 2) * sin, py - (sprite.height / 2) * cos - (sprite.width / 2) * sin);
74-
points = Phaser.SpriteUtils.getCornersAsPoints3(sprite);
75-
game.stage.context.save();
76-
game.stage.context.fillStyle = 'rgb(0,255,255)';
77-
//game.stage.context.fillRect(px, py, 2, 2);
78-
game.stage.context.fillText('rect width: ' + originX + ' height: ' + originY, 32, 32);
79-
game.stage.context.fillText('center x: ' + centerX + ' centerY: ' + centerY, 32, 52);
80-
game.stage.context.fillText('angle: ' + sprite.rotation, 32, 72);
81-
game.stage.context.fillText('point of rotation x: ' + sprite.transform.origin.x + ' y: ' + sprite.transform.origin.y, 32, 92);
82-
game.stage.context.fillText('x: ' + sprite.x + ' y: ' + sprite.y, sprite.x + 4, sprite.y);
83-
game.stage.context.fillRect(points[0].x, points[0].y, 2, 2);
84-
game.stage.context.fillRect(points[1].x, points[1].y, 2, 2);
85-
game.stage.context.fillRect(points[2].x, points[2].y, 2, 2);
86-
game.stage.context.fillRect(points[3].x, points[3].y, 2, 2);
87-
game.stage.context.restore();
8834
game.stage.context.save();
89-
game.stage.context.fillStyle = 'rgba(255,255,255,0.1)';
90-
game.stage.context.beginPath();
91-
game.stage.context.moveTo(sprite.x, sprite.y);
92-
game.stage.context.arc(sprite.x, sprite.y, distance, 0, Math.PI * 2);
93-
game.stage.context.closePath();
94-
game.stage.context.fill();
35+
game.stage.context.fillStyle = 'rgb(255,0,255)';
36+
game.stage.context.fillText('x: ' + Math.round(sprite.transform.upperLeft.x) + ' y: ' + Math.round(sprite.transform.upperLeft.y), sprite.transform.upperLeft.x, sprite.transform.upperLeft.y);
37+
game.stage.context.fillText('x: ' + Math.round(sprite.transform.upperRight.x) + ' y: ' + Math.round(sprite.transform.upperRight.y), sprite.transform.upperRight.x, sprite.transform.upperRight.y);
38+
game.stage.context.fillText('x: ' + Math.round(sprite.transform.bottomLeft.x) + ' y: ' + Math.round(sprite.transform.bottomLeft.y), sprite.transform.bottomLeft.x, sprite.transform.bottomLeft.y);
39+
game.stage.context.fillText('x: ' + Math.round(sprite.transform.bottomRight.x) + ' y: ' + Math.round(sprite.transform.bottomRight.y), sprite.transform.bottomRight.x, sprite.transform.bottomRight.y);
40+
var minX = Math.min(sprite.transform.upperLeft.x, sprite.transform.upperRight.x, sprite.transform.bottomLeft.x, sprite.transform.bottomRight.x);
41+
var minY = Math.min(sprite.transform.upperLeft.y, sprite.transform.upperRight.y, sprite.transform.bottomLeft.y, sprite.transform.bottomRight.y);
42+
var maxX = Math.max(sprite.transform.upperLeft.x, sprite.transform.upperRight.x, sprite.transform.bottomLeft.x, sprite.transform.bottomRight.x);
43+
var maxY = Math.max(sprite.transform.upperLeft.y, sprite.transform.upperRight.y, sprite.transform.bottomLeft.y, sprite.transform.bottomRight.y);
44+
var width = maxX - minX;
45+
var height = maxY - minY;
46+
game.stage.context.fillText('minX: ' + minX + ' minY: ' + minY, 32, 32);
47+
game.stage.context.fillText('maxX: ' + maxX + ' maxY: ' + maxY, 32, 64);
48+
game.stage.context.fillRect(sprite.transform.center.x, sprite.transform.center.y, 2, 2);
49+
game.stage.context.fillRect(sprite.transform.upperLeft.x, sprite.transform.upperLeft.y, 2, 2);
50+
game.stage.context.fillRect(sprite.transform.upperRight.x, sprite.transform.upperRight.y, 2, 2);
51+
game.stage.context.fillRect(sprite.transform.bottomLeft.x, sprite.transform.bottomLeft.y, 2, 2);
52+
game.stage.context.fillRect(sprite.transform.bottomRight.x, sprite.transform.bottomRight.y, 2, 2);
53+
game.stage.context.strokeStyle = 'rgb(255,255,0)';
54+
game.stage.context.strokeRect(sprite.cameraView.x, sprite.cameraView.y, sprite.cameraView.width, sprite.cameraView.height);
55+
//game.stage.context.strokeRect(minX, minY, width, height);
9556
game.stage.context.restore();
9657
}
9758
})();

0 commit comments

Comments
 (0)