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
/ * *
2014-01-23 21:45:35 +00:00
* Set the checkCollision properties to control which directions collision is processed for this Body .
* For example checkCollision . up = false means it won ' t collide when the collision happened while moving up .
* @ property { object } checkCollision - An object containing allowed collision .
2013-10-25 15:54:40 +00:00
* /
2014-01-23 21:45:35 +00:00
this . checkCollision = { 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-23 21:45:35 +00:00
this . polygons = new SAT . Box ( new SAT . Vector ( this . x , this . y ) , this . width , this . height ) . toPolygon ( ) ;
this . response = new SAT . Response ( ) ;
// this.vx;
// this.vy;
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 ) ;
2014-01-23 21:45:35 +00:00
// Scale by the difference between this and what it was previously
this . polygons . scale ( scaleX / this . _sx , scaleY / this . _sy ) ;
2014-01-21 16:12:50 +00:00
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-23 21:45:35 +00:00
// this.touching.none = true;
// this.touching.up = false;
// this.touching.down = false;
// this.touching.left = false;
// this.touching.right = false;
2014-01-22 16:16:53 +00:00
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 ) ;
2014-01-23 21:45:35 +00:00
2014-01-22 14:31:18 +00:00
this . applyMotion ( ) ;
2014-01-22 10:54:49 +00:00
}
2014-01-23 21:45:35 +00:00
this . polygons . pos . x = this . x ;
this . polygons . pos . y = this . y ;
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-23 01:50:43 +00:00
this . touching . 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-23 01:50:43 +00:00
this . touching . 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-23 01:50:43 +00:00
this . touching . 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-23 01:50:43 +00:00
this . touching . down = true ;
2014-01-22 10:54:49 +00:00
}
} ,
2014-01-23 21:45:35 +00:00
/ * *
* Internal method used to check the Body against the World Bounds .
*
* @ method Phaser . Physics . Arcade # checkWorldBounds
* @ protected
* /
NEWcheckWorldBounds : function ( ) {
this . blockedPoint . setTo ( 0 , 0 ) ;
if ( this . x < this . game . world . bounds . x )
{
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 ;
}
// overlapX/Y values at this point will be penetration into the bounds and DELTA WILL BE ZERO
if ( this . blocked . left && this . blockedPoint . x > 0 )
{
// Separate
this . x += this . blockedPoint . x ;
this . velocity . x *= - this . bounce . x ;
// this.reboundCheck(true, false);
}
else if ( this . blocked . right && this . blockedPoint . x > 0 )
{
// Separate
this . x -= this . blockedPoint . x ;
this . velocity . x *= - this . bounce . x ;
// this.reboundCheck(true, false);
}
else
{
this . x += this . game . time . physicsElapsed * ( this . velocity . x + this . motionVelocity . x / 2 ) ;
this . velocity . x += this . motionVelocity . x ;
}
// overlapX/Y values at this point will be penetration into the bounds and DELTA WILL BE ZERO
if ( this . blocked . up && this . blockedPoint . y > 0 )
{
// Separate
this . y += this . blockedPoint . y ;
this . velocity . y *= - this . bounce . y ;
// this.reboundCheck(false, true);
}
else if ( this . blocked . down && this . blockedPoint . y > 0 )
{
// Separate
this . y -= this . blockedPoint . y ;
this . velocity . y *= - this . bounce . y ;
// this.reboundCheck(false, true);
}
else
{
this . y += this . game . time . physicsElapsed * ( this . velocity . y + this . motionVelocity . y / 2 ) ;
this . velocity . y += this . motionVelocity . y ;
}
this . polygons . pos . x = this . x ;
this . polygons . pos . y = this . y ;
} ,
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 ;
2014-01-23 01:50:43 +00:00
this . reboundCheck ( true , false ) ;
2014-01-15 14:21:06 +00:00
this . _dx = this . game . time . physicsElapsed * ( this . velocity . x + this . motionVelocity . x / 2 ) ;
2014-01-23 01:50:43 +00:00
if ( this . _dx > this . minBounceVelocity || this . getTotalGravityX ( ) > 0 )
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-23 01:50:43 +00:00
this . preX = this . x ;
2014-01-15 13:20:51 +00:00
this . velocity . 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 ;
2014-01-23 01:50:43 +00:00
this . reboundCheck ( true , false ) ;
2014-01-15 14:21:06 +00:00
this . _dx = this . game . time . physicsElapsed * ( this . velocity . x + this . motionVelocity . x / 2 ) ;
2014-01-23 01:50:43 +00:00
if ( this . _dx < - this . minBounceVelocity || this . getTotalGravityX ( ) < 0 )
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-23 01:50:43 +00:00
this . preX = this . x ;
2014-01-15 13:20:51 +00:00
this . velocity . 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-23 01:50:43 +00:00
this . reboundCheck ( false , true ) ;
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-23 01:50:43 +00:00
if ( this . _dy > this . minBounceVelocity || this . getTotalGravityY ( ) > 0 )
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-23 01:50:43 +00:00
this . preY = this . y ;
2014-01-15 13:20:51 +00:00
this . velocity . 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 ;
2014-01-23 01:50:43 +00:00
this . reboundCheck ( false , true ) ;
2014-01-15 14:21:06 +00:00
this . _dy = this . game . time . physicsElapsed * ( this . velocity . y + this . motionVelocity . y / 2 ) ;
2014-01-15 13:20:51 +00:00
2014-01-23 01:50:43 +00:00
if ( this . _dy < - this . minBounceVelocity || this . getTotalGravityY ( ) < 0 )
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-23 01:50:43 +00:00
this . preY = this . y ;
2014-01-15 13:20:51 +00:00
this . velocity . 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
}
2014-01-23 21:45:35 +00:00
this . polygons . pos . x = this . x ;
this . polygons . pos . y = this . y ;
2013-11-25 04:40:04 +00:00
} ,
2013-09-23 00:06:09 +00:00
2014-01-22 16:16:53 +00:00
/ * *
2014-01-23 21:45:35 +00:00
* Checks for an overlap between this Body and the given Body , taking into account the checkCollision flags on both bodies .
2014-01-22 16:16:53 +00:00
* 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 ) {
2014-01-23 21:45:35 +00:00
// var r = new Phaser.Rectangle();
// This gives us our area of intersection (width / height)
// Phaser.Rectangle.intersection(this, body, r);
/ *
2014-01-21 16:12:50 +00:00
this . overlapX = 0 ;
this . overlapY = 0 ;
2014-01-23 21:45:35 +00:00
if ( this . x < body . x && this . checkCollision . right && body . checkCollision . left )
2014-01-21 16:12:50 +00:00
{
// Negative = body touched this one on the right face
2014-01-23 21:45:35 +00:00
console . log ( 'Negative = body touched this one on the right face' ) ;
2014-01-21 16:12:50 +00:00
this . overlapX = body . x - this . right ;
this . touching . right = true ;
}
2014-01-23 21:45:35 +00:00
else if ( this . x > body . x && this . checkCollision . left && body . checkCollision . right )
2014-01-21 16:12:50 +00:00
{
// Positive means body touched this one on the left face
2014-01-23 21:45:35 +00:00
console . log ( 'Positive means body touched this one on the left face' ) ;
2014-01-21 16:12:50 +00:00
this . overlapX = body . right - this . x ;
this . touching . left = true ;
}
2014-01-23 21:45:35 +00:00
if ( this . y < body . y && this . checkCollision . down && body . checkCollision . up )
2014-01-21 16:12:50 +00:00
{
// Negative = body touched this one on the bottom face
this . overlapY = body . y - this . bottom ;
this . touching . down = true ;
}
2014-01-23 21:45:35 +00:00
else if ( this . y > body . y && this . checkCollision . up && body . checkCollision . down )
2014-01-21 16:12:50 +00:00
{
// Positive means body touched this one on the top face
this . overlapY = body . bottom - this . y ;
this . touching . up = true ;
}
2014-01-23 21:45:35 +00:00
* /
/ *
var ax = this . deltaX ( ) ;
var bx = body . deltaX ( ) ;
var check = Phaser . NONE ;
// if (ax <= 0 && bx < 0)
// {
// check = Phaser.RIGHT;
// }
if ( ax <= 0 && bx < 0 )
{
// This is stationary (or moving left) and Body is moving left
if ( this . x <= body . x )
{
// Body entering right side of This
if ( this . checkCollision . right )
{
this . overlapX = - r . width ;
this . touching . right = true ;
}
if ( body . checkCollision . left )
{
body . touching . left = true ;
}
}
}
else if ( ax <= 0 && bx > 0 )
{
// This is stationary (or moving left) and Body is moving right
if ( this . x >= body . x )
{
// Body entering left side of This
if ( this . checkCollision . left )
{
this . overlapX = r . width ;
this . touching . left = true ;
}
if ( body . checkCollision . right )
{
body . touching . right = true ;
}
}
}
else if ( ax > 0 && bx < 0 )
{
// This is moving right and Body is moving left
if ( this . x <= body . x )
{
// Body entering right side of This
if ( this . checkCollision . right )
{
this . overlapX = - r . width ;
this . touching . right = true ;
}
if ( body . checkCollision . left )
{
body . touching . left = true ;
}
}
}
else if ( ax > 0 && bx > 0 )
{
// This is moving right and Body is moving right
if ( this . x >= body . x )
{
// Body entering left side of This
if ( this . checkCollision . left )
{
this . overlapX = r . width ;
this . touching . left = true ;
}
if ( body . checkCollision . right )
{
body . touching . right = true ;
}
}
}
* /
this . response . clear ( ) ;
return SAT . testPolygonPolygon ( this . polygons , body . polygons , this . response ) ;
// console.log(this.overlapX, r.width);
// console.log(r);
2014-01-21 16:12:50 +00:00
// Which is the largest?
2014-01-23 21:45:35 +00:00
/ *
2014-01-21 16:12:50 +00:00
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-23 21:45:35 +00:00
* /
2014-01-21 16:12:50 +00:00
} ,
2014-01-23 21:45:35 +00:00
/ * *
* Check if we 're below minVelocity and gravity isn' t trying to drag us in the opposite direction .
*
* @ method Phaser . Physics . Arcade # reboundCheck
* @ protected
* @ param { boolean } x - Check the X axis ?
* @ param { boolean } y - Check the Y axis ?
* /
2014-01-23 01:50:43 +00:00
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 ;
}
}
} ,
2014-01-23 21:45:35 +00:00
/ * *
* Gets the total gravity to be applied on the X axis .
*
* @ method Phaser . Physics . Arcade # getTotalGravityX
* @ protected
* @ return { number } The total gravity to be applied on the X axis .
* /
2014-01-23 01:50:43 +00:00
getTotalGravityX : function ( ) {
if ( this . allowGravity )
{
return this . gravity . x + this . game . physics . gravity . x ;
}
else
{
return this . gravity . x ;
}
} ,
2014-01-23 21:45:35 +00:00
/ * *
* Gets the total gravity to be applied on the Y axis .
*
* @ method Phaser . Physics . Arcade # getTotalGravityY
* @ protected
* @ return { number } The total gravity to be applied on the Y axis .
* /
2014-01-23 01:50:43 +00:00
getTotalGravityY : function ( ) {
if ( this . allowGravity )
{
return this . gravity . y + this . game . physics . gravity . y ;
}
else
{
return this . gravity . y ;
}
} ,
2014-01-23 21:45:35 +00:00
hitLeft : function ( body , response ) {
// This body isn't moving horizontally, so it was hit by something moving right
if ( this . immovable || this . blocked . right )
{
body . add ( response . overlapV ) ;
body . velocity . x = this . velocity . x - body . velocity . x * body . bounce . x ;
body . velocity . y = this . velocity . y - body . velocity . y * body . bounce . y ;
body . reboundCheck ( true , true ) ;
}
else
{
if ( body . immovable || body . blocked . left )
{
// We take the full separation as what hit is isn't moveable
this . sub ( response . overlapV ) ;
this . velocity . x = body . velocity . x - this . velocity . x * this . bounce . x ;
this . velocity . y = body . velocity . y - this . velocity . y * this . bounce . y ;
this . reboundCheck ( true , true ) ;
}
else
{
response . overlapV . scale ( 0.5 ) ;
this . sub ( response . overlapV ) ;
body . add ( response . overlapV ) ;
// this.reboundCheck(true, false);
// body.reboundCheck(true, false);
var tempVX = body . velocity . x ;
var tempVY = body . velocity . y ;
body . velocity . x = this . velocity . x * body . bounce . x ;
body . velocity . y = this . velocity . y * body . bounce . x ;
this . velocity . x = tempVX * this . bounce . x ;
this . velocity . y = tempVY * this . bounce . y ;
this . reboundCheck ( true , true ) ;
body . reboundCheck ( true , false ) ;
this . acceleration . setTo ( 0 , 0 ) ;
body . acceleration . setTo ( 0 , 0 ) ;
}
}
// 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 ;
}
if ( this . collideCallback )
{
this . collideCallback . call ( this . collideCallbackContext , Phaser . LEFT , this , body ) ;
}
} ,
hitRight : function ( body , response ) {
// This body isn't moving horizontally, so it was hit by something moving right
if ( this . immovable || this . blocked . left )
{
body . add ( response . overlapV ) ;
body . velocity . x = this . velocity . x - body . velocity . x * body . bounce . x ;
body . velocity . y = this . velocity . y - body . velocity . y * body . bounce . y ;
body . reboundCheck ( true , true ) ;
}
else
{
if ( body . immovable || body . blocked . right )
{
// We take the full separation as what hit is isn't moveable
this . sub ( response . overlapV ) ;
this . velocity . x = body . velocity . x - this . velocity . x * this . bounce . x ;
this . velocity . y = body . velocity . y - this . velocity . y * this . bounce . y ;
this . reboundCheck ( true , true ) ;
}
else
{
response . overlapV . scale ( 0.5 ) ;
this . sub ( response . overlapV ) ;
body . add ( response . overlapV ) ;
// this.reboundCheck(true, false);
// body.reboundCheck(true, false);
var tempVX = body . velocity . x ;
var tempVY = body . velocity . y ;
body . velocity . x = this . velocity . x * body . bounce . x ;
body . velocity . y = this . velocity . y * body . bounce . x ;
this . velocity . x = tempVX * this . bounce . x ;
this . velocity . y = tempVY * this . bounce . y ;
this . reboundCheck ( true , true ) ;
body . reboundCheck ( true , false ) ;
this . acceleration . setTo ( 0 , 0 ) ;
body . acceleration . setTo ( 0 , 0 ) ;
}
}
// 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 ;
}
if ( this . collideCallback )
{
this . collideCallback . call ( this . collideCallbackContext , Phaser . RIGHT , this , body ) ;
}
} ,
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-23 21:45:35 +00:00
XhitLeft : function ( x , body , nv1 , nv2 , avg ) {
2014-01-21 16:12:50 +00:00
// 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 ;
2014-01-23 01:50:43 +00:00
body . reboundCheck ( true , false ) ;
2014-01-21 16:12:50 +00:00
}
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-23 01:50:43 +00:00
this . reboundCheck ( true , false ) ;
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
2014-01-23 01:50:43 +00:00
this . reboundCheck ( true , false ) ;
body . reboundCheck ( true , false ) ;
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-23 21:45:35 +00:00
XhitRight : function ( x , body , nv1 , nv2 , avg ) {
2014-01-21 16:12:50 +00:00
// 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 ;
2014-01-23 01:50:43 +00:00
body . reboundCheck ( true , false ) ;
2014-01-21 16:12:50 +00:00
}
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-23 01:50:43 +00:00
this . reboundCheck ( true , false ) ;
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-23 01:50:43 +00:00
this . reboundCheck ( true , false ) ;
body . reboundCheck ( true , false ) ;
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-23 21:45:35 +00:00
XhitUp : function ( y , body , nv1 , nv2 , avg ) {
2014-01-21 16:12:50 +00:00
// 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 ;
2014-01-23 01:50:43 +00:00
body . reboundCheck ( true , false ) ;
2014-01-21 16:12:50 +00:00
}
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-23 01:50:43 +00:00
this . reboundCheck ( false , true ) ;
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-23 01:50:43 +00:00
this . reboundCheck ( false , true ) ;
body . reboundCheck ( true , false ) ;
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-23 21:45:35 +00:00
XhitDown : function ( y , body , nv1 , nv2 , avg ) {
2014-01-21 16:12:50 +00:00
// 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 ;
2014-01-23 01:50:43 +00:00
body . reboundCheck ( true , false ) ;
2014-01-21 16:12:50 +00:00
}
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-23 01:50:43 +00:00
this . reboundCheck ( false , true ) ;
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-23 01:50:43 +00:00
this . reboundCheck ( false , true ) ;
body . reboundCheck ( true , false ) ;
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-23 21:45:35 +00:00
sub : function ( v ) {
this . x -= v . x ;
this . y -= v . y ;
} ,
add : function ( v ) {
this . x += v . x ;
this . y += v . y ;
} ,
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
2014-01-23 21:45:35 +00:00
// if (this.immovable && body.immovable)
// {
// this.response.overlapV.scale(0.5);
// this.sub(this.response.overlapV);
// body.add(this.response.overlapV);
// }
// Move equally out of each other
// console.log(this.response);
// angle of collision
// var dx = this.x - body.x;
// var dy = this.y - body.y;
// var collision_angle = Math.atan2(dy, dx);
// var sin = Math.sin(collision_angle);
// var cos = Math.sin(collision_angle);
// var sin2 = Math.sin(collision_angle + Math.PI / 2);
// var cos2 = Math.sin(collision_angle + Math.PI / 2);
var distances = [
( body . right - this . x ) , // distance of box 'b' to face on 'left' side of 'a'.
( this . right - body . x ) , // distance of box 'b' to face on 'right' side of 'a'.
( body . bottom - this . y ) , // distance of box 'b' to face on 'bottom' side of 'a'.
( this . bottom - body . y ) // distance of box 'b' to face on 'top' side of 'a'.
] ;
// console.log('angle of collision', collision_angle, this.game.math.radToDeg(collision_angle), this.response);
// console.log(distances);
if ( this . response . overlapN . x )
{
// Which is smaller? Left or Right?
if ( distances [ 0 ] < distances [ 1 ] )
{
console . log ( this . sprite . name , 'collided on the LEFT with' , body . sprite . name ) ;
this . hitLeft ( body , this . response ) ;
}
else if ( distances [ 1 ] < distances [ 0 ] )
{
console . log ( this . sprite . name , 'collided on the RIGHT with' , body . sprite . name ) ;
this . hitRight ( body , this . response ) ;
}
}
else if ( this . response . overlapN . y )
{
// Which is smaller? Top or Bottom?
if ( distances [ 2 ] < distances [ 3 ] )
{
console . log ( this . sprite . name , 'collided on the TOP with' , body . sprite . name ) ;
this . touching . up = true ;
body . touching . down = true ;
}
else if ( distances [ 3 ] < distances [ 2 ] )
{
console . log ( this . sprite . name , 'collided on the BOTTOM with' , body . sprite . name ) ;
this . touching . down = true ;
body . touching . up = true ;
}
}
return true ;
// this.response.overlapV.scale(0.5);
// this.x -= this.response.overlapV.x;
// this.y -= this.response.overlapV.y;
// body.x += this.response.overlapV.x;
// body.y += this.response.overlapV.y;
// this.polygons.pos.x = this.x;
// this.polygons.pos.y = this.y;
// body.polygons.pos.x = body.x;
// body.polygons.pos.y = body.y;
// var tempVX = body.velocity.x;
// var tempVY = body.velocity.y;
// body.velocity.x = this.velocity.x * body.bounce.x;
// body.velocity.y = this.velocity.y * body.bounce.x;
// this.velocity.x = tempVX * this.bounce.x;
// this.velocity.y = tempVY * this.bounce.y;
// this.reboundCheck(true, true);
// this.acceleration.setTo(0, 0);
// body.acceleration.setTo(0, 0);
/ *
Find the positions right before the collision . You are already approximating this by : "finding the shortest penetration vector and adding it to the AABB's position."
Find the velocities right after the collision using Newtonian physics :
For the case where mass is hard - coded as 1 , simply swap the velocities ( this does not apply to static objects which must have infinite mass ) :
A . v = B . u
B . v = A . u
If objects A and B have different masses :
A . v = ( A . u * ( A . m - B . m ) + ( 2 * B . m * B . u ) ) / ( A . m + B . m )
B . v = ( B . u * ( B . m - A . m ) + ( 2 * A . m * A . u ) ) / ( A . m + B . m )
where :
v : velocity after collision
u : velocity before collision
m : mass ( use the largest number possible for the mass of a fixed , static object )
Set acceleration to 0 : The acceleration from the collision was accounted for above by the velocity calculations in step number 2.
* /
/ *
var vx _1 = this . speed * Math . cos ( this . angle - collision _angle ) ;
var vy _1 = this . speed * Math . sin ( this . angle - collision _angle ) ;
var vx _2 = body . speed * Math . cos ( body . angle - collision _angle ) ;
var vy _2 = body . speed * Math . sin ( body . angle - collision _angle ) ;
var final _vx _1 = ( ( this . mass - body . mass ) * vx _1 + ( body . mass + body . mass ) * vx _2 ) / ( this . mass + body . mass ) ;
var final _vx _2 = ( ( this . mass + this . mass ) * vx _1 + ( body . mass - this . mass ) * vx _2 ) / ( this . mass + body . mass ) ;
var final _vy _1 = vy _1 ;
var final _vy _2 = vy _2
this . velocity . x = ( cos * final _vx _1 + cos2 * final _vy _1 ) ;
this . velocity . y = ( sin * final _vx _1 + sin2 * final _vy _1 ) ;
body . velocity . x = ( cos * final _vx _2 + cos2 * final _vy _2 ) ;
body . velocity . y = ( sin * final _vx _2 + sin2 * final _vy _2 ) ;
// this.velocity.x = (cos * final_vx_1 + cos2 * final_vy_1) * this.bounce.x;
// this.velocity.y = (sin * final_vx_1 + sin2 * final_vy_1) * this.bounce.y;
// body.velocity.x = (cos * final_vx_2 + cos2 * final_vy_2) * body.bounce.x;
// body.velocity.y = (sin * final_vx_2 + sin2 * final_vy_2) * body.bounce.y;
// this.velocity.x = (Math.cos(collision_angle) * final_vx_1 + Math.cos(collision_angle + Math.PI/2) * final_vy_1) * this.bounce.x;
// this.velocity.y = (Math.sin(collision_angle) * final_vx_1 + Math.sin(collision_angle + Math.PI/2) * final_vy_1) * this.bounce.y;
// body.velocity.x = (Math.cos(collision_angle) * final_vx_2 + Math.cos(collision_angle + Math.PI/2) * final_vy_2) * body.bounce.x;
// body.velocity.y = (Math.sin(collision_angle) * final_vx_2 + Math.sin(collision_angle + Math.PI/2) * final_vy_2) * body.bounce.y;
// this.sub(response.overlapV);
// body.add(response.overlapV);
* /
/ *
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-23 21:45:35 +00:00
* /
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-23 21:45:35 +00:00
// this.applyMotion();
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
} ) ;