mirror of
https://github.com/photonstorm/phaser
synced 2024-11-11 07:34:43 +00:00
More robust gravity handling avoiding 'sticky walls'. Added new platform test with mixture of mass tile collision and physics.
This commit is contained in:
parent
31b68ac94f
commit
110ab4e253
5 changed files with 143 additions and 143 deletions
File diff suppressed because one or more lines are too long
11
examples/assets/tilemaps/tmx/platform test.tmx
Normal file
11
examples/assets/tilemaps/tmx/platform test.tmx
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.0" orientation="orthogonal" width="50" height="40" tilewidth="16" tileheight="16">
|
||||
<tileset firstgid="1" name="platformer_tiles" tilewidth="16" tileheight="16">
|
||||
<image source="../tiles/platformer_tiles.png" width="304" height="96"/>
|
||||
</tileset>
|
||||
<layer name="Tile Layer 1" width="50" height="40">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJztlcsOgjAQRavu1Y2PGI2IK6PG+Nr5Daj//zOOsYkExz5mphSUm5wgpZ3eW1tQ6rfUKuDaz4VYonitSg5p702OTz+SOShjXHxIr0VoH5T6lDxl7CvueaGuq+lZjBw+NbB+Ejm4/jGfvv3LPAMUHyH8uuaQWoeYGWxeqKpaDmqWKuXgZOGuQQhxzwh3LqwO5z+j5MhfKd6xOV37Su1TbG5bFps4+5Uq33V0rRlDEu+afC3KfBLZy/wGUM5DiMw9i0cX+Z4z6RwJsNDX/O9lrq0OStXbb4rcJ1Fc/Y58zlyMb4KrKDmqBJalrHWwjfWpa/IUS3tgB2yBA3DU93tVrz0+AQaaE3AGRsDMs05f2JdJXWS+KTBWL+/P61C9Ms0ttdrAqsAaafvWXmxbG8aHYAN0gAy41JxMc2Vyszy/C8xhImtoaPgLHpcgdus=
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
|
@ -6,12 +6,15 @@ function preload() {
|
|||
game.load.tilemap('map', 'assets/tilemaps/maps/platform.json', null, Phaser.Tilemap.TILED_JSON);
|
||||
game.load.image('platformer_tiles', 'assets/tilemaps/tiles/platformer_tiles.png');
|
||||
game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60);
|
||||
game.load.spritesheet('balls', 'assets/sprites/balls.png', 17, 17);
|
||||
|
||||
}
|
||||
|
||||
var map;
|
||||
var layer;
|
||||
var sprite;
|
||||
var sprite2;
|
||||
var balls;
|
||||
|
||||
function create() {
|
||||
|
||||
|
@ -21,20 +24,38 @@ function create() {
|
|||
|
||||
map.addTilesetImage('platformer_tiles');
|
||||
|
||||
map.setCollisionBetween(32, 35);
|
||||
map.setCollisionByIndex(21);
|
||||
map.setCollisionBetween(21, 53);
|
||||
|
||||
layer = map.createLayer('Tile Layer 1');
|
||||
|
||||
// layer.debug = true;
|
||||
|
||||
game.physics.gravity.y = 200;
|
||||
game.physics.gravity.y = 150;
|
||||
|
||||
balls = game.add.group();
|
||||
|
||||
for (var i = 0; i < 50; i++)
|
||||
{
|
||||
var s = balls.create(game.rnd.integerInRange(100, 700), game.rnd.integerInRange(100, 200), 'balls', game.rnd.integerInRange(0, 5));
|
||||
s.body.velocity.x = game.rnd.integerInRange(-400, 400);
|
||||
s.body.velocity.y = game.rnd.integerInRange(-100, -200);
|
||||
s.name = 'ball' + i;
|
||||
}
|
||||
|
||||
balls.setAll('body.collideWorldBounds', true);
|
||||
balls.setAll('body.bounce.x', 0.8);
|
||||
balls.setAll('body.bounce.y', 0.9);
|
||||
|
||||
sprite = game.add.sprite(300, 100, 'gameboy', 0);
|
||||
sprite.name = 'red';
|
||||
sprite.body.collideWorldBounds = true;
|
||||
sprite.body.bounce.setTo(0.5, 0.5);
|
||||
|
||||
sprite2 = game.add.sprite(300, 250, 'gameboy', 2);
|
||||
sprite2.name = 'yellow';
|
||||
sprite2.body.collideWorldBounds = true;
|
||||
// sprite2.body.bounce.setTo(0.5, 0.5);
|
||||
|
||||
game.input.onDown.add(launch, this);
|
||||
|
||||
}
|
||||
|
@ -52,9 +73,28 @@ function hit(face, body1, body2) {
|
|||
|
||||
}
|
||||
|
||||
var flag = false;
|
||||
|
||||
function update() {
|
||||
|
||||
game.physics.collide(balls, layer);
|
||||
game.physics.collide(sprite, layer);
|
||||
game.physics.collide(sprite2, layer);
|
||||
game.physics.collide(sprite, sprite2);
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
for (var i = 0; i < balls._container.children.length; i++)
|
||||
{
|
||||
if (balls._container.children[i].y < 5 && balls._container.children[i].body.velocity.y === 0)
|
||||
{
|
||||
balls._container.children[i].alpha = 0.5;
|
||||
console.log(balls._container.children[i]);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -49,62 +49,6 @@ Phaser.Physics.Arcade = function (game) {
|
|||
*/
|
||||
this.maxLevels = 4;
|
||||
|
||||
// Avoid gc spikes by caching these values for re-use
|
||||
|
||||
/**
|
||||
* @property {Phaser.Rectangle} _bounds1 - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._bounds1 = new Phaser.Rectangle();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Rectangle} _bounds2 - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._bounds2 = new Phaser.Rectangle();
|
||||
|
||||
/**
|
||||
* @property {number} _overlap - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._overlap = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _maxOverlap - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._maxOverlap = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _velocity1 - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._velocity1 = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _velocity2 - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._velocity2 = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _newVelocity1 - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._newVelocity1 = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _newVelocity2 - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._newVelocity2 = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _average - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
// this._average = 0;
|
||||
|
||||
/**
|
||||
* @property {Array} _mapData - Internal cache var.
|
||||
* @private
|
||||
|
@ -918,12 +862,7 @@ Phaser.Physics.Arcade.prototype = {
|
|||
else
|
||||
{
|
||||
body.velocity.x = -body.velocity.x * body.bounce.x;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(body.velocity.x) < body.minVelocity.x)
|
||||
{
|
||||
body.velocity.x = 0;
|
||||
}
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -939,12 +878,7 @@ Phaser.Physics.Arcade.prototype = {
|
|||
else
|
||||
{
|
||||
body.velocity.y = -body.velocity.y * body.bounce.y;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(body.velocity.y) < body.minVelocity.y)
|
||||
{
|
||||
body.velocity.y = 0;
|
||||
}
|
||||
body.reboundCheck(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -390,6 +390,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
this.blocked.left = false;
|
||||
this.blocked.right = false;
|
||||
|
||||
this.touching.none = true;
|
||||
this.touching.up = false;
|
||||
this.touching.down = false;
|
||||
this.touching.left = false;
|
||||
|
@ -414,18 +415,6 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
this.applyMotion();
|
||||
}
|
||||
|
||||
// if (this.deltaX() != 0)
|
||||
// {
|
||||
// this.touching.left = false;
|
||||
// this.touching.right = false;
|
||||
// }
|
||||
|
||||
// if (this.deltaY() != 0)
|
||||
// {
|
||||
// this.touching.up = false;
|
||||
// this.touching.down = false;
|
||||
// }
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -442,22 +431,26 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
{
|
||||
this.blockedPoint.x = this.game.world.bounds.x - this.x;
|
||||
this.blocked.left = true;
|
||||
this.touching.left = true;
|
||||
}
|
||||
else if (this.right > this.game.world.bounds.right)
|
||||
{
|
||||
this.blockedPoint.x = this.right - this.game.world.bounds.right;
|
||||
this.blocked.right = true;
|
||||
this.touching.right = true;
|
||||
}
|
||||
|
||||
if (this.y < this.game.world.bounds.y)
|
||||
{
|
||||
this.blockedPoint.y = this.game.world.bounds.y - this.y;
|
||||
this.blocked.up = true;
|
||||
this.touching.up = true;
|
||||
}
|
||||
else if (this.bottom > this.game.world.bounds.bottom)
|
||||
{
|
||||
this.blockedPoint.y = this.bottom - this.game.world.bounds.bottom;
|
||||
this.blocked.down = true;
|
||||
this.touching.down = true;
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -491,19 +484,19 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// Separate
|
||||
this.x += this.blockedPoint.x;
|
||||
this.velocity.x *= -this.bounce.x;
|
||||
this.reboundCheck(true, false);
|
||||
|
||||
this._dx = this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2);
|
||||
|
||||
if (this._dx > this.minBounceVelocity)
|
||||
if (this._dx > this.minBounceVelocity || this.getTotalGravityX() > 0)
|
||||
{
|
||||
this.x += this._dx;
|
||||
this.velocity.x += this.motionVelocity.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.preX = this.x; // because we don't want any delta from a separation
|
||||
this.preX = this.x;
|
||||
this.velocity.x = 0;
|
||||
this.motionVelocity.x = 0;
|
||||
}
|
||||
}
|
||||
else if (this.blocked.right && this.blockedPoint.x > 0)
|
||||
|
@ -511,19 +504,19 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// Separate
|
||||
this.x -= this.blockedPoint.x;
|
||||
this.velocity.x *= -this.bounce.x;
|
||||
this.reboundCheck(true, false);
|
||||
|
||||
this._dx = this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2);
|
||||
|
||||
if (this._dx < -this.minBounceVelocity)
|
||||
if (this._dx < -this.minBounceVelocity || this.getTotalGravityX() < 0)
|
||||
{
|
||||
this.x += this._dx;
|
||||
this.velocity.x += this.motionVelocity.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.preX = this.x; // because we don't want any delta from a separation
|
||||
this.preX = this.x;
|
||||
this.velocity.x = 0;
|
||||
this.motionVelocity.x = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -538,19 +531,19 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// Separate
|
||||
this.y += this.blockedPoint.y;
|
||||
this.velocity.y *= -this.bounce.y;
|
||||
this.reboundCheck(false, true);
|
||||
|
||||
this._dy = this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2);
|
||||
|
||||
if (this._dy > this.minBounceVelocity)
|
||||
if (this._dy > this.minBounceVelocity || this.getTotalGravityY() > 0)
|
||||
{
|
||||
this.y += this._dy;
|
||||
this.velocity.y += this.motionVelocity.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.preY = this.y; // because we don't want any delta from a separation
|
||||
this.preY = this.y;
|
||||
this.velocity.y = 0;
|
||||
this.motionVelocity.y = 0;
|
||||
}
|
||||
}
|
||||
else if (this.blocked.down && this.blockedPoint.y > 0)
|
||||
|
@ -558,19 +551,19 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// Separate
|
||||
this.y -= this.blockedPoint.y;
|
||||
this.velocity.y *= -this.bounce.y;
|
||||
this.reboundCheck(false, true);
|
||||
|
||||
this._dy = this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2);
|
||||
|
||||
if (this._dy < -this.minBounceVelocity)
|
||||
if (this._dy < -this.minBounceVelocity || this.getTotalGravityY() < 0)
|
||||
{
|
||||
this.y += this._dy;
|
||||
this.velocity.y += this.motionVelocity.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.preY = this.y; // because we don't want any delta from a separation
|
||||
this.preY = this.y;
|
||||
this.velocity.y = 0;
|
||||
this.motionVelocity.y = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -663,6 +656,57 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
|
||||
},
|
||||
|
||||
// Check if we're below minVelocity and gravity isn't trying to drag us in the opposite direction
|
||||
reboundCheck: function (x, y) {
|
||||
|
||||
if (x)
|
||||
{
|
||||
var gx = this.getTotalGravityX();
|
||||
|
||||
if (Math.abs(this.velocity.x) < this.minVelocity.x && (this.blocked.left && gx < 0 || this.blocked.right && gx > 0))
|
||||
{
|
||||
this.velocity.x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (y)
|
||||
{
|
||||
var gy = this.getTotalGravityY();
|
||||
|
||||
if (Math.abs(this.velocity.y) < this.minVelocity.y && (this.blocked.up && gy < 0 || this.blocked.down && gy > 0))
|
||||
{
|
||||
this.velocity.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getTotalGravityX: function () {
|
||||
|
||||
if (this.allowGravity)
|
||||
{
|
||||
return this.gravity.x + this.game.physics.gravity.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.gravity.x;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getTotalGravityY: function () {
|
||||
|
||||
if (this.allowGravity)
|
||||
{
|
||||
return this.gravity.y + this.game.physics.gravity.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.gravity.y;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Process a collision with the left face of this Body. If possible the Body will be moved right.
|
||||
* Uses overlayX which will be positive.
|
||||
|
@ -682,6 +726,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
{
|
||||
body.x -= x;
|
||||
body.velocity.x = this.velocity.x - body.velocity.x * body.bounce.x;
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -690,12 +735,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// We take the full separation as what hit is isn't moveable
|
||||
this.x += x;
|
||||
this.velocity.x = body.velocity.x - this.velocity.x * this.bounce.x;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
||||
{
|
||||
this.velocity.x = 0;
|
||||
}
|
||||
this.reboundCheck(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -706,11 +746,8 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
this.velocity.x = avg + nv1 * this.bounce.x;
|
||||
body.velocity.x = avg + nv2 * body.bounce.x;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
||||
{
|
||||
this.velocity.x = 0;
|
||||
}
|
||||
this.reboundCheck(true, false);
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -747,6 +784,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
{
|
||||
body.x -= x;
|
||||
body.velocity.x = this.velocity.x - body.velocity.x * body.bounce.x;
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -755,12 +793,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// We take the full separation as what hit is isn't moveable
|
||||
this.x += x;
|
||||
this.velocity.x = body.velocity.x - this.velocity.x * this.bounce.x;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
||||
{
|
||||
this.velocity.x = 0;
|
||||
}
|
||||
this.reboundCheck(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -770,12 +803,9 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
body.x -= x;
|
||||
this.velocity.x = avg + nv1 * this.bounce.x;
|
||||
body.velocity.x = avg + nv2 * body.bounce.x;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
||||
{
|
||||
this.velocity.x = 0;
|
||||
}
|
||||
|
||||
this.reboundCheck(true, false);
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,6 +842,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
{
|
||||
body.y -= y;
|
||||
body.velocity.y = this.velocity.y - body.velocity.y * body.bounce.y;
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -820,12 +851,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// We take the full separation as what hit is isn't moveable
|
||||
this.y += y;
|
||||
this.velocity.y = body.velocity.y - this.velocity.y * this.bounce.y;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
||||
{
|
||||
this.velocity.y = 0;
|
||||
}
|
||||
this.reboundCheck(false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -835,12 +861,9 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
body.y -= y;
|
||||
this.velocity.y = avg + nv1 * this.bounce.y;
|
||||
body.velocity.y = avg + nv2 * body.bounce.y;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
||||
{
|
||||
this.velocity.y = 0;
|
||||
}
|
||||
|
||||
this.reboundCheck(false, true);
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -877,6 +900,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
{
|
||||
body.y -= y;
|
||||
body.velocity.y = this.velocity.y - body.velocity.y * body.bounce.y;
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -885,12 +909,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
// We take the full separation as what hit is isn't moveable
|
||||
this.y += y;
|
||||
this.velocity.y = body.velocity.y - this.velocity.y * this.bounce.y;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
||||
{
|
||||
this.velocity.y = 0;
|
||||
}
|
||||
this.reboundCheck(false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -900,12 +919,8 @@ Phaser.Physics.Arcade.Body.prototype = {
|
|||
body.y -= y;
|
||||
this.velocity.y = avg + nv1 * this.bounce.y;
|
||||
body.velocity.y = avg + nv2 * body.bounce.y;
|
||||
|
||||
// Rebound check
|
||||
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
||||
{
|
||||
this.velocity.y = 0;
|
||||
}
|
||||
this.reboundCheck(false, true);
|
||||
body.reboundCheck(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue