diff --git a/Phaser/Game.ts b/Phaser/Game.ts
index 4d03a574..fb147c58 100644
--- a/Phaser/Game.ts
+++ b/Phaser/Game.ts
@@ -639,9 +639,9 @@ module Phaser {
* @param context The context in which the callbacks will be called
* @returns {boolean} true if the objects overlap, otherwise false.
*/
- //public collide(objectOrGroup1 = null, objectOrGroup2 = null, notifyCallback = null, context? = this.callbackContext): bool {
- // return this.collision.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, Collision.separate, context);
- //}
+ public collide(objectOrGroup1 = null, objectOrGroup2 = null, notifyCallback = null, context? = this.callbackContext): bool {
+ return this.world.physics.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.world.physics.separate, context);
+ }
public get camera(): Camera {
return this.world.cameras.current;
diff --git a/Phaser/Phaser.csproj b/Phaser/Phaser.csproj
index 0196f2ed..bffdefb0 100644
--- a/Phaser/Phaser.csproj
+++ b/Phaser/Phaser.csproj
@@ -121,9 +121,21 @@
+
+
+ Body.ts
+
Circle.ts
+
+
+
+ Fixture.ts
+
+
+ IPhysicsBody.ts
+
IPhysicsShape.ts
@@ -215,7 +227,7 @@
LinkedList.ts
-
+
QuadTree.ts
@@ -234,7 +246,7 @@
-
+
diff --git a/Phaser/Statics.ts b/Phaser/Statics.ts
index 23bc4afb..1560d3fd 100644
--- a/Phaser/Statics.ts
+++ b/Phaser/Statics.ts
@@ -24,6 +24,11 @@ module Phaser {
static GEOM_LINE: number = 3;
static GEOM_POLYGON: number = 4;
+ static BODY_DISABLED: number = 0;
+ static BODY_DYNAMIC: number = 1;
+ static BODY_STATIC: number = 2;
+ static BODY_KINEMATIC: number = 3;
+
/**
* Flag used to allow GameObjects to collide on their left side
* @type {number}
diff --git a/Phaser/World.ts b/Phaser/World.ts
index 5eef880b..00c6172a 100644
--- a/Phaser/World.ts
+++ b/Phaser/World.ts
@@ -37,8 +37,6 @@ module Phaser {
this.physics = new Physics.PhysicsManager(this._game, width, height);
- this.worldDivisions = 6;
-
}
/**
@@ -70,17 +68,13 @@ module Phaser {
*/
public physics: Physics.PhysicsManager;
- /**
- * @type {number}
- */
- public worldDivisions: number;
/**
* This is called automatically every frame, and is where main logic happens.
*/
public update() {
- this.physics.update();
+ //this.physics.update();
this.group.update();
this.cameras.update();
diff --git a/Phaser/components/sprite/Physics.ts b/Phaser/components/sprite/Physics.ts
index cf52fa05..0cb8ff7a 100644
--- a/Phaser/components/sprite/Physics.ts
+++ b/Phaser/components/sprite/Physics.ts
@@ -4,6 +4,7 @@
///
///
///
+///
/**
* Phaser - Components - Physics
@@ -11,7 +12,7 @@
module Phaser.Components {
- export class Physics {
+ export class Physics implements Phaser.Physics.IPhysicsBody {
constructor(parent: Sprite) {
@@ -50,7 +51,6 @@ module Phaser.Components {
* @type {boolean}
*/
public moves: bool = true;
- public mass: number = 1;
public gravity: Vec2;
public drag: Vec2;
@@ -62,9 +62,11 @@ module Phaser.Components {
public touching: number;
public allowCollisions: number;
public wasTouching: number;
+ public mass: number = 1;
public setCircle(diameter: number) {
+ // Here is the stuff I want to remove
this.game.world.physics.remove(this.shape);
this.shape = this.game.world.physics.add(new Phaser.Physics.Circle(this.game, this._sprite, this._sprite.x, this._sprite.y, diameter));
this._sprite.physics.shape.physics = this;
@@ -76,6 +78,7 @@ module Phaser.Components {
*/
public update() {
+ // if this is all it does maybe move elsewhere? Sprite postUpdate?
if (this.moves && this.shape)
{
this._sprite.x = (this.shape.position.x - this.shape.bounds.halfWidth) - this.shape.offset.x;
diff --git a/Phaser/core/Group.ts b/Phaser/core/Group.ts
index 8760fdd4..7ef7f86a 100644
--- a/Phaser/core/Group.ts
+++ b/Phaser/core/Group.ts
@@ -153,7 +153,7 @@ module Phaser {
* Calls update on all members of this Group who have a status of active=true and exists=true
* You can also call Object.update directly, which will bypass the active/exists check.
*/
- public update(forceUpdate?: bool = false) {
+ public update() {
this._i = 0;
@@ -164,7 +164,7 @@ module Phaser {
if (this._member != null && this._member.exists && this._member.active)
{
this._member.preUpdate();
- this._member.update(forceUpdate);
+ this._member.update();
this._member.postUpdate();
}
}
diff --git a/Phaser/gameobjects/GameObjectFactory.ts b/Phaser/gameobjects/GameObjectFactory.ts
index a20ca2c4..008d390d 100644
--- a/Phaser/gameobjects/GameObjectFactory.ts
+++ b/Phaser/gameobjects/GameObjectFactory.ts
@@ -62,11 +62,12 @@ module Phaser {
*
* @param x {number} X position of the new sprite.
* @param y {number} Y position of the new sprite.
- * @param key {string} Optional, key for the sprite sheet you want it to use.
+ * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
* @returns {Sprite} The newly created sprite object.
*/
- public sprite(x: number, y: number, key?: string = ''): Sprite {
- return this._world.group.add(new Sprite(this._game, x, y, key));
+ public sprite(x: number, y: number, key?: string = '', bodyType?: number = Phaser.Types.BODY_DISABLED): Sprite {
+ return this._world.group.add(new Sprite(this._game, x, y, key, bodyType));
}
/**
@@ -90,18 +91,6 @@ module Phaser {
return this._world.group.add(new Group(this._game, maxSize));
}
- /**
- * Create a new Sprite with specific position and sprite sheet key.
- *
- * @param x {number} X position of the new sprite.
- * @param y {number} Y position of the new sprite.
- * @param key {string} Optional, key for the sprite sheet you want it to use.
- * @returns {Sprite} The newly created sprite object.
- * WILL NEED TO TRACK A SPRITE
- */
- public physicsAABB(x: number, y: number, width: number, height: number): Physics.AABB {
- return this._world.physics.add(new Physics.AABB(this._game, null, x, y, width, height));
- }
/**
* Create a new Particle.
diff --git a/Phaser/gameobjects/Sprite.ts b/Phaser/gameobjects/Sprite.ts
index 9e5aca88..ea0f1d40 100644
--- a/Phaser/gameobjects/Sprite.ts
+++ b/Phaser/gameobjects/Sprite.ts
@@ -4,6 +4,7 @@
///
///
///
+///
/**
* Phaser - Sprite
@@ -21,10 +22,10 @@ module Phaser {
* @param [x] {number} the initial x position of the sprite.
* @param [y] {number} the initial y position of the sprite.
* @param [key] {string} Key of the graphic you want to load for this sprite.
- * @param [width] {number} The width of the object.
- * @param [height] {number} The height of the object.
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
*/
- constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, width?: number = 16, height?: number = 16) {
+ //constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, width?: number = 16, height?: number = 16) {
+ constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, bodyType?: number = Phaser.Types.BODY_DISABLED) {
this.game = game;
this.type = Phaser.Types.SPRITE;
@@ -35,7 +36,8 @@ module Phaser {
this.visible = true;
this.alive = true;
- this.frameBounds = new Rectangle(x, y, width, height);
+ // We give it a default size of 16x16 but when the texture loads (if given) it will reset this
+ this.frameBounds = new Rectangle(x, y, 16, 16);
this.scrollFactor = new Phaser.Vec2(1, 1);
this.x = x;
@@ -50,17 +52,11 @@ module Phaser {
this.scale = new Phaser.Vec2(1, 1);
this.skew = new Phaser.Vec2(0, 0);
- this.physics = new Phaser.Components.Physics(this);
- this.physics.shape.physics = this.physics;
+ // If a texture has been given the body will be set to that size, otherwise 16x16
+ this.body = new Phaser.Physics.Body(this, bodyType);
}
- /**
- * Rotation angle of this object.
- * @type {number}
- */
- private _rotation: number = 0;
-
/**
* Reference to the main game object
*/
@@ -97,9 +93,9 @@ module Phaser {
public alive: bool;
/**
- * Sprite physics.
+ * Sprite physics body.
*/
- public physics: Phaser.Components.Physics;
+ public body: Phaser.Physics.Body;
/**
* The texture used to render the Sprite.
@@ -160,26 +156,26 @@ module Phaser {
public z: number = 0;
/**
- * This value is added to the rotation of the Sprite.
+ * This value is added to the angle of the Sprite.
* For example if you had a sprite graphic drawn facing straight up then you could set
- * rotationOffset to 90 and it would correspond correctly with Phasers right-handed coordinate system.
+ * angleOffset to 90 and it would correspond correctly with Phasers right-handed coordinate system.
* @type {number}
*/
- public rotationOffset: number = 0;
+ public angleOffset: number = 0;
/**
- * The rotation of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
+ * The angle of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
*/
- public get rotation(): number {
- return this._rotation;
+ public get angle(): number {
+ return this.body.angle;
}
/**
- * Set the rotation of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
+ * Set the angle of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
* The value is automatically wrapped to be between 0 and 360.
*/
- public set rotation(value: number) {
- this._rotation = this.game.math.wrap(value, 360, 0);
+ public set angle(value: number) {
+ this.body.angle = this.game.math.wrap(value, 360, 0);
}
/**
@@ -234,7 +230,7 @@ module Phaser {
this.frameBounds.x = this.x;
this.frameBounds.y = this.y;
- if (this.modified == false && (!this.scale.equals(1) || !this.skew.equals(0) || this.rotation != 0 || this.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY))
+ if (this.modified == false && (!this.scale.equals(1) || !this.skew.equals(0) || this.angle != 0 || this.angleOffset != 0 || this.texture.flippedX || this.texture.flippedY))
{
this.modified = true;
}
@@ -253,7 +249,7 @@ module Phaser {
public postUpdate() {
this.animations.update();
- this.physics.update();
+ this.body.postUpdate();
/*
if (this.worldBounds != null)
@@ -287,15 +283,11 @@ module Phaser {
}
}
- this.collisionMask.update();
-
if (this.inputEnabled)
{
this.updateInput();
}
- this.wasTouching = this.touching;
- this.touching = Collision.NONE;
*/
if (this.modified == true && this.scale.equals(1) && this.skew.equals(0) && this.rotation == 0 && this.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false)
diff --git a/Phaser/physics/Body.ts b/Phaser/physics/Body.ts
new file mode 100644
index 00000000..318aaccf
--- /dev/null
+++ b/Phaser/physics/Body.ts
@@ -0,0 +1,285 @@
+///
+///
+///
+///
+///
+///
+
+/**
+* Phaser - Physics - Body
+*/
+
+module Phaser.Physics {
+
+ export class Body {
+
+ constructor(parent: Sprite, type: number) {
+
+ this.parent = parent;
+ this.game = parent.game;
+ this.type = type;
+
+ // Fixture properties
+ // Will extend into its own class at a later date - can move the fixture defs there and add shape support, but this will do for 1.0 release
+ this.bounds = new Rectangle(parent.x + Math.round(parent.width / 2), parent.y + Math.round(parent.height / 2), parent.width, parent.height);
+ this.bounce = Vec2Utils.clone(this.game.world.physics.bounce);
+
+ // Body properties
+ this.gravity = Vec2Utils.clone(this.game.world.physics.gravity);
+
+ this.velocity = new Vec2;
+ this.acceleration = new Vec2;
+ this.drag = Vec2Utils.clone(this.game.world.physics.drag);
+ this.maxVelocity = new Vec2(10000, 10000);
+
+ this.angle = 0;
+ this.angularVelocity = 0;
+ this.angularAcceleration = 0;
+ this.angularDrag = 0;
+
+ this.touching = Types.NONE;
+ this.wasTouching = Types.NONE;
+ this.allowCollisions = Types.ANY;
+
+ this.position = new Vec2(parent.x + this.bounds.halfWidth, parent.y + this.bounds.halfHeight);
+ this.oldPosition = new Vec2(parent.x + this.bounds.halfWidth, parent.y + this.bounds.halfHeight);
+ this.offset = new Vec2;
+
+ }
+
+ public game: Game;
+ public parent: Sprite;
+
+ /**
+ * The type of Body (disabled, dynamic, static or kinematic)
+ * Disabled = skips all physics operations / tests (default)
+ * Dynamic = gives and receives impacts
+ * Static = gives but doesn't receive impacts, cannot be moved by physics
+ * Kinematic = gives impacts, but never receives, can be moved by physics
+ * @type {number}
+ */
+ public type: number;
+
+ public gravity: Vec2;
+ public bounce: Vec2;
+
+ public velocity: Vec2;
+ public acceleration: Vec2;
+ public drag: Vec2;
+ public maxVelocity: Vec2;
+
+ public angularVelocity: number = 0;
+ public angularAcceleration: number = 0;
+ public angularDrag: number = 0;
+ public maxAngular: number = 10000;
+
+ /**
+ * Angle of rotation of this body.
+ * @type {number}
+ */
+ public angle: number;
+
+ /**
+ * Orientation of the object.
+ * @type {number}
+ */
+ public facing: number;
+
+ public touching: number;
+ public allowCollisions: number;
+ public wasTouching: number;
+ public mass: number = 1;
+
+ public position: Vec2;
+ public oldPosition: Vec2;
+ public offset: Vec2;
+ public bounds: Rectangle;
+
+
+
+
+ public preUpdate() {
+
+ this.oldPosition.copyFrom(this.position);
+
+ this.bounds.x = this.position.x - this.bounds.halfWidth;
+ this.bounds.y = this.position.y - this.bounds.halfHeight;
+
+ if (this.parent.scale.equals(1) == false)
+ {
+ }
+
+ }
+
+ // Shall we do this? Or just update the values directly in the separate functions? But then the bounds will be out of sync - as long as
+ // the bounds are updated and used in calculations then we can do one final sprite movement here I guess?
+ public postUpdate() {
+
+ // if this is all it does maybe move elsewhere? Sprite postUpdate?
+ if (this.type !== Phaser.Types.BODY_DISABLED)
+ {
+ this.game.world.physics.updateMotion(this);
+
+ this.parent.x = (this.position.x - this.bounds.halfWidth) - this.offset.x;
+ this.parent.y = (this.position.y - this.bounds.halfHeight) - this.offset.y;
+
+ this.wasTouching = this.touching;
+ this.touching = Phaser.Types.NONE;
+
+ }
+
+ }
+
+ public get hullWidth(): number {
+
+ if (this.deltaX > 0)
+ {
+ return this.bounds.width + this.deltaX;
+ }
+ else
+ {
+ return this.bounds.width - this.deltaX;
+ }
+
+ }
+
+ public get hullHeight(): number {
+
+ if (this.deltaY > 0)
+ {
+ return this.bounds.height + this.deltaY;
+ }
+ else
+ {
+ return this.bounds.height - this.deltaY;
+ }
+
+ }
+
+ public get hullX(): number {
+
+ if (this.position.x < this.oldPosition.x)
+ {
+ return this.position.x;
+ }
+ else
+ {
+ return this.oldPosition.x;
+ }
+
+ }
+
+ public get hullY(): number {
+
+ if (this.position.y < this.oldPosition.y)
+ {
+ return this.position.y;
+ }
+ else
+ {
+ return this.oldPosition.y;
+ }
+
+ }
+
+ public get deltaXAbs(): number {
+ return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
+ }
+
+ public get deltaYAbs(): number {
+ return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
+ }
+
+ public get deltaX(): number {
+ return this.position.x - this.oldPosition.x;
+ }
+
+ public get deltaY(): number {
+ return this.position.y - this.oldPosition.y;
+ }
+
+
+
+
+
+
+
+
+
+
+ // MOVE THESE TO A UTIL
+
+ public render(context:CanvasRenderingContext2D) {
+
+ context.beginPath();
+ context.strokeStyle = 'rgb(0,255,0)';
+ context.strokeRect(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight, this.bounds.width, this.bounds.height);
+ context.stroke();
+ context.closePath();
+
+ // center point
+ context.fillStyle = 'rgb(0,255,0)';
+ context.fillRect(this.position.x, this.position.y, 2, 2);
+
+ if (this.touching & Phaser.Types.LEFT)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if (this.touching & Phaser.Types.RIGHT)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+
+ if (this.touching & Phaser.Types.UP)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if (this.touching & Phaser.Types.DOWN)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+
+ }
+
+
+ /**
+ * Render debug infos. (including name, bounds info, position and some other properties)
+ * @param x {number} X position of the debug info to be rendered.
+ * @param y {number} Y position of the debug info to be rendered.
+ * @param [color] {number} color of the debug info to be rendered. (format is css color string)
+ */
+ public renderDebugInfo(x: number, y: number, color?: string = 'rgb(255,255,255)') {
+
+ this.parent.texture.context.fillStyle = color;
+ this.parent.texture.context.fillText('Sprite: (' + this.parent.frameBounds.width + ' x ' + this.parent.frameBounds.height + ')', x, y);
+ //this.parent.texture.context.fillText('x: ' + this._parent.frameBounds.x.toFixed(1) + ' y: ' + this._parent.frameBounds.y.toFixed(1) + ' rotation: ' + this._parent.rotation.toFixed(1), x, y + 14);
+ this.parent.texture.context.fillText('x: ' + this.shape.bounds.x.toFixed(1) + ' y: ' + this.shape.bounds.y.toFixed(1) + ' rotation: ' + this._parent.rotation.toFixed(1), x, y + 14);
+ this.parent.texture.context.fillText('vx: ' + this.velocity.x.toFixed(1) + ' vy: ' + this.velocity.y.toFixed(1), x, y + 28);
+ this.parent.texture.context.fillText('ax: ' + this.acceleration.x.toFixed(1) + ' ay: ' + this.acceleration.y.toFixed(1), x, y + 42);
+
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/Phaser/physics/Fixture.ts b/Phaser/physics/Fixture.ts
new file mode 100644
index 00000000..3b0e20b4
--- /dev/null
+++ b/Phaser/physics/Fixture.ts
@@ -0,0 +1,31 @@
+///
+///
+///
+///
+///
+///
+
+/**
+* Phaser - Physics - Fixture
+*/
+
+module Phaser.Physics {
+
+ export class Fixture {
+
+ constructor(parent: Sprite, type: number) {
+
+ this.parent = parent;
+
+ // these are shape properties really
+ this.bounce = Vec2Utils.clone(this.game.world.physics.bounce);
+ this.friction = Vec2Utils.clone(this.game.world.physics.friction);
+
+ }
+
+ public game: Game;
+ public parent: Sprite;
+
+ }
+
+}
\ No newline at end of file
diff --git a/Phaser/physics/IPhysicsBody.ts b/Phaser/physics/IPhysicsBody.ts
new file mode 100644
index 00000000..6dbf961e
--- /dev/null
+++ b/Phaser/physics/IPhysicsBody.ts
@@ -0,0 +1,40 @@
+///
+///
+///
+
+/**
+* Phaser - Physics - IPhysicsShape
+*/
+
+module Phaser.Physics {
+
+ export interface IPhysicsBody {
+
+ //game: Game;
+ //world: PhysicsManager;
+ //sprite: Sprite;
+ //physics: Phaser.Components.Physics;
+
+ //position: Vec2;
+ //oldPosition: Vec2;
+ //offset: Vec2;
+
+ //bounds: Rectangle;
+
+ //setSize(width: number, height: number);
+ //preUpdate();
+ //update();
+ //render(context:CanvasRenderingContext2D);
+
+ //hullX;
+ //hullY;
+ //hullWidth;
+ //hullHeight;
+ //deltaX;
+ //deltaY;
+ //deltaXAbs;
+ //deltaYAbs;
+
+ }
+
+}
diff --git a/Phaser/physics/PhysicsManager.ts b/Phaser/physics/PhysicsManager.ts
index c34327ec..7104d66e 100644
--- a/Phaser/physics/PhysicsManager.ts
+++ b/Phaser/physics/PhysicsManager.ts
@@ -1,7 +1,8 @@
///
-///
///
///
+///
+///
/**
* Phaser - PhysicsManager
@@ -21,14 +22,14 @@ module Phaser.Physics {
this.gravity = new Vec2;
this.drag = new Vec2;
this.bounce = new Vec2;
- this.friction = new Vec2;
+ this.angularDrag = 0;
this.bounds = new Rectangle(0, 0, width, height);
this._distance = new Vec2;
this._tangent = new Vec2;
- this._objects = [];
+ this.members = new Group(game);
}
@@ -37,7 +38,10 @@ module Phaser.Physics {
*/
public game: Game;
- private _objects: IPhysicsShape[];
+ /**
+ * Physics object pool
+ */
+ public members: Group;
// Temp calculation vars
private _drag: number;
@@ -46,15 +50,38 @@ module Phaser.Physics {
private _length: number = 0;
private _distance: Vec2;
private _tangent: Vec2;
+ private _separatedX: bool;
+ private _separatedY: bool;
+ private _overlap: number;
+ private _maxOverlap: number;
+ private _obj1Velocity: number;
+ private _obj2Velocity: number;
+ private _obj1NewVelocity: number;
+ private _obj2NewVelocity: number;
+ private _average: number;
+ private _quadTree: QuadTree;
+ private _quadTreeResult: bool;
+
+
+
public bounds: Rectangle;
public gravity: Vec2;
public drag: Vec2;
public bounce: Vec2;
- public friction: Vec2;
+ public angularDrag: number;
+
+ static OVERLAP_BIAS: number = 4;
+
+ /**
+ * @type {number}
+ */
+ public worldDivisions: number = 6;
+
// Add some sanity checks here + remove method, etc
+ /*
public add(shape: IPhysicsShape): IPhysicsShape {
this._objects.push(shape);
@@ -115,32 +142,31 @@ module Phaser.Physics {
}
}
+*/
- private updateMotion(shape: IPhysicsShape) {
+ public updateMotion(body: Phaser.Physics.Body) {
- if (shape.physics.moves == false)
+ if (body.type == Types.BODY_DISABLED)
{
return;
}
- /*
- velocityDelta = (this._game.motion.computeVelocity(this.angularVelocity, this.angularAcceleration, this.angularDrag, this.maxAngular) - this.angularVelocity) / 2;
- this.angularVelocity += velocityDelta;
- this._angle += this.angularVelocity * this._game.time.elapsed;
- this.angularVelocity += velocityDelta;
- */
+ this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
+ body.angularVelocity += this._velocityDelta;
+ body.angle += body.angularVelocity * this.game.time.elapsed;
+ body.angularVelocity += this._velocityDelta;
- this._velocityDelta = (this.computeVelocity(shape.physics.velocity.x, shape.physics.gravity.x, shape.physics.acceleration.x, shape.physics.drag.x) - shape.physics.velocity.x) / 2;
- shape.physics.velocity.x += this._velocityDelta;
- this._delta = shape.physics.velocity.x * this.game.time.elapsed;
- shape.physics.velocity.x += this._velocityDelta;
- shape.position.x += this._delta;
+ this._velocityDelta = (this.computeVelocity(body.velocity.x, body.gravity.x, body.acceleration.x, body.drag.x) - body.velocity.x) / 2;
+ body.velocity.x += this._velocityDelta;
+ this._delta = body.velocity.x * this.game.time.elapsed;
+ body.velocity.x += this._velocityDelta;
+ body.position.x += this._delta;
- this._velocityDelta = (this.computeVelocity(shape.physics.velocity.y, shape.physics.gravity.y, shape.physics.acceleration.y, shape.physics.drag.y) - shape.physics.velocity.y) / 2;
- shape.physics.velocity.y += this._velocityDelta;
- this._delta = shape.physics.velocity.y * this.game.time.elapsed;
- shape.physics.velocity.y += this._velocityDelta;
- shape.position.y += this._delta;
+ this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2;
+ body.velocity.y += this._velocityDelta;
+ this._delta = body.velocity.y * this.game.time.elapsed;
+ body.velocity.y += this._velocityDelta;
+ body.position.y += this._delta;
}
@@ -265,17 +291,17 @@ module Phaser.Physics {
}
/**
- * 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.
+ * The core Collision separation method.
+ * @param body1 The first Physics.Body to separate
+ * @param body2 The second Physics.Body to separate
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
*/
- public NEWseparate(object1, object2): bool {
+ public separate(body1: Body, body2: Body): bool {
- var separatedX: bool = this.separateSpriteToSpriteX(object1, object2);
- var separatedY: bool = this.separateSpriteToSpriteY(object1, object2);
+ this._separatedX = this.separateBodyX(body1, body2);
+ this._separatedY = this.separateBodyY(body1, body2);
- return separatedX || separatedY;
+ return this._separatedX || this._separatedY;
}
@@ -300,98 +326,95 @@ module Phaser.Physics {
* @param object2 The second GameObject to separate
* @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
*/
- public separateSpriteToSpriteX(object1:Sprite, object2:Sprite): bool {
+ public separateBodyX(body1: Body, body2: Body): bool {
- // Can't separate two immovable objects
- if (object1.physics.immovable && object2.physics.immovable)
+ // Can't separate two disabled or static objects
+ if ((body1.type == Types.BODY_DISABLED || body1.type == Types.BODY_STATIC) && (body2.type == Types.BODY_DISABLED || body2.type == Types.BODY_STATIC))
{
return false;
}
// First, get the two object deltas
- var overlap: number = 0;
+ this._overlap = 0;
- if (object1.physics.shape.deltaX != object2.physics.shape.deltaX)
+ if (body1.deltaX != body2.deltaX)
{
- //var intersects: bool = false;
-
- //if (object1.physics.shape['radius'])
- //{
- // intersects = CircleUtils.intersectsRectangle(object1.physics.shape, object2.physics.shape.bounds)
- //}
- //else
- //{
- // intersects = RectangleUtils.intersects(object1.physics.shape.bounds, object2.physics.shape.bounds)
- //}
-
- if (RectangleUtils.intersects(object1.physics.shape.bounds, object2.physics.shape.bounds))
+ if (RectangleUtils.intersects(body1.bounds, body2.bounds))
{
- //var maxOverlap: number = object1.physics.shape.deltaXAbs + object2.physics.shape.deltaXAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object1.physics.shape.deltaXAbs + object2.physics.shape.deltaXAbs + 4;
+ this._maxOverlap = body1.deltaXAbs + body2.deltaXAbs + PhysicsManager.OVERLAP_BIAS;
// If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object1.physics.shape.deltaX > object2.physics.shape.deltaX)
+ if (body1.deltaX > body2.deltaX)
{
- overlap = object1.physics.shape.bounds.right - object2.physics.shape.bounds.x;
+ this._overlap = body1.bounds.right - body2.bounds.x;
- if ((overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.RIGHT) || !(object2.physics.allowCollisions & Phaser.Types.LEFT))
+ if ((this._overlap > this._maxOverlap) || !(body1.allowCollisions & Types.RIGHT) || !(body2.allowCollisions & Types.LEFT))
{
- overlap = 0;
+ this._overlap = 0;
}
else
{
- object1.physics.touching |= Phaser.Types.RIGHT;
- object2.physics.touching |= Phaser.Types.LEFT;
+ body1.touching |= Types.RIGHT;
+ body2.touching |= Types.LEFT;
}
}
- else if (object1.physics.shape.deltaX < object2.physics.shape.deltaX)
+ else if (body1.deltaX < body2.deltaX)
{
- overlap = object1.physics.shape.bounds.x - object2.physics.shape.bounds.width - object2.physics.shape.bounds.x;
+ this._overlap = body1.bounds.x - body2.bounds.width - body2.bounds.x;
- if ((-overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.LEFT) || !(object2.physics.allowCollisions & Phaser.Types.RIGHT))
+ if ((-this._overlap > this._maxOverlap) || !(body1.allowCollisions & Types.LEFT) || !(body2.allowCollisions & Types.RIGHT))
{
- overlap = 0;
+ this._overlap = 0;
}
else
{
- object1.physics.touching |= Phaser.Types.LEFT;
- object2.physics.touching |= Phaser.Types.RIGHT;
+ body1.touching |= Types.LEFT;
+ body2.touching |= Types.RIGHT;
}
}
}
}
// Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
+ if (this._overlap != 0)
{
- var obj1Velocity: number = object1.physics.velocity.x;
- var obj2Velocity: number = object2.physics.velocity.x;
+ this._obj1Velocity = body1.velocity.x;
+ this._obj2Velocity = body2.velocity.x;
- if (!object1.physics.immovable && !object2.physics.immovable)
- {
- overlap *= 0.5;
- object1.physics.shape.position.x = object1.physics.shape.position.x - overlap;
- object2.physics.shape.position.x += overlap;
+ /**
+ * Dynamic = gives and receives impacts
+ * Static = gives but doesn't receive impacts, cannot be moved by physics
+ * Kinematic = gives impacts, but never receives, can be moved by physics
+ */
- var obj1NewVelocity: number = Math.sqrt((obj2Velocity * obj2Velocity * object2.physics.mass) / object1.physics.mass) * ((obj2Velocity > 0) ? 1 : -1);
- var obj2NewVelocity: number = Math.sqrt((obj1Velocity * obj1Velocity * object1.physics.mass) / object2.physics.mass) * ((obj1Velocity > 0) ? 1 : -1);
- var average: number = (obj1NewVelocity + obj2NewVelocity) * 0.5;
- obj1NewVelocity -= average;
- obj2NewVelocity -= average;
- object1.physics.velocity.x = average + obj1NewVelocity * object1.physics.bounce.x;
- object2.physics.velocity.x = average + obj2NewVelocity * object2.physics.bounce.x;
- }
- else if (!object1.physics.immovable)
+ // 2 dynamic bodies will exchange velocities
+ if (body1.type == Types.BODY_DYNAMIC && body2.type == Types.BODY_DYNAMIC)
{
- overlap *= 2;
- object1.physics.shape.position.x -= overlap;
- object1.physics.velocity.x = obj2Velocity - obj1Velocity * object1.physics.bounce.x;
+ this._overlap *= 0.5;
+ body1.position.x = body1.position.x - this._overlap;
+ body2.position.x += this._overlap;
+
+ this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * body2.mass) / body1.mass) * ((this._obj2Velocity > 0) ? 1 : -1);
+ this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * body1.mass) / body2.mass) * ((this._obj1Velocity > 0) ? 1 : -1);
+ this._average = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5;
+ this._obj1NewVelocity -= this._average;
+ this._obj2NewVelocity -= this._average;
+ body1.velocity.x = this._average + this._obj1NewVelocity * body1.bounce.x;
+ body2.velocity.x = this._average + this._obj2NewVelocity * body2.bounce.x;
}
- else if (!object2.physics.immovable)
+ else if (body2.type != Types.BODY_DYNAMIC)
{
- overlap *= 2;
- object2.physics.shape.position.x += overlap;
- object2.physics.velocity.x = obj1Velocity - obj2Velocity * object2.physics.bounce.x;
+ // Body 2 is Static or Kinematic
+ this._overlap *= 2;
+ body1.position.x -= this._overlap;
+ body1.velocity.x = this._obj2Velocity - this._obj1Velocity * body1.bounce.x;
+ }
+ else if (body1.type != Types.BODY_DYNAMIC)
+ {
+ // Body 1 is Static or Kinematic
+ this._overlap *= 2;
+ body2.position.x += this._overlap;
+ body2.velocity.x = this._obj1Velocity - this._obj2Velocity * body2.bounce.x;
}
return true;
@@ -409,96 +432,104 @@ module Phaser.Physics {
* @param object2 The second GameObject to separate
* @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
*/
- public separateSpriteToSpriteY(object1:Sprite, object2:Sprite): bool {
+ public separateBodyY(body1: Body, body2: Body): bool {
// Can't separate two immovable objects
- if (object1.physics.immovable && object2.physics.immovable) {
+ if ((body1.type == Types.BODY_DISABLED || body1.type == Types.BODY_STATIC) && (body2.type == Types.BODY_DISABLED || body2.type == Types.BODY_STATIC))
+ {
return false;
}
// First, get the two object deltas
- var overlap: number = 0;
+ this._overlap = 0;
- if (object1.physics.shape.deltaY != object2.physics.shape.deltaY)
+ if (body1.deltaY != body2.deltaY)
{
- if (RectangleUtils.intersects(object1.physics.shape.bounds, object2.physics.shape.bounds))
+ if (RectangleUtils.intersects(body1.bounds, body2.bounds))
{
// This is the only place to use the DeltaAbs values
- //var maxOverlap: number = object1.physics.shape.deltaYAbs + object2.physics.shape.deltaYAbs + Phaser.Types.OVERLAP_BIAS;
- var maxOverlap: number = object1.physics.shape.deltaYAbs + object2.physics.shape.deltaYAbs + 4;
+ this._maxOverlap = body1.deltaYAbs + body2.deltaYAbs + PhysicsManager.OVERLAP_BIAS;
// If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object1.physics.shape.deltaY > object2.physics.shape.deltaY)
+ if (body1.deltaY > body2.deltaY)
{
- overlap = object1.physics.shape.bounds.bottom - object2.physics.shape.bounds.y;
+ this._overlap = body1.bounds.bottom - body2.bounds.y;
- if ((overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.DOWN) || !(object2.physics.allowCollisions & Phaser.Types.UP))
+ if ((this._overlap > this._maxOverlap) || !(body1.allowCollisions & Types.DOWN) || !(body2.allowCollisions & Types.UP))
{
- overlap = 0;
+ this._overlap = 0;
}
else
{
- object1.physics.touching |= Phaser.Types.DOWN;
- object2.physics.touching |= Phaser.Types.UP;
+ body1.touching |= Types.DOWN;
+ body2.touching |= Types.UP;
}
}
- else if (object1.physics.shape.deltaY < object2.physics.shape.deltaY)
+ else if (body1.deltaY < body2.deltaY)
{
- overlap = object1.physics.shape.bounds.y - object2.physics.shape.bounds.height - object2.physics.shape.bounds.y;
+ this._overlap = body1.bounds.y - body2.bounds.height - body2.bounds.y;
- if ((-overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.UP) || !(object2.physics.allowCollisions & Phaser.Types.DOWN))
+ if ((-this._overlap > this._maxOverlap) || !(body1.allowCollisions & Types.UP) || !(body2.allowCollisions & Types.DOWN))
{
- overlap = 0;
+ this._overlap = 0;
}
else
{
- object1.physics.touching |= Phaser.Types.UP;
- object2.physics.touching |= Phaser.Types.DOWN;
+ body1.touching |= Types.UP;
+ body2.touching |= Types.DOWN;
}
}
}
}
// Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
+ if (this._overlap != 0)
{
- var obj1Velocity: number = object1.physics.velocity.y;
- var obj2Velocity: number = object2.physics.velocity.y;
+ this._obj1Velocity = body1.velocity.y;
+ this._obj2Velocity = body2.velocity.y;
- if (!object1.physics.immovable && !object2.physics.immovable)
+ /**
+ * Dynamic = gives and receives impacts
+ * Static = gives but doesn't receive impacts, cannot be moved by physics
+ * Kinematic = gives impacts, but never receives, can be moved by physics
+ */
+
+ if (body1.type == Types.BODY_DYNAMIC && body2.type == Types.BODY_DYNAMIC)
{
- overlap *= 0.5;
- object1.physics.shape.position.y = object1.physics.shape.position.y - overlap;
- object2.physics.shape.position.y += overlap;
+ this._overlap *= 0.5;
+ body1.position.y = body1.position.y - this._overlap;
+ body2.position.y += this._overlap;
- var obj1NewVelocity: number = Math.sqrt((obj2Velocity * obj2Velocity * object2.physics.mass) / object1.physics.mass) * ((obj2Velocity > 0) ? 1 : -1);
- var obj2NewVelocity: number = Math.sqrt((obj1Velocity * obj1Velocity * object1.physics.mass) / object2.physics.mass) * ((obj1Velocity > 0) ? 1 : -1);
- var average: number = (obj1NewVelocity + obj2NewVelocity) * 0.5;
- obj1NewVelocity -= average;
- obj2NewVelocity -= average;
- object1.physics.velocity.y = average + obj1NewVelocity * object1.physics.bounce.y;
- object2.physics.velocity.y = average + obj2NewVelocity * object2.physics.bounce.y;
+ this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * body2.mass) / body1.mass) * ((this._obj2Velocity > 0) ? 1 : -1);
+ this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * body1.mass) / body2.mass) * ((this._obj1Velocity > 0) ? 1 : -1);
+ var average: number = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5;
+ this._obj1NewVelocity -= average;
+ this._obj2NewVelocity -= average;
+ body1.velocity.y = average + this._obj1NewVelocity * body1.bounce.y;
+ body2.velocity.y = average + this._obj2NewVelocity * body2.bounce.y;
}
- else if (!object1.physics.immovable)
+ else if (body2.type != Types.BODY_DYNAMIC)
{
- overlap *= 2;
- object1.physics.shape.position.y -= overlap;
- object1.physics.velocity.y = obj2Velocity - obj1Velocity * object1.physics.bounce.y;
+ this._overlap *= 2;
+ body1.position.y -= this._overlap;
+ body1.velocity.y = this._obj2Velocity - this._obj1Velocity * body1.bounce.y;
// This is special case code that handles things like horizontal moving platforms you can ride
- if (object2.active && object2.physics.moves && (object1.physics.shape.deltaY > object2.physics.shape.deltaY))
+ //if (body2.parent.active && body2.moves && (body1.deltaY > body2.deltaY))
+ if (body2.parent.active && (body1.deltaY > body2.deltaY))
{
- object1.physics.shape.position.x += object2.physics.shape.position.x - object2.physics.shape.oldPosition.x;
+ body1.position.x += body2.position.x - body2.oldPosition.x;
}
}
- else if (!object2.physics.immovable)
+ else if (body1.type != Types.BODY_DYNAMIC)
{
- overlap *= 2;
- object2.physics.shape.position.y += overlap;
- object2.physics.velocity.y = obj1Velocity - obj2Velocity * object2.physics.bounce.y;
+ this._overlap *= 2;
+ body2.position.y += this._overlap;
+ body2.velocity.y = this._obj1Velocity - this._obj2Velocity * body2.bounce.y;
// This is special case code that handles things like horizontal moving platforms you can ride
- if (object1.active && object1.physics.moves && (object1.physics.shape.deltaY < object2.physics.shape.deltaY))
+ //if (object1.active && body1.moves && (body1.deltaY < body2.deltaY))
+ if (body1.parent.active && (body1.deltaY < body2.deltaY))
{
- object2.physics.shape.position.x += object1.physics.shape.position.x - object1.physics.shape.oldPosition.x;
+ body2.position.x += body1.position.x - body1.oldPosition.x;
}
}
@@ -517,7 +548,7 @@ module Phaser.Physics {
- private separate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
+ private OLDseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
if (tangent.x == 1)
{
@@ -777,83 +808,21 @@ module Phaser.Physics {
}
- private OLDseparate(shape:IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- // collision edges
- //shape.oH = tangent.x;
- //shape.oV = tangent.y;
-
- // Velocity (move to temp vars)
-
- // was vx/vy
- var velocity: Vec2 = Vec2Utils.subtract(shape.position, shape.oldPosition);
-
- // was dp
- var dot: number = Vec2Utils.dot(shape.physics.velocity, tangent);
-
- // project velocity onto the collision normal
- // was nx/ny
- tangent.multiplyByScalar(dot);
-
- // was tx/ty (tangent velocity?)
- var tangentVelocity: Vec2 = Vec2Utils.subtract(velocity, tangent);
-
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- if (dot < 0)
- {
- // Apply horizontal bounce
- if (distance.x != 0)
- {
- if (shape.physics.bounce.x > 0)
- {
- shape.physics.velocity.x *= -(shape.physics.bounce.x);
- }
- else
- {
- shape.physics.velocity.x = 0;
- }
- }
-
- // Apply vertical bounce
- if (distance.y != 0)
- {
- if (shape.physics.bounce.y > 0)
- {
- shape.physics.velocity.y *= -(shape.physics.bounce.y);
- }
- else
- {
- shape.physics.velocity.y = 0;
- }
- }
- }
- else
- {
- // moving out of collision
- }
-
- // project object out of collision
- //console.log('proj out', distance.x, distance.y,'dot',dot);
- shape.position.add(distance);
-
- }
-
/**
- * Checks for overlaps between two objects using the world QuadTree. Can be GameObject vs. GameObject, GameObject vs. Group or Group vs. Group.
+ * Checks for overlaps between two objects using the world QuadTree. Can be Sprite vs. Sprite, Sprite 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 object1 The first Sprite or Group to check. If null the world.group is used.
+ * @param object2 The second Sprite 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.
* @param context The context in which the callbacks will be called
* @returns {boolean} true if the objects overlap, otherwise false.
*/
- /*
- public overlap(object1: Basic = null, object2: Basic = null, notifyCallback = null, processCallback = null, context = null): bool {
+ public overlap(object1 = null, object2 = null, notifyCallback = null, processCallback = null, context = null): bool {
if (object1 == null)
{
- object1 = this._game.world.group;
+ object1 = this.game.world.group;
}
if (object2 == object1)
@@ -861,23 +830,21 @@ module Phaser.Physics {
object2 = null;
}
- QuadTree.divisions = this._game.world.worldDivisions;
+ QuadTree.divisions = this.worldDivisions;
- var quadTree: QuadTree = new QuadTree(this._game.world.bounds.x, this._game.world.bounds.y, this._game.world.bounds.width, this._game.world.bounds.height);
+ this._quadTree = new QuadTree(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
- quadTree.load(object1, object2, notifyCallback, processCallback, context);
+ this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
- var result: bool = quadTree.execute();
+ this._quadTreeResult = this._quadTree.execute();
- quadTree.destroy();
+ this._quadTree.destroy();
- quadTree = null;
+ this._quadTree = null;
- return result;
+ return this._quadTreeResult;
}
- */
-
}
diff --git a/Phaser/math/QuadTree.ts b/Phaser/physics/QuadTree.ts
similarity index 89%
rename from Phaser/math/QuadTree.ts
rename to Phaser/physics/QuadTree.ts
index 33253e36..e6aa9831 100644
--- a/Phaser/math/QuadTree.ts
+++ b/Phaser/physics/QuadTree.ts
@@ -1,5 +1,5 @@
///
-///
+///
///
/**
@@ -10,7 +10,7 @@
* or the A list against the B list. Handy for different things!
*/
-module Phaser {
+module Phaser.Physics {
export class QuadTree extends Rectangle {
@@ -333,7 +333,7 @@ module Phaser {
QuadTree._list = list;
- if (objectOrGroup.isGroup == true)
+ if (objectOrGroup.type == Types.GROUP)
{
this._i = 0;
this._members = objectOrGroup['members'];
@@ -353,7 +353,7 @@ module Phaser {
{
QuadTree._object = this._basic;
- if (QuadTree._object.exists && QuadTree._object.allowCollisions)
+ if (QuadTree._object.exists && QuadTree._object.body.allowCollisions)
{
this.addObject();
}
@@ -365,7 +365,7 @@ module Phaser {
{
QuadTree._object = objectOrGroup;
- if (QuadTree._object.exists && QuadTree._object.allowCollisions)
+ if (QuadTree._object.exists && QuadTree._object.body.allowCollisions)
{
this.addObject();
}
@@ -379,16 +379,16 @@ module Phaser {
private addObject() {
//If this quad (not its children) lies entirely inside this object, add it here
- if (!this._canSubdivide || ((this._leftEdge >= QuadTree._object.collisionMask.x) && (this._rightEdge <= QuadTree._object.collisionMask.right) && (this._topEdge >= QuadTree._object.collisionMask.y) && (this._bottomEdge <= QuadTree._object.collisionMask.bottom)))
+ if (!this._canSubdivide || ((this._leftEdge >= QuadTree._object.body.bounds.x) && (this._rightEdge <= QuadTree._object.body.bounds.right) && (this._topEdge >= QuadTree._object.body.bounds.y) && (this._bottomEdge <= QuadTree._object.body.bounds.bottom)))
{
this.addToList();
return;
}
//See if the selected object fits completely inside any of the quadrants
- if ((QuadTree._object.collisionMask.x > this._leftEdge) && (QuadTree._object.collisionMask.right < this._midpointX))
+ if ((QuadTree._object.body.bounds.x > this._leftEdge) && (QuadTree._object.body.bounds.right < this._midpointX))
{
- if ((QuadTree._object.collisionMask.y > this._topEdge) && (QuadTree._object.collisionMask.bottom < this._midpointY))
+ if ((QuadTree._object.body.bounds.y > this._topEdge) && (QuadTree._object.body.bounds.bottom < this._midpointY))
{
if (this._northWestTree == null)
{
@@ -399,7 +399,7 @@ module Phaser {
return;
}
- if ((QuadTree._object.collisionMask.y > this._midpointY) && (QuadTree._object.collisionMask.bottom < this._bottomEdge))
+ if ((QuadTree._object.body.bounds.y > this._midpointY) && (QuadTree._object.body.bounds.bottom < this._bottomEdge))
{
if (this._southWestTree == null)
{
@@ -411,9 +411,9 @@ module Phaser {
}
}
- if ((QuadTree._object.collisionMask.x > this._midpointX) && (QuadTree._object.collisionMask.right < this._rightEdge))
+ if ((QuadTree._object.body.bounds.x > this._midpointX) && (QuadTree._object.body.bounds.right < this._rightEdge))
{
- if ((QuadTree._object.collisionMask.y > this._topEdge) && (QuadTree._object.collisionMask.bottom < this._midpointY))
+ if ((QuadTree._object.body.bounds.y > this._topEdge) && (QuadTree._object.body.bounds.bottom < this._midpointY))
{
if (this._northEastTree == null)
{
@@ -424,7 +424,7 @@ module Phaser {
return;
}
- if ((QuadTree._object.collisionMask.y > this._midpointY) && (QuadTree._object.collisionMask.bottom < this._bottomEdge))
+ if ((QuadTree._object.body.bounds.y > this._midpointY) && (QuadTree._object.body.bounds.bottom < this._bottomEdge))
{
if (this._southEastTree == null)
{
@@ -437,7 +437,7 @@ module Phaser {
}
//If it wasn't completely contained we have to check out the partial overlaps
- if ((QuadTree._object.collisionMask.right > this._leftEdge) && (QuadTree._object.collisionMask.x < this._midpointX) && (QuadTree._object.collisionMask.bottom > this._topEdge) && (QuadTree._object.collisionMask.y < this._midpointY))
+ if ((QuadTree._object.body.bounds.right > this._leftEdge) && (QuadTree._object.body.bounds.x < this._midpointX) && (QuadTree._object.body.bounds.bottom > this._topEdge) && (QuadTree._object.body.bounds.y < this._midpointY))
{
if (this._northWestTree == null)
{
@@ -447,7 +447,7 @@ module Phaser {
this._northWestTree.addObject();
}
- if ((QuadTree._object.collisionMask.right > this._midpointX) && (QuadTree._object.collisionMask.x < this._rightEdge) && (QuadTree._object.collisionMask.bottom > this._topEdge) && (QuadTree._object.collisionMask.y < this._midpointY))
+ if ((QuadTree._object.body.bounds.right > this._midpointX) && (QuadTree._object.body.bounds.x < this._rightEdge) && (QuadTree._object.body.bounds.bottom > this._topEdge) && (QuadTree._object.body.bounds.y < this._midpointY))
{
if (this._northEastTree == null)
{
@@ -457,7 +457,7 @@ module Phaser {
this._northEastTree.addObject();
}
- if ((QuadTree._object.collisionMask.right > this._midpointX) && (QuadTree._object.collisionMask.x < this._rightEdge) && (QuadTree._object.collisionMask.bottom > this._midpointY) && (QuadTree._object.collisionMask.y < this._bottomEdge))
+ if ((QuadTree._object.body.bounds.right > this._midpointX) && (QuadTree._object.body.bounds.x < this._rightEdge) && (QuadTree._object.body.bounds.bottom > this._midpointY) && (QuadTree._object.body.bounds.y < this._bottomEdge))
{
if (this._southEastTree == null)
{
@@ -467,7 +467,7 @@ module Phaser {
this._southEastTree.addObject();
}
- if ((QuadTree._object.collisionMask.right > this._leftEdge) && (QuadTree._object.collisionMask.x < this._midpointX) && (QuadTree._object.collisionMask.bottom > this._midpointY) && (QuadTree._object.collisionMask.y < this._bottomEdge))
+ if ((QuadTree._object.body.bounds.right > this._leftEdge) && (QuadTree._object.body.bounds.x < this._midpointX) && (QuadTree._object.body.bounds.bottom > this._midpointY) && (QuadTree._object.body.bounds.y < this._bottomEdge))
{
if (this._southWestTree == null)
{
@@ -561,7 +561,7 @@ module Phaser {
QuadTree._iterator = this._iterator.next;
}
- if (QuadTree._object.exists && (QuadTree._object.allowCollisions > 0) && (QuadTree._iterator != null) && (QuadTree._iterator.object != null) && QuadTree._iterator.object.exists && this.overlapNode())
+ if (QuadTree._object.exists && (QuadTree._object.body.allowCollisions > 0) && (QuadTree._iterator != null) && (QuadTree._iterator.object != null) && QuadTree._iterator.object.exists && this.overlapNode())
{
this._overlapProcessed = true;
}
@@ -608,20 +608,20 @@ module Phaser {
while (QuadTree._iterator != null)
{
- if (!QuadTree._object.exists || (QuadTree._object.allowCollisions <= 0))
+ if (!QuadTree._object.exists || (QuadTree._object.body.allowCollisions <= 0))
{
break;
}
this._checkObject = QuadTree._iterator.object;
- if ((QuadTree._object === this._checkObject) || !this._checkObject.exists || (this._checkObject.allowCollisions <= 0))
+ if ((QuadTree._object === this._checkObject) || !this._checkObject.exists || (this._checkObject.body.allowCollisions <= 0))
{
QuadTree._iterator = QuadTree._iterator.next;
continue;
}
- if (QuadTree._object.collisionMask.checkHullIntersection(this._checkObject.collisionMask))
+ if (QuadTree._object.body.bounds.checkHullIntersection(this._checkObject.body.bounds))
{
//Execute callback functions if they exist
if ((QuadTree._processingCallback == null) || QuadTree._processingCallback(QuadTree._object, this._checkObject))
diff --git a/Phaser/renderers/CanvasRenderer.ts b/Phaser/renderers/CanvasRenderer.ts
index ee3b824c..ae96be96 100644
--- a/Phaser/renderers/CanvasRenderer.ts
+++ b/Phaser/renderers/CanvasRenderer.ts
@@ -54,9 +54,6 @@ module Phaser {
this._camera.postRender();
}
- // Physics Debug layer
- this._game.world.physics.render();
-
}
/**
@@ -121,10 +118,10 @@ module Phaser {
// Rotation and Flipped
if (sprite.modified)
{
- if (sprite.texture.renderRotation == true && (sprite.rotation !== 0 || sprite.rotationOffset !== 0))
+ if (sprite.texture.renderRotation == true && (sprite.angle !== 0 || sprite.angleOffset !== 0))
{
- this._sin = Math.sin(sprite.game.math.degreesToRadians(sprite.rotationOffset + sprite.rotation));
- this._cos = Math.cos(sprite.game.math.degreesToRadians(sprite.rotationOffset + sprite.rotation));
+ this._sin = Math.sin(sprite.game.math.degreesToRadians(sprite.angleOffset + sprite.angle));
+ this._cos = Math.cos(sprite.game.math.degreesToRadians(sprite.angleOffset + sprite.angle));
}
// setTransform(a, b, c, d, e, f);
@@ -185,12 +182,6 @@ module Phaser {
sprite.texture.context.restore();
}
- //if (this.renderDebug)
- //{
- // this.renderBounds(camera, cameraOffsetX, cameraOffsetY);
- //this.collisionMask.render(camera, cameraOffsetX, cameraOffsetY);
- //}
-
if (this._ga > -1)
{
sprite.texture.context.globalAlpha = this._ga;
@@ -245,10 +236,10 @@ module Phaser {
// Rotation and Flipped
if (scrollZone.modified)
{
- if (scrollZone.texture.renderRotation == true && (scrollZone.rotation !== 0 || scrollZone.rotationOffset !== 0))
+ if (scrollZone.texture.renderRotation == true && (scrollZone.angle !== 0 || scrollZone.angleOffset !== 0))
{
- this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.rotationOffset + scrollZone.rotation));
- this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.rotationOffset + scrollZone.rotation));
+ this._sin = Math.sin(scrollZone.game.math.degreesToRadians(scrollZone.angleOffset + scrollZone.angle));
+ this._cos = Math.cos(scrollZone.game.math.degreesToRadians(scrollZone.angleOffset + scrollZone.angle));
}
// setTransform(a, b, c, d, e, f);
@@ -300,12 +291,6 @@ module Phaser {
scrollZone.texture.context.restore();
}
- //if (this.renderDebug)
- //{
- // this.renderBounds(camera, cameraOffsetX, cameraOffsetY);
- //this.collisionMask.render(camera, cameraOffsetX, cameraOffsetY);
- //}
-
if (this._ga > -1)
{
scrollZone.texture.context.globalAlpha = this._ga;
diff --git a/README.md b/README.md
index ac070607..8b359d1f 100644
--- a/README.md
+++ b/README.md
@@ -23,13 +23,11 @@ Latest Update
TODO:
* Dispatch world resize event
-* Removed ignoreGlobalUpdate because it checks exists etc in the Group update, so remove those checks from Sprite.update (same for render)
* Investigate why tweens don't restart after the game pauses
* Fix bug in Tween yoyo + loop combo
* Copy the setTransform from Sprite to Camera
* Move Camera.scroll.x to just Camera.x/y
-* Get AABB offset working somehow
-
+* Apply Sprite scaling to Body.bounds
V1.0.0
@@ -49,6 +47,9 @@ V1.0.0
* Added Tween.loop property so they can now re-run themselves indefinitely.
* Added Tween.yoyo property so they can reverse themselves after completing.
* Added Gravity to the Physics component.
+* Removed Sprite.rotation - use Sprite.angle instead
+* Optimised separateX/Y and overlap so they don't use any temporary vars any more.
+* Added the new Physics.Body object to all Sprites. Used for all physics calculations in-game. Will be extended for Fixtures/Joints in future.
V0.9.6
@@ -143,9 +144,7 @@ V0.9.6
* TODO: Game.Time should monitor pause duration
* TODO: Investigate bug re: tilemap collision and animation frames
* TODO: Update tests that use arrow keys and include touch/mouse support (FlxControlHandler style)
-* TODO: GameObject.clipRect - won't work with rotation :( have to use context.clip which is crazy expensive, damnit
* TODO: Polygon geom primitive
-* TODO: Move GameObject transforms to a single matrix
* TODO: this.target.view.style.cursor = "pointer"; ("default")
* TODO: If the Camera is larger than the Stage size then the rotation offset isn't correct
* TODO: Texture Repeat doesn't scroll, because it's part of the camera not the world, need to think about this more
diff --git a/build/phaser.js b/build/phaser.js
index bb887891..a3f9f003 100644
--- a/build/phaser.js
+++ b/build/phaser.js
@@ -3989,10 +3989,1588 @@ var Phaser;
})(Phaser || (Phaser = {}));
///
///
+/**
+* Phaser - Vec2Utils
+*
+* A collection of methods useful for manipulating and performing operations on 2D vectors.
+*
+*/
+var Phaser;
+(function (Phaser) {
+ var Vec2Utils = (function () {
+ function Vec2Utils() { }
+ Vec2Utils.add = /**
+ * Adds two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is the sum of the two vectors.
+ */
+ function add(a, b, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.x + b.x, a.y + b.y);
+ };
+ Vec2Utils.subtract = /**
+ * Subtracts two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is the difference of the two vectors.
+ */
+ function subtract(a, b, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.x - b.x, a.y - b.y);
+ };
+ Vec2Utils.multiply = /**
+ * Multiplies two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is the sum of the two vectors multiplied.
+ */
+ function multiply(a, b, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.x * b.x, a.y * b.y);
+ };
+ Vec2Utils.divide = /**
+ * Divides two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is the sum of the two vectors divided.
+ */
+ function divide(a, b, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.x / b.x, a.y / b.y);
+ };
+ Vec2Utils.scale = /**
+ * Scales a 2D vector.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {number} s Scaling value.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is the scaled vector.
+ */
+ function scale(a, s, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.x * s, a.y * s);
+ };
+ Vec2Utils.perp = /**
+ * Rotate a 2D vector by 90 degrees.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is the scaled vector.
+ */
+ function perp(a, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.y, -a.x);
+ };
+ Vec2Utils.equals = /**
+ * Checks if two 2D vectors are equal.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Boolean}
+ */
+ function equals(a, b) {
+ return a.x == b.x && a.y == b.y;
+ };
+ Vec2Utils.epsilonEquals = /**
+ *
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} epsilon
+ * @return {Boolean}
+ */
+ function epsilonEquals(a, b, epsilon) {
+ return Math.abs(a.x - b.x) <= epsilon && Math.abs(a.y - b.y) <= epsilon;
+ };
+ Vec2Utils.distance = /**
+ * Get the distance between two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Number}
+ */
+ function distance(a, b) {
+ return Math.sqrt(Vec2Utils.distanceSq(a, b));
+ };
+ Vec2Utils.distanceSq = /**
+ * Get the distance squared between two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Number}
+ */
+ function distanceSq(a, b) {
+ return ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
+ };
+ Vec2Utils.project = /**
+ * Project two 2D vectors onto another vector.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2.
+ */
+ function project(a, b, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ var amt = a.dot(b) / b.lengthSq();
+ if(amt != 0) {
+ out.setTo(amt * b.x, amt * b.y);
+ }
+ return out;
+ };
+ Vec2Utils.projectUnit = /**
+ * Project this vector onto a vector of unit length.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2.
+ */
+ function projectUnit(a, b, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ var amt = a.dot(b);
+ if(amt != 0) {
+ out.setTo(amt * b.x, amt * b.y);
+ }
+ return out;
+ };
+ Vec2Utils.normalRightHand = /**
+ * Right-hand normalize (make unit length) a 2D vector.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2.
+ */
+ function normalRightHand(a, out) {
+ if (typeof out === "undefined") { out = this; }
+ return out.setTo(a.y * -1, a.x);
+ };
+ Vec2Utils.normalize = /**
+ * Normalize (make unit length) a 2D vector.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2.
+ */
+ function normalize(a, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ var m = a.length();
+ if(m != 0) {
+ out.setTo(a.x / m, a.y / m);
+ }
+ return out;
+ };
+ Vec2Utils.dot = /**
+ * The dot product of two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Number}
+ */
+ function dot(a, b) {
+ return ((a.x * b.x) + (a.y * b.y));
+ };
+ Vec2Utils.cross = /**
+ * The cross product of two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Number}
+ */
+ function cross(a, b) {
+ return ((a.x * b.y) - (a.y * b.x));
+ };
+ Vec2Utils.angle = /**
+ * The angle between two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Number}
+ */
+ function angle(a, b) {
+ return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
+ };
+ Vec2Utils.angleSq = /**
+ * The angle squared between two 2D vectors.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @return {Number}
+ */
+ function angleSq(a, b) {
+ return a.subtract(b).angle(b.subtract(a));
+ };
+ Vec2Utils.rotate = /**
+ * Rotate a 2D vector around the origin to the given angle (theta).
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} b Reference to a source Vec2 object.
+ * @param {Number} theta The angle of rotation in radians.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2.
+ */
+ function rotate(a, b, theta, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ var x = a.x - b.x;
+ var y = a.y - b.y;
+ return out.setTo(x * Math.cos(theta) - y * Math.sin(theta) + b.x, x * Math.sin(theta) + y * Math.cos(theta) + b.y);
+ };
+ Vec2Utils.clone = /**
+ * Clone a 2D vector.
+ *
+ * @param {Vec2} a Reference to a source Vec2 object.
+ * @param {Vec2} out The output Vec2 that is the result of the operation.
+ * @return {Vec2} A Vec2 that is a copy of the source Vec2.
+ */
+ function clone(a, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ return out.setTo(a.x, a.y);
+ };
+ return Vec2Utils;
+ })();
+ Phaser.Vec2Utils = Vec2Utils;
+ /**
+ * Reflect this vector on an arbitrary axis.
+ *
+ * @param {Vec2} axis The vector representing the axis.
+ * @return {Vec2} This for chaining.
+ */
+ /*
+ static reflect(axis): Vec2 {
+
+ var x = this.x;
+ var y = this.y;
+ this.project(axis).scale(2);
+ this.x -= x;
+ this.y -= y;
+
+ return this;
+
+ }
+ */
+ /**
+ * Reflect this vector on an arbitrary axis (represented by a unit vector)
+ *
+ * @param {Vec2} axis The unit vector representing the axis.
+ * @return {Vec2} This for chaining.
+ */
+ /*
+ static reflectN(axis): Vec2 {
+
+ var x = this.x;
+ var y = this.y;
+ this.projectN(axis).scale(2);
+ this.x -= x;
+ this.y -= y;
+
+ return this;
+
+ }
+
+ static getMagnitude(): number {
+ return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
+ }
+ */
+ })(Phaser || (Phaser = {}));
+///
+///
+///
+///
+/**
+* Phaser - CircleUtils
+*
+* A collection of methods useful for manipulating and comparing Circle objects.
+*
+* TODO:
+*/
+var Phaser;
+(function (Phaser) {
+ var CircleUtils = (function () {
+ function CircleUtils() { }
+ CircleUtils.clone = /**
+ * Returns a new Circle object with the same values for the x, y, width, and height properties as the original Circle object.
+ * @method clone
+ * @param {Circle} a - The Circle object.
+ * @param {Circle} [optional] out Optional Circle object. If given the values will be set into the object, otherwise a brand new Circle object will be created and returned.
+ * @return {Phaser.Circle}
+ **/
+ function clone(a, out) {
+ if (typeof out === "undefined") { out = new Phaser.Circle(); }
+ return out.setTo(a.x, a.y, a.diameter);
+ };
+ CircleUtils.contains = /**
+ * Return true if the given x/y coordinates are within the Circle object.
+ * If you need details about the intersection then use Phaser.Intersect.circleContainsPoint instead.
+ * @method contains
+ * @param {Circle} a - The Circle object.
+ * @param {Number} The X value of the coordinate to test.
+ * @param {Number} The Y value of the coordinate to test.
+ * @return {Boolean} True if the coordinates are within this circle, otherwise false.
+ **/
+ function contains(a, x, y) {
+ //return (a.radius * a.radius >= Collision.distanceSquared(a.x, a.y, x, y));
+ return true;
+ };
+ CircleUtils.containsPoint = /**
+ * Return true if the coordinates of the given Point object are within this Circle object.
+ * If you need details about the intersection then use Phaser.Intersect.circleContainsPoint instead.
+ * @method containsPoint
+ * @param {Circle} a - The Circle object.
+ * @param {Point} The Point object to test.
+ * @return {Boolean} True if the coordinates are within this circle, otherwise false.
+ **/
+ function containsPoint(a, point) {
+ return CircleUtils.contains(a, point.x, point.y);
+ };
+ CircleUtils.containsCircle = /**
+ * Return true if the given Circle is contained entirely within this Circle object.
+ * If you need details about the intersection then use Phaser.Intersect.circleToCircle instead.
+ * @method containsCircle
+ * @param {Circle} The Circle object to test.
+ * @return {Boolean} True if the coordinates are within this circle, otherwise false.
+ **/
+ function containsCircle(a, b) {
+ //return ((a.radius + b.radius) * (a.radius + b.radius)) >= Collision.distanceSquared(a.x, a.y, b.x, b.y);
+ return true;
+ };
+ CircleUtils.distanceBetween = /**
+ * Returns the distance from the center of the Circle object to the given object (can be Circle, Point or anything with x/y properties)
+ * @method distanceBetween
+ * @param {Circle} a - The Circle object.
+ * @param {Circle} b - The target object. Must have visible x and y properties that represent the center of the object.
+ * @param {Boolean} [optional] round - Round the distance to the nearest integer (default false)
+ * @return {Number} The distance between this Point object and the destination Point object.
+ **/
+ function distanceBetween(a, target, round) {
+ if (typeof round === "undefined") { round = false; }
+ var dx = a.x - target.x;
+ var dy = a.y - target.y;
+ if(round === true) {
+ return Math.round(Math.sqrt(dx * dx + dy * dy));
+ } else {
+ return Math.sqrt(dx * dx + dy * dy);
+ }
+ };
+ CircleUtils.equals = /**
+ * Determines whether the two Circle objects match. This method compares the x, y and diameter properties.
+ * @method equals
+ * @param {Circle} a - The first Circle object.
+ * @param {Circle} b - The second Circle object.
+ * @return {Boolean} A value of true if the object has exactly the same values for the x, y and diameter properties as this Circle object; otherwise false.
+ **/
+ function equals(a, b) {
+ return (a.x == b.x && a.y == b.y && a.diameter == b.diameter);
+ };
+ CircleUtils.intersects = /**
+ * Determines whether the two Circle objects intersect.
+ * This method checks the radius distances between the two Circle objects to see if they intersect.
+ * @method intersects
+ * @param {Circle} a - The first Circle object.
+ * @param {Circle} b - The second Circle object.
+ * @return {Boolean} A value of true if the specified object intersects with this Circle object; otherwise false.
+ **/
+ function intersects(a, b) {
+ return (CircleUtils.distanceBetween(a, b) <= (a.radius + b.radius));
+ };
+ CircleUtils.circumferencePoint = /**
+ * Returns a Point object containing the coordinates of a point on the circumference of the Circle based on the given angle.
+ * @method circumferencePoint
+ * @param {Circle} a - The first Circle object.
+ * @param {Number} angle The angle in radians (unless asDegrees is true) to return the point from.
+ * @param {Boolean} asDegrees Is the given angle in radians (false) or degrees (true)?
+ * @param {Phaser.Point} [optional] output An optional Point object to put the result in to. If none specified a new Point object will be created.
+ * @return {Phaser.Point} The Point object holding the result.
+ **/
+ function circumferencePoint(a, angle, asDegrees, out) {
+ if (typeof asDegrees === "undefined") { asDegrees = false; }
+ if (typeof out === "undefined") { out = new Phaser.Point(); }
+ if(asDegrees === true) {
+ angle = angle * Phaser.GameMath.DEG_TO_RAD;
+ }
+ return out.setTo(a.x + a.radius * Math.cos(angle), a.y + a.radius * Math.sin(angle));
+ };
+ CircleUtils.intersectsRectangle = /*
+ public static boolean intersect(Rectangle r, Circle c)
+ {
+ float cx = Math.abs(c.x - r.x - r.halfWidth);
+ float xDist = r.halfWidth + c.radius;
+ if (cx > xDist)
+ return false;
+ float cy = Math.abs(c.y - r.y - r.halfHeight);
+ float yDist = r.halfHeight + c.radius;
+ if (cy > yDist)
+ return false;
+ if (cx <= r.halfWidth || cy <= r.halfHeight)
+ return true;
+ float xCornerDist = cx - r.halfWidth;
+ float yCornerDist = cy - r.halfHeight;
+ float xCornerDistSq = xCornerDist * xCornerDist;
+ float yCornerDistSq = yCornerDist * yCornerDist;
+ float maxCornerDistSq = c.radius * c.radius;
+ return xCornerDistSq + yCornerDistSq <= maxCornerDistSq;
+ }
+ */
+ function intersectsRectangle(c, r) {
+ var cx = Math.abs(c.x - r.x - r.halfWidth);
+ var xDist = r.halfWidth + c.radius;
+ if(cx > xDist) {
+ return false;
+ }
+ var cy = Math.abs(c.y - r.y - r.halfHeight);
+ var yDist = r.halfHeight + c.radius;
+ if(cy > yDist) {
+ return false;
+ }
+ if(cx <= r.halfWidth || cy <= r.halfHeight) {
+ return true;
+ }
+ var xCornerDist = cx - r.halfWidth;
+ var yCornerDist = cy - r.halfHeight;
+ var xCornerDistSq = xCornerDist * xCornerDist;
+ var yCornerDistSq = yCornerDist * yCornerDist;
+ var maxCornerDistSq = c.radius * c.radius;
+ return xCornerDistSq + yCornerDistSq <= maxCornerDistSq;
+ };
+ return CircleUtils;
+ })();
+ Phaser.CircleUtils = CircleUtils;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - PhysicsManager
+ *
+ * Your game only has one PhysicsManager instance and it's responsible for looking after, creating and colliding
+ * all of the physics objects in the world.
+ */
+ (function (Physics) {
+ var PhysicsManager = (function () {
+ function PhysicsManager(game, width, height) {
+ this._length = 0;
+ this.game = game;
+ this.gravity = new Phaser.Vec2();
+ this.drag = new Phaser.Vec2();
+ this.bounce = new Phaser.Vec2();
+ this.angularDrag = 0;
+ this.bounds = new Phaser.Rectangle(0, 0, width, height);
+ this._distance = new Phaser.Vec2();
+ this._tangent = new Phaser.Vec2();
+ this._objects = [];
+ }
+ PhysicsManager.OVERLAP_BIAS = 4;
+ PhysicsManager.prototype.updateMotion = // Add some sanity checks here + remove method, etc
+ /*
+ public add(shape: IPhysicsShape): IPhysicsShape {
+
+ this._objects.push(shape);
+ return shape;
+
+ }
+
+ public remove(shape: IPhysicsShape) {
+
+ this._length = this._objects.length;
+
+ for (var i = 0; i < this._length; i++)
+ {
+ if (this._objects[i] === shape)
+ {
+ this._objects[i] = null;
+ }
+ }
+
+ }
+
+ public update() {
+
+ this._length = this._objects.length;
+
+ for (var i = 0; i < this._length; i++)
+ {
+ if (this._objects[i])
+ {
+ this._objects[i].preUpdate();
+ this.updateMotion(this._objects[i]);
+ this.collideWorld(this._objects[i]);
+
+ for (var x = 0; x < this._length; x++)
+ {
+ if (this._objects[x] && this._objects[x] !== this._objects[i])
+ {
+ //this.collideShapes(this._objects[i], this._objects[x]);
+ var r = this.NEWseparate(this._objects[i], this._objects[x]);
+ //console.log('sep', r);
+ }
+ }
+
+ }
+ }
+
+ }
+
+ public render() {
+
+ // iterate through the objects here, updating and colliding
+ for (var i = 0; i < this._length; i++)
+ {
+ if (this._objects[i])
+ {
+ this._objects[i].render(this.game.stage.context);
+ }
+ }
+
+ }
+ */
+ function (body) {
+ if(body.type == Phaser.Types.BODY_DISABLED) {
+ return;
+ }
+ this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
+ body.angularVelocity += this._velocityDelta;
+ body.angle += body.angularVelocity * this.game.time.elapsed;
+ body.angularVelocity += this._velocityDelta;
+ this._velocityDelta = (this.computeVelocity(body.velocity.x, body.gravity.x, body.acceleration.x, body.drag.x) - body.velocity.x) / 2;
+ body.velocity.x += this._velocityDelta;
+ this._delta = body.velocity.x * this.game.time.elapsed;
+ body.velocity.x += this._velocityDelta;
+ body.position.x += this._delta;
+ this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2;
+ body.velocity.y += this._velocityDelta;
+ this._delta = body.velocity.y * this.game.time.elapsed;
+ body.velocity.y += this._velocityDelta;
+ body.position.y += this._delta;
+ };
+ PhysicsManager.prototype.computeVelocity = /**
+ * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
+ *
+ * @param {number} Velocity Any component of velocity (e.g. 20).
+ * @param {number} Acceleration Rate at which the velocity is changing.
+ * @param {number} Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
+ * @param {number} Max An absolute value cap for the velocity.
+ *
+ * @return {number} The altered Velocity value.
+ */
+ function (velocity, gravity, acceleration, drag, max) {
+ if (typeof gravity === "undefined") { gravity = 0; }
+ if (typeof acceleration === "undefined") { acceleration = 0; }
+ if (typeof drag === "undefined") { drag = 0; }
+ if (typeof max === "undefined") { max = 10000; }
+ if(acceleration !== 0) {
+ velocity += (acceleration + gravity) * this.game.time.elapsed;
+ } else if(drag !== 0) {
+ this._drag = drag * this.game.time.elapsed;
+ if(velocity - this._drag > 0) {
+ velocity = velocity - this._drag;
+ } else if(velocity + this._drag < 0) {
+ velocity += this._drag;
+ } else {
+ velocity = 0;
+ }
+ velocity += gravity;
+ }
+ if((velocity != 0) && (max != 10000)) {
+ if(velocity > max) {
+ velocity = max;
+ } else if(velocity < -max) {
+ velocity = -max;
+ }
+ }
+ return velocity;
+ };
+ PhysicsManager.prototype.collideShapes = function (shapeA, shapeB) {
+ if(shapeA.physics.immovable && shapeB.physics.immovable) {
+ return;
+ }
+ this._distance.setTo(0, 0);
+ this._tangent.setTo(0, 0);
+ // Simple bounds check first
+ if(Phaser.RectangleUtils.intersects(shapeA.bounds, shapeB.bounds)) {
+ // Collide on the x-axis
+ if(shapeA.physics.velocity.x > 0 && shapeA.bounds.right > shapeB.bounds.x && shapeA.bounds.right <= shapeB.bounds.right) {
+ // The right side of ShapeA hit the left side of ShapeB
+ this._distance.x = shapeB.bounds.x - shapeA.bounds.right;
+ if(this._distance.x != 0) {
+ this._tangent.x = -1;
+ }
+ } else if(shapeA.physics.velocity.x < 0 && shapeA.bounds.x < shapeB.bounds.right && shapeA.bounds.x >= shapeB.bounds.x) {
+ // The left side of ShapeA hit the right side of ShapeB
+ this._distance.x = shapeB.bounds.right - shapeA.bounds.x;
+ if(this._distance.x != 0) {
+ this._tangent.x = 1;
+ }
+ }
+ // Collide on the y-axis
+ if(shapeA.physics.velocity.y < 0 && shapeA.bounds.y < shapeB.bounds.bottom && shapeA.bounds.y > shapeB.bounds.y) {
+ console.log('top A -> bot B');
+ // The top of ShapeA hit the bottom of ShapeB
+ this._distance.y = shapeB.bounds.bottom - shapeA.bounds.y;
+ console.log(shapeA.bounds, shapeB.bounds, this._distance.y);
+ if(this._distance.y != 0) {
+ this._tangent.y = 1;
+ }
+ } else if(shapeA.physics.velocity.y > 0 && shapeA.bounds.bottom > shapeB.bounds.y && shapeA.bounds.bottom < shapeB.bounds.bottom) {
+ // The bottom of ShapeA hit the top of ShapeB
+ this._distance.y = shapeB.bounds.y - shapeA.bounds.bottom;
+ if(this._distance.y != 0) {
+ this._tangent.y = -1;
+ }
+ }
+ // Separate
+ if(this._distance.equals(0) == false) {
+ //this.separate(shapeA, shapeB, this._distance, this._tangent);
+ }
+ }
+ };
+ PhysicsManager.prototype.separate = /**
+ * The core Collision separation method.
+ * @param body1 The first Physics.Body to separate
+ * @param body2 The second Physics.Body to separate
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ */
+ function (body1, body2) {
+ this._separatedX = this.separateBodyX(body1, body2);
+ this._separatedY = this.separateBodyY(body1, body2);
+ return this._separatedX || this._separatedY;
+ };
+ PhysicsManager.prototype.checkHullIntersection = function (shape1, shape2) {
+ //if ((shape1.hullX + shape1.hullWidth > shape2.hullX) && (shape1.hullX < shape2.hullX + shape2.bounds.width) && (shape1.hullY + shape1.hullHeight > shape2.hullY) && (shape1.hullY < shape2.hullY + shape2.hullHeight))
+ // maybe not bounds.width?
+ if((shape1.hullX + shape1.hullWidth > shape2.hullX) && (shape1.hullX < shape2.hullX + shape2.hullWidth) && (shape1.hullY + shape1.hullHeight > shape2.hullY) && (shape1.hullY < shape2.hullY + shape2.hullHeight)) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+ PhysicsManager.prototype.separateBodyX = /**
+ * 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.
+ */
+ function (body1, body2) {
+ // Can't separate two disabled or static objects
+ if((body1.type == Phaser.Types.BODY_DISABLED || body1.type == Phaser.Types.BODY_STATIC) && (body2.type == Phaser.Types.BODY_DISABLED || body2.type == Phaser.Types.BODY_STATIC)) {
+ return false;
+ }
+ // First, get the two object deltas
+ this._overlap = 0;
+ if(body1.deltaX != body2.deltaX) {
+ if(Phaser.RectangleUtils.intersects(body1.bounds, body2.bounds)) {
+ this._maxOverlap = body1.deltaXAbs + body2.deltaXAbs + PhysicsManager.OVERLAP_BIAS;
+ // If they did overlap (and can), figure out by how much and flip the corresponding flags
+ if(body1.deltaX > body2.deltaX) {
+ this._overlap = body1.bounds.right - body2.bounds.x;
+ if((this._overlap > this._maxOverlap) || !(body1.allowCollisions & Phaser.Types.RIGHT) || !(body2.allowCollisions & Phaser.Types.LEFT)) {
+ this._overlap = 0;
+ } else {
+ body1.touching |= Phaser.Types.RIGHT;
+ body2.touching |= Phaser.Types.LEFT;
+ }
+ } else if(body1.deltaX < body2.deltaX) {
+ this._overlap = body1.bounds.x - body2.bounds.width - body2.bounds.x;
+ if((-this._overlap > this._maxOverlap) || !(body1.allowCollisions & Phaser.Types.LEFT) || !(body2.allowCollisions & Phaser.Types.RIGHT)) {
+ this._overlap = 0;
+ } else {
+ body1.touching |= Phaser.Types.LEFT;
+ body2.touching |= Phaser.Types.RIGHT;
+ }
+ }
+ }
+ }
+ // Then adjust their positions and velocities accordingly (if there was any overlap)
+ if(this._overlap != 0) {
+ this._obj1Velocity = body1.velocity.x;
+ this._obj2Velocity = body2.velocity.x;
+ /**
+ * Dynamic = gives and receives impacts
+ * Static = gives but doesn't receive impacts, cannot be moved by physics
+ * Kinematic = gives impacts, but never receives, can be moved by physics
+ */
+ // 2 dynamic bodies will exchange velocities
+ if(body1.type == Phaser.Types.BODY_DYNAMIC && body2.type == Phaser.Types.BODY_DYNAMIC) {
+ this._overlap *= 0.5;
+ body1.position.x = body1.position.x - this._overlap;
+ body2.position.x += this._overlap;
+ this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * body2.mass) / body1.mass) * ((this._obj2Velocity > 0) ? 1 : -1);
+ this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * body1.mass) / body2.mass) * ((this._obj1Velocity > 0) ? 1 : -1);
+ this._average = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5;
+ this._obj1NewVelocity -= this._average;
+ this._obj2NewVelocity -= this._average;
+ body1.velocity.x = this._average + this._obj1NewVelocity * body1.bounce.x;
+ body2.velocity.x = this._average + this._obj2NewVelocity * body2.bounce.x;
+ } else if(body2.type != Phaser.Types.BODY_DYNAMIC) {
+ // Body 2 is Static or Kinematic
+ this._overlap *= 2;
+ body1.position.x -= this._overlap;
+ body1.velocity.x = this._obj2Velocity - this._obj1Velocity * body1.bounce.x;
+ } else if(body1.type != Phaser.Types.BODY_DYNAMIC) {
+ // Body 1 is Static or Kinematic
+ this._overlap *= 2;
+ body2.position.x += this._overlap;
+ body2.velocity.x = this._obj1Velocity - this._obj2Velocity * body2.bounce.x;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ };
+ PhysicsManager.prototype.separateBodyY = /**
+ * 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.
+ */
+ function (body1, body2) {
+ // Can't separate two immovable objects
+ if((body1.type == Phaser.Types.BODY_DISABLED || body1.type == Phaser.Types.BODY_STATIC) && (body2.type == Phaser.Types.BODY_DISABLED || body2.type == Phaser.Types.BODY_STATIC)) {
+ return false;
+ }
+ // First, get the two object deltas
+ this._overlap = 0;
+ if(body1.deltaY != body2.deltaY) {
+ if(Phaser.RectangleUtils.intersects(body1.bounds, body2.bounds)) {
+ // This is the only place to use the DeltaAbs values
+ this._maxOverlap = body1.deltaYAbs + body2.deltaYAbs + PhysicsManager.OVERLAP_BIAS;
+ // If they did overlap (and can), figure out by how much and flip the corresponding flags
+ if(body1.deltaY > body2.deltaY) {
+ this._overlap = body1.bounds.bottom - body2.bounds.y;
+ if((this._overlap > this._maxOverlap) || !(body1.allowCollisions & Phaser.Types.DOWN) || !(body2.allowCollisions & Phaser.Types.UP)) {
+ this._overlap = 0;
+ } else {
+ body1.touching |= Phaser.Types.DOWN;
+ body2.touching |= Phaser.Types.UP;
+ }
+ } else if(body1.deltaY < body2.deltaY) {
+ this._overlap = body1.bounds.y - body2.bounds.height - body2.bounds.y;
+ if((-this._overlap > this._maxOverlap) || !(body1.allowCollisions & Phaser.Types.UP) || !(body2.allowCollisions & Phaser.Types.DOWN)) {
+ this._overlap = 0;
+ } else {
+ body1.touching |= Phaser.Types.UP;
+ body2.touching |= Phaser.Types.DOWN;
+ }
+ }
+ }
+ }
+ // Then adjust their positions and velocities accordingly (if there was any overlap)
+ if(this._overlap != 0) {
+ this._obj1Velocity = body1.velocity.y;
+ this._obj2Velocity = body2.velocity.y;
+ /**
+ * Dynamic = gives and receives impacts
+ * Static = gives but doesn't receive impacts, cannot be moved by physics
+ * Kinematic = gives impacts, but never receives, can be moved by physics
+ */
+ if(body1.type == Phaser.Types.BODY_DYNAMIC && body2.type == Phaser.Types.BODY_DYNAMIC) {
+ this._overlap *= 0.5;
+ body1.position.y = body1.position.y - this._overlap;
+ body2.position.y += this._overlap;
+ this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * body2.mass) / body1.mass) * ((this._obj2Velocity > 0) ? 1 : -1);
+ this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * body1.mass) / body2.mass) * ((this._obj1Velocity > 0) ? 1 : -1);
+ var average = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5;
+ this._obj1NewVelocity -= average;
+ this._obj2NewVelocity -= average;
+ body1.velocity.y = average + this._obj1NewVelocity * body1.bounce.y;
+ body2.velocity.y = average + this._obj2NewVelocity * body2.bounce.y;
+ } else if(body2.type != Phaser.Types.BODY_DYNAMIC) {
+ this._overlap *= 2;
+ body1.position.y -= this._overlap;
+ body1.velocity.y = this._obj2Velocity - this._obj1Velocity * body1.bounce.y;
+ // This is special case code that handles things like horizontal moving platforms you can ride
+ //if (body2.parent.active && body2.moves && (body1.deltaY > body2.deltaY))
+ if(body2.parent.active && (body1.deltaY > body2.deltaY)) {
+ body1.position.x += body2.position.x - body2.oldPosition.x;
+ }
+ } else if(body1.type != Phaser.Types.BODY_DYNAMIC) {
+ this._overlap *= 2;
+ body2.position.y += this._overlap;
+ body2.velocity.y = this._obj1Velocity - this._obj2Velocity * body2.bounce.y;
+ // This is special case code that handles things like horizontal moving platforms you can ride
+ //if (object1.active && body1.moves && (body1.deltaY < body2.deltaY))
+ if(body1.parent.active && (body1.deltaY < body2.deltaY)) {
+ body2.position.x += body1.position.x - body1.oldPosition.x;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ };
+ PhysicsManager.prototype.OLDseparate = function (shapeA, shapeB, distance, tangent) {
+ if(tangent.x == 1) {
+ console.log('1 The left side of ShapeA hit the right side of ShapeB', Math.floor(distance.x));
+ shapeA.physics.touching |= Phaser.Types.LEFT;
+ shapeB.physics.touching |= Phaser.Types.RIGHT;
+ } else if(tangent.x == -1) {
+ console.log('2 The right side of ShapeA hit the left side of ShapeB', Math.floor(distance.x));
+ shapeA.physics.touching |= Phaser.Types.RIGHT;
+ shapeB.physics.touching |= Phaser.Types.LEFT;
+ }
+ if(tangent.y == 1) {
+ console.log('3 The top of ShapeA hit the bottom of ShapeB', Math.floor(distance.y));
+ shapeA.physics.touching |= Phaser.Types.UP;
+ shapeB.physics.touching |= Phaser.Types.DOWN;
+ } else if(tangent.y == -1) {
+ console.log('4 The bottom of ShapeA hit the top of ShapeB', Math.floor(distance.y));
+ shapeA.physics.touching |= Phaser.Types.DOWN;
+ shapeB.physics.touching |= Phaser.Types.UP;
+ }
+ // only apply collision response forces if the object is travelling into, and not out of, the collision
+ var dot = Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent);
+ if(dot < 0) {
+ console.log('in to', dot);
+ // Apply horizontal bounce
+ if(shapeA.physics.bounce.x > 0) {
+ shapeA.physics.velocity.x *= -(shapeA.physics.bounce.x);
+ } else {
+ shapeA.physics.velocity.x = 0;
+ }
+ // Apply horizontal bounce
+ if(shapeA.physics.bounce.y > 0) {
+ shapeA.physics.velocity.y *= -(shapeA.physics.bounce.y);
+ } else {
+ shapeA.physics.velocity.y = 0;
+ }
+ } else {
+ console.log('out of', dot);
+ }
+ shapeA.position.x += Math.floor(distance.x);
+ //shapeA.bounds.x += Math.floor(distance.x);
+ shapeA.position.y += Math.floor(distance.y);
+ //shapeA.bounds.y += distance.y;
+ console.log('------------------------------------------------');
+ };
+ PhysicsManager.prototype.collideWorld = function (shape) {
+ // Collide on the x-axis
+ this._distance.x = shape.world.bounds.x - (shape.position.x - shape.bounds.halfWidth);
+ if(0 < this._distance.x) {
+ // Hit Left
+ this._tangent.setTo(1, 0);
+ this.separateXWall(shape, this._distance, this._tangent);
+ } else {
+ this._distance.x = (shape.position.x + shape.bounds.halfWidth) - shape.world.bounds.right;
+ if(0 < this._distance.x) {
+ // Hit Right
+ this._tangent.setTo(-1, 0);
+ this._distance.reverse();
+ this.separateXWall(shape, this._distance, this._tangent);
+ }
+ }
+ // Collide on the y-axis
+ this._distance.y = shape.world.bounds.y - (shape.position.y - shape.bounds.halfHeight);
+ if(0 < this._distance.y) {
+ // Hit Top
+ this._tangent.setTo(0, 1);
+ this.separateYWall(shape, this._distance, this._tangent);
+ } else {
+ this._distance.y = (shape.position.y + shape.bounds.halfHeight) - shape.world.bounds.bottom;
+ if(0 < this._distance.y) {
+ // Hit Bottom
+ this._tangent.setTo(0, -1);
+ this._distance.reverse();
+ this.separateYWall(shape, this._distance, this._tangent);
+ }
+ }
+ };
+ PhysicsManager.prototype.separateX = function (shapeA, shapeB, distance, tangent) {
+ if(tangent.x == 1) {
+ console.log('The left side of ShapeA hit the right side of ShapeB', distance.x);
+ shapeA.physics.touching |= Phaser.Types.LEFT;
+ shapeB.physics.touching |= Phaser.Types.RIGHT;
+ } else {
+ console.log('The right side of ShapeA hit the left side of ShapeB', distance.x);
+ shapeA.physics.touching |= Phaser.Types.RIGHT;
+ shapeB.physics.touching |= Phaser.Types.LEFT;
+ }
+ // collision edges
+ //shapeA.oH = tangent.x;
+ // only apply collision response forces if the object is travelling into, and not out of, the collision
+ if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
+ // Apply horizontal bounce
+ if(shapeA.physics.bounce.x > 0) {
+ shapeA.physics.velocity.x *= -(shapeA.physics.bounce.x);
+ } else {
+ shapeA.physics.velocity.x = 0;
+ }
+ }
+ shapeA.position.x += distance.x;
+ shapeA.bounds.x += distance.x;
+ };
+ PhysicsManager.prototype.separateY = function (shapeA, shapeB, distance, tangent) {
+ if(tangent.y == 1) {
+ console.log('The top of ShapeA hit the bottom of ShapeB', distance.y);
+ shapeA.physics.touching |= Phaser.Types.UP;
+ shapeB.physics.touching |= Phaser.Types.DOWN;
+ } else {
+ console.log('The bottom of ShapeA hit the top of ShapeB', distance.y);
+ shapeA.physics.touching |= Phaser.Types.DOWN;
+ shapeB.physics.touching |= Phaser.Types.UP;
+ }
+ // collision edges
+ //shapeA.oV = tangent.y;
+ // only apply collision response forces if the object is travelling into, and not out of, the collision
+ if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
+ // Apply horizontal bounce
+ if(shapeA.physics.bounce.y > 0) {
+ shapeA.physics.velocity.y *= -(shapeA.physics.bounce.y);
+ } else {
+ shapeA.physics.velocity.y = 0;
+ }
+ }
+ shapeA.position.y += distance.y;
+ shapeA.bounds.y += distance.y;
+ };
+ PhysicsManager.prototype.separateXWall = function (shapeA, distance, tangent) {
+ if(tangent.x == 1) {
+ console.log('The left side of ShapeA hit the right side of ShapeB', distance.x);
+ shapeA.physics.touching |= Phaser.Types.LEFT;
+ } else {
+ console.log('The right side of ShapeA hit the left side of ShapeB', distance.x);
+ shapeA.physics.touching |= Phaser.Types.RIGHT;
+ }
+ // collision edges
+ //shapeA.oH = tangent.x;
+ // only apply collision response forces if the object is travelling into, and not out of, the collision
+ if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
+ // Apply horizontal bounce
+ if(shapeA.physics.bounce.x > 0) {
+ shapeA.physics.velocity.x *= -(shapeA.physics.bounce.x);
+ } else {
+ shapeA.physics.velocity.x = 0;
+ }
+ }
+ shapeA.position.x += distance.x;
+ };
+ PhysicsManager.prototype.separateYWall = function (shapeA, distance, tangent) {
+ if(tangent.y == 1) {
+ console.log('The top of ShapeA hit the bottom of ShapeB', distance.y);
+ shapeA.physics.touching |= Phaser.Types.UP;
+ } else {
+ console.log('The bottom of ShapeA hit the top of ShapeB', distance.y);
+ shapeA.physics.touching |= Phaser.Types.DOWN;
+ }
+ // collision edges
+ //shapeA.oV = tangent.y;
+ // only apply collision response forces if the object is travelling into, and not out of, the collision
+ if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
+ // Apply horizontal bounce
+ if(shapeA.physics.bounce.y > 0) {
+ shapeA.physics.velocity.y *= -(shapeA.physics.bounce.y);
+ } else {
+ shapeA.physics.velocity.y = 0;
+ }
+ }
+ shapeA.position.y += distance.y;
+ };
+ PhysicsManager.prototype.overlap = /**
+ * 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.
+ * @param context The context in which the callbacks will be called
+ * @returns {boolean} true if the objects overlap, otherwise false.
+ */
+ function (object1, object2, notifyCallback, processCallback, context) {
+ if (typeof object1 === "undefined") { object1 = null; }
+ if (typeof object2 === "undefined") { object2 = null; }
+ if (typeof notifyCallback === "undefined") { notifyCallback = null; }
+ if (typeof processCallback === "undefined") { processCallback = null; }
+ if (typeof context === "undefined") { context = null; }
+ if(object1 == null) {
+ object1 = this._game.world.group;
+ }
+ if(object2 == object1) {
+ object2 = null;
+ }
+ Phaser.QuadTree.divisions = this._game.world.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, context);
+ var result = quadTree.execute();
+ quadTree.destroy();
+ quadTree = null;
+ return result;
+ };
+ return PhysicsManager;
+ })();
+ Physics.PhysicsManager = PhysicsManager;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ })(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Physics - AABB
+ */
+ (function (Physics) {
+ var AABB = (function () {
+ function AABB(game, sprite, x, y, width, height) {
+ this.game = game;
+ this.world = game.world.physics;
+ if(sprite !== null) {
+ this.sprite = sprite;
+ this.scale = Phaser.Vec2Utils.clone(this.sprite.scale);
+ } else {
+ this.sprite = null;
+ this.physics = null;
+ this.scale = new Phaser.Vec2(1, 1);
+ }
+ this.bounds = new Phaser.Rectangle(x + Math.round(width / 2), y + Math.round(height / 2), width, height);
+ this.position = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
+ this.oldPosition = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
+ this.offset = new Phaser.Vec2(0, 0);
+ }
+ AABB.prototype.preUpdate = function () {
+ this.oldPosition.copyFrom(this.position);
+ this.bounds.x = this.position.x - this.bounds.halfWidth;
+ this.bounds.y = this.position.y - this.bounds.halfHeight;
+ if(this.sprite) {
+ this.position.setTo((this.sprite.x + this.bounds.halfWidth) + this.offset.x, (this.sprite.y + this.bounds.halfHeight) + this.offset.y);
+ // Update scale / dimensions
+ if(Phaser.Vec2Utils.equals(this.scale, this.sprite.scale) == false) {
+ this.scale.copyFrom(this.sprite.scale);
+ this.bounds.width = this.sprite.width;
+ this.bounds.height = this.sprite.height;
+ }
+ }
+ };
+ AABB.prototype.update = function () {
+ //this.bounds.x = this.position.x;
+ //this.bounds.y = this.position.y;
+ };
+ AABB.prototype.setSize = function (width, height) {
+ this.bounds.width = width;
+ this.bounds.height = height;
+ };
+ AABB.prototype.render = function (context) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(0,255,0)';
+ context.strokeRect(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight, this.bounds.width, this.bounds.height);
+ context.stroke();
+ context.closePath();
+ // center point
+ context.fillStyle = 'rgb(0,255,0)';
+ context.fillRect(this.position.x, this.position.y, 2, 2);
+ if(this.physics.touching & Phaser.Types.LEFT) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if(this.physics.touching & Phaser.Types.RIGHT) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if(this.physics.touching & Phaser.Types.UP) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if(this.physics.touching & Phaser.Types.DOWN) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ };
+ Object.defineProperty(AABB.prototype, "hullWidth", {
+ get: function () {
+ if(this.deltaX > 0) {
+ return this.bounds.width + this.deltaX;
+ } else {
+ return this.bounds.width - this.deltaX;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "hullHeight", {
+ get: function () {
+ if(this.deltaY > 0) {
+ return this.bounds.height + this.deltaY;
+ } else {
+ return this.bounds.height - this.deltaY;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "hullX", {
+ get: function () {
+ if(this.position.x < this.oldPosition.x) {
+ return this.position.x;
+ } else {
+ return this.oldPosition.x;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "hullY", {
+ get: function () {
+ if(this.position.y < this.oldPosition.y) {
+ return this.position.y;
+ } else {
+ return this.oldPosition.y;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "deltaXAbs", {
+ get: function () {
+ return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "deltaYAbs", {
+ get: function () {
+ return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "deltaX", {
+ get: function () {
+ return this.position.x - this.oldPosition.x;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AABB.prototype, "deltaY", {
+ get: function () {
+ return this.position.y - this.oldPosition.y;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return AABB;
+ })();
+ Physics.AABB = AABB;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Physics - Circle
+ */
+ (function (Physics) {
+ var Circle = (function () {
+ function Circle(game, sprite, x, y, diameter) {
+ this.game = game;
+ this.world = game.world.physics;
+ if(sprite !== null) {
+ this.sprite = sprite;
+ this.scale = Phaser.Vec2Utils.clone(this.sprite.scale);
+ } else {
+ this.sprite = null;
+ this.physics = null;
+ this.scale = new Phaser.Vec2(1, 1);
+ }
+ this.diameter = diameter;
+ this.radius = diameter / 2;
+ this.bounds = new Phaser.Rectangle(x + Math.round(diameter / 2), y + Math.round(diameter / 2), diameter, diameter);
+ this.position = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
+ this.oldPosition = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
+ this.offset = new Phaser.Vec2(0, 0);
+ }
+ Circle.prototype.preUpdate = function () {
+ this.oldPosition.copyFrom(this.position);
+ this.bounds.x = this.position.x - this.bounds.halfWidth;
+ this.bounds.y = this.position.y - this.bounds.halfHeight;
+ if(this.sprite) {
+ this.position.setTo((this.sprite.x + this.bounds.halfWidth) + this.offset.x, (this.sprite.y + this.bounds.halfHeight) + this.offset.y);
+ // Update scale / dimensions
+ if(Phaser.Vec2Utils.equals(this.scale, this.sprite.scale) == false) {
+ this.scale.copyFrom(this.sprite.scale);
+ // needs to be radius based (+ square)
+ //this.bounds.width = this.sprite.width;
+ //this.bounds.height = this.sprite.height;
+ }
+ }
+ };
+ Circle.prototype.update = function () {
+ //this.bounds.x = this.position.x;
+ //this.bounds.y = this.position.y;
+ };
+ Circle.prototype.setSize = function (width, height) {
+ this.bounds.width = width;
+ this.bounds.height = height;
+ };
+ Circle.prototype.render = function (context) {
+ // center point
+ context.fillStyle = 'rgba(255,0,0,0.5)';
+ context.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
+ context.rect(this.position.x, this.position.y, 2, 2);
+ context.fill();
+ /*
+ if (this.oH == 1)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ else if (this.oH == -1)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+
+ if (this.oV == 1)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ else if (this.oV == -1)
+ {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ */
+ };
+ Object.defineProperty(Circle.prototype, "hullWidth", {
+ get: function () {
+ if(this.deltaX > 0) {
+ //return this.bounds.width + this.deltaX;
+ return this.diameter + this.deltaX;
+ } else {
+ //return this.bounds.width - this.deltaX;
+ return this.diameter - this.deltaX;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "hullHeight", {
+ get: function () {
+ if(this.deltaY > 0) {
+ //return this.bounds.height + this.deltaY;
+ return this.diameter + this.deltaY;
+ } else {
+ //return this.bounds.height - this.deltaY;
+ return this.diameter - this.deltaY;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "hullX", {
+ get: function () {
+ if(this.position.x < this.oldPosition.x) {
+ return this.position.x;
+ } else {
+ return this.oldPosition.x;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "hullY", {
+ get: function () {
+ if(this.position.y < this.oldPosition.y) {
+ return this.position.y;
+ } else {
+ return this.oldPosition.y;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "deltaXAbs", {
+ get: function () {
+ return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "deltaYAbs", {
+ get: function () {
+ return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "deltaX", {
+ get: function () {
+ return this.position.x - this.oldPosition.x;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Circle.prototype, "deltaY", {
+ get: function () {
+ return this.position.y - this.oldPosition.y;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return Circle;
+ })();
+ Physics.Circle = Circle;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ })(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Physics - Body
+ */
+ (function (Physics) {
+ var Body = (function () {
+ function Body(parent, type) {
+ this.angularVelocity = 0;
+ this.angularAcceleration = 0;
+ this.angularDrag = 0;
+ this.maxAngular = 10000;
+ this.mass = 1;
+ this.parent = parent;
+ this.game = parent.game;
+ this.type = type;
+ // Fixture properties
+ // Will extend into its own class at a later date - can move the fixture defs there and add shape support, but this will do for 1.0 release
+ this.bounds = new Phaser.Rectangle(parent.x + Math.round(parent.width / 2), parent.y + Math.round(parent.height / 2), parent.width, parent.height);
+ this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce);
+ // Body properties
+ this.gravity = Phaser.Vec2Utils.clone(this.game.world.physics.gravity);
+ this.velocity = new Phaser.Vec2();
+ this.acceleration = new Phaser.Vec2();
+ this.drag = Phaser.Vec2Utils.clone(this.game.world.physics.drag);
+ this.maxVelocity = new Phaser.Vec2(10000, 10000);
+ this.angle = 0;
+ this.angularVelocity = 0;
+ this.angularAcceleration = 0;
+ this.angularDrag = 0;
+ this.touching = Phaser.Types.NONE;
+ this.wasTouching = Phaser.Types.NONE;
+ this.allowCollisions = Phaser.Types.ANY;
+ this.position = new Phaser.Vec2(parent.x + this.bounds.halfWidth, parent.y + this.bounds.halfHeight);
+ this.oldPosition = new Phaser.Vec2(parent.x + this.bounds.halfWidth, parent.y + this.bounds.halfHeight);
+ this.offset = new Phaser.Vec2();
+ }
+ Body.prototype.preUpdate = function () {
+ this.oldPosition.copyFrom(this.position);
+ this.bounds.x = this.position.x - this.bounds.halfWidth;
+ this.bounds.y = this.position.y - this.bounds.halfHeight;
+ if(this.parent.scale.equals(1) == false) {
+ }
+ };
+ Body.prototype.postUpdate = // Shall we do this? Or just update the values directly in the separate functions? But then the bounds will be out of sync - as long as
+ // the bounds are updated and used in calculations then we can do one final sprite movement here I guess?
+ function () {
+ // if this is all it does maybe move elsewhere? Sprite postUpdate?
+ if(this.type !== Phaser.Types.BODY_DISABLED) {
+ this.parent.x = (this.position.x - this.bounds.halfWidth) - this.offset.x;
+ this.parent.y = (this.position.y - this.bounds.halfHeight) - this.offset.y;
+ this.wasTouching = this.touching;
+ this.touching = Phaser.Types.NONE;
+ }
+ };
+ Object.defineProperty(Body.prototype, "hullWidth", {
+ get: function () {
+ if(this.deltaX > 0) {
+ return this.bounds.width + this.deltaX;
+ } else {
+ return this.bounds.width - this.deltaX;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "hullHeight", {
+ get: function () {
+ if(this.deltaY > 0) {
+ return this.bounds.height + this.deltaY;
+ } else {
+ return this.bounds.height - this.deltaY;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "hullX", {
+ get: function () {
+ if(this.position.x < this.oldPosition.x) {
+ return this.position.x;
+ } else {
+ return this.oldPosition.x;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "hullY", {
+ get: function () {
+ if(this.position.y < this.oldPosition.y) {
+ return this.position.y;
+ } else {
+ return this.oldPosition.y;
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "deltaXAbs", {
+ get: function () {
+ return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "deltaYAbs", {
+ get: function () {
+ return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "deltaX", {
+ get: function () {
+ return this.position.x - this.oldPosition.x;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "deltaY", {
+ get: function () {
+ return this.position.y - this.oldPosition.y;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Body.prototype.render = // MOVE THESE TO A UTIL
+ function (context) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(0,255,0)';
+ context.strokeRect(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight, this.bounds.width, this.bounds.height);
+ context.stroke();
+ context.closePath();
+ // center point
+ context.fillStyle = 'rgb(0,255,0)';
+ context.fillRect(this.position.x, this.position.y, 2, 2);
+ if(this.touching & Phaser.Types.LEFT) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if(this.touching & Phaser.Types.RIGHT) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if(this.touching & Phaser.Types.UP) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ if(this.touching & Phaser.Types.DOWN) {
+ context.beginPath();
+ context.strokeStyle = 'rgb(255,0,0)';
+ context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
+ context.stroke();
+ context.closePath();
+ }
+ };
+ Body.prototype.renderDebugInfo = /**
+ * Render debug infos. (including name, bounds info, position and some other properties)
+ * @param x {number} X position of the debug info to be rendered.
+ * @param y {number} Y position of the debug info to be rendered.
+ * @param [color] {number} color of the debug info to be rendered. (format is css color string)
+ */
+ function (x, y, color) {
+ if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
+ this.parent.texture.context.fillStyle = color;
+ this.parent.texture.context.fillText('Sprite: (' + this.parent.frameBounds.width + ' x ' + this.parent.frameBounds.height + ')', x, y);
+ //this.parent.texture.context.fillText('x: ' + this._parent.frameBounds.x.toFixed(1) + ' y: ' + this._parent.frameBounds.y.toFixed(1) + ' rotation: ' + this._parent.rotation.toFixed(1), x, y + 14);
+ this.parent.texture.context.fillText('x: ' + this.shape.bounds.x.toFixed(1) + ' y: ' + this.shape.bounds.y.toFixed(1) + ' rotation: ' + this._parent.rotation.toFixed(1), x, y + 14);
+ this.parent.texture.context.fillText('vx: ' + this.velocity.x.toFixed(1) + ' vy: ' + this.velocity.y.toFixed(1), x, y + 28);
+ this.parent.texture.context.fillText('ax: ' + this.acceleration.x.toFixed(1) + ' ay: ' + this.acceleration.y.toFixed(1), x, y + 42);
+ };
+ return Body;
+ })();
+ Physics.Body = Body;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+///
+///
///
///
///
///
+///
/**
* Phaser - Sprite
*
@@ -4007,20 +5585,14 @@ var Phaser;
* @param [x] {number} the initial x position of the sprite.
* @param [y] {number} the initial y position of the sprite.
* @param [key] {string} Key of the graphic you want to load for this sprite.
- * @param [width] {number} The width of the object.
- * @param [height] {number} The height of the object.
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
*/
- function Sprite(game, x, y, key, width, height) {
+ //constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, width?: number = 16, height?: number = 16) {
+ function Sprite(game, x, y, key, bodyType) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof key === "undefined") { key = null; }
- if (typeof width === "undefined") { width = 16; }
- if (typeof height === "undefined") { height = 16; }
- /**
- * Rotation angle of this object.
- * @type {number}
- */
- this._rotation = 0;
+ if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; }
/**
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
*/
@@ -4038,12 +5610,12 @@ var Phaser;
*/
this.z = 0;
/**
- * This value is added to the rotation of the Sprite.
+ * This value is added to the angle of the Sprite.
* For example if you had a sprite graphic drawn facing straight up then you could set
- * rotationOffset to 90 and it would correspond correctly with Phasers right-handed coordinate system.
+ * angleOffset to 90 and it would correspond correctly with Phasers right-handed coordinate system.
* @type {number}
*/
- this.rotationOffset = 0;
+ this.angleOffset = 0;
this.game = game;
this.type = Phaser.Types.SPRITE;
this.render = game.renderer.renderSprite;
@@ -4051,7 +5623,8 @@ var Phaser;
this.active = true;
this.visible = true;
this.alive = true;
- this.frameBounds = new Phaser.Rectangle(x, y, width, height);
+ // We give it a default size of 16x16 but when the texture loads (if given) it will reset this
+ this.frameBounds = new Phaser.Rectangle(x, y, 16, 16);
this.scrollFactor = new Phaser.Vec2(1, 1);
this.x = x;
this.y = y;
@@ -4063,22 +5636,22 @@ var Phaser;
this.origin = new Phaser.Vec2(0, 0);
this.scale = new Phaser.Vec2(1, 1);
this.skew = new Phaser.Vec2(0, 0);
- this.physics = new Phaser.Components.Physics(this);
- this.physics.shape.physics = this.physics;
+ // If a texture has been given the body will be set to that size, otherwise 16x16
+ this.body = new Phaser.Physics.Body(this, bodyType);
}
- Object.defineProperty(Sprite.prototype, "rotation", {
+ Object.defineProperty(Sprite.prototype, "angle", {
get: /**
- * The rotation of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
+ * The angle of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
*/
function () {
- return this._rotation;
+ return this.body.angle;
},
set: /**
- * Set the rotation of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
+ * Set the angle of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
* The value is automatically wrapped to be between 0 and 360.
*/
function (value) {
- this._rotation = this.game.math.wrap(value, 360, 0);
+ this.body.angle = this.game.math.wrap(value, 360, 0);
},
enumerable: true,
configurable: true
@@ -4155,7 +5728,8 @@ var Phaser;
*/
function () {
this.animations.update();
- this.physics.update();
+ this.body.postUpdate();
+ //this.physics.update();
/*
if (this.worldBounds != null)
{
@@ -4188,15 +5762,11 @@ var Phaser;
}
}
- this.collisionMask.update();
-
if (this.inputEnabled)
{
this.updateInput();
}
- this.wasTouching = this.touching;
- this.touching = Collision.NONE;
*/
if(this.modified == true && this.scale.equals(1) && this.skew.equals(0) && this.rotation == 0 && this.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) {
this.modified = false;
@@ -5562,1049 +7132,6 @@ var Phaser;
Phaser.Tween = Tween;
})(Phaser || (Phaser = {}));
///
-///
-/**
-* Phaser - Vec2Utils
-*
-* A collection of methods useful for manipulating and performing operations on 2D vectors.
-*
-*/
-var Phaser;
-(function (Phaser) {
- var Vec2Utils = (function () {
- function Vec2Utils() { }
- Vec2Utils.add = /**
- * Adds two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is the sum of the two vectors.
- */
- function add(a, b, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.x + b.x, a.y + b.y);
- };
- Vec2Utils.subtract = /**
- * Subtracts two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is the difference of the two vectors.
- */
- function subtract(a, b, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.x - b.x, a.y - b.y);
- };
- Vec2Utils.multiply = /**
- * Multiplies two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is the sum of the two vectors multiplied.
- */
- function multiply(a, b, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.x * b.x, a.y * b.y);
- };
- Vec2Utils.divide = /**
- * Divides two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is the sum of the two vectors divided.
- */
- function divide(a, b, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.x / b.x, a.y / b.y);
- };
- Vec2Utils.scale = /**
- * Scales a 2D vector.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {number} s Scaling value.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is the scaled vector.
- */
- function scale(a, s, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.x * s, a.y * s);
- };
- Vec2Utils.perp = /**
- * Rotate a 2D vector by 90 degrees.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is the scaled vector.
- */
- function perp(a, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.y, -a.x);
- };
- Vec2Utils.equals = /**
- * Checks if two 2D vectors are equal.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Boolean}
- */
- function equals(a, b) {
- return a.x == b.x && a.y == b.y;
- };
- Vec2Utils.epsilonEquals = /**
- *
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} epsilon
- * @return {Boolean}
- */
- function epsilonEquals(a, b, epsilon) {
- return Math.abs(a.x - b.x) <= epsilon && Math.abs(a.y - b.y) <= epsilon;
- };
- Vec2Utils.distance = /**
- * Get the distance between two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Number}
- */
- function distance(a, b) {
- return Math.sqrt(Vec2Utils.distanceSq(a, b));
- };
- Vec2Utils.distanceSq = /**
- * Get the distance squared between two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Number}
- */
- function distanceSq(a, b) {
- return ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
- };
- Vec2Utils.project = /**
- * Project two 2D vectors onto another vector.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2.
- */
- function project(a, b, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- var amt = a.dot(b) / b.lengthSq();
- if(amt != 0) {
- out.setTo(amt * b.x, amt * b.y);
- }
- return out;
- };
- Vec2Utils.projectUnit = /**
- * Project this vector onto a vector of unit length.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2.
- */
- function projectUnit(a, b, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- var amt = a.dot(b);
- if(amt != 0) {
- out.setTo(amt * b.x, amt * b.y);
- }
- return out;
- };
- Vec2Utils.normalRightHand = /**
- * Right-hand normalize (make unit length) a 2D vector.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2.
- */
- function normalRightHand(a, out) {
- if (typeof out === "undefined") { out = this; }
- return out.setTo(a.y * -1, a.x);
- };
- Vec2Utils.normalize = /**
- * Normalize (make unit length) a 2D vector.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2.
- */
- function normalize(a, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- var m = a.length();
- if(m != 0) {
- out.setTo(a.x / m, a.y / m);
- }
- return out;
- };
- Vec2Utils.dot = /**
- * The dot product of two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Number}
- */
- function dot(a, b) {
- return ((a.x * b.x) + (a.y * b.y));
- };
- Vec2Utils.cross = /**
- * The cross product of two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Number}
- */
- function cross(a, b) {
- return ((a.x * b.y) - (a.y * b.x));
- };
- Vec2Utils.angle = /**
- * The angle between two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Number}
- */
- function angle(a, b) {
- return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
- };
- Vec2Utils.angleSq = /**
- * The angle squared between two 2D vectors.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @return {Number}
- */
- function angleSq(a, b) {
- return a.subtract(b).angle(b.subtract(a));
- };
- Vec2Utils.rotate = /**
- * Rotate a 2D vector around the origin to the given angle (theta).
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} b Reference to a source Vec2 object.
- * @param {Number} theta The angle of rotation in radians.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2.
- */
- function rotate(a, b, theta, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- var x = a.x - b.x;
- var y = a.y - b.y;
- return out.setTo(x * Math.cos(theta) - y * Math.sin(theta) + b.x, x * Math.sin(theta) + y * Math.cos(theta) + b.y);
- };
- Vec2Utils.clone = /**
- * Clone a 2D vector.
- *
- * @param {Vec2} a Reference to a source Vec2 object.
- * @param {Vec2} out The output Vec2 that is the result of the operation.
- * @return {Vec2} A Vec2 that is a copy of the source Vec2.
- */
- function clone(a, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- return out.setTo(a.x, a.y);
- };
- return Vec2Utils;
- })();
- Phaser.Vec2Utils = Vec2Utils;
- /**
- * Reflect this vector on an arbitrary axis.
- *
- * @param {Vec2} axis The vector representing the axis.
- * @return {Vec2} This for chaining.
- */
- /*
- static reflect(axis): Vec2 {
-
- var x = this.x;
- var y = this.y;
- this.project(axis).scale(2);
- this.x -= x;
- this.y -= y;
-
- return this;
-
- }
- */
- /**
- * Reflect this vector on an arbitrary axis (represented by a unit vector)
- *
- * @param {Vec2} axis The unit vector representing the axis.
- * @return {Vec2} This for chaining.
- */
- /*
- static reflectN(axis): Vec2 {
-
- var x = this.x;
- var y = this.y;
- this.projectN(axis).scale(2);
- this.x -= x;
- this.y -= y;
-
- return this;
-
- }
-
- static getMagnitude(): number {
- return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
- }
- */
- })(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- })(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- ///
- ///
- ///
- /**
- * Phaser - PhysicsManager
- *
- * Your game only has one PhysicsManager instance and it's responsible for looking after, creating and colliding
- * all of the physics objects in the world.
- */
- (function (Physics) {
- var PhysicsManager = (function () {
- function PhysicsManager(game, width, height) {
- this._length = 0;
- this.game = game;
- this.gravity = new Phaser.Vec2();
- this.drag = new Phaser.Vec2();
- this.bounce = new Phaser.Vec2();
- this.friction = new Phaser.Vec2();
- this.bounds = new Phaser.Rectangle(0, 0, width, height);
- this._distance = new Phaser.Vec2();
- this._tangent = new Phaser.Vec2();
- this._objects = [];
- }
- PhysicsManager.prototype.add = // Add some sanity checks here + remove method, etc
- function (shape) {
- this._objects.push(shape);
- return shape;
- };
- PhysicsManager.prototype.remove = function (shape) {
- this._length = this._objects.length;
- for(var i = 0; i < this._length; i++) {
- if(this._objects[i] === shape) {
- this._objects[i] = null;
- }
- }
- };
- PhysicsManager.prototype.update = function () {
- this._length = this._objects.length;
- for(var i = 0; i < this._length; i++) {
- if(this._objects[i]) {
- this._objects[i].preUpdate();
- this.updateMotion(this._objects[i]);
- this.collideWorld(this._objects[i]);
- for(var x = 0; x < this._length; x++) {
- if(this._objects[x] && this._objects[x] !== this._objects[i]) {
- //this.collideShapes(this._objects[i], this._objects[x]);
- var r = this.NEWseparate(this._objects[i], this._objects[x]);
- //console.log('sep', r);
- }
- }
- }
- }
- };
- PhysicsManager.prototype.render = function () {
- // iterate through the objects here, updating and colliding
- for(var i = 0; i < this._length; i++) {
- if(this._objects[i]) {
- this._objects[i].render(this.game.stage.context);
- }
- }
- };
- PhysicsManager.prototype.updateMotion = function (shape) {
- if(shape.physics.moves == false) {
- return;
- }
- /*
- velocityDelta = (this._game.motion.computeVelocity(this.angularVelocity, this.angularAcceleration, this.angularDrag, this.maxAngular) - this.angularVelocity) / 2;
- this.angularVelocity += velocityDelta;
- this._angle += this.angularVelocity * this._game.time.elapsed;
- this.angularVelocity += velocityDelta;
- */
- this._velocityDelta = (this.computeVelocity(shape.physics.velocity.x, shape.physics.gravity.x, shape.physics.acceleration.x, shape.physics.drag.x) - shape.physics.velocity.x) / 2;
- shape.physics.velocity.x += this._velocityDelta;
- this._delta = shape.physics.velocity.x * this.game.time.elapsed;
- shape.physics.velocity.x += this._velocityDelta;
- shape.position.x += this._delta;
- this._velocityDelta = (this.computeVelocity(shape.physics.velocity.y, shape.physics.gravity.y, shape.physics.acceleration.y, shape.physics.drag.y) - shape.physics.velocity.y) / 2;
- shape.physics.velocity.y += this._velocityDelta;
- this._delta = shape.physics.velocity.y * this.game.time.elapsed;
- shape.physics.velocity.y += this._velocityDelta;
- shape.position.y += this._delta;
- };
- PhysicsManager.prototype.computeVelocity = /**
- * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
- *
- * @param {number} Velocity Any component of velocity (e.g. 20).
- * @param {number} Acceleration Rate at which the velocity is changing.
- * @param {number} Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
- * @param {number} Max An absolute value cap for the velocity.
- *
- * @return {number} The altered Velocity value.
- */
- function (velocity, gravity, acceleration, drag, max) {
- if (typeof gravity === "undefined") { gravity = 0; }
- if (typeof acceleration === "undefined") { acceleration = 0; }
- if (typeof drag === "undefined") { drag = 0; }
- if (typeof max === "undefined") { max = 10000; }
- if(acceleration !== 0) {
- velocity += (acceleration + gravity) * this.game.time.elapsed;
- } else if(drag !== 0) {
- this._drag = drag * this.game.time.elapsed;
- if(velocity - this._drag > 0) {
- velocity = velocity - this._drag;
- } else if(velocity + this._drag < 0) {
- velocity += this._drag;
- } else {
- velocity = 0;
- }
- velocity += gravity;
- }
- if((velocity != 0) && (max != 10000)) {
- if(velocity > max) {
- velocity = max;
- } else if(velocity < -max) {
- velocity = -max;
- }
- }
- return velocity;
- };
- PhysicsManager.prototype.collideShapes = function (shapeA, shapeB) {
- if(shapeA.physics.immovable && shapeB.physics.immovable) {
- return;
- }
- this._distance.setTo(0, 0);
- this._tangent.setTo(0, 0);
- // Simple bounds check first
- if(Phaser.RectangleUtils.intersects(shapeA.bounds, shapeB.bounds)) {
- // Collide on the x-axis
- if(shapeA.physics.velocity.x > 0 && shapeA.bounds.right > shapeB.bounds.x && shapeA.bounds.right <= shapeB.bounds.right) {
- // The right side of ShapeA hit the left side of ShapeB
- this._distance.x = shapeB.bounds.x - shapeA.bounds.right;
- if(this._distance.x != 0) {
- this._tangent.x = -1;
- }
- } else if(shapeA.physics.velocity.x < 0 && shapeA.bounds.x < shapeB.bounds.right && shapeA.bounds.x >= shapeB.bounds.x) {
- // The left side of ShapeA hit the right side of ShapeB
- this._distance.x = shapeB.bounds.right - shapeA.bounds.x;
- if(this._distance.x != 0) {
- this._tangent.x = 1;
- }
- }
- // Collide on the y-axis
- if(shapeA.physics.velocity.y < 0 && shapeA.bounds.y < shapeB.bounds.bottom && shapeA.bounds.y > shapeB.bounds.y) {
- console.log('top A -> bot B');
- // The top of ShapeA hit the bottom of ShapeB
- this._distance.y = shapeB.bounds.bottom - shapeA.bounds.y;
- console.log(shapeA.bounds, shapeB.bounds, this._distance.y);
- if(this._distance.y != 0) {
- this._tangent.y = 1;
- }
- } else if(shapeA.physics.velocity.y > 0 && shapeA.bounds.bottom > shapeB.bounds.y && shapeA.bounds.bottom < shapeB.bounds.bottom) {
- // The bottom of ShapeA hit the top of ShapeB
- this._distance.y = shapeB.bounds.y - shapeA.bounds.bottom;
- if(this._distance.y != 0) {
- this._tangent.y = -1;
- }
- }
- // Separate
- if(this._distance.equals(0) == false) {
- //this.separate(shapeA, shapeB, this._distance, this._tangent);
- }
- }
- };
- PhysicsManager.prototype.NEWseparate = /**
- * 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.
- */
- function (object1, object2) {
- var separatedX = this.separateSpriteToSpriteX(object1, object2);
- var separatedY = this.separateSpriteToSpriteY(object1, object2);
- return separatedX || separatedY;
- };
- PhysicsManager.prototype.checkHullIntersection = function (shape1, shape2) {
- //if ((shape1.hullX + shape1.hullWidth > shape2.hullX) && (shape1.hullX < shape2.hullX + shape2.bounds.width) && (shape1.hullY + shape1.hullHeight > shape2.hullY) && (shape1.hullY < shape2.hullY + shape2.hullHeight))
- // maybe not bounds.width?
- if((shape1.hullX + shape1.hullWidth > shape2.hullX) && (shape1.hullX < shape2.hullX + shape2.hullWidth) && (shape1.hullY + shape1.hullHeight > shape2.hullY) && (shape1.hullY < shape2.hullY + shape2.hullHeight)) {
- return true;
- } else {
- return false;
- }
- };
- PhysicsManager.prototype.separateSpriteToSpriteX = /**
- * 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.
- */
- function (object1, object2) {
- // Can't separate two immovable objects
- if(object1.physics.immovable && object2.physics.immovable) {
- return false;
- }
- // First, get the two object deltas
- var overlap = 0;
- if(object1.physics.shape.deltaX != object2.physics.shape.deltaX) {
- if(Phaser.RectangleUtils.intersects(object1.physics.shape.bounds, object2.physics.shape.bounds)) {
- //var maxOverlap: number = object1.physics.shape.deltaXAbs + object2.physics.shape.deltaXAbs + Collision.OVERLAP_BIAS;
- var maxOverlap = object1.physics.shape.deltaXAbs + object2.physics.shape.deltaXAbs + 4;
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if(object1.physics.shape.deltaX > object2.physics.shape.deltaX) {
- overlap = object1.physics.shape.bounds.right - object2.physics.shape.bounds.x;
- if((overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.RIGHT) || !(object2.physics.allowCollisions & Phaser.Types.LEFT)) {
- overlap = 0;
- } else {
- object1.physics.touching |= Phaser.Types.RIGHT;
- object2.physics.touching |= Phaser.Types.LEFT;
- }
- } else if(object1.physics.shape.deltaX < object2.physics.shape.deltaX) {
- overlap = object1.physics.shape.bounds.x - object2.physics.shape.bounds.width - object2.physics.shape.bounds.x;
- if((-overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.LEFT) || !(object2.physics.allowCollisions & Phaser.Types.RIGHT)) {
- overlap = 0;
- } else {
- object1.physics.touching |= Phaser.Types.LEFT;
- object2.physics.touching |= Phaser.Types.RIGHT;
- }
- }
- }
- }
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if(overlap != 0) {
- var obj1Velocity = object1.physics.velocity.x;
- var obj2Velocity = object2.physics.velocity.x;
- if(!object1.physics.immovable && !object2.physics.immovable) {
- overlap *= 0.5;
- object1.physics.shape.position.x = object1.physics.shape.position.x - overlap;
- object2.physics.shape.position.x += overlap;
- var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.physics.mass) / object1.physics.mass) * ((obj2Velocity > 0) ? 1 : -1);
- var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.physics.mass) / object2.physics.mass) * ((obj1Velocity > 0) ? 1 : -1);
- var average = (obj1NewVelocity + obj2NewVelocity) * 0.5;
- obj1NewVelocity -= average;
- obj2NewVelocity -= average;
- object1.physics.velocity.x = average + obj1NewVelocity * object1.physics.bounce.x;
- object2.physics.velocity.x = average + obj2NewVelocity * object2.physics.bounce.x;
- } else if(!object1.physics.immovable) {
- overlap *= 2;
- object1.physics.shape.position.x -= overlap;
- object1.physics.velocity.x = obj2Velocity - obj1Velocity * object1.physics.bounce.x;
- } else if(!object2.physics.immovable) {
- overlap *= 2;
- object2.physics.shape.position.x += overlap;
- object2.physics.velocity.x = obj1Velocity - obj2Velocity * object2.physics.bounce.x;
- }
- return true;
- } else {
- return false;
- }
- };
- PhysicsManager.prototype.separateSpriteToSpriteY = /**
- * 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.
- */
- function (object1, object2) {
- // Can't separate two immovable objects
- if(object1.physics.immovable && object2.physics.immovable) {
- return false;
- }
- // First, get the two object deltas
- var overlap = 0;
- if(object1.physics.shape.deltaY != object2.physics.shape.deltaY) {
- if(Phaser.RectangleUtils.intersects(object1.physics.shape.bounds, object2.physics.shape.bounds)) {
- // This is the only place to use the DeltaAbs values
- //var maxOverlap: number = object1.physics.shape.deltaYAbs + object2.physics.shape.deltaYAbs + Phaser.Types.OVERLAP_BIAS;
- var maxOverlap = object1.physics.shape.deltaYAbs + object2.physics.shape.deltaYAbs + 4;
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if(object1.physics.shape.deltaY > object2.physics.shape.deltaY) {
- overlap = object1.physics.shape.bounds.bottom - object2.physics.shape.bounds.y;
- if((overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.DOWN) || !(object2.physics.allowCollisions & Phaser.Types.UP)) {
- overlap = 0;
- } else {
- object1.physics.touching |= Phaser.Types.DOWN;
- object2.physics.touching |= Phaser.Types.UP;
- }
- } else if(object1.physics.shape.deltaY < object2.physics.shape.deltaY) {
- overlap = object1.physics.shape.bounds.y - object2.physics.shape.bounds.height - object2.physics.shape.bounds.y;
- if((-overlap > maxOverlap) || !(object1.physics.allowCollisions & Phaser.Types.UP) || !(object2.physics.allowCollisions & Phaser.Types.DOWN)) {
- overlap = 0;
- } else {
- object1.physics.touching |= Phaser.Types.UP;
- object2.physics.touching |= Phaser.Types.DOWN;
- }
- }
- }
- }
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if(overlap != 0) {
- var obj1Velocity = object1.physics.velocity.y;
- var obj2Velocity = object2.physics.velocity.y;
- if(!object1.physics.immovable && !object2.physics.immovable) {
- overlap *= 0.5;
- object1.physics.shape.position.y = object1.physics.shape.position.y - overlap;
- object2.physics.shape.position.y += overlap;
- var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.physics.mass) / object1.physics.mass) * ((obj2Velocity > 0) ? 1 : -1);
- var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.physics.mass) / object2.physics.mass) * ((obj1Velocity > 0) ? 1 : -1);
- var average = (obj1NewVelocity + obj2NewVelocity) * 0.5;
- obj1NewVelocity -= average;
- obj2NewVelocity -= average;
- object1.physics.velocity.y = average + obj1NewVelocity * object1.physics.bounce.y;
- object2.physics.velocity.y = average + obj2NewVelocity * object2.physics.bounce.y;
- } else if(!object1.physics.immovable) {
- overlap *= 2;
- object1.physics.shape.position.y -= overlap;
- object1.physics.velocity.y = obj2Velocity - obj1Velocity * object1.physics.bounce.y;
- // This is special case code that handles things like horizontal moving platforms you can ride
- if(object2.active && object2.physics.moves && (object1.physics.shape.deltaY > object2.physics.shape.deltaY)) {
- object1.physics.shape.position.x += object2.physics.shape.position.x - object2.physics.shape.oldPosition.x;
- }
- } else if(!object2.physics.immovable) {
- overlap *= 2;
- object2.physics.shape.position.y += overlap;
- object2.physics.velocity.y = obj1Velocity - obj2Velocity * object2.physics.bounce.y;
- // This is special case code that handles things like horizontal moving platforms you can ride
- if(object1.active && object1.physics.moves && (object1.physics.shape.deltaY < object2.physics.shape.deltaY)) {
- object2.physics.shape.position.x += object1.physics.shape.position.x - object1.physics.shape.oldPosition.x;
- }
- }
- return true;
- } else {
- return false;
- }
- };
- PhysicsManager.prototype.separate = function (shapeA, shapeB, distance, tangent) {
- if(tangent.x == 1) {
- console.log('1 The left side of ShapeA hit the right side of ShapeB', Math.floor(distance.x));
- shapeA.physics.touching |= Phaser.Types.LEFT;
- shapeB.physics.touching |= Phaser.Types.RIGHT;
- } else if(tangent.x == -1) {
- console.log('2 The right side of ShapeA hit the left side of ShapeB', Math.floor(distance.x));
- shapeA.physics.touching |= Phaser.Types.RIGHT;
- shapeB.physics.touching |= Phaser.Types.LEFT;
- }
- if(tangent.y == 1) {
- console.log('3 The top of ShapeA hit the bottom of ShapeB', Math.floor(distance.y));
- shapeA.physics.touching |= Phaser.Types.UP;
- shapeB.physics.touching |= Phaser.Types.DOWN;
- } else if(tangent.y == -1) {
- console.log('4 The bottom of ShapeA hit the top of ShapeB', Math.floor(distance.y));
- shapeA.physics.touching |= Phaser.Types.DOWN;
- shapeB.physics.touching |= Phaser.Types.UP;
- }
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- var dot = Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent);
- if(dot < 0) {
- console.log('in to', dot);
- // Apply horizontal bounce
- if(shapeA.physics.bounce.x > 0) {
- shapeA.physics.velocity.x *= -(shapeA.physics.bounce.x);
- } else {
- shapeA.physics.velocity.x = 0;
- }
- // Apply horizontal bounce
- if(shapeA.physics.bounce.y > 0) {
- shapeA.physics.velocity.y *= -(shapeA.physics.bounce.y);
- } else {
- shapeA.physics.velocity.y = 0;
- }
- } else {
- console.log('out of', dot);
- }
- shapeA.position.x += Math.floor(distance.x);
- //shapeA.bounds.x += Math.floor(distance.x);
- shapeA.position.y += Math.floor(distance.y);
- //shapeA.bounds.y += distance.y;
- console.log('------------------------------------------------');
- };
- PhysicsManager.prototype.collideWorld = function (shape) {
- // Collide on the x-axis
- this._distance.x = shape.world.bounds.x - (shape.position.x - shape.bounds.halfWidth);
- if(0 < this._distance.x) {
- // Hit Left
- this._tangent.setTo(1, 0);
- this.separateXWall(shape, this._distance, this._tangent);
- } else {
- this._distance.x = (shape.position.x + shape.bounds.halfWidth) - shape.world.bounds.right;
- if(0 < this._distance.x) {
- // Hit Right
- this._tangent.setTo(-1, 0);
- this._distance.reverse();
- this.separateXWall(shape, this._distance, this._tangent);
- }
- }
- // Collide on the y-axis
- this._distance.y = shape.world.bounds.y - (shape.position.y - shape.bounds.halfHeight);
- if(0 < this._distance.y) {
- // Hit Top
- this._tangent.setTo(0, 1);
- this.separateYWall(shape, this._distance, this._tangent);
- } else {
- this._distance.y = (shape.position.y + shape.bounds.halfHeight) - shape.world.bounds.bottom;
- if(0 < this._distance.y) {
- // Hit Bottom
- this._tangent.setTo(0, -1);
- this._distance.reverse();
- this.separateYWall(shape, this._distance, this._tangent);
- }
- }
- };
- PhysicsManager.prototype.separateX = function (shapeA, shapeB, distance, tangent) {
- if(tangent.x == 1) {
- console.log('The left side of ShapeA hit the right side of ShapeB', distance.x);
- shapeA.physics.touching |= Phaser.Types.LEFT;
- shapeB.physics.touching |= Phaser.Types.RIGHT;
- } else {
- console.log('The right side of ShapeA hit the left side of ShapeB', distance.x);
- shapeA.physics.touching |= Phaser.Types.RIGHT;
- shapeB.physics.touching |= Phaser.Types.LEFT;
- }
- // collision edges
- //shapeA.oH = tangent.x;
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
- // Apply horizontal bounce
- if(shapeA.physics.bounce.x > 0) {
- shapeA.physics.velocity.x *= -(shapeA.physics.bounce.x);
- } else {
- shapeA.physics.velocity.x = 0;
- }
- }
- shapeA.position.x += distance.x;
- shapeA.bounds.x += distance.x;
- };
- PhysicsManager.prototype.separateY = function (shapeA, shapeB, distance, tangent) {
- if(tangent.y == 1) {
- console.log('The top of ShapeA hit the bottom of ShapeB', distance.y);
- shapeA.physics.touching |= Phaser.Types.UP;
- shapeB.physics.touching |= Phaser.Types.DOWN;
- } else {
- console.log('The bottom of ShapeA hit the top of ShapeB', distance.y);
- shapeA.physics.touching |= Phaser.Types.DOWN;
- shapeB.physics.touching |= Phaser.Types.UP;
- }
- // collision edges
- //shapeA.oV = tangent.y;
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
- // Apply horizontal bounce
- if(shapeA.physics.bounce.y > 0) {
- shapeA.physics.velocity.y *= -(shapeA.physics.bounce.y);
- } else {
- shapeA.physics.velocity.y = 0;
- }
- }
- shapeA.position.y += distance.y;
- shapeA.bounds.y += distance.y;
- };
- PhysicsManager.prototype.separateXWall = function (shapeA, distance, tangent) {
- if(tangent.x == 1) {
- console.log('The left side of ShapeA hit the right side of ShapeB', distance.x);
- shapeA.physics.touching |= Phaser.Types.LEFT;
- } else {
- console.log('The right side of ShapeA hit the left side of ShapeB', distance.x);
- shapeA.physics.touching |= Phaser.Types.RIGHT;
- }
- // collision edges
- //shapeA.oH = tangent.x;
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
- // Apply horizontal bounce
- if(shapeA.physics.bounce.x > 0) {
- shapeA.physics.velocity.x *= -(shapeA.physics.bounce.x);
- } else {
- shapeA.physics.velocity.x = 0;
- }
- }
- shapeA.position.x += distance.x;
- };
- PhysicsManager.prototype.separateYWall = function (shapeA, distance, tangent) {
- if(tangent.y == 1) {
- console.log('The top of ShapeA hit the bottom of ShapeB', distance.y);
- shapeA.physics.touching |= Phaser.Types.UP;
- } else {
- console.log('The bottom of ShapeA hit the top of ShapeB', distance.y);
- shapeA.physics.touching |= Phaser.Types.DOWN;
- }
- // collision edges
- //shapeA.oV = tangent.y;
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- if(Phaser.Vec2Utils.dot(shapeA.physics.velocity, tangent) < 0) {
- // Apply horizontal bounce
- if(shapeA.physics.bounce.y > 0) {
- shapeA.physics.velocity.y *= -(shapeA.physics.bounce.y);
- } else {
- shapeA.physics.velocity.y = 0;
- }
- }
- shapeA.position.y += distance.y;
- };
- PhysicsManager.prototype.OLDseparate = function (shape, distance, tangent) {
- // collision edges
- //shape.oH = tangent.x;
- //shape.oV = tangent.y;
- // Velocity (move to temp vars)
- // was vx/vy
- var velocity = Phaser.Vec2Utils.subtract(shape.position, shape.oldPosition);
- // was dp
- var dot = Phaser.Vec2Utils.dot(shape.physics.velocity, tangent);
- // project velocity onto the collision normal
- // was nx/ny
- tangent.multiplyByScalar(dot);
- // was tx/ty (tangent velocity?)
- var tangentVelocity = Phaser.Vec2Utils.subtract(velocity, tangent);
- // only apply collision response forces if the object is travelling into, and not out of, the collision
- if(dot < 0) {
- // Apply horizontal bounce
- if(distance.x != 0) {
- if(shape.physics.bounce.x > 0) {
- shape.physics.velocity.x *= -(shape.physics.bounce.x);
- } else {
- shape.physics.velocity.x = 0;
- }
- }
- // Apply vertical bounce
- if(distance.y != 0) {
- if(shape.physics.bounce.y > 0) {
- shape.physics.velocity.y *= -(shape.physics.bounce.y);
- } else {
- shape.physics.velocity.y = 0;
- }
- }
- } else {
- // moving out of collision
- }
- // project object out of collision
- //console.log('proj out', distance.x, distance.y,'dot',dot);
- shape.position.add(distance);
- };
- return PhysicsManager;
- })();
- Physics.PhysicsManager = PhysicsManager;
- /**
- * 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.
- * @param context The context in which the callbacks will be called
- * @returns {boolean} true if the objects overlap, otherwise false.
- */
- /*
- public overlap(object1: Basic = null, object2: Basic = null, notifyCallback = null, processCallback = null, context = null): bool {
-
- if (object1 == null)
- {
- object1 = this._game.world.group;
- }
-
- if (object2 == object1)
- {
- object2 = null;
- }
-
- QuadTree.divisions = this._game.world.worldDivisions;
-
- var quadTree: QuadTree = new 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, context);
-
- var result: bool = quadTree.execute();
-
- quadTree.destroy();
-
- quadTree = null;
-
- return result;
-
- }
- */
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Physics - AABB
- */
- (function (Physics) {
- var AABB = (function () {
- function AABB(game, sprite, x, y, width, height) {
- this.game = game;
- this.world = game.world.physics;
- if(sprite !== null) {
- this.sprite = sprite;
- this.scale = Phaser.Vec2Utils.clone(this.sprite.scale);
- } else {
- this.sprite = null;
- this.physics = null;
- this.scale = new Phaser.Vec2(1, 1);
- }
- this.bounds = new Phaser.Rectangle(x + Math.round(width / 2), y + Math.round(height / 2), width, height);
- this.position = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
- this.oldPosition = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
- this.offset = new Phaser.Vec2(0, 0);
- }
- AABB.prototype.preUpdate = function () {
- this.oldPosition.copyFrom(this.position);
- this.bounds.x = this.position.x - this.bounds.halfWidth;
- this.bounds.y = this.position.y - this.bounds.halfHeight;
- if(this.sprite) {
- this.position.setTo((this.sprite.x + this.bounds.halfWidth) + this.offset.x, (this.sprite.y + this.bounds.halfHeight) + this.offset.y);
- // Update scale / dimensions
- if(Phaser.Vec2Utils.equals(this.scale, this.sprite.scale) == false) {
- this.scale.copyFrom(this.sprite.scale);
- this.bounds.width = this.sprite.width;
- this.bounds.height = this.sprite.height;
- }
- }
- };
- AABB.prototype.update = function () {
- //this.bounds.x = this.position.x;
- //this.bounds.y = this.position.y;
- };
- AABB.prototype.setSize = function (width, height) {
- this.bounds.width = width;
- this.bounds.height = height;
- };
- AABB.prototype.render = function (context) {
- context.beginPath();
- context.strokeStyle = 'rgb(0,255,0)';
- context.strokeRect(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight, this.bounds.width, this.bounds.height);
- context.stroke();
- context.closePath();
- // center point
- context.fillStyle = 'rgb(0,255,0)';
- context.fillRect(this.position.x, this.position.y, 2, 2);
- if(this.physics.touching & Phaser.Types.LEFT) {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.lineTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- if(this.physics.touching & Phaser.Types.RIGHT) {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- if(this.physics.touching & Phaser.Types.UP) {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- if(this.physics.touching & Phaser.Types.DOWN) {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- };
- Object.defineProperty(AABB.prototype, "hullWidth", {
- get: function () {
- if(this.deltaX > 0) {
- return this.bounds.width + this.deltaX;
- } else {
- return this.bounds.width - this.deltaX;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "hullHeight", {
- get: function () {
- if(this.deltaY > 0) {
- return this.bounds.height + this.deltaY;
- } else {
- return this.bounds.height - this.deltaY;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "hullX", {
- get: function () {
- if(this.position.x < this.oldPosition.x) {
- return this.position.x;
- } else {
- return this.oldPosition.x;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "hullY", {
- get: function () {
- if(this.position.y < this.oldPosition.y) {
- return this.position.y;
- } else {
- return this.oldPosition.y;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "deltaXAbs", {
- get: function () {
- return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "deltaYAbs", {
- get: function () {
- return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "deltaX", {
- get: function () {
- return this.position.x - this.oldPosition.x;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(AABB.prototype, "deltaY", {
- get: function () {
- return this.position.y - this.oldPosition.y;
- },
- enumerable: true,
- configurable: true
- });
- return AABB;
- })();
- Physics.AABB = AABB;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-///
///
///
/**
@@ -6650,12 +7177,14 @@ var Phaser;
*
* @param x {number} X position of the new sprite.
* @param y {number} Y position of the new sprite.
- * @param key {string} Optional, key for the sprite sheet you want it to use.
+ * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
* @returns {Sprite} The newly created sprite object.
*/
- function (x, y, key) {
+ function (x, y, key, bodyType) {
if (typeof key === "undefined") { key = ''; }
- return this._world.group.add(new Phaser.Sprite(this._game, x, y, key));
+ if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; }
+ return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, bodyType));
};
GameObjectFactory.prototype.dynamicTexture = /**
* Create a new DynamicTexture with specific size.
@@ -6835,6 +7364,10 @@ var Phaser;
Types.GEOM_RECTANGLE = 2;
Types.GEOM_LINE = 3;
Types.GEOM_POLYGON = 4;
+ Types.BODY_DISABLED = 0;
+ Types.BODY_DYNAMIC = 1;
+ Types.BODY_STATIC = 2;
+ Types.BODY_KINEMATIC = 3;
Types.LEFT = 0x0001;
Types.RIGHT = 0x0010;
Types.UP = 0x0100;
@@ -11573,7 +12106,7 @@ var Phaser;
if (typeof y === "undefined") { y = 0; }
if (typeof width === "undefined") { width = 0; }
if (typeof height === "undefined") { height = 0; }
- _super.call(this, game, x, y, key, width, height);
+ _super.call(this, game, x, y, key, width, height);
this.type = Phaser.Types.SCROLLZONE;
this.render = game.renderer.renderScrollZone;
this.physics.moves = false;
@@ -12537,187 +13070,6 @@ var Phaser;
Phaser.Vec2 = Vec2;
})(Phaser || (Phaser = {}));
var Phaser;
-(function (Phaser) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Physics - Circle
- */
- (function (Physics) {
- var Circle = (function () {
- function Circle(game, sprite, x, y, diameter) {
- this.game = game;
- this.world = game.world.physics;
- if(sprite !== null) {
- this.sprite = sprite;
- this.scale = Phaser.Vec2Utils.clone(this.sprite.scale);
- } else {
- this.sprite = null;
- this.physics = null;
- this.scale = new Phaser.Vec2(1, 1);
- }
- this.diameter = diameter;
- this.radius = diameter / 2;
- this.bounds = new Phaser.Rectangle(x + Math.round(diameter / 2), y + Math.round(diameter / 2), diameter, diameter);
- this.position = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
- this.oldPosition = new Phaser.Vec2(x + this.bounds.halfWidth, y + this.bounds.halfHeight);
- this.offset = new Phaser.Vec2(0, 0);
- }
- Circle.prototype.preUpdate = function () {
- this.oldPosition.copyFrom(this.position);
- this.bounds.x = this.position.x - this.bounds.halfWidth;
- this.bounds.y = this.position.y - this.bounds.halfHeight;
- if(this.sprite) {
- this.position.setTo((this.sprite.x + this.bounds.halfWidth) + this.offset.x, (this.sprite.y + this.bounds.halfHeight) + this.offset.y);
- // Update scale / dimensions
- if(Phaser.Vec2Utils.equals(this.scale, this.sprite.scale) == false) {
- this.scale.copyFrom(this.sprite.scale);
- // needs to be radius based (+ square)
- //this.bounds.width = this.sprite.width;
- //this.bounds.height = this.sprite.height;
- }
- }
- };
- Circle.prototype.update = function () {
- //this.bounds.x = this.position.x;
- //this.bounds.y = this.position.y;
- };
- Circle.prototype.setSize = function (width, height) {
- this.bounds.width = width;
- this.bounds.height = height;
- };
- Circle.prototype.render = function (context) {
- // center point
- context.fillStyle = 'rgba(255,0,0,0.5)';
- context.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
- context.rect(this.position.x, this.position.y, 2, 2);
- context.fill();
- /*
- if (this.oH == 1)
- {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.lineTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- else if (this.oH == -1)
- {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
-
- if (this.oV == 1)
- {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y - this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- else if (this.oV == -1)
- {
- context.beginPath();
- context.strokeStyle = 'rgb(255,0,0)';
- context.moveTo(this.position.x - this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.lineTo(this.position.x + this.bounds.halfWidth, this.position.y + this.bounds.halfHeight);
- context.stroke();
- context.closePath();
- }
- */
- };
- Object.defineProperty(Circle.prototype, "hullWidth", {
- get: function () {
- if(this.deltaX > 0) {
- //return this.bounds.width + this.deltaX;
- return this.diameter + this.deltaX;
- } else {
- //return this.bounds.width - this.deltaX;
- return this.diameter - this.deltaX;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "hullHeight", {
- get: function () {
- if(this.deltaY > 0) {
- //return this.bounds.height + this.deltaY;
- return this.diameter + this.deltaY;
- } else {
- //return this.bounds.height - this.deltaY;
- return this.diameter - this.deltaY;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "hullX", {
- get: function () {
- if(this.position.x < this.oldPosition.x) {
- return this.position.x;
- } else {
- return this.oldPosition.x;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "hullY", {
- get: function () {
- if(this.position.y < this.oldPosition.y) {
- return this.position.y;
- } else {
- return this.oldPosition.y;
- }
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "deltaXAbs", {
- get: function () {
- return (this.deltaX > 0 ? this.deltaX : -this.deltaX);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "deltaYAbs", {
- get: function () {
- return (this.deltaY > 0 ? this.deltaY : -this.deltaY);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "deltaX", {
- get: function () {
- return this.position.x - this.oldPosition.x;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Circle.prototype, "deltaY", {
- get: function () {
- return this.position.y - this.oldPosition.y;
- },
- enumerable: true,
- configurable: true
- });
- return Circle;
- })();
- Physics.Circle = Circle;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
(function (Phaser) {
///
///
@@ -12725,6 +13077,7 @@ var Phaser;
///
///
///
+ ///
/**
* Phaser - Components - Physics
*/
@@ -12756,6 +13109,7 @@ var Phaser;
this.shape = this.game.world.physics.add(new Phaser.Physics.AABB(this.game, this._sprite, this._sprite.x, this._sprite.y, this._sprite.width, this._sprite.height));
}
Physics.prototype.setCircle = function (diameter) {
+ // Here is the stuff I want to remove
this.game.world.physics.remove(this.shape);
this.shape = this.game.world.physics.add(new Phaser.Physics.Circle(this.game, this._sprite, this._sprite.x, this._sprite.y, diameter));
this._sprite.physics.shape.physics = this;
@@ -12764,6 +13118,7 @@ var Phaser;
* Internal function for updating the position and speed of this object.
*/
function () {
+ // if this is all it does maybe move elsewhere? Sprite postUpdate?
if(this.moves && this.shape) {
this._sprite.x = (this.shape.position.x - this.shape.bounds.halfWidth) - this.shape.offset.x;
this._sprite.y = (this.shape.position.y - this.shape.bounds.halfHeight) - this.shape.offset.y;
@@ -12825,157 +13180,30 @@ var Phaser;
})();
Phaser.Polygon = Polygon;
})(Phaser || (Phaser = {}));
-///
-///
-///
-///
-/**
-* Phaser - CircleUtils
-*
-* A collection of methods useful for manipulating and comparing Circle objects.
-*
-* TODO:
-*/
var Phaser;
(function (Phaser) {
- var CircleUtils = (function () {
- function CircleUtils() { }
- CircleUtils.clone = /**
- * Returns a new Circle object with the same values for the x, y, width, and height properties as the original Circle object.
- * @method clone
- * @param {Circle} a - The Circle object.
- * @param {Circle} [optional] out Optional Circle object. If given the values will be set into the object, otherwise a brand new Circle object will be created and returned.
- * @return {Phaser.Circle}
- **/
- function clone(a, out) {
- if (typeof out === "undefined") { out = new Phaser.Circle(); }
- return out.setTo(a.x, a.y, a.diameter);
- };
- CircleUtils.contains = /**
- * Return true if the given x/y coordinates are within the Circle object.
- * If you need details about the intersection then use Phaser.Intersect.circleContainsPoint instead.
- * @method contains
- * @param {Circle} a - The Circle object.
- * @param {Number} The X value of the coordinate to test.
- * @param {Number} The Y value of the coordinate to test.
- * @return {Boolean} True if the coordinates are within this circle, otherwise false.
- **/
- function contains(a, x, y) {
- //return (a.radius * a.radius >= Collision.distanceSquared(a.x, a.y, x, y));
- return true;
- };
- CircleUtils.containsPoint = /**
- * Return true if the coordinates of the given Point object are within this Circle object.
- * If you need details about the intersection then use Phaser.Intersect.circleContainsPoint instead.
- * @method containsPoint
- * @param {Circle} a - The Circle object.
- * @param {Point} The Point object to test.
- * @return {Boolean} True if the coordinates are within this circle, otherwise false.
- **/
- function containsPoint(a, point) {
- return CircleUtils.contains(a, point.x, point.y);
- };
- CircleUtils.containsCircle = /**
- * Return true if the given Circle is contained entirely within this Circle object.
- * If you need details about the intersection then use Phaser.Intersect.circleToCircle instead.
- * @method containsCircle
- * @param {Circle} The Circle object to test.
- * @return {Boolean} True if the coordinates are within this circle, otherwise false.
- **/
- function containsCircle(a, b) {
- //return ((a.radius + b.radius) * (a.radius + b.radius)) >= Collision.distanceSquared(a.x, a.y, b.x, b.y);
- return true;
- };
- CircleUtils.distanceBetween = /**
- * Returns the distance from the center of the Circle object to the given object (can be Circle, Point or anything with x/y properties)
- * @method distanceBetween
- * @param {Circle} a - The Circle object.
- * @param {Circle} b - The target object. Must have visible x and y properties that represent the center of the object.
- * @param {Boolean} [optional] round - Round the distance to the nearest integer (default false)
- * @return {Number} The distance between this Point object and the destination Point object.
- **/
- function distanceBetween(a, target, round) {
- if (typeof round === "undefined") { round = false; }
- var dx = a.x - target.x;
- var dy = a.y - target.y;
- if(round === true) {
- return Math.round(Math.sqrt(dx * dx + dy * dy));
- } else {
- return Math.sqrt(dx * dx + dy * dy);
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Physics - Fixture
+ */
+ (function (Physics) {
+ var Fixture = (function () {
+ function Fixture(parent, type) {
+ this.parent = parent;
+ // these are shape properties really
+ this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce);
+ this.friction = Phaser.Vec2Utils.clone(this.game.world.physics.friction);
}
- };
- CircleUtils.equals = /**
- * Determines whether the two Circle objects match. This method compares the x, y and diameter properties.
- * @method equals
- * @param {Circle} a - The first Circle object.
- * @param {Circle} b - The second Circle object.
- * @return {Boolean} A value of true if the object has exactly the same values for the x, y and diameter properties as this Circle object; otherwise false.
- **/
- function equals(a, b) {
- return (a.x == b.x && a.y == b.y && a.diameter == b.diameter);
- };
- CircleUtils.intersects = /**
- * Determines whether the two Circle objects intersect.
- * This method checks the radius distances between the two Circle objects to see if they intersect.
- * @method intersects
- * @param {Circle} a - The first Circle object.
- * @param {Circle} b - The second Circle object.
- * @return {Boolean} A value of true if the specified object intersects with this Circle object; otherwise false.
- **/
- function intersects(a, b) {
- return (CircleUtils.distanceBetween(a, b) <= (a.radius + b.radius));
- };
- CircleUtils.circumferencePoint = /**
- * Returns a Point object containing the coordinates of a point on the circumference of the Circle based on the given angle.
- * @method circumferencePoint
- * @param {Circle} a - The first Circle object.
- * @param {Number} angle The angle in radians (unless asDegrees is true) to return the point from.
- * @param {Boolean} asDegrees Is the given angle in radians (false) or degrees (true)?
- * @param {Phaser.Point} [optional] output An optional Point object to put the result in to. If none specified a new Point object will be created.
- * @return {Phaser.Point} The Point object holding the result.
- **/
- function circumferencePoint(a, angle, asDegrees, out) {
- if (typeof asDegrees === "undefined") { asDegrees = false; }
- if (typeof out === "undefined") { out = new Phaser.Point(); }
- if(asDegrees === true) {
- angle = angle * Phaser.GameMath.DEG_TO_RAD;
- }
- return out.setTo(a.x + a.radius * Math.cos(angle), a.y + a.radius * Math.sin(angle));
- };
- return CircleUtils;
- })();
- Phaser.CircleUtils = CircleUtils;
-})(Phaser || (Phaser = {}));
-///
-///
-/**
-* Phaser - LinkedList
-*
-* A miniature linked list class. Useful for optimizing time-critical or highly repetitive tasks!
-*/
-var Phaser;
-(function (Phaser) {
- var LinkedList = (function () {
- /**
- * Creates a new link, and sets object and next to null.
- */
- function LinkedList() {
- this.object = null;
- this.next = null;
- }
- LinkedList.prototype.destroy = /**
- * Clean up memory.
- */
- function () {
- this.object = null;
- if(this.next != null) {
- this.next.destroy();
- }
- this.next = null;
- };
- return LinkedList;
- })();
- Phaser.LinkedList = LinkedList;
+ return Fixture;
+ })();
+ Physics.Fixture = Fixture;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
})(Phaser || (Phaser = {}));
///
///
@@ -13323,6 +13551,37 @@ var Phaser;
Phaser.QuadTree = QuadTree;
})(Phaser || (Phaser = {}));
///
+///
+/**
+* Phaser - LinkedList
+*
+* A miniature linked list class. Useful for optimizing time-critical or highly repetitive tasks!
+*/
+var Phaser;
+(function (Phaser) {
+ var LinkedList = (function () {
+ /**
+ * Creates a new link, and sets object and next to null.
+ */
+ function LinkedList() {
+ this.object = null;
+ this.next = null;
+ }
+ LinkedList.prototype.destroy = /**
+ * Clean up memory.
+ */
+ function () {
+ this.object = null;
+ if(this.next != null) {
+ this.next.destroy();
+ }
+ this.next = null;
+ };
+ return LinkedList;
+ })();
+ Phaser.LinkedList = LinkedList;
+})(Phaser || (Phaser = {}));
+///
/**
* Phaser - Line
*