phaser/src/physics/impact/Body.js

614 lines
15 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
2017-06-21 23:47:35 +00:00
var Class = require('../../utils/Class');
var COLLIDES = require('./COLLIDES');
var GetVelocity = require('./GetVelocity');
2017-06-21 23:47:35 +00:00
var TYPE = require('./TYPE');
var UpdateMotion = require('./UpdateMotion');
2017-06-21 23:47:35 +00:00
2018-03-19 20:42:07 +00:00
/**
* @callback BodyUpdateCallback
*
* @param {Phaser.Physics.Impact.Body} body - [description]
*/
2018-03-21 13:15:25 +00:00
/**
* @typedef {object} JSONImpactBody
* @todo Replace object types
*
* @property {string} name - [description]
* @property {object} size - [description]
* @property {object} pos - [description]
* @property {object} vel - [description]
* @property {object} accel - [description]
* @property {object} friction - [description]
* @property {object} maxVel - [description]
* @property {number} gravityFactor - [description]
* @property {number} bounciness - [description]
* @property {number} minBounceVelocity - [description]
* @property {Phaser.Physics.Impact.TYPE} type - [description]
* @property {Phaser.Physics.Impact.TYPE} checkAgainst - [description]
* @property {Phaser.Physics.Impact.COLLIDES} collides - [description]
*/
2017-06-21 23:47:35 +00:00
/**
2018-02-09 15:23:33 +00:00
* @classdesc
* An Impact.js compatible physics body.
* This re-creates the properties you'd get on an Entity and the math needed to update them.
*
* @class Body
2018-10-10 09:49:13 +00:00
* @memberof Phaser.Physics.Impact
2018-02-09 15:23:33 +00:00
* @constructor
* @since 3.0.0
*
* @param {Phaser.Physics.Impact.World} world - [description]
* @param {number} x - [description]
* @param {number} y - [description]
* @param {number} [sx=16] - [description]
* @param {number} [sy=16] - [description]
*/
2017-06-21 23:47:35 +00:00
var Body = new Class({
initialize:
2017-06-22 01:40:10 +00:00
function Body (world, x, y, sx, sy)
2017-06-21 23:47:35 +00:00
{
2017-06-22 01:40:10 +00:00
if (sx === undefined) { sx = 16; }
if (sy === undefined) { sy = sx; }
2017-06-22 01:40:10 +00:00
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#world
* @type {Phaser.Physics.Impact.World}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.world = world;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#gameObject
* @type {Phaser.GameObjects.GameObject}
* @default null
* @since 3.0.0
*/
this.gameObject = null;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#enabled
* @type {boolean}
* @default true
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.enabled = true;
2018-02-09 15:23:33 +00:00
/**
2018-02-09 16:04:43 +00:00
* The ImpactBody, ImpactSprite or ImpactImage object that owns this Body, if any.
2018-02-09 15:23:33 +00:00
*
* @name Phaser.Physics.Impact.Body#parent
2018-03-20 14:36:03 +00:00
* @type {?(Phaser.Physics.Impact.ImpactBody|Phaser.Physics.Impact.ImpactImage|Phaser.Physics.Impact.ImpactSprite)}
2018-02-09 15:23:33 +00:00
* @since 3.0.0
*/
this.parent;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#id
* @type {integer}
* @since 3.0.0
*/
this.id = world.getNextID();
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#name
* @type {string}
* @default ''
* @since 3.0.0
*/
this.name = '';
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#size
* @type {{x: number, y: number}}
* @since 3.0.0
*/
2017-06-22 01:40:10 +00:00
this.size = { x: sx, y: sy };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#offset
* @type {{x: number, y: number}}
* @since 3.0.0
*/
this.offset = { x: 0, y: 0 };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#pos
* @type {{x: number, y: number}}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.pos = { x: x, y: y };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#last
* @type {{x: number, y: number}}
* @since 3.0.0
*/
this.last = { x: x, y: y };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#vel
* @type {{x: number, y: number}}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.vel = { x: 0, y: 0 };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#accel
* @type {{x: number, y: number}}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.accel = { x: 0, y: 0 };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#friction
* @type {{x: number, y: number}}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.friction = { x: 0, y: 0 };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#maxVel
* @type {{x: number, y: number}}
* @since 3.0.0
*/
this.maxVel = { x: world.defaults.maxVelocityX, y: world.defaults.maxVelocityY };
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#standing
* @type {boolean}
* @default false
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.standing = false;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#gravityFactor
* @type {number}
* @since 3.0.0
*/
this.gravityFactor = world.defaults.gravityFactor;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#bounciness
* @type {number}
* @since 3.0.0
*/
this.bounciness = world.defaults.bounciness;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#minBounceVelocity
* @type {number}
* @since 3.0.0
*/
this.minBounceVelocity = world.defaults.minBounceVelocity;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#accelGround
* @type {number}
* @default 0
* @since 3.0.0
*/
this.accelGround = 0;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#accelAir
* @type {number}
* @default 0
* @since 3.0.0
*/
this.accelAir = 0;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#jumpSpeed
* @type {number}
* @default 0
* @since 3.0.0
*/
this.jumpSpeed = 0;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#type
* @type {Phaser.Physics.Impact.TYPE}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.type = TYPE.NONE;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#checkAgainst
* @type {Phaser.Physics.Impact.TYPE}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.checkAgainst = TYPE.NONE;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#collides
* @type {Phaser.Physics.Impact.COLLIDES}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.collides = COLLIDES.NEVER;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#debugShowBody
* @type {boolean}
* @since 3.0.0
*/
this.debugShowBody = world.defaults.debugShowBody;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#debugShowVelocity
* @type {boolean}
* @since 3.0.0
*/
this.debugShowVelocity = world.defaults.debugShowVelocity;
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#debugBodyColor
* @type {integer}
* @since 3.0.0
*/
this.debugBodyColor = world.defaults.bodyDebugColor;
2017-08-17 02:15:02 +00:00
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @name Phaser.Physics.Impact.Body#updateCallback
2018-03-19 20:42:07 +00:00
* @type {?BodyUpdateCallback}
2018-02-09 15:23:33 +00:00
* @since 3.0.0
*/
2017-08-17 02:15:02 +00:00
this.updateCallback;
2018-03-18 23:42:09 +00:00
2018-02-09 15:23:33 +00:00
/**
* min 44 deg, max 136 deg
*
* @name Phaser.Physics.Impact.Body#slopeStanding
* @type {{ min: number, max: number }}
* @since 3.0.0
*/
2017-06-21 23:47:35 +00:00
this.slopeStanding = { min: 0.767944870877505, max: 2.3736477827122884 };
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#reset
* @since 3.0.0
*
* @param {number} x - [description]
* @param {number} y - [description]
*/
2017-08-16 15:30:38 +00:00
reset: function (x, y)
{
2017-08-16 15:30:38 +00:00
this.pos = { x: x, y: y };
this.last = { x: x, y: y };
this.vel = { x: 0, y: 0 };
this.accel = { x: 0, y: 0 };
this.friction = { x: 0, y: 0 };
this.maxVel = { x: 100, y: 100 };
this.standing = false;
this.gravityFactor = 1;
this.bounciness = 0;
this.minBounceVelocity = 40;
this.accelGround = 0;
this.accelAir = 0;
this.jumpSpeed = 0;
2018-03-18 23:42:09 +00:00
2017-08-16 15:30:38 +00:00
this.type = TYPE.NONE;
this.checkAgainst = TYPE.NONE;
this.collides = COLLIDES.NEVER;
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#update
* @since 3.0.0
*
2018-09-13 07:09:44 +00:00
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
2018-02-09 15:23:33 +00:00
*/
update: function (delta)
2017-06-21 23:47:35 +00:00
{
var pos = this.pos;
this.last.x = pos.x;
this.last.y = pos.y;
2017-06-21 23:47:35 +00:00
this.vel.y += this.world.gravity * delta * this.gravityFactor;
2018-03-18 23:42:09 +00:00
this.vel.x = GetVelocity(delta, this.vel.x, this.accel.x, this.friction.x, this.maxVel.x);
this.vel.y = GetVelocity(delta, this.vel.y, this.accel.y, this.friction.y, this.maxVel.y);
2018-03-18 23:42:09 +00:00
2017-06-21 23:47:35 +00:00
var mx = this.vel.x * delta;
var my = this.vel.y * delta;
var res = this.world.collisionMap.trace(pos.x, pos.y, mx, my, this.size.x, this.size.y);
2017-06-21 23:47:35 +00:00
if (this.handleMovementTrace(res))
{
UpdateMotion(this, res);
}
2017-06-23 17:08:22 +00:00
var go = this.gameObject;
if (go)
2017-06-23 17:08:22 +00:00
{
go.x = (pos.x - this.offset.x) + go.displayOriginX * go.scaleX;
go.y = (pos.y - this.offset.y) + go.displayOriginY * go.scaleY;
2017-06-23 17:08:22 +00:00
}
if (this.updateCallback)
{
this.updateCallback(this);
}
},
2017-08-17 02:15:02 +00:00
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#drawDebug
* @since 3.0.0
*
* @param {Phaser.GameObjects.Graphics} graphic - [description]
*/
drawDebug: function (graphic)
{
var pos = this.pos;
if (this.debugShowBody)
2017-08-17 02:15:02 +00:00
{
graphic.lineStyle(1, this.debugBodyColor, 1);
graphic.strokeRect(pos.x, pos.y, this.size.x, this.size.y);
2017-08-17 02:15:02 +00:00
}
if (this.debugShowVelocity)
{
var x = pos.x + this.size.x / 2;
var y = pos.y + this.size.y / 2;
graphic.lineStyle(1, this.world.defaults.velocityDebugColor, 1);
graphic.lineBetween(x, y, x + this.vel.x, y + this.vel.y);
}
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#willDrawDebug
* @since 3.0.0
*
* @return {boolean} [description]
*/
willDrawDebug: function ()
{
return (this.debugShowBody || this.debugShowVelocity);
2017-06-21 23:47:35 +00:00
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#skipHash
* @since 3.0.0
*
* @return {boolean} [description]
*/
2017-06-21 23:47:35 +00:00
skipHash: function ()
{
return (!this.enabled || (this.type === 0 && this.checkAgainst === 0 && this.collides === 0));
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#touches
* @since 3.0.0
*
* @param {Phaser.Physics.Impact.Body} other - [description]
*
* @return {boolean} [description]
*/
2017-06-21 23:47:35 +00:00
touches: function (other)
{
return !(
this.pos.x >= other.pos.x + other.size.x ||
this.pos.x + this.size.x <= other.pos.x ||
this.pos.y >= other.pos.y + other.size.y ||
this.pos.y + this.size.y <= other.pos.y
);
},
2018-02-09 15:23:33 +00:00
/**
2018-09-28 11:19:21 +00:00
* Reset the size and position of the physics body.
2018-02-09 15:23:33 +00:00
*
* @method Phaser.Physics.Impact.Body#resetSize
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {number} x - The x coordinate to position the body.
* @param {number} y - The y coordinate to position the body.
* @param {number} width - The width of the body.
* @param {number} height - The height of the body.
2018-02-09 15:23:33 +00:00
*
* @return {Phaser.Physics.Impact.Body} This Body object.
*/
resetSize: function (x, y, width, height)
2017-06-21 23:47:35 +00:00
{
2017-08-17 00:20:40 +00:00
this.pos.x = x;
this.pos.y = y;
this.size.x = width;
this.size.y = height;
2017-06-21 23:47:35 +00:00
return this;
},
2018-02-09 15:23:33 +00:00
/**
2018-10-19 11:32:43 +00:00
* Export this body object to JSON.
2018-02-09 15:23:33 +00:00
*
* @method Phaser.Physics.Impact.Body#toJSON
* @since 3.0.0
*
2018-10-19 11:32:43 +00:00
* @return {JSONImpactBody} JSON representation of this body object.
2018-02-09 15:23:33 +00:00
*/
toJSON: function ()
{
var output = {
name: this.name,
size: { x: this.size.x, y: this.size.y },
pos: { x: this.pos.x, y: this.pos.y },
vel: { x: this.vel.x, y: this.vel.y },
accel: { x: this.accel.x, y: this.accel.y },
friction: { x: this.friction.x, y: this.friction.y },
maxVel: { x: this.maxVel.x, y: this.maxVel.y },
gravityFactor: this.gravityFactor,
bounciness: this.bounciness,
minBounceVelocity: this.minBounceVelocity,
type: this.type,
checkAgainst: this.checkAgainst,
collides: this.collides
};
return output;
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#fromJSON
2018-02-09 16:52:08 +00:00
* @todo Code it!
2018-02-09 15:23:33 +00:00
* @since 3.0.0
*
* @param {object} config - [description]
*/
2018-02-16 18:44:07 +00:00
fromJSON: function ()
{
},
2018-02-09 15:23:33 +00:00
/**
* Can be overridden by user code
*
* @method Phaser.Physics.Impact.Body#check
* @since 3.0.0
*
2018-02-16 18:44:07 +00:00
* @param {Phaser.Physics.Impact.Body} other - [description]
2018-02-09 15:23:33 +00:00
*/
2018-02-16 18:44:07 +00:00
check: function ()
{
},
2017-06-21 23:47:35 +00:00
2018-02-09 15:23:33 +00:00
/**
* Can be overridden by user code
*
* @method Phaser.Physics.Impact.Body#collideWith
* @since 3.0.0
*
* @param {Phaser.Physics.Impact.Body} other - [description]
2018-03-18 23:42:09 +00:00
* @param {string} axis - [description]
2018-02-09 15:23:33 +00:00
*/
collideWith: function (other, axis)
{
if (this.parent && this.parent._collideCallback)
{
this.parent._collideCallback.call(this.parent._callbackScope, this, other, axis);
}
2017-08-16 15:30:38 +00:00
},
2018-02-09 15:23:33 +00:00
/**
* Can be overridden by user code but must return a boolean.
*
* @method Phaser.Physics.Impact.Body#handleMovementTrace
* @since 3.0.0
*
2018-03-19 13:45:00 +00:00
* @param {number} res - [description]
2018-02-09 15:23:33 +00:00
*
* @return {boolean} [description]
*/
2018-02-16 19:17:49 +00:00
handleMovementTrace: function ()
2017-08-16 15:30:38 +00:00
{
return true;
},
2018-02-09 15:23:33 +00:00
/**
* [description]
*
* @method Phaser.Physics.Impact.Body#destroy
* @since 3.0.0
*/
2017-08-16 15:30:38 +00:00
destroy: function ()
{
this.world.remove(this);
2017-08-16 15:30:38 +00:00
this.enabled = false;
this.world = null;
this.gameObject = null;
this.parent = null;
}
2017-06-21 23:47:35 +00:00
});
module.exports = Body;