mirror of
https://github.com/wassname/phaser.git
synced 2026-07-02 17:00:42 +08:00
n-way collision checks and onBeginContact and onEndContact done and working. Also fixed issue in TweenManager.removeAll.
This commit is contained in:
+1
-2
@@ -49,8 +49,7 @@ Phaser.Group = function (game, parent, name, useStage) {
|
||||
{
|
||||
if (parent instanceof Phaser.Group)
|
||||
{
|
||||
parent._container.addChild(this._container);
|
||||
parent._container.updateTransform();
|
||||
parent.add(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
Phaser.Events = function (sprite) {
|
||||
|
||||
this.parent = sprite;
|
||||
|
||||
this.onAddedToGroup = new Phaser.Signal();
|
||||
this.onRemovedFromGroup = new Phaser.Signal();
|
||||
this.onKilled = new Phaser.Signal();
|
||||
@@ -41,6 +42,9 @@ Phaser.Events = function (sprite) {
|
||||
this.onAnimationComplete = null;
|
||||
this.onAnimationLoop = null;
|
||||
|
||||
this.onBeginContact = null;
|
||||
this.onEndContact = null;
|
||||
|
||||
};
|
||||
|
||||
Phaser.Events.prototype = {
|
||||
|
||||
@@ -934,6 +934,11 @@ Phaser.Sprite.prototype.destroy = function() {
|
||||
this.animations.destroy();
|
||||
}
|
||||
|
||||
if (this.body)
|
||||
{
|
||||
this.body.destroy();
|
||||
}
|
||||
|
||||
this.alive = false;
|
||||
this.exists = false;
|
||||
this.visible = false;
|
||||
|
||||
@@ -397,12 +397,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||
// pos = pos + dt*(vel + temp/2)
|
||||
// vel = vel + temp
|
||||
|
||||
if (body.sprite.debug)
|
||||
{
|
||||
console.log('updateMotion: acx', body.acceleration.x, 'acy', body.acceleration.y, 'gravx', this._gravityX, 'gravy', this._gravityY, 'elapsed', this.game.time.physicsElapsed);
|
||||
// console.log('updateMotion: rotation', body.rotation, 'vd', this._velocityDelta, 'drag', this._drag, 'acceleration', body.angularAcceleration);
|
||||
}
|
||||
|
||||
this._p.setTo((body.acceleration.x + this._gravityX) * this.game.time.physicsElapsed, (body.acceleration.y + this._gravityY) * this.game.time.physicsElapsed);
|
||||
|
||||
return this._p;
|
||||
@@ -413,10 +407,11 @@ Phaser.Physics.Arcade.prototype = {
|
||||
* Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters.
|
||||
* You can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks.
|
||||
* Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.
|
||||
* The second parameter can be an array of objects, of differing types.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#overlap
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
|
||||
* @param {function} [overlapCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then overlapCallback will only be called if processCallback returns true.
|
||||
* @param {object} [callbackContext] - The context in which to run the callbacks.
|
||||
@@ -431,39 +426,16 @@ Phaser.Physics.Arcade.prototype = {
|
||||
this._result = false;
|
||||
this._total = 0;
|
||||
|
||||
this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true);
|
||||
|
||||
return (this._total > 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for overlaps between a game object and a array of game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer checks.
|
||||
* Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.
|
||||
* An optional processCallback can be provided. If given this function will be called when two sprites are found to be overlapping,
|
||||
* giving you the chance to perform additional checks. If the function returns true then the overlap takes place. If it returns false it is skipped.
|
||||
* The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for overlapCallback to be called.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#overlapArray
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
|
||||
* @param {<Phaser.Sprite>array|<Phaser.Group>array|<Phaser.Particles.Emitter>array|<Phaser.Tilemap>array} objectArray - An array of objects to check. Can contain instances of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
|
||||
* @param {function} [overlapCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {object} [callbackContext] - The context in which to run the callbacks.
|
||||
* @returns {boolean} True if a collision occured otherwise false.
|
||||
*/
|
||||
overlapArray: function (object1, objectArray, overlapCallback, processCallback, callbackContext) {
|
||||
|
||||
overlapCallback = overlapCallback || null;
|
||||
processCallback = processCallback || null;
|
||||
callbackContext = callbackContext || overlapCallback;
|
||||
|
||||
this._result = false;
|
||||
this._total = 0;
|
||||
|
||||
for (var i = 0, len = objectArray.length; i < len; i++)
|
||||
if (Array.isArray(object2))
|
||||
{
|
||||
this.collideHandler(object1, objectArray[i], overlapCallback, processCallback, callbackContext, true);
|
||||
for (var i = 0, len = object2.length; i < len; i++)
|
||||
{
|
||||
this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true);
|
||||
}
|
||||
|
||||
return (this._total > 0);
|
||||
@@ -472,7 +444,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
/**
|
||||
* Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
|
||||
* If you'd like to collide an array of objects see Phaser.Physics.Arcade#collideArray.
|
||||
* The second parameter can be an array of objects, of differing types.
|
||||
* The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead.
|
||||
* An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place,
|
||||
* giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped.
|
||||
@@ -480,7 +452,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collide
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
|
||||
* @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {object} [callbackContext] - The context in which to run the callbacks.
|
||||
@@ -495,39 +467,16 @@ Phaser.Physics.Arcade.prototype = {
|
||||
this._result = false;
|
||||
this._total = 0;
|
||||
|
||||
this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false);
|
||||
|
||||
return (this._total > 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for collision between a game object and an array of game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
|
||||
* The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead.
|
||||
* An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place,
|
||||
* giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped.
|
||||
* The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collideArray
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
|
||||
* @param {<Phaser.Sprite>array|<Phaser.Group>array|<Phaser.Particles.Emitter>array|<Phaser.Tilemap>array} objectArray - An array of objects to check. Can contain instances of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
|
||||
* @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {object} [callbackContext] - The context in which to run the callbacks.
|
||||
* @returns {boolean} True if a collision occured otherwise false.
|
||||
*/
|
||||
collideArray: function (object1, objectArray, collideCallback, processCallback, callbackContext) {
|
||||
|
||||
collideCallback = collideCallback || null;
|
||||
processCallback = processCallback || null;
|
||||
callbackContext = callbackContext || collideCallback;
|
||||
|
||||
this._result = false;
|
||||
this._total = 0;
|
||||
|
||||
for (var i = 0, len = objectArray.length; i < len; i++)
|
||||
if (Array.isArray(object2))
|
||||
{
|
||||
this.collideHandler(object1, objectArray[i], collideCallback, processCallback, callbackContext, false);
|
||||
for (var i = 0, len = object2.length; i < len; i++)
|
||||
{
|
||||
this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false);
|
||||
}
|
||||
|
||||
return (this._total > 0);
|
||||
@@ -745,8 +694,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||
*/
|
||||
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
|
||||
|
||||
// console.log('collideSpriteVsTilemapLayer x:', sprite.body.x, 'y:', sprite.body.y, 'body left:', sprite.body.left, 'right:', sprite.body.right);
|
||||
|
||||
this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true);
|
||||
|
||||
if (this._mapData.length === 0)
|
||||
@@ -871,12 +818,19 @@ Phaser.Physics.Arcade.prototype = {
|
||||
*/
|
||||
intersects: function (a, b) {
|
||||
|
||||
var result = false;
|
||||
|
||||
if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0)
|
||||
{
|
||||
return false;
|
||||
result = false;
|
||||
}
|
||||
|
||||
return !(a.right < b.left || a.bottom < b.top || a.left > b.right || a.top > b.bottom);
|
||||
result = !(a.right < b.left || a.bottom < b.top || a.left > b.right || a.top > b.bottom);
|
||||
|
||||
if (!result && a.inContact(b))
|
||||
{
|
||||
a.removeContact(b);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
+284
-183
@@ -271,6 +271,24 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.height = 0;
|
||||
|
||||
/**
|
||||
* @property {array<Phaser.Physics.Arcade.Body>} contacts - Used to store references to bodies this Body is in contact with.
|
||||
* @protected
|
||||
*/
|
||||
this.contacts = [];
|
||||
|
||||
/**
|
||||
* @property {number} overlapX - Mostly used internally to store the overlap values from Tile seperation.
|
||||
* @protected
|
||||
*/
|
||||
this.overlapX = 0;
|
||||
|
||||
/**
|
||||
* @property {number} overlapY - Mostly used internally to store the overlap values from Tile seperation.
|
||||
* @protected
|
||||
*/
|
||||
this.overlapY = 0;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} _temp - Internal cache var.
|
||||
* @private
|
||||
@@ -307,129 +325,34 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this._distances = [0, 0, 0, 0];
|
||||
|
||||
this.overlapX = 0;
|
||||
this.overlapY = 0;
|
||||
|
||||
// Velocity cache
|
||||
/**
|
||||
* @property {number} _vx - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
this._vx = 0;
|
||||
|
||||
/**
|
||||
* @property {number} _vy - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
this._vy = 0;
|
||||
|
||||
// Set-up the default shape
|
||||
this.setRectangle(sprite.width, sprite.height, 0, 0);
|
||||
|
||||
// Set-up contact events
|
||||
this.sprite.events.onBeginContact = new Phaser.Signal();
|
||||
this.sprite.events.onEndContact = new Phaser.Signal();
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Arcade.Body.prototype = {
|
||||
|
||||
/**
|
||||
* Sets this Body to use a circle of the given radius for all collision.
|
||||
* The Circle will be centered on the center of the Sprite by default, but can be adjusted via the Body.offset property and the setCircle x/y parameters.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#setCircle
|
||||
* @param {number} radius - The radius of this circle (in pixels)
|
||||
* @param {number} [offsetX=0] - The x amount the circle will be offset from the Sprites center.
|
||||
* @param {number} [offsetY=0] - The y amount the circle will be offset from the Sprites center.
|
||||
*/
|
||||
setCircle: function (radius, offsetX, offsetY) {
|
||||
|
||||
if (typeof offsetX === 'undefined') { offsetX = this.sprite._cache.halfWidth; }
|
||||
if (typeof offsetY === 'undefined') { offsetY = this.sprite._cache.halfHeight; }
|
||||
|
||||
this.type = Phaser.Physics.Arcade.CIRCLE;
|
||||
this.shape = new SAT.Circle(new SAT.Vector(this.sprite.x, this.sprite.y), radius);
|
||||
this.polygon = null;
|
||||
|
||||
this.offset.setTo(offsetX, offsetY);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this Body to use a rectangle for all collision.
|
||||
* If you don't specify any parameters it will be sized to match the parent Sprites current width and height (including scale factor) and centered on the sprite.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#setRectangle
|
||||
* @param {number} [width] - The width of the rectangle. If not specified it will default to the width of the parent Sprite.
|
||||
* @param {number} [height] - The height of the rectangle. If not specified it will default to the height of the parent Sprite.
|
||||
* @param {number} [translateX] - The x amount the rectangle will be translated from the Sprites center.
|
||||
* @param {number} [translateY] - The y amount the rectangle will be translated from the Sprites center.
|
||||
*/
|
||||
setRectangle: function (width, height, translateX, translateY) {
|
||||
|
||||
if (typeof width === 'undefined') { width = this.sprite.width; }
|
||||
if (typeof height === 'undefined') { height = this.sprite.height; }
|
||||
if (typeof translateX === 'undefined') { translateX = -this.sprite._cache.halfWidth; }
|
||||
if (typeof translateY === 'undefined') { translateY = -this.sprite._cache.halfHeight; }
|
||||
|
||||
this.type = Phaser.Physics.Arcade.RECT;
|
||||
this.shape = new SAT.Box(new SAT.Vector(this.sprite.world.x, this.sprite.world.y), width, height);
|
||||
this.polygon = this.shape.toPolygon();
|
||||
this.polygon.translate(translateX, translateY);
|
||||
|
||||
this.offset.setTo(0, 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this Body to use a convex polygon for collision.
|
||||
* The points are specified in a counter-clockwise direction and must create a convex polygon.
|
||||
* Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#setPolygon
|
||||
* @param {array<SAT.Vector>|Array<Number>|SAT.Vector...|Number...} points - This can be an array of Vectors that form the polygon,
|
||||
* a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
|
||||
* all the points of the polygon e.g. `setPolygon(new SAT.Vector(), new SAT.Vector(), ...)`, or the
|
||||
* arguments passed can be flat x,y values e.g. `setPolygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers.
|
||||
*/
|
||||
setPolygon: function (points) {
|
||||
|
||||
this.type = Phaser.Physics.Arcade.POLYGON;
|
||||
this.shape = null;
|
||||
|
||||
if (!(points instanceof Array))
|
||||
{
|
||||
points = Array.prototype.slice.call(arguments);
|
||||
}
|
||||
|
||||
if (typeof points[0] === 'number')
|
||||
{
|
||||
var p = [];
|
||||
|
||||
for (var i = 0, len = points.length; i < len; i += 2)
|
||||
{
|
||||
p.push(new SAT.Vector(points[i], points[i + 1]));
|
||||
}
|
||||
|
||||
points = p;
|
||||
}
|
||||
|
||||
this.polygon = new SAT.Polygon(new SAT.Vector(this.sprite.center.x, this.sprite.center.y), points);
|
||||
|
||||
this.offset.setTo(0, 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles.
|
||||
* See also the Body.offset property.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#translate
|
||||
* @param {number} x - The x amount the polygon or rectangle will be translated by from the Sprite.
|
||||
* @param {number} y - The y amount the polygon or rectangle will be translated by from the Sprite.
|
||||
*/
|
||||
translate: function (x, y) {
|
||||
|
||||
if (this.polygon)
|
||||
{
|
||||
this.polygon.translate(x, y);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
* Internal method that updates the Body scale in relation to the parent Sprite.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#updateScale
|
||||
* @private
|
||||
* @protected
|
||||
*/
|
||||
updateScale: function () {
|
||||
|
||||
@@ -448,7 +371,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
* Internal method that updates the Body position in relation to the parent Sprite.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#preUpdate
|
||||
* @protected
|
||||
@@ -530,7 +453,7 @@ if (this.sprite.debug)
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal method that checks and potentially resets the blocke status.
|
||||
* Internal method that checks and potentially resets the blocked status flags.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#checkBlocked
|
||||
* @protected
|
||||
@@ -753,7 +676,7 @@ if (this.sprite.debug)
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given Vector from this Body.
|
||||
* Adds the given Vector to this Body.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#add
|
||||
* @protected
|
||||
@@ -905,40 +828,110 @@ if (this.sprite.debug)
|
||||
*/
|
||||
overlap: function (body, response) {
|
||||
|
||||
var result = false;
|
||||
|
||||
if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
|
||||
{
|
||||
return SAT.testPolygonPolygon(this.polygon, body.polygon, response);
|
||||
result = SAT.testPolygonPolygon(this.polygon, body.polygon, response);
|
||||
}
|
||||
else if (this.type === Phaser.Physics.Arcade.CIRCLE && body.type === Phaser.Physics.Arcade.CIRCLE)
|
||||
{
|
||||
return SAT.testCircleCircle(this.shape, body.shape, response);
|
||||
result = SAT.testCircleCircle(this.shape, body.shape, response);
|
||||
}
|
||||
else if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && body.type === Phaser.Physics.Arcade.CIRCLE)
|
||||
{
|
||||
return SAT.testPolygonCircle(this.polygon, body.shape, response);
|
||||
result = SAT.testPolygonCircle(this.polygon, body.shape, response);
|
||||
}
|
||||
else if (this.type === Phaser.Physics.Arcade.CIRCLE && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
|
||||
{
|
||||
return SAT.testCirclePolygon(this.shape, body.polygon, response);
|
||||
result = SAT.testCirclePolygon(this.shape, body.polygon, response);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
this.removeContact(body);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if this Body is already in contact with the given Body.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#inContact
|
||||
* @param {Phaser.Physics.Arcade.Body} body - The Body to be checked.
|
||||
* @return {boolean} True if the given Body is already in contact with this Body.
|
||||
*/
|
||||
inContact: function (body) {
|
||||
|
||||
return (this.contacts.indexOf(body) != -1);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given Body to the contact list of this Body. Also adds this Body to the contact list of the given Body.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#addContact
|
||||
* @param {Phaser.Physics.Arcade.Body} body - The Body to be added.
|
||||
* @return {boolean} True if the given Body was added to this contact list, false if already on it.
|
||||
*/
|
||||
addContact: function (body) {
|
||||
|
||||
if (this.inContact(body))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.contacts.push(body);
|
||||
|
||||
this.sprite.events.onBeginContact.dispatch(this.sprite, body.sprite, this, body);
|
||||
|
||||
body.addContact(this);
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the given Body from the contact list of this Body. Also removes this Body from the contact list of the given Body.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#removeContact
|
||||
* @param {Phaser.Physics.Arcade.Body} body - The Body to be removed.
|
||||
* @return {boolean} True if the given Body was removed from this contact list, false if wasn't on it.
|
||||
*/
|
||||
removeContact: function (body) {
|
||||
|
||||
if (!this.inContact(body))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.contacts.splice(this.contacts.indexOf(body), 1);
|
||||
|
||||
this.sprite.events.onEndContact.dispatch(this.sprite, body.sprite, this, body);
|
||||
|
||||
body.removeContact(this);
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* It assumes they have already been overlap checked and the resulting overlap is stored in the SAT response.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#separate
|
||||
* @protected
|
||||
* @param {Phaser.Physics.Arcade.Body} body - The Body to be separated from this one.
|
||||
* @param {SAT.Response} response - SAT Response handler.
|
||||
* @return {boolean}
|
||||
* @return {boolean} True if the bodies were separated, false if not (for example checkCollide allows them to pass through)
|
||||
*/
|
||||
separate: function (body, response) {
|
||||
|
||||
if (this.customSeparateCallback)
|
||||
if (this.inContact(body))
|
||||
{
|
||||
return this.customSeparateCallback.call(this.customSeparateContext, this, response);
|
||||
return false;
|
||||
}
|
||||
|
||||
this._distances[0] = body.right - this.x; // Distance of B to face on left side of A
|
||||
@@ -946,42 +939,65 @@ if (this.sprite.debug)
|
||||
this._distances[2] = body.bottom - this.y; // Distance of B to face on bottom side of A
|
||||
this._distances[3] = this.bottom - body.y; // Distance of B to face on top side of A
|
||||
|
||||
console.log(this.sprite.name, 'collided with', body.sprite.name, response.overlapN, this._distances);
|
||||
// If we've zero distance then check for side-slicing
|
||||
if (response.overlapN.x && (this._distances[0] === 0 || this._distances[1] === 0))
|
||||
{
|
||||
response.overlapN.x = false;
|
||||
response.overlapN.y = true;
|
||||
}
|
||||
else if (response.overlapN.y && (this._distances[2] === 0 || this._distances[3] === 0))
|
||||
{
|
||||
response.overlapN.x = true;
|
||||
response.overlapN.y = false;
|
||||
}
|
||||
|
||||
if (this.customSeparateCallback)
|
||||
{
|
||||
return this.customSeparateCallback.call(this.customSeparateContext, this, response, this._distances);
|
||||
}
|
||||
|
||||
var hasSeparated = false;
|
||||
|
||||
if (response.overlapN.x)
|
||||
{
|
||||
// Which is smaller? Left or Right?
|
||||
if (this._distances[0] < this._distances[1])
|
||||
if (this._distances[0] < this._distances[1] && (body.checkCollision.right || this.checkCollision.left))
|
||||
{
|
||||
console.log(this.sprite.name, 'collided on the LEFT with', body.sprite.name, response);
|
||||
this.hitLeft(body, response);
|
||||
// console.log(this.sprite.name, 'collided on the LEFT with', body.sprite.name, response);
|
||||
hasSeparated = this.hitLeft(body, response);
|
||||
}
|
||||
else if (this._distances[1] < this._distances[0])
|
||||
else if (this._distances[1] < this._distances[0] && (body.checkCollision.left || this.checkCollision.right))
|
||||
{
|
||||
console.log(this.sprite.name, 'collided on the RIGHT with', body.sprite.name, response);
|
||||
this.hitRight(body, response);
|
||||
// console.log(this.sprite.name, 'collided on the RIGHT with', body.sprite.name, response);
|
||||
hasSeparated = this.hitRight(body, response);
|
||||
}
|
||||
}
|
||||
else if (response.overlapN.y)
|
||||
{
|
||||
// Which is smaller? Top or Bottom?
|
||||
if (this._distances[2] < this._distances[3])
|
||||
if (this._distances[2] < this._distances[3] && (body.checkCollision.down || this.checkCollision.up))
|
||||
{
|
||||
console.log(this.sprite.name, 'collided on the TOP with', body.sprite.name, response);
|
||||
this.hitTop(body, response);
|
||||
// console.log(this.sprite.name, 'collided on the TOP with', body.sprite.name, response);
|
||||
hasSeparated = this.hitTop(body, response);
|
||||
}
|
||||
else if (this._distances[3] < this._distances[2])
|
||||
else if (this._distances[3] < this._distances[2] && (body.checkCollision.up || this.checkCollision.down))
|
||||
{
|
||||
console.log(this.sprite.name, 'collided on the BOTTOM with', body.sprite.name, response);
|
||||
this.hitBottom(body, response);
|
||||
// console.log(this.sprite.name, 'collided on the BOTTOM with', body.sprite.name, response);
|
||||
hasSeparated = this.hitBottom(body, response);
|
||||
}
|
||||
}
|
||||
|
||||
this.game.physics.checkBounds(this);
|
||||
this.game.physics.checkBounds(body);
|
||||
if (hasSeparated)
|
||||
{
|
||||
this.game.physics.checkBounds(this);
|
||||
this.game.physics.checkBounds(body);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.addContact(body);
|
||||
}
|
||||
|
||||
return true;
|
||||
return hasSeparated;
|
||||
|
||||
},
|
||||
|
||||
@@ -999,17 +1015,6 @@ if (this.sprite.debug)
|
||||
*/
|
||||
hitLeft: function (body, response) {
|
||||
|
||||
// We know that Body is overlapping with This on the left hand side (deltaX < 0 = moving left, > 0 = moving right)
|
||||
if (body.speed > 0 && (body.deltaX() <= 0 || (body.deltaX() > 0 && !this.checkCollision.left)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.speed > 0 && (this.deltaX() >= 0 || (this.deltaX() < 0 && !body.checkCollision.right)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.LEFT, this, body, response))
|
||||
{
|
||||
return;
|
||||
@@ -1052,17 +1057,6 @@ if (this.sprite.debug)
|
||||
*/
|
||||
hitRight: function (body, response) {
|
||||
|
||||
// We know that Body is overlapping with This on the right hand side (deltaX < 0 = moving left, > 0 = moving right)
|
||||
if (body.speed > 0 && (body.deltaX() >= 0 || (body.deltaX() < 0 && !this.checkCollision.right)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.speed > 0 && (this.deltaX() <= 0 || (this.deltaX() > 0 && !body.checkCollision.left)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.RIGHT, this, body))
|
||||
{
|
||||
return;
|
||||
@@ -1105,20 +1099,9 @@ if (this.sprite.debug)
|
||||
*/
|
||||
hitTop: function (body, response) {
|
||||
|
||||
// We know that Body is overlapping with This on the bottom side (deltaY < 0 = moving up, > 0 = moving down)
|
||||
if (body.speed > 0 && (body.deltaY() <= 0 || (body.deltaY() > 0 && !this.checkCollision.up)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.speed > 0 && (this.deltaY() >= 0 || (this.deltaY() < 0 && !body.checkCollision.down)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.UP, this, body))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.moves || this.immovable || this.blocked.down || this.touching.down)
|
||||
@@ -1142,6 +1125,8 @@ if (this.sprite.debug)
|
||||
this.touching.up = true;
|
||||
body.touching.down = true;
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1158,20 +1143,9 @@ if (this.sprite.debug)
|
||||
*/
|
||||
hitBottom: function (body, response) {
|
||||
|
||||
// We know that Body is overlapping with This on the bottom side (deltaY < 0 = moving up, > 0 = moving down)
|
||||
if (body.speed > 0 && (body.deltaY() >= 0 || (body.deltaY() < 0 && !this.checkCollision.down)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.speed > 0 && (this.deltaY() <= 0 || (this.deltaY() > 0 && !body.checkCollision.up)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.DOWN, this, body))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.moves || this.immovable || this.blocked.up || this.touching.up)
|
||||
@@ -1195,6 +1169,8 @@ if (this.sprite.debug)
|
||||
this.touching.down = true;
|
||||
body.touching.up = true;
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1361,6 +1337,131 @@ if (this.sprite.debug)
|
||||
this.preY = this.y;
|
||||
this.updateBounds();
|
||||
|
||||
this.contacts.length = 0;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys this Body and all references it holds to other objects.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#destroy
|
||||
*/
|
||||
destroy: function () {
|
||||
|
||||
this.sprite = null;
|
||||
|
||||
this.collideCallback = null;
|
||||
this.collideCallbackContext = null;
|
||||
|
||||
this.customSeparateCallback = null;
|
||||
this.customSeparateContext = null;
|
||||
|
||||
this.contacts.length = 0;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this Body to use a circle of the given radius for all collision.
|
||||
* The Circle will be centered on the center of the Sprite by default, but can be adjusted via the Body.offset property and the setCircle x/y parameters.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#setCircle
|
||||
* @param {number} radius - The radius of this circle (in pixels)
|
||||
* @param {number} [offsetX=0] - The x amount the circle will be offset from the Sprites center.
|
||||
* @param {number} [offsetY=0] - The y amount the circle will be offset from the Sprites center.
|
||||
*/
|
||||
setCircle: function (radius, offsetX, offsetY) {
|
||||
|
||||
if (typeof offsetX === 'undefined') { offsetX = this.sprite._cache.halfWidth; }
|
||||
if (typeof offsetY === 'undefined') { offsetY = this.sprite._cache.halfHeight; }
|
||||
|
||||
this.type = Phaser.Physics.Arcade.CIRCLE;
|
||||
this.shape = new SAT.Circle(new SAT.Vector(this.sprite.x, this.sprite.y), radius);
|
||||
this.polygon = null;
|
||||
|
||||
this.offset.setTo(offsetX, offsetY);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this Body to use a rectangle for all collision.
|
||||
* If you don't specify any parameters it will be sized to match the parent Sprites current width and height (including scale factor) and centered on the sprite.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#setRectangle
|
||||
* @param {number} [width] - The width of the rectangle. If not specified it will default to the width of the parent Sprite.
|
||||
* @param {number} [height] - The height of the rectangle. If not specified it will default to the height of the parent Sprite.
|
||||
* @param {number} [translateX] - The x amount the rectangle will be translated from the Sprites center.
|
||||
* @param {number} [translateY] - The y amount the rectangle will be translated from the Sprites center.
|
||||
*/
|
||||
setRectangle: function (width, height, translateX, translateY) {
|
||||
|
||||
if (typeof width === 'undefined') { width = this.sprite.width; }
|
||||
if (typeof height === 'undefined') { height = this.sprite.height; }
|
||||
if (typeof translateX === 'undefined') { translateX = -this.sprite._cache.halfWidth; }
|
||||
if (typeof translateY === 'undefined') { translateY = -this.sprite._cache.halfHeight; }
|
||||
|
||||
this.type = Phaser.Physics.Arcade.RECT;
|
||||
this.shape = new SAT.Box(new SAT.Vector(this.sprite.world.x, this.sprite.world.y), width, height);
|
||||
this.polygon = this.shape.toPolygon();
|
||||
this.polygon.translate(translateX, translateY);
|
||||
|
||||
this.offset.setTo(0, 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this Body to use a convex polygon for collision.
|
||||
* The points are specified in a counter-clockwise direction and must create a convex polygon.
|
||||
* Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#setPolygon
|
||||
* @param {array<SAT.Vector>|Array<Number>|SAT.Vector...|Number...} points - This can be an array of Vectors that form the polygon,
|
||||
* a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
|
||||
* all the points of the polygon e.g. `setPolygon(new SAT.Vector(), new SAT.Vector(), ...)`, or the
|
||||
* arguments passed can be flat x,y values e.g. `setPolygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers.
|
||||
*/
|
||||
setPolygon: function (points) {
|
||||
|
||||
this.type = Phaser.Physics.Arcade.POLYGON;
|
||||
this.shape = null;
|
||||
|
||||
if (!Array.isArray(points))
|
||||
{
|
||||
points = Array.prototype.slice.call(arguments);
|
||||
}
|
||||
|
||||
if (typeof points[0] === 'number')
|
||||
{
|
||||
var p = [];
|
||||
|
||||
for (var i = 0, len = points.length; i < len; i += 2)
|
||||
{
|
||||
p.push(new SAT.Vector(points[i], points[i + 1]));
|
||||
}
|
||||
|
||||
points = p;
|
||||
}
|
||||
|
||||
this.polygon = new SAT.Polygon(new SAT.Vector(this.sprite.center.x, this.sprite.center.y), points);
|
||||
|
||||
this.offset.setTo(0, 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles.
|
||||
* See also the Body.offset property.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#translate
|
||||
* @param {number} x - The x amount the polygon or rectangle will be translated by from the Sprite.
|
||||
* @param {number} y - The y amount the polygon or rectangle will be translated by from the Sprite.
|
||||
*/
|
||||
translate: function (x, y) {
|
||||
|
||||
if (this.polygon)
|
||||
{
|
||||
this.polygon.translate(x, y);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
+13
-2
@@ -125,6 +125,13 @@ Phaser.Tween = function (object, game) {
|
||||
*/
|
||||
this._onUpdateCallback = null;
|
||||
|
||||
/**
|
||||
* @property {object} _onUpdateCallbackContext - The context in which to call the onUpdate callback.
|
||||
* @private
|
||||
* @default null
|
||||
*/
|
||||
this._onUpdateCallbackContext = null;
|
||||
|
||||
/**
|
||||
* @property {number} _pausedTime - Private pause timer.
|
||||
* @private
|
||||
@@ -293,6 +300,8 @@ Phaser.Tween.prototype = {
|
||||
|
||||
this.isRunning = false;
|
||||
|
||||
this._onUpdateCallback = null;
|
||||
|
||||
this._manager.remove(this);
|
||||
|
||||
return this;
|
||||
@@ -411,9 +420,11 @@ Phaser.Tween.prototype = {
|
||||
* @param {function} callback - The callback to invoke each time this tween is updated.
|
||||
* @return {Phaser.Tween} Itself.
|
||||
*/
|
||||
onUpdateCallback: function (callback) {
|
||||
onUpdateCallback: function (callback, callbackContext) {
|
||||
|
||||
this._onUpdateCallback = callback;
|
||||
this._onUpdateCallbackContext = callbackContext;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
@@ -506,7 +517,7 @@ Phaser.Tween.prototype = {
|
||||
|
||||
if (this._onUpdateCallback !== null)
|
||||
{
|
||||
this._onUpdateCallback.call(this._object, value);
|
||||
this._onUpdateCallback.call(this._onUpdateCallbackContext, this, value);
|
||||
}
|
||||
|
||||
if (elapsed == 1)
|
||||
|
||||
@@ -28,13 +28,13 @@ Phaser.TweenManager = function (game) {
|
||||
this.game = game;
|
||||
|
||||
/**
|
||||
* @property {array} _tweens - Description.
|
||||
* @property {array<Phaser.Tween>} _tweens - All of the currently running tweens.
|
||||
* @private
|
||||
*/
|
||||
this._tweens = [];
|
||||
|
||||
/**
|
||||
* @property {array} _add - Description.
|
||||
* @property {array<Phaser.Tween>} _add - All of the tweens queued to be added in the next update.
|
||||
* @private
|
||||
*/
|
||||
this._add = [];
|
||||
@@ -46,13 +46,6 @@ Phaser.TweenManager = function (game) {
|
||||
|
||||
Phaser.TweenManager.prototype = {
|
||||
|
||||
/**
|
||||
* Version number of this library.
|
||||
* @property {string} REVISION
|
||||
* @default
|
||||
*/
|
||||
REVISION: '11dev',
|
||||
|
||||
/**
|
||||
* Get all the tween objects in an array.
|
||||
* @method Phaser.TweenManager#getAll
|
||||
@@ -65,12 +58,17 @@ Phaser.TweenManager.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all tween objects.
|
||||
* Remove all tweens running and in the queue. Doesn't call any of the tween onComplete events.
|
||||
* @method Phaser.TweenManager#removeAll
|
||||
*/
|
||||
removeAll: function () {
|
||||
|
||||
this._tweens = [];
|
||||
for (var i = 0; i < this._tweens.length; i++)
|
||||
{
|
||||
this._tweens[i].pendingDelete = true;
|
||||
}
|
||||
|
||||
this._add = [];
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -265,3 +265,13 @@ if (typeof Function.prototype.bind != 'function') {
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* A polyfill for Array.isArray
|
||||
*/
|
||||
if (!Array.isArray) {
|
||||
Array.isArray = function (arg) {
|
||||
return Object.prototype.toString.call(arg) == '[object Array]';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user