Skip to content

Commit 2a353a0

Browse files
committed
Flixel physics optimised about as much as it can be. Also added world and local gravity support and flag to toggle it on / off.
1 parent 0f438d5 commit 2a353a0

3 files changed

Lines changed: 145 additions & 110 deletions

File tree

examples/body3.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,38 @@ function preload() {
2626
function create() {
2727

2828
game.world._stage.backgroundColorString = '#182d3b';
29+
// game.physics.gravity.y = 10;
2930

30-
bunny = game.add.sprite(200, 200, 'bunny');
31-
bunny.body.bounce.x = 0.8;
31+
bunny = game.add.sprite(200, 100, 'bunny');
32+
bunny.body.bounce.y = 0.5;
33+
// bunny.body.gravity.y = -10;
34+
// bunny.body.setSize(20, 100);
35+
// bunny.body.offset.setTo(25, -20);
36+
// bunny.anchor.setTo(0.5, 0.5);
3237

33-
wall = game.add.sprite(700, 200, 'bunny');
38+
wall = game.add.sprite(200, 450, 'bunny');
3439
wall.body.immovable = true;
40+
wall.body.allowGravity = false;
3541

36-
bunny.body.velocity.x = 180;
42+
// bunny.body.angularVelocity = 1;
43+
bunny.body.velocity.x = 30;
44+
// bunny.body.velocity.y = 120;
45+
// bunny.body.velocity.y = 50;
3746

3847
}
3948

4049
function update() {
4150

42-
game.physics.separateX(bunny.body, wall.body);
51+
// bunny.rotation += 0.01;
52+
game.physics.separate(bunny.body, wall.body);
4353

4454
}
4555

4656
function render() {
4757

4858
game.debug.renderSpriteCorners(bunny, true, true);
49-
game.debug.renderRectangle(bunny.body.hitArea);
59+
game.debug.renderRectangle(bunny.body.bounds);
60+
game.debug.renderRectangle(wall.body.bounds);
5061

5162
}
5263

src/physics/arcade/ArcadePhysics.js

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Phaser.Physics.Arcade = function (game) {
44

55
this.game = game;
66

7-
this._length = 0;
7+
this.gravity = new Phaser.Point;
8+
this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
89

910
/**
1011
* @type {number}
@@ -20,11 +21,11 @@ Phaser.Physics.Arcade = function (game) {
2021
this.FLOOR = this.DOWN;
2122
this.WALL = this.LEFT | this.RIGHT;
2223
this.ANY = this.LEFT | this.RIGHT | this.UP | this.DOWN;
23-
// console.log('any', this.ANY);
24+
2425
this.OVERLAP_BIAS = 4;
2526
this.TILE_OVERLAP = false;
2627

27-
// avoid creating these every frame, per collision
28+
// avoid gc spikes by caching these values for re-use
2829
this._obj1Bounds = new Phaser.Rectangle;
2930
this._obj2Bounds = new Phaser.Rectangle;
3031
this._overlap = 0;
@@ -35,14 +36,6 @@ Phaser.Physics.Arcade = function (game) {
3536
this._obj2NewVelocity = 0;
3637
this._average = 0;
3738

38-
// this.angularDrag = 0;
39-
// this.gravity = new Phaser.Point;
40-
// this.drag = new Phaser.Point;
41-
// this.bounce = new Phaser.Point;
42-
// this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
43-
// this._distance = new Phaser.Point;
44-
// this._tangent = new Phaser.Point;
45-
4639
};
4740

4841
Phaser.Physics.Arcade.prototype = {
@@ -55,21 +48,21 @@ Phaser.Physics.Arcade.prototype = {
5548

5649
updateMotion: function (body) {
5750

58-
this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
59-
body.angularVelocity += this._velocityDelta;
60-
body.sprite.rotation += body.angularVelocity * this.game.time.physicsElapsed;
51+
// Rotation
52+
this._velocityDelta = (this.computeVelocity(0, false, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
6153
body.angularVelocity += this._velocityDelta;
54+
body.rotation += body.angularVelocity * this.game.time.physicsElapsed;
6255

63-
this._velocityDelta = (this.computeVelocity(body.velocity.x, body.gravity.x, body.acceleration.x, body.drag.x) - body.velocity.x) / 2;
64-
body.velocity.x += this._velocityDelta;
65-
this._delta = body.velocity.x * this.game.time.physicsElapsed;
56+
// Horizontal
57+
this._velocityDelta = (this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x) - body.velocity.x) / 2;
6658
body.velocity.x += this._velocityDelta;
59+
this._delta = body.velocity.x * this.game.time.physicsElapsed;
6760
body.x += this._delta;
6861

69-
this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2;
62+
// Vertical
63+
this._velocityDelta = (this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2;
7064
body.velocity.y += this._velocityDelta;
7165
this._delta = body.velocity.y * this.game.time.physicsElapsed;
72-
body.velocity.y += this._velocityDelta;
7366
body.y += this._delta;
7467

7568
},
@@ -84,16 +77,22 @@ Phaser.Physics.Arcade.prototype = {
8477
*
8578
* @return {number} The altered Velocity value.
8679
*/
87-
computeVelocity: function (velocity, gravity, acceleration, drag, max) {
80+
computeVelocity: function (axis, body, velocity, acceleration, drag, max) {
8881

89-
gravity = gravity || 0;
90-
acceleration = acceleration || 0;
91-
drag = drag || 0;
9282
max = max || 10000;
9383

84+
if (axis == 1 && body.allowGravity)
85+
{
86+
velocity += this.gravity.x + body.gravity.x;
87+
}
88+
else if (axis == 2 && body.allowGravity)
89+
{
90+
velocity += this.gravity.y + body.gravity.y;
91+
}
92+
9493
if (acceleration !== 0)
9594
{
96-
velocity += (acceleration + gravity) * this.game.time.physicsElapsed;
95+
velocity += acceleration * this.game.time.physicsElapsed;
9796
}
9897
else if (drag !== 0)
9998
{
@@ -111,11 +110,9 @@ Phaser.Physics.Arcade.prototype = {
111110
{
112111
velocity = 0;
113112
}
114-
115-
velocity += gravity;
116113
}
117114

118-
if ((velocity != 0) && (max != 10000))
115+
if (velocity != 0)
119116
{
120117
if (velocity > max)
121118
{
@@ -176,10 +173,7 @@ Phaser.Physics.Arcade.prototype = {
176173
*/
177174
separate: function (object1, object2) {
178175

179-
var separatedX = this.separateX(object1, object2);
180-
var separatedY = this.separateY(object1, object2);
181-
182-
return separatedX || separatedY;
176+
return this.separateX(object1, object2) || this.separateY(object1, object2)
183177

184178
},
185179

@@ -207,7 +201,7 @@ Phaser.Physics.Arcade.prototype = {
207201
this._obj1Bounds.setTo(object1.x - ((object1.deltaX() > 0) ? object1.deltaX() : 0), object1.lastY, object1.width + ((object1.deltaX() > 0) ? object1.deltaX() : -object1.deltaX()), object1.height);
208202
this._obj2Bounds.setTo(object2.x - ((object2.deltaX() > 0) ? object2.deltaX() : 0), object2.lastY, object2.width + ((object2.deltaX() > 0) ? object2.deltaX() : -object2.deltaX()), object2.height);
209203

210-
if ((this._obj1Bounds.x + this._obj1Bounds.width > this._obj2Bounds.x) && (this._obj1Bounds.x < this._obj2Bounds.x + this._obj2Bounds.width) && (this._obj1Bounds.y + this._obj1Bounds.height > this._obj2Bounds.y) && (this._obj1Bounds.y < this._obj2Bounds.y + this._obj2Bounds.height))
204+
if ((this._obj1Bounds.right > this._obj2Bounds.x) && (this._obj1Bounds.x < this._obj2Bounds.right) && (this._obj1Bounds.bottom > this._obj2Bounds.y) && (this._obj1Bounds.y < this._obj2Bounds.bottom))
211205
{
212206
this._maxOverlap = object1.deltaAbsX() + object2.deltaAbsX() + this.OVERLAP_BIAS;
213207

@@ -239,9 +233,7 @@ Phaser.Physics.Arcade.prototype = {
239233
object1.touching |= this.LEFT;
240234
object2.touching |= this.RIGHT;
241235
}
242-
243236
}
244-
245237
}
246238
}
247239

@@ -275,7 +267,6 @@ Phaser.Physics.Arcade.prototype = {
275267
object2.x += this._overlap;
276268
object2.velocity.x = this._obj1Velocity - this._obj2Velocity * object2.bounce.x;
277269
}
278-
279270
return true;
280271
}
281272
else
@@ -294,100 +285,96 @@ Phaser.Physics.Arcade.prototype = {
294285
separateY: function (object1, object2) {
295286

296287
// Can't separate two immovable objects
297-
if (object1.immovable && object2.immovable) {
288+
if (object1.immovable && object2.immovable)
289+
{
298290
return false;
299291
}
300292

301293
// First, get the two object deltas
302-
var overlap = 0;
303-
var obj1Delta = object1.y - object1.last.y;
304-
var obj2Delta = object2.y - object2.last.y;
294+
this._overlap = 0;
305295

306-
if (obj1Delta != obj2Delta)
296+
if (object1.deltaY() != object2.deltaY())
307297
{
308298
// Check if the Y hulls actually overlap
309-
var obj1DeltaAbs = (obj1Delta > 0) ? obj1Delta : -obj1Delta;
310-
var obj2DeltaAbs = (obj2Delta > 0) ? obj2Delta : -obj2Delta;
311-
this._obj1Bounds = new Phaser.Rectangle(object1.x, object1.y - ((obj1Delta > 0) ? obj1Delta : 0), object1.width, object1.height + obj1DeltaAbs);
312-
this._obj2Bounds = new Phaser.Rectangle(object2.x, object2.y - ((obj2Delta > 0) ? obj2Delta : 0), object2.width, object2.height + obj2DeltaAbs);
299+
this._obj1Bounds.setTo(object1.x, object1.y - ((object1.deltaY() > 0) ? object1.deltaY() : 0), object1.width, object1.height + object1.deltaAbsY());
300+
this._obj2Bounds.setTo(object2.x, object2.y - ((object2.deltaY() > 0) ? object2.deltaY() : 0), object2.width, object2.height + object2.deltaAbsY());
313301

314-
if ((this._obj1Bounds.x + this._obj1Bounds.width > this._obj2Bounds.x) && (this._obj1Bounds.x < this._obj2Bounds.x + this._obj2Bounds.width) && (this._obj1Bounds.y + this._obj1Bounds.height > this._obj2Bounds.y) && (this._obj1Bounds.y < this._obj2Bounds.y + this._obj2Bounds.height))
302+
if ((this._obj1Bounds.right > this._obj2Bounds.x) && (this._obj1Bounds.x < this._obj2Bounds.right) && (this._obj1Bounds.bottom > this._obj2Bounds.y) && (this._obj1Bounds.y < this._obj2Bounds.bottom))
315303
{
316-
var maxOverlap = obj1DeltaAbs + obj2DeltaAbs + Collision.OVERLAP_BIAS;
304+
this._maxOverlap = object1.deltaAbsY() + object2.deltaAbsY() + this.OVERLAP_BIAS;
317305

318306
// If they did overlap (and can), figure out by how much and flip the corresponding flags
319-
if (obj1Delta > obj2Delta)
307+
if (object1.deltaY() > object2.deltaY())
320308
{
321-
overlap = object1.y + object1.height - object2.y;
309+
this._overlap = object1.y + object1.height - object2.y;
322310

323-
if ((overlap > maxOverlap) || !(object1.allowCollisions & Collision.DOWN) || !(object2.allowCollisions & Collision.UP))
311+
if ((this._overlap > this._maxOverlap) || !(object1.allowCollisions & this.DOWN) || !(object2.allowCollisions & this.UP))
324312
{
325-
overlap = 0;
313+
this._overlap = 0;
326314
}
327315
else
328316
{
329-
object1.touching |= Collision.DOWN;
330-
object2.touching |= Collision.UP;
317+
object1.touching |= this.DOWN;
318+
object2.touching |= this.UP;
331319
}
332320
}
333-
else if (obj1Delta < obj2Delta)
321+
else if (object1.deltaY() < object2.deltaY())
334322
{
335-
overlap = object1.y - object2.height - object2.y;
323+
this._overlap = object1.y - object2.height - object2.y;
336324

337-
if ((-overlap > maxOverlap) || !(object1.allowCollisions & Collision.UP) || !(object2.allowCollisions & Collision.DOWN))
325+
if ((-this._overlap > this._maxOverlap) || !(object1.allowCollisions & this.UP) || !(object2.allowCollisions & this.DOWN))
338326
{
339-
overlap = 0;
327+
this._overlap = 0;
340328
}
341329
else
342330
{
343-
object1.touching |= Collision.UP;
344-
object2.touching |= Collision.DOWN;
331+
object1.touching |= this.UP;
332+
object2.touching |= this.DOWN;
345333
}
346334
}
347335
}
348336
}
349337

350338
// Then adjust their positions and velocities accordingly (if there was any overlap)
351-
if (overlap != 0)
339+
if (this._overlap != 0)
352340
{
353341
this._obj1Velocity = object1.velocity.y;
354342
this._obj2Velocity = object2.velocity.y;
355343

356344
if (!object1.immovable && !object2.immovable)
357345
{
358-
overlap *= 0.5;
359-
object1.y = object1.y - overlap;
360-
object2.y += overlap;
346+
this._overlap *= 0.5;
347+
object1.y = object1.y - this._overlap;
348+
object2.y += this._overlap;
361349

362350
this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * object2.mass) / object1.mass) * ((this._obj2Velocity > 0) ? 1 : -1);
363351
this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * object1.mass) / object2.mass) * ((this._obj1Velocity > 0) ? 1 : -1);
364352
this._average = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5;
365353
this._obj1NewVelocity -= this._average;
366354
this._obj2NewVelocity -= this._average;
367-
object1.velocity.y = this._average + this._obj1NewVelocity * object1.elasticity;
368-
object2.velocity.y = this._average + this._obj2NewVelocity * object2.elasticity;
355+
object1.velocity.y = this._average + this._obj1NewVelocity * object1.bounce.y;
356+
object2.velocity.y = this._average + this._obj2NewVelocity * object2.bounce.y;
369357
}
370358
else if (!object1.immovable)
371359
{
372-
object1.y = object1.y - overlap;
373-
object1.velocity.y = this._obj2Velocity - this._obj1Velocity * object1.elasticity;
360+
object1.y = object1.y - this._overlap;
361+
object1.velocity.y = this._obj2Velocity - this._obj1Velocity * object1.bounce.y;
374362
// This is special case code that handles things like horizontal moving platforms you can ride
375-
if (object2.active && object2.moves && (obj1Delta > obj2Delta))
363+
if (object2.active && object2.moves && (object1.deltaY() > object2.deltaY()))
376364
{
377-
object1.x += object2.x - object2.last.x;
365+
object1.x += object2.x - object2.lastX;
378366
}
379367
}
380368
else if (!object2.immovable)
381369
{
382-
object2.y += overlap;
383-
object2.velocity.y = this._obj1Velocity - this._obj2Velocity * object2.elasticity;
370+
object2.y += this._overlap;
371+
object2.velocity.y = this._obj1Velocity - this._obj2Velocity * object2.bounce.y;
384372
// This is special case code that handles things like horizontal moving platforms you can ride
385-
if (object1.active && object1.moves && (obj1Delta < obj2Delta))
373+
if (object1.sprite.active && object1.moves && (object1.deltaY() < object2.deltaY()))
386374
{
387-
object2.x += object1.x - object1.last.x;
375+
object2.x += object1.x - object1.lastX;
388376
}
389377
}
390-
391378
return true;
392379
}
393380
else

0 commit comments

Comments
 (0)