mirror of
https://github.com/wassname/phaser.git
synced 2026-06-30 16:40:20 +08:00
Forces working, collision half way there.
This commit is contained in:
+3
-2
@@ -379,16 +379,17 @@ Phaser.Game.prototype = {
|
||||
|
||||
this.input.update();
|
||||
this.tweens.update();
|
||||
// this.stage.update();
|
||||
this.sound.update();
|
||||
// this.physics.update();
|
||||
this.world.update();
|
||||
this.state.update();
|
||||
// this.physics.update();
|
||||
this.plugins.update();
|
||||
|
||||
this.renderer.render(this.world._stage);
|
||||
this.state.render();
|
||||
|
||||
this.world.postUpdate();
|
||||
|
||||
this.plugins.postRender();
|
||||
|
||||
},
|
||||
|
||||
@@ -71,6 +71,30 @@ Phaser.World.prototype = {
|
||||
|
||||
},
|
||||
|
||||
postUpdate: function () {
|
||||
|
||||
//this.camera.update();
|
||||
|
||||
var displayObject = this._stage;
|
||||
|
||||
// once the display object hits this. we can break the loop
|
||||
var testObject = displayObject.last._iNext;
|
||||
displayObject = displayObject.first;
|
||||
|
||||
do
|
||||
{
|
||||
if (displayObject['postUpdate'])
|
||||
{
|
||||
displayObject.postUpdate();
|
||||
}
|
||||
|
||||
// count++
|
||||
displayObject = displayObject._iNext;
|
||||
}
|
||||
while(displayObject != testObject)
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the size of this world.
|
||||
*
|
||||
|
||||
@@ -250,6 +250,12 @@ Phaser.Sprite.prototype.update = function() {
|
||||
|
||||
}
|
||||
|
||||
Phaser.Sprite.prototype.postUpdate = function() {
|
||||
|
||||
this.body.postUpdate();
|
||||
|
||||
}
|
||||
|
||||
Phaser.Sprite.prototype.updateBounds = function() {
|
||||
|
||||
// Update the edge points
|
||||
|
||||
@@ -11,6 +11,16 @@ Phaser.Physics.Arcade = function (game) {
|
||||
*/
|
||||
this.worldDivisions = 6;
|
||||
|
||||
this.LEFT = 0x0001;
|
||||
this.RIGHT = 0x0010;
|
||||
this.UP = 0x0100;
|
||||
this.DOWN = 0x1000;
|
||||
this.NONE = 0;
|
||||
this.CEILING = this.UP;
|
||||
this.FLOOR = this.DOWN;
|
||||
this.WALL = this.LEFT | this.RIGHT;
|
||||
this.ANY = this.LEFT | this.RIGHT | this.UP | this.DOWN;
|
||||
|
||||
// this.angularDrag = 0;
|
||||
// this.gravity = new Phaser.Point;
|
||||
// this.drag = new Phaser.Point;
|
||||
@@ -23,6 +33,12 @@ Phaser.Physics.Arcade = function (game) {
|
||||
|
||||
Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
collide: function (objectOrGroup1, objectOrGroup2, notifyCallback) {
|
||||
|
||||
return this.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.separate);
|
||||
|
||||
},
|
||||
|
||||
updateMotion: function (body) {
|
||||
|
||||
this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
|
||||
@@ -101,7 +117,279 @@ Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for overlaps between two objects using the world QuadTree. Can be GameObject vs. GameObject, GameObject vs. Group or Group vs. Group.
|
||||
* Note: Does not take the objects scrollFactor into account. All overlaps are check in world space.
|
||||
* @param object1 The first GameObject or Group to check. If null the world.group is used.
|
||||
* @param object2 The second GameObject or Group to check.
|
||||
* @param notifyCallback A 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 passed them to Collision.overlap.
|
||||
* @param processCallback A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then notifyCallback will only be called if processCallback returns true.
|
||||
* @returns {boolean} true if the objects overlap, otherwise false.
|
||||
*/
|
||||
overlap: function (object1, object2, notifyCallback, processCallback) {
|
||||
|
||||
if (object1 == null)
|
||||
{
|
||||
object1 = this._game.world.group;
|
||||
}
|
||||
|
||||
if (object2 == object1)
|
||||
{
|
||||
object2 = null;
|
||||
}
|
||||
|
||||
Phaser.QuadTree.divisions = this.worldDivisions;
|
||||
|
||||
var quadTree = new Phaser.QuadTree(this._game.world.bounds.x, this._game.world.bounds.y, this._game.world.bounds.width, this._game.world.bounds.height);
|
||||
|
||||
quadTree.load(object1, object2, notifyCallback, processCallback);
|
||||
|
||||
var result = quadTree.execute();
|
||||
|
||||
quadTree.destroy();
|
||||
|
||||
quadTree = null;
|
||||
|
||||
return result;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The core Collision separation function used by Collision.overlap.
|
||||
* @param object1 The first GameObject to separate
|
||||
* @param object2 The second GameObject to separate
|
||||
* @returns {boolean} Returns true if the objects were separated, otherwise false.
|
||||
*/
|
||||
separate: function (object1, object2) {
|
||||
|
||||
var separatedX = this.separateX(object1, object2);
|
||||
var separatedY = this.separateY(object1, object2);
|
||||
|
||||
return separatedX || separatedY;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Separates the two objects on their x axis
|
||||
* @param object1 The first GameObject to separate
|
||||
* @param object2 The second GameObject to separate
|
||||
* @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
|
||||
*/
|
||||
separateX: function (object1, object2) {
|
||||
|
||||
// Can't separate two immovable objects
|
||||
if (object1.immovable && object2.immovable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, get the two object deltas
|
||||
var overlap = 0;
|
||||
var obj1Delta = object1.x - object1.last.x;
|
||||
var obj2Delta = object2.x - object2.last.x;
|
||||
|
||||
if (obj1Delta != obj2Delta)
|
||||
{
|
||||
// Check if the X hulls actually overlap
|
||||
var obj1DeltaAbs = (obj1Delta > 0) ? obj1Delta : -obj1Delta;
|
||||
var obj2DeltaAbs = (obj2Delta > 0) ? obj2Delta : -obj2Delta;
|
||||
var obj1Bounds = new Quad(object1.x - ((obj1Delta > 0) ? obj1Delta : 0), object1.last.y, object1.width + ((obj1Delta > 0) ? obj1Delta : -obj1Delta), object1.height);
|
||||
var obj2Bounds = new Quad(object2.x - ((obj2Delta > 0) ? obj2Delta : 0), object2.last.y, object2.width + ((obj2Delta > 0) ? obj2Delta : -obj2Delta), object2.height);
|
||||
|
||||
if ((obj1Bounds.x + obj1Bounds.width > obj2Bounds.x) && (obj1Bounds.x < obj2Bounds.x + obj2Bounds.width) && (obj1Bounds.y + obj1Bounds.height > obj2Bounds.y) && (obj1Bounds.y < obj2Bounds.y + obj2Bounds.height))
|
||||
{
|
||||
var maxOverlap = obj1DeltaAbs + obj2DeltaAbs + Collision.OVERLAP_BIAS;
|
||||
|
||||
// If they did overlap (and can), figure out by how much and flip the corresponding flags
|
||||
if (obj1Delta > obj2Delta)
|
||||
{
|
||||
overlap = object1.x + object1.width - object2.x;
|
||||
|
||||
if ((overlap > maxOverlap) || !(object1.allowCollisions & Collision.RIGHT) || !(object2.allowCollisions & Collision.LEFT))
|
||||
{
|
||||
overlap = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
object1.touching |= Collision.RIGHT;
|
||||
object2.touching |= Collision.LEFT;
|
||||
}
|
||||
}
|
||||
else if (obj1Delta < obj2Delta)
|
||||
{
|
||||
overlap = object1.x - object2.width - object2.x;
|
||||
|
||||
if ((-overlap > maxOverlap) || !(object1.allowCollisions & Collision.LEFT) || !(object2.allowCollisions & Collision.RIGHT))
|
||||
{
|
||||
overlap = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
object1.touching |= Collision.LEFT;
|
||||
object2.touching |= Collision.RIGHT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Then adjust their positions and velocities accordingly (if there was any overlap)
|
||||
if (overlap != 0)
|
||||
{
|
||||
var obj1Velocity = object1.velocity.x;
|
||||
var obj2Velocity = object2.velocity.x;
|
||||
|
||||
if (!object1.immovable && !object2.immovable)
|
||||
{
|
||||
overlap *= 0.5;
|
||||
object1.x = object1.x - overlap;
|
||||
object2.x += overlap;
|
||||
|
||||
var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.mass) / object1.mass) * ((obj2Velocity > 0) ? 1 : -1);
|
||||
var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.mass) / object2.mass) * ((obj1Velocity > 0) ? 1 : -1);
|
||||
var average = (obj1NewVelocity + obj2NewVelocity) * 0.5;
|
||||
obj1NewVelocity -= average;
|
||||
obj2NewVelocity -= average;
|
||||
object1.velocity.x = average + obj1NewVelocity * object1.elasticity;
|
||||
object2.velocity.x = average + obj2NewVelocity * object2.elasticity;
|
||||
}
|
||||
else if (!object1.immovable)
|
||||
{
|
||||
object1.x = object1.x - overlap;
|
||||
object1.velocity.x = obj2Velocity - obj1Velocity * object1.elasticity;
|
||||
}
|
||||
else if (!object2.immovable)
|
||||
{
|
||||
object2.x += overlap;
|
||||
object2.velocity.x = obj1Velocity - obj2Velocity * object2.elasticity;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Separates the two objects on their y axis
|
||||
* @param object1 The first GameObject to separate
|
||||
* @param object2 The second GameObject to separate
|
||||
* @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
|
||||
*/
|
||||
separateY: function (object1, object2) {
|
||||
|
||||
// Can't separate two immovable objects
|
||||
if (object1.immovable && object2.immovable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, get the two object deltas
|
||||
var overlap = 0;
|
||||
var obj1Delta = object1.y - object1.last.y;
|
||||
var obj2Delta = object2.y - object2.last.y;
|
||||
|
||||
if (obj1Delta != obj2Delta)
|
||||
{
|
||||
// Check if the Y hulls actually overlap
|
||||
var obj1DeltaAbs = (obj1Delta > 0) ? obj1Delta : -obj1Delta;
|
||||
var obj2DeltaAbs = (obj2Delta > 0) ? obj2Delta : -obj2Delta;
|
||||
var obj1Bounds: Quad = new Quad(object1.x, object1.y - ((obj1Delta > 0) ? obj1Delta : 0), object1.width, object1.height + obj1DeltaAbs);
|
||||
var obj2Bounds: Quad = new Quad(object2.x, object2.y - ((obj2Delta > 0) ? obj2Delta : 0), object2.width, object2.height + obj2DeltaAbs);
|
||||
|
||||
if ((obj1Bounds.x + obj1Bounds.width > obj2Bounds.x) && (obj1Bounds.x < obj2Bounds.x + obj2Bounds.width) && (obj1Bounds.y + obj1Bounds.height > obj2Bounds.y) && (obj1Bounds.y < obj2Bounds.y + obj2Bounds.height))
|
||||
{
|
||||
var maxOverlap = obj1DeltaAbs + obj2DeltaAbs + Collision.OVERLAP_BIAS;
|
||||
|
||||
// If they did overlap (and can), figure out by how much and flip the corresponding flags
|
||||
if (obj1Delta > obj2Delta)
|
||||
{
|
||||
overlap = object1.y + object1.height - object2.y;
|
||||
|
||||
if ((overlap > maxOverlap) || !(object1.allowCollisions & Collision.DOWN) || !(object2.allowCollisions & Collision.UP))
|
||||
{
|
||||
overlap = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
object1.touching |= Collision.DOWN;
|
||||
object2.touching |= Collision.UP;
|
||||
}
|
||||
}
|
||||
else if (obj1Delta < obj2Delta)
|
||||
{
|
||||
overlap = object1.y - object2.height - object2.y;
|
||||
|
||||
if ((-overlap > maxOverlap) || !(object1.allowCollisions & Collision.UP) || !(object2.allowCollisions & Collision.DOWN))
|
||||
{
|
||||
overlap = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
object1.touching |= Collision.UP;
|
||||
object2.touching |= Collision.DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then adjust their positions and velocities accordingly (if there was any overlap)
|
||||
if (overlap != 0)
|
||||
{
|
||||
var obj1Velocity = object1.velocity.y;
|
||||
var obj2Velocity = object2.velocity.y;
|
||||
|
||||
if (!object1.immovable && !object2.immovable)
|
||||
{
|
||||
overlap *= 0.5;
|
||||
object1.y = object1.y - overlap;
|
||||
object2.y += overlap;
|
||||
|
||||
var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.mass) / object1.mass) * ((obj2Velocity > 0) ? 1 : -1);
|
||||
var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.mass) / object2.mass) * ((obj1Velocity > 0) ? 1 : -1);
|
||||
var average = (obj1NewVelocity + obj2NewVelocity) * 0.5;
|
||||
obj1NewVelocity -= average;
|
||||
obj2NewVelocity -= average;
|
||||
object1.velocity.y = average + obj1NewVelocity * object1.elasticity;
|
||||
object2.velocity.y = average + obj2NewVelocity * object2.elasticity;
|
||||
}
|
||||
else if (!object1.immovable)
|
||||
{
|
||||
object1.y = object1.y - overlap;
|
||||
object1.velocity.y = obj2Velocity - obj1Velocity * object1.elasticity;
|
||||
// This is special case code that handles things like horizontal moving platforms you can ride
|
||||
if (object2.active && object2.moves && (obj1Delta > obj2Delta))
|
||||
{
|
||||
object1.x += object2.x - object2.last.x;
|
||||
}
|
||||
}
|
||||
else if (!object2.immovable)
|
||||
{
|
||||
object2.y += overlap;
|
||||
object2.velocity.y = obj1Velocity - obj2Velocity * object2.elasticity;
|
||||
// This is special case code that handles things like horizontal moving platforms you can ride
|
||||
if (object1.active && object1.moves && (obj1Delta < obj2Delta))
|
||||
{
|
||||
object2.x += object1.x - object1.last.x;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Arcade.prototype.OVERLAP_BIAS = 4;
|
||||
Phaser.Physics.Arcade.prototype.TILE_OVERLAP = false;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
this.maxAngular = 1000;
|
||||
this.mass = 1;
|
||||
|
||||
this.immovable = false;
|
||||
this.touching = 0;
|
||||
this.wasTouching = 0;
|
||||
this.allowCollisions = 1;
|
||||
@@ -54,9 +55,6 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
this.hitArea.centerX = x;
|
||||
this.hitArea.centerY = y;
|
||||
|
||||
// this._ox = x;
|
||||
// this._oy = y;
|
||||
|
||||
},
|
||||
|
||||
updateMotion: function () {
|
||||
|
||||
Reference in New Issue
Block a user