Skip to content

Commit a8f3c3b

Browse files
committed
New BodyBounds class for getting body bounds based coordinates
1 parent fceef3d commit a8f3c3b

1 file changed

Lines changed: 381 additions & 0 deletions

File tree

Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2019 Photon Storm Ltd.
4+
* @license {@link https://opensource.org/licenses/MIT|MIT License}
5+
*/
6+
7+
var Class = require('../../utils/Class');
8+
var Vec2 = require('../../math/Vector2');
9+
10+
/**
11+
* @classdesc
12+
*
13+
* The Body Bounds class contains methods to help you extract the world coordinates from various points around
14+
* the bounds of a Matter Body. Because Matter bodies are positioned based on their center of mass, and not a
15+
* dimension based center, you often need to get the bounds coordinates in order to properly align them in the world.
16+
*
17+
* You can access this class via the MatterPhysics class from a Scene, i.e.:
18+
*
19+
* ```javascript
20+
* this.matter.bodyBounds.getTopLeft(body);
21+
* ```
22+
*
23+
* See also the `MatterPhysics.alignBody` method.
24+
*
25+
* @class BodyBounds
26+
* @memberof Phaser.Physics.Matter
27+
* @constructor
28+
* @since 3.22.0
29+
*/
30+
var BodyBounds = new Class({
31+
32+
initialize:
33+
34+
function BodyBounds ()
35+
{
36+
this.boundsCenter = new Vec2();
37+
this.centerDiff = new Vec2();
38+
},
39+
40+
/**
41+
* Returns the length of the given constraint, which is the distance between the two points.
42+
*
43+
* @method Phaser.Physics.Matter.BodyBounds#parseBody
44+
* @since 3.22.0
45+
*
46+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the bounds position from.
47+
*
48+
* @return {boolean} `true` if it was able to get the bounds, otherwise `false`.
49+
*/
50+
parseBody: function (body)
51+
{
52+
body = (body.hasOwnProperty('body')) ? body.body : body;
53+
54+
if (!body.hasOwnProperty('bounds') || !body.hasOwnProperty('centerOfMass'))
55+
{
56+
return false;
57+
}
58+
59+
var boundsCenter = this.boundsCenter;
60+
var centerDiff = this.centerDiff;
61+
62+
var boundsWidth = body.bounds.max.x - body.bounds.min.x;
63+
var boundsHeight = body.bounds.max.y - body.bounds.min.y;
64+
65+
var bodyCenterX = boundsWidth * body.centerOfMass.x;
66+
var bodyCenterY = boundsHeight * body.centerOfMass.y;
67+
68+
boundsCenter.set(boundsWidth / 2, boundsHeight / 2);
69+
centerDiff.set(bodyCenterX - boundsCenter.x, bodyCenterY - boundsCenter.y);
70+
71+
return true;
72+
},
73+
74+
/**
75+
* Takes a Body and returns the world coordinates of the top-left of its _bounds_.
76+
*
77+
* Body bounds are updated by Matter each step and factor in scale and rotation.
78+
* This will return the world coordinate based on the bodies _current_ position and bounds.
79+
*
80+
* @method Phaser.Physics.Matter.BodyBounds#getTopLeft
81+
* @since 3.22.0
82+
*
83+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
84+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
85+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
86+
*
87+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
88+
*/
89+
getTopLeft: function (body, x, y)
90+
{
91+
if (x === undefined) { x = 0; }
92+
if (y === undefined) { y = 0; }
93+
94+
if (this.parseBody(body))
95+
{
96+
var center = this.boundsCenter;
97+
var diff = this.centerDiff;
98+
99+
return new Vec2(
100+
x + center.x + diff.x,
101+
y + center.y + diff.y
102+
);
103+
}
104+
105+
return false;
106+
},
107+
108+
/**
109+
* Takes a Body and returns the world coordinates of the top-center of its _bounds_.
110+
*
111+
* Body bounds are updated by Matter each step and factor in scale and rotation.
112+
* This will return the world coordinate based on the bodies _current_ position and bounds.
113+
*
114+
* @method Phaser.Physics.Matter.BodyBounds#getTopCenter
115+
* @since 3.22.0
116+
*
117+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
118+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
119+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
120+
*
121+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
122+
*/
123+
getTopCenter: function (body, x, y)
124+
{
125+
if (x === undefined) { x = 0; }
126+
if (y === undefined) { y = 0; }
127+
128+
if (this.parseBody(body))
129+
{
130+
var center = this.boundsCenter;
131+
var diff = this.centerDiff;
132+
133+
return new Vec2(
134+
x + diff.x,
135+
y + center.y + diff.y
136+
);
137+
}
138+
139+
return false;
140+
},
141+
142+
/**
143+
* Takes a Body and returns the world coordinates of the top-right of its _bounds_.
144+
*
145+
* Body bounds are updated by Matter each step and factor in scale and rotation.
146+
* This will return the world coordinate based on the bodies _current_ position and bounds.
147+
*
148+
* @method Phaser.Physics.Matter.BodyBounds#getTopRight
149+
* @since 3.22.0
150+
*
151+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
152+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
153+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
154+
*
155+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
156+
*/
157+
getTopRight: function (body, x, y)
158+
{
159+
if (x === undefined) { x = 0; }
160+
if (y === undefined) { y = 0; }
161+
162+
if (this.parseBody(body))
163+
{
164+
var center = this.boundsCenter;
165+
var diff = this.centerDiff;
166+
167+
return new Vec2(
168+
x - (center.x - diff.x),
169+
y + center.y + diff.y
170+
);
171+
}
172+
173+
return false;
174+
},
175+
176+
/**
177+
* Takes a Body and returns the world coordinates of the left-center of its _bounds_.
178+
*
179+
* Body bounds are updated by Matter each step and factor in scale and rotation.
180+
* This will return the world coordinate based on the bodies _current_ position and bounds.
181+
*
182+
* @method Phaser.Physics.Matter.BodyBounds#getLeftCenter
183+
* @since 3.22.0
184+
*
185+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
186+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
187+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
188+
*
189+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
190+
*/
191+
getLeftCenter: function (body, x, y)
192+
{
193+
if (x === undefined) { x = 0; }
194+
if (y === undefined) { y = 0; }
195+
196+
if (this.parseBody(body))
197+
{
198+
var center = this.boundsCenter;
199+
var diff = this.centerDiff;
200+
201+
return new Vec2(
202+
x + center.x + diff.x,
203+
y + diff.y
204+
);
205+
}
206+
207+
return false;
208+
},
209+
210+
/**
211+
* Takes a Body and returns the world coordinates of the center of its _bounds_.
212+
*
213+
* Body bounds are updated by Matter each step and factor in scale and rotation.
214+
* This will return the world coordinate based on the bodies _current_ position and bounds.
215+
*
216+
* @method Phaser.Physics.Matter.BodyBounds#getCenter
217+
* @since 3.22.0
218+
*
219+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
220+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
221+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
222+
*
223+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
224+
*/
225+
getCenter: function (body, x, y)
226+
{
227+
if (x === undefined) { x = 0; }
228+
if (y === undefined) { y = 0; }
229+
230+
if (this.parseBody(body))
231+
{
232+
var diff = this.centerDiff;
233+
234+
return new Vec2(
235+
x + diff.x,
236+
y + diff.y
237+
);
238+
}
239+
240+
return false;
241+
},
242+
243+
/**
244+
* Takes a Body and returns the world coordinates of the right-center of its _bounds_.
245+
*
246+
* Body bounds are updated by Matter each step and factor in scale and rotation.
247+
* This will return the world coordinate based on the bodies _current_ position and bounds.
248+
*
249+
* @method Phaser.Physics.Matter.BodyBounds#getRightCenter
250+
* @since 3.22.0
251+
*
252+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
253+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
254+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
255+
*
256+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
257+
*/
258+
getRightCenter: function (body, x, y)
259+
{
260+
if (x === undefined) { x = 0; }
261+
if (y === undefined) { y = 0; }
262+
263+
if (this.parseBody(body))
264+
{
265+
var center = this.boundsCenter;
266+
var diff = this.centerDiff;
267+
268+
return new Vec2(
269+
x - (center.x - diff.x),
270+
y + diff.y
271+
);
272+
}
273+
274+
return false;
275+
},
276+
277+
/**
278+
* Takes a Body and returns the world coordinates of the bottom-left of its _bounds_.
279+
*
280+
* Body bounds are updated by Matter each step and factor in scale and rotation.
281+
* This will return the world coordinate based on the bodies _current_ position and bounds.
282+
*
283+
* @method Phaser.Physics.Matter.BodyBounds#getBottomLeft
284+
* @since 3.22.0
285+
*
286+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
287+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
288+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
289+
*
290+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
291+
*/
292+
getBottomLeft: function (body, x, y)
293+
{
294+
if (x === undefined) { x = 0; }
295+
if (y === undefined) { y = 0; }
296+
297+
if (this.parseBody(body))
298+
{
299+
var center = this.boundsCenter;
300+
var diff = this.centerDiff;
301+
302+
return new Vec2(
303+
x + center.x + diff.x,
304+
y - (center.y - diff.y)
305+
);
306+
}
307+
308+
return false;
309+
},
310+
311+
/**
312+
* Takes a Body and returns the world coordinates of the bottom-center of its _bounds_.
313+
*
314+
* Body bounds are updated by Matter each step and factor in scale and rotation.
315+
* This will return the world coordinate based on the bodies _current_ position and bounds.
316+
*
317+
* @method Phaser.Physics.Matter.BodyBounds#getBottomCenter
318+
* @since 3.22.0
319+
*
320+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
321+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
322+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
323+
*
324+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
325+
*/
326+
getBottomCenter: function (body, x, y)
327+
{
328+
if (x === undefined) { x = 0; }
329+
if (y === undefined) { y = 0; }
330+
331+
if (this.parseBody(body))
332+
{
333+
var center = this.boundsCenter;
334+
var diff = this.centerDiff;
335+
336+
return new Vec2(
337+
x + diff.x,
338+
y - (center.y - diff.y)
339+
);
340+
}
341+
342+
return false;
343+
},
344+
345+
/**
346+
* Takes a Body and returns the world coordinates of the bottom-right of its _bounds_.
347+
*
348+
* Body bounds are updated by Matter each step and factor in scale and rotation.
349+
* This will return the world coordinate based on the bodies _current_ position and bounds.
350+
*
351+
* @method Phaser.Physics.Matter.BodyBounds#getBottomRight
352+
* @since 3.22.0
353+
*
354+
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
355+
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
356+
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
357+
*
358+
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
359+
*/
360+
getBottomRight: function (body, x, y)
361+
{
362+
if (x === undefined) { x = 0; }
363+
if (y === undefined) { y = 0; }
364+
365+
if (this.parseBody(body))
366+
{
367+
var center = this.boundsCenter;
368+
var diff = this.centerDiff;
369+
370+
return new Vec2(
371+
x - (center.x - diff.x),
372+
y - (center.y - diff.y)
373+
);
374+
}
375+
376+
return false;
377+
}
378+
379+
});
380+
381+
module.exports = BodyBounds;

0 commit comments

Comments
 (0)