2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
|
|
* @copyright 2013 Photon Storm Ltd.
|
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Physics Body is linked to a single Sprite. All physics operations should be performed against the body rather than
|
|
|
|
* the Sprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.
|
|
|
|
*
|
|
|
|
* @class Phaser.Physics.Arcade.Body
|
|
|
|
* @classdesc Arcade Physics Body Constructor
|
|
|
|
* @constructor
|
|
|
|
* @param {Phaser.Sprite} sprite - The Sprite object this physics body belongs to.
|
|
|
|
*/
|
2013-09-03 14:35:40 +00:00
|
|
|
Phaser.Physics.Arcade.Body = function (sprite) {
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Sprite} sprite - Reference to the parent Sprite.
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.sprite = sprite;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {Phaser.Game} game - Local reference to game.
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.game = sprite.game;
|
2013-09-03 14:35:40 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position.
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.offset = new Phaser.Point();
|
2013-09-03 14:35:40 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @property {number} x - The x position of the physics body.
|
|
|
|
* @readonly
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.x = sprite.x;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} y - The y position of the physics body.
|
|
|
|
* @readonly
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.y = sprite.y;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} preX - The previous x position of the physics body.
|
|
|
|
* @readonly
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.preX = sprite.x;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} preY - The previous y position of the physics body.
|
|
|
|
* @readonly
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.preY = sprite.y;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} preRotation - The previous rotation of the physics body.
|
|
|
|
* @readonly
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.preRotation = sprite.angle;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
/**
|
|
|
|
* @property {number} screenX - The x position of the physics body translated to screen space.
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.screenX = sprite.x;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} screenY - The y position of the physics body translated to screen space.
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.screenY = sprite.y;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} sourceWidth - The un-scaled original size.
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.sourceWidth = sprite.currentFrame.sourceSizeW;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} sourceHeight - The un-scaled original size.
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
this.sourceHeight = sprite.currentFrame.sourceSizeH;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @property {number} width - The calculated width of the physics body.
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.width = sprite.currentFrame.sourceSizeW;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property .numInternal ID cache
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.height = sprite.currentFrame.sourceSizeH;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
/**
|
|
|
|
* @property {number} halfWidth - The calculated width / 2 of the physics body.
|
|
|
|
*/
|
|
|
|
this.halfWidth = Math.floor(sprite.currentFrame.sourceSizeW / 2);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} halfHeight - The calculated height / 2 of the physics body.
|
|
|
|
*/
|
|
|
|
this.halfHeight = Math.floor(sprite.currentFrame.sourceSizeH / 2);
|
|
|
|
|
2013-10-30 03:46:52 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Point} center - The center coordinate of the Physics Body.
|
|
|
|
*/
|
|
|
|
this.center = new Phaser.Point(this.x + this.halfWidth, this.y + this.halfHeight);
|
|
|
|
|
2014-01-02 23:28:22 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Point} motionVelocity - The data from the updateMotion function.
|
|
|
|
*/
|
|
|
|
this.motionVelocity = new Phaser.Point();
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {Phaser.Point} velocity - The velocity of the Body.
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.velocity = new Phaser.Point();
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {Phaser.Point} acceleration - The acceleration in pixels per second sq. of the Body.
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.acceleration = new Phaser.Point();
|
2013-10-25 15:54:40 +00:00
|
|
|
|
2014-01-14 02:43:09 +00:00
|
|
|
/**
|
2014-01-22 14:31:18 +00:00
|
|
|
* @property {number} speed - The speed in pixels per second sq. of the Body.
|
2014-01-14 02:43:09 +00:00
|
|
|
*/
|
2014-01-03 02:24:06 +00:00
|
|
|
this.speed = 0;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-14 02:43:09 +00:00
|
|
|
* @property {number} angle - The angle of the Body in radians.
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2014-01-14 02:43:09 +00:00
|
|
|
this.angle = 0;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
2014-01-15 13:20:51 +00:00
|
|
|
/**
|
|
|
|
* @property {number} minBounceVelocity - The minimum bounce velocity (could just be the bounce value?).
|
|
|
|
*/
|
2014-01-22 14:31:18 +00:00
|
|
|
this.minBounceVelocity = 0.5;
|
2014-01-15 13:20:51 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {Phaser.Point} gravity - The gravity applied to the motion of the Body. This works in addition to any gravity set on the world.
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.gravity = new Phaser.Point();
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
this.bounce = new Phaser.Point();
|
2013-10-25 15:54:40 +00:00
|
|
|
|
2014-01-20 20:14:34 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Point} minVelocity - When a body rebounds off another the minVelocity is checked, if the new velocity is lower than the minVelocity the body is stopped.
|
|
|
|
* @default
|
|
|
|
*/
|
2014-01-22 12:31:35 +00:00
|
|
|
this.minVelocity = new Phaser.Point(10, 10);
|
2014-01-20 20:14:34 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {Phaser.Point} maxVelocity - The maximum velocity that the Body can reach.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2014-01-22 14:31:18 +00:00
|
|
|
this.maxVelocity = new Phaser.Point(2000, 2000);
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {number} angularVelocity - The angular velocity of the Body.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
this.angularVelocity = 0;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {number} angularAcceleration - The angular acceleration of the Body.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
this.angularAcceleration = 0;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} angularDrag - The angular drag applied to the rotation of the Body.
|
|
|
|
* @default
|
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
this.angularDrag = 0;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {number} maxAngular - The maximum angular velocity that the Body can reach.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
this.maxAngular = 1000;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} mass - The mass of the Body.
|
|
|
|
* @default
|
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
this.mass = 1;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* Set the allowCollision properties to control which directions collision is processed for this Body.
|
|
|
|
* For example allowCollision.up = false means it won't collide when the collision happened while moving up.
|
|
|
|
* @property {object} allowCollision - An object containing allowed collision.
|
|
|
|
*/
|
2013-09-04 15:12:58 +00:00
|
|
|
this.allowCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This object is populated with boolean values when the Body collides with another.
|
|
|
|
* touching.up = true means the collision happened to the top of this Body for example.
|
|
|
|
* @property {object} touching - An object containing touching results.
|
|
|
|
*/
|
2013-09-04 12:54:55 +00:00
|
|
|
this.touching = { none: true, up: false, down: false, left: false, right: false };
|
2013-09-04 00:10:01 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
/**
|
|
|
|
* @property {number} facing - A const reference to the direction the Body is traveling or facing.
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
this.facing = Phaser.NONE;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-02 23:28:22 +00:00
|
|
|
* @property {boolean} immovable - An immovable Body will not receive any impacts or exchanges of velocity from other bodies.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-03 16:28:12 +00:00
|
|
|
this.immovable = false;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-21 16:12:50 +00:00
|
|
|
* @property {boolean} moves - Set to true to allow the Physics system to move this Body, or false to move it manually.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-04 00:10:01 +00:00
|
|
|
this.moves = true;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-14 02:43:09 +00:00
|
|
|
* @property {number} rotation - The amount the parent Sprite is rotated. Note: You cannot rotate an AABB.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-04 00:10:01 +00:00
|
|
|
this.rotation = 0;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-14 02:43:09 +00:00
|
|
|
* @property {boolean} allowRotation - Allow angular rotation? This will cause the Sprite to be rotated via angularVelocity, etc. Note that the AABB remains un-rotated.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-06 14:00:05 +00:00
|
|
|
this.allowRotation = true;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-14 02:43:09 +00:00
|
|
|
* @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity value? Note: It will always be influenced by the local gravity value.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2013-09-04 00:10:01 +00:00
|
|
|
this.allowGravity = true;
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-22 14:31:18 +00:00
|
|
|
* @property {function} customSeparateCallback - If set this callback will be used for Body separation instead of the built-in one. Callback should return true if separated, otherwise false.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2014-01-22 14:31:18 +00:00
|
|
|
this.customSeparateCallback = null;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
2014-01-22 14:31:18 +00:00
|
|
|
* @property {object} customSeparateContext - The context in which the customSeparateCallback is called.
|
2013-10-25 15:54:40 +00:00
|
|
|
* @default
|
|
|
|
*/
|
2014-01-22 14:31:18 +00:00
|
|
|
this.customSeparateContext = null;
|
2013-09-13 02:07:39 +00:00
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* @property {function} collideCallback - If set this callback will be fired whenever this Body is hit (on any face). It will send three parameters, the face it hit on, this Body and the Body that hit it.
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
this.collideCallback = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {object} collideCallbackContext - The context in which the collideCallback is called.
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
this.collideCallbackContext = null;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* When this body collides with another, the amount of overlap is stored here.
|
|
|
|
* @property {number} overlapX - The amount of horizontal overlap during the collision.
|
|
|
|
*/
|
2013-09-13 02:07:39 +00:00
|
|
|
this.overlapX = 0;
|
2013-10-25 15:54:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* When this body collides with another, the amount of overlap is stored here.
|
|
|
|
* @property {number} overlapY - The amount of vertical overlap during the collision.
|
|
|
|
*/
|
2013-09-13 02:07:39 +00:00
|
|
|
this.overlapY = 0;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-22 14:31:18 +00:00
|
|
|
* @property {number} friction - The amount of friction this body experiences during motion.
|
2014-01-02 23:28:22 +00:00
|
|
|
* @default
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2014-01-22 10:54:49 +00:00
|
|
|
this.friction = 0.1;
|
2013-10-14 18:37:44 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
|
|
|
|
* @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
|
|
|
|
*/
|
2013-09-04 02:48:15 +00:00
|
|
|
this.collideWorldBounds = false;
|
|
|
|
|
2014-01-15 13:33:05 +00:00
|
|
|
/**
|
|
|
|
* This object is populated with boolean values when the Body collides with the World bounds or a Tile.
|
|
|
|
* For example if blocked.up is true then the Body cannot move up.
|
|
|
|
* @property {object} blocked - An object containing on which faces this Body is blocked from moving, if any.
|
|
|
|
*/
|
2013-12-06 01:07:25 +00:00
|
|
|
this.blocked = { up: false, down: false, left: false, right: false };
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
/**
|
|
|
|
* @property {Phaser.Point} blockedPoint - A Point object holding the blocked penetration distance.
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
this.blockedPoint = new Phaser.Point(0, 0);
|
|
|
|
|
2014-01-15 13:33:05 +00:00
|
|
|
/**
|
|
|
|
* @property {number} _dx - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._dx = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} _dy - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._dy = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} _sx - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._sx = sprite.scale.x;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} _sy - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._sy = sprite.scale.y;
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
/**
|
|
|
|
* @property {number} _newVelocity1 - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
this._newVelocity1 = 0;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} _newVelocity2 - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
this._newVelocity2 = 0;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {number} _average - Internal cache var.
|
|
|
|
* @private
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
this._average = 0;
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
this._debug = 0;
|
|
|
|
|
2013-09-03 14:35:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Phaser.Physics.Arcade.Body.prototype = {
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* Internal method.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#updateBounds
|
|
|
|
* @protected
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
updateBounds: function (centerX, centerY, scaleX, scaleY) {
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
if (scaleX != this._sx || scaleY != this._sy)
|
|
|
|
{
|
|
|
|
this.width = this.sourceWidth * scaleX;
|
|
|
|
this.height = this.sourceHeight * scaleY;
|
|
|
|
this.halfWidth = Math.floor(this.width / 2);
|
|
|
|
this.halfHeight = Math.floor(this.height / 2);
|
|
|
|
this._sx = scaleX;
|
|
|
|
this._sy = scaleY;
|
|
|
|
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
|
|
|
}
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2013-11-25 04:40:04 +00:00
|
|
|
},
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* Internal method.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#preUpdate
|
|
|
|
* @protected
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
preUpdate: function () {
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
2014-01-22 14:31:18 +00:00
|
|
|
this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
|
|
|
|
|
|
|
this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
|
|
|
this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
|
|
|
this.preRotation = this.sprite.angle;
|
2014-01-22 10:54:49 +00:00
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
this.blocked.up = false;
|
|
|
|
this.blocked.down = false;
|
|
|
|
this.blocked.left = false;
|
|
|
|
this.blocked.right = false;
|
2014-01-22 10:54:49 +00:00
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
this.touching.up = false;
|
|
|
|
this.touching.down = false;
|
|
|
|
this.touching.left = false;
|
|
|
|
this.touching.right = false;
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
this.x = this.preX;
|
|
|
|
this.y = this.preY;
|
|
|
|
this.rotation = this.preRotation;
|
2014-01-22 12:31:35 +00:00
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y);
|
|
|
|
this.angle = Math.atan2(this.velocity.y, this.velocity.x);
|
2014-01-22 12:31:35 +00:00
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
if (this.moves)
|
2014-01-22 10:54:49 +00:00
|
|
|
{
|
2014-01-22 14:31:18 +00:00
|
|
|
if (this.collideWorldBounds)
|
2014-01-22 10:54:49 +00:00
|
|
|
{
|
2014-01-22 14:31:18 +00:00
|
|
|
this.checkWorldBounds();
|
2014-01-22 10:54:49 +00:00
|
|
|
}
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
this.game.physics.updateMotion(this);
|
|
|
|
|
|
|
|
this.applyMotion();
|
2014-01-22 10:54:49 +00:00
|
|
|
}
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
// if (this.deltaX() != 0)
|
|
|
|
// {
|
|
|
|
// this.touching.left = false;
|
|
|
|
// this.touching.right = false;
|
|
|
|
// }
|
2014-01-22 10:54:49 +00:00
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
// if (this.deltaY() != 0)
|
|
|
|
// {
|
|
|
|
// this.touching.up = false;
|
|
|
|
// this.touching.down = false;
|
|
|
|
// }
|
2014-01-22 10:54:49 +00:00
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal method used to check the Body against the World Bounds.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#checkWorldBounds
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
checkWorldBounds: function () {
|
|
|
|
|
|
|
|
this.blockedPoint.setTo(0, 0);
|
|
|
|
|
|
|
|
if (this.x < this.game.world.bounds.x)
|
2014-01-22 10:54:49 +00:00
|
|
|
{
|
2014-01-22 14:31:18 +00:00
|
|
|
this.blockedPoint.x = this.game.world.bounds.x - this.x;
|
|
|
|
this.blocked.left = true;
|
2014-01-22 10:54:49 +00:00
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
else if (this.right > this.game.world.bounds.right)
|
2014-01-22 10:54:49 +00:00
|
|
|
{
|
2014-01-22 14:31:18 +00:00
|
|
|
this.blockedPoint.x = this.right - this.game.world.bounds.right;
|
|
|
|
this.blocked.right = true;
|
2014-01-22 10:54:49 +00:00
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
if (this.y < this.game.world.bounds.y)
|
2014-01-22 10:54:49 +00:00
|
|
|
{
|
2014-01-22 14:31:18 +00:00
|
|
|
this.blockedPoint.y = this.game.world.bounds.y - this.y;
|
|
|
|
this.blocked.up = true;
|
2014-01-22 10:54:49 +00:00
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
else if (this.bottom > this.game.world.bounds.bottom)
|
2014-01-22 10:54:49 +00:00
|
|
|
{
|
2014-01-22 14:31:18 +00:00
|
|
|
this.blockedPoint.y = this.bottom - this.game.world.bounds.bottom;
|
|
|
|
this.blocked.down = true;
|
2014-01-22 10:54:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-01-14 02:43:09 +00:00
|
|
|
/**
|
|
|
|
* Internal method.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#applyMotion
|
|
|
|
* @protected
|
|
|
|
*/
|
2014-01-22 14:31:18 +00:00
|
|
|
applyMotion: function () {
|
2014-01-02 23:28:22 +00:00
|
|
|
|
2014-01-09 03:42:58 +00:00
|
|
|
if (this.friction > 0 && this.acceleration.isZero())
|
2014-01-03 04:50:31 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
if (this.speed > this.friction)
|
2014-01-03 04:50:31 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
this.speed -= this.friction;
|
2014-01-03 04:50:31 +00:00
|
|
|
}
|
2014-01-09 03:42:58 +00:00
|
|
|
else
|
2014-01-03 04:50:31 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
this.speed = 0;
|
2014-01-03 04:50:31 +00:00
|
|
|
}
|
|
|
|
|
2014-01-09 03:42:58 +00:00
|
|
|
this.velocity.x = Math.cos(this.angle) * this.speed;
|
|
|
|
this.velocity.y = Math.sin(this.angle) * this.speed;
|
2014-01-03 04:50:31 +00:00
|
|
|
}
|
|
|
|
|
2014-01-15 13:20:51 +00:00
|
|
|
// overlapX/Y values at this point will be penetration into the bounds and DELTA WILL BE ZERO
|
2014-01-22 14:31:18 +00:00
|
|
|
if (this.blocked.left && this.blockedPoint.x > 0)
|
2014-01-15 03:17:26 +00:00
|
|
|
{
|
2014-01-15 13:20:51 +00:00
|
|
|
// Separate
|
2014-01-21 16:12:50 +00:00
|
|
|
this.x += this.blockedPoint.x;
|
2014-01-15 14:21:06 +00:00
|
|
|
this.velocity.x *= -this.bounce.x;
|
|
|
|
|
|
|
|
this._dx = this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2);
|
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
if (this._dx > this.minBounceVelocity)
|
2014-01-15 13:20:51 +00:00
|
|
|
{
|
2014-01-15 14:21:06 +00:00
|
|
|
this.x += this._dx;
|
2014-01-15 13:20:51 +00:00
|
|
|
this.velocity.x += this.motionVelocity.x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-15 14:21:06 +00:00
|
|
|
this.preX = this.x; // because we don't want any delta from a separation
|
2014-01-15 13:20:51 +00:00
|
|
|
this.velocity.x = 0;
|
|
|
|
this.motionVelocity.x = 0;
|
|
|
|
}
|
2014-01-15 03:17:26 +00:00
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
else if (this.blocked.right && this.blockedPoint.x > 0)
|
2014-01-15 03:17:26 +00:00
|
|
|
{
|
2014-01-15 13:20:51 +00:00
|
|
|
// Separate
|
2014-01-21 16:12:50 +00:00
|
|
|
this.x -= this.blockedPoint.x;
|
2014-01-15 14:21:06 +00:00
|
|
|
this.velocity.x *= -this.bounce.x;
|
|
|
|
|
|
|
|
this._dx = this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2);
|
|
|
|
|
|
|
|
if (this._dx < -this.minBounceVelocity)
|
2014-01-15 13:20:51 +00:00
|
|
|
{
|
2014-01-15 14:21:06 +00:00
|
|
|
this.x += this._dx;
|
2014-01-15 13:20:51 +00:00
|
|
|
this.velocity.x += this.motionVelocity.x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-15 14:21:06 +00:00
|
|
|
this.preX = this.x; // because we don't want any delta from a separation
|
2014-01-15 13:20:51 +00:00
|
|
|
this.velocity.x = 0;
|
|
|
|
this.motionVelocity.x = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.x += this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2);
|
|
|
|
this.velocity.x += this.motionVelocity.x;
|
2014-01-15 03:17:26 +00:00
|
|
|
}
|
2014-01-03 04:50:31 +00:00
|
|
|
|
2014-01-15 13:20:51 +00:00
|
|
|
// overlapX/Y values at this point will be penetration into the bounds and DELTA WILL BE ZERO
|
2014-01-22 14:31:18 +00:00
|
|
|
if (this.blocked.up && this.blockedPoint.y > 0)
|
2014-01-15 13:20:51 +00:00
|
|
|
{
|
|
|
|
// Separate
|
2014-01-21 16:12:50 +00:00
|
|
|
this.y += this.blockedPoint.y;
|
2014-01-15 14:21:06 +00:00
|
|
|
this.velocity.y *= -this.bounce.y;
|
2014-01-15 13:33:05 +00:00
|
|
|
|
2014-01-15 14:21:06 +00:00
|
|
|
this._dy = this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2);
|
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
if (this._dy > this.minBounceVelocity)
|
2014-01-15 13:20:51 +00:00
|
|
|
{
|
2014-01-15 14:21:06 +00:00
|
|
|
this.y += this._dy;
|
|
|
|
this.velocity.y += this.motionVelocity.y;
|
2014-01-15 13:20:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-15 13:33:05 +00:00
|
|
|
this.preY = this.y; // because we don't want any delta from a separation
|
2014-01-15 13:20:51 +00:00
|
|
|
this.velocity.y = 0;
|
|
|
|
this.motionVelocity.y = 0;
|
|
|
|
}
|
2014-01-15 03:17:26 +00:00
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
else if (this.blocked.down && this.blockedPoint.y > 0)
|
2014-01-15 03:17:26 +00:00
|
|
|
{
|
2014-01-15 13:20:51 +00:00
|
|
|
// Separate
|
2014-01-21 16:12:50 +00:00
|
|
|
this.y -= this.blockedPoint.y;
|
2014-01-15 14:21:06 +00:00
|
|
|
this.velocity.y *= -this.bounce.y;
|
|
|
|
|
|
|
|
this._dy = this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2);
|
2014-01-15 13:20:51 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
if (this._dy < -this.minBounceVelocity)
|
2014-01-15 13:20:51 +00:00
|
|
|
{
|
2014-01-15 14:21:06 +00:00
|
|
|
this.y += this._dy;
|
|
|
|
this.velocity.y += this.motionVelocity.y;
|
2014-01-15 13:20:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.preY = this.y; // because we don't want any delta from a separation
|
|
|
|
this.velocity.y = 0;
|
|
|
|
this.motionVelocity.y = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2014-01-15 03:17:26 +00:00
|
|
|
{
|
2014-01-15 13:20:51 +00:00
|
|
|
this.y += this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2);
|
|
|
|
this.velocity.y += this.motionVelocity.y;
|
2014-01-15 03:17:26 +00:00
|
|
|
}
|
|
|
|
|
2014-01-09 03:42:58 +00:00
|
|
|
if (this.velocity.x > this.maxVelocity.x)
|
2014-01-03 02:24:06 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
this.velocity.x = this.maxVelocity.x;
|
2014-01-03 02:24:06 +00:00
|
|
|
}
|
2014-01-09 03:42:58 +00:00
|
|
|
else if (this.velocity.x < -this.maxVelocity.x)
|
2014-01-03 02:24:06 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
this.velocity.x = -this.maxVelocity.x;
|
2014-01-03 02:24:06 +00:00
|
|
|
}
|
|
|
|
|
2014-01-09 03:42:58 +00:00
|
|
|
if (this.velocity.y > this.maxVelocity.y)
|
2014-01-03 02:24:06 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
this.velocity.y = this.maxVelocity.y;
|
2014-01-03 02:24:06 +00:00
|
|
|
}
|
2014-01-09 03:42:58 +00:00
|
|
|
else if (this.velocity.y < -this.maxVelocity.y)
|
2014-01-03 02:24:06 +00:00
|
|
|
{
|
2014-01-09 03:42:58 +00:00
|
|
|
this.velocity.y = -this.maxVelocity.y;
|
2014-01-03 02:24:06 +00:00
|
|
|
}
|
|
|
|
|
2013-11-25 04:40:04 +00:00
|
|
|
},
|
2013-09-23 00:06:09 +00:00
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* Checks for an overlap between this Body and the given Body, taking into account the allowCollision flags on both bodies.
|
|
|
|
* If an overlap occurs the Body.touching flags are set and the results are stored in overlapX and overlapY.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#overlap
|
|
|
|
* @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
|
|
|
|
* @return {boolean} True if the two bodies overlap, otherwise false.
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
overlap: function (body) {
|
|
|
|
|
|
|
|
this.overlapX = 0;
|
|
|
|
this.overlapY = 0;
|
|
|
|
|
|
|
|
if (this.x < body.x && this.allowCollision.right && body.allowCollision.left)
|
|
|
|
{
|
|
|
|
// Negative = body touched this one on the right face
|
|
|
|
this.overlapX = body.x - this.right;
|
|
|
|
this.touching.right = true;
|
|
|
|
}
|
|
|
|
else if (this.x > body.x && this.allowCollision.left && body.allowCollision.right)
|
|
|
|
{
|
|
|
|
// Positive means body touched this one on the left face
|
|
|
|
this.overlapX = body.right - this.x;
|
|
|
|
this.touching.left = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.y < body.y && this.allowCollision.down && body.allowCollision.up)
|
|
|
|
{
|
|
|
|
// Negative = body touched this one on the bottom face
|
|
|
|
this.overlapY = body.y - this.bottom;
|
|
|
|
this.touching.down = true;
|
|
|
|
}
|
|
|
|
else if (this.y > body.y && this.allowCollision.up && body.allowCollision.down)
|
|
|
|
{
|
|
|
|
// Positive means body touched this one on the top face
|
|
|
|
this.overlapY = body.bottom - this.y;
|
|
|
|
this.touching.up = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Which is the largest?
|
|
|
|
if (this.overlapX !== 0 && this.overlapY !== 0)
|
|
|
|
{
|
2014-01-22 16:16:53 +00:00
|
|
|
// Crudely find out which is the largest penetration side
|
2014-01-21 16:12:50 +00:00
|
|
|
if (Math.abs(this.overlapX) > Math.abs(this.overlapY))
|
|
|
|
{
|
|
|
|
// Vertical penetration (as x is larger than y)
|
|
|
|
this.overlapX = 0;
|
|
|
|
this.touching.left = false;
|
|
|
|
this.touching.right = false;
|
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
else
|
2014-01-21 16:12:50 +00:00
|
|
|
{
|
|
|
|
// Horizontal penetration (as y is larger than x)
|
|
|
|
this.overlapY = 0;
|
|
|
|
this.touching.up = false;
|
|
|
|
this.touching.down = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// overlapX/Y now contains either zero or a positive value containing the overlapping area
|
|
|
|
return (this.overlapX !== 0 || this.overlapY !== 0);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* Process a collision with the left face of this Body. If possible the Body will be moved right.
|
|
|
|
* Uses overlayX which will be positive.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#hitLeft
|
|
|
|
* @protected
|
|
|
|
* @param {number} x - The overlapX value.
|
|
|
|
* @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
|
|
|
|
* @param {number} nv1 - The new velocity for this Body.
|
|
|
|
* @param {number} nv2 - The new velocity for the colliding Body.
|
|
|
|
* @param {number} avg - The new average velocity between the two Bodies.
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
hitLeft: function (x, body, nv1, nv2, avg) {
|
|
|
|
|
|
|
|
// This body isn't moving horizontally, so it was hit by something moving right
|
|
|
|
if (this.immovable || this.blocked.right)
|
|
|
|
{
|
|
|
|
body.x -= x;
|
|
|
|
body.velocity.x = this.velocity.x - body.velocity.x * body.bounce.x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (body.immovable || body.blocked.left)
|
|
|
|
{
|
|
|
|
// 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;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
|
|
|
{
|
|
|
|
this.velocity.x = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Share the separation
|
|
|
|
x *= 0.5;
|
|
|
|
this.x += x;
|
|
|
|
body.x -= x;
|
|
|
|
this.velocity.x = avg + nv1 * this.bounce.x;
|
|
|
|
body.velocity.x = avg + nv2 * body.bounce.x;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
|
|
|
{
|
|
|
|
this.velocity.x = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
// Bounds check
|
|
|
|
if (this.checkWorldBounds && this.right >= this.game.world.bounds.right)
|
|
|
|
{
|
|
|
|
this.blocked.right = true;
|
|
|
|
this.x -= this.right - this.game.world.bounds.right;
|
|
|
|
}
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
if (this.collideCallback)
|
|
|
|
{
|
|
|
|
this.collideCallback.call(this.collideCallbackContext, Phaser.LEFT, this, body);
|
|
|
|
}
|
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
},
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* Process a collision with the right face of this Body. If possible the Body will be moved left.
|
|
|
|
* Uses overlayX which will be negative.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#hitRight
|
|
|
|
* @protected
|
|
|
|
* @param {number} x - The overlapX value.
|
|
|
|
* @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
|
|
|
|
* @param {number} nv1 - The new velocity for this Body.
|
|
|
|
* @param {number} nv2 - The new velocity for the colliding Body.
|
|
|
|
* @param {number} avg - The new average velocity between the two Bodies.
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
hitRight: function (x, body, nv1, nv2, avg) {
|
|
|
|
|
|
|
|
// This body isn't moving horizontally, so it was hit by something moving right
|
|
|
|
if (this.immovable || this.blocked.left)
|
|
|
|
{
|
|
|
|
body.x -= x;
|
|
|
|
body.velocity.x = this.velocity.x - body.velocity.x * body.bounce.x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (body.immovable || body.blocked.right)
|
|
|
|
{
|
|
|
|
// 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;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
|
|
|
{
|
|
|
|
this.velocity.x = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Share the separation
|
|
|
|
x *= 0.5;
|
|
|
|
this.x += x;
|
|
|
|
body.x -= x;
|
|
|
|
this.velocity.x = avg + nv1 * this.bounce.x;
|
|
|
|
body.velocity.x = avg + nv2 * body.bounce.x;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.x) < this.minVelocity.x)
|
|
|
|
{
|
|
|
|
this.velocity.x = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
// Bounds check
|
|
|
|
if (this.checkWorldBounds && this.x <= this.game.world.bounds.x)
|
|
|
|
{
|
|
|
|
this.blocked.left = true;
|
|
|
|
this.x += this.game.world.bounds.x - this.x;
|
|
|
|
}
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
if (this.collideCallback)
|
|
|
|
{
|
|
|
|
this.collideCallback.call(this.collideCallbackContext, Phaser.RIGHT, this, body);
|
|
|
|
}
|
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
},
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* Process a collision with the top face of this Body. If possible the Body will be moved down.
|
|
|
|
* Uses overlayY which will be positive.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#hitUp
|
|
|
|
* @protected
|
|
|
|
* @param {number} y - The overlapY value.
|
|
|
|
* @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
|
|
|
|
* @param {number} nv1 - The new velocity for this Body.
|
|
|
|
* @param {number} nv2 - The new velocity for the colliding Body.
|
|
|
|
* @param {number} avg - The new average velocity between the two Bodies.
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
hitUp: function (y, body, nv1, nv2, avg) {
|
|
|
|
|
|
|
|
// This body isn't moving horizontally, so it was hit by something moving right
|
|
|
|
if (this.immovable || this.blocked.down)
|
|
|
|
{
|
|
|
|
body.y -= y;
|
|
|
|
body.velocity.y = this.velocity.y - body.velocity.y * body.bounce.y;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (body.immovable || body.blocked.up)
|
|
|
|
{
|
|
|
|
// 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;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
|
|
|
{
|
|
|
|
this.velocity.y = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Share the separation
|
|
|
|
y *= 0.5;
|
|
|
|
this.y += y;
|
|
|
|
body.y -= y;
|
|
|
|
this.velocity.y = avg + nv1 * this.bounce.y;
|
|
|
|
body.velocity.y = avg + nv2 * body.bounce.y;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
|
|
|
{
|
|
|
|
this.velocity.y = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
// Bounds check
|
|
|
|
if (this.checkWorldBounds && this.bottom >= this.game.world.bounds.bottom)
|
|
|
|
{
|
|
|
|
this.blocked.down = true;
|
|
|
|
this.y -= this.bottom - this.game.world.bounds.bottom;
|
|
|
|
}
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
if (this.collideCallback)
|
|
|
|
{
|
|
|
|
this.collideCallback.call(this.collideCallbackContext, Phaser.UP, this, body);
|
|
|
|
}
|
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
},
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* Process a collision with the bottom face of this Body. If possible the Body will be moved up.
|
|
|
|
* Uses overlayY which will be negative.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#hitDown
|
|
|
|
* @protected
|
|
|
|
* @param {number} y - The overlapY value.
|
|
|
|
* @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
|
|
|
|
* @param {number} nv1 - The new velocity for this Body.
|
|
|
|
* @param {number} nv2 - The new velocity for the colliding Body.
|
|
|
|
* @param {number} avg - The new average velocity between the two Bodies.
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
hitDown: function (y, body, nv1, nv2, avg) {
|
|
|
|
|
|
|
|
// This body isn't moving horizontally, so it was hit by something moving right
|
|
|
|
if (this.immovable || this.blocked.up)
|
|
|
|
{
|
|
|
|
body.y -= y;
|
|
|
|
body.velocity.y = this.velocity.y - body.velocity.y * body.bounce.y;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (body.immovable || body.blocked.down)
|
|
|
|
{
|
|
|
|
// 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;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
|
|
|
{
|
|
|
|
this.velocity.y = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Share the separation
|
|
|
|
y *= 0.5;
|
|
|
|
this.y += y;
|
|
|
|
body.y -= y;
|
|
|
|
this.velocity.y = avg + nv1 * this.bounce.y;
|
|
|
|
body.velocity.y = avg + nv2 * body.bounce.y;
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
// Rebound check
|
|
|
|
if (Math.abs(this.velocity.y) < this.minVelocity.y)
|
|
|
|
{
|
|
|
|
this.velocity.y = 0;
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
// Bounds check
|
|
|
|
if (this.checkWorldBounds && this.y <= this.game.world.bounds.y)
|
|
|
|
{
|
|
|
|
this.blocked.up = true;
|
|
|
|
this.y += this.game.world.bounds.y - this.y;
|
|
|
|
}
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
if (this.collideCallback)
|
|
|
|
{
|
|
|
|
this.collideCallback.call(this.collideCallbackContext, Phaser.DOWN, this, body);
|
|
|
|
}
|
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
},
|
|
|
|
|
2014-01-22 16:16:53 +00:00
|
|
|
/**
|
|
|
|
* This separates this Body from the given Body unless a customSeparateCallback is set.
|
|
|
|
* It assumes they have already been overlap checked and the resulting overlap is stored in overlapX and overlapY.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#separate
|
|
|
|
* @protected
|
|
|
|
* @param {Phaser.Physics.Arcade.Body} body - The Body to be separated from this one.
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
2014-01-21 16:12:50 +00:00
|
|
|
separate: function (body) {
|
|
|
|
|
2014-01-22 14:31:18 +00:00
|
|
|
if (this.customSeparateCallback)
|
|
|
|
{
|
|
|
|
return this.customSeparateCallback.call(this.customSeparateContext, this, this.overlapX, this.overlapY);
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
|
|
|
|
if (this.overlapX !== 0)
|
|
|
|
{
|
|
|
|
this._newVelocity1 = Math.sqrt((body.velocity.x * body.velocity.x * body.mass) / this.mass) * ((body.velocity.x > 0) ? 1 : -1);
|
|
|
|
this._newVelocity2 = Math.sqrt((this.velocity.x * this.velocity.x * this.mass) / body.mass) * ((this.velocity.x > 0) ? 1 : -1);
|
|
|
|
this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
|
|
|
|
this._newVelocity1 -= this._average;
|
|
|
|
this._newVelocity2 -= this._average;
|
|
|
|
|
|
|
|
if (this.overlapX < 0)
|
|
|
|
{
|
|
|
|
this.hitLeft(this.overlapX, body, this._newVelocity1, this._newVelocity2, this._average);
|
|
|
|
}
|
|
|
|
else if (this.overlapX > 0)
|
|
|
|
{
|
|
|
|
this.hitRight(this.overlapX, body, this._newVelocity1, this._newVelocity2, this._average);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.overlapY !== 0)
|
|
|
|
{
|
|
|
|
this._newVelocity1 = Math.sqrt((body.velocity.y * body.velocity.y * body.mass) / this.mass) * ((body.velocity.y > 0) ? 1 : -1);
|
|
|
|
this._newVelocity2 = Math.sqrt((this.velocity.y * this.velocity.y * this.mass) / body.mass) * ((this.velocity.y > 0) ? 1 : -1);
|
|
|
|
this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
|
|
|
|
this._newVelocity1 -= this._average;
|
|
|
|
this._newVelocity2 -= this._average;
|
|
|
|
|
|
|
|
if (this.overlapY < 0)
|
|
|
|
{
|
|
|
|
this.hitDown(this.overlapY, body, this._newVelocity1, this._newVelocity2, this._average);
|
|
|
|
}
|
|
|
|
else if (this.overlapY > 0)
|
|
|
|
{
|
|
|
|
this.hitUp(this.overlapY, body, this._newVelocity1, this._newVelocity2, this._average);
|
|
|
|
}
|
|
|
|
}
|
2014-01-22 14:31:18 +00:00
|
|
|
|
|
|
|
return true;
|
2014-01-22 10:54:49 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
},
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2014-01-20 20:14:34 +00:00
|
|
|
* Internal method. This is called directly before the sprites are sent to the renderer.
|
2013-10-25 15:54:40 +00:00
|
|
|
*
|
2014-01-20 20:14:34 +00:00
|
|
|
* @method Phaser.Physics.Arcade#postUpdate
|
2013-10-25 15:54:40 +00:00
|
|
|
* @protected
|
|
|
|
*/
|
2014-01-20 20:14:34 +00:00
|
|
|
postUpdate: function () {
|
2013-11-25 04:40:04 +00:00
|
|
|
|
2014-01-20 20:14:34 +00:00
|
|
|
if (this.moves)
|
2013-11-25 04:40:04 +00:00
|
|
|
{
|
2014-01-21 16:12:50 +00:00
|
|
|
if (this.deltaX() < 0)
|
|
|
|
{
|
|
|
|
this.facing = Phaser.LEFT;
|
|
|
|
}
|
|
|
|
else if (this.deltaX() > 0)
|
|
|
|
{
|
|
|
|
this.facing = Phaser.RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.deltaY() < 0)
|
|
|
|
{
|
|
|
|
this.facing = Phaser.UP;
|
|
|
|
}
|
|
|
|
else if (this.deltaY() > 0)
|
|
|
|
{
|
|
|
|
this.facing = Phaser.DOWN;
|
|
|
|
}
|
|
|
|
|
2014-01-22 14:49:06 +00:00
|
|
|
if ((this.deltaX() < 0 && !this.blocked.left) || (this.deltaX() > 0 && !this.blocked.right))
|
|
|
|
{
|
|
|
|
this.sprite.x += this.deltaX();
|
|
|
|
this.sprite.worldTransform[2] += this.deltaX();
|
|
|
|
}
|
2014-01-21 16:12:50 +00:00
|
|
|
|
2014-01-22 14:49:06 +00:00
|
|
|
if ((this.deltaY() < 0 && !this.blocked.up) || (this.deltaY() > 0 && !this.blocked.down))
|
|
|
|
{
|
|
|
|
this.sprite.y += this.deltaY();
|
|
|
|
this.sprite.worldTransform[5] += this.deltaY();
|
|
|
|
}
|
2013-11-25 04:40:04 +00:00
|
|
|
|
2014-01-20 20:14:34 +00:00
|
|
|
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
|
|
|
|
|
|
|
if (this.allowRotation)
|
|
|
|
{
|
|
|
|
this.sprite.angle += this.deltaZ();
|
|
|
|
}
|
2013-11-25 04:40:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
},
|
2013-09-03 16:07:05 +00:00
|
|
|
|
2014-01-21 16:12:50 +00:00
|
|
|
/**
|
|
|
|
* You can modify the size of the physics Body to be any dimension you need.
|
|
|
|
* So it could be smaller or larger than the parent Sprite. You can also control the x and y offset, which
|
|
|
|
* is the position of the Body relative to the top-left of the Sprite.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#setSize
|
|
|
|
* @param {number} width - The width of the Body.
|
|
|
|
* @param {number} height - The height of the Body.
|
|
|
|
* @param {number} offsetX - The X offset of the Body from the Sprite position.
|
|
|
|
* @param {number} offsetY - The Y offset of the Body from the Sprite position.
|
|
|
|
*/
|
|
|
|
setSize: function (width, height, offsetX, offsetY) {
|
|
|
|
|
|
|
|
offsetX = offsetX || this.offset.x;
|
|
|
|
offsetY = offsetY || this.offset.y;
|
|
|
|
|
|
|
|
this.sourceWidth = width;
|
|
|
|
this.sourceHeight = height;
|
|
|
|
this.width = this.sourceWidth * this._sx;
|
|
|
|
this.height = this.sourceHeight * this._sy;
|
|
|
|
this.halfWidth = Math.floor(this.width / 2);
|
|
|
|
this.halfHeight = Math.floor(this.height / 2);
|
|
|
|
this.offset.setTo(offsetX, offsetY);
|
|
|
|
|
|
|
|
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* Resets all Body values (velocity, acceleration, rotation, etc)
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade#reset
|
|
|
|
*/
|
2013-11-25 04:40:04 +00:00
|
|
|
reset: function () {
|
2013-09-10 00:26:50 +00:00
|
|
|
|
2013-11-25 04:40:04 +00:00
|
|
|
this.velocity.setTo(0, 0);
|
|
|
|
this.acceleration.setTo(0, 0);
|
2013-09-10 00:26:50 +00:00
|
|
|
|
2013-11-25 04:40:04 +00:00
|
|
|
this.angularVelocity = 0;
|
|
|
|
this.angularAcceleration = 0;
|
2013-10-29 04:07:26 +00:00
|
|
|
this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
|
|
|
this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
2013-11-25 04:40:04 +00:00
|
|
|
this.preRotation = this.sprite.angle;
|
2013-10-08 20:09:46 +00:00
|
|
|
|
2013-11-25 04:40:04 +00:00
|
|
|
this.x = this.preX;
|
|
|
|
this.y = this.preY;
|
|
|
|
this.rotation = this.preRotation;
|
2013-10-30 03:46:52 +00:00
|
|
|
|
|
|
|
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
2013-09-10 00:26:50 +00:00
|
|
|
|
2013-11-25 04:40:04 +00:00
|
|
|
},
|
2013-09-10 00:26:50 +00:00
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* Returns the absolute delta x value.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade.Body#deltaAbsX
|
|
|
|
* @return {number} The absolute delta value.
|
|
|
|
*/
|
2013-09-03 18:34:38 +00:00
|
|
|
deltaAbsX: function () {
|
|
|
|
return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX());
|
2013-09-03 16:07:05 +00:00
|
|
|
},
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* Returns the absolute delta y value.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade.Body#deltaAbsY
|
|
|
|
* @return {number} The absolute delta value.
|
|
|
|
*/
|
2013-09-03 18:34:38 +00:00
|
|
|
deltaAbsY: function () {
|
|
|
|
return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY());
|
2013-09-03 16:07:05 +00:00
|
|
|
},
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2013-11-01 02:07:21 +00:00
|
|
|
* Returns the delta x value. The difference between Body.x now and in the previous step.
|
2013-10-25 15:54:40 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade.Body#deltaX
|
2013-12-06 01:07:25 +00:00
|
|
|
* @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
deltaX: function () {
|
2013-09-23 00:06:09 +00:00
|
|
|
return this.x - this.preX;
|
2013-09-03 16:07:05 +00:00
|
|
|
},
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
2013-11-01 02:07:21 +00:00
|
|
|
* Returns the delta y value. The difference between Body.y now and in the previous step.
|
2013-10-25 15:54:40 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Arcade.Body#deltaY
|
2013-12-06 01:07:25 +00:00
|
|
|
* @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
|
2013-10-25 15:54:40 +00:00
|
|
|
*/
|
2013-09-03 16:07:05 +00:00
|
|
|
deltaY: function () {
|
2013-09-23 00:06:09 +00:00
|
|
|
return this.y - this.preY;
|
2013-10-07 23:58:20 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
deltaZ: function () {
|
|
|
|
return this.rotation - this.preRotation;
|
2013-09-03 16:07:05 +00:00
|
|
|
}
|
|
|
|
|
2013-09-08 00:24:59 +00:00
|
|
|
};
|
|
|
|
|
2013-12-30 16:54:00 +00:00
|
|
|
Phaser.Physics.Arcade.Body.prototype.constructor = Phaser.Physics.Arcade.Body;
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @name Phaser.Physics.Arcade.Body#bottom
|
|
|
|
* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
|
|
|
|
*/
|
2013-09-08 00:24:59 +00:00
|
|
|
Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
|
|
|
|
* @method bottom
|
2013-10-01 15:39:39 +00:00
|
|
|
* @return {number}
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-09-08 00:24:59 +00:00
|
|
|
get: function () {
|
2014-01-15 13:20:51 +00:00
|
|
|
return this.y + this.height;
|
2013-09-08 00:24:59 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
|
|
|
|
* @method bottom
|
2013-10-01 15:39:39 +00:00
|
|
|
* @param {number} value
|
2013-11-25 04:40:04 +00:00
|
|
|
*/
|
2013-09-08 00:24:59 +00:00
|
|
|
set: function (value) {
|
2013-09-11 12:21:07 +00:00
|
|
|
|
|
|
|
if (value <= this.y)
|
|
|
|
{
|
2013-09-08 00:24:59 +00:00
|
|
|
this.height = 0;
|
2013-09-11 12:21:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-09-08 00:24:59 +00:00
|
|
|
this.height = (this.y - value);
|
|
|
|
}
|
2013-09-11 12:21:07 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-09-08 00:24:59 +00:00
|
|
|
});
|
|
|
|
|
2013-10-25 15:54:40 +00:00
|
|
|
/**
|
|
|
|
* @name Phaser.Physics.Arcade.Body#right
|
|
|
|
* @property {number} right - The right value of this Body (same as Body.x + Body.width)
|
|
|
|
*/
|
2013-09-08 00:24:59 +00:00
|
|
|
Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
|
|
|
|
* However it does affect the width property.
|
|
|
|
* @method right
|
2013-10-01 15:39:39 +00:00
|
|
|
* @return {number}
|
2013-11-25 04:40:04 +00:00
|
|
|
*/
|
2013-09-08 00:24:59 +00:00
|
|
|
get: function () {
|
2014-01-15 13:20:51 +00:00
|
|
|
return this.x + this.width;
|
2013-09-08 00:24:59 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
|
|
|
|
* However it does affect the width property.
|
|
|
|
* @method right
|
2013-10-01 15:39:39 +00:00
|
|
|
* @param {number} value
|
2013-11-25 03:13:04 +00:00
|
|
|
*/
|
2013-09-08 00:24:59 +00:00
|
|
|
set: function (value) {
|
2013-09-11 12:21:07 +00:00
|
|
|
|
|
|
|
if (value <= this.x)
|
|
|
|
{
|
2013-09-08 00:24:59 +00:00
|
|
|
this.width = 0;
|
2013-09-11 12:21:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-09-08 00:24:59 +00:00
|
|
|
this.width = this.x + value;
|
|
|
|
}
|
2013-09-11 12:21:07 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-09-08 00:24:59 +00:00
|
|
|
});
|