Skip to content

Commit ec0b222

Browse files
committed
Added Body.tilePadding to help with small/fast moving bodies vs. tile collision.
1 parent 5297497 commit ec0b222

4 files changed

Lines changed: 59 additions & 133 deletions

File tree

examples/wip/tilemap new 1.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,18 @@ function create() {
2727

2828
map.setCollisionBetween(1, 12);
2929

30-
layer.debug = true;
30+
// layer.debug = true;
3131

3232
sprite = game.add.sprite(260, 70, 'phaser');
3333

3434
game.physics.enable(sprite);
3535

36+
sprite.body.bounce.set(0.8);
37+
sprite.body.tilePadding.set(32);
38+
3639
game.camera.follow(sprite);
3740

38-
// game.physics.arcade.gravity.y = 500;
41+
game.physics.arcade.gravity.y = 200;
3942

4043
cursors = game.input.keyboard.createCursorKeys();
4144

@@ -46,7 +49,7 @@ function update() {
4649
game.physics.arcade.collide(sprite, layer);
4750

4851
sprite.body.velocity.x = 0;
49-
sprite.body.velocity.y = 0;
52+
// sprite.body.velocity.y = 0;
5053

5154
if (cursors.up.isDown)
5255
{
@@ -76,6 +79,6 @@ function render() {
7679
// game.debug.text(sprite.body.deltaX(), 400, 32);
7780
// game.debug.text(sprite.body.deltaY(), 400, 64);
7881

79-
game.debug.body(sprite);
82+
// game.debug.body(sprite);
8083

8184
}

src/Phaser.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ var Phaser = Phaser || {
1818
WEBGL: 2,
1919
HEADLESS: 3,
2020

21+
NONE: 0,
22+
LEFT: 1,
23+
RIGHT: 2,
24+
UP: 3,
25+
DOWN: 4,
26+
2127
SPRITE: 0,
2228
BUTTON: 1,
2329
IMAGE: 2,

src/physics/arcade/Body.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,6 @@ Phaser.Physics.Arcade.Body = function (sprite) {
147147
*/
148148
this.gravity = new Phaser.Point(0, 0);
149149

150-
/**
151-
* @property {Phaser.Point} gravityScale - Gravity scaling factor. This is only applied to world gravity, not local gravity. If you want the body to ignore gravity, set this to zero. If you want to reverse gravity, set it to -1.
152-
*/
153-
this.gravityScale = new Phaser.Point(1, 1);
154-
155150
/**
156151
* @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.
157152
*/
@@ -296,6 +291,13 @@ Phaser.Physics.Arcade.Body = function (sprite) {
296291
*/
297292
this.blocked = { up: false, down: false, left: false, right: false };
298293

294+
/**
295+
* If this is an especially small or fast moving object then it can sometimes skip over tilemap collisions if it moves through a tile in a step.
296+
* Set this padding value to add extra padding to its bounds. tilePadding.x applied to its width, y to its height.
297+
* @property {Phaser.Point} tilePadding - Extra padding to be added to this sprites dimensions when checking for tile collision.
298+
*/
299+
this.tilePadding = new Phaser.Point();
300+
299301
};
300302

301303
Phaser.Physics.Arcade.Body.prototype = {
@@ -403,8 +405,6 @@ Phaser.Physics.Arcade.Body.prototype = {
403405

404406
if (this.deltaX() !== 0 || this.deltaY() !== 0)
405407
{
406-
// this.sprite.position.x = this.position.x;
407-
// this.sprite.position.y = this.position.y;
408408
this.sprite.x += this.deltaX();
409409
this.sprite.y += this.deltaY();
410410
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);

src/physics/arcade/World.js

Lines changed: 39 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -240,35 +240,12 @@ Phaser.Physics.Arcade.prototype = {
240240
*/
241241
updateMotion: function (body) {
242242

243-
this._velocityDelta = this.computeVelocity(body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity;
243+
this._velocityDelta = this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity;
244244
body.angularVelocity += this._velocityDelta;
245245
body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
246246

247-
// Apply gravity using the p2 style gravityScale
248-
if (body.allowGravity)
249-
{
250-
if (body.gravity.x !== 0)
251-
{
252-
body.velocity.x += body.gravity.x * this.game.time.physicsElapsed;
253-
}
254-
else
255-
{
256-
body.velocity.x += this.gravity.x * this.game.time.physicsElapsed * body.gravityScale.x;
257-
}
258-
259-
if (body.gravity.y !== 0)
260-
{
261-
body.velocity.y += body.gravity.y * this.game.time.physicsElapsed;
262-
}
263-
else
264-
{
265-
body.velocity.y += this.gravity.y * this.game.time.physicsElapsed * body.gravityScale.y;
266-
}
267-
}
268-
269-
// Apply velocity
270-
body.velocity.x = this.computeVelocity(body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x);
271-
body.velocity.y = this.computeVelocity(body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y);
247+
body.velocity.x = this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x);
248+
body.velocity.y = this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y);
272249

273250
},
274251

@@ -277,16 +254,27 @@ Phaser.Physics.Arcade.prototype = {
277254
* Based on a function in Flixel by @ADAMATOMIC
278255
*
279256
* @method Phaser.Physics.Arcade#computeVelocity
257+
* @param {number} axis - 0 for nothing, 1 for horizontal, 2 for vertical.
258+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated.
280259
* @param {number} velocity - Any component of velocity (e.g. 20).
281260
* @param {number} acceleration - Rate at which the velocity is changing.
282261
* @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
283262
* @param {number} [max=10000] - An absolute value cap for the velocity.
284263
* @return {number} The altered Velocity value.
285264
*/
286-
computeVelocity: function (velocity, acceleration, drag, max) {
265+
computeVelocity: function (axis, body, velocity, acceleration, drag, max) {
287266

288267
max = max || 10000;
289268

269+
if (axis == 1 && body.allowGravity)
270+
{
271+
velocity += (this.gravity.x + body.gravity.x) * this.game.time.physicsElapsed;
272+
}
273+
else if (axis == 2 && body.allowGravity)
274+
{
275+
velocity += (this.gravity.y + body.gravity.y) * this.game.time.physicsElapsed;
276+
}
277+
290278
if (acceleration)
291279
{
292280
velocity += acceleration * this.game.time.physicsElapsed;
@@ -606,8 +594,12 @@ Phaser.Physics.Arcade.prototype = {
606594
*/
607595
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
608596

609-
// this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, sprite.body.right, sprite.body.bottom);
610-
this._mapData = tilemapLayer.getTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, false, true);
597+
this._mapData = tilemapLayer.getTiles(
598+
sprite.body.position.x - sprite.body.tilePadding.x,
599+
sprite.body.position.y - sprite.body.tilePadding.y,
600+
sprite.body.width + sprite.body.tilePadding.x,
601+
sprite.body.height + sprite.body.tilePadding.y,
602+
false, true);
611603

612604
if (this._mapData.length === 0)
613605
{
@@ -616,9 +608,6 @@ Phaser.Physics.Arcade.prototype = {
616608

617609
for (var i = 0; i < this._mapData.length; i++)
618610
{
619-
// console.log('-------------------------------------- tile', this._mapData[i].faceLeft, this._mapData[i].faceRight, this._mapData[i].faceTop, this._mapData[i].faceBottom);
620-
// console.log('-------------------------------------- tile', i, 'of', this._mapData.length, 'xy', this._mapData[i].x, this._mapData[i].y);
621-
622611
if (this.separateTile(i, sprite.body, this._mapData[i]))
623612
{
624613
// They collided, is there a custom process callback?
@@ -945,86 +934,6 @@ Phaser.Physics.Arcade.prototype = {
945934

946935
},
947936

948-
BUSTEDseparateTile: function (i, body, tile) {
949-
950-
// we re-check for collision in case body was separated in a previous step
951-
if (i > 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
952-
{
953-
// no collision so bail out (separted in a previous step)
954-
console.log('no collision so bail out (separted in a previous step');
955-
return false;
956-
}
957-
958-
console.log('body intersecting tile');
959-
console.log('x', body.position.x, 'y', body.position.y, 'r', body.right, 'b', body.bottom, 'wh', body.width, body.height);
960-
console.log('x', tile.x, 'y', tile.y, 'r', tile.right, 'b', tile.bottom);
961-
962-
if (body.newVelocity.x && (tile.faceLeft || tile.faceRight))
963-
{
964-
var px = 0;
965-
var tx = 0;
966-
967-
if (body.newVelocity.x > 0 && tile.faceLeft)
968-
{
969-
px = body.width;
970-
}
971-
else if (body.newVelocity.x < 0 && tile.faceRight)
972-
{
973-
tx = tile.width;
974-
}
975-
976-
body.position.x = tile.worldX - px + tx;
977-
978-
body.velocity.x = 0; // rebound check
979-
// body.newVelocity.x = 0; // rebound check
980-
}
981-
982-
// Vertical only if still colliding
983-
984-
// if (tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
985-
// if (body.newVelocity.y && tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
986-
if (body.newVelocity.y && (tile.faceTop || tile.faceBottom))
987-
{
988-
var py = 0;
989-
var ty = 0;
990-
991-
if (body.newVelocity.y > 0 && tile.faceBottom)
992-
{
993-
py = body.height;
994-
}
995-
else if (body.newVelocity.y < 0 && tile.faceTop)
996-
{
997-
ty = tile.height;
998-
}
999-
1000-
// console.log('cy', body.newVelocity.y, py, ty);
1001-
1002-
body.position.y = tile.worldY - py + ty;
1003-
1004-
body.velocity.y = 0; // rebound check
1005-
// body.newVelocity.y = 0; // rebound check
1006-
}
1007-
1008-
// var pxOffsetX = (body.newVelocity.x > 0 ? body.width : 0);
1009-
// var tileOffsetX = (body.newVelocity.x < 0 ? tile.width : 0);
1010-
// var pxOffsetY = (body.newVelocity.y > 0 ? body.height : 0);
1011-
// var tileOffsetY = (body.newVelocity.y < 0 ? tile.height : 0);
1012-
1013-
// Assume fully solid for now
1014-
1015-
// body.result.x = true;
1016-
// body.result.tile = tile;
1017-
// body.result.px = tile.x - pxOffsetX + tileOffsetX;
1018-
// body.position.x = tile.x - pxOffsetX + tileOffsetX;
1019-
1020-
// res.pos.y = tileY * this.tilesize - pxOffsetY + tileOffsetY;
1021-
1022-
1023-
1024-
// console.log('nv', body.newVelocity.x, 'tile.xy', tile.x, tile.y, 'p', pxOffsetX, 't', tileOffsetX, 'body xy', body.position.x, body.position.y);
1025-
1026-
},
1027-
1028937
/**
1029938
* The core separation function to separate a physics body and a tile.
1030939
* @method Phaser.Physics.Arcade#separateTile
@@ -1080,16 +989,6 @@ Phaser.Physics.Arcade.prototype = {
1080989
minY = Math.min(Math.abs(body.position.y - tile.bottom), Math.abs(body.bottom - tile.top));
1081990

1082991
// console.log('checking faces', minX, minY);
1083-
1084-
// var distLeft = Math.abs(body.position.x - tile.right);
1085-
// var distRight = Math.abs(body.right - tile.left);
1086-
// var distTop = Math.abs(body.position.y - tile.bottom);
1087-
// var distBottom = Math.abs(body.bottom - tile.top);
1088-
// minX = Math.min(distLeft, distRight);
1089-
// minY = Math.min(distTop, distBottom);
1090-
// console.log('dist left', distLeft, 'right', distRight, 'top', distTop, 'bottom', distBottom, 'minX', minX, 'minY', minY);
1091-
// console.log('tile lr', tile.left, tile.right, 'tb', tile.top, tile.bottom);
1092-
// console.log('body lr', body.x, body.right, 'tb', body.y, body.bottom);
1093992
}
1094993

1095994
if (minX < minY)
@@ -1133,6 +1032,15 @@ Phaser.Physics.Arcade.prototype = {
11331032

11341033
},
11351034

1035+
/**
1036+
* Check the body against the given tile on the X axis.
1037+
*
1038+
* @method Phaser.Physics.Arcade#tileCheckX
1039+
* @protected
1040+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
1041+
* @param {Phaser.Tile} tile - The tile to check.
1042+
* @returns {number} The amount of separation that occured.
1043+
*/
11361044
tileCheckX: function (body, tile) {
11371045

11381046
var ox = 0;
@@ -1173,6 +1081,15 @@ Phaser.Physics.Arcade.prototype = {
11731081

11741082
},
11751083

1084+
/**
1085+
* Check the body against the given tile on the Y axis.
1086+
*
1087+
* @method Phaser.Physics.Arcade#tileCheckY
1088+
* @protected
1089+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
1090+
* @param {Phaser.Tile} tile - The tile to check.
1091+
* @returns {number} The amount of separation that occured.
1092+
*/
11761093
tileCheckY: function (body, tile) {
11771094

11781095
var oy = 0;

0 commit comments

Comments
 (0)