mirror of
https://github.com/photonstorm/phaser
synced 2024-11-23 13:13:43 +00:00
Added Body.tilePadding to help with small/fast moving bodies vs. tile collision.
This commit is contained in:
parent
5297497632
commit
ec0b22268d
4 changed files with 59 additions and 133 deletions
|
@ -27,15 +27,18 @@ function create() {
|
||||||
|
|
||||||
map.setCollisionBetween(1, 12);
|
map.setCollisionBetween(1, 12);
|
||||||
|
|
||||||
layer.debug = true;
|
// layer.debug = true;
|
||||||
|
|
||||||
sprite = game.add.sprite(260, 70, 'phaser');
|
sprite = game.add.sprite(260, 70, 'phaser');
|
||||||
|
|
||||||
game.physics.enable(sprite);
|
game.physics.enable(sprite);
|
||||||
|
|
||||||
|
sprite.body.bounce.set(0.8);
|
||||||
|
sprite.body.tilePadding.set(32);
|
||||||
|
|
||||||
game.camera.follow(sprite);
|
game.camera.follow(sprite);
|
||||||
|
|
||||||
// game.physics.arcade.gravity.y = 500;
|
game.physics.arcade.gravity.y = 200;
|
||||||
|
|
||||||
cursors = game.input.keyboard.createCursorKeys();
|
cursors = game.input.keyboard.createCursorKeys();
|
||||||
|
|
||||||
|
@ -46,7 +49,7 @@ function update() {
|
||||||
game.physics.arcade.collide(sprite, layer);
|
game.physics.arcade.collide(sprite, layer);
|
||||||
|
|
||||||
sprite.body.velocity.x = 0;
|
sprite.body.velocity.x = 0;
|
||||||
sprite.body.velocity.y = 0;
|
// sprite.body.velocity.y = 0;
|
||||||
|
|
||||||
if (cursors.up.isDown)
|
if (cursors.up.isDown)
|
||||||
{
|
{
|
||||||
|
@ -76,6 +79,6 @@ function render() {
|
||||||
// game.debug.text(sprite.body.deltaX(), 400, 32);
|
// game.debug.text(sprite.body.deltaX(), 400, 32);
|
||||||
// game.debug.text(sprite.body.deltaY(), 400, 64);
|
// game.debug.text(sprite.body.deltaY(), 400, 64);
|
||||||
|
|
||||||
game.debug.body(sprite);
|
// game.debug.body(sprite);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,12 @@ var Phaser = Phaser || {
|
||||||
WEBGL: 2,
|
WEBGL: 2,
|
||||||
HEADLESS: 3,
|
HEADLESS: 3,
|
||||||
|
|
||||||
|
NONE: 0,
|
||||||
|
LEFT: 1,
|
||||||
|
RIGHT: 2,
|
||||||
|
UP: 3,
|
||||||
|
DOWN: 4,
|
||||||
|
|
||||||
SPRITE: 0,
|
SPRITE: 0,
|
||||||
BUTTON: 1,
|
BUTTON: 1,
|
||||||
IMAGE: 2,
|
IMAGE: 2,
|
||||||
|
|
|
@ -147,11 +147,6 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||||
*/
|
*/
|
||||||
this.gravity = new Phaser.Point(0, 0);
|
this.gravity = new Phaser.Point(0, 0);
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.
|
|
||||||
*/
|
|
||||||
this.gravityScale = new Phaser.Point(1, 1);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
* @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.
|
||||||
*/
|
*/
|
||||||
|
@ -296,6 +291,13 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||||
*/
|
*/
|
||||||
this.blocked = { up: false, down: false, left: false, right: false };
|
this.blocked = { up: false, down: false, left: false, right: false };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* Set this padding value to add extra padding to its bounds. tilePadding.x applied to its width, y to its height.
|
||||||
|
* @property {Phaser.Point} tilePadding - Extra padding to be added to this sprites dimensions when checking for tile collision.
|
||||||
|
*/
|
||||||
|
this.tilePadding = new Phaser.Point();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Phaser.Physics.Arcade.Body.prototype = {
|
Phaser.Physics.Arcade.Body.prototype = {
|
||||||
|
@ -403,8 +405,6 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||||
|
|
||||||
if (this.deltaX() !== 0 || this.deltaY() !== 0)
|
if (this.deltaX() !== 0 || this.deltaY() !== 0)
|
||||||
{
|
{
|
||||||
// this.sprite.position.x = this.position.x;
|
|
||||||
// this.sprite.position.y = this.position.y;
|
|
||||||
this.sprite.x += this.deltaX();
|
this.sprite.x += this.deltaX();
|
||||||
this.sprite.y += this.deltaY();
|
this.sprite.y += this.deltaY();
|
||||||
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
||||||
|
|
|
@ -240,35 +240,12 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
*/
|
*/
|
||||||
updateMotion: function (body) {
|
updateMotion: function (body) {
|
||||||
|
|
||||||
this._velocityDelta = this.computeVelocity(body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity;
|
this._velocityDelta = this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity;
|
||||||
body.angularVelocity += this._velocityDelta;
|
body.angularVelocity += this._velocityDelta;
|
||||||
body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
|
body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
|
||||||
|
|
||||||
// Apply gravity using the p2 style gravityScale
|
body.velocity.x = this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x);
|
||||||
if (body.allowGravity)
|
body.velocity.y = this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y);
|
||||||
{
|
|
||||||
if (body.gravity.x !== 0)
|
|
||||||
{
|
|
||||||
body.velocity.x += body.gravity.x * this.game.time.physicsElapsed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
body.velocity.x += this.gravity.x * this.game.time.physicsElapsed * body.gravityScale.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body.gravity.y !== 0)
|
|
||||||
{
|
|
||||||
body.velocity.y += body.gravity.y * this.game.time.physicsElapsed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
body.velocity.y += this.gravity.y * this.game.time.physicsElapsed * body.gravityScale.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply velocity
|
|
||||||
body.velocity.x = this.computeVelocity(body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x);
|
|
||||||
body.velocity.y = this.computeVelocity(body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -277,16 +254,27 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
* Based on a function in Flixel by @ADAMATOMIC
|
* Based on a function in Flixel by @ADAMATOMIC
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Arcade#computeVelocity
|
* @method Phaser.Physics.Arcade#computeVelocity
|
||||||
|
* @param {number} axis - 0 for nothing, 1 for horizontal, 2 for vertical.
|
||||||
|
* @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated.
|
||||||
* @param {number} velocity - Any component of velocity (e.g. 20).
|
* @param {number} velocity - Any component of velocity (e.g. 20).
|
||||||
* @param {number} acceleration - Rate at which the velocity is changing.
|
* @param {number} acceleration - Rate at which the velocity is changing.
|
||||||
* @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
|
* @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
|
||||||
* @param {number} [max=10000] - An absolute value cap for the velocity.
|
* @param {number} [max=10000] - An absolute value cap for the velocity.
|
||||||
* @return {number} The altered Velocity value.
|
* @return {number} The altered Velocity value.
|
||||||
*/
|
*/
|
||||||
computeVelocity: function (velocity, acceleration, drag, max) {
|
computeVelocity: function (axis, body, velocity, acceleration, drag, max) {
|
||||||
|
|
||||||
max = max || 10000;
|
max = max || 10000;
|
||||||
|
|
||||||
|
if (axis == 1 && body.allowGravity)
|
||||||
|
{
|
||||||
|
velocity += (this.gravity.x + body.gravity.x) * this.game.time.physicsElapsed;
|
||||||
|
}
|
||||||
|
else if (axis == 2 && body.allowGravity)
|
||||||
|
{
|
||||||
|
velocity += (this.gravity.y + body.gravity.y) * this.game.time.physicsElapsed;
|
||||||
|
}
|
||||||
|
|
||||||
if (acceleration)
|
if (acceleration)
|
||||||
{
|
{
|
||||||
velocity += acceleration * this.game.time.physicsElapsed;
|
velocity += acceleration * this.game.time.physicsElapsed;
|
||||||
|
@ -606,8 +594,12 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
*/
|
*/
|
||||||
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
|
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
|
||||||
|
|
||||||
// this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, sprite.body.right, sprite.body.bottom);
|
this._mapData = tilemapLayer.getTiles(
|
||||||
this._mapData = tilemapLayer.getTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, false, true);
|
sprite.body.position.x - sprite.body.tilePadding.x,
|
||||||
|
sprite.body.position.y - sprite.body.tilePadding.y,
|
||||||
|
sprite.body.width + sprite.body.tilePadding.x,
|
||||||
|
sprite.body.height + sprite.body.tilePadding.y,
|
||||||
|
false, true);
|
||||||
|
|
||||||
if (this._mapData.length === 0)
|
if (this._mapData.length === 0)
|
||||||
{
|
{
|
||||||
|
@ -616,9 +608,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
|
|
||||||
for (var i = 0; i < this._mapData.length; i++)
|
for (var i = 0; i < this._mapData.length; i++)
|
||||||
{
|
{
|
||||||
// console.log('-------------------------------------- tile', this._mapData[i].faceLeft, this._mapData[i].faceRight, this._mapData[i].faceTop, this._mapData[i].faceBottom);
|
|
||||||
// console.log('-------------------------------------- tile', i, 'of', this._mapData.length, 'xy', this._mapData[i].x, this._mapData[i].y);
|
|
||||||
|
|
||||||
if (this.separateTile(i, sprite.body, this._mapData[i]))
|
if (this.separateTile(i, sprite.body, this._mapData[i]))
|
||||||
{
|
{
|
||||||
// They collided, is there a custom process callback?
|
// They collided, is there a custom process callback?
|
||||||
|
@ -945,86 +934,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
BUSTEDseparateTile: function (i, body, tile) {
|
|
||||||
|
|
||||||
// we re-check for collision in case body was separated in a previous step
|
|
||||||
if (i > 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
|
||||||
{
|
|
||||||
// no collision so bail out (separted in a previous step)
|
|
||||||
console.log('no collision so bail out (separted in a previous step');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('body intersecting tile');
|
|
||||||
console.log('x', body.position.x, 'y', body.position.y, 'r', body.right, 'b', body.bottom, 'wh', body.width, body.height);
|
|
||||||
console.log('x', tile.x, 'y', tile.y, 'r', tile.right, 'b', tile.bottom);
|
|
||||||
|
|
||||||
if (body.newVelocity.x && (tile.faceLeft || tile.faceRight))
|
|
||||||
{
|
|
||||||
var px = 0;
|
|
||||||
var tx = 0;
|
|
||||||
|
|
||||||
if (body.newVelocity.x > 0 && tile.faceLeft)
|
|
||||||
{
|
|
||||||
px = body.width;
|
|
||||||
}
|
|
||||||
else if (body.newVelocity.x < 0 && tile.faceRight)
|
|
||||||
{
|
|
||||||
tx = tile.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.position.x = tile.worldX - px + tx;
|
|
||||||
|
|
||||||
body.velocity.x = 0; // rebound check
|
|
||||||
// body.newVelocity.x = 0; // rebound check
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vertical only if still colliding
|
|
||||||
|
|
||||||
// if (tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
|
||||||
// if (body.newVelocity.y && tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
|
||||||
if (body.newVelocity.y && (tile.faceTop || tile.faceBottom))
|
|
||||||
{
|
|
||||||
var py = 0;
|
|
||||||
var ty = 0;
|
|
||||||
|
|
||||||
if (body.newVelocity.y > 0 && tile.faceBottom)
|
|
||||||
{
|
|
||||||
py = body.height;
|
|
||||||
}
|
|
||||||
else if (body.newVelocity.y < 0 && tile.faceTop)
|
|
||||||
{
|
|
||||||
ty = tile.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('cy', body.newVelocity.y, py, ty);
|
|
||||||
|
|
||||||
body.position.y = tile.worldY - py + ty;
|
|
||||||
|
|
||||||
body.velocity.y = 0; // rebound check
|
|
||||||
// body.newVelocity.y = 0; // rebound check
|
|
||||||
}
|
|
||||||
|
|
||||||
// var pxOffsetX = (body.newVelocity.x > 0 ? body.width : 0);
|
|
||||||
// var tileOffsetX = (body.newVelocity.x < 0 ? tile.width : 0);
|
|
||||||
// var pxOffsetY = (body.newVelocity.y > 0 ? body.height : 0);
|
|
||||||
// var tileOffsetY = (body.newVelocity.y < 0 ? tile.height : 0);
|
|
||||||
|
|
||||||
// Assume fully solid for now
|
|
||||||
|
|
||||||
// body.result.x = true;
|
|
||||||
// body.result.tile = tile;
|
|
||||||
// body.result.px = tile.x - pxOffsetX + tileOffsetX;
|
|
||||||
// body.position.x = tile.x - pxOffsetX + tileOffsetX;
|
|
||||||
|
|
||||||
// res.pos.y = tileY * this.tilesize - pxOffsetY + tileOffsetY;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// console.log('nv', body.newVelocity.x, 'tile.xy', tile.x, tile.y, 'p', pxOffsetX, 't', tileOffsetX, 'body xy', body.position.x, body.position.y);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core separation function to separate a physics body and a tile.
|
* The core separation function to separate a physics body and a tile.
|
||||||
* @method Phaser.Physics.Arcade#separateTile
|
* @method Phaser.Physics.Arcade#separateTile
|
||||||
|
@ -1080,16 +989,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
minY = Math.min(Math.abs(body.position.y - tile.bottom), Math.abs(body.bottom - tile.top));
|
minY = Math.min(Math.abs(body.position.y - tile.bottom), Math.abs(body.bottom - tile.top));
|
||||||
|
|
||||||
// console.log('checking faces', minX, minY);
|
// console.log('checking faces', minX, minY);
|
||||||
|
|
||||||
// var distLeft = Math.abs(body.position.x - tile.right);
|
|
||||||
// var distRight = Math.abs(body.right - tile.left);
|
|
||||||
// var distTop = Math.abs(body.position.y - tile.bottom);
|
|
||||||
// var distBottom = Math.abs(body.bottom - tile.top);
|
|
||||||
// minX = Math.min(distLeft, distRight);
|
|
||||||
// minY = Math.min(distTop, distBottom);
|
|
||||||
// console.log('dist left', distLeft, 'right', distRight, 'top', distTop, 'bottom', distBottom, 'minX', minX, 'minY', minY);
|
|
||||||
// console.log('tile lr', tile.left, tile.right, 'tb', tile.top, tile.bottom);
|
|
||||||
// console.log('body lr', body.x, body.right, 'tb', body.y, body.bottom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minX < minY)
|
if (minX < minY)
|
||||||
|
@ -1133,6 +1032,15 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the body against the given tile on the X axis.
|
||||||
|
*
|
||||||
|
* @method Phaser.Physics.Arcade#tileCheckX
|
||||||
|
* @protected
|
||||||
|
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
|
||||||
|
* @param {Phaser.Tile} tile - The tile to check.
|
||||||
|
* @returns {number} The amount of separation that occured.
|
||||||
|
*/
|
||||||
tileCheckX: function (body, tile) {
|
tileCheckX: function (body, tile) {
|
||||||
|
|
||||||
var ox = 0;
|
var ox = 0;
|
||||||
|
@ -1173,6 +1081,15 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the body against the given tile on the Y axis.
|
||||||
|
*
|
||||||
|
* @method Phaser.Physics.Arcade#tileCheckY
|
||||||
|
* @protected
|
||||||
|
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
|
||||||
|
* @param {Phaser.Tile} tile - The tile to check.
|
||||||
|
* @returns {number} The amount of separation that occured.
|
||||||
|
*/
|
||||||
tileCheckY: function (body, tile) {
|
tileCheckY: function (body, tile) {
|
||||||
|
|
||||||
var oy = 0;
|
var oy = 0;
|
||||||
|
|
Loading…
Reference in a new issue