diff --git a/Phaser/Game.ts b/Phaser/Game.ts
index 49e96bc9..469069f5 100644
--- a/Phaser/Game.ts
+++ b/Phaser/Game.ts
@@ -82,18 +82,6 @@ module Phaser {
*/
public _raf: RequestAnimationFrame;
- /**
- * Max allowable accumulation.
- * @type {number}
- */
- private _maxAccumulation: number = 32;
-
- /**
- * Total number of milliseconds elapsed since last update loop.
- * @type {number}
- */
- private _accumulator: number = 0;
-
/**
* Milliseconds of time per step of the game loop.
* @type {number}
@@ -231,6 +219,12 @@ module Phaser {
*/
public world: World;
+ /**
+ * Reference to the physics manager.
+ * @type {Physics.Manager}
+ */
+ public physics: Physics.Manager;
+
/**
* Instance of repeatable random data generator helper.
* @type {RandomDataGenerator}
@@ -293,6 +287,7 @@ module Phaser {
this.tweens = new TweenManager(this);
this.input = new Input(this);
this.rnd = new RandomDataGenerator([(Date.now() * Math.random()).toString()]);
+ this.physics = new Physics.Manager(this);
this.setRenderer(Phaser.Types.RENDERER_CANVAS);
@@ -300,12 +295,12 @@ module Phaser {
this.stage.boot();
this.input.boot();
- this.framerate = 60;
this.isBooted = true;
// Set-up some static helper references
DebugUtils.game = this;
ColorUtils.game = this;
+ DebugUtils.context = this.stage.context;
// Display the default game screen?
if (this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null)
@@ -396,20 +391,8 @@ module Phaser {
this.tweens.update();
this.input.update();
this.stage.update();
-
- this._accumulator += this.time.delta;
-
- if (this._accumulator > this._maxAccumulation)
- {
- this._accumulator = this._maxAccumulation;
- }
-
- while (this._accumulator >= this._step)
- {
- this.time.elapsed = this.time.timeScale * (this._step / 1000);
- this.world.update();
- this._accumulator = this._accumulator - this._step;
- }
+ this.physics.update();
+ this.world.update();
if (this._loadComplete && this.onUpdateCallback)
{
@@ -624,21 +607,6 @@ module Phaser {
}
- public get framerate(): number {
- return 1000 / this._step;
- }
-
- public set framerate(value: number) {
-
- this._step = 1000 / value;
-
- if (this._maxAccumulation < this._step)
- {
- this._maxAccumulation = this._step;
- }
-
- }
-
/**
* 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.
@@ -650,7 +618,8 @@ module Phaser {
* @returns {boolean} true if the objects overlap, otherwise false.
*/
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);
+ //return this.world.physics.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.world.physics.separate, context);
+ return false;
}
public get camera(): Camera {
diff --git a/Phaser/Motion.ts b/Phaser/Motion.ts
index 16e4a040..a469c4a7 100644
--- a/Phaser/Motion.ts
+++ b/Phaser/Motion.ts
@@ -52,6 +52,7 @@ module Phaser {
* @param {number} maxTime Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the source will arrive at destination in the given number of ms
*/
public moveTowardsObject(source: Sprite, dest: Sprite, speed: number = 60, maxTime: number = 0) {
+
var a: number = this.angleBetween(source, dest);
if (maxTime > 0)
@@ -79,6 +80,8 @@ module Phaser {
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
public accelerateTowardsObject(source: Sprite, dest: Sprite, speed: number, xSpeedMax: number, ySpeedMax: number) {
+
+ /*
var a: number = this.angleBetween(source, dest);
source.body.velocity.x = 0;
@@ -89,6 +92,7 @@ module Phaser {
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
+ */
}
@@ -103,6 +107,7 @@ module Phaser {
* @param {number} maxTime Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the source will arrive at destination in the given number of ms
*/
public moveTowardsMouse(source: Sprite, speed: number = 60, maxTime: number = 0) {
+
var a: number = this.angleBetweenMouse(source);
if (maxTime > 0)
@@ -129,6 +134,8 @@ module Phaser {
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
public accelerateTowardsMouse(source: Sprite, speed: number, xSpeedMax: number, ySpeedMax: number) {
+
+ /*
var a: number = this.angleBetweenMouse(source);
source.body.velocity.x = 0;
@@ -139,6 +146,8 @@ module Phaser {
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
+ */
+
}
/**
@@ -153,6 +162,7 @@ module Phaser {
* @param {number} maxTime Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the source will arrive at destination in the given number of ms
*/
public moveTowardsPoint(source: Sprite, target: Point, speed: number = 60, maxTime: number = 0) {
+
var a: number = this.angleBetweenPoint(source, target);
if (maxTime > 0)
@@ -179,6 +189,8 @@ module Phaser {
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
public accelerateTowardsPoint(source: Sprite, target: Point, speed: number, xSpeedMax: number, ySpeedMax: number) {
+
+ /*
var a: number = this.angleBetweenPoint(source, target);
source.body.velocity.x = 0;
@@ -189,6 +201,8 @@ module Phaser {
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
+ */
+
}
/**
@@ -240,6 +254,7 @@ module Phaser {
* @return {number} The angle (in radians unless asDegrees is true)
*/
public angleBetweenPoint(a: Sprite, target: Point, asDegrees: bool = false): number {
+
var dx: number = (target.x) - (a.x + a.transform.origin.x);
var dy: number = (target.y) - (a.y + a.transform.origin.y);
@@ -251,6 +266,7 @@ module Phaser {
{
return Math.atan2(dy, dx);
}
+
}
/**
@@ -287,6 +303,8 @@ module Phaser {
* @return {Point} An Point where Point.x contains the velocity x value and Point.y contains the velocity y value
*/
public velocityFromFacing(parent: Sprite, speed: number): Point {
+
+ /*
var a: number;
if (parent.body.facing == Types.LEFT)
@@ -307,6 +325,9 @@ module Phaser {
}
return new Point(Math.cos(a) * speed, Math.sin(a) * speed);
+ */
+
+ return new Point;
}
diff --git a/Phaser/Phaser.csproj b/Phaser/Phaser.csproj
index 0873a13b..9776fa7a 100644
--- a/Phaser/Phaser.csproj
+++ b/Phaser/Phaser.csproj
@@ -56,9 +56,7 @@
../build/phaser.js
true
-
-
-
+
AnimationManager.ts
@@ -143,7 +141,6 @@
-
@@ -177,83 +174,72 @@
Motion.ts
-
-
-
- Body.ts
-
-
-
- Bounds.ts
-
-
-
-
- Collision.ts
-
-
- Contact.ts
-
-
-
- ContactSolver.ts
-
-
-
-
- IJoint.ts
-
-
-
- Joint.ts
-
-
- Manager.ts
-
-
-
-
-
-
- Plane.ts
-
-
- Box.ts
-
-
-
- Circle.ts
-
-
- IShape.ts
-
-
-
- Poly.ts
-
-
-
- Segment.ts
-
-
- Shape.ts
-
-
-
- Triangle.ts
-
-
-
- Space.ts
-
-
- ArcadePhysics.ts
-
Body.ts
-
- PhysicsManager.ts
+
+
+ Bounds.ts
+
+
+
+ Collision.ts
+
+
+
+ Contact.ts
+
+
+
+ ContactSolver.ts
+
+
+
+
+ IJoint.ts
+
+
+
+ Joint.ts
+
+
+ Manager.ts
+
+
+
+ Plane.ts
+
+
+
+
+ Box.ts
+
+
+
+ Circle.ts
+
+
+
+ IShape.ts
+
+
+
+ Poly.ts
+
+
+
+ Segment.ts
+
+
+
+ Shape.ts
+
+
+
+ Triangle.ts
+
+
+ Space.ts
HeadlessRenderer.ts
diff --git a/Phaser/World.ts b/Phaser/World.ts
index cbabd992..3d04e365 100644
--- a/Phaser/World.ts
+++ b/Phaser/World.ts
@@ -2,7 +2,7 @@
///
///
///
-///
+///
/**
* Phaser - World
@@ -59,10 +59,10 @@ module Phaser {
public bounds: Rectangle;
/**
- * Reference to the physics manager.
- * @type {Physics.PhysicsManager}
+ * The Gravity of the World (defaults to 0,0, or no gravity at all)
+ * @type {Vec2}
*/
- public physics: Physics.PhysicsManager;
+ public gravity: Phaser.Vec2;
/**
* Object container stores every object created with `create*` methods.
@@ -81,8 +81,6 @@ module Phaser {
this.group = new Group(this._game, 0);
- this.physics = new Physics.PhysicsManager(this._game, this.width, this.height);
-
}
/**
@@ -90,7 +88,6 @@ module Phaser {
*/
public update() {
- //this.physics.update();
this.group.update();
this.cameras.update();
@@ -101,7 +98,6 @@ module Phaser {
*/
public postUpdate() {
- //this.physics.postUpdate();
this.group.postUpdate();
this.cameras.postUpdate();
@@ -112,7 +108,6 @@ module Phaser {
*/
public destroy() {
- //this.physics.destroy();
this.group.destroy();
this.cameras.destroy();
@@ -125,7 +120,7 @@ module Phaser {
* @param height {number} New height of the world.
* @param [updateCameraBounds] {boolean} Update camera bounds automatically or not. Default to true.
*/
- public setSize(width: number, height: number, updateCameraBounds: bool = true, updatePhysicsBounds: bool = true) {
+ public setSize(width: number, height: number, updateCameraBounds: bool = true) {
this.bounds.width = width;
this.bounds.height = height;
@@ -135,11 +130,6 @@ module Phaser {
this._game.camera.setBounds(0, 0, width, height);
}
- if (updatePhysicsBounds == true)
- {
- //this.physics.bounds.copyFrom(this.bounds);
- }
-
// dispatch world resize event
}
diff --git a/Phaser/components/TilemapLayer.ts b/Phaser/components/TilemapLayer.ts
index b26b26bf..21360b63 100644
--- a/Phaser/components/TilemapLayer.ts
+++ b/Phaser/components/TilemapLayer.ts
@@ -375,8 +375,7 @@ module Phaser {
this._tempBlockResults = [];
this.getTempBlock(this._tempTileX, this._tempTileY, this._tempTileW, this._tempTileH, true);
- Phaser.Physics.PhysicsManager.TILE_OVERLAP = false;
-
+ /*
for (var r = 0; r < this._tempTileBlock.length; r++)
{
if (this._game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true)
@@ -384,6 +383,7 @@ module Phaser {
this._tempBlockResults.push({ x: this._tempTileBlock[r].x, y: this._tempTileBlock[r].y, tile: this._tempTileBlock[r].tile });
}
}
+ */
return this._tempBlockResults;
diff --git a/Phaser/components/Transform.ts b/Phaser/components/Transform.ts
index 1112529a..47e51866 100644
--- a/Phaser/components/Transform.ts
+++ b/Phaser/components/Transform.ts
@@ -183,7 +183,7 @@ module Phaser.Components {
dirty = true;
}
- // If it has moved, updated the edges and center
+ // If it has moved, update the edges and center
if (dirty || this.parent.x != this._pos.x || this.parent.y != this._pos.y)
{
this.center.x = this.parent.x + this._distance * this._scA.y;
diff --git a/Phaser/gameobjects/Emitter.ts b/Phaser/gameobjects/Emitter.ts
index 661a38bd..4ed7b653 100644
--- a/Phaser/gameobjects/Emitter.ts
+++ b/Phaser/gameobjects/Emitter.ts
@@ -238,19 +238,19 @@ module Phaser {
if (collide > 0)
{
- particle.body.allowCollisions = Types.ANY;
+ //particle.body.allowCollisions = Types.ANY;
particle.body.type = Types.BODY_DYNAMIC;
particle.width *= collide;
particle.height *= collide;
}
else
{
- particle.body.allowCollisions = Types.NONE;
+ //particle.body.allowCollisions = Types.NONE;
}
particle.exists = false;
// Center the origin for rotation assistance
- particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
+ //particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
this.add(particle);
@@ -363,7 +363,7 @@ module Phaser {
var particle: Particle = this.recycle(Particle);
particle.lifespan = this.lifespan;
- particle.body.bounce.setTo(this.bounce, this.bounce);
+ //particle.body.bounce.setTo(this.bounce, this.bounce);
SpriteUtils.reset(particle, this.x - (particle.width >> 1) + this.game.math.random() * this.width, this.y - (particle.height >> 1) + this.game.math.random() * this.height);
particle.visible = true;
@@ -385,7 +385,7 @@ module Phaser {
particle.body.velocity.y = this.minParticleSpeed.y;
}
- particle.body.acceleration.y = this.gravity;
+ //particle.body.acceleration.y = this.gravity;
if (this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0)
{
@@ -401,8 +401,8 @@ module Phaser {
particle.rotation = this.game.math.random() * 360 - 180;
}
- particle.body.drag.x = this.particleDrag.x;
- particle.body.drag.y = this.particleDrag.y;
+ //particle.body.drag.x = this.particleDrag.x;
+ //particle.body.drag.y = this.particleDrag.y;
particle.onEmit();
}
@@ -457,8 +457,8 @@ module Phaser {
* @param Object {object} The Object that you want to sync up with.
*/
public at(object: Sprite) {
- this.x = object.body.bounds.halfWidth - (this.width >> 1);
- this.y = object.body.bounds.halfHeight - (this.height >> 1);
+ //this.x = object.body.bounds.halfWidth - (this.width >> 1);
+ //this.y = object.body.bounds.halfHeight - (this.height >> 1);
}
}
diff --git a/Phaser/gameobjects/GameObjectFactory.ts b/Phaser/gameobjects/GameObjectFactory.ts
index d74ac54c..47bc8f2b 100644
--- a/Phaser/gameobjects/GameObjectFactory.ts
+++ b/Phaser/gameobjects/GameObjectFactory.ts
@@ -72,10 +72,24 @@ module Phaser {
* @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 = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DYNAMIC): Sprite {
+ public sprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DISABLED): Sprite {
return this._world.group.add(new Sprite(this._game, x, y, key, frame, bodyType));
}
+ /**
+ * Create a new Sprite with the physics automatically created and set to DYNAMIC. The Sprite position offset is set to its center.
+ *
+ * @param x {number} X position of the new sprite.
+ * @param y {number} Y position of the new sprite.
+ * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite
+ * @param [frame] {string|number} If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name.
+ * @param [shapeType] The default body shape is either 0 for a Box or 1 for a Circle. See Sprite.body.addShape for custom shapes (polygons, etc)
+ * @returns {Sprite} The newly created sprite object.
+ */
+ public physicsSprite(x: number, y: number, key?: string = '', frame? = null, shapeType?:number = 0): Sprite {
+ return this._world.group.add(new Sprite(this._game, x, y, key, frame, Phaser.Types.BODY_DYNAMIC, shapeType));
+ }
+
/**
* Create a new DynamicTexture with specific size.
*
diff --git a/Phaser/gameobjects/Particle.ts b/Phaser/gameobjects/Particle.ts
index ffbc074d..1bae82e5 100644
--- a/Phaser/gameobjects/Particle.ts
+++ b/Phaser/gameobjects/Particle.ts
@@ -22,7 +22,6 @@ module Phaser {
this.body.type = Types.BODY_DYNAMIC;
this.lifespan = 0;
- this.friction = 500;
}
@@ -34,15 +33,7 @@ module Phaser {
public lifespan: number;
/**
- * Determines how quickly the particles come to rest on the ground.
- * Only used if the particle has gravity-like acceleration applied.
- * @default 500
- */
- public friction: number;
-
- /**
- * The particle's main update logic. Basically it checks to see if it should
- * be dead yet, and then has some special bounce behavior if there is some gravity on it.
+ * The particle's main update logic. Basically it checks to see if it should be dead yet.
*/
public update() {
@@ -59,42 +50,6 @@ module Phaser {
this.kill();
}
- //simpler bounce/spin behavior for now
- if (this.body.touching)
- {
- if (this.body.angularVelocity != 0)
- {
- this.body.angularVelocity = -this.body.angularVelocity;
- }
- }
-
- if (this.body.acceleration.y > 0) //special behavior for particles with gravity
- {
- if (this.body.touching & Types.FLOOR)
- {
- this.body.drag.x = this.friction;
-
- if (!(this.body.wasTouching & Types.FLOOR))
- {
- if (this.body.velocity.y < -this.body.bounce.y * 10)
- {
- if (this.body.angularVelocity != 0)
- {
- this.body.angularVelocity *= -this.body.bounce.y;
- }
- }
- else
- {
- this.body.velocity.y = 0;
- this.body.angularVelocity = 0;
- }
- }
- }
- else
- {
- this.body.drag.x = 0;
- }
- }
}
/**
diff --git a/Phaser/gameobjects/Sprite.ts b/Phaser/gameobjects/Sprite.ts
index 488bf62f..524c4009 100644
--- a/Phaser/gameobjects/Sprite.ts
+++ b/Phaser/gameobjects/Sprite.ts
@@ -23,9 +23,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 [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC)
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
+ * @param [shapeType] {number} The physics shape the body will consist of (either Box (0) or Circle (1), for custom types see body.addShape)
*/
- constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, frame? = null, bodyType?: number = Phaser.Types.BODY_DYNAMIC) {
+ constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, frame? = null, bodyType?: number = Phaser.Types.BODY_DISABLED, shapeType?:number = 0) {
this.game = game;
this.type = Phaser.Types.SPRITE;
@@ -67,7 +68,13 @@ module Phaser {
}
}
- this.body = new Phaser.Physics.Body(this, bodyType);
+ if (bodyType !== Phaser.Types.BODY_DISABLED)
+ {
+ this.body = new Phaser.Physics.Body(this, bodyType, 0, 0, shapeType);
+ this.game.physics.addBody(this.body);
+ this.transform.origin.setTo(0.5, 0.5);
+ }
+
this.worldView = new Rectangle(x, y, this.width, this.height);
this.cameraView = new Rectangle(x, y, this.width, this.height);
@@ -118,7 +125,7 @@ module Phaser {
/**
* Sprite physics body.
*/
- public body: Phaser.Physics.Body;
+ public body: Phaser.Physics.Body = null;
/**
* The texture used to render the Sprite.
@@ -268,8 +275,6 @@ module Phaser {
this.worldView.x = (this.x * this.transform.scrollFactor.x) - (this.width * this.transform.origin.x);
this.worldView.y = (this.y * this.transform.scrollFactor.y) - (this.height * this.transform.origin.y);
- //this.worldView.x = this.x * this.transform.scrollFactor.x;
- //this.worldView.y = this.y * this.transform.scrollFactor.y;
this.worldView.width = this.width;
this.worldView.height = this.height;
@@ -281,7 +286,7 @@ module Phaser {
}
/**
- * Override this function to update your class's position and appearance.
+ * Override this function to update your sprites position and appearance.
*/
public update() {
}
@@ -292,7 +297,6 @@ module Phaser {
public postUpdate() {
this.animations.update();
- this.body.postUpdate();
/*
if (this.worldBounds != null)
diff --git a/Phaser/math/QuadTree.ts b/Phaser/math/QuadTree.ts
index 738ab331..03a44fc8 100644
--- a/Phaser/math/QuadTree.ts
+++ b/Phaser/math/QuadTree.ts
@@ -23,7 +23,7 @@ module Phaser {
* @param {Number} height Desired height of this node.
* @param {Number} parent The parent branch or node. Pass null to create a root.
*/
- constructor(manager: Phaser.Physics.PhysicsManager, x: number, y: number, width: number, height: number, parent: QuadTree = null) {
+ constructor(manager: Phaser.Physics.Manager, x: number, y: number, width: number, height: number, parent: QuadTree = null) {
super(x, y, width, height);
@@ -104,7 +104,7 @@ module Phaser {
private _overlapProcessed: bool;
private _checkObject;
- public static physics: Phaser.Physics.PhysicsManager;
+ public static physics: Phaser.Physics.Manager;
/**
* Flag for specifying that you want to add an object to the A list.
@@ -625,7 +625,7 @@ module Phaser {
continue;
}
- //if (QuadTree._object.body.bounds.checkHullIntersection(this._checkObject.body.bounds))
+ /*
if (QuadTree.physics.checkHullIntersection(QuadTree._object.body, this._checkObject.body))
{
//Execute callback functions if they exist
@@ -646,6 +646,7 @@ module Phaser {
}
}
}
+ */
QuadTree._iterator = QuadTree._iterator.next;
diff --git a/Phaser/physics/ArcadePhysics.ts b/Phaser/physics/ArcadePhysics.ts
deleted file mode 100644
index 00ae9b18..00000000
--- a/Phaser/physics/ArcadePhysics.ts
+++ /dev/null
@@ -1,1121 +0,0 @@
-///
-///
-///
-///
-///
-
-/**
-* 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.
-*/
-
-
-module Phaser.Physics {
-
- export class ArcadePhysics {
-
- constructor(game: Game, width: number, height: number) {
-
- this.game = game;
-
- this.gravity = new Vec2;
- this.drag = new Vec2;
- this.bounce = new Vec2;
- this.angularDrag = 0;
-
- this.bounds = new Rectangle(0, 0, width, height);
-
- this._distance = new Vec2;
- this._tangent = new Vec2;
-
- this.members = new Group(game);
-
- }
-
- /**
- * Local private reference to Game.
- */
- public game: Game;
-
- /**
- * Physics object pool
- */
- public members: Group;
-
- // Temp calculation vars
- private _drag: number;
- private _delta: number;
- private _velocityDelta: number;
- 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 angularDrag: number;
-
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static OVERLAP_BIAS: number = 4;
-
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static TILE_OVERLAP: bool = false;
-
- /**
- * @type {number}
- */
- public worldDivisions: number = 6;
-
-
- /*
- 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);
- }
- }
-
- }
-*/
-
- public updateMotion(body: Phaser.Physics.Body) {
-
- if (body.type == Types.BODY_DISABLED)
- {
- return;
- }
-
- this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
- body.angularVelocity += this._velocityDelta;
- body.sprite.transform.rotation += 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;
- body.sprite.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;
- body.sprite.y += this._delta;
-
- }
-
- /**
- * 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.
- */
- public computeVelocity(velocity: number, gravity: number = 0, acceleration: number = 0, drag: number = 0, max: number = 10000): number {
-
- 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;
-
- }
-
- /**
- * 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 separate(body1: Body, body2: Body): bool {
-
- this._separatedX = this.separateBodyX(body1, body2);
- this._separatedY = this.separateBodyY(body1, body2);
-
- return this._separatedX || this._separatedY;
-
- }
-
- public checkHullIntersection(body1: Body, body2:Body): bool {
- return ((body1.hullX + body1.hullWidth > body2.hullX) && (body1.hullX < body2.hullX + body2.hullWidth) && (body1.hullY + body1.hullHeight > body2.hullY) && (body1.hullY < body2.hullY + body2.hullHeight));
- }
-
- /**
- * 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.
- */
- public separateBodyX(body1: Body, body2: Body): bool {
-
- // 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
- this._overlap = 0;
-
- if (body1.deltaX != body2.deltaX)
- {
- if (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 & Types.RIGHT) || !(body2.allowCollisions & Types.LEFT))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.RIGHT;
- body2.touching |= 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 & Types.LEFT) || !(body2.allowCollisions & Types.RIGHT))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.LEFT;
- body2.touching |= 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 == Types.BODY_DYNAMIC && body2.type == 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 != 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 != 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;
- }
-
- }
-
- /**
- * 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.
- */
- public separateBodyY(body1: Body, body2: Body): bool {
-
- // Can't separate two immovable 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
- this._overlap = 0;
-
- if (body1.deltaY != body2.deltaY)
- {
- if (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 & Types.DOWN) || !(body2.allowCollisions & Types.UP))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.DOWN;
- body2.touching |= 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 & Types.UP) || !(body2.allowCollisions & Types.DOWN))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.UP;
- body2.touching |= 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 == Types.BODY_DYNAMIC && body2.type == 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: 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 (body2.type != 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.sprite.active && (body1.deltaY > body2.deltaY))
- {
- body1.position.x += body2.position.x - body2.oldPosition.x;
- }
- }
- else if (body1.type != 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.sprite.active && (body1.deltaY < body2.deltaY))
- {
- body2.position.x += body1.position.x - body1.oldPosition.x;
- }
- }
-
- return true;
- }
- else
- {
- return false;
- }
- }
-
-
-
-
-
-
-
- /*
- private TILEseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 = 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('------------------------------------------------');
-
- }
-
- private collideWorld(shape:IPhysicsShape) {
-
- // 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);
- }
- }
-
- }
-
- private separateX(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateY(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateXWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateYWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
- */
-
- /**
- * 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 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 = null, object2 = null, notifyCallback = null, processCallback = null, context = null): bool {
-
- /*
- if (object1 == null)
- {
- object1 = this.game.world.group;
- }
-
- if (object2 == object1)
- {
- object2 = null;
- }
-
- QuadTree.divisions = this.worldDivisions;
-
- this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
-
- this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
-
- this._quadTreeResult = this._quadTree.execute();
-
- console.log('over', this._quadTreeResult);
-
- this._quadTree.destroy();
-
- this._quadTree = null;
-
- return this._quadTreeResult;
- */
-
- return false;
-
- }
-
-
-
-
-
-
- /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- public separateTile(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, collideUp: bool, collideDown: bool, separateX: bool, separateY: bool): bool {
-
- //var separatedX: bool = this.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
- //var separatedY: bool = this.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
-
- //return separatedX || separatedY;
-
- return false;
-
- }
-
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public separateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
- var objDelta: number = object.x - object.last.x;
- //var objDelta: number = object.collisionMask.deltaX;
-
- if (objDelta != 0)
- {
- // Check if the X hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objDeltaAbs: number = object.collisionMask.deltaXAbs;
- var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.x + object.width - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- //console.log('
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
-
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public separateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- var objDelta: number = object.y - object.last.y;
-
- if (objDelta != 0)
- {
- // Check if the Y hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.y + object.height - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
-
-
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public static NEWseparateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
-
- if (object.collisionMask.deltaX != 0)
- {
- // Check if the X hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- var maxOverlap: number = object.collisionMask.deltaXAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaX > 0)
- {
- //overlap = object.x + object.width - x;
- overlap = object.collisionMask.right - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (object.collisionMask.deltaX < 0)
- {
- //overlap = object.x - width - x;
- overlap = object.collisionMask.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
-
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public NEWseparateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- //var objDelta: number = object.y - object.last.y;
-
- if (object.collisionMask.deltaY != 0)
- {
- // Check if the Y hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- //var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object.collisionMask.deltaYAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaY > 0)
- {
- //overlap = object.y + object.height - y;
- overlap = object.collisionMask.bottom - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (object.collisionMask.deltaY < 0)
- {
- //overlap = object.y - height - y;
- overlap = object.collisionMask.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
-
- }
-
-}
\ No newline at end of file
diff --git a/Phaser/physics/Body.ts b/Phaser/physics/Body.ts
index a4b7a9f8..aa9c82d1 100644
--- a/Phaser/physics/Body.ts
+++ b/Phaser/physics/Body.ts
@@ -1,52 +1,93 @@
///
///
///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
/**
-* Phaser - Physics - Body
+* Phaser - Advanced Physics - Body
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics {
export class Body {
- constructor(sprite: Phaser.Sprite, type: number) {
+ constructor(sprite: Phaser.Sprite, type: number, x?: number = 0, y?: number = 0, shapeType?: number = 0) {
- this.sprite = sprite;
- this.game = sprite.game;
+ this.id = Phaser.Physics.Manager.bodyCounter++;
+ this.name = 'body' + this.id;
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;
-
- this._width = sprite.width;
- this._height = sprite.height;
-
-
- // Body properties
- this.gravity = Vec2Utils.clone(this.game.world.physics.gravity);
- this.bounce = Vec2Utils.clone(this.game.world.physics.bounce);
-
- this.velocity = new Vec2;
- this.acceleration = new Vec2;
- this.drag = Vec2Utils.clone(this.game.world.physics.drag);
- this.maxVelocity = new Vec2(10000, 10000);
+ if (sprite)
+ {
+ this.sprite = sprite;
+ this.game = sprite.game;
+ this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Manager.pixelsToMeters(sprite.y));
+ this.angle = sprite.rotation;
+ }
+ else
+ {
+ this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(x), Phaser.Physics.Manager.pixelsToMeters(y));
+ this.angle = 0;
+ }
+ this.transform = new Phaser.Transform(this.position, this.angle);
+ this.centroid = new Phaser.Vec2;
+ this.velocity = new Phaser.Vec2;
+ this.force = new Phaser.Vec2;
this.angularVelocity = 0;
- this.angularAcceleration = 0;
- this.angularDrag = 0;
+ this.torque = 0;
+ this.linearDamping = 0;
+ this.angularDamping = 0;
+ this.sleepTime = 0;
+ this.awaked = false;
- this.touching = Types.NONE;
- this.wasTouching = Types.NONE;
- this.allowCollisions = Types.ANY;
+ this.shapes = [];
+ this.joints = [];
+ this.jointHash = {};
- this.position = new Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight);
- this.oldPosition = new Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight);
- this.offset = new Vec2;
+ this.bounds = new Bounds;
+
+ this.allowCollisions = Phaser.Types.ANY;
+ this.fixedRotation = false;
+
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+
+ this.stepCount = 0;
+
+ if (sprite)
+ {
+ if (shapeType == 0)
+ {
+ this.addBox(0, 0, this.sprite.width, this.sprite.height, 1, 1, 1);
+ }
+ else
+ {
+ this.addCircle(Math.max(this.sprite.width, this.sprite.height) / 2, 0, 0, 1, 1, 1);
+ }
+ }
}
+ public toString(): string {
+ return "[{Body (name=" + this.name + " velocity=" + this.velocity.toString() + " angularVelocity: " + this.angularVelocity + ")}]";
+ }
+
+ private _tempVec2: Phaser.Vec2 = new Phaser.Vec2;
+
/**
* Reference to Phaser.Game
*/
@@ -57,6 +98,16 @@ module Phaser.Physics {
*/
public sprite: Phaser.Sprite;
+ /**
+ * The Body ID
+ */
+ public id: number;
+
+ /**
+ * The Body name
+ */
+ public name: string;
+
/**
* The type of Body (disabled, dynamic, static or kinematic)
* Disabled = skips all physics operations / tests (default)
@@ -67,243 +118,586 @@ module Phaser.Physics {
*/
public type: number;
- public gravity: Vec2;
- public bounce: Vec2;
+ public angle: number;
- public velocity: Vec2;
- public acceleration: Vec2;
- public drag: Vec2;
- public maxVelocity: Vec2;
+ // Local to world transform
+ public transform: Phaser.Transform;
- public angularVelocity: number = 0;
- public angularAcceleration: number = 0;
- public angularDrag: number = 0;
- public maxAngular: number = 10000;
+ // Local center of mass
+ public centroid: Phaser.Vec2;
- /**
- * Orientation of the object.
- * @type {number}
- */
- public facing: number;
+ // World position of centroid
+ public position: Phaser.Vec2;
- public touching: number;
+ // Velocity
+ public velocity: Phaser.Vec2;
+
+ // Force
+ public force: Phaser.Vec2;
+
+ // Angular velocity
+ public angularVelocity: number;
+
+ // Torque
+ public torque: number;
+
+ // Linear damping
+ public linearDamping: number;
+
+ // Angular damping
+ public angularDamping: number;
+
+ // Sleep time
+ public sleepTime: number;
+
+ // Awaked
+ public awaked: bool;
+
+ // Allow Collisions
public allowCollisions: number;
- public wasTouching: number;
- public mass: number = 1;
- public position: Vec2;
- public oldPosition: Vec2;
- public offset: Vec2;
- public bounds: Rectangle;
+ // Shapes
+ public shapes: IShape[] = [];
+ // Length of the shapes array
+ public shapesLength: number;
+ // Joints
+ public joints: IJoint[] = [];
+ public jointHash = {};
- private _width: number = 0;
- private _height: number = 0;
+ // Bounds of all shapes
+ public bounds: Bounds;
- public get x(): number {
- return this.sprite.x + this.offset.x;
- }
+ public mass: number;
+ public massInverted: number;
+ public inertia: number;
+ public inertiaInverted: number;
- public get y(): number {
- return this.sprite.y + this.offset.y;
- }
+ public fixedRotation = false;
+ public categoryBits = 0x0001;
+ public maskBits = 0xFFFF;
+ public stepCount = 0;
+ public space: Space;
- public set width(value: number) {
- this._width = value;
- }
+ public duplicate() {
- public set height(value: number) {
- this._height = value;
- }
+ console.log('body duplicate called');
- public get width(): number {
- return this._width * this.sprite.transform.scale.x;
- }
+ //var body = new Body(this.type, this.transform.t, this.angle);
+
+ //for (var i = 0; i < this.shapes.length; i++)
+ //{
+ // body.addShape(this.shapes[i].duplicate());
+ //}
- public get height(): number {
- return this._height * this.sprite.transform.scale.y;
- }
+ //body.resetMassData();
- public preUpdate() {
+ //return body;
- this.oldPosition.copyFrom(this.position);
+ }
- this.bounds.x = this.x;
- this.bounds.y = this.y;
- this.bounds.width = this.width;
- this.bounds.height = this.height;
+ public get isDisabled(): bool {
+ return this.type == Phaser.Types.BODY_DISABLED ? true : false;
+ }
- }
+ public get isStatic(): bool {
+ return this.type == Phaser.Types.BODY_STATIC ? true : 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() {
+ public get isKinetic(): bool {
+ return this.type == Phaser.Types.BODY_KINETIC ? true : false;
+ }
- // if this is all it does maybe move elsewhere? Sprite postUpdate?
- if (this.type !== Phaser.Types.BODY_DISABLED)
+ public get isDynamic(): bool {
+ return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
+ }
+
+ public setType(type: number) {
+
+ if (type == this.type)
+ {
+ return;
+ }
+
+ this.force.setTo(0, 0);
+ this.velocity.setTo(0, 0);
+ this.torque = 0;
+ this.angularVelocity = 0;
+ this.type = type;
+
+ this.awake(true);
+
+ }
+
+ public addPoly(verts, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Shapes.Poly {
+
+ var poly: Phaser.Physics.Shapes.Poly = new Phaser.Physics.Shapes.Poly(verts);
+ poly.elasticity = elasticity;
+ poly.friction = friction;
+ poly.density = density;
+
+ this.addShape(poly);
+ this.resetMassData();
+
+ return poly;
+
+ }
+
+ public addTriangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Shapes.Triangle {
+
+ var tri: Phaser.Physics.Shapes.Triangle = new Phaser.Physics.Shapes.Triangle(x1, y1, x2, y2, x3, y3);
+ tri.elasticity = elasticity;
+ tri.friction = friction;
+ tri.density = density;
+
+ this.addShape(tri);
+ this.resetMassData();
+
+ return tri;
+
+ }
+
+ public addBox(x: number, y: number, width: number, height: number, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Shapes.Box {
+
+ var box: Phaser.Physics.Shapes.Box = new Phaser.Physics.Shapes.Box(x, y, width, height);
+ box.elasticity = elasticity;
+ box.friction = friction;
+ box.density = density;
+
+ this.addShape(box);
+ this.resetMassData();
+
+ return box;
+
+ }
+
+ public addCircle(radius: number, x?: number = 0, y?: number = 0, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Shapes.Circle {
+
+ var circle: Phaser.Physics.Shapes.Circle = new Phaser.Physics.Shapes.Circle(radius, x, y);
+ circle.elasticity = elasticity;
+ circle.friction = friction;
+ circle.density = density;
+
+ this.addShape(circle);
+ this.resetMassData();
+
+ return circle;
+
+ }
+
+ public addShape(shape) {
+
+ // Check not already part of this body
+ shape.body = this;
+
+ this.shapes.push(shape);
+
+ this.shapesLength = this.shapes.length;
+
+ return shape;
+
+ }
+
+ public removeShape(shape) {
+
+ var index = this.shapes.indexOf(shape);
+
+ if (index != -1)
+ {
+ this.shapes.splice(index, 1);
+ shape.body = undefined;
+ }
+
+ this.shapesLength = this.shapes.length;
+
+ }
+
+ private setMass(mass) {
+
+ this.mass = mass;
+ this.massInverted = mass > 0 ? 1 / mass : 0;
+
+ }
+
+ private setInertia(inertia) {
+
+ this.inertia = inertia;
+ this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
+
+ }
+
+ public setTransform(pos, angle) {
+
+ // inject the transform into this.position
+ this.transform.setTo(pos, angle);
+ Manager.write('setTransform: ' + this.position.toString());
+ Manager.write('centroid: ' + this.centroid.toString());
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ Manager.write('post setTransform: ' + this.position.toString());
+ //this.position.copyFrom(this.transform.transform(this.centroid));
+ this.angle = angle;
+
+ }
+
+ public syncTransform() {
+
+ Manager.write('syncTransform:');
+ Manager.write('p: ' + this.position.toString());
+ Manager.write('centroid: ' + this.centroid.toString());
+ Manager.write('xf: ' + this.transform.toString());
+ Manager.write('a: ' + this.angle);
+ this.transform.setRotation(this.angle);
+ // OPTIMISE: Creating new vector
+ Phaser.Vec2Utils.subtract(this.position, Phaser.TransformUtils.rotate(this.transform, this.centroid), this.transform.t);
+ Manager.write('--------------------');
+ Manager.write('xf: ' + this.transform.toString());
+ Manager.write('--------------------');
+
+ }
+
+ public getWorldPoint(p:Phaser.Vec2) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.transform(this.transform, p);
+ }
+
+ public getWorldVector(v:Phaser.Vec2) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.rotate(this.transform, v);
+ }
+
+ public getLocalPoint(p:Phaser.Vec2) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.untransform(this.transform, p);
+ }
+
+ public getLocalVector(v:Phaser.Vec2) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.unrotate(this.transform, v);
+ }
+
+ public setFixedRotation(flag) {
+ this.fixedRotation = flag;
+ this.resetMassData();
+ }
+
+ public resetMassData() {
+
+ this.centroid.setTo(0, 0);
+ this.mass = 0;
+ this.massInverted = 0;
+ this.inertia = 0;
+ this.inertiaInverted = 0;
+
+ if (this.isDynamic == false)
+ {
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ //this.position.copyFrom(this.transform.transform(this.centroid));
+ return;
+ }
+
+ var totalMassCentroid = new Phaser.Vec2(0, 0);
+ var totalMass = 0;
+ var totalInertia = 0;
+
+ for (var i = 0; i < this.shapes.length; i++)
+ {
+ var shape = this.shapes[i];
+ var centroid = shape.centroid();
+ var mass = shape.area() * shape.density;
+ var inertia = shape.inertia(mass);
+
+ //console.log('rmd', centroid, shape);
+
+ totalMassCentroid.multiplyAddByScalar(centroid, mass);
+ totalMass += mass;
+ totalInertia += inertia;
+ }
+
+ //this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
+ Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
+
+ this.setMass(totalMass);
+
+ if (!this.fixedRotation)
+ {
+ this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
+ }
+
+ // Move center of mass
+ var oldPosition: Phaser.Vec2 = Phaser.Vec2Utils.clone(this.position);
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+
+ // Update center of mass velocity
+ oldPosition.subtract(this.position);
+ this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
+
+ }
+
+ public resetJointAnchors() {
+
+ for (var i = 0; i < this.joints.length; i++)
+ {
+ var joint = this.joints[i];
+
+ if (!joint)
+ {
+ continue;
+ }
+
+ var anchor1 = joint.getWorldAnchor1();
+ var anchor2 = joint.getWorldAnchor2();
+
+ joint.setWorldAnchor1(anchor1);
+ joint.setWorldAnchor2(anchor2);
+ }
+ }
+
+ public cacheData(source:string = '') {
+
+ Manager.write('cacheData -- start');
+ Manager.write('p: ' + this.position.toString());
+ Manager.write('xf: ' + this.transform.toString());
+
+ this.bounds.clear();
+
+ for (var i = 0; i < this.shapes.length; i++)
+ {
+ var shape: IShape = this.shapes[i];
+ shape.cacheData(this.transform);
+ this.bounds.addBounds(shape.bounds);
+ }
+
+ Manager.write('bounds: ' + this.bounds.toString());
+
+ Manager.write('p: ' + this.position.toString());
+ Manager.write('xf: ' + this.transform.toString());
+ Manager.write('cacheData -- stop');
+
+ }
+
+ public updateVelocity(gravity, dt, damping) {
+
+ Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
+ Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
+
+ this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
+
+ // Apply damping.
+ // ODE: dv/dt + c * v = 0
+ // Solution: v(t) = v0 * exp(-c * t)
+ // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
+ // v2 = exp(-c * dt) * v1
+ // Taylor expansion:
+ // v2 = (1.0f - c * dt) * v1
+ this.velocity.scale(this.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
+ this.angularVelocity *= this.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
+
+ this.force.setTo(0, 0);
+ this.torque = 0;
+
+ }
+
+ public inContact(body2: Body): bool {
+
+ if (!body2 || this.stepCount == body2.stepCount)
+ {
+ return false;
+ }
+
+ if (!(this.isAwake && this.isStatic == false) && !(body2.isAwake && body2.isStatic == false))
+ {
+ return false;
+ }
+
+ if (this.isCollidable(body2) == false)
+ {
+ return false;
+ }
+
+ if (!this.bounds.intersectsBounds(body2.bounds))
{
- this.game.world.physics.updateMotion(this);
-
- this.wasTouching = this.touching;
- this.touching = Phaser.Types.NONE;
-
+ return false;
}
- this.position.setTo(this.x, this.y);
+ return true;
+ }
+
+ public clamp(v, min, max) {
+ return v < min ? min : (v > max ? max : v);
}
- public get hullWidth(): number {
+ public updatePosition(dt:number) {
- if (this.deltaX > 0)
- {
- return this.bounds.width + this.deltaX;
- }
- else
- {
- return this.bounds.width - this.deltaX;
- }
+ this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
- }
+ this.angle += this.angularVelocity * dt;
- public get hullHeight(): number {
+ if (this.sprite)
+ {
+ this.sprite.x = this.position.x * 50;
+ this.sprite.y = this.position.y * 50;
+ // Obey fixed rotation?
+ this.sprite.rotation = this.game.math.radiansToDegrees(this.angle);
+ }
- if (this.deltaY > 0)
- {
- return this.bounds.height + this.deltaY;
- }
- else
- {
- return this.bounds.height - this.deltaY;
- }
+ }
- }
+ public resetForce() {
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ }
- public get hullX(): number {
+ public applyForce(force:Phaser.Vec2, p:Phaser.Vec2) {
- if (this.position.x < this.oldPosition.x)
- {
- return this.position.x;
- }
- else
- {
- return this.oldPosition.x;
- }
+ if (this.isDynamic == false)
+ {
+ return;
+ }
- }
+ if (this.isAwake == false)
+ {
+ this.awake(true);
+ }
- public get hullY(): number {
+ this.force.add(force);
- if (this.position.y < this.oldPosition.y)
- {
- return this.position.y;
- }
- else
- {
- return this.oldPosition.y;
- }
+ Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
- }
+ this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
- 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 applyForceToCenter(force:Phaser.Vec2) {
- public get deltaX(): number {
- return this.position.x - this.oldPosition.x;
- }
+ if (this.isDynamic == false)
+ {
+ return;
+ }
- public get deltaY(): number {
- return this.position.y - this.oldPosition.y;
- }
+ if (this.isAwake == false)
+ {
+ this.awake(true);
+ }
+ this.force.add(force);
+ }
+ public applyTorque(torque:number) {
+ if (this.isDynamic == false)
+ {
+ return;
+ }
+ if (this.isAwake == false)
+ {
+ this.awake(true);
+ }
+ this.torque += torque;
+ }
+ public applyLinearImpulse(impulse:Phaser.Vec2, p:Phaser.Vec2) {
+ if (this.isDynamic == false)
+ {
+ return;
+ }
- // MOVE THESE TO A UTIL
+ if (this.isAwake == false)
+ {
+ this.awake(true);
+ }
- public render(context:CanvasRenderingContext2D) {
+ this.velocity.multiplyAddByScalar(impulse, this.massInverted);
- 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();
+ Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
- // center point
- context.fillStyle = 'rgb(0,255,0)';
- context.fillRect(this.position.x, this.position.y, 2, 2);
+ this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
- 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();
- }
+ public applyAngularImpulse(impulse: number) {
- }
+ if (this.isDynamic == false)
+ {
+ return;
+ }
+ if (this.isAwake == false)
+ {
+ this.awake(true);
+ }
- /**
- * 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.angularVelocity += impulse * this.inertiaInverted;
- this.sprite.texture.context.fillStyle = color;
- this.sprite.texture.context.fillText('Sprite: (' + this.sprite.width + ' x ' + this.sprite.height + ')', x, y);
- //this.sprite.texture.context.fillText('x: ' + this._sprite.frameBounds.x.toFixed(1) + ' y: ' + this._sprite.frameBounds.y.toFixed(1) + ' rotation: ' + this._sprite.rotation.toFixed(1), x, y + 14);
- this.sprite.texture.context.fillText('x: ' + this.bounds.x.toFixed(1) + ' y: ' + this.bounds.y.toFixed(1) + ' rotation: ' + this.sprite.transform.rotation.toFixed(0), x, y + 14);
- this.sprite.texture.context.fillText('vx: ' + this.velocity.x.toFixed(1) + ' vy: ' + this.velocity.y.toFixed(1), x, y + 28);
- this.sprite.texture.context.fillText('acx: ' + this.acceleration.x.toFixed(1) + ' acy: ' + this.acceleration.y.toFixed(1), x, y + 42);
- this.sprite.texture.context.fillText('angVx: ' + this.angularVelocity.toFixed(1) + ' angAc: ' + this.angularAcceleration.toFixed(1), x, y + 56);
+ }
- }
+ public kineticEnergy() {
+ var vsq = this.velocity.dot(this.velocity);
+ var wsq = this.angularVelocity * this.angularVelocity;
+
+ return 0.5 * (this.mass * vsq + this.inertia * wsq);
+
+ }
+
+ public get isAwake(): bool {
+ return this.awaked;
+ }
+
+ public awake(flag) {
+
+ this.awaked = flag;
+
+ if (flag)
+ {
+ this.sleepTime = 0;
+ }
+ else
+ {
+ this.velocity.setTo(0, 0);
+ this.angularVelocity = 0;
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ }
+
+ }
+
+ public isCollidable(other:Body) {
+
+ if (this == other)
+ {
+ return false;
+ }
+
+ if (this.isDynamic == false && other.isDynamic == false)
+ {
+ return false;
+ }
+
+ if (!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits))
+ {
+ return false;
+ }
+
+ for (var i = 0; i < this.joints.length; i++)
+ {
+ var joint = this.joints[i];
+
+ if (!this.joints[i] || (!this.joints[i].collideConnected && other.jointHash[this.joints[i].id] != undefined))
+ {
+ return false;
+ }
+ }
+
+ return true;
+
+ }
}
diff --git a/Phaser/physics/advanced/Bounds.ts b/Phaser/physics/Bounds.ts
similarity index 86%
rename from Phaser/physics/advanced/Bounds.ts
rename to Phaser/physics/Bounds.ts
index b5eb34f8..7e054a07 100644
--- a/Phaser/physics/advanced/Bounds.ts
+++ b/Phaser/physics/Bounds.ts
@@ -1,6 +1,6 @@
-///
-///
-///
+///
+///
+///
/**
* Phaser - 2D AABB
@@ -8,7 +8,7 @@
* A 2D AABB object
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Bounds {
@@ -72,19 +72,27 @@ module Phaser.Physics.Advanced {
}
public get x(): number {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.mins.x);
+ return Phaser.Physics.Manager.metersToPixels(this.mins.x);
}
public get y(): number {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.mins.y);
+ return Phaser.Physics.Manager.metersToPixels(this.mins.y);
}
public get width(): number {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.maxs.x - this.mins.x);
+ return Phaser.Physics.Manager.metersToPixels(this.maxs.x - this.mins.x);
}
public get height(): number {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.maxs.y - this.mins.y);
+ return Phaser.Physics.Manager.metersToPixels(this.maxs.y - this.mins.y);
+ }
+
+ public get right(): number {
+ return this.x + this.width;
+ }
+
+ public get bottom(): number {
+ return this.y + this.height;
}
public isEmpty(): bool {
@@ -125,11 +133,13 @@ module Phaser.Physics.Advanced {
return this;
}
- public addBounds2(mins, maxs) {
+ public addBounds2(mins, maxs): Bounds {
+
if (this.mins.x > mins.x) this.mins.x = mins.x;
if (this.maxs.x < maxs.x) this.maxs.x = maxs.x;
if (this.mins.y > mins.y) this.mins.y = mins.y;
if (this.maxs.y < maxs.y) this.maxs.y = maxs.y;
+
return this;
}
diff --git a/Phaser/physics/advanced/Collision.ts b/Phaser/physics/Collision.ts
similarity index 91%
rename from Phaser/physics/advanced/Collision.ts
rename to Phaser/physics/Collision.ts
index 465a1658..8d749a06 100644
--- a/Phaser/physics/advanced/Collision.ts
+++ b/Phaser/physics/Collision.ts
@@ -1,6 +1,6 @@
-///
-///
-///
+///
+///
+///
///
///
///
@@ -15,13 +15,10 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Collision {
- constructor() {
- }
-
public collide(a, b, contacts: Contact[]) {
// Circle (a is the circle)
@@ -114,11 +111,11 @@ module Phaser.Physics.Advanced {
}
- public circle2Circle(circ1: Phaser.Physics.Advanced.Shapes.Circle, circ2: Phaser.Physics.Advanced.Shapes.Circle, contactArr: Contact[]) {
+ public circle2Circle(circ1: Phaser.Physics.Shapes.Circle, circ2: Phaser.Physics.Shapes.Circle, contactArr: Contact[]) {
return this._circle2Circle(circ1.tc, circ1.radius, circ2.tc, circ2.radius, contactArr);
}
- public circle2Segment(circ: Phaser.Physics.Advanced.Shapes.Circle, seg: Phaser.Physics.Advanced.Shapes.Segment, contactArr: Contact[]) {
+ public circle2Segment(circ: Phaser.Physics.Shapes.Circle, seg: Phaser.Physics.Shapes.Segment, contactArr: Contact[]) {
var rsum = circ.radius + seg.radius;
@@ -179,7 +176,7 @@ module Phaser.Physics.Advanced {
}
- public circle2Poly(circ: Phaser.Physics.Advanced.Shapes.Circle, poly: Phaser.Physics.Advanced.Shapes.Poly, contactArr: Contact[]) {
+ public circle2Poly(circ: Phaser.Physics.Shapes.Circle, poly: Phaser.Physics.Shapes.Poly, contactArr: Contact[]) {
var minDist = -999999;
var minIdx = -1;
@@ -230,7 +227,7 @@ module Phaser.Physics.Advanced {
}
- public segmentPointDistanceSq(seg: Phaser.Physics.Advanced.Shapes.Segment, p) {
+ public segmentPointDistanceSq(seg: Phaser.Physics.Shapes.Segment, p) {
var w: Phaser.Vec2 = new Phaser.Vec2;
var d: Phaser.Vec2 = new Phaser.Vec2;
@@ -259,7 +256,7 @@ module Phaser.Physics.Advanced {
}
// FIXME and optimise me lots!!!
- public segment2Segment(seg1: Phaser.Physics.Advanced.Shapes.Segment, seg2: Phaser.Physics.Advanced.Shapes.Segment, contactArr: Contact[]) {
+ public segment2Segment(seg1: Phaser.Physics.Shapes.Segment, seg2: Phaser.Physics.Shapes.Segment, contactArr: Contact[]) {
var d = [];
d[0] = this.segmentPointDistanceSq(seg1, seg2.ta);
@@ -307,7 +304,7 @@ module Phaser.Physics.Advanced {
}
// Identify vertexes that have penetrated the segment.
- public findPointsBehindSeg(contactArr: Contact[], seg: Phaser.Physics.Advanced.Shapes.Segment, poly: Phaser.Physics.Advanced.Shapes.Poly, dist: number, coef: number) {
+ public findPointsBehindSeg(contactArr: Contact[], seg: Phaser.Physics.Shapes.Segment, poly: Phaser.Physics.Shapes.Poly, dist: number, coef: number) {
var dta = Phaser.Vec2Utils.cross(seg.tn, seg.ta);
var dtb = Phaser.Vec2Utils.cross(seg.tn, seg.tb);
@@ -332,7 +329,7 @@ module Phaser.Physics.Advanced {
}
}
- public segment2Poly(seg: Phaser.Physics.Advanced.Shapes.Segment, poly: Phaser.Physics.Advanced.Shapes.Poly, contactArr: Contact[]) {
+ public segment2Poly(seg: Phaser.Physics.Shapes.Segment, poly: Phaser.Physics.Shapes.Poly, contactArr: Contact[]) {
var seg_td = Phaser.Vec2Utils.dot(seg.tn, seg.ta);
var seg_d1 = poly.distanceOnPlane(seg.tn, seg_td) - seg.radius;
@@ -442,7 +439,7 @@ module Phaser.Physics.Advanced {
}
// Find the minimum separating axis for the given poly and plane list.
- public findMSA(poly: Phaser.Physics.Advanced.Shapes.Poly, planes: Phaser.Physics.Advanced.Plane[], num: number) {
+ public findMSA(poly: Phaser.Physics.Shapes.Poly, planes: Phaser.Physics.Plane[], num: number) {
var min_dist: number = -999999;
var min_index: number = -1;
@@ -468,7 +465,7 @@ module Phaser.Physics.Advanced {
}
- public findVertsFallback(contactArr: Contact[], poly1: Phaser.Physics.Advanced.Shapes.Poly, poly2: Phaser.Physics.Advanced.Shapes.Poly, n, dist: number) {
+ public findVertsFallback(contactArr: Contact[], poly1: Phaser.Physics.Shapes.Poly, poly2: Phaser.Physics.Shapes.Poly, n, dist: number) {
var num = 0;
@@ -499,7 +496,7 @@ module Phaser.Physics.Advanced {
}
// Find the overlapped vertices.
- public findVerts(contactArr: Contact[], poly1: Phaser.Physics.Advanced.Shapes.Poly, poly2: Phaser.Physics.Advanced.Shapes.Poly, n, dist: number) {
+ public findVerts(contactArr: Contact[], poly1: Phaser.Physics.Shapes.Poly, poly2: Phaser.Physics.Shapes.Poly, n, dist: number) {
var num = 0;
@@ -529,7 +526,7 @@ module Phaser.Physics.Advanced {
}
- public poly2Poly(poly1: Phaser.Physics.Advanced.Shapes.Poly, poly2: Phaser.Physics.Advanced.Shapes.Poly, contactArr: Contact[]) {
+ public poly2Poly(poly1: Phaser.Physics.Shapes.Poly, poly2: Phaser.Physics.Shapes.Poly, contactArr: Contact[]) {
var msa1 = this.findMSA(poly2, poly1.tplanes, poly1.verts.length);
diff --git a/Phaser/physics/advanced/Contact.ts b/Phaser/physics/Contact.ts
similarity index 91%
rename from Phaser/physics/advanced/Contact.ts
rename to Phaser/physics/Contact.ts
index d927764b..1ae8f776 100644
--- a/Phaser/physics/advanced/Contact.ts
+++ b/Phaser/physics/Contact.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
///
@@ -10,7 +10,7 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Contact {
diff --git a/Phaser/physics/advanced/ContactSolver.ts b/Phaser/physics/ContactSolver.ts
similarity index 98%
rename from Phaser/physics/advanced/ContactSolver.ts
rename to Phaser/physics/ContactSolver.ts
index 3e5244c9..f43db61f 100644
--- a/Phaser/physics/advanced/ContactSolver.ts
+++ b/Phaser/physics/ContactSolver.ts
@@ -1,6 +1,6 @@
-///
-///
-///
+///
+///
+///
///
///
///
@@ -32,7 +32,7 @@
// NOTE: lambda is an impulse in constraint space.
//-------------------------------------------------------------------------------------------------
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class ContactSolver {
diff --git a/Phaser/physics/advanced/Manager.ts b/Phaser/physics/Manager.ts
similarity index 91%
rename from Phaser/physics/advanced/Manager.ts
rename to Phaser/physics/Manager.ts
index 7fa322d8..9b672efd 100644
--- a/Phaser/physics/advanced/Manager.ts
+++ b/Phaser/physics/Manager.ts
@@ -1,15 +1,15 @@
-///
+///
///
///
/**
-* Phaser - Advanced Physics Manager
+* Phaser - Physics Manager
*
-* 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.
+* The Physics Manager is responsible for looking after, creating and colliding
+* all of the physics bodies and joints in the world.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Manager {
@@ -17,7 +17,9 @@ module Phaser.Physics.Advanced {
this.game = game;
- this.space = new Space();
+ this.gravity = new Phaser.Vec2;
+
+ this.space = new Space(this);
Manager.collision = new Collision();
@@ -31,12 +33,12 @@ module Phaser.Physics.Advanced {
public static debug: HTMLTextAreaElement;
public static clear() {
- Manager.debug.textContent = "";
+ //Manager.debug.textContent = "";
Manager.log = [];
}
public static write(s: string) {
- Manager.debug.textContent += s + "\n";
+ //Manager.debug.textContent += s + "\n";
}
public static writeAll() {
@@ -52,6 +54,7 @@ module Phaser.Physics.Advanced {
public static dump(phase: string, body: Body) {
+ /*
var s = "\n\nPhase: " + phase + "\n";
s += "Position: " + body.position.toString() + "\n";
s += "Velocity: " + body.velocity.toString() + "\n";
@@ -78,6 +81,7 @@ module Phaser.Physics.Advanced {
s += "TPlane 3: " + body.shapes[0].tplanes[3].normal.toString() + "\n";
Manager.log.push(s);
+ */
}
@@ -98,9 +102,9 @@ module Phaser.Physics.Advanced {
public static JOINT_TYPE_MOUSE: number = 7;
public static JOINT_LINEAR_SLOP: number = 0.0008;
- public static JOINT_ANGULAR_SLOP: number = 2 * Phaser.GameMath.DEG_TO_RAD;
+ public static JOINT_ANGULAR_SLOP: number = 2 * 0.017453292519943294444444444444444;
public static JOINT_MAX_LINEAR_CORRECTION: number = 0.5;
- public static JOINT_MAX_ANGULAR_CORRECTION: number = 8 * Phaser.GameMath.DEG_TO_RAD;
+ public static JOINT_MAX_ANGULAR_CORRECTION: number = 8 * 0.017453292519943294444444444444444;
public static JOINT_LIMIT_STATE_INACTIVE: number = 0;
public static JOINT_LIMIT_STATE_AT_LOWER: number = 1;
@@ -119,19 +123,21 @@ module Phaser.Physics.Advanced {
public lastTime: number = Date.now();
public frameRateHz: number = 60;
public timeDelta: number = 0;
- //public paused: bool = false;
- //public step: bool = false; // step through the simulation (i.e. per click)
- public paused: bool = true;
+ public paused: bool = false;
public step: bool = false; // step through the simulation (i.e. per click)
+ //public paused: bool = true;
+ //public step: bool = false; // step through the simulation (i.e. per click)
public velocityIterations: number = 8;
public positionIterations: number = 4;
- //public velocityIterations: number = 1;
- //public positionIterations: number = 1;
public allowSleep: bool = true;
public warmStarting: bool = true;
+ public gravity: Phaser.Vec2;
+
+
public update() {
+ // Get these from Phaser.Time instead
var time = Date.now();
var frameTime = (time - this.lastTime) / 1000;
this.lastTime = time;
@@ -176,6 +182,22 @@ module Phaser.Physics.Advanced {
}
+ public addBody(body: Body) {
+ this.space.addBody(body);
+ }
+
+ public removeBody(body: Body) {
+ this.space.removeBody(body);
+ }
+
+ public addJoint(joint: IJoint) {
+ this.space.addJoint(joint);
+ }
+
+ public removeJoint(joint: IJoint) {
+ this.space.removeJoint(joint);
+ }
+
public pixelsToMeters(value: number): number {
return value * 0.02;
}
diff --git a/Phaser/physics/PhysicsManager.ts b/Phaser/physics/PhysicsManager.ts
deleted file mode 100644
index ab24ed07..00000000
--- a/Phaser/physics/PhysicsManager.ts
+++ /dev/null
@@ -1,1116 +0,0 @@
-///
-///
-///
-///
-///
-
-/**
-* 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.
-*/
-
-module Phaser.Physics {
-
- export class PhysicsManager {
-
- constructor(game: Game, width: number, height: number) {
-
- this.game = game;
-
- this.gravity = new Vec2;
- this.drag = new Vec2;
- this.bounce = new Vec2;
- this.angularDrag = 0;
-
- this.bounds = new Rectangle(0, 0, width, height);
-
- this._distance = new Vec2;
- this._tangent = new Vec2;
-
- this.members = new Group(game);
-
- }
-
- /**
- * Local private reference to Game.
- */
- public game: Game;
-
- /**
- * Physics object pool
- */
- public members: Group;
-
- // Temp calculation vars
- private _drag: number;
- private _delta: number;
- private _velocityDelta: number;
- 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 angularDrag: number;
-
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static OVERLAP_BIAS: number = 4;
-
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static TILE_OVERLAP: bool = false;
-
- /**
- * @type {number}
- */
- public worldDivisions: number = 6;
-
-
- /*
- 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);
- }
- }
-
- }
-*/
-
- public updateMotion(body: Phaser.Physics.Body) {
-
- if (body.type == Types.BODY_DISABLED)
- {
- return;
- }
-
- this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
- body.angularVelocity += this._velocityDelta;
- body.sprite.transform.rotation += 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;
- body.sprite.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;
- body.sprite.y += this._delta;
-
- }
-
- /**
- * 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.
- */
- public computeVelocity(velocity: number, gravity: number = 0, acceleration: number = 0, drag: number = 0, max: number = 10000): number {
-
- 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;
-
- }
-
- /**
- * 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 separate(body1: Body, body2: Body): bool {
-
- this._separatedX = this.separateBodyX(body1, body2);
- this._separatedY = this.separateBodyY(body1, body2);
-
- return this._separatedX || this._separatedY;
-
- }
-
- public checkHullIntersection(body1: Body, body2:Body): bool {
- return ((body1.hullX + body1.hullWidth > body2.hullX) && (body1.hullX < body2.hullX + body2.hullWidth) && (body1.hullY + body1.hullHeight > body2.hullY) && (body1.hullY < body2.hullY + body2.hullHeight));
- }
-
- /**
- * 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.
- */
- public separateBodyX(body1: Body, body2: Body): bool {
-
- // 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
- this._overlap = 0;
-
- if (body1.deltaX != body2.deltaX)
- {
- if (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 & Types.RIGHT) || !(body2.allowCollisions & Types.LEFT))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.RIGHT;
- body2.touching |= 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 & Types.LEFT) || !(body2.allowCollisions & Types.RIGHT))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.LEFT;
- body2.touching |= 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 == Types.BODY_DYNAMIC && body2.type == 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 != 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 != 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;
- }
-
- }
-
- /**
- * 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.
- */
- public separateBodyY(body1: Body, body2: Body): bool {
-
- // Can't separate two immovable 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
- this._overlap = 0;
-
- if (body1.deltaY != body2.deltaY)
- {
- if (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 & Types.DOWN) || !(body2.allowCollisions & Types.UP))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.DOWN;
- body2.touching |= 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 & Types.UP) || !(body2.allowCollisions & Types.DOWN))
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching |= Types.UP;
- body2.touching |= 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 == Types.BODY_DYNAMIC && body2.type == 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: 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 (body2.type != 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.sprite.active && (body1.deltaY > body2.deltaY))
- {
- body1.position.x += body2.position.x - body2.oldPosition.x;
- }
- }
- else if (body1.type != 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.sprite.active && (body1.deltaY < body2.deltaY))
- {
- body2.position.x += body1.position.x - body1.oldPosition.x;
- }
- }
-
- return true;
- }
- else
- {
- return false;
- }
- }
-
-
-
-
-
-
-
- /*
- private TILEseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 = 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('------------------------------------------------');
-
- }
-
- private collideWorld(shape:IPhysicsShape) {
-
- // 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);
- }
- }
-
- }
-
- private separateX(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateY(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateXWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateYWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
- */
-
- /**
- * 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 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 = null, object2 = null, notifyCallback = null, processCallback = null, context = null): bool {
-
- if (object1 == null)
- {
- object1 = this.game.world.group;
- }
-
- if (object2 == object1)
- {
- object2 = null;
- }
-
- QuadTree.divisions = this.worldDivisions;
-
- this._quadTree = new QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
-
- this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
-
- this._quadTreeResult = this._quadTree.execute();
-
- console.log('over', this._quadTreeResult);
-
- this._quadTree.destroy();
-
- this._quadTree = null;
-
- return this._quadTreeResult;
-
- }
-
-
-
-
-
-
- /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- public separateTile(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, collideUp: bool, collideDown: bool, separateX: bool, separateY: bool): bool {
-
- //var separatedX: bool = this.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
- //var separatedY: bool = this.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
-
- //return separatedX || separatedY;
-
- return false;
-
- }
-
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public separateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
- var objDelta: number = object.x - object.last.x;
- //var objDelta: number = object.collisionMask.deltaX;
-
- if (objDelta != 0)
- {
- // Check if the X hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objDeltaAbs: number = object.collisionMask.deltaXAbs;
- var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.x + object.width - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- //console.log('
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
-
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public separateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- var objDelta: number = object.y - object.last.y;
-
- if (objDelta != 0)
- {
- // Check if the Y hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.y + object.height - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
-
-
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public static NEWseparateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
-
- if (object.collisionMask.deltaX != 0)
- {
- // Check if the X hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- var maxOverlap: number = object.collisionMask.deltaXAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaX > 0)
- {
- //overlap = object.x + object.width - x;
- overlap = object.collisionMask.right - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (object.collisionMask.deltaX < 0)
- {
- //overlap = object.x - width - x;
- overlap = object.collisionMask.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
-
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public NEWseparateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- //var objDelta: number = object.y - object.last.y;
-
- if (object.collisionMask.deltaY != 0)
- {
- // Check if the Y hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- //var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object.collisionMask.deltaYAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaY > 0)
- {
- //overlap = object.y + object.height - y;
- overlap = object.collisionMask.bottom - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (object.collisionMask.deltaY < 0)
- {
- //overlap = object.y - height - y;
- overlap = object.collisionMask.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
-
- }
-
-}
\ No newline at end of file
diff --git a/Phaser/physics/advanced/Plane.ts b/Phaser/physics/Plane.ts
similarity index 75%
rename from Phaser/physics/advanced/Plane.ts
rename to Phaser/physics/Plane.ts
index 965c5600..3d15be03 100644
--- a/Phaser/physics/advanced/Plane.ts
+++ b/Phaser/physics/Plane.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
@@ -9,7 +9,7 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Plane {
diff --git a/Phaser/physics/advanced/Space.ts b/Phaser/physics/Space.ts
similarity index 98%
rename from Phaser/physics/advanced/Space.ts
rename to Phaser/physics/Space.ts
index 4eecf70e..f8e8d9bb 100644
--- a/Phaser/physics/advanced/Space.ts
+++ b/Phaser/physics/Space.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
///
@@ -14,11 +14,13 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Space {
- constructor() {
+ constructor(manager: Phaser.Physics.Manager) {
+
+ this._manager = manager;
this.bodies = [];
this.bodyHash = {};
@@ -29,7 +31,7 @@ module Phaser.Physics.Advanced {
this.numContacts = 0;
this.contactSolvers = [];
- this.gravity = new Phaser.Vec2(0, 10);
+ this.gravity = this._manager.gravity;
this.damping = 0;
this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE;
@@ -37,6 +39,8 @@ module Phaser.Physics.Advanced {
}
+ private _manager: Phaser.Physics.Manager;
+
// Delta Timer
private _delta: number;
private _deltaInv: number;
@@ -68,7 +72,7 @@ module Phaser.Physics.Advanced {
public static TIME_TO_SLEEP = 0.5;
public static SLEEP_LINEAR_TOLERANCE = 0.5;
- public static SLEEP_ANGULAR_TOLERANCE = 2 * Phaser.GameMath.DEG_TO_RAD;
+ public static SLEEP_ANGULAR_TOLERANCE = 2 * 0.017453292519943294444444444444444;
public bodies: Body[];
public joints: IJoint[];
diff --git a/Phaser/physics/advanced/Body.ts b/Phaser/physics/advanced/Body.ts
deleted file mode 100644
index 41bd828a..00000000
--- a/Phaser/physics/advanced/Body.ts
+++ /dev/null
@@ -1,680 +0,0 @@
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-
-/**
-* Phaser - Advanced Physics - Body
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-
-module Phaser.Physics.Advanced {
-
- export class Body {
-
- constructor(sprite: Phaser.Sprite, type: number, x?: number = 0, y?: number = 0) {
-
- this.id = Phaser.Physics.Advanced.Manager.bodyCounter++;
- this.name = 'body' + this.id;
- this.type = type;
-
- if (sprite)
- {
- this.sprite = sprite;
- this.game = sprite.game;
- this.position = new Phaser.Vec2(Phaser.Physics.Advanced.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Advanced.Manager.pixelsToMeters(sprite.y));
- this.angle = sprite.rotation;
- }
- else
- {
- this.position = new Phaser.Vec2(Phaser.Physics.Advanced.Manager.pixelsToMeters(x), Phaser.Physics.Advanced.Manager.pixelsToMeters(y));
- this.angle = 0;
- }
-
- this.transform = new Phaser.Transform(this.position, this.angle);
- this.centroid = new Phaser.Vec2;
- this.velocity = new Phaser.Vec2;
- this.force = new Phaser.Vec2;
- this.angularVelocity = 0;
- this.torque = 0;
- this.linearDamping = 0;
- this.angularDamping = 0;
- this.sleepTime = 0;
- this.awaked = false;
-
- this.shapes = [];
- this.joints = [];
- this.jointHash = {};
-
- this.bounds = new Bounds;
-
- this.fixedRotation = false;
-
- this.categoryBits = 0x0001;
- this.maskBits = 0xFFFF;
-
- this.stepCount = 0;
-
- }
-
- public toString(): string {
- return "[{Body (name=" + this.name + " velocity=" + this.velocity.toString() + " angularVelocity: " + this.angularVelocity + ")}]";
- }
-
- private _tempVec2: Phaser.Vec2 = new Phaser.Vec2;
-
- /**
- * Reference to Phaser.Game
- */
- public game: Game;
-
- /**
- * Reference to the parent Sprite
- */
- public sprite: Phaser.Sprite;
-
- /**
- * The Body ID
- */
- public id: number;
-
- /**
- * The Body name
- */
- public name: string;
-
- /**
- * 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 angle: number;
-
- // Local to world transform
- public transform: Phaser.Transform;
-
- // Local center of mass
- public centroid: Phaser.Vec2;
-
- // World position of centroid
- public position: Phaser.Vec2;
-
- // Velocity
- public velocity: Phaser.Vec2;
-
- // Force
- public force: Phaser.Vec2;
-
- // Angular velocity
- public angularVelocity: number;
-
- // Torque
- public torque: number;
-
- // Linear damping
- public linearDamping: number;
-
- // Angular damping
- public angularDamping: number;
-
- // Sleep time
- public sleepTime: number;
-
- // Awaked
- public awaked: bool;
-
- // Shapes
- public shapes: IShape[] = [];
-
- // Length of the shapes array
- public shapesLength: number;
-
- // Joints
- public joints: IJoint[] = [];
- public jointHash = {};
-
- // Bounds of all shapes
- public bounds: Bounds;
-
- public mass: number;
- public massInverted: number;
- public inertia: number;
- public inertiaInverted: number;
-
- public fixedRotation = false;
- public categoryBits = 0x0001;
- public maskBits = 0xFFFF;
- public stepCount = 0;
- public space: Space;
-
- public duplicate() {
-
- console.log('body duplicate called');
-
- //var body = new Body(this.type, this.transform.t, this.angle);
-
- //for (var i = 0; i < this.shapes.length; i++)
- //{
- // body.addShape(this.shapes[i].duplicate());
- //}
-
- //body.resetMassData();
-
- //return body;
-
- }
-
- public get isDisabled(): bool {
- return this.type == Phaser.Types.BODY_DISABLED ? true : false;
- }
-
- public get isStatic(): bool {
- return this.type == Phaser.Types.BODY_STATIC ? true : false;
- }
-
- public get isKinetic(): bool {
- return this.type == Phaser.Types.BODY_KINETIC ? true : false;
- }
-
- public get isDynamic(): bool {
- return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
- }
-
- public setType(type: number) {
-
- if (type == this.type)
- {
- return;
- }
-
- this.force.setTo(0, 0);
- this.velocity.setTo(0, 0);
- this.torque = 0;
- this.angularVelocity = 0;
- this.type = type;
-
- this.awake(true);
-
- }
-
- public addPoly(verts, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Advanced.Shapes.Poly {
-
- var poly: Phaser.Physics.Advanced.Shapes.Poly = new Phaser.Physics.Advanced.Shapes.Poly(verts);
- poly.elasticity = elasticity;
- poly.friction = friction;
- poly.density = density;
-
- this.addShape(poly);
- this.resetMassData();
-
- return poly;
-
- }
-
- public addTriangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Advanced.Shapes.Triangle {
-
- var tri: Phaser.Physics.Advanced.Shapes.Triangle = new Phaser.Physics.Advanced.Shapes.Triangle(x1, y1, x2, y2, x3, y3);
- tri.elasticity = elasticity;
- tri.friction = friction;
- tri.density = density;
-
- this.addShape(tri);
- this.resetMassData();
-
- return tri;
-
- }
-
- public addBox(x: number, y: number, width: number, height: number, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Advanced.Shapes.Box {
-
- var box: Phaser.Physics.Advanced.Shapes.Box = new Phaser.Physics.Advanced.Shapes.Box(x, y, width, height);
- box.elasticity = elasticity;
- box.friction = friction;
- box.density = density;
-
- this.addShape(box);
- this.resetMassData();
-
- return box;
-
- }
-
- public addCircle(radius: number, x?: number = 0, y?: number = 0, elasticity?: number = 1, friction?: number = 1, density?: number = 1): Phaser.Physics.Advanced.Shapes.Circle {
-
- var circle: Phaser.Physics.Advanced.Shapes.Circle = new Phaser.Physics.Advanced.Shapes.Circle(radius, x, y);
- circle.elasticity = elasticity;
- circle.friction = friction;
- circle.density = density;
-
- this.addShape(circle);
- this.resetMassData();
-
- return circle;
-
- }
-
- public addShape(shape) {
-
- // Check not already part of this body
- shape.body = this;
-
- this.shapes.push(shape);
-
- this.shapesLength = this.shapes.length;
-
- return shape;
-
- }
-
- public removeShape(shape) {
-
- var index = this.shapes.indexOf(shape);
-
- if (index != -1)
- {
- this.shapes.splice(index, 1);
- shape.body = undefined;
- }
-
- this.shapesLength = this.shapes.length;
-
- }
-
- private setMass(mass) {
-
- this.mass = mass;
- this.massInverted = mass > 0 ? 1 / mass : 0;
-
- }
-
- private setInertia(inertia) {
-
- this.inertia = inertia;
- this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
-
- }
-
- public setTransform(pos, angle) {
-
- // inject the transform into this.position
- this.transform.setTo(pos, angle);
- Manager.write('setTransform: ' + this.position.toString());
- Manager.write('centroid: ' + this.centroid.toString());
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- Manager.write('post setTransform: ' + this.position.toString());
- //this.position.copyFrom(this.transform.transform(this.centroid));
- this.angle = angle;
-
- }
-
- public syncTransform() {
-
- Manager.write('syncTransform:');
- Manager.write('p: ' + this.position.toString());
- Manager.write('centroid: ' + this.centroid.toString());
- Manager.write('xf: ' + this.transform.toString());
- Manager.write('a: ' + this.angle);
- this.transform.setRotation(this.angle);
- // OPTIMISE: Creating new vector
- Phaser.Vec2Utils.subtract(this.position, Phaser.TransformUtils.rotate(this.transform, this.centroid), this.transform.t);
- Manager.write('--------------------');
- Manager.write('xf: ' + this.transform.toString());
- Manager.write('--------------------');
-
- }
-
- public getWorldPoint(p:Phaser.Vec2) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.transform(this.transform, p);
- }
-
- public getWorldVector(v:Phaser.Vec2) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.rotate(this.transform, v);
- }
-
- public getLocalPoint(p:Phaser.Vec2) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.untransform(this.transform, p);
- }
-
- public getLocalVector(v:Phaser.Vec2) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.unrotate(this.transform, v);
- }
-
- public setFixedRotation(flag) {
- this.fixedRotation = flag;
- this.resetMassData();
- }
-
- public resetMassData() {
-
- this.centroid.setTo(0, 0);
- this.mass = 0;
- this.massInverted = 0;
- this.inertia = 0;
- this.inertiaInverted = 0;
-
- if (this.isDynamic == false)
- {
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- //this.position.copyFrom(this.transform.transform(this.centroid));
- return;
- }
-
- var totalMassCentroid = new Phaser.Vec2(0, 0);
- var totalMass = 0;
- var totalInertia = 0;
-
- for (var i = 0; i < this.shapes.length; i++)
- {
- var shape = this.shapes[i];
- var centroid = shape.centroid();
- var mass = shape.area() * shape.density;
- var inertia = shape.inertia(mass);
-
- //console.log('rmd', centroid, shape);
-
- totalMassCentroid.multiplyAddByScalar(centroid, mass);
- totalMass += mass;
- totalInertia += inertia;
- }
-
- //this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
- Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
-
- this.setMass(totalMass);
-
- if (!this.fixedRotation)
- {
- this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
- }
-
- // Move center of mass
- var oldPosition: Phaser.Vec2 = Phaser.Vec2Utils.clone(this.position);
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
-
- // Update center of mass velocity
- oldPosition.subtract(this.position);
- this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
-
- }
-
- public resetJointAnchors() {
-
- for (var i = 0; i < this.joints.length; i++)
- {
- var joint = this.joints[i];
-
- if (!joint)
- {
- continue;
- }
-
- var anchor1 = joint.getWorldAnchor1();
- var anchor2 = joint.getWorldAnchor2();
-
- joint.setWorldAnchor1(anchor1);
- joint.setWorldAnchor2(anchor2);
- }
- }
-
- public cacheData(source:string = '') {
-
- Manager.write('cacheData -- start');
- Manager.write('p: ' + this.position.toString());
- Manager.write('xf: ' + this.transform.toString());
-
- this.bounds.clear();
-
- for (var i = 0; i < this.shapes.length; i++)
- {
- var shape: IShape = this.shapes[i];
- shape.cacheData(this.transform);
- this.bounds.addBounds(shape.bounds);
- }
-
- Manager.write('bounds: ' + this.bounds.toString());
-
- Manager.write('p: ' + this.position.toString());
- Manager.write('xf: ' + this.transform.toString());
- Manager.write('cacheData -- stop');
-
- }
-
- public updateVelocity(gravity, dt, damping) {
-
- Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
- Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
-
- this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
-
- // Apply damping.
- // ODE: dv/dt + c * v = 0
- // Solution: v(t) = v0 * exp(-c * t)
- // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
- // v2 = exp(-c * dt) * v1
- // Taylor expansion:
- // v2 = (1.0f - c * dt) * v1
- this.velocity.scale(this.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
- this.angularVelocity *= this.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
-
- this.force.setTo(0, 0);
- this.torque = 0;
-
- }
-
- public inContact(body2: Body): bool {
-
- if (!body2 || this.stepCount == body2.stepCount)
- {
- return false;
- }
-
- if (!(this.isAwake && this.isStatic == false) && !(body2.isAwake && body2.isStatic == false))
- {
- return false;
- }
-
- if (this.isCollidable(body2) == false)
- {
- return false;
- }
-
- if (!this.bounds.intersectsBounds(body2.bounds))
- {
- return false;
- }
-
- return true;
-
- }
-
- public clamp(v, min, max) {
- return v < min ? min : (v > max ? max : v);
- }
-
- public updatePosition(dt:number) {
-
- this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
-
- this.angle += this.angularVelocity * dt;
-
- }
-
- public resetForce() {
- this.force.setTo(0, 0);
- this.torque = 0;
- }
-
- public applyForce(force:Phaser.Vec2, p:Phaser.Vec2) {
-
- if (this.isDynamic == false)
- {
- return;
- }
-
- if (this.isAwake == false)
- {
- this.awake(true);
- }
-
- this.force.add(force);
-
- Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
-
- this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
-
- }
-
- public applyForceToCenter(force:Phaser.Vec2) {
-
- if (this.isDynamic == false)
- {
- return;
- }
-
- if (this.isAwake == false)
- {
- this.awake(true);
- }
-
- this.force.add(force);
-
- }
-
- public applyTorque(torque:number) {
-
- if (this.isDynamic == false)
- {
- return;
- }
-
- if (this.isAwake == false)
- {
- this.awake(true);
- }
-
- this.torque += torque;
-
- }
-
- public applyLinearImpulse(impulse:Phaser.Vec2, p:Phaser.Vec2) {
-
- if (this.isDynamic == false)
- {
- return;
- }
-
- if (this.isAwake == false)
- {
- this.awake(true);
- }
-
- this.velocity.multiplyAddByScalar(impulse, this.massInverted);
-
- Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
-
- this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
-
- }
-
- public applyAngularImpulse(impulse: number) {
-
- if (this.isDynamic == false)
- {
- return;
- }
-
- if (this.isAwake == false)
- {
- this.awake(true);
- }
-
- this.angularVelocity += impulse * this.inertiaInverted;
-
- }
-
- public kineticEnergy() {
-
- var vsq = this.velocity.dot(this.velocity);
- var wsq = this.angularVelocity * this.angularVelocity;
-
- return 0.5 * (this.mass * vsq + this.inertia * wsq);
-
- }
-
- public get isAwake(): bool {
- return this.awaked;
- }
-
- public awake(flag) {
-
- this.awaked = flag;
-
- if (flag)
- {
- this.sleepTime = 0;
- }
- else
- {
- this.velocity.setTo(0, 0);
- this.angularVelocity = 0;
- this.force.setTo(0, 0);
- this.torque = 0;
- }
-
- }
-
- public isCollidable(other:Body) {
-
- if (this == other)
- {
- return false;
- }
-
- if (this.isDynamic == false && other.isDynamic == false)
- {
- return false;
- }
-
- if (!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits))
- {
- return false;
- }
-
- for (var i = 0; i < this.joints.length; i++)
- {
- var joint = this.joints[i];
-
- if (!this.joints[i] || (!this.joints[i].collideConnected && other.jointHash[this.joints[i].id] != undefined))
- {
- return false;
- }
- }
-
- return true;
-
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/Phaser/physics/advanced/joints/IJoint.ts b/Phaser/physics/joints/IJoint.ts
similarity index 71%
rename from Phaser/physics/advanced/joints/IJoint.ts
rename to Phaser/physics/joints/IJoint.ts
index 1f0f1fb9..fdeb393a 100644
--- a/Phaser/physics/advanced/joints/IJoint.ts
+++ b/Phaser/physics/joints/IJoint.ts
@@ -1,6 +1,6 @@
-///
-///
-///
+///
+///
+///
///
///
@@ -10,15 +10,15 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export interface IJoint {
id: number;
type: number;
- body1: Phaser.Physics.Advanced.Body;
- body2: Phaser.Physics.Advanced.Body;
+ body1: Phaser.Physics.Body;
+ body2: Phaser.Physics.Body;
collideConnected; // bool?
maxForce: number;
diff --git a/Phaser/physics/advanced/joints/Joint.ts b/Phaser/physics/joints/Joint.ts
similarity index 70%
rename from Phaser/physics/advanced/joints/Joint.ts
rename to Phaser/physics/joints/Joint.ts
index 6a64ae79..3f850959 100644
--- a/Phaser/physics/advanced/joints/Joint.ts
+++ b/Phaser/physics/joints/Joint.ts
@@ -1,6 +1,6 @@
-///
-///
-///
+///
+///
+///
///
///
@@ -10,13 +10,13 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Joint {
- constructor(type: number, body1:Phaser.Physics.Advanced.Body, body2:Phaser.Physics.Advanced.Body, collideConnected) {
+ constructor(type: number, body1:Phaser.Physics.Body, body2:Phaser.Physics.Body, collideConnected) {
- this.id = Phaser.Physics.Advanced.Manager.jointCounter++;
+ this.id = Phaser.Physics.Manager.jointCounter++;
this.type = type;
this.body1 = body1;
@@ -32,8 +32,8 @@ module Phaser.Physics.Advanced {
public id: number;
public type: number;
- public body1: Phaser.Physics.Advanced.Body;
- public body2: Phaser.Physics.Advanced.Body;
+ public body1: Phaser.Physics.Body;
+ public body2: Phaser.Physics.Body;
public collideConnected; // bool?
public maxForce: number;
diff --git a/Phaser/physics/advanced/shapes/Box.ts b/Phaser/physics/shapes/Box.ts
similarity index 63%
rename from Phaser/physics/advanced/shapes/Box.ts
rename to Phaser/physics/shapes/Box.ts
index c252a504..461faf86 100644
--- a/Phaser/physics/advanced/shapes/Box.ts
+++ b/Phaser/physics/shapes/Box.ts
@@ -1,4 +1,4 @@
-///
+///
///
///
///
@@ -10,17 +10,17 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced.Shapes {
+module Phaser.Physics.Shapes {
- export class Box extends Phaser.Physics.Advanced.Shapes.Poly {
+ export class Box extends Phaser.Physics.Shapes.Poly {
// Give in pixels
constructor(x, y, width, height) {
- //x = Manager.pixelsToMeters(x);
- //y = Manager.pixelsToMeters(y);
- //width = Manager.pixelsToMeters(width);
- //height = Manager.pixelsToMeters(height);
+ x = Manager.pixelsToMeters(x);
+ y = Manager.pixelsToMeters(y);
+ width = Manager.pixelsToMeters(width);
+ height = Manager.pixelsToMeters(height);
var hw = width * 0.5;
var hh = height * 0.5;
diff --git a/Phaser/physics/advanced/shapes/Circle.ts b/Phaser/physics/shapes/Circle.ts
similarity index 92%
rename from Phaser/physics/advanced/shapes/Circle.ts
rename to Phaser/physics/shapes/Circle.ts
index 0f12673b..23997aa5 100644
--- a/Phaser/physics/advanced/shapes/Circle.ts
+++ b/Phaser/physics/shapes/Circle.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
///
@@ -10,9 +10,9 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced.Shapes {
+module Phaser.Physics.Shapes {
- export class Circle extends Phaser.Physics.Advanced.Shape implements IShape {
+ export class Circle extends Phaser.Physics.Shape implements IShape {
constructor(radius: number, x?: number = 0, y?: number = 0) {
diff --git a/Phaser/physics/advanced/shapes/IShape.ts b/Phaser/physics/shapes/IShape.ts
similarity index 74%
rename from Phaser/physics/advanced/shapes/IShape.ts
rename to Phaser/physics/shapes/IShape.ts
index 8ef1dbb5..1e49f5a9 100644
--- a/Phaser/physics/advanced/shapes/IShape.ts
+++ b/Phaser/physics/shapes/IShape.ts
@@ -1,6 +1,6 @@
-///
-///
-///
+///
+///
+///
///
///
///
@@ -11,7 +11,7 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export interface IShape {
@@ -34,9 +34,9 @@ module Phaser.Physics.Advanced {
findVertexByPoint(p: Phaser.Vec2, minDist: number): number;
verts: Phaser.Vec2[];
- planes: Phaser.Physics.Advanced.Plane[];
+ planes: Phaser.Physics.Plane[];
tverts: Phaser.Vec2[];
- tplanes: Phaser.Physics.Advanced.Plane[];
+ tplanes: Phaser.Physics.Plane[];
convexity: bool;
}
diff --git a/Phaser/physics/advanced/shapes/Poly.ts b/Phaser/physics/shapes/Poly.ts
similarity index 93%
rename from Phaser/physics/advanced/shapes/Poly.ts
rename to Phaser/physics/shapes/Poly.ts
index 0a8e3f77..a11cdc6f 100644
--- a/Phaser/physics/advanced/shapes/Poly.ts
+++ b/Phaser/physics/shapes/Poly.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
///
@@ -11,9 +11,9 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced.Shapes {
+module Phaser.Physics.Shapes {
- export class Poly extends Phaser.Physics.Advanced.Shape implements IShape {
+ export class Poly extends Phaser.Physics.Shape implements IShape {
// Verts is an optional array of objects, the objects must have public x and y properties which will be used
// to seed this polygon (i.e. Vec2 objects, or just straight JS objects) and must wind COUNTER clockwise
@@ -33,7 +33,7 @@ module Phaser.Physics.Advanced.Shapes {
this.verts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
this.tverts[i] = this.verts[i];
//this.tverts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
- this.tplanes[i] = new Phaser.Physics.Advanced.Plane(new Phaser.Vec2, 0);
+ this.tplanes[i] = new Phaser.Physics.Plane(new Phaser.Vec2, 0);
}
}
@@ -62,12 +62,12 @@ module Phaser.Physics.Advanced.Shapes {
var b = this.verts[(i + 1) % this.verts.length];
var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
- this.planes[i] = new Phaser.Physics.Advanced.Plane(n, Phaser.Vec2Utils.dot(n, a));
+ this.planes[i] = new Phaser.Physics.Plane(n, Phaser.Vec2Utils.dot(n, a));
this.tverts[i] = Phaser.Vec2Utils.clone(this.verts[i]); // reference???
//this.tverts[i] = this.verts[i]; // reference???
- this.tplanes[i] = new Phaser.Physics.Advanced.Plane(new Phaser.Vec2, 0);
+ this.tplanes[i] = new Phaser.Physics.Plane(new Phaser.Vec2, 0);
}
for (var i = 0; i < this.verts.length; i++)
@@ -85,7 +85,7 @@ module Phaser.Physics.Advanced.Shapes {
}
public duplicate() {
- return new Phaser.Physics.Advanced.Shapes.Poly(this.verts);
+ return new Phaser.Physics.Shapes.Poly(this.verts);
}
public recenter(c) {
diff --git a/Phaser/physics/advanced/shapes/Segment.ts b/Phaser/physics/shapes/Segment.ts
similarity index 94%
rename from Phaser/physics/advanced/shapes/Segment.ts
rename to Phaser/physics/shapes/Segment.ts
index 51ebc470..b949206e 100644
--- a/Phaser/physics/advanced/shapes/Segment.ts
+++ b/Phaser/physics/shapes/Segment.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
///
@@ -10,9 +10,9 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced.Shapes {
+module Phaser.Physics.Shapes {
- export class Segment extends Phaser.Physics.Advanced.Shape implements IShape {
+ export class Segment extends Phaser.Physics.Shape implements IShape {
constructor(a, b, radius: number) {
@@ -52,7 +52,7 @@ module Phaser.Physics.Advanced.Shapes {
}
public duplicate() {
- return new Phaser.Physics.Advanced.Shapes.Segment(this.a, this.b, this.radius);
+ return new Phaser.Physics.Shapes.Segment(this.a, this.b, this.radius);
}
public recenter(c) {
diff --git a/Phaser/physics/advanced/shapes/Shape.ts b/Phaser/physics/shapes/Shape.ts
similarity index 77%
rename from Phaser/physics/advanced/shapes/Shape.ts
rename to Phaser/physics/shapes/Shape.ts
index c1d81c2c..ed206c8e 100644
--- a/Phaser/physics/advanced/shapes/Shape.ts
+++ b/Phaser/physics/shapes/Shape.ts
@@ -1,5 +1,5 @@
-///
-///
+///
+///
///
///
///
@@ -11,13 +11,13 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced {
+module Phaser.Physics {
export class Shape {
constructor(type: number) {
- this.id = Phaser.Physics.Advanced.Manager.shapeCounter++;
+ this.id = Phaser.Physics.Manager.shapeCounter++;
this.type = type;
this.elasticity = 0.0;
@@ -33,10 +33,10 @@ module Phaser.Physics.Advanced {
public body: Body;
public verts: Phaser.Vec2[];
- public planes: Phaser.Physics.Advanced.Plane[];
+ public planes: Phaser.Physics.Plane[];
public tverts: Phaser.Vec2[];
- public tplanes: Phaser.Physics.Advanced.Plane[];
+ public tplanes: Phaser.Physics.Plane[];
public convexity: bool;
diff --git a/Phaser/physics/advanced/shapes/Triangle.ts b/Phaser/physics/shapes/Triangle.ts
similarity index 81%
rename from Phaser/physics/advanced/shapes/Triangle.ts
rename to Phaser/physics/shapes/Triangle.ts
index 7b88e013..8d78647d 100644
--- a/Phaser/physics/advanced/shapes/Triangle.ts
+++ b/Phaser/physics/shapes/Triangle.ts
@@ -1,4 +1,4 @@
-///
+///
///
///
///
@@ -10,9 +10,9 @@
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
-module Phaser.Physics.Advanced.Shapes {
+module Phaser.Physics.Shapes {
- export class Triangle extends Phaser.Physics.Advanced.Shapes.Poly {
+ export class Triangle extends Phaser.Physics.Shapes.Poly {
constructor(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number) {
diff --git a/Phaser/utils/ColorUtils.ts b/Phaser/utils/ColorUtils.ts
index 9f26ca8e..9ca2aa8c 100644
--- a/Phaser/utils/ColorUtils.ts
+++ b/Phaser/utils/ColorUtils.ts
@@ -124,7 +124,7 @@ module Phaser {
if (threshold >= 359 || threshold <= 0)
{
- throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()");
+ throw Error("ColorUtils Warning: Invalid threshold given to getSplitComplementHarmony()");
}
var opposite: number = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359);
diff --git a/Phaser/utils/DebugUtils.ts b/Phaser/utils/DebugUtils.ts
index ec2220b7..c593f7ed 100644
--- a/Phaser/utils/DebugUtils.ts
+++ b/Phaser/utils/DebugUtils.ts
@@ -17,6 +17,12 @@ module Phaser {
static game: Game;
+ /**
+ * Render context of stage's canvas.
+ * @type {CanvasRenderingContext2D}
+ */
+ static context: CanvasRenderingContext2D;
+
/**
* Render debug infos. (including name, bounds info, position and some other properties)
* @param x {number} X position of the debug info to be rendered.
@@ -25,14 +31,14 @@ module Phaser {
*/
static renderSpriteInfo(sprite: Sprite, x: number, y: number, color?: string = 'rgb(255,255,255)') {
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y);
- DebugUtils.game.stage.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14);
- DebugUtils.game.stage.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28);
- DebugUtils.game.stage.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42);
- DebugUtils.game.stage.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56);
- DebugUtils.game.stage.context.fillText('cx: ' + sprite.cameraView.x + ' cy: ' + sprite.cameraView.y + ' cw: ' + sprite.cameraView.width + ' ch: ' + sprite.cameraView.height + ' cb: ' + sprite.cameraView.bottom + ' cr: ' + sprite.cameraView.right, x, y + 70);
- DebugUtils.game.stage.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 84);
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y);
+ DebugUtils.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14);
+ DebugUtils.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28);
+ DebugUtils.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42);
+ DebugUtils.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56);
+ DebugUtils.context.fillText('cx: ' + sprite.cameraView.x + ' cy: ' + sprite.cameraView.y + ' cw: ' + sprite.cameraView.width + ' ch: ' + sprite.cameraView.height + ' cb: ' + sprite.cameraView.bottom + ' cr: ' + sprite.cameraView.right, x, y + 70);
+ DebugUtils.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 84);
}
@@ -43,29 +49,53 @@ module Phaser {
camera = DebugUtils.game.camera;
}
- //var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x);
- //var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y);
var dx = sprite.worldView.x;
var dy = sprite.worldView.y;
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillRect(dx, dy, sprite.width, sprite.height);
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillRect(dx, dy, sprite.width, sprite.height);
}
- static renderSpritePhysicsBody(sprite: Sprite, camera?: Camera = null, color?: string = 'rgba(255,0,0,0.2)') {
+ static renderPhysicsBody(body: Phaser.Physics.Body, lineWidth: number = 1, fillStyle: string = 'rgba(0,255,0,0.2)', sleepStyle: string = 'rgba(100,100,100,0.2)') {
- if (camera == null)
+ for (var s = 0; s < body.shapes.length; s++)
{
- camera = DebugUtils.game.camera;
+ DebugUtils.context.beginPath();
+
+ if (body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_POLY)
+ {
+ var verts = body.shapes[s].tverts;
+
+ DebugUtils.context.moveTo((body.position.x + verts[0].x) * 50, (body.position.y + verts[0].y) * 50);
+
+ for (var i = 0; i < verts.length; i++) {
+ DebugUtils.context.lineTo((body.position.x + verts[i].x) * 50, (body.position.y + verts[i].y) * 50);
+ }
+
+ DebugUtils.context.lineTo((body.position.x + verts[verts.length - 1].x) * 50, (body.position.y + verts[verts.length - 1].y) * 50);
+ }
+ else if (body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_CIRCLE)
+ {
+ var circle = body.shapes[s];
+ DebugUtils.context.arc(circle.tc.x * 50, circle.tc.y * 50, circle.radius * 50, 0, Math.PI * 2, false);
+ }
+
+ DebugUtils.context.closePath();
+
+ if (body.isAwake)
+ {
+ DebugUtils.context.fillStyle = fillStyle;
+ }
+ else
+ {
+ DebugUtils.context.fillStyle = sleepStyle;
+ }
+
+ DebugUtils.context.fill();
+
}
- var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.body.x - (camera.worldView.x * sprite.transform.scrollFactor.x);
- var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.body.y - (camera.worldView.y * sprite.transform.scrollFactor.y);
-
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillRect(dx, dy, sprite.body.width, sprite.body.height);
-
}
}
diff --git a/Phaser/utils/SpriteUtils.ts b/Phaser/utils/SpriteUtils.ts
index 28b597d1..be61a296 100644
--- a/Phaser/utils/SpriteUtils.ts
+++ b/Phaser/utils/SpriteUtils.ts
@@ -272,8 +272,8 @@ module Phaser {
static reset(sprite: Sprite, x: number, y: number) {
sprite.revive();
- sprite.body.touching = Types.NONE;
- sprite.body.wasTouching = Types.NONE;
+ //sprite.body.touching = Types.NONE;
+ //sprite.body.wasTouching = Types.NONE;
sprite.x = x;
sprite.y = y;
sprite.body.velocity.x = 0;
diff --git a/README.md b/README.md
index bd59ca53..d92e7722 100644
--- a/README.md
+++ b/README.md
@@ -44,15 +44,17 @@ TODO:
* Drag Sprite with "snap to center" uses local coords not world, so fails on scrolling world (no center lock works fine)
* Need to be able to set the current tilemap layer, then the getTileXY default layer uses that one if no other given
* Pointer worldX/Y don't appear to be correct for some reason
-
-
+* Create a Pixel game object type (useful for particles / fx)
* Sprite collision events
* See which functions in the input component can move elsewhere (utils)
* Move all of the renderDebugInfo methods to the DebugUtils class
* Check bounds/edge points when sprite is only 1x1 sized :)
-
* See what I can move out of Body and into a BodyUtils class.
* See about optimising Advanced Physics a lot more, so it doesn't create lots of Vec2s everywhere.
+* QuadTree.physics.checkHullIntersection
+* Fix the Motion methods for the new physics system
+* Moved findShapeByPoint etc from Space to Manager (or at least add a proxy to them)
+
V1.0.0
@@ -71,7 +73,7 @@ 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
+* Removed Sprite.angle - use Sprite.rotation 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.
* Added SpriteUtils.setOriginToCenter to quickly set the origin of a sprite based on either frameBounds or body.bounds
@@ -83,7 +85,7 @@ V1.0.0
* Added Group.addNewSprite(x,y,key) for quick addition of new Sprites to a Group
* Fixed Group.sort so the sortHandler is called correctly
* Added Group.swap(a,b) to swap the z-index of 2 objects with optional rendering update boolean
-* Sprites dispatch killed/revived and added to and removed from Group events.
+* Sprites dispatch new events for: killed, revived, added to Group and removed from Group.
* Added Input drag, bounds, sprite bounds and snapping support.
* Added the new ColorUtils class full of lots of handy color manipulation functions.
* Fixed issue in Camera.inCamera check where it wouldn't take into consideration the Sprites scrollFactor.
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 27a5bcf9..3af754cb 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -65,7 +65,6 @@
scrollfactor 2.ts
-
@@ -174,25 +173,14 @@
when particles collide.ts
-
- aabb 1.ts
-
-
-
- aabb vs aabb 1.ts
-
-
-
-
- body1.ts
-
-
- obb vs obb.ts
+
+
+ simple test 1.ts
ballscroller.ts
diff --git a/Tests/cameras/world sprite.js b/Tests/cameras/world sprite.js
index 588a638a..93ac9c22 100644
--- a/Tests/cameras/world sprite.js
+++ b/Tests/cameras/world sprite.js
@@ -12,9 +12,6 @@
function create() {
game.add.sprite(0, 0, 'backdrop');
ball = game.add.sprite(200, 200, 'ball');
- ball.body.offset.setTo(-16, -16);
- ball.body.width = 100;
- ball.body.height = 100;
ball.body.velocity.x = 50;
ball.transform.scale.setTo(2, 2);
}
@@ -56,7 +53,5 @@
function render() {
game.camera.renderDebugInfo(32, 32);
Phaser.DebugUtils.renderSpriteInfo(ball, 32, 200);
- //Phaser.DebugUtils.renderSpriteBounds(ball);
- Phaser.DebugUtils.renderSpritePhysicsBody(ball);
}
})();
diff --git a/Tests/cameras/world sprite.ts b/Tests/cameras/world sprite.ts
index 597b4c67..62d4ecd6 100644
--- a/Tests/cameras/world sprite.ts
+++ b/Tests/cameras/world sprite.ts
@@ -24,10 +24,6 @@
ball = game.add.sprite(200, 200, 'ball');
- ball.body.offset.setTo(-16, -16);
- ball.body.width = 100;
- ball.body.height = 100;
-
ball.body.velocity.x = 50;
ball.transform.scale.setTo(2, 2);
@@ -83,8 +79,6 @@
game.camera.renderDebugInfo(32, 32);
Phaser.DebugUtils.renderSpriteInfo(ball, 32, 200);
- //Phaser.DebugUtils.renderSpriteBounds(ball);
- Phaser.DebugUtils.renderSpritePhysicsBody(ball);
}
diff --git a/Tests/input/world drag.js b/Tests/input/world drag.js
index f6a3d3ab..e75a9887 100644
--- a/Tests/input/world drag.js
+++ b/Tests/input/world drag.js
@@ -33,7 +33,6 @@
}
function render() {
game.camera.renderDebugInfo(32, 32);
- test.body.renderDebugInfo(300, 32);
Phaser.DebugUtils.renderSpriteInfo(test, 32, 200);
game.input.renderDebugInfo(300, 200);
}
diff --git a/Tests/input/world drag.ts b/Tests/input/world drag.ts
index afbb9f87..d2572724 100644
--- a/Tests/input/world drag.ts
+++ b/Tests/input/world drag.ts
@@ -62,8 +62,6 @@
game.camera.renderDebugInfo(32, 32);
- test.body.renderDebugInfo(300, 32);
-
Phaser.DebugUtils.renderSpriteInfo(test, 32, 200);
game.input.renderDebugInfo(300, 200);
diff --git a/Tests/phaser.js b/Tests/phaser.js
index 96d3a9b8..661e4d30 100644
--- a/Tests/phaser.js
+++ b/Tests/phaser.js
@@ -708,20 +708,28 @@ var Phaser;
QuadTree._iterator = QuadTree._iterator.next;
continue;
}
- //if (QuadTree._object.body.bounds.checkHullIntersection(this._checkObject.body.bounds))
- if(QuadTree.physics.checkHullIntersection(QuadTree._object.body, this._checkObject.body)) {
- //Execute callback functions if they exist
- if((QuadTree._processingCallback == null) || QuadTree._processingCallback(QuadTree._object, this._checkObject)) {
- this._overlapProcessed = true;
- }
- if(this._overlapProcessed && (QuadTree._notifyCallback != null)) {
- if(QuadTree._callbackContext !== null) {
- QuadTree._notifyCallback.call(QuadTree._callbackContext, QuadTree._object, this._checkObject);
- } else {
- QuadTree._notifyCallback(QuadTree._object, this._checkObject);
- }
- }
+ /*
+ if (QuadTree.physics.checkHullIntersection(QuadTree._object.body, this._checkObject.body))
+ {
+ //Execute callback functions if they exist
+ if ((QuadTree._processingCallback == null) || QuadTree._processingCallback(QuadTree._object, this._checkObject))
+ {
+ this._overlapProcessed = true;
}
+
+ if (this._overlapProcessed && (QuadTree._notifyCallback != null))
+ {
+ if (QuadTree._callbackContext !== null)
+ {
+ QuadTree._notifyCallback.call(QuadTree._callbackContext, QuadTree._object, this._checkObject);
+ }
+ else
+ {
+ QuadTree._notifyCallback(QuadTree._object, this._checkObject);
+ }
+ }
+ }
+ */
QuadTree._iterator = QuadTree._iterator.next;
}
return this._overlapProcessed;
@@ -1587,7 +1595,7 @@ var Phaser;
if (typeof threshold === "undefined") { threshold = 30; }
var hsv = ColorUtils.RGBtoHSV(color);
if(threshold >= 359 || threshold <= 0) {
- throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()");
+ throw Error("ColorUtils Warning: Invalid threshold given to getSplitComplementHarmony()");
}
var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359);
var warmer = ColorUtils.game.math.wrapValue(hsv.hue, opposite - threshold, 359);
@@ -3195,7 +3203,7 @@ var Phaser;
this._prevRotation = this.rotation;
dirty = true;
}
- // If it has moved, updated the edges and center
+ // If it has moved, update the edges and center
if(dirty || this.parent.x != this._pos.x || this.parent.y != this._pos.y) {
this.center.x = this.parent.x + this._distance * this._scA.y;
this.center.y = this.parent.y + this._distance * this._scA.x;
@@ -4260,231 +4268,2817 @@ var Phaser;
}
*/
})(Phaser || (Phaser = {}));
+///
+///
+/**
+* Phaser - 2D Transform
+*
+* A 2D Transform
+*/
+var Phaser;
+(function (Phaser) {
+ var Transform = (function () {
+ /**
+ * Creates a new 2D Transform object.
+ * @class Transform
+ * @constructor
+ * @return {Transform} This object
+ **/
+ function Transform(pos, angle) {
+ this.t = Phaser.Vec2Utils.clone(pos);
+ this.c = Math.cos(angle);
+ this.s = Math.sin(angle);
+ this.angle = angle;
+ }
+ Transform.prototype.toString = function () {
+ return 't=' + this.t.toString() + ' c=' + this.c + ' s=' + this.s + ' a=' + this.angle;
+ };
+ Transform.prototype.setTo = function (pos, angle) {
+ this.t.copyFrom(pos);
+ this.c = Math.cos(angle);
+ this.s = Math.sin(angle);
+ return this;
+ };
+ Transform.prototype.setRotation = function (angle) {
+ if(angle !== this.angle) {
+ this.c = Math.cos(angle);
+ this.s = Math.sin(angle);
+ this.angle = angle;
+ }
+ return this;
+ };
+ Transform.prototype.setPosition = function (p) {
+ this.t.copyFrom(p);
+ return this;
+ };
+ Transform.prototype.identity = function () {
+ this.t.setTo(0, 0);
+ this.c = 1;
+ this.s = 0;
+ return this;
+ };
+ return Transform;
+ })();
+ Phaser.Transform = Transform;
+})(Phaser || (Phaser = {}));
+///
+///
+///
+/**
+* Phaser - TransformUtils
+*
+* A collection of methods useful for manipulating and performing operations on 2D Transforms.
+*
+*/
+var Phaser;
+(function (Phaser) {
+ var TransformUtils = (function () {
+ function TransformUtils() { }
+ TransformUtils.rotate = function rotate(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ //return new vec2(v.x * this.c - v.y * this.s, v.x * this.s + v.y * this.c);
+ return out.setTo(v.x * t.c - v.y * t.s, v.x * t.s + v.y * t.c);
+ };
+ TransformUtils.unrotate = function unrotate(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ //return new vec2(v.x * this.c + v.y * this.s, -v.x * this.s + v.y * this.c);
+ return out.setTo(v.x * t.c + v.y * t.s, -v.x * t.s + v.y * t.c);
+ };
+ TransformUtils.transform = function transform(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ //return new vec2(v.x * this.c - v.y * this.s + this.t.x, v.x * this.s + v.y * this.c + this.t.y);
+ return out.setTo(v.x * t.c - v.y * t.s + t.t.x, v.x * t.s + v.y * t.c + t.t.y);
+ };
+ TransformUtils.untransform = function untransform(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ var px = v.x - t.t.x;
+ var py = v.y - t.t.y;
+ //return new vec2(px * this.c + py * this.s, -px * this.s + py * this.c);
+ return out.setTo(px * t.c + py * t.s, -px * t.s + py * t.c);
+ };
+ return TransformUtils;
+ })();
+ Phaser.TransformUtils = TransformUtils;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Joint
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Joint = (function () {
+ function Joint(type, body1, body2, collideConnected) {
+ this.id = Phaser.Physics.Manager.jointCounter++;
+ this.type = type;
+ this.body1 = body1;
+ this.body2 = body2;
+ this.collideConnected = collideConnected;
+ this.maxForce = 9999999999;
+ this.breakable = false;
+ }
+ Joint.prototype.getWorldAnchor1 = function () {
+ return this.body1.getWorldPoint(this.anchor1);
+ };
+ Joint.prototype.getWorldAnchor2 = function () {
+ return this.body2.getWorldPoint(this.anchor2);
+ };
+ Joint.prototype.setWorldAnchor1 = function (anchor1) {
+ this.anchor1 = this.body1.getLocalPoint(anchor1);
+ };
+ Joint.prototype.setWorldAnchor2 = function (anchor2) {
+ this.anchor2 = this.body2.getLocalPoint(anchor2);
+ };
+ return Joint;
+ })();
+ Physics.Joint = Joint;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Physics Manager
+ *
+ * The Physics Manager is responsible for looking after, creating and colliding
+ * all of the physics bodies and joints in the world.
+ */
+ (function (Physics) {
+ var Manager = (function () {
+ function Manager(game) {
+ this.lastTime = Date.now();
+ this.frameRateHz = 60;
+ this.timeDelta = 0;
+ this.paused = false;
+ this.step = false;
+ // step through the simulation (i.e. per click)
+ //public paused: bool = true;
+ //public step: bool = false; // step through the simulation (i.e. per click)
+ this.velocityIterations = 8;
+ this.positionIterations = 4;
+ this.allowSleep = true;
+ this.warmStarting = true;
+ this.game = game;
+ this.gravity = new Phaser.Vec2();
+ this.space = new Physics.Space(this);
+ Manager.collision = new Physics.Collision();
+ }
+ Manager.clear = function clear() {
+ //Manager.debug.textContent = "";
+ Manager.log = [];
+ };
+ Manager.write = function write(s) {
+ //Manager.debug.textContent += s + "\n";
+ };
+ Manager.writeAll = function writeAll() {
+ for(var i = 0; i < Manager.log.length; i++) {
+ //Manager.debug.textContent += Manager.log[i];
+ }
+ };
+ Manager.log = [];
+ Manager.dump = function dump(phase, body) {
+ /*
+ var s = "\n\nPhase: " + phase + "\n";
+ s += "Position: " + body.position.toString() + "\n";
+ s += "Velocity: " + body.velocity.toString() + "\n";
+ s += "Angle: " + body.angle + "\n";
+ s += "Force: " + body.force.toString() + "\n";
+ s += "Torque: " + body.torque + "\n";
+ s += "Bounds: " + body.bounds.toString() + "\n";
+ s += "Shape ***\n";
+ s += "Vert 0: " + body.shapes[0].verts[0].toString() + "\n";
+ s += "Vert 1: " + body.shapes[0].verts[1].toString() + "\n";
+ s += "Vert 2: " + body.shapes[0].verts[2].toString() + "\n";
+ s += "Vert 3: " + body.shapes[0].verts[3].toString() + "\n";
+ s += "TVert 0: " + body.shapes[0].tverts[0].toString() + "\n";
+ s += "TVert 1: " + body.shapes[0].tverts[1].toString() + "\n";
+ s += "TVert 2: " + body.shapes[0].tverts[2].toString() + "\n";
+ s += "TVert 3: " + body.shapes[0].tverts[3].toString() + "\n";
+ s += "Plane 0: " + body.shapes[0].planes[0].normal.toString() + "\n";
+ s += "Plane 1: " + body.shapes[0].planes[1].normal.toString() + "\n";
+ s += "Plane 2: " + body.shapes[0].planes[2].normal.toString() + "\n";
+ s += "Plane 3: " + body.shapes[0].planes[3].normal.toString() + "\n";
+ s += "TPlane 0: " + body.shapes[0].tplanes[0].normal.toString() + "\n";
+ s += "TPlane 1: " + body.shapes[0].tplanes[1].normal.toString() + "\n";
+ s += "TPlane 2: " + body.shapes[0].tplanes[2].normal.toString() + "\n";
+ s += "TPlane 3: " + body.shapes[0].tplanes[3].normal.toString() + "\n";
+
+ Manager.log.push(s);
+ */
+ };
+ Manager.SHAPE_TYPE_CIRCLE = 0;
+ Manager.SHAPE_TYPE_SEGMENT = 1;
+ Manager.SHAPE_TYPE_POLY = 2;
+ Manager.SHAPE_NUM_TYPES = 3;
+ Manager.JOINT_TYPE_ANGLE = 0;
+ Manager.JOINT_TYPE_REVOLUTE = 1;
+ Manager.JOINT_TYPE_WELD = 2;
+ Manager.JOINT_TYPE_WHEEL = 3;
+ Manager.JOINT_TYPE_PRISMATIC = 4;
+ Manager.JOINT_TYPE_DISTANCE = 5;
+ Manager.JOINT_TYPE_ROPE = 6;
+ Manager.JOINT_TYPE_MOUSE = 7;
+ Manager.JOINT_LINEAR_SLOP = 0.0008;
+ Manager.JOINT_ANGULAR_SLOP = 2 * 0.017453292519943294444444444444444;
+ Manager.JOINT_MAX_LINEAR_CORRECTION = 0.5;
+ Manager.JOINT_MAX_ANGULAR_CORRECTION = 8 * 0.017453292519943294444444444444444;
+ Manager.JOINT_LIMIT_STATE_INACTIVE = 0;
+ Manager.JOINT_LIMIT_STATE_AT_LOWER = 1;
+ Manager.JOINT_LIMIT_STATE_AT_UPPER = 2;
+ Manager.JOINT_LIMIT_STATE_EQUAL_LIMITS = 3;
+ Manager.CONTACT_SOLVER_COLLISION_SLOP = 0.0008;
+ Manager.CONTACT_SOLVER_BAUMGARTE = 0.28;
+ Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION = 1;
+ Manager.bodyCounter = 0;
+ Manager.jointCounter = 0;
+ Manager.shapeCounter = 0;
+ Manager.prototype.update = function () {
+ // Get these from Phaser.Time instead
+ var time = Date.now();
+ var frameTime = (time - this.lastTime) / 1000;
+ this.lastTime = time;
+ // if rAf - why?
+ frameTime = Math.floor(frameTime * 60 + 0.5) / 60;
+ //if (!mouseDown)
+ //{
+ // var p = canvasToWorld(mousePosition);
+ // var body = space.findBodyByPoint(p);
+ // //domCanvas.style.cursor = body ? "pointer" : "default";
+ //}
+ if(!this.paused || this.step) {
+ Manager.clear();
+ var h = 1 / this.frameRateHz;
+ this.timeDelta += frameTime;
+ if(this.step) {
+ this.step = false;
+ this.timeDelta = h;
+ }
+ for(var maxSteps = 4; maxSteps > 0 && this.timeDelta >= h; maxSteps--) {
+ this.space.step(h, this.velocityIterations, this.positionIterations, this.warmStarting, this.allowSleep);
+ this.timeDelta -= h;
+ }
+ if(this.timeDelta > h) {
+ this.timeDelta = 0;
+ }
+ }
+ //frameCount++;
+ };
+ Manager.prototype.addBody = function (body) {
+ this.space.addBody(body);
+ };
+ Manager.prototype.removeBody = function (body) {
+ this.space.removeBody(body);
+ };
+ Manager.prototype.addJoint = function (joint) {
+ this.space.addJoint(joint);
+ };
+ Manager.prototype.removeJoint = function (joint) {
+ this.space.removeJoint(joint);
+ };
+ Manager.prototype.pixelsToMeters = function (value) {
+ return value * 0.02;
+ };
+ Manager.prototype.metersToPixels = function (value) {
+ return value * 50;
+ };
+ Manager.pixelsToMeters = function pixelsToMeters(value) {
+ return value * 0.02;
+ };
+ Manager.metersToPixels = function metersToPixels(value) {
+ return value * 50;
+ };
+ Manager.p2m = function p2m(value) {
+ return value * 0.02;
+ };
+ Manager.m2p = function m2p(value) {
+ return value * 50;
+ };
+ Manager.areaForCircle = function areaForCircle(radius_outer, radius_inner) {
+ return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
+ };
+ Manager.inertiaForCircle = function inertiaForCircle(mass, center, radius_outer, radius_inner) {
+ return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
+ };
+ Manager.areaForSegment = function areaForSegment(a, b, radius) {
+ return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
+ };
+ Manager.centroidForSegment = function centroidForSegment(a, b) {
+ return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+ };
+ Manager.inertiaForSegment = function inertiaForSegment(mass, a, b) {
+ var distsq = Phaser.Vec2Utils.distanceSq(b, a);
+ var offset = Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+ return mass * (distsq / 12 + offset.lengthSq());
+ };
+ Manager.areaForPoly = function areaForPoly(verts) {
+ var area = 0;
+ for(var i = 0; i < verts.length; i++) {
+ area += Phaser.Vec2Utils.cross(verts[i], verts[(i + 1) % verts.length]);
+ }
+ return area / 2;
+ };
+ Manager.centroidForPoly = function centroidForPoly(verts) {
+ var area = 0;
+ var vsum = new Phaser.Vec2();
+ for(var i = 0; i < verts.length; i++) {
+ var v1 = verts[i];
+ var v2 = verts[(i + 1) % verts.length];
+ var cross = Phaser.Vec2Utils.cross(v1, v2);
+ area += cross;
+ // SO many vecs created here - unroll these bad boys
+ vsum.add(Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(v1, v2), cross));
+ }
+ return Phaser.Vec2Utils.scale(vsum, 1 / (3 * area));
+ };
+ Manager.inertiaForPoly = function inertiaForPoly(mass, verts, offset) {
+ var sum1 = 0;
+ var sum2 = 0;
+ for(var i = 0; i < verts.length; i++) {
+ var v1 = Phaser.Vec2Utils.add(verts[i], offset);
+ var v2 = Phaser.Vec2Utils.add(verts[(i + 1) % verts.length], offset);
+ var a = Phaser.Vec2Utils.cross(v2, v1);
+ var b = Phaser.Vec2Utils.dot(v1, v1) + Phaser.Vec2Utils.dot(v1, v2) + Phaser.Vec2Utils.dot(v2, v2);
+ sum1 += a * b;
+ sum2 += a;
+ }
+ return (mass * sum1) / (6 * sum2);
+ };
+ Manager.inertiaForBox = function inertiaForBox(mass, w, h) {
+ return mass * (w * w + h * h) / 12;
+ };
+ Manager.createConvexHull = // Create the convex hull using the Gift wrapping algorithm (http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)
+ function createConvexHull(points) {
+ // Find the right most point on the hull
+ var i0 = 0;
+ var x0 = points[0].x;
+ for(var i = 1; i < points.length; i++) {
+ var x = points[i].x;
+ if(x > x0 || (x == x0 && points[i].y < points[i0].y)) {
+ i0 = i;
+ x0 = x;
+ }
+ }
+ var n = points.length;
+ var hull = [];
+ var m = 0;
+ var ih = i0;
+ while(1) {
+ hull[m] = ih;
+ var ie = 0;
+ for(var j = 1; j < n; j++) {
+ if(ie == ih) {
+ ie = j;
+ continue;
+ }
+ var r = Phaser.Vec2Utils.subtract(points[ie], points[hull[m]]);
+ var v = Phaser.Vec2Utils.subtract(points[j], points[hull[m]]);
+ var c = Phaser.Vec2Utils.cross(r, v);
+ if(c < 0) {
+ ie = j;
+ }
+ // Collinearity check
+ if(c == 0 && v.lengthSq() > r.lengthSq()) {
+ ie = j;
+ }
+ }
+ m++;
+ ih = ie;
+ if(ie == i0) {
+ break;
+ }
+ }
+ // Copy vertices
+ var newPoints = [];
+ for(var i = 0; i < m; ++i) {
+ newPoints.push(points[hull[i]]);
+ }
+ return newPoints;
+ };
+ return Manager;
+ })();
+ Physics.Manager = Manager;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ /**
+ * Phaser - 2D AABB
+ *
+ * A 2D AABB object
+ */
+ (function (Physics) {
+ var Bounds = (function () {
+ /**
+ * Creates a new 2D AABB object.
+ * @class Bounds
+ * @constructor
+ * @return {Bounds} This object
+ **/
+ function Bounds(mins, maxs) {
+ if (typeof mins === "undefined") { mins = null; }
+ if (typeof maxs === "undefined") { maxs = null; }
+ if(mins) {
+ this.mins = Phaser.Vec2Utils.clone(mins);
+ } else {
+ this.mins = new Phaser.Vec2(999999, 999999);
+ }
+ if(maxs) {
+ this.maxs = Phaser.Vec2Utils.clone(maxs);
+ } else {
+ this.maxs = new Phaser.Vec2(999999, 999999);
+ }
+ }
+ Bounds.prototype.toString = function () {
+ return [
+ "mins:",
+ this.mins.toString(),
+ "maxs:",
+ this.maxs.toString()
+ ].join(" ");
+ };
+ Bounds.prototype.setTo = function (mins, maxs) {
+ this.mins.setTo(mins.x, mins.y);
+ this.maxs.setTo(maxs.x, maxs.y);
+ };
+ Bounds.prototype.copy = function (b) {
+ this.mins.copyFrom(b.mins);
+ this.maxs.copyFrom(b.maxs);
+ return this;
+ };
+ Bounds.prototype.clear = function () {
+ this.mins.setTo(999999, 999999);
+ this.maxs.setTo(-999999, -999999);
+ return this;
+ };
+ Object.defineProperty(Bounds.prototype, "x", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.mins.x);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "y", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.mins.y);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "width", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.maxs.x - this.mins.x);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "height", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.maxs.y - this.mins.y);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "right", {
+ get: function () {
+ return this.x + this.width;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "bottom", {
+ get: function () {
+ return this.y + this.height;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Bounds.prototype.isEmpty = function () {
+ return (this.mins.x > this.maxs.x || this.mins.y > this.maxs.y);
+ };
+ Bounds.prototype.getPerimeter = /*
+ public getCenter() {
+ return vec2.scale(vec2.add(this.mins, this.maxs), 0.5);
+ }
+
+ public getExtent() {
+ return vec2.scale(vec2.sub(this.maxs, this.mins), 0.5);
+ }
+ */
+ function () {
+ return (this.maxs.x - this.mins.x + this.maxs.y - this.mins.y) * 2;
+ };
+ Bounds.prototype.addPoint = function (p) {
+ if(this.mins.x > p.x) {
+ this.mins.x = p.x;
+ }
+ if(this.maxs.x < p.x) {
+ this.maxs.x = p.x;
+ }
+ if(this.mins.y > p.y) {
+ this.mins.y = p.y;
+ }
+ if(this.maxs.y < p.y) {
+ this.maxs.y = p.y;
+ }
+ return this;
+ };
+ Bounds.prototype.addBounds = function (b) {
+ if(this.mins.x > b.mins.x) {
+ this.mins.x = b.mins.x;
+ }
+ if(this.maxs.x < b.maxs.x) {
+ this.maxs.x = b.maxs.x;
+ }
+ if(this.mins.y > b.mins.y) {
+ this.mins.y = b.mins.y;
+ }
+ if(this.maxs.y < b.maxs.y) {
+ this.maxs.y = b.maxs.y;
+ }
+ return this;
+ };
+ Bounds.prototype.addBounds2 = function (mins, maxs) {
+ if(this.mins.x > mins.x) {
+ this.mins.x = mins.x;
+ }
+ if(this.maxs.x < maxs.x) {
+ this.maxs.x = maxs.x;
+ }
+ if(this.mins.y > mins.y) {
+ this.mins.y = mins.y;
+ }
+ if(this.maxs.y < maxs.y) {
+ this.maxs.y = maxs.y;
+ }
+ return this;
+ };
+ Bounds.prototype.addExtents = function (center, extent_x, extent_y) {
+ if(this.mins.x > center.x - extent_x) {
+ this.mins.x = center.x - extent_x;
+ }
+ if(this.maxs.x < center.x + extent_x) {
+ this.maxs.x = center.x + extent_x;
+ }
+ if(this.mins.y > center.y - extent_y) {
+ this.mins.y = center.y - extent_y;
+ }
+ if(this.maxs.y < center.y + extent_y) {
+ this.maxs.y = center.y + extent_y;
+ }
+ return this;
+ };
+ Bounds.prototype.expand = function (ax, ay) {
+ this.mins.x -= ax;
+ this.mins.y -= ay;
+ this.maxs.x += ax;
+ this.maxs.y += ay;
+ return this;
+ };
+ Bounds.prototype.containPoint = function (p) {
+ if(p.x < this.mins.x || p.x > this.maxs.x || p.y < this.mins.y || p.y > this.maxs.y) {
+ return false;
+ }
+ return true;
+ };
+ Bounds.prototype.intersectsBounds = function (b) {
+ if(this.mins.x > b.maxs.x || this.maxs.x < b.mins.x || this.mins.y > b.maxs.y || this.maxs.y < b.mins.y) {
+ return false;
+ }
+ return true;
+ };
+ Bounds.expand = function expand(b, ax, ay) {
+ var b = new Bounds(b.mins, b.maxs);
+ b.expand(ax, ay);
+ return b;
+ };
+ return Bounds;
+ })();
+ Physics.Bounds = Bounds;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ })(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shape
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Shape = (function () {
+ function Shape(type) {
+ this.id = Phaser.Physics.Manager.shapeCounter++;
+ this.type = type;
+ this.elasticity = 0.0;
+ this.friction = 1.0;
+ this.density = 1;
+ this.bounds = new Physics.Bounds();
+ }
+ Shape.prototype.findEdgeByPoint = // Over-ridden by ShapePoly
+ function (p, minDist) {
+ return -1;
+ };
+ return Shape;
+ })();
+ Physics.Shape = Shape;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Contact
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Contact = (function () {
+ function Contact(p, n, d, hash) {
+ this.hash = hash;
+ this.point = p;
+ this.normal = n;
+ this.depth = d;
+ this.lambdaNormal = 0;
+ this.lambdaTangential = 0;
+ this.r1 = new Phaser.Vec2();
+ this.r2 = new Phaser.Vec2();
+ this.r1_local = new Phaser.Vec2();
+ this.r2_local = new Phaser.Vec2();
+ }
+ return Contact;
+ })();
+ Physics.Contact = Contact;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
///
///
///
+ ///
+ ///
+ ///
+ ///
/**
- * Phaser - Physics - Body
+ * Phaser - Advanced Physics - ContactSolver
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ //-------------------------------------------------------------------------------------------------
+ // Contact Constraint
+ //
+ // Non-penetration constraint:
+ // C = dot(p2 - p1, n)
+ // Cdot = dot(v2 - v1, n)
+ // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
+ //
+ // impulse = JT * lambda = [ -n * lambda, -cross(r1, n) * lambda, n * lambda, cross(r1, n) * lambda ]
+ //
+ // Friction constraint:
+ // C = dot(p2 - p1, t)
+ // Cdot = dot(v2 - v1, t)
+ // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
+ //
+ // impulse = JT * lambda = [ -t * lambda, -cross(r1, t) * lambda, t * lambda, cross(r1, t) * lambda ]
+ //
+ // NOTE: lambda is an impulse in constraint space.
+ //-------------------------------------------------------------------------------------------------
+ (function (Physics) {
+ var ContactSolver = (function () {
+ function ContactSolver(shape1, shape2) {
+ this.shape1 = shape1;
+ this.shape2 = shape2;
+ this.contacts = [];
+ this.elasticity = 1;
+ this.friction = 1;
+ }
+ ContactSolver.prototype.update = function (newContactArr) {
+ for(var i = 0; i < newContactArr.length; i++) {
+ var newContact = newContactArr[i];
+ var k = -1;
+ for(var j = 0; j < this.contacts.length; j++) {
+ if(newContact.hash == this.contacts[j].hash) {
+ k = j;
+ break;
+ }
+ }
+ if(k > -1) {
+ newContact.lambdaNormal = this.contacts[k].lambdaNormal;
+ newContact.lambdaTangential = this.contacts[k].lambdaTangential;
+ }
+ }
+ this.contacts = newContactArr;
+ };
+ ContactSolver.prototype.initSolver = function (dt_inv) {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ var sum_m_inv = body1.massInverted + body2.massInverted;
+ for(var i = 0; i < this.contacts.length; i++) {
+ var con = this.contacts[i];
+ //console.log('initSolver con');
+ //console.log(con);
+ // Transformed r1, r2
+ Phaser.Vec2Utils.subtract(con.point, body1.position, con.r1);
+ Phaser.Vec2Utils.subtract(con.point, body2.position, con.r2);
+ //con.r1 = vec2.sub(con.point, body1.p);
+ //con.r2 = vec2.sub(con.point, body2.p);
+ // Local r1, r2
+ Phaser.TransformUtils.unrotate(body1.transform, con.r1, con.r1_local);
+ Phaser.TransformUtils.unrotate(body2.transform, con.r2, con.r2_local);
+ //con.r1_local = body1.transform.unrotate(con.r1);
+ //con.r2_local = body2.transform.unrotate(con.r2);
+ var n = con.normal;
+ var t = Phaser.Vec2Utils.perp(con.normal);
+ // invEMn = J * invM * JT
+ // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
+ var sn1 = Phaser.Vec2Utils.cross(con.r1, n);
+ var sn2 = Phaser.Vec2Utils.cross(con.r2, n);
+ var emn_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
+ con.emn = emn_inv == 0 ? 0 : 1 / emn_inv;
+ // invEMt = J * invM * JT
+ // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
+ var st1 = Phaser.Vec2Utils.cross(con.r1, t);
+ var st2 = Phaser.Vec2Utils.cross(con.r2, t);
+ var emt_inv = sum_m_inv + body1.inertiaInverted * st1 * st1 + body2.inertiaInverted * st2 * st2;
+ con.emt = emt_inv == 0 ? 0 : 1 / emt_inv;
+ // Linear velocities at contact point
+ // in 2D: cross(w, r) = perp(r) * w
+ var v1 = new Phaser.Vec2();
+ var v2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(con.r1), body1.angularVelocity, v1);
+ Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(con.r2), body2.angularVelocity, v2);
+ //var v1 = vec2.mad(body1.v, vec2.perp(con.r1), body1.w);
+ //var v2 = vec2.mad(body2.v, vec2.perp(con.r2), body2.w);
+ // relative velocity at contact point
+ var rv = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(v2, v1, rv);
+ //var rv = vec2.sub(v2, v1);
+ // bounce velocity dot n
+ con.bounce = Phaser.Vec2Utils.dot(rv, con.normal) * this.elasticity;
+ }
+ };
+ ContactSolver.prototype.warmStart = function () {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ for(var i = 0; i < this.contacts.length; i++) {
+ var con = this.contacts[i];
+ var n = con.normal;
+ var lambda_n = con.lambdaNormal;
+ var lambda_t = con.lambdaTangential;
+ // Apply accumulated impulses
+ //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
+ //var impulse = new vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
+ var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
+ //console.log('phaser warmStart impulse ' + i + ' = ' + impulse.toString());
+ body1.velocity.multiplyAddByScalar(impulse, -body1.massInverted);
+ //body1.v.mad(impulse, -body1.m_inv);
+ body1.angularVelocity -= Phaser.Vec2Utils.cross(con.r1, impulse) * body1.inertiaInverted;
+ //body1.w -= vec2.cross(con.r1, impulse) * body1.i_inv;
+ body2.velocity.multiplyAddByScalar(impulse, body2.massInverted);
+ //body2.v.mad(impulse, body2.m_inv);
+ body2.angularVelocity += Phaser.Vec2Utils.cross(con.r2, impulse) * body2.inertiaInverted;
+ //body2.w += vec2.cross(con.r2, impulse) * body2.i_inv;
+ }
+ };
+ ContactSolver.prototype.solveVelocityConstraints = function () {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ Physics.Manager.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
+ Physics.Manager.write('Shape 1: ' + this.shape1.type + ' Shape 2: ' + this.shape2.type);
+ var m1_inv = body1.massInverted;
+ var i1_inv = body1.inertiaInverted;
+ var m2_inv = body2.massInverted;
+ var i2_inv = body2.inertiaInverted;
+ Physics.Manager.write('m1_inv: ' + m1_inv);
+ Physics.Manager.write('i1_inv: ' + i1_inv);
+ Physics.Manager.write('m2_inv: ' + m2_inv);
+ Physics.Manager.write('i2_inv: ' + i2_inv);
+ for(var i = 0; i < this.contacts.length; i++) {
+ Physics.Manager.write('------------ solve con ' + i);
+ var con = this.contacts[i];
+ var n = con.normal;
+ var t = Phaser.Vec2Utils.perp(n);
+ var r1 = con.r1;
+ var r2 = con.r2;
+ // Linear velocities at contact point
+ // in 2D: cross(w, r) = perp(r) * w
+ var v1 = new Phaser.Vec2();
+ var v2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(r1), body1.angularVelocity, v1);
+ //var v1 = vec2.mad(body1.v, vec2.perp(r1), body1.w);
+ Physics.Manager.write('v1 ' + v1.toString());
+ Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(r2), body2.angularVelocity, v2);
+ //var v2 = vec2.mad(body2.v, vec2.perp(r2), body2.w);
+ Physics.Manager.write('v2 ' + v2.toString());
+ // Relative velocity at contact point
+ var rv = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(v2, v1, rv);
+ //var rv = vec2.sub(v2, v1);
+ Physics.Manager.write('rv ' + rv.toString());
+ // Compute normal constraint impulse + adding bounce as a velocity bias
+ // lambda_n = -EMn * J * V
+ var lambda_n = -con.emn * (Phaser.Vec2Utils.dot(n, rv) + con.bounce);
+ Physics.Manager.write('lambda_n: ' + lambda_n);
+ // Accumulate and clamp
+ var lambda_n_old = con.lambdaNormal;
+ con.lambdaNormal = Math.max(lambda_n_old + lambda_n, 0);
+ //con.lambdaNormal = this.clamp(lambda_n_old + lambda_n, 0);
+ lambda_n = con.lambdaNormal - lambda_n_old;
+ Physics.Manager.write('lambda_n clamped: ' + lambda_n);
+ // Compute frictional constraint impulse
+ // lambda_t = -EMt * J * V
+ var lambda_t = -con.emt * Phaser.Vec2Utils.dot(t, rv);
+ // Max friction constraint impulse (Coulomb's Law)
+ var lambda_t_max = con.lambdaNormal * this.friction;
+ // Accumulate and clamp
+ var lambda_t_old = con.lambdaTangential;
+ con.lambdaTangential = this.clamp(lambda_t_old + lambda_t, -lambda_t_max, lambda_t_max);
+ lambda_t = con.lambdaTangential - lambda_t_old;
+ // Apply the final impulses
+ //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
+ var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
+ Physics.Manager.write('impulse: ' + impulse.toString());
+ body1.velocity.multiplyAddByScalar(impulse, -m1_inv);
+ //body1.v.mad(impulse, -m1_inv);
+ body1.angularVelocity -= Phaser.Vec2Utils.cross(r1, impulse) * i1_inv;
+ //body1.w -= vec2.cross(r1, impulse) * i1_inv;
+ body2.velocity.multiplyAddByScalar(impulse, m2_inv);
+ //body2.v.mad(impulse, m2_inv);
+ body2.angularVelocity += Phaser.Vec2Utils.cross(r2, impulse) * i2_inv;
+ //body2.w += vec2.cross(r2, impulse) * i2_inv;
+ Physics.Manager.write('body1: ' + body1.toString());
+ Physics.Manager.write('body2: ' + body2.toString());
+ }
+ };
+ ContactSolver.prototype.solvePositionConstraints = function () {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ Physics.Manager.write('solvePositionConstraints');
+ var m1_inv = body1.massInverted;
+ var i1_inv = body1.inertiaInverted;
+ var m2_inv = body2.massInverted;
+ var i2_inv = body2.inertiaInverted;
+ var sum_m_inv = m1_inv + m2_inv;
+ var max_penetration = 0;
+ for(var i = 0; i < this.contacts.length; i++) {
+ Physics.Manager.write('------------- solvePositionConstraints ' + i);
+ var con = this.contacts[i];
+ var n = con.normal;
+ var r1 = new Phaser.Vec2();
+ var r2 = new Phaser.Vec2();
+ // Transformed r1, r2
+ Phaser.Vec2Utils.rotate(con.r1_local, body1.angle, r1);
+ //var r1 = vec2.rotate(con.r1_local, body1.a);
+ Phaser.Vec2Utils.rotate(con.r2_local, body2.angle, r2);
+ //var r2 = vec2.rotate(con.r2_local, body2.a);
+ Physics.Manager.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
+ Physics.Manager.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
+ Physics.Manager.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
+ Physics.Manager.write('r2 rotated: r2.x = ' + r2.x + ' r2.y = ' + r2.y);
+ // Contact points (corrected)
+ var p1 = new Phaser.Vec2();
+ var p2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.add(body1.position, r1, p1);
+ //var p1 = vec2.add(body1.p, r1);
+ Phaser.Vec2Utils.add(body2.position, r2, p2);
+ //var p2 = vec2.add(body2.p, r2);
+ Physics.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ Physics.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
+ // Corrected delta vector
+ var dp = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(p2, p1, dp);
+ //var dp = vec2.sub(p2, p1);
+ // Position constraint
+ var c = Phaser.Vec2Utils.dot(dp, n) + con.depth;
+ var correction = this.clamp(Physics.Manager.CONTACT_SOLVER_BAUMGARTE * (c + Physics.Manager.CONTACT_SOLVER_COLLISION_SLOP), -Physics.Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
+ if(correction == 0) {
+ continue;
+ }
+ // We don't need max_penetration less than or equal slop
+ max_penetration = Math.max(max_penetration, -c);
+ // Compute lambda for position constraint
+ // Solve (J * invM * JT) * lambda = -C / dt
+ var sn1 = Phaser.Vec2Utils.cross(r1, n);
+ var sn2 = Phaser.Vec2Utils.cross(r2, n);
+ var em_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
+ var lambda_dt = em_inv == 0 ? 0 : -correction / em_inv;
+ // Apply correction impulses
+ var impulse_dt = new Phaser.Vec2();
+ Phaser.Vec2Utils.scale(n, lambda_dt, impulse_dt);
+ //var impulse_dt = vec2.scale(n, lambda_dt);
+ body1.position.multiplyAddByScalar(impulse_dt, -m1_inv);
+ //body1.p.mad(impulse_dt, -m1_inv);
+ body1.angle -= sn1 * lambda_dt * i1_inv;
+ body2.position.multiplyAddByScalar(impulse_dt, m2_inv);
+ //body2.p.mad(impulse_dt, m2_inv);
+ body2.angle += sn2 * lambda_dt * i2_inv;
+ Physics.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ Physics.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
+ }
+ Physics.Manager.write('max_penetration: ' + max_penetration);
+ return max_penetration <= Physics.Manager.CONTACT_SOLVER_COLLISION_SLOP * 3;
+ };
+ ContactSolver.prototype.clamp = function (v, min, max) {
+ return v < min ? min : (v > max ? max : v);
+ };
+ return ContactSolver;
+ })();
+ Physics.ContactSolver = ContactSolver;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shape - Circle
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Circle = (function (_super) {
+ __extends(Circle, _super);
+ function Circle(radius, x, y) {
+ if (typeof x === "undefined") { x = 0; }
+ if (typeof y === "undefined") { y = 0; }
+ _super.call(this, Physics.Manager.SHAPE_TYPE_CIRCLE);
+ x = Physics.Manager.pixelsToMeters(x);
+ y = Physics.Manager.pixelsToMeters(y);
+ radius = Physics.Manager.pixelsToMeters(radius);
+ this.center = new Phaser.Vec2(x, y);
+ this.radius = radius;
+ this.tc = new Phaser.Vec2();
+ this.finishVerts();
+ }
+ Circle.prototype.finishVerts = function () {
+ this.radius = Math.abs(this.radius);
+ };
+ Circle.prototype.duplicate = function () {
+ return new Circle(this.center.x, this.center.y, this.radius);
+ };
+ Circle.prototype.recenter = function (c) {
+ this.center.subtract(c);
+ };
+ Circle.prototype.transform = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.center, this.center);
+ //this.center = xf.transform(this.center);
+ };
+ Circle.prototype.untransform = function (xf) {
+ Phaser.TransformUtils.untransform(xf, this.center, this.center);
+ //this.center = xf.untransform(this.center);
+ };
+ Circle.prototype.area = function () {
+ return Physics.Manager.areaForCircle(this.radius, 0);
+ };
+ Circle.prototype.centroid = function () {
+ return Phaser.Vec2Utils.clone(this.center);
+ };
+ Circle.prototype.inertia = function (mass) {
+ return Physics.Manager.inertiaForCircle(mass, this.center, this.radius, 0);
+ };
+ Circle.prototype.cacheData = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.center, this.tc);
+ //this.tc = xf.transform(this.center);
+ this.bounds.mins.setTo(this.tc.x - this.radius, this.tc.y - this.radius);
+ this.bounds.maxs.setTo(this.tc.x + this.radius, this.tc.y + this.radius);
+ };
+ Circle.prototype.pointQuery = function (p) {
+ //return vec2.distsq(this.tc, p) < (this.r * this.r);
+ return Phaser.Vec2Utils.distanceSq(this.tc, p) < (this.radius * this.radius);
+ };
+ Circle.prototype.findVertexByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ if(Phaser.Vec2Utils.distanceSq(this.tc, p) < dsq) {
+ return 0;
+ }
+ return -1;
+ };
+ Circle.prototype.distanceOnPlane = function (n, d) {
+ Phaser.Vec2Utils.dot(n, this.tc) - this.radius - d;
+ };
+ return Circle;
+ })(Phaser.Physics.Shape);
+ Shapes.Circle = Circle;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Plane
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Plane = (function () {
+ function Plane(normal, d) {
+ this.normal = normal;
+ this.d = d;
+ }
+ return Plane;
+ })();
+ Physics.Plane = Plane;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Convex Polygon
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Poly = (function (_super) {
+ __extends(Poly, _super);
+ // Verts is an optional array of objects, the objects must have public x and y properties which will be used
+ // to seed this polygon (i.e. Vec2 objects, or just straight JS objects) and must wind COUNTER clockwise
+ function Poly(verts) {
+ _super.call(this, Physics.Manager.SHAPE_TYPE_POLY);
+ this.verts = [];
+ this.planes = [];
+ this.tverts = [];
+ this.tplanes = [];
+ if(verts) {
+ for(var i = 0; i < verts.length; i++) {
+ this.verts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
+ this.tverts[i] = this.verts[i];
+ //this.tverts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
+ this.tplanes[i] = new Phaser.Physics.Plane(new Phaser.Vec2(), 0);
+ }
+ }
+ this.finishVerts();
+ }
+ Poly.prototype.finishVerts = function () {
+ if(this.verts.length < 2) {
+ this.convexity = false;
+ this.planes = [];
+ return;
+ }
+ this.convexity = true;
+ this.tverts = [];
+ this.tplanes = [];
+ // Must be counter-clockwise verts
+ for(var i = 0; i < this.verts.length; i++) {
+ var a = this.verts[i];
+ var b = this.verts[(i + 1) % this.verts.length];
+ var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
+ this.planes[i] = new Phaser.Physics.Plane(n, Phaser.Vec2Utils.dot(n, a));
+ this.tverts[i] = Phaser.Vec2Utils.clone(this.verts[i])// reference???
+ ;
+ //this.tverts[i] = this.verts[i]; // reference???
+ this.tplanes[i] = new Phaser.Physics.Plane(new Phaser.Vec2(), 0);
+ }
+ for(var i = 0; i < this.verts.length; i++) {
+ //var b = this.verts[(i + 2) % this.verts.length];
+ //var n = this.planes[i].normal;
+ //var d = this.planes[i].d;
+ if(Phaser.Vec2Utils.dot(this.planes[i].normal, this.verts[(i + 2) % this.verts.length]) - this.planes[i].d > 0) {
+ this.convexity = false;
+ }
+ }
+ };
+ Poly.prototype.duplicate = function () {
+ return new Phaser.Physics.Shapes.Poly(this.verts);
+ };
+ Poly.prototype.recenter = function (c) {
+ for(var i = 0; i < this.verts.length; i++) {
+ this.verts[i].subtract(c);
+ }
+ };
+ Poly.prototype.transform = function (xf) {
+ for(var i = 0; i < this.verts.length; i++) {
+ this.verts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
+ //this.verts[i] = xf.transform(this.verts[i]);
+ }
+ };
+ Poly.prototype.untransform = function (xf) {
+ for(var i = 0; i < this.verts.length; i++) {
+ this.verts[i] = Phaser.TransformUtils.untransform(xf, this.verts[i]);
+ //this.verts[i] = xf.untransform(this.verts[i]);
+ }
+ };
+ Poly.prototype.area = function () {
+ return Physics.Manager.areaForPoly(this.verts);
+ };
+ Poly.prototype.centroid = function () {
+ return Physics.Manager.centroidForPoly(this.verts);
+ };
+ Poly.prototype.inertia = function (mass) {
+ return Physics.Manager.inertiaForPoly(mass, this.verts, new Phaser.Vec2());
+ };
+ Poly.prototype.cacheData = function (xf) {
+ this.bounds.clear();
+ var numVerts = this.verts.length;
+ Physics.Manager.write('----------- Poly cacheData = ' + numVerts);
+ if(numVerts == 0) {
+ return;
+ }
+ for(var i = 0; i < numVerts; i++) {
+ this.tverts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
+ //this.tverts[i] = xf.transform(this.verts[i]);
+ Physics.Manager.write('tvert' + i + ' = ' + this.tverts[i].toString());
+ }
+ if(numVerts < 2) {
+ this.bounds.addPoint(this.tverts[0]);
+ return;
+ }
+ for(var i = 0; i < numVerts; i++) {
+ var a = this.tverts[i];
+ var b = this.tverts[(i + 1) % numVerts];
+ var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
+ Physics.Manager.write('a = ' + a.toString());
+ Physics.Manager.write('b = ' + b.toString());
+ Physics.Manager.write('n = ' + n.toString());
+ this.tplanes[i].normal = n;
+ this.tplanes[i].d = Phaser.Vec2Utils.dot(n, a);
+ Physics.Manager.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
+ Physics.Manager.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
+ this.bounds.addPoint(a);
+ }
+ };
+ Poly.prototype.pointQuery = function (p) {
+ if(!this.bounds.containPoint(p)) {
+ return false;
+ }
+ return this.containPoint(p);
+ };
+ Poly.prototype.findVertexByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ for(var i = 0; i < this.tverts.length; i++) {
+ if(Phaser.Vec2Utils.distanceSq(this.tverts[i], p) < dsq) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ Poly.prototype.findEdgeByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ var numVerts = this.tverts.length;
+ for(var i = 0; i < this.tverts.length; i++) {
+ var v1 = this.tverts[i];
+ var v2 = this.tverts[(i + 1) % numVerts];
+ var n = this.tplanes[i].normal;
+ var dtv1 = Phaser.Vec2Utils.cross(v1, n);
+ var dtv2 = Phaser.Vec2Utils.cross(v2, n);
+ var dt = Phaser.Vec2Utils.cross(p, n);
+ if(dt > dtv1) {
+ if(Phaser.Vec2Utils.distanceSq(v1, p) < dsq) {
+ return i;
+ }
+ } else if(dt < dtv2) {
+ if(Phaser.Vec2Utils.distanceSq(v2, p) < dsq) {
+ return i;
+ }
+ } else {
+ var dist = Phaser.Vec2Utils.dot(n, p) - Phaser.Vec2Utils.dot(n, v1);
+ if(dist * dist < dsq) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ };
+ Poly.prototype.distanceOnPlane = function (n, d) {
+ var min = 999999;
+ for(var i = 0; i < this.verts.length; i++) {
+ min = Math.min(min, Phaser.Vec2Utils.dot(n, this.tverts[i]));
+ }
+ return min - d;
+ };
+ Poly.prototype.containPoint = function (p) {
+ for(var i = 0; i < this.verts.length; i++) {
+ var plane = this.tplanes[i];
+ if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
+ return false;
+ }
+ }
+ return true;
+ };
+ Poly.prototype.containPointPartial = function (p, n) {
+ for(var i = 0; i < this.verts.length; i++) {
+ var plane = this.tplanes[i];
+ if(Phaser.Vec2Utils.dot(plane.normal, n) < 0.0001) {
+ continue;
+ }
+ if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
+ return false;
+ }
+ }
+ return true;
+ };
+ return Poly;
+ })(Phaser.Physics.Shape);
+ Shapes.Poly = Poly;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Segment
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Segment = (function (_super) {
+ __extends(Segment, _super);
+ function Segment(a, b, radius) {
+ _super.call(this, Physics.Manager.SHAPE_TYPE_SEGMENT);
+ this.a = a.duplicate();
+ this.b = b.duplicate();
+ this.radius = radius;
+ this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(b, a));
+ this.normal.normalize();
+ this.ta = new Phaser.Vec2();
+ this.tb = new Phaser.Vec2();
+ this.tn = new Phaser.Vec2();
+ this.finishVerts();
+ }
+ Segment.prototype.finishVerts = function () {
+ this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.b, this.a));
+ this.normal.normalize();
+ this.radius = Math.abs(this.radius);
+ };
+ Segment.prototype.duplicate = function () {
+ return new Phaser.Physics.Shapes.Segment(this.a, this.b, this.radius);
+ };
+ Segment.prototype.recenter = function (c) {
+ this.a.subtract(c);
+ this.b.subtract(c);
+ };
+ Segment.prototype.transform = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.a, this.a);
+ Phaser.TransformUtils.transform(xf, this.b, this.b);
+ //this.a = xf.transform(this.a);
+ //this.b = xf.transform(this.b);
+ };
+ Segment.prototype.untransform = function (xf) {
+ Phaser.TransformUtils.untransform(xf, this.a, this.a);
+ Phaser.TransformUtils.untransform(xf, this.b, this.b);
+ //this.a = xf.untransform(this.a);
+ //this.b = xf.untransform(this.b);
+ };
+ Segment.prototype.area = function () {
+ return Physics.Manager.areaForSegment(this.a, this.b, this.radius);
+ };
+ Segment.prototype.centroid = function () {
+ return Physics.Manager.centroidForSegment(this.a, this.b);
+ };
+ Segment.prototype.inertia = function (mass) {
+ return Physics.Manager.inertiaForSegment(mass, this.a, this.b);
+ };
+ Segment.prototype.cacheData = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.a, this.ta);
+ Phaser.TransformUtils.transform(xf, this.b, this.tb);
+ //this.ta = xf.transform(this.a);
+ //this.tb = xf.transform(this.b);
+ this.tn = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.tb, this.ta)).normalize();
+ var l;
+ var r;
+ var t;
+ var b;
+ if(this.ta.x < this.tb.x) {
+ l = this.ta.x;
+ r = this.tb.x;
+ } else {
+ l = this.tb.x;
+ r = this.ta.x;
+ }
+ if(this.ta.y < this.tb.y) {
+ b = this.ta.y;
+ t = this.tb.y;
+ } else {
+ b = this.tb.y;
+ t = this.ta.y;
+ }
+ this.bounds.mins.setTo(l - this.radius, b - this.radius);
+ this.bounds.maxs.setTo(r + this.radius, t + this.radius);
+ };
+ Segment.prototype.pointQuery = function (p) {
+ if(!this.bounds.containPoint(p)) {
+ return false;
+ }
+ var dn = Phaser.Vec2Utils.dot(this.tn, p) - Phaser.Vec2Utils.dot(this.ta, this.tn);
+ var dist = Math.abs(dn);
+ if(dist > this.radius) {
+ return false;
+ }
+ var dt = Phaser.Vec2Utils.cross(p, this.tn);
+ var dta = Phaser.Vec2Utils.cross(this.ta, this.tn);
+ var dtb = Phaser.Vec2Utils.cross(this.tb, this.tn);
+ if(dt <= dta) {
+ if(dt < dta - this.radius) {
+ return false;
+ }
+ return Phaser.Vec2Utils.distanceSq(this.ta, p) < (this.radius * this.radius);
+ } else if(dt > dtb) {
+ if(dt > dtb + this.radius) {
+ return false;
+ }
+ return Phaser.Vec2Utils.distanceSq(this.tb, p) < (this.radius * this.radius);
+ }
+ return true;
+ };
+ Segment.prototype.findVertexByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ if(Phaser.Vec2Utils.distanceSq(this.ta, p) < dsq) {
+ return 0;
+ }
+ if(Phaser.Vec2Utils.distanceSq(this.tb, p) < dsq) {
+ return 1;
+ }
+ return -1;
+ };
+ Segment.prototype.distanceOnPlane = function (n, d) {
+ var a = Phaser.Vec2Utils.dot(n, this.ta) - this.radius;
+ var b = Phaser.Vec2Utils.dot(n, this.tb) - this.radius;
+ return Math.min(a, b) - d;
+ };
+ return Segment;
+ })(Phaser.Physics.Shape);
+ Shapes.Segment = Segment;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Collision Handlers
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Collision = (function () {
+ function Collision() { }
+ Collision.prototype.collide = function (a, b, contacts) {
+ // Circle (a is the circle)
+ if(a.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ if(b.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ return this.circle2Circle(a, b, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ return this.circle2Segment(a, b, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ return this.circle2Poly(a, b, contacts);
+ }
+ }
+ // Segment (a is the segment)
+ if(a.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ if(b.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ return this.circle2Segment(b, a, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ return this.segment2Segment(a, b, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ return this.segment2Poly(a, b, contacts);
+ }
+ }
+ // Poly (a is the poly)
+ if(a.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ if(b.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ return this.circle2Poly(b, a, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ return this.segment2Poly(b, a, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ return this.poly2Poly(a, b, contacts);
+ }
+ }
+ };
+ Collision.prototype._circle2Circle = function (c1, r1, c2, r2, contactArr) {
+ var rmax = r1 + r2;
+ var t = new Phaser.Vec2();
+ //var t = vec2.sub(c2, c1);
+ Phaser.Vec2Utils.subtract(c2, c1, t);
+ var distsq = t.lengthSq();
+ if(distsq > rmax * rmax) {
+ return 0;
+ }
+ var dist = Math.sqrt(distsq);
+ var p = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(c1, t, 0.5 + (r1 - r2) * 0.5 / dist, p);
+ //var p = vec2.mad(c1, t, 0.5 + (r1 - r2) * 0.5 / dist);
+ var n = new Phaser.Vec2();
+ //var n = (dist != 0) ? vec2.scale(t, 1 / dist) : vec2.zero;
+ if(dist != 0) {
+ Phaser.Vec2Utils.scale(t, 1 / dist, n);
+ }
+ var d = dist - rmax;
+ contactArr.push(new Physics.Contact(p, n, d, 0));
+ return 1;
+ };
+ Collision.prototype.circle2Circle = function (circ1, circ2, contactArr) {
+ return this._circle2Circle(circ1.tc, circ1.radius, circ2.tc, circ2.radius, contactArr);
+ };
+ Collision.prototype.circle2Segment = function (circ, seg, contactArr) {
+ var rsum = circ.radius + seg.radius;
+ // Normal distance from segment
+ var dn = Phaser.Vec2Utils.dot(circ.tc, seg.tn) - Phaser.Vec2Utils.dot(seg.ta, seg.tn);
+ var dist = (dn < 0 ? dn * -1 : dn) - rsum;
+ if(dist > 0) {
+ return 0;
+ }
+ // Tangential distance along segment
+ var dt = Phaser.Vec2Utils.cross(circ.tc, seg.tn);
+ var dtMin = Phaser.Vec2Utils.cross(seg.ta, seg.tn);
+ var dtMax = Phaser.Vec2Utils.cross(seg.tb, seg.tn);
+ if(dt < dtMin) {
+ if(dt < dtMin - rsum) {
+ return 0;
+ }
+ return this._circle2Circle(circ.tc, circ.radius, seg.ta, seg.radius, contactArr);
+ } else if(dt > dtMax) {
+ if(dt > dtMax + rsum) {
+ return 0;
+ }
+ return this._circle2Circle(circ.tc, circ.radius, seg.tb, seg.radius, contactArr);
+ }
+ var n = new Phaser.Vec2();
+ if(dn > 0) {
+ n.copyFrom(seg.tn);
+ } else {
+ Phaser.Vec2Utils.negative(seg.tn, n);
+ }
+ //var n = (dn > 0) ? seg.tn : vec2.neg(seg.tn);
+ var c1 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + dist * 0.5), c1);
+ var c2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(n, c2);
+ contactArr.push(new Physics.Contact(c1, c2, dist, 0));
+ //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + dist * 0.5)), vec2.neg(n), dist, 0));
+ return 1;
+ };
+ Collision.prototype.circle2Poly = function (circ, poly, contactArr) {
+ var minDist = -999999;
+ var minIdx = -1;
+ for(var i = 0; i < poly.verts.length; i++) {
+ var plane = poly.tplanes[i];
+ var dist = Phaser.Vec2Utils.dot(circ.tc, plane.normal) - plane.d - circ.radius;
+ if(dist > 0) {
+ return 0;
+ } else if(dist > minDist) {
+ minDist = dist;
+ minIdx = i;
+ }
+ }
+ var n = poly.tplanes[minIdx].normal;
+ var a = poly.tverts[minIdx];
+ var b = poly.tverts[(minIdx + 1) % poly.verts.length];
+ var dta = Phaser.Vec2Utils.cross(a, n);
+ var dtb = Phaser.Vec2Utils.cross(b, n);
+ var dt = Phaser.Vec2Utils.cross(circ.tc, n);
+ if(dt > dta) {
+ return this._circle2Circle(circ.tc, circ.radius, a, 0, contactArr);
+ } else if(dt < dtb) {
+ return this._circle2Circle(circ.tc, circ.radius, b, 0, contactArr);
+ }
+ var c1 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + minDist * 0.5), c1);
+ var c2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(n, c2);
+ contactArr.push(new Physics.Contact(c1, c2, minDist, 0));
+ //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + minDist * 0.5)), vec2.neg(n), minDist, 0));
+ return 1;
+ };
+ Collision.prototype.segmentPointDistanceSq = function (seg, p) {
+ var w = new Phaser.Vec2();
+ var d = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(p, seg.ta, w);
+ Phaser.Vec2Utils.subtract(seg.tb, seg.ta, d);
+ //var w = vec2.sub(p, seg.ta);
+ //var d = vec2.sub(seg.tb, seg.ta);
+ var proj = w.dot(d);
+ if(proj <= 0) {
+ return w.dot(w);
+ }
+ var vsq = d.dot(d);
+ if(proj >= vsq) {
+ return w.dot(w) - 2 * proj + vsq;
+ }
+ return w.dot(w) - proj * proj / vsq;
+ };
+ Collision.prototype.segment2Segment = // FIXME and optimise me lots!!!
+ function (seg1, seg2, contactArr) {
+ var d = [];
+ d[0] = this.segmentPointDistanceSq(seg1, seg2.ta);
+ d[1] = this.segmentPointDistanceSq(seg1, seg2.tb);
+ d[2] = this.segmentPointDistanceSq(seg2, seg1.ta);
+ d[3] = this.segmentPointDistanceSq(seg2, seg1.tb);
+ var idx1 = d[0] < d[1] ? 0 : 1;
+ var idx2 = d[2] < d[3] ? 2 : 3;
+ var idxm = d[idx1] < d[idx2] ? idx1 : idx2;
+ var s, t;
+ var u = Phaser.Vec2Utils.subtract(seg1.tb, seg1.ta);
+ var v = Phaser.Vec2Utils.subtract(seg2.tb, seg2.ta);
+ switch(idxm) {
+ case 0:
+ s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.ta, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
+ s = s < 0 ? 0 : (s > 1 ? 1 : s);
+ t = 0;
+ break;
+ case 1:
+ s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.tb, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
+ s = s < 0 ? 0 : (s > 1 ? 1 : s);
+ t = 1;
+ break;
+ case 2:
+ s = 0;
+ t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.ta, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
+ t = t < 0 ? 0 : (t > 1 ? 1 : t);
+ break;
+ case 3:
+ s = 1;
+ t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.tb, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
+ t = t < 0 ? 0 : (t > 1 ? 1 : t);
+ break;
+ }
+ var minp1 = Phaser.Vec2Utils.multiplyAdd(seg1.ta, u, s);
+ var minp2 = Phaser.Vec2Utils.multiplyAdd(seg2.ta, v, t);
+ return this._circle2Circle(minp1, seg1.radius, minp2, seg2.radius, contactArr);
+ };
+ Collision.prototype.findPointsBehindSeg = // Identify vertexes that have penetrated the segment.
+ function (contactArr, seg, poly, dist, coef) {
+ var dta = Phaser.Vec2Utils.cross(seg.tn, seg.ta);
+ var dtb = Phaser.Vec2Utils.cross(seg.tn, seg.tb);
+ var n = new Phaser.Vec2();
+ Phaser.Vec2Utils.scale(seg.tn, coef, n);
+ //var n = vec2.scale(seg.tn, coef);
+ for(var i = 0; i < poly.verts.length; i++) {
+ var v = poly.tverts[i];
+ if(Phaser.Vec2Utils.dot(v, n) < Phaser.Vec2Utils.dot(seg.tn, seg.ta) * coef + seg.radius) {
+ var dt = Phaser.Vec2Utils.cross(seg.tn, v);
+ if(dta >= dt && dt >= dtb) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly.id << 16) | i));
+ }
+ }
+ }
+ };
+ Collision.prototype.segment2Poly = function (seg, poly, contactArr) {
+ var seg_td = Phaser.Vec2Utils.dot(seg.tn, seg.ta);
+ var seg_d1 = poly.distanceOnPlane(seg.tn, seg_td) - seg.radius;
+ if(seg_d1 > 0) {
+ return 0;
+ }
+ var n = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(seg.tn, n);
+ var seg_d2 = poly.distanceOnPlane(n, -seg_td) - seg.radius;
+ //var seg_d2 = poly.distanceOnPlane(vec2.neg(seg.tn), -seg_td) - seg.r;
+ if(seg_d2 > 0) {
+ return 0;
+ }
+ var poly_d = -999999;
+ var poly_i = -1;
+ for(var i = 0; i < poly.verts.length; i++) {
+ var plane = poly.tplanes[i];
+ var dist = seg.distanceOnPlane(plane.normal, plane.d);
+ if(dist > 0) {
+ return 0;
+ }
+ if(dist > poly_d) {
+ poly_d = dist;
+ poly_i = i;
+ }
+ }
+ var poly_n = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(poly.tplanes[poly_i].normal, poly_n);
+ //var poly_n = vec2.neg(poly.tplanes[poly_i].n);
+ var va = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(seg.ta, poly_n, seg.radius, va);
+ //var va = vec2.mad(seg.ta, poly_n, seg.r);
+ var vb = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(seg.tb, poly_n, seg.radius, vb);
+ //var vb = vec2.mad(seg.tb, poly_n, seg.r);
+ if(poly.containPoint(va)) {
+ contactArr.push(new Physics.Contact(va, poly_n, poly_d, (seg.id << 16) | 0));
+ }
+ if(poly.containPoint(vb)) {
+ contactArr.push(new Physics.Contact(vb, poly_n, poly_d, (seg.id << 16) | 1));
+ }
+ // Floating point precision problems here.
+ // This will have to do for now.
+ poly_d -= 0.1;
+ if(seg_d1 >= poly_d || seg_d2 >= poly_d) {
+ if(seg_d1 > seg_d2) {
+ this.findPointsBehindSeg(contactArr, seg, poly, seg_d1, 1);
+ } else {
+ this.findPointsBehindSeg(contactArr, seg, poly, seg_d2, -1);
+ }
+ }
+ // If no other collision points are found, try colliding endpoints.
+ if(contactArr.length == 0) {
+ var poly_a = poly.tverts[poly_i];
+ var poly_b = poly.tverts[(poly_i + 1) % poly.verts.length];
+ if(this._circle2Circle(seg.ta, seg.radius, poly_a, 0, contactArr)) {
+ return 1;
+ }
+ if(this._circle2Circle(seg.tb, seg.radius, poly_a, 0, contactArr)) {
+ return 1;
+ }
+ if(this._circle2Circle(seg.ta, seg.radius, poly_b, 0, contactArr)) {
+ return 1;
+ }
+ if(this._circle2Circle(seg.tb, seg.radius, poly_b, 0, contactArr)) {
+ return 1;
+ }
+ }
+ return contactArr.length;
+ };
+ Collision.prototype.findMSA = // Find the minimum separating axis for the given poly and plane list.
+ function (poly, planes, num) {
+ var min_dist = -999999;
+ var min_index = -1;
+ for(var i = 0; i < num; i++) {
+ var dist = poly.distanceOnPlane(planes[i].normal, planes[i].d);
+ if(dist > 0) {
+ // no collision
+ return {
+ dist: 0,
+ index: -1
+ };
+ } else if(dist > min_dist) {
+ min_dist = dist;
+ min_index = i;
+ }
+ }
+ // new object - see what we can do here
+ return {
+ dist: min_dist,
+ index: min_index
+ };
+ };
+ Collision.prototype.findVertsFallback = function (contactArr, poly1, poly2, n, dist) {
+ var num = 0;
+ for(var i = 0; i < poly1.verts.length; i++) {
+ var v = poly1.tverts[i];
+ if(poly2.containPointPartial(v, n)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly1.id << 16) | i));
+ num++;
+ }
+ }
+ for(var i = 0; i < poly2.verts.length; i++) {
+ var v = poly2.tverts[i];
+ if(poly1.containPointPartial(v, n)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly2.id << 16) | i));
+ num++;
+ }
+ }
+ return num;
+ };
+ Collision.prototype.findVerts = // Find the overlapped vertices.
+ function (contactArr, poly1, poly2, n, dist) {
+ var num = 0;
+ for(var i = 0; i < poly1.verts.length; i++) {
+ var v = poly1.tverts[i];
+ if(poly2.containPoint(v)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly1.id << 16) | i));
+ num++;
+ }
+ }
+ for(var i = 0; i < poly2.verts.length; i++) {
+ var v = poly2.tverts[i];
+ if(poly1.containPoint(v)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly2.id << 16) | i));
+ num++;
+ }
+ }
+ return num > 0 ? num : this.findVertsFallback(contactArr, poly1, poly2, n, dist);
+ };
+ Collision.prototype.poly2Poly = function (poly1, poly2, contactArr) {
+ var msa1 = this.findMSA(poly2, poly1.tplanes, poly1.verts.length);
+ if(msa1.index == -1) {
+ console.log('poly2poly 0', msa1);
+ return 0;
+ }
+ var msa2 = this.findMSA(poly1, poly2.tplanes, poly2.verts.length);
+ if(msa2.index == -1) {
+ console.log('poly2poly 1', msa2);
+ return 0;
+ }
+ // Penetration normal direction should be from poly1 to poly2
+ if(msa1.dist > msa2.dist) {
+ return this.findVerts(contactArr, poly1, poly2, poly1.tplanes[msa1.index].normal, msa1.dist);
+ }
+ return this.findVerts(contactArr, poly1, poly2, Phaser.Vec2Utils.negative(poly2.tplanes[msa2.index].normal), msa2.dist);
+ };
+ return Collision;
+ })();
+ Physics.Collision = Collision;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ })(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Space
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Space = (function () {
+ function Space(manager) {
+ this.postSolve = null;
+ this.stepCount = 0;
+ this._manager = manager;
+ this.bodies = [];
+ this.bodyHash = {
+ };
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.numContacts = 0;
+ this.contactSolvers = [];
+ this.gravity = this._manager.gravity;
+ this.damping = 0;
+ this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE;
+ this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE;
+ }
+ Space.TIME_TO_SLEEP = 0.5;
+ Space.SLEEP_LINEAR_TOLERANCE = 0.5;
+ Space.SLEEP_ANGULAR_TOLERANCE = 2 * 0.017453292519943294444444444444444;
+ Space.prototype.clear = function () {
+ Physics.Manager.shapeCounter = 0;
+ Physics.Manager.bodyCounter = 0;
+ Physics.Manager.jointCounter = 0;
+ for(var i = 0; i < this.bodies.length; i++) {
+ if(this.bodies[i]) {
+ this.removeBody(this.bodies[i]);
+ }
+ }
+ this.bodies = [];
+ this.bodyHash = {
+ };
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.contactSolvers = [];
+ this.stepCount = 0;
+ };
+ Space.prototype.addBody = function (body) {
+ if(this.bodyHash[body.id] != undefined) {
+ return;
+ }
+ var index = this.bodies.push(body) - 1;
+ this.bodyHash[body.id] = index;
+ body.awake(true);
+ body.space = this;
+ body.cacheData('addBody');
+ };
+ Space.prototype.removeBody = function (body) {
+ if(this.bodyHash[body.id] == undefined) {
+ return;
+ }
+ // Remove linked joints
+ for(var i = 0; i < body.joints.length; i++) {
+ if(body.joints[i]) {
+ this.removeJoint(body.joints[i]);
+ }
+ }
+ body.space = null;
+ var index = this.bodyHash[body.id];
+ delete this.bodyHash[body.id];
+ delete this.bodies[index];
+ };
+ Space.prototype.addJoint = function (joint) {
+ if(this.jointHash[joint.id] != undefined) {
+ return;
+ }
+ joint.body1.awake(true);
+ joint.body2.awake(true);
+ var index = this.joints.push(joint) - 1;
+ this.jointHash[joint.id] = index;
+ var index = joint.body1.joints.push(joint) - 1;
+ joint.body1.jointHash[joint.id] = index;
+ var index = joint.body2.joints.push(joint) - 1;
+ joint.body2.jointHash[joint.id] = index;
+ };
+ Space.prototype.removeJoint = function (joint) {
+ if(this.jointHash[joint.id] == undefined) {
+ return;
+ }
+ joint.body1.awake(true);
+ joint.body2.awake(true);
+ var index = joint.body1.jointHash[joint.id];
+ delete joint.body1.jointHash[joint.id];
+ delete joint.body1.joints[index];
+ var index = joint.body2.jointHash[joint.id];
+ delete joint.body2.jointHash[joint.id];
+ delete joint.body2.joints[index];
+ var index = this.jointHash[joint.id];
+ delete this.jointHash[joint.id];
+ delete this.joints[index];
+ };
+ Space.prototype.findShapeByPoint = function (p, refShape) {
+ var firstShape;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ if(shape.pointQuery(p)) {
+ if(!refShape) {
+ return shape;
+ }
+ if(!firstShape) {
+ firstShape = shape;
+ }
+ if(shape == refShape) {
+ refShape = null;
+ }
+ }
+ }
+ }
+ return firstShape;
+ };
+ Space.prototype.findBodyByPoint = function (p, refBody) {
+ var firstBody;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ if(shape.pointQuery(p)) {
+ if(!refBody) {
+ return shape.body;
+ }
+ if(!firstBody) {
+ firstBody = shape.body;
+ }
+ if(shape.body == refBody) {
+ refBody = null;
+ }
+ break;
+ }
+ }
+ }
+ return firstBody;
+ };
+ Space.prototype.shapeById = function (id) {
+ var shape;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ if(body.shapes[j].id == id) {
+ return body.shapes[j];
+ }
+ }
+ }
+ return null;
+ };
+ Space.prototype.jointById = function (id) {
+ var index = this.jointHash[id];
+ if(index != undefined) {
+ return this.joints[index];
+ }
+ return null;
+ };
+ Space.prototype.findVertexByPoint = function (p, minDist, refVertexId) {
+ var firstVertexId = -1;
+ refVertexId = refVertexId || -1;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ var index = shape.findVertexByPoint(p, minDist);
+ if(index != -1) {
+ var vertex = (shape.id << 16) | index;
+ if(refVertexId == -1) {
+ return vertex;
+ }
+ if(firstVertexId == -1) {
+ firstVertexId = vertex;
+ }
+ if(vertex == refVertexId) {
+ refVertexId = -1;
+ }
+ }
+ }
+ }
+ return firstVertexId;
+ };
+ Space.prototype.findEdgeByPoint = function (p, minDist, refEdgeId) {
+ var firstEdgeId = -1;
+ refEdgeId = refEdgeId || -1;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ if(shape.type != Physics.Manager.SHAPE_TYPE_POLY) {
+ continue;
+ }
+ var index = shape.findEdgeByPoint(p, minDist);
+ if(index != -1) {
+ var edge = (shape.id << 16) | index;
+ if(refEdgeId == -1) {
+ return edge;
+ }
+ if(firstEdgeId == -1) {
+ firstEdgeId = edge;
+ }
+ if(edge == refEdgeId) {
+ refEdgeId = -1;
+ }
+ }
+ }
+ }
+ return firstEdgeId;
+ };
+ Space.prototype.findJointByPoint = function (p, minDist, refJointId) {
+ var firstJointId = -1;
+ var dsq = minDist * minDist;
+ refJointId = refJointId || -1;
+ for(var i = 0; i < this.joints.length; i++) {
+ var joint = this.joints[i];
+ if(!joint) {
+ continue;
+ }
+ var jointId = -1;
+ if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor1()) < dsq) {
+ jointId = (joint.id << 16 | 0);
+ } else if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor2()) < dsq) {
+ jointId = (joint.id << 16 | 1);
+ }
+ if(jointId != -1) {
+ if(refJointId == -1) {
+ return jointId;
+ }
+ if(firstJointId == -1) {
+ firstJointId = jointId;
+ }
+ if(jointId == refJointId) {
+ refJointId = -1;
+ }
+ }
+ }
+ return firstJointId;
+ };
+ Space.prototype.findContactSolver = function (shape1, shape2) {
+ Physics.Manager.write('findContactSolver. Length: ' + this._cl);
+ for(var i = 0; i < this._cl; i++) {
+ var contactSolver = this.contactSolvers[i];
+ if(shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) {
+ return contactSolver;
+ }
+ }
+ return null;
+ };
+ Space.prototype.genTemporalContactSolvers = function () {
+ Physics.Manager.write('genTemporalContactSolvers');
+ this._cl = 0;
+ this.contactSolvers.length = 0;
+ this.numContacts = 0;
+ for(var body1Index = 0; body1Index < this._bl; body1Index++) {
+ if(!this.bodies[body1Index]) {
+ continue;
+ }
+ this.bodies[body1Index].stepCount = this.stepCount;
+ for(var body2Index = 0; body2Index < this._bl; body2Index++) {
+ if(this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) {
+ continue;
+ }
+ Physics.Manager.write('body1 and body2 intersect');
+ for(var i = 0; i < this.bodies[body1Index].shapesLength; i++) {
+ for(var j = 0; j < this.bodies[body2Index].shapesLength; j++) {
+ this._shape1 = this.bodies[body1Index].shapes[i];
+ this._shape2 = this.bodies[body2Index].shapes[j];
+ var contactArr = [];
+ if(!Physics.Manager.collision.collide(this._shape1, this._shape2, contactArr)) {
+ continue;
+ }
+ if(this._shape1.type > this._shape2.type) {
+ var temp = this._shape1;
+ this._shape1 = this._shape2;
+ this._shape2 = temp;
+ }
+ this.numContacts += contactArr.length;
+ // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers)
+ var contactSolver = this.findContactSolver(this._shape1, this._shape2);
+ Physics.Manager.write('findContactSolver result: ' + contactSolver);
+ if(contactSolver) {
+ contactSolver.update(contactArr);
+ this.contactSolvers.push(contactSolver);
+ } else {
+ Physics.Manager.write('awake both bodies');
+ this.bodies[body1Index].awake(true);
+ this.bodies[body2Index].awake(true);
+ var newContactSolver = new Physics.ContactSolver(this._shape1, this._shape2);
+ newContactSolver.contacts = contactArr;
+ newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity);
+ newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction);
+ this.contactSolvers.push(newContactSolver);
+ Physics.Manager.write('new contact solver');
+ }
+ }
+ }
+ }
+ }
+ this._cl = this.contactSolvers.length;
+ };
+ Space.prototype.initSolver = function (warmStarting) {
+ Physics.Manager.write('initSolver');
+ Physics.Manager.write('contactSolvers.length: ' + this._cl);
+ // Initialize contact solvers
+ for(var c = 0; c < this._cl; c++) {
+ this.contactSolvers[c].initSolver(this._deltaInv);
+ // Warm starting (apply cached impulse)
+ if(warmStarting) {
+ this.contactSolvers[c].warmStart();
+ }
+ }
+ // Initialize joint solver
+ for(var j = 0; j < this.joints.length; j++) {
+ if(this.joints[j]) {
+ this.joints[j].initSolver(this._delta, warmStarting);
+ }
+ }
+ // Warm starting (apply cached impulse)
+ /*
+ if (warmStarting)
+ {
+ for (var c = 0; c < this._cl; c++)
+ {
+ this.contactSolvers[c].warmStart();
+ }
+ }
+ */
+ };
+ Space.prototype.velocitySolver = function (iterations) {
+ Physics.Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl);
+ for(var i = 0; i < iterations; i++) {
+ for(var j = 0; j < this._jl; j++) {
+ if(this.joints[j]) {
+ this.joints[j].solveVelocityConstraints();
+ }
+ }
+ for(var c = 0; c < this._cl; c++) {
+ this.contactSolvers[c].solveVelocityConstraints();
+ }
+ }
+ };
+ Space.prototype.positionSolver = function (iterations) {
+ this._positionSolved = false;
+ for(var i = 0; i < iterations; i++) {
+ this._contactsOk = true;
+ this._jointsOk = true;
+ for(var c = 0; c < this._cl; c++) {
+ this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk;
+ }
+ for(var j = 0; j < this._jl; j++) {
+ if(this.joints[j]) {
+ this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk;
+ }
+ }
+ if(this._contactsOk && this._jointsOk) {
+ // exit early if the position errors are small
+ this._positionSolved = true;
+ break;
+ }
+ }
+ return this._positionSolved;
+ };
+ Space.prototype.step = // Step through the physics simulation
+ function (dt, velocityIterations, positionIterations, warmStarting, allowSleep) {
+ Physics.Manager.clear();
+ Physics.Manager.write('Space step ' + this.stepCount);
+ this._delta = dt;
+ this._deltaInv = 1 / dt;
+ this._bl = this.bodies.length;
+ this._jl = this.joints.length;
+ this.stepCount++;
+ // 1) Generate Contact Solvers (into the this.contactSolvers array)
+ this.genTemporalContactSolvers();
+ Physics.Manager.dump("Contact Solvers", this.bodies[1]);
+ // 2) Initialize the Contact Solvers
+ this.initSolver(warmStarting);
+ Physics.Manager.dump("Init Solver", this.bodies[1]);
+ // 3) Intergrate velocity
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
+ this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping);
+ }
+ }
+ Physics.Manager.dump("Update Velocity", this.bodies[1]);
+ // 4) Awaken bodies via joints
+ for(var j = 0; i < this._jl; j++) {
+ if(!this.joints[j]) {
+ continue;
+ }
+ // combine
+ var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic;
+ var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic;
+ if(awake1 ^ awake2) {
+ if(!awake1) {
+ this.joints[j].body1.awake(true);
+ }
+ if(!awake2) {
+ this.joints[j].body2.awake(true);
+ }
+ }
+ }
+ // 5) Iterative velocity constraints solver
+ this.velocitySolver(velocityIterations);
+ Physics.Manager.dump("Velocity Solvers", this.bodies[1]);
+ // 6) Intergrate position
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
+ this.bodies[i].updatePosition(this._delta);
+ }
+ }
+ Physics.Manager.dump("Update Position", this.bodies[1]);
+ // 7) Process breakable joint
+ for(var i = 0; i < this._jl; i++) {
+ if(this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) {
+ this.removeJoint(this.joints[i]);
+ }
+ }
+ // 8) Iterative position constraints solver (result stored in this._positionSolved)
+ this.positionSolver(positionIterations);
+ Physics.Manager.dump("Position Solver", this.bodies[1]);
+ // 9) Sync the Transforms
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i]) {
+ this.bodies[i].syncTransform();
+ }
+ }
+ Physics.Manager.dump("Sync Transform", this.bodies[1]);
+ // 10) Post solve collision callback
+ if(this.postSolve) {
+ for(var i = 0; i < this._cl; i++) {
+ this.postSolve(this.contactSolvers[i]);
+ }
+ }
+ // 11) Cache Body Data
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
+ this.bodies[i].cacheData('post solve collision callback');
+ }
+ }
+ Physics.Manager.dump("Cache Data", this.bodies[1]);
+ Physics.Manager.writeAll();
+ // 12) Process sleeping
+ if(allowSleep) {
+ this._minSleepTime = 999999;
+ for(var i = 0; i < this._bl; i++) {
+ if(!this.bodies[i] || this.bodies[i].isDynamic == false) {
+ continue;
+ }
+ if(this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) {
+ this.bodies[i].sleepTime = 0;
+ this._minSleepTime = 0;
+ } else {
+ this.bodies[i].sleepTime += this._delta;
+ this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime);
+ }
+ }
+ if(this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) {
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i]) {
+ this.bodies[i].awake(false);
+ }
+ }
+ }
+ }
+ };
+ return Space;
+ })();
+ Physics.Space = Space;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Triangle
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Triangle = (function (_super) {
+ __extends(Triangle, _super);
+ function Triangle(x1, y1, x2, y2, x3, y3) {
+ x1 = Physics.Manager.pixelsToMeters(x1);
+ y1 = Physics.Manager.pixelsToMeters(y1);
+ x2 = Physics.Manager.pixelsToMeters(x2);
+ y2 = Physics.Manager.pixelsToMeters(y2);
+ x3 = Physics.Manager.pixelsToMeters(x3);
+ y3 = Physics.Manager.pixelsToMeters(y3);
+ _super.call(this, [
+ {
+ x: x1,
+ y: y1
+ },
+ {
+ x: x2,
+ y: y2
+ },
+ {
+ x: x3,
+ y: y3
+ }
+ ]);
+ }
+ return Triangle;
+ })(Phaser.Physics.Shapes.Poly);
+ Shapes.Triangle = Triangle;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Box
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Box = (function (_super) {
+ __extends(Box, _super);
+ // Give in pixels
+ function Box(x, y, width, height) {
+ x = Physics.Manager.pixelsToMeters(x);
+ y = Physics.Manager.pixelsToMeters(y);
+ width = Physics.Manager.pixelsToMeters(width);
+ height = Physics.Manager.pixelsToMeters(height);
+ var hw = width * 0.5;
+ var hh = height * 0.5;
+ _super.call(this, [
+ {
+ x: -hw + x,
+ y: +hh + y
+ },
+ {
+ x: -hw + x,
+ y: -hh + y
+ },
+ {
+ x: +hw + x,
+ y: -hh + y
+ },
+ {
+ x: +hw + x,
+ y: +hh + y
+ }
+ ]);
+ }
+ return Box;
+ })(Phaser.Physics.Shapes.Poly);
+ Shapes.Box = Box;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Body
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
*/
(function (Physics) {
var Body = (function () {
- function Body(sprite, type) {
- this.angularVelocity = 0;
- this.angularAcceleration = 0;
- this.angularDrag = 0;
- this.maxAngular = 10000;
- this.mass = 1;
- this._width = 0;
- this._height = 0;
- this.sprite = sprite;
- this.game = sprite.game;
+ function Body(sprite, type, x, y, shapeType) {
+ if (typeof x === "undefined") { x = 0; }
+ if (typeof y === "undefined") { y = 0; }
+ if (typeof shapeType === "undefined") { shapeType = 0; }
+ this._tempVec2 = new Phaser.Vec2();
+ // Shapes
+ this.shapes = [];
+ // Joints
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.fixedRotation = false;
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+ this.stepCount = 0;
+ this.id = Phaser.Physics.Manager.bodyCounter++;
+ this.name = 'body' + this.id;
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();
- this._width = sprite.width;
- this._height = sprite.height;
- // Body properties
- this.gravity = Phaser.Vec2Utils.clone(this.game.world.physics.gravity);
- this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce);
+ if(sprite) {
+ this.sprite = sprite;
+ this.game = sprite.game;
+ this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Manager.pixelsToMeters(sprite.y));
+ this.angle = sprite.rotation;
+ } else {
+ this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(x), Phaser.Physics.Manager.pixelsToMeters(y));
+ this.angle = 0;
+ }
+ this.transform = new Phaser.Transform(this.position, this.angle);
+ this.centroid = new Phaser.Vec2();
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.force = new Phaser.Vec2();
this.angularVelocity = 0;
- this.angularAcceleration = 0;
- this.angularDrag = 0;
- this.touching = Phaser.Types.NONE;
- this.wasTouching = Phaser.Types.NONE;
+ this.torque = 0;
+ this.linearDamping = 0;
+ this.angularDamping = 0;
+ this.sleepTime = 0;
+ this.awaked = false;
+ this.shapes = [];
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.bounds = new Physics.Bounds();
this.allowCollisions = Phaser.Types.ANY;
- this.position = new Phaser.Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight);
- this.oldPosition = new Phaser.Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight);
- this.offset = new Phaser.Vec2();
+ this.fixedRotation = false;
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+ this.stepCount = 0;
+ if(sprite) {
+ if(shapeType == 0) {
+ this.addBox(0, 0, this.sprite.width, this.sprite.height, 1, 1, 1);
+ } else {
+ this.addCircle(Math.max(this.sprite.width, this.sprite.height) / 2, 0, 0, 1, 1, 1);
+ }
+ }
}
- Object.defineProperty(Body.prototype, "x", {
- get: function () {
- return this.sprite.x + this.offset.x;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "y", {
- get: function () {
- return this.sprite.y + this.offset.y;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "width", {
- get: function () {
- return this._width * this.sprite.transform.scale.x;
- },
- set: function (value) {
- this._width = value;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "height", {
- get: function () {
- return this._height * this.sprite.transform.scale.y;
- },
- set: function (value) {
- this._height = value;
- },
- enumerable: true,
- configurable: true
- });
- Body.prototype.preUpdate = function () {
- this.oldPosition.copyFrom(this.position);
- this.bounds.x = this.x;
- this.bounds.y = this.y;
- this.bounds.width = this.width;
- this.bounds.height = this.height;
+ Body.prototype.toString = function () {
+ return "[{Body (name=" + this.name + " velocity=" + this.velocity.toString() + " angularVelocity: " + this.angularVelocity + ")}]";
};
- 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.game.world.physics.updateMotion(this);
- this.wasTouching = this.touching;
- this.touching = Phaser.Types.NONE;
+ Body.prototype.duplicate = function () {
+ console.log('body duplicate called');
+ //var body = new Body(this.type, this.transform.t, this.angle);
+ //for (var i = 0; i < this.shapes.length; i++)
+ //{
+ // body.addShape(this.shapes[i].duplicate());
+ //}
+ //body.resetMassData();
+ //return body;
+ };
+ Object.defineProperty(Body.prototype, "isDisabled", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_DISABLED ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "isStatic", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_STATIC ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "isKinetic", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_KINETIC ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "isDynamic", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Body.prototype.setType = function (type) {
+ if(type == this.type) {
+ return;
}
- this.position.setTo(this.x, this.y);
+ this.force.setTo(0, 0);
+ this.velocity.setTo(0, 0);
+ this.torque = 0;
+ this.angularVelocity = 0;
+ this.type = type;
+ this.awake(true);
};
- 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();
+ Body.prototype.addPoly = function (verts, elasticity, friction, density) {
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var poly = new Phaser.Physics.Shapes.Poly(verts);
+ poly.elasticity = elasticity;
+ poly.friction = friction;
+ poly.density = density;
+ this.addShape(poly);
+ this.resetMassData();
+ return poly;
+ };
+ Body.prototype.addTriangle = function (x1, y1, x2, y2, x3, y3, elasticity, friction, density) {
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var tri = new Phaser.Physics.Shapes.Triangle(x1, y1, x2, y2, x3, y3);
+ tri.elasticity = elasticity;
+ tri.friction = friction;
+ tri.density = density;
+ this.addShape(tri);
+ this.resetMassData();
+ return tri;
+ };
+ Body.prototype.addBox = function (x, y, width, height, elasticity, friction, density) {
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var box = new Phaser.Physics.Shapes.Box(x, y, width, height);
+ box.elasticity = elasticity;
+ box.friction = friction;
+ box.density = density;
+ this.addShape(box);
+ this.resetMassData();
+ return box;
+ };
+ Body.prototype.addCircle = function (radius, x, y, elasticity, friction, density) {
+ if (typeof x === "undefined") { x = 0; }
+ if (typeof y === "undefined") { y = 0; }
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var circle = new Phaser.Physics.Shapes.Circle(radius, x, y);
+ circle.elasticity = elasticity;
+ circle.friction = friction;
+ circle.density = density;
+ this.addShape(circle);
+ this.resetMassData();
+ return circle;
+ };
+ Body.prototype.addShape = function (shape) {
+ // Check not already part of this body
+ shape.body = this;
+ this.shapes.push(shape);
+ this.shapesLength = this.shapes.length;
+ return shape;
+ };
+ Body.prototype.removeShape = function (shape) {
+ var index = this.shapes.indexOf(shape);
+ if(index != -1) {
+ this.shapes.splice(index, 1);
+ shape.body = undefined;
}
- 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();
+ this.shapesLength = this.shapes.length;
+ };
+ Body.prototype.setMass = function (mass) {
+ this.mass = mass;
+ this.massInverted = mass > 0 ? 1 / mass : 0;
+ };
+ Body.prototype.setInertia = function (inertia) {
+ this.inertia = inertia;
+ this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
+ };
+ Body.prototype.setTransform = function (pos, angle) {
+ // inject the transform into this.position
+ this.transform.setTo(pos, angle);
+ Physics.Manager.write('setTransform: ' + this.position.toString());
+ Physics.Manager.write('centroid: ' + this.centroid.toString());
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ Physics.Manager.write('post setTransform: ' + this.position.toString());
+ //this.position.copyFrom(this.transform.transform(this.centroid));
+ this.angle = angle;
+ };
+ Body.prototype.syncTransform = function () {
+ Physics.Manager.write('syncTransform:');
+ Physics.Manager.write('p: ' + this.position.toString());
+ Physics.Manager.write('centroid: ' + this.centroid.toString());
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ Physics.Manager.write('a: ' + this.angle);
+ this.transform.setRotation(this.angle);
+ // OPTIMISE: Creating new vector
+ Phaser.Vec2Utils.subtract(this.position, Phaser.TransformUtils.rotate(this.transform, this.centroid), this.transform.t);
+ Physics.Manager.write('--------------------');
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ Physics.Manager.write('--------------------');
+ };
+ Body.prototype.getWorldPoint = function (p) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.transform(this.transform, p);
+ };
+ Body.prototype.getWorldVector = function (v) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.rotate(this.transform, v);
+ };
+ Body.prototype.getLocalPoint = function (p) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.untransform(this.transform, p);
+ };
+ Body.prototype.getLocalVector = function (v) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.unrotate(this.transform, v);
+ };
+ Body.prototype.setFixedRotation = function (flag) {
+ this.fixedRotation = flag;
+ this.resetMassData();
+ };
+ Body.prototype.resetMassData = function () {
+ this.centroid.setTo(0, 0);
+ this.mass = 0;
+ this.massInverted = 0;
+ this.inertia = 0;
+ this.inertiaInverted = 0;
+ if(this.isDynamic == false) {
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ //this.position.copyFrom(this.transform.transform(this.centroid));
+ return;
}
- 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();
+ var totalMassCentroid = new Phaser.Vec2(0, 0);
+ var totalMass = 0;
+ var totalInertia = 0;
+ for(var i = 0; i < this.shapes.length; i++) {
+ var shape = this.shapes[i];
+ var centroid = shape.centroid();
+ var mass = shape.area() * shape.density;
+ var inertia = shape.inertia(mass);
+ //console.log('rmd', centroid, shape);
+ totalMassCentroid.multiplyAddByScalar(centroid, mass);
+ totalMass += mass;
+ totalInertia += inertia;
}
- 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();
+ //this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
+ Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
+ this.setMass(totalMass);
+ if(!this.fixedRotation) {
+ this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
+ }
+ // Move center of mass
+ var oldPosition = Phaser.Vec2Utils.clone(this.position);
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ // Update center of mass velocity
+ oldPosition.subtract(this.position);
+ this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
+ };
+ Body.prototype.resetJointAnchors = function () {
+ for(var i = 0; i < this.joints.length; i++) {
+ var joint = this.joints[i];
+ if(!joint) {
+ continue;
+ }
+ var anchor1 = joint.getWorldAnchor1();
+ var anchor2 = joint.getWorldAnchor2();
+ joint.setWorldAnchor1(anchor1);
+ joint.setWorldAnchor2(anchor2);
}
};
- 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.sprite.texture.context.fillStyle = color;
- this.sprite.texture.context.fillText('Sprite: (' + this.sprite.width + ' x ' + this.sprite.height + ')', x, y);
- //this.sprite.texture.context.fillText('x: ' + this._sprite.frameBounds.x.toFixed(1) + ' y: ' + this._sprite.frameBounds.y.toFixed(1) + ' rotation: ' + this._sprite.rotation.toFixed(1), x, y + 14);
- this.sprite.texture.context.fillText('x: ' + this.bounds.x.toFixed(1) + ' y: ' + this.bounds.y.toFixed(1) + ' rotation: ' + this.sprite.transform.rotation.toFixed(0), x, y + 14);
- this.sprite.texture.context.fillText('vx: ' + this.velocity.x.toFixed(1) + ' vy: ' + this.velocity.y.toFixed(1), x, y + 28);
- this.sprite.texture.context.fillText('acx: ' + this.acceleration.x.toFixed(1) + ' acy: ' + this.acceleration.y.toFixed(1), x, y + 42);
- this.sprite.texture.context.fillText('angVx: ' + this.angularVelocity.toFixed(1) + ' angAc: ' + this.angularAcceleration.toFixed(1), x, y + 56);
+ Body.prototype.cacheData = function (source) {
+ if (typeof source === "undefined") { source = ''; }
+ Physics.Manager.write('cacheData -- start');
+ Physics.Manager.write('p: ' + this.position.toString());
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ this.bounds.clear();
+ for(var i = 0; i < this.shapes.length; i++) {
+ var shape = this.shapes[i];
+ shape.cacheData(this.transform);
+ this.bounds.addBounds(shape.bounds);
+ }
+ Physics.Manager.write('bounds: ' + this.bounds.toString());
+ Physics.Manager.write('p: ' + this.position.toString());
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ Physics.Manager.write('cacheData -- stop');
+ };
+ Body.prototype.updateVelocity = function (gravity, dt, damping) {
+ Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
+ Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
+ this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
+ // Apply damping.
+ // ODE: dv/dt + c * v = 0
+ // Solution: v(t) = v0 * exp(-c * t)
+ // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
+ // v2 = exp(-c * dt) * v1
+ // Taylor expansion:
+ // v2 = (1.0f - c * dt) * v1
+ this.velocity.scale(this.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
+ this.angularVelocity *= this.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ };
+ Body.prototype.inContact = function (body2) {
+ if(!body2 || this.stepCount == body2.stepCount) {
+ return false;
+ }
+ if(!(this.isAwake && this.isStatic == false) && !(body2.isAwake && body2.isStatic == false)) {
+ return false;
+ }
+ if(this.isCollidable(body2) == false) {
+ return false;
+ }
+ if(!this.bounds.intersectsBounds(body2.bounds)) {
+ return false;
+ }
+ return true;
+ };
+ Body.prototype.clamp = function (v, min, max) {
+ return v < min ? min : (v > max ? max : v);
+ };
+ Body.prototype.updatePosition = function (dt) {
+ this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
+ this.angle += this.angularVelocity * dt;
+ if(this.sprite) {
+ this.sprite.x = this.position.x * 50;
+ this.sprite.y = this.position.y * 50;
+ // Obey fixed rotation?
+ this.sprite.rotation = this.game.math.radiansToDegrees(this.angle);
+ }
+ };
+ Body.prototype.resetForce = function () {
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ };
+ Body.prototype.applyForce = function (force, p) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.force.add(force);
+ Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
+ this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
+ };
+ Body.prototype.applyForceToCenter = function (force) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.force.add(force);
+ };
+ Body.prototype.applyTorque = function (torque) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.torque += torque;
+ };
+ Body.prototype.applyLinearImpulse = function (impulse, p) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.velocity.multiplyAddByScalar(impulse, this.massInverted);
+ Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
+ this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
+ };
+ Body.prototype.applyAngularImpulse = function (impulse) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.angularVelocity += impulse * this.inertiaInverted;
+ };
+ Body.prototype.kineticEnergy = function () {
+ var vsq = this.velocity.dot(this.velocity);
+ var wsq = this.angularVelocity * this.angularVelocity;
+ return 0.5 * (this.mass * vsq + this.inertia * wsq);
+ };
+ Object.defineProperty(Body.prototype, "isAwake", {
+ get: function () {
+ return this.awaked;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Body.prototype.awake = function (flag) {
+ this.awaked = flag;
+ if(flag) {
+ this.sleepTime = 0;
+ } else {
+ this.velocity.setTo(0, 0);
+ this.angularVelocity = 0;
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ }
+ };
+ Body.prototype.isCollidable = function (other) {
+ if(this == other) {
+ return false;
+ }
+ if(this.isDynamic == false && other.isDynamic == false) {
+ return false;
+ }
+ if(!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits)) {
+ return false;
+ }
+ for(var i = 0; i < this.joints.length; i++) {
+ var joint = this.joints[i];
+ if(!this.joints[i] || (!this.joints[i].collideConnected && other.jointHash[this.joints[i].id] != undefined)) {
+ return false;
+ }
+ }
+ return true;
};
return Body;
})();
@@ -4514,14 +7108,20 @@ 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 [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC)
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
+ * @param [shapeType] {number} The physics shape the body will consist of (either Box (0) or Circle (1), for custom types see body.addShape)
*/
- function Sprite(game, x, y, key, frame, bodyType) {
+ function Sprite(game, x, y, key, frame, bodyType, shapeType) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof key === "undefined") { key = null; }
if (typeof frame === "undefined") { frame = null; }
- if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; }
+ if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; }
+ if (typeof shapeType === "undefined") { shapeType = 0; }
+ /**
+ * Sprite physics body.
+ */
+ this.body = null;
/**
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
*/
@@ -4569,7 +7169,11 @@ var Phaser;
this.frame = frame;
}
}
- this.body = new Phaser.Physics.Body(this, bodyType);
+ if(bodyType !== Phaser.Types.BODY_DISABLED) {
+ this.body = new Phaser.Physics.Body(this, bodyType, 0, 0, shapeType);
+ this.game.physics.addBody(this.body);
+ this.transform.origin.setTo(0.5, 0.5);
+ }
this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
this.cameraView = new Phaser.Rectangle(x, y, this.width, this.height);
this.transform.setCache();
@@ -4654,8 +7258,6 @@ var Phaser;
this.transform.update();
this.worldView.x = (this.x * this.transform.scrollFactor.x) - (this.width * this.transform.origin.x);
this.worldView.y = (this.y * this.transform.scrollFactor.y) - (this.height * this.transform.origin.y);
- //this.worldView.x = this.x * this.transform.scrollFactor.x;
- //this.worldView.y = this.y * this.transform.scrollFactor.y;
this.worldView.width = this.width;
this.worldView.height = this.height;
if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) {
@@ -4663,7 +7265,7 @@ var Phaser;
}
};
Sprite.prototype.update = /**
- * Override this function to update your class's position and appearance.
+ * Override this function to update your sprites position and appearance.
*/
function () {
};
@@ -4672,7 +7274,6 @@ var Phaser;
*/
function () {
this.animations.update();
- this.body.postUpdate();
/*
if (this.worldBounds != null)
{
@@ -4960,8 +7561,8 @@ var Phaser;
*/
function reset(sprite, x, y) {
sprite.revive();
- sprite.body.touching = Phaser.Types.NONE;
- sprite.body.wasTouching = Phaser.Types.NONE;
+ //sprite.body.touching = Types.NONE;
+ //sprite.body.wasTouching = Types.NONE;
sprite.x = x;
sprite.y = y;
sprite.body.velocity.x = 0;
@@ -9436,11 +12037,9 @@ var Phaser;
_super.call(this, game);
this.body.type = Phaser.Types.BODY_DYNAMIC;
this.lifespan = 0;
- this.friction = 500;
}
Particle.prototype.update = /**
- * The particle's main update logic. Basically it checks to see if it should
- * be dead yet, and then has some special bounce behavior if there is some gravity on it.
+ * The particle's main update logic. Basically it checks to see if it should be dead yet.
*/
function () {
// Lifespan behavior
@@ -9451,30 +12050,6 @@ var Phaser;
if(this.lifespan <= 0) {
this.kill();
}
- //simpler bounce/spin behavior for now
- if(this.body.touching) {
- if(this.body.angularVelocity != 0) {
- this.body.angularVelocity = -this.body.angularVelocity;
- }
- }
- if(this.body.acceleration.y > 0)//special behavior for particles with gravity
- {
- if(this.body.touching & Phaser.Types.FLOOR) {
- this.body.drag.x = this.friction;
- if(!(this.body.wasTouching & Phaser.Types.FLOOR)) {
- if(this.body.velocity.y < -this.body.bounce.y * 10) {
- if(this.body.angularVelocity != 0) {
- this.body.angularVelocity *= -this.body.bounce.y;
- }
- } else {
- this.body.velocity.y = 0;
- this.body.angularVelocity = 0;
- }
- }
- } else {
- this.body.drag.x = 0;
- }
- }
};
Particle.prototype.onEmit = /**
* Triggered whenever this object is launched by a Emitter.
@@ -9591,16 +12166,16 @@ var Phaser;
}
}
if(collide > 0) {
- particle.body.allowCollisions = Phaser.Types.ANY;
+ //particle.body.allowCollisions = Types.ANY;
particle.body.type = Phaser.Types.BODY_DYNAMIC;
particle.width *= collide;
particle.height *= collide;
} else {
- particle.body.allowCollisions = Phaser.Types.NONE;
- }
+ //particle.body.allowCollisions = Types.NONE;
+ }
particle.exists = false;
// Center the origin for rotation assistance
- particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
+ //particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
this.add(particle);
i++;
}
@@ -9686,7 +12261,7 @@ var Phaser;
function () {
var particle = this.recycle(Phaser.Particle);
particle.lifespan = this.lifespan;
- particle.body.bounce.setTo(this.bounce, this.bounce);
+ //particle.body.bounce.setTo(this.bounce, this.bounce);
Phaser.SpriteUtils.reset(particle, this.x - (particle.width >> 1) + this.game.math.random() * this.width, this.y - (particle.height >> 1) + this.game.math.random() * this.height);
particle.visible = true;
if(this.minParticleSpeed.x != this.maxParticleSpeed.x) {
@@ -9699,7 +12274,7 @@ var Phaser;
} else {
particle.body.velocity.y = this.minParticleSpeed.y;
}
- particle.body.acceleration.y = this.gravity;
+ //particle.body.acceleration.y = this.gravity;
if(this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0) {
particle.body.angularVelocity = this.minRotation + this.game.math.random() * (this.maxRotation - this.minRotation);
} else {
@@ -9708,8 +12283,8 @@ var Phaser;
if(particle.body.angularVelocity != 0) {
particle.rotation = this.game.math.random() * 360 - 180;
}
- particle.body.drag.x = this.particleDrag.x;
- particle.body.drag.y = this.particleDrag.y;
+ //particle.body.drag.x = this.particleDrag.x;
+ //particle.body.drag.y = this.particleDrag.y;
particle.onEmit();
};
Emitter.prototype.setSize = /**
@@ -9764,9 +12339,9 @@ var Phaser;
* @param Object {object} The Object that you want to sync up with.
*/
function (object) {
- this.x = object.body.bounds.halfWidth - (this.width >> 1);
- this.y = object.body.bounds.halfHeight - (this.height >> 1);
- };
+ //this.x = object.body.bounds.halfWidth - (this.width >> 1);
+ //this.y = object.body.bounds.halfHeight - (this.height >> 1);
+ };
return Emitter;
})(Phaser.Group);
Phaser.Emitter = Emitter;
@@ -10275,16 +12850,15 @@ var Phaser;
// Loop through the tiles we've got and check overlaps accordingly (the results are stored in this._tempTileBlock)
this._tempBlockResults = [];
this.getTempBlock(this._tempTileX, this._tempTileY, this._tempTileW, this._tempTileH, true);
- Phaser.Physics.PhysicsManager.TILE_OVERLAP = false;
- for(var r = 0; r < this._tempTileBlock.length; r++) {
- if(this._game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true) {
- this._tempBlockResults.push({
- x: this._tempTileBlock[r].x,
- y: this._tempTileBlock[r].y,
- tile: this._tempTileBlock[r].tile
- });
- }
+ /*
+ for (var r = 0; r < this._tempTileBlock.length; r++)
+ {
+ if (this._game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true)
+ {
+ this._tempBlockResults.push({ x: this._tempTileBlock[r].x, y: this._tempTileBlock[r].y, tile: this._tempTileBlock[r].tile });
}
+ }
+ */
return this._tempBlockResults;
};
TilemapLayer.prototype.getTempBlock = /**
@@ -10989,9 +13563,25 @@ var Phaser;
function (x, y, key, frame, bodyType) {
if (typeof key === "undefined") { key = ''; }
if (typeof frame === "undefined") { frame = null; }
- if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; }
+ if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; }
return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, frame, bodyType));
};
+ GameObjectFactory.prototype.physicsSprite = /**
+ * Create a new Sprite with the physics automatically created and set to DYNAMIC. The Sprite position offset is set to its center.
+ *
+ * @param x {number} X position of the new sprite.
+ * @param y {number} Y position of the new sprite.
+ * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite
+ * @param [frame] {string|number} If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name.
+ * @param [shapeType] The default body shape is either 0 for a Box or 1 for a Circle. See Sprite.body.addShape for custom shapes (polygons, etc)
+ * @returns {Sprite} The newly created sprite object.
+ */
+ function (x, y, key, frame, shapeType) {
+ if (typeof key === "undefined") { key = ''; }
+ if (typeof frame === "undefined") { frame = null; }
+ if (typeof shapeType === "undefined") { shapeType = 0; }
+ return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, frame, Phaser.Types.BODY_DYNAMIC, shapeType));
+ };
GameObjectFactory.prototype.dynamicTexture = /**
* Create a new DynamicTexture with specific size.
*
@@ -12476,1111 +15066,11 @@ var Phaser;
})();
Phaser.TweenManager = TweenManager;
})(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;
- /**
- * @type {number}
- */
- this.worldDivisions = 6;
- 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.members = new Phaser.Group(game);
- }
- PhysicsManager.OVERLAP_BIAS = 4;
- PhysicsManager.TILE_OVERLAP = false;
- PhysicsManager.prototype.updateMotion = /*
- 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.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
- body.angularVelocity += this._velocityDelta;
- body.sprite.transform.rotation += 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;
- body.sprite.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;
- body.sprite.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.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 (body1, body2) {
- return ((body1.hullX + body1.hullWidth > body2.hullX) && (body1.hullX < body2.hullX + body2.hullWidth) && (body1.hullY + body1.hullHeight > body2.hullY) && (body1.hullY < body2.hullY + body2.hullHeight));
- };
- 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.sprite.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.sprite.active && (body1.deltaY < body2.deltaY)) {
- body2.position.x += body1.position.x - body1.oldPosition.x;
- }
- }
- return true;
- } else {
- return false;
- }
- };
- PhysicsManager.prototype.overlap = /*
- private TILEseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 = 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('------------------------------------------------');
-
- }
-
- private collideWorld(shape:IPhysicsShape) {
-
- // 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);
- }
- }
-
- }
-
- private separateX(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateY(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateXWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateYWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
- */
- /**
- * 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 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.
- */
- 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.worldDivisions;
- this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
- this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
- this._quadTreeResult = this._quadTree.execute();
- console.log('over', this._quadTreeResult);
- this._quadTree.destroy();
- this._quadTree = null;
- return this._quadTreeResult;
- };
- PhysicsManager.prototype.separateTile = /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- function (object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY) {
- //var separatedX: bool = this.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
- //var separatedY: bool = this.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
- //return separatedX || separatedY;
- return false;
- };
- return PhysicsManager;
- })();
- Physics.PhysicsManager = PhysicsManager;
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public separateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
- var objDelta: number = object.x - object.last.x;
- //var objDelta: number = object.collisionMask.deltaX;
-
- if (objDelta != 0)
- {
- // Check if the X hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objDeltaAbs: number = object.collisionMask.deltaXAbs;
- var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.x + object.width - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- //console.log('
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public separateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- var objDelta: number = object.y - object.last.y;
-
- if (objDelta != 0)
- {
- // Check if the Y hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.y + object.height - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public static NEWseparateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
-
- if (object.collisionMask.deltaX != 0)
- {
- // Check if the X hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- var maxOverlap: number = object.collisionMask.deltaXAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaX > 0)
- {
- //overlap = object.x + object.width - x;
- overlap = object.collisionMask.right - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (object.collisionMask.deltaX < 0)
- {
- //overlap = object.x - width - x;
- overlap = object.collisionMask.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public NEWseparateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- //var objDelta: number = object.y - object.last.y;
-
- if (object.collisionMask.deltaY != 0)
- {
- // Check if the Y hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- //var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object.collisionMask.deltaYAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaY > 0)
- {
- //overlap = object.y + object.height - y;
- overlap = object.collisionMask.bottom - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (object.collisionMask.deltaY < 0)
- {
- //overlap = object.y - height - y;
- overlap = object.collisionMask.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
///
///
///
///
-///
+///
/**
* Phaser - World
*
@@ -13618,13 +15108,11 @@ var Phaser;
*/
function () {
this.group = new Phaser.Group(this._game, 0);
- this.physics = new Phaser.Physics.PhysicsManager(this._game, this.width, this.height);
};
World.prototype.update = /**
* This is called automatically every frame, and is where main logic happens.
*/
function () {
- //this.physics.update();
this.group.update();
this.cameras.update();
};
@@ -13632,7 +15120,6 @@ var Phaser;
* This is called automatically every frame, and is where main logic happens.
*/
function () {
- //this.physics.postUpdate();
this.group.postUpdate();
this.cameras.postUpdate();
};
@@ -13640,7 +15127,6 @@ var Phaser;
* Clean up memory.
*/
function () {
- //this.physics.destroy();
this.group.destroy();
this.cameras.destroy();
};
@@ -13651,17 +15137,13 @@ var Phaser;
* @param height {number} New height of the world.
* @param [updateCameraBounds] {boolean} Update camera bounds automatically or not. Default to true.
*/
- function (width, height, updateCameraBounds, updatePhysicsBounds) {
+ function (width, height, updateCameraBounds) {
if (typeof updateCameraBounds === "undefined") { updateCameraBounds = true; }
- if (typeof updatePhysicsBounds === "undefined") { updatePhysicsBounds = true; }
this.bounds.width = width;
this.bounds.height = height;
if(updateCameraBounds == true) {
this._game.camera.setBounds(0, 0, width, height);
}
- if(updatePhysicsBounds == true) {
- //this.physics.bounds.copyFrom(this.bounds);
- }
// dispatch world resize event
};
Object.defineProperty(World.prototype, "width", {
@@ -13789,14 +15271,19 @@ var Phaser;
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
function (source, dest, speed, xSpeedMax, ySpeedMax) {
- var a = this.angleBetween(source, dest);
+ /*
+ var a: number = this.angleBetween(source, dest);
+
source.body.velocity.x = 0;
source.body.velocity.y = 0;
+
source.body.acceleration.x = Math.cos(a) * speed;
source.body.acceleration.y = Math.sin(a) * speed;
+
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
- };
+ */
+ };
Motion.prototype.moveTowardsMouse = /**
* Move the given Sprite towards the mouse pointer coordinates at a steady velocity
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
@@ -13830,14 +15317,19 @@ var Phaser;
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
function (source, speed, xSpeedMax, ySpeedMax) {
- var a = this.angleBetweenMouse(source);
+ /*
+ var a: number = this.angleBetweenMouse(source);
+
source.body.velocity.x = 0;
source.body.velocity.y = 0;
+
source.body.acceleration.x = Math.cos(a) * speed;
source.body.acceleration.y = Math.sin(a) * speed;
+
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
- };
+ */
+ };
Motion.prototype.moveTowardsPoint = /**
* Sets the x/y velocity on the source Sprite so it will move towards the target coordinates at the speed given (in pixels per second)
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
@@ -13873,14 +15365,19 @@ var Phaser;
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
function (source, target, speed, xSpeedMax, ySpeedMax) {
- var a = this.angleBetweenPoint(source, target);
+ /*
+ var a: number = this.angleBetweenPoint(source, target);
+
source.body.velocity.x = 0;
source.body.velocity.y = 0;
+
source.body.acceleration.x = Math.cos(a) * speed;
source.body.acceleration.y = Math.sin(a) * speed;
+
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
- };
+ */
+ };
Motion.prototype.distanceBetween = /**
* Find the distance between two Sprites, taking their origin into account
*
@@ -13963,17 +15460,29 @@ var Phaser;
* @return {Point} An Point where Point.x contains the velocity x value and Point.y contains the velocity y value
*/
function (parent, speed) {
- var a;
- if(parent.body.facing == Phaser.Types.LEFT) {
- a = this.game.math.degreesToRadians(180);
- } else if(parent.body.facing == Phaser.Types.RIGHT) {
- a = this.game.math.degreesToRadians(0);
- } else if(parent.body.facing == Phaser.Types.UP) {
- a = this.game.math.degreesToRadians(-90);
- } else if(parent.body.facing == Phaser.Types.DOWN) {
- a = this.game.math.degreesToRadians(90);
+ /*
+ var a: number;
+
+ if (parent.body.facing == Types.LEFT)
+ {
+ a = this.game.math.degreesToRadians(180);
}
- return new Phaser.Point(Math.cos(a) * speed, Math.sin(a) * speed);
+ else if (parent.body.facing == Types.RIGHT)
+ {
+ a = this.game.math.degreesToRadians(0);
+ }
+ else if (parent.body.facing == Types.UP)
+ {
+ a = this.game.math.degreesToRadians(-90);
+ }
+ else if (parent.body.facing == Types.DOWN)
+ {
+ a = this.game.math.degreesToRadians(90);
+ }
+
+ return new Point(Math.cos(a) * speed, Math.sin(a) * speed);
+ */
+ return new Phaser.Point();
};
Motion.prototype.angleBetweenMouse = /**
* Find the angle (in radians) between an Sprite and the mouse, taking their x/y and origin into account.
@@ -17064,14 +18573,14 @@ var Phaser;
*/
function renderSpriteInfo(sprite, x, y, color) {
if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y);
- DebugUtils.game.stage.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14);
- DebugUtils.game.stage.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28);
- DebugUtils.game.stage.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42);
- DebugUtils.game.stage.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56);
- DebugUtils.game.stage.context.fillText('cx: ' + sprite.cameraView.x + ' cy: ' + sprite.cameraView.y + ' cw: ' + sprite.cameraView.width + ' ch: ' + sprite.cameraView.height + ' cb: ' + sprite.cameraView.bottom + ' cr: ' + sprite.cameraView.right, x, y + 70);
- DebugUtils.game.stage.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 84);
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y);
+ DebugUtils.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14);
+ DebugUtils.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28);
+ DebugUtils.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42);
+ DebugUtils.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56);
+ DebugUtils.context.fillText('cx: ' + sprite.cameraView.x + ' cy: ' + sprite.cameraView.y + ' cw: ' + sprite.cameraView.width + ' ch: ' + sprite.cameraView.height + ' cb: ' + sprite.cameraView.bottom + ' cr: ' + sprite.cameraView.right, x, y + 70);
+ DebugUtils.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 84);
};
DebugUtils.renderSpriteBounds = function renderSpriteBounds(sprite, camera, color) {
if (typeof camera === "undefined") { camera = null; }
@@ -17079,23 +18588,36 @@ var Phaser;
if(camera == null) {
camera = DebugUtils.game.camera;
}
- //var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x);
- //var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y);
var dx = sprite.worldView.x;
var dy = sprite.worldView.y;
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillRect(dx, dy, sprite.width, sprite.height);
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillRect(dx, dy, sprite.width, sprite.height);
};
- DebugUtils.renderSpritePhysicsBody = function renderSpritePhysicsBody(sprite, camera, color) {
- if (typeof camera === "undefined") { camera = null; }
- if (typeof color === "undefined") { color = 'rgba(255,0,0,0.2)'; }
- if(camera == null) {
- camera = DebugUtils.game.camera;
+ DebugUtils.renderPhysicsBody = function renderPhysicsBody(body, lineWidth, fillStyle, sleepStyle) {
+ if (typeof lineWidth === "undefined") { lineWidth = 1; }
+ if (typeof fillStyle === "undefined") { fillStyle = 'rgba(0,255,0,0.2)'; }
+ if (typeof sleepStyle === "undefined") { sleepStyle = 'rgba(100,100,100,0.2)'; }
+ for(var s = 0; s < body.shapes.length; s++) {
+ DebugUtils.context.beginPath();
+ if(body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_POLY) {
+ var verts = body.shapes[s].tverts;
+ DebugUtils.context.moveTo((body.position.x + verts[0].x) * 50, (body.position.y + verts[0].y) * 50);
+ for(var i = 0; i < verts.length; i++) {
+ DebugUtils.context.lineTo((body.position.x + verts[i].x) * 50, (body.position.y + verts[i].y) * 50);
+ }
+ DebugUtils.context.lineTo((body.position.x + verts[verts.length - 1].x) * 50, (body.position.y + verts[verts.length - 1].y) * 50);
+ } else if(body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ var circle = body.shapes[s];
+ DebugUtils.context.arc(circle.tc.x * 50, circle.tc.y * 50, circle.radius * 50, 0, Math.PI * 2, false);
+ }
+ DebugUtils.context.closePath();
+ if(body.isAwake) {
+ DebugUtils.context.fillStyle = fillStyle;
+ } else {
+ DebugUtils.context.fillStyle = sleepStyle;
+ }
+ DebugUtils.context.fill();
}
- var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.body.x - (camera.worldView.x * sprite.transform.scrollFactor.x);
- var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.body.y - (camera.worldView.y * sprite.transform.scrollFactor.y);
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillRect(dx, dy, sprite.body.width, sprite.body.height);
};
return DebugUtils;
})();
@@ -17167,16 +18689,6 @@ var Phaser;
if (typeof destroyCallback === "undefined") { destroyCallback = null; }
var _this = this;
/**
- * Max allowable accumulation.
- * @type {number}
- */
- this._maxAccumulation = 32;
- /**
- * Total number of milliseconds elapsed since last update loop.
- * @type {number}
- */
- this._accumulator = 0;
- /**
* Milliseconds of time per step of the game loop.
* @type {number}
*/
@@ -17291,15 +18803,16 @@ var Phaser;
this.rnd = new Phaser.RandomDataGenerator([
(Date.now() * Math.random()).toString()
]);
+ this.physics = new Phaser.Physics.Manager(this);
this.setRenderer(Phaser.Types.RENDERER_CANVAS);
this.world.boot();
this.stage.boot();
this.input.boot();
- this.framerate = 60;
this.isBooted = true;
// Set-up some static helper references
Phaser.DebugUtils.game = this;
Phaser.ColorUtils.game = this;
+ Phaser.DebugUtils.context = this.stage.context;
// Display the default game screen?
if(this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) {
this._raf = new Phaser.RequestAnimationFrame(this, this.bootLoop);
@@ -17359,15 +18872,8 @@ var Phaser;
this.tweens.update();
this.input.update();
this.stage.update();
- this._accumulator += this.time.delta;
- if(this._accumulator > this._maxAccumulation) {
- this._accumulator = this._maxAccumulation;
- }
- while(this._accumulator >= this._step) {
- this.time.elapsed = this.time.timeScale * (this._step / 1000);
- this.world.update();
- this._accumulator = this._accumulator - this._step;
- }
+ this.physics.update();
+ this.world.update();
if(this._loadComplete && this.onUpdateCallback) {
this.onUpdateCallback.call(this.callbackContext);
}
@@ -17523,19 +19029,6 @@ var Phaser;
enumerable: true,
configurable: true
});
- Object.defineProperty(Game.prototype, "framerate", {
- get: function () {
- return 1000 / this._step;
- },
- set: function (value) {
- this._step = 1000 / value;
- if(this._maxAccumulation < this._step) {
- this._maxAccumulation = this._step;
- }
- },
- enumerable: true,
- configurable: true
- });
Game.prototype.collide = /**
* 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.
@@ -17551,7 +19044,8 @@ var Phaser;
if (typeof objectOrGroup2 === "undefined") { objectOrGroup2 = null; }
if (typeof notifyCallback === "undefined") { notifyCallback = null; }
if (typeof context === "undefined") { context = this.callbackContext; }
- return this.world.physics.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.world.physics.separate, context);
+ //return this.world.physics.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.world.physics.separate, context);
+ return false;
};
Object.defineProperty(Game.prototype, "camera", {
get: function () {
@@ -17906,6 +19400,169 @@ var Phaser;
Phaser.Line = Line;
})(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 = {}));
+///
///
///
/**
@@ -18061,3795 +19718,6 @@ var Phaser;
Phaser.Mat3Utils = Mat3Utils;
})(Phaser || (Phaser = {}));
///
-///
-/**
-* Phaser - 2D Transform
-*
-* A 2D Transform
-*/
-var Phaser;
-(function (Phaser) {
- var Transform = (function () {
- /**
- * Creates a new 2D Transform object.
- * @class Transform
- * @constructor
- * @return {Transform} This object
- **/
- function Transform(pos, angle) {
- this.t = Phaser.Vec2Utils.clone(pos);
- this.c = Math.cos(angle);
- this.s = Math.sin(angle);
- this.angle = angle;
- }
- Transform.prototype.toString = function () {
- return 't=' + this.t.toString() + ' c=' + this.c + ' s=' + this.s + ' a=' + this.angle;
- };
- Transform.prototype.setTo = function (pos, angle) {
- this.t.copyFrom(pos);
- this.c = Math.cos(angle);
- this.s = Math.sin(angle);
- return this;
- };
- Transform.prototype.setRotation = function (angle) {
- if(angle !== this.angle) {
- this.c = Math.cos(angle);
- this.s = Math.sin(angle);
- this.angle = angle;
- }
- return this;
- };
- Transform.prototype.setPosition = function (p) {
- this.t.copyFrom(p);
- return this;
- };
- Transform.prototype.identity = function () {
- this.t.setTo(0, 0);
- this.c = 1;
- this.s = 0;
- return this;
- };
- return Transform;
- })();
- Phaser.Transform = Transform;
-})(Phaser || (Phaser = {}));
-///
-///
-///
-/**
-* Phaser - TransformUtils
-*
-* A collection of methods useful for manipulating and performing operations on 2D Transforms.
-*
-*/
-var Phaser;
-(function (Phaser) {
- var TransformUtils = (function () {
- function TransformUtils() { }
- TransformUtils.rotate = function rotate(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- //return new vec2(v.x * this.c - v.y * this.s, v.x * this.s + v.y * this.c);
- return out.setTo(v.x * t.c - v.y * t.s, v.x * t.s + v.y * t.c);
- };
- TransformUtils.unrotate = function unrotate(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- //return new vec2(v.x * this.c + v.y * this.s, -v.x * this.s + v.y * this.c);
- return out.setTo(v.x * t.c + v.y * t.s, -v.x * t.s + v.y * t.c);
- };
- TransformUtils.transform = function transform(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- //return new vec2(v.x * this.c - v.y * this.s + this.t.x, v.x * this.s + v.y * this.c + this.t.y);
- return out.setTo(v.x * t.c - v.y * t.s + t.t.x, v.x * t.s + v.y * t.c + t.t.y);
- };
- TransformUtils.untransform = function untransform(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- var px = v.x - t.t.x;
- var py = v.y - t.t.y;
- //return new vec2(px * this.c + py * this.s, -px * this.s + py * this.c);
- return out.setTo(px * t.c + py * t.s, -px * t.s + py * t.c);
- };
- return TransformUtils;
- })();
- Phaser.TransformUtils = TransformUtils;
-})(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 ArcadePhysics = (function () {
- function ArcadePhysics(game, width, height) {
- this._length = 0;
- /**
- * @type {number}
- */
- this.worldDivisions = 6;
- 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.members = new Phaser.Group(game);
- }
- ArcadePhysics.OVERLAP_BIAS = 4;
- ArcadePhysics.TILE_OVERLAP = false;
- ArcadePhysics.prototype.updateMotion = /*
- 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.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
- body.angularVelocity += this._velocityDelta;
- body.sprite.transform.rotation += 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;
- body.sprite.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;
- body.sprite.y += this._delta;
- };
- ArcadePhysics.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;
- };
- ArcadePhysics.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;
- };
- ArcadePhysics.prototype.checkHullIntersection = function (body1, body2) {
- return ((body1.hullX + body1.hullWidth > body2.hullX) && (body1.hullX < body2.hullX + body2.hullWidth) && (body1.hullY + body1.hullHeight > body2.hullY) && (body1.hullY < body2.hullY + body2.hullHeight));
- };
- ArcadePhysics.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 + Physics.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;
- }
- };
- ArcadePhysics.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 + Physics.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.sprite.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.sprite.active && (body1.deltaY < body2.deltaY)) {
- body2.position.x += body1.position.x - body1.oldPosition.x;
- }
- }
- return true;
- } else {
- return false;
- }
- };
- ArcadePhysics.prototype.overlap = /*
- private TILEseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 = 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('------------------------------------------------');
-
- }
-
- private collideWorld(shape:IPhysicsShape) {
-
- // 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);
- }
- }
-
- }
-
- private separateX(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateY(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateXWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateYWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
- */
- /**
- * 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 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.
- */
- 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;
- }
-
- QuadTree.divisions = this.worldDivisions;
-
- this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
-
- this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
-
- this._quadTreeResult = this._quadTree.execute();
-
- console.log('over', this._quadTreeResult);
-
- this._quadTree.destroy();
-
- this._quadTree = null;
-
- return this._quadTreeResult;
- */
- return false;
- };
- ArcadePhysics.prototype.separateTile = /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- function (object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY) {
- //var separatedX: bool = this.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
- //var separatedY: bool = this.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
- //return separatedX || separatedY;
- return false;
- };
- return ArcadePhysics;
- })();
- Physics.ArcadePhysics = ArcadePhysics;
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public separateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
- var objDelta: number = object.x - object.last.x;
- //var objDelta: number = object.collisionMask.deltaX;
-
- if (objDelta != 0)
- {
- // Check if the X hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objDeltaAbs: number = object.collisionMask.deltaXAbs;
- var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.x + object.width - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- //console.log('
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public separateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- var objDelta: number = object.y - object.last.y;
-
- if (objDelta != 0)
- {
- // Check if the Y hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.y + object.height - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public static NEWseparateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
-
- if (object.collisionMask.deltaX != 0)
- {
- // Check if the X hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- var maxOverlap: number = object.collisionMask.deltaXAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaX > 0)
- {
- //overlap = object.x + object.width - x;
- overlap = object.collisionMask.right - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (object.collisionMask.deltaX < 0)
- {
- //overlap = object.x - width - x;
- overlap = object.collisionMask.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public NEWseparateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- //var objDelta: number = object.y - object.last.y;
-
- if (object.collisionMask.deltaY != 0)
- {
- // Check if the Y hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- //var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object.collisionMask.deltaYAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaY > 0)
- {
- //overlap = object.y + object.height - y;
- overlap = object.collisionMask.bottom - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (object.collisionMask.deltaY < 0)
- {
- //overlap = object.y - height - y;
- overlap = object.collisionMask.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Joint
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Joint = (function () {
- function Joint(type, body1, body2, collideConnected) {
- this.id = Phaser.Physics.Advanced.Manager.jointCounter++;
- this.type = type;
- this.body1 = body1;
- this.body2 = body2;
- this.collideConnected = collideConnected;
- this.maxForce = 9999999999;
- this.breakable = false;
- }
- Joint.prototype.getWorldAnchor1 = function () {
- return this.body1.getWorldPoint(this.anchor1);
- };
- Joint.prototype.getWorldAnchor2 = function () {
- return this.body2.getWorldPoint(this.anchor2);
- };
- Joint.prototype.setWorldAnchor1 = function (anchor1) {
- this.anchor1 = this.body1.getLocalPoint(anchor1);
- };
- Joint.prototype.setWorldAnchor2 = function (anchor2) {
- this.anchor2 = this.body2.getLocalPoint(anchor2);
- };
- return Joint;
- })();
- Advanced.Joint = Joint;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics Manager
- *
- * 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 (Advanced) {
- var Manager = (function () {
- function Manager(game) {
- this.lastTime = Date.now();
- this.frameRateHz = 60;
- this.timeDelta = 0;
- //public paused: bool = false;
- //public step: bool = false; // step through the simulation (i.e. per click)
- this.paused = true;
- this.step = false;
- // step through the simulation (i.e. per click)
- this.velocityIterations = 8;
- this.positionIterations = 4;
- //public velocityIterations: number = 1;
- //public positionIterations: number = 1;
- this.allowSleep = true;
- this.warmStarting = true;
- this.game = game;
- this.space = new Advanced.Space();
- Manager.collision = new Advanced.Collision();
- }
- Manager.clear = function clear() {
- Manager.debug.textContent = "";
- Manager.log = [];
- };
- Manager.write = function write(s) {
- Manager.debug.textContent += s + "\n";
- };
- Manager.writeAll = function writeAll() {
- for(var i = 0; i < Manager.log.length; i++) {
- //Manager.debug.textContent += Manager.log[i];
- }
- };
- Manager.log = [];
- Manager.dump = function dump(phase, body) {
- var s = "\n\nPhase: " + phase + "\n";
- s += "Position: " + body.position.toString() + "\n";
- s += "Velocity: " + body.velocity.toString() + "\n";
- s += "Angle: " + body.angle + "\n";
- s += "Force: " + body.force.toString() + "\n";
- s += "Torque: " + body.torque + "\n";
- s += "Bounds: " + body.bounds.toString() + "\n";
- s += "Shape ***\n";
- s += "Vert 0: " + body.shapes[0].verts[0].toString() + "\n";
- s += "Vert 1: " + body.shapes[0].verts[1].toString() + "\n";
- s += "Vert 2: " + body.shapes[0].verts[2].toString() + "\n";
- s += "Vert 3: " + body.shapes[0].verts[3].toString() + "\n";
- s += "TVert 0: " + body.shapes[0].tverts[0].toString() + "\n";
- s += "TVert 1: " + body.shapes[0].tverts[1].toString() + "\n";
- s += "TVert 2: " + body.shapes[0].tverts[2].toString() + "\n";
- s += "TVert 3: " + body.shapes[0].tverts[3].toString() + "\n";
- s += "Plane 0: " + body.shapes[0].planes[0].normal.toString() + "\n";
- s += "Plane 1: " + body.shapes[0].planes[1].normal.toString() + "\n";
- s += "Plane 2: " + body.shapes[0].planes[2].normal.toString() + "\n";
- s += "Plane 3: " + body.shapes[0].planes[3].normal.toString() + "\n";
- s += "TPlane 0: " + body.shapes[0].tplanes[0].normal.toString() + "\n";
- s += "TPlane 1: " + body.shapes[0].tplanes[1].normal.toString() + "\n";
- s += "TPlane 2: " + body.shapes[0].tplanes[2].normal.toString() + "\n";
- s += "TPlane 3: " + body.shapes[0].tplanes[3].normal.toString() + "\n";
- Manager.log.push(s);
- };
- Manager.SHAPE_TYPE_CIRCLE = 0;
- Manager.SHAPE_TYPE_SEGMENT = 1;
- Manager.SHAPE_TYPE_POLY = 2;
- Manager.SHAPE_NUM_TYPES = 3;
- Manager.JOINT_TYPE_ANGLE = 0;
- Manager.JOINT_TYPE_REVOLUTE = 1;
- Manager.JOINT_TYPE_WELD = 2;
- Manager.JOINT_TYPE_WHEEL = 3;
- Manager.JOINT_TYPE_PRISMATIC = 4;
- Manager.JOINT_TYPE_DISTANCE = 5;
- Manager.JOINT_TYPE_ROPE = 6;
- Manager.JOINT_TYPE_MOUSE = 7;
- Manager.JOINT_LINEAR_SLOP = 0.0008;
- Manager.JOINT_ANGULAR_SLOP = 2 * Phaser.GameMath.DEG_TO_RAD;
- Manager.JOINT_MAX_LINEAR_CORRECTION = 0.5;
- Manager.JOINT_MAX_ANGULAR_CORRECTION = 8 * Phaser.GameMath.DEG_TO_RAD;
- Manager.JOINT_LIMIT_STATE_INACTIVE = 0;
- Manager.JOINT_LIMIT_STATE_AT_LOWER = 1;
- Manager.JOINT_LIMIT_STATE_AT_UPPER = 2;
- Manager.JOINT_LIMIT_STATE_EQUAL_LIMITS = 3;
- Manager.CONTACT_SOLVER_COLLISION_SLOP = 0.0008;
- Manager.CONTACT_SOLVER_BAUMGARTE = 0.28;
- Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION = 1;
- Manager.bodyCounter = 0;
- Manager.jointCounter = 0;
- Manager.shapeCounter = 0;
- Manager.prototype.update = function () {
- var time = Date.now();
- var frameTime = (time - this.lastTime) / 1000;
- this.lastTime = time;
- // if rAf - why?
- frameTime = Math.floor(frameTime * 60 + 0.5) / 60;
- //if (!mouseDown)
- //{
- // var p = canvasToWorld(mousePosition);
- // var body = space.findBodyByPoint(p);
- // //domCanvas.style.cursor = body ? "pointer" : "default";
- //}
- if(!this.paused || this.step) {
- Manager.clear();
- var h = 1 / this.frameRateHz;
- this.timeDelta += frameTime;
- if(this.step) {
- this.step = false;
- this.timeDelta = h;
- }
- for(var maxSteps = 4; maxSteps > 0 && this.timeDelta >= h; maxSteps--) {
- this.space.step(h, this.velocityIterations, this.positionIterations, this.warmStarting, this.allowSleep);
- this.timeDelta -= h;
- }
- if(this.timeDelta > h) {
- this.timeDelta = 0;
- }
- }
- //frameCount++;
- };
- Manager.prototype.pixelsToMeters = function (value) {
- return value * 0.02;
- };
- Manager.prototype.metersToPixels = function (value) {
- return value * 50;
- };
- Manager.pixelsToMeters = function pixelsToMeters(value) {
- return value * 0.02;
- };
- Manager.metersToPixels = function metersToPixels(value) {
- return value * 50;
- };
- Manager.p2m = function p2m(value) {
- return value * 0.02;
- };
- Manager.m2p = function m2p(value) {
- return value * 50;
- };
- Manager.areaForCircle = function areaForCircle(radius_outer, radius_inner) {
- return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
- };
- Manager.inertiaForCircle = function inertiaForCircle(mass, center, radius_outer, radius_inner) {
- return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
- };
- Manager.areaForSegment = function areaForSegment(a, b, radius) {
- return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
- };
- Manager.centroidForSegment = function centroidForSegment(a, b) {
- return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
- };
- Manager.inertiaForSegment = function inertiaForSegment(mass, a, b) {
- var distsq = Phaser.Vec2Utils.distanceSq(b, a);
- var offset = Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
- return mass * (distsq / 12 + offset.lengthSq());
- };
- Manager.areaForPoly = function areaForPoly(verts) {
- var area = 0;
- for(var i = 0; i < verts.length; i++) {
- area += Phaser.Vec2Utils.cross(verts[i], verts[(i + 1) % verts.length]);
- }
- return area / 2;
- };
- Manager.centroidForPoly = function centroidForPoly(verts) {
- var area = 0;
- var vsum = new Phaser.Vec2();
- for(var i = 0; i < verts.length; i++) {
- var v1 = verts[i];
- var v2 = verts[(i + 1) % verts.length];
- var cross = Phaser.Vec2Utils.cross(v1, v2);
- area += cross;
- // SO many vecs created here - unroll these bad boys
- vsum.add(Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(v1, v2), cross));
- }
- return Phaser.Vec2Utils.scale(vsum, 1 / (3 * area));
- };
- Manager.inertiaForPoly = function inertiaForPoly(mass, verts, offset) {
- var sum1 = 0;
- var sum2 = 0;
- for(var i = 0; i < verts.length; i++) {
- var v1 = Phaser.Vec2Utils.add(verts[i], offset);
- var v2 = Phaser.Vec2Utils.add(verts[(i + 1) % verts.length], offset);
- var a = Phaser.Vec2Utils.cross(v2, v1);
- var b = Phaser.Vec2Utils.dot(v1, v1) + Phaser.Vec2Utils.dot(v1, v2) + Phaser.Vec2Utils.dot(v2, v2);
- sum1 += a * b;
- sum2 += a;
- }
- return (mass * sum1) / (6 * sum2);
- };
- Manager.inertiaForBox = function inertiaForBox(mass, w, h) {
- return mass * (w * w + h * h) / 12;
- };
- Manager.createConvexHull = // Create the convex hull using the Gift wrapping algorithm (http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)
- function createConvexHull(points) {
- // Find the right most point on the hull
- var i0 = 0;
- var x0 = points[0].x;
- for(var i = 1; i < points.length; i++) {
- var x = points[i].x;
- if(x > x0 || (x == x0 && points[i].y < points[i0].y)) {
- i0 = i;
- x0 = x;
- }
- }
- var n = points.length;
- var hull = [];
- var m = 0;
- var ih = i0;
- while(1) {
- hull[m] = ih;
- var ie = 0;
- for(var j = 1; j < n; j++) {
- if(ie == ih) {
- ie = j;
- continue;
- }
- var r = Phaser.Vec2Utils.subtract(points[ie], points[hull[m]]);
- var v = Phaser.Vec2Utils.subtract(points[j], points[hull[m]]);
- var c = Phaser.Vec2Utils.cross(r, v);
- if(c < 0) {
- ie = j;
- }
- // Collinearity check
- if(c == 0 && v.lengthSq() > r.lengthSq()) {
- ie = j;
- }
- }
- m++;
- ih = ie;
- if(ie == i0) {
- break;
- }
- }
- // Copy vertices
- var newPoints = [];
- for(var i = 0; i < m; ++i) {
- newPoints.push(points[hull[i]]);
- }
- return newPoints;
- };
- return Manager;
- })();
- Advanced.Manager = Manager;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- /**
- * Phaser - 2D AABB
- *
- * A 2D AABB object
- */
- (function (Advanced) {
- var Bounds = (function () {
- /**
- * Creates a new 2D AABB object.
- * @class Bounds
- * @constructor
- * @return {Bounds} This object
- **/
- function Bounds(mins, maxs) {
- if (typeof mins === "undefined") { mins = null; }
- if (typeof maxs === "undefined") { maxs = null; }
- if(mins) {
- this.mins = Phaser.Vec2Utils.clone(mins);
- } else {
- this.mins = new Phaser.Vec2(999999, 999999);
- }
- if(maxs) {
- this.maxs = Phaser.Vec2Utils.clone(maxs);
- } else {
- this.maxs = new Phaser.Vec2(999999, 999999);
- }
- }
- Bounds.prototype.toString = function () {
- return [
- "mins:",
- this.mins.toString(),
- "maxs:",
- this.maxs.toString()
- ].join(" ");
- };
- Bounds.prototype.setTo = function (mins, maxs) {
- this.mins.setTo(mins.x, mins.y);
- this.maxs.setTo(maxs.x, maxs.y);
- };
- Bounds.prototype.copy = function (b) {
- this.mins.copyFrom(b.mins);
- this.maxs.copyFrom(b.maxs);
- return this;
- };
- Bounds.prototype.clear = function () {
- this.mins.setTo(999999, 999999);
- this.maxs.setTo(-999999, -999999);
- return this;
- };
- Object.defineProperty(Bounds.prototype, "x", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.mins.x);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Bounds.prototype, "y", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.mins.y);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Bounds.prototype, "width", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.maxs.x - this.mins.x);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Bounds.prototype, "height", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.maxs.y - this.mins.y);
- },
- enumerable: true,
- configurable: true
- });
- Bounds.prototype.isEmpty = function () {
- return (this.mins.x > this.maxs.x || this.mins.y > this.maxs.y);
- };
- Bounds.prototype.getPerimeter = /*
- public getCenter() {
- return vec2.scale(vec2.add(this.mins, this.maxs), 0.5);
- }
-
- public getExtent() {
- return vec2.scale(vec2.sub(this.maxs, this.mins), 0.5);
- }
- */
- function () {
- return (this.maxs.x - this.mins.x + this.maxs.y - this.mins.y) * 2;
- };
- Bounds.prototype.addPoint = function (p) {
- if(this.mins.x > p.x) {
- this.mins.x = p.x;
- }
- if(this.maxs.x < p.x) {
- this.maxs.x = p.x;
- }
- if(this.mins.y > p.y) {
- this.mins.y = p.y;
- }
- if(this.maxs.y < p.y) {
- this.maxs.y = p.y;
- }
- return this;
- };
- Bounds.prototype.addBounds = function (b) {
- if(this.mins.x > b.mins.x) {
- this.mins.x = b.mins.x;
- }
- if(this.maxs.x < b.maxs.x) {
- this.maxs.x = b.maxs.x;
- }
- if(this.mins.y > b.mins.y) {
- this.mins.y = b.mins.y;
- }
- if(this.maxs.y < b.maxs.y) {
- this.maxs.y = b.maxs.y;
- }
- return this;
- };
- Bounds.prototype.addBounds2 = function (mins, maxs) {
- if(this.mins.x > mins.x) {
- this.mins.x = mins.x;
- }
- if(this.maxs.x < maxs.x) {
- this.maxs.x = maxs.x;
- }
- if(this.mins.y > mins.y) {
- this.mins.y = mins.y;
- }
- if(this.maxs.y < maxs.y) {
- this.maxs.y = maxs.y;
- }
- return this;
- };
- Bounds.prototype.addExtents = function (center, extent_x, extent_y) {
- if(this.mins.x > center.x - extent_x) {
- this.mins.x = center.x - extent_x;
- }
- if(this.maxs.x < center.x + extent_x) {
- this.maxs.x = center.x + extent_x;
- }
- if(this.mins.y > center.y - extent_y) {
- this.mins.y = center.y - extent_y;
- }
- if(this.maxs.y < center.y + extent_y) {
- this.maxs.y = center.y + extent_y;
- }
- return this;
- };
- Bounds.prototype.expand = function (ax, ay) {
- this.mins.x -= ax;
- this.mins.y -= ay;
- this.maxs.x += ax;
- this.maxs.y += ay;
- return this;
- };
- Bounds.prototype.containPoint = function (p) {
- if(p.x < this.mins.x || p.x > this.maxs.x || p.y < this.mins.y || p.y > this.maxs.y) {
- return false;
- }
- return true;
- };
- Bounds.prototype.intersectsBounds = function (b) {
- if(this.mins.x > b.maxs.x || this.maxs.x < b.mins.x || this.mins.y > b.maxs.y || this.maxs.y < b.mins.y) {
- return false;
- }
- return true;
- };
- Bounds.expand = function expand(b, ax, ay) {
- var b = new Bounds(b.mins, b.maxs);
- b.expand(ax, ay);
- return b;
- };
- return Bounds;
- })();
- Advanced.Bounds = Bounds;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shape
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Shape = (function () {
- function Shape(type) {
- this.id = Phaser.Physics.Advanced.Manager.shapeCounter++;
- this.type = type;
- this.elasticity = 0.0;
- this.friction = 1.0;
- this.density = 1;
- this.bounds = new Advanced.Bounds();
- }
- Shape.prototype.findEdgeByPoint = // Over-ridden by ShapePoly
- function (p, minDist) {
- return -1;
- };
- return Shape;
- })();
- Advanced.Shape = Shape;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Contact
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Contact = (function () {
- function Contact(p, n, d, hash) {
- this.hash = hash;
- this.point = p;
- this.normal = n;
- this.depth = d;
- this.lambdaNormal = 0;
- this.lambdaTangential = 0;
- this.r1 = new Phaser.Vec2();
- this.r2 = new Phaser.Vec2();
- this.r1_local = new Phaser.Vec2();
- this.r2_local = new Phaser.Vec2();
- }
- return Contact;
- })();
- Advanced.Contact = Contact;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - ContactSolver
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- //-------------------------------------------------------------------------------------------------
- // Contact Constraint
- //
- // Non-penetration constraint:
- // C = dot(p2 - p1, n)
- // Cdot = dot(v2 - v1, n)
- // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
- //
- // impulse = JT * lambda = [ -n * lambda, -cross(r1, n) * lambda, n * lambda, cross(r1, n) * lambda ]
- //
- // Friction constraint:
- // C = dot(p2 - p1, t)
- // Cdot = dot(v2 - v1, t)
- // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
- //
- // impulse = JT * lambda = [ -t * lambda, -cross(r1, t) * lambda, t * lambda, cross(r1, t) * lambda ]
- //
- // NOTE: lambda is an impulse in constraint space.
- //-------------------------------------------------------------------------------------------------
- (function (Advanced) {
- var ContactSolver = (function () {
- function ContactSolver(shape1, shape2) {
- this.shape1 = shape1;
- this.shape2 = shape2;
- this.contacts = [];
- this.elasticity = 1;
- this.friction = 1;
- }
- ContactSolver.prototype.update = function (newContactArr) {
- for(var i = 0; i < newContactArr.length; i++) {
- var newContact = newContactArr[i];
- var k = -1;
- for(var j = 0; j < this.contacts.length; j++) {
- if(newContact.hash == this.contacts[j].hash) {
- k = j;
- break;
- }
- }
- if(k > -1) {
- newContact.lambdaNormal = this.contacts[k].lambdaNormal;
- newContact.lambdaTangential = this.contacts[k].lambdaTangential;
- }
- }
- this.contacts = newContactArr;
- };
- ContactSolver.prototype.initSolver = function (dt_inv) {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- var sum_m_inv = body1.massInverted + body2.massInverted;
- for(var i = 0; i < this.contacts.length; i++) {
- var con = this.contacts[i];
- //console.log('initSolver con');
- //console.log(con);
- // Transformed r1, r2
- Phaser.Vec2Utils.subtract(con.point, body1.position, con.r1);
- Phaser.Vec2Utils.subtract(con.point, body2.position, con.r2);
- //con.r1 = vec2.sub(con.point, body1.p);
- //con.r2 = vec2.sub(con.point, body2.p);
- // Local r1, r2
- Phaser.TransformUtils.unrotate(body1.transform, con.r1, con.r1_local);
- Phaser.TransformUtils.unrotate(body2.transform, con.r2, con.r2_local);
- //con.r1_local = body1.transform.unrotate(con.r1);
- //con.r2_local = body2.transform.unrotate(con.r2);
- var n = con.normal;
- var t = Phaser.Vec2Utils.perp(con.normal);
- // invEMn = J * invM * JT
- // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
- var sn1 = Phaser.Vec2Utils.cross(con.r1, n);
- var sn2 = Phaser.Vec2Utils.cross(con.r2, n);
- var emn_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
- con.emn = emn_inv == 0 ? 0 : 1 / emn_inv;
- // invEMt = J * invM * JT
- // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
- var st1 = Phaser.Vec2Utils.cross(con.r1, t);
- var st2 = Phaser.Vec2Utils.cross(con.r2, t);
- var emt_inv = sum_m_inv + body1.inertiaInverted * st1 * st1 + body2.inertiaInverted * st2 * st2;
- con.emt = emt_inv == 0 ? 0 : 1 / emt_inv;
- // Linear velocities at contact point
- // in 2D: cross(w, r) = perp(r) * w
- var v1 = new Phaser.Vec2();
- var v2 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(con.r1), body1.angularVelocity, v1);
- Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(con.r2), body2.angularVelocity, v2);
- //var v1 = vec2.mad(body1.v, vec2.perp(con.r1), body1.w);
- //var v2 = vec2.mad(body2.v, vec2.perp(con.r2), body2.w);
- // relative velocity at contact point
- var rv = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(v2, v1, rv);
- //var rv = vec2.sub(v2, v1);
- // bounce velocity dot n
- con.bounce = Phaser.Vec2Utils.dot(rv, con.normal) * this.elasticity;
- }
- };
- ContactSolver.prototype.warmStart = function () {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- for(var i = 0; i < this.contacts.length; i++) {
- var con = this.contacts[i];
- var n = con.normal;
- var lambda_n = con.lambdaNormal;
- var lambda_t = con.lambdaTangential;
- // Apply accumulated impulses
- //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
- //var impulse = new vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
- var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
- //console.log('phaser warmStart impulse ' + i + ' = ' + impulse.toString());
- body1.velocity.multiplyAddByScalar(impulse, -body1.massInverted);
- //body1.v.mad(impulse, -body1.m_inv);
- body1.angularVelocity -= Phaser.Vec2Utils.cross(con.r1, impulse) * body1.inertiaInverted;
- //body1.w -= vec2.cross(con.r1, impulse) * body1.i_inv;
- body2.velocity.multiplyAddByScalar(impulse, body2.massInverted);
- //body2.v.mad(impulse, body2.m_inv);
- body2.angularVelocity += Phaser.Vec2Utils.cross(con.r2, impulse) * body2.inertiaInverted;
- //body2.w += vec2.cross(con.r2, impulse) * body2.i_inv;
- }
- };
- ContactSolver.prototype.solveVelocityConstraints = function () {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- Advanced.Manager.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
- Advanced.Manager.write('Shape 1: ' + this.shape1.type + ' Shape 2: ' + this.shape2.type);
- var m1_inv = body1.massInverted;
- var i1_inv = body1.inertiaInverted;
- var m2_inv = body2.massInverted;
- var i2_inv = body2.inertiaInverted;
- Advanced.Manager.write('m1_inv: ' + m1_inv);
- Advanced.Manager.write('i1_inv: ' + i1_inv);
- Advanced.Manager.write('m2_inv: ' + m2_inv);
- Advanced.Manager.write('i2_inv: ' + i2_inv);
- for(var i = 0; i < this.contacts.length; i++) {
- Advanced.Manager.write('------------ solve con ' + i);
- var con = this.contacts[i];
- var n = con.normal;
- var t = Phaser.Vec2Utils.perp(n);
- var r1 = con.r1;
- var r2 = con.r2;
- // Linear velocities at contact point
- // in 2D: cross(w, r) = perp(r) * w
- var v1 = new Phaser.Vec2();
- var v2 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(r1), body1.angularVelocity, v1);
- //var v1 = vec2.mad(body1.v, vec2.perp(r1), body1.w);
- Advanced.Manager.write('v1 ' + v1.toString());
- Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(r2), body2.angularVelocity, v2);
- //var v2 = vec2.mad(body2.v, vec2.perp(r2), body2.w);
- Advanced.Manager.write('v2 ' + v2.toString());
- // Relative velocity at contact point
- var rv = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(v2, v1, rv);
- //var rv = vec2.sub(v2, v1);
- Advanced.Manager.write('rv ' + rv.toString());
- // Compute normal constraint impulse + adding bounce as a velocity bias
- // lambda_n = -EMn * J * V
- var lambda_n = -con.emn * (Phaser.Vec2Utils.dot(n, rv) + con.bounce);
- Advanced.Manager.write('lambda_n: ' + lambda_n);
- // Accumulate and clamp
- var lambda_n_old = con.lambdaNormal;
- con.lambdaNormal = Math.max(lambda_n_old + lambda_n, 0);
- //con.lambdaNormal = this.clamp(lambda_n_old + lambda_n, 0);
- lambda_n = con.lambdaNormal - lambda_n_old;
- Advanced.Manager.write('lambda_n clamped: ' + lambda_n);
- // Compute frictional constraint impulse
- // lambda_t = -EMt * J * V
- var lambda_t = -con.emt * Phaser.Vec2Utils.dot(t, rv);
- // Max friction constraint impulse (Coulomb's Law)
- var lambda_t_max = con.lambdaNormal * this.friction;
- // Accumulate and clamp
- var lambda_t_old = con.lambdaTangential;
- con.lambdaTangential = this.clamp(lambda_t_old + lambda_t, -lambda_t_max, lambda_t_max);
- lambda_t = con.lambdaTangential - lambda_t_old;
- // Apply the final impulses
- //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
- var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
- Advanced.Manager.write('impulse: ' + impulse.toString());
- body1.velocity.multiplyAddByScalar(impulse, -m1_inv);
- //body1.v.mad(impulse, -m1_inv);
- body1.angularVelocity -= Phaser.Vec2Utils.cross(r1, impulse) * i1_inv;
- //body1.w -= vec2.cross(r1, impulse) * i1_inv;
- body2.velocity.multiplyAddByScalar(impulse, m2_inv);
- //body2.v.mad(impulse, m2_inv);
- body2.angularVelocity += Phaser.Vec2Utils.cross(r2, impulse) * i2_inv;
- //body2.w += vec2.cross(r2, impulse) * i2_inv;
- Advanced.Manager.write('body1: ' + body1.toString());
- Advanced.Manager.write('body2: ' + body2.toString());
- }
- };
- ContactSolver.prototype.solvePositionConstraints = function () {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- Advanced.Manager.write('solvePositionConstraints');
- var m1_inv = body1.massInverted;
- var i1_inv = body1.inertiaInverted;
- var m2_inv = body2.massInverted;
- var i2_inv = body2.inertiaInverted;
- var sum_m_inv = m1_inv + m2_inv;
- var max_penetration = 0;
- for(var i = 0; i < this.contacts.length; i++) {
- Advanced.Manager.write('------------- solvePositionConstraints ' + i);
- var con = this.contacts[i];
- var n = con.normal;
- var r1 = new Phaser.Vec2();
- var r2 = new Phaser.Vec2();
- // Transformed r1, r2
- Phaser.Vec2Utils.rotate(con.r1_local, body1.angle, r1);
- //var r1 = vec2.rotate(con.r1_local, body1.a);
- Phaser.Vec2Utils.rotate(con.r2_local, body2.angle, r2);
- //var r2 = vec2.rotate(con.r2_local, body2.a);
- Advanced.Manager.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
- Advanced.Manager.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
- Advanced.Manager.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
- Advanced.Manager.write('r2 rotated: r2.x = ' + r2.x + ' r2.y = ' + r2.y);
- // Contact points (corrected)
- var p1 = new Phaser.Vec2();
- var p2 = new Phaser.Vec2();
- Phaser.Vec2Utils.add(body1.position, r1, p1);
- //var p1 = vec2.add(body1.p, r1);
- Phaser.Vec2Utils.add(body2.position, r2, p2);
- //var p2 = vec2.add(body2.p, r2);
- Advanced.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
- Advanced.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
- // Corrected delta vector
- var dp = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(p2, p1, dp);
- //var dp = vec2.sub(p2, p1);
- // Position constraint
- var c = Phaser.Vec2Utils.dot(dp, n) + con.depth;
- var correction = this.clamp(Advanced.Manager.CONTACT_SOLVER_BAUMGARTE * (c + Advanced.Manager.CONTACT_SOLVER_COLLISION_SLOP), -Advanced.Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
- if(correction == 0) {
- continue;
- }
- // We don't need max_penetration less than or equal slop
- max_penetration = Math.max(max_penetration, -c);
- // Compute lambda for position constraint
- // Solve (J * invM * JT) * lambda = -C / dt
- var sn1 = Phaser.Vec2Utils.cross(r1, n);
- var sn2 = Phaser.Vec2Utils.cross(r2, n);
- var em_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
- var lambda_dt = em_inv == 0 ? 0 : -correction / em_inv;
- // Apply correction impulses
- var impulse_dt = new Phaser.Vec2();
- Phaser.Vec2Utils.scale(n, lambda_dt, impulse_dt);
- //var impulse_dt = vec2.scale(n, lambda_dt);
- body1.position.multiplyAddByScalar(impulse_dt, -m1_inv);
- //body1.p.mad(impulse_dt, -m1_inv);
- body1.angle -= sn1 * lambda_dt * i1_inv;
- body2.position.multiplyAddByScalar(impulse_dt, m2_inv);
- //body2.p.mad(impulse_dt, m2_inv);
- body2.angle += sn2 * lambda_dt * i2_inv;
- Advanced.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
- Advanced.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
- }
- Advanced.Manager.write('max_penetration: ' + max_penetration);
- return max_penetration <= Advanced.Manager.CONTACT_SOLVER_COLLISION_SLOP * 3;
- };
- ContactSolver.prototype.clamp = function (v, min, max) {
- return v < min ? min : (v > max ? max : v);
- };
- return ContactSolver;
- })();
- Advanced.ContactSolver = ContactSolver;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shape - Circle
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Circle = (function (_super) {
- __extends(Circle, _super);
- function Circle(radius, x, y) {
- if (typeof x === "undefined") { x = 0; }
- if (typeof y === "undefined") { y = 0; }
- _super.call(this, Advanced.Manager.SHAPE_TYPE_CIRCLE);
- x = Advanced.Manager.pixelsToMeters(x);
- y = Advanced.Manager.pixelsToMeters(y);
- radius = Advanced.Manager.pixelsToMeters(radius);
- this.center = new Phaser.Vec2(x, y);
- this.radius = radius;
- this.tc = new Phaser.Vec2();
- this.finishVerts();
- }
- Circle.prototype.finishVerts = function () {
- this.radius = Math.abs(this.radius);
- };
- Circle.prototype.duplicate = function () {
- return new Circle(this.center.x, this.center.y, this.radius);
- };
- Circle.prototype.recenter = function (c) {
- this.center.subtract(c);
- };
- Circle.prototype.transform = function (xf) {
- Phaser.TransformUtils.transform(xf, this.center, this.center);
- //this.center = xf.transform(this.center);
- };
- Circle.prototype.untransform = function (xf) {
- Phaser.TransformUtils.untransform(xf, this.center, this.center);
- //this.center = xf.untransform(this.center);
- };
- Circle.prototype.area = function () {
- return Advanced.Manager.areaForCircle(this.radius, 0);
- };
- Circle.prototype.centroid = function () {
- return Phaser.Vec2Utils.clone(this.center);
- };
- Circle.prototype.inertia = function (mass) {
- return Advanced.Manager.inertiaForCircle(mass, this.center, this.radius, 0);
- };
- Circle.prototype.cacheData = function (xf) {
- Phaser.TransformUtils.transform(xf, this.center, this.tc);
- //this.tc = xf.transform(this.center);
- this.bounds.mins.setTo(this.tc.x - this.radius, this.tc.y - this.radius);
- this.bounds.maxs.setTo(this.tc.x + this.radius, this.tc.y + this.radius);
- };
- Circle.prototype.pointQuery = function (p) {
- //return vec2.distsq(this.tc, p) < (this.r * this.r);
- return Phaser.Vec2Utils.distanceSq(this.tc, p) < (this.radius * this.radius);
- };
- Circle.prototype.findVertexByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- if(Phaser.Vec2Utils.distanceSq(this.tc, p) < dsq) {
- return 0;
- }
- return -1;
- };
- Circle.prototype.distanceOnPlane = function (n, d) {
- Phaser.Vec2Utils.dot(n, this.tc) - this.radius - d;
- };
- return Circle;
- })(Phaser.Physics.Advanced.Shape);
- Shapes.Circle = Circle;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Plane
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Plane = (function () {
- function Plane(normal, d) {
- this.normal = normal;
- this.d = d;
- }
- return Plane;
- })();
- Advanced.Plane = Plane;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Convex Polygon
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Poly = (function (_super) {
- __extends(Poly, _super);
- // Verts is an optional array of objects, the objects must have public x and y properties which will be used
- // to seed this polygon (i.e. Vec2 objects, or just straight JS objects) and must wind COUNTER clockwise
- function Poly(verts) {
- _super.call(this, Advanced.Manager.SHAPE_TYPE_POLY);
- this.verts = [];
- this.planes = [];
- this.tverts = [];
- this.tplanes = [];
- if(verts) {
- for(var i = 0; i < verts.length; i++) {
- this.verts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
- this.tverts[i] = this.verts[i];
- //this.tverts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
- this.tplanes[i] = new Phaser.Physics.Advanced.Plane(new Phaser.Vec2(), 0);
- }
- }
- this.finishVerts();
- }
- Poly.prototype.finishVerts = function () {
- if(this.verts.length < 2) {
- this.convexity = false;
- this.planes = [];
- return;
- }
- this.convexity = true;
- this.tverts = [];
- this.tplanes = [];
- // Must be counter-clockwise verts
- for(var i = 0; i < this.verts.length; i++) {
- var a = this.verts[i];
- var b = this.verts[(i + 1) % this.verts.length];
- var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
- this.planes[i] = new Phaser.Physics.Advanced.Plane(n, Phaser.Vec2Utils.dot(n, a));
- this.tverts[i] = Phaser.Vec2Utils.clone(this.verts[i])// reference???
- ;
- //this.tverts[i] = this.verts[i]; // reference???
- this.tplanes[i] = new Phaser.Physics.Advanced.Plane(new Phaser.Vec2(), 0);
- }
- for(var i = 0; i < this.verts.length; i++) {
- //var b = this.verts[(i + 2) % this.verts.length];
- //var n = this.planes[i].normal;
- //var d = this.planes[i].d;
- if(Phaser.Vec2Utils.dot(this.planes[i].normal, this.verts[(i + 2) % this.verts.length]) - this.planes[i].d > 0) {
- this.convexity = false;
- }
- }
- };
- Poly.prototype.duplicate = function () {
- return new Phaser.Physics.Advanced.Shapes.Poly(this.verts);
- };
- Poly.prototype.recenter = function (c) {
- for(var i = 0; i < this.verts.length; i++) {
- this.verts[i].subtract(c);
- }
- };
- Poly.prototype.transform = function (xf) {
- for(var i = 0; i < this.verts.length; i++) {
- this.verts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
- //this.verts[i] = xf.transform(this.verts[i]);
- }
- };
- Poly.prototype.untransform = function (xf) {
- for(var i = 0; i < this.verts.length; i++) {
- this.verts[i] = Phaser.TransformUtils.untransform(xf, this.verts[i]);
- //this.verts[i] = xf.untransform(this.verts[i]);
- }
- };
- Poly.prototype.area = function () {
- return Advanced.Manager.areaForPoly(this.verts);
- };
- Poly.prototype.centroid = function () {
- return Advanced.Manager.centroidForPoly(this.verts);
- };
- Poly.prototype.inertia = function (mass) {
- return Advanced.Manager.inertiaForPoly(mass, this.verts, new Phaser.Vec2());
- };
- Poly.prototype.cacheData = function (xf) {
- this.bounds.clear();
- var numVerts = this.verts.length;
- Advanced.Manager.write('----------- Poly cacheData = ' + numVerts);
- if(numVerts == 0) {
- return;
- }
- for(var i = 0; i < numVerts; i++) {
- this.tverts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
- //this.tverts[i] = xf.transform(this.verts[i]);
- Advanced.Manager.write('tvert' + i + ' = ' + this.tverts[i].toString());
- }
- if(numVerts < 2) {
- this.bounds.addPoint(this.tverts[0]);
- return;
- }
- for(var i = 0; i < numVerts; i++) {
- var a = this.tverts[i];
- var b = this.tverts[(i + 1) % numVerts];
- var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
- Advanced.Manager.write('a = ' + a.toString());
- Advanced.Manager.write('b = ' + b.toString());
- Advanced.Manager.write('n = ' + n.toString());
- this.tplanes[i].normal = n;
- this.tplanes[i].d = Phaser.Vec2Utils.dot(n, a);
- Advanced.Manager.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
- Advanced.Manager.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
- this.bounds.addPoint(a);
- }
- };
- Poly.prototype.pointQuery = function (p) {
- if(!this.bounds.containPoint(p)) {
- return false;
- }
- return this.containPoint(p);
- };
- Poly.prototype.findVertexByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- for(var i = 0; i < this.tverts.length; i++) {
- if(Phaser.Vec2Utils.distanceSq(this.tverts[i], p) < dsq) {
- return i;
- }
- }
- return -1;
- };
- Poly.prototype.findEdgeByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- var numVerts = this.tverts.length;
- for(var i = 0; i < this.tverts.length; i++) {
- var v1 = this.tverts[i];
- var v2 = this.tverts[(i + 1) % numVerts];
- var n = this.tplanes[i].normal;
- var dtv1 = Phaser.Vec2Utils.cross(v1, n);
- var dtv2 = Phaser.Vec2Utils.cross(v2, n);
- var dt = Phaser.Vec2Utils.cross(p, n);
- if(dt > dtv1) {
- if(Phaser.Vec2Utils.distanceSq(v1, p) < dsq) {
- return i;
- }
- } else if(dt < dtv2) {
- if(Phaser.Vec2Utils.distanceSq(v2, p) < dsq) {
- return i;
- }
- } else {
- var dist = Phaser.Vec2Utils.dot(n, p) - Phaser.Vec2Utils.dot(n, v1);
- if(dist * dist < dsq) {
- return i;
- }
- }
- }
- return -1;
- };
- Poly.prototype.distanceOnPlane = function (n, d) {
- var min = 999999;
- for(var i = 0; i < this.verts.length; i++) {
- min = Math.min(min, Phaser.Vec2Utils.dot(n, this.tverts[i]));
- }
- return min - d;
- };
- Poly.prototype.containPoint = function (p) {
- for(var i = 0; i < this.verts.length; i++) {
- var plane = this.tplanes[i];
- if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
- return false;
- }
- }
- return true;
- };
- Poly.prototype.containPointPartial = function (p, n) {
- for(var i = 0; i < this.verts.length; i++) {
- var plane = this.tplanes[i];
- if(Phaser.Vec2Utils.dot(plane.normal, n) < 0.0001) {
- continue;
- }
- if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
- return false;
- }
- }
- return true;
- };
- return Poly;
- })(Phaser.Physics.Advanced.Shape);
- Shapes.Poly = Poly;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Segment
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Segment = (function (_super) {
- __extends(Segment, _super);
- function Segment(a, b, radius) {
- _super.call(this, Advanced.Manager.SHAPE_TYPE_SEGMENT);
- this.a = a.duplicate();
- this.b = b.duplicate();
- this.radius = radius;
- this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(b, a));
- this.normal.normalize();
- this.ta = new Phaser.Vec2();
- this.tb = new Phaser.Vec2();
- this.tn = new Phaser.Vec2();
- this.finishVerts();
- }
- Segment.prototype.finishVerts = function () {
- this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.b, this.a));
- this.normal.normalize();
- this.radius = Math.abs(this.radius);
- };
- Segment.prototype.duplicate = function () {
- return new Phaser.Physics.Advanced.Shapes.Segment(this.a, this.b, this.radius);
- };
- Segment.prototype.recenter = function (c) {
- this.a.subtract(c);
- this.b.subtract(c);
- };
- Segment.prototype.transform = function (xf) {
- Phaser.TransformUtils.transform(xf, this.a, this.a);
- Phaser.TransformUtils.transform(xf, this.b, this.b);
- //this.a = xf.transform(this.a);
- //this.b = xf.transform(this.b);
- };
- Segment.prototype.untransform = function (xf) {
- Phaser.TransformUtils.untransform(xf, this.a, this.a);
- Phaser.TransformUtils.untransform(xf, this.b, this.b);
- //this.a = xf.untransform(this.a);
- //this.b = xf.untransform(this.b);
- };
- Segment.prototype.area = function () {
- return Advanced.Manager.areaForSegment(this.a, this.b, this.radius);
- };
- Segment.prototype.centroid = function () {
- return Advanced.Manager.centroidForSegment(this.a, this.b);
- };
- Segment.prototype.inertia = function (mass) {
- return Advanced.Manager.inertiaForSegment(mass, this.a, this.b);
- };
- Segment.prototype.cacheData = function (xf) {
- Phaser.TransformUtils.transform(xf, this.a, this.ta);
- Phaser.TransformUtils.transform(xf, this.b, this.tb);
- //this.ta = xf.transform(this.a);
- //this.tb = xf.transform(this.b);
- this.tn = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.tb, this.ta)).normalize();
- var l;
- var r;
- var t;
- var b;
- if(this.ta.x < this.tb.x) {
- l = this.ta.x;
- r = this.tb.x;
- } else {
- l = this.tb.x;
- r = this.ta.x;
- }
- if(this.ta.y < this.tb.y) {
- b = this.ta.y;
- t = this.tb.y;
- } else {
- b = this.tb.y;
- t = this.ta.y;
- }
- this.bounds.mins.setTo(l - this.radius, b - this.radius);
- this.bounds.maxs.setTo(r + this.radius, t + this.radius);
- };
- Segment.prototype.pointQuery = function (p) {
- if(!this.bounds.containPoint(p)) {
- return false;
- }
- var dn = Phaser.Vec2Utils.dot(this.tn, p) - Phaser.Vec2Utils.dot(this.ta, this.tn);
- var dist = Math.abs(dn);
- if(dist > this.radius) {
- return false;
- }
- var dt = Phaser.Vec2Utils.cross(p, this.tn);
- var dta = Phaser.Vec2Utils.cross(this.ta, this.tn);
- var dtb = Phaser.Vec2Utils.cross(this.tb, this.tn);
- if(dt <= dta) {
- if(dt < dta - this.radius) {
- return false;
- }
- return Phaser.Vec2Utils.distanceSq(this.ta, p) < (this.radius * this.radius);
- } else if(dt > dtb) {
- if(dt > dtb + this.radius) {
- return false;
- }
- return Phaser.Vec2Utils.distanceSq(this.tb, p) < (this.radius * this.radius);
- }
- return true;
- };
- Segment.prototype.findVertexByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- if(Phaser.Vec2Utils.distanceSq(this.ta, p) < dsq) {
- return 0;
- }
- if(Phaser.Vec2Utils.distanceSq(this.tb, p) < dsq) {
- return 1;
- }
- return -1;
- };
- Segment.prototype.distanceOnPlane = function (n, d) {
- var a = Phaser.Vec2Utils.dot(n, this.ta) - this.radius;
- var b = Phaser.Vec2Utils.dot(n, this.tb) - this.radius;
- return Math.min(a, b) - d;
- };
- return Segment;
- })(Phaser.Physics.Advanced.Shape);
- Shapes.Segment = Segment;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Collision Handlers
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Collision = (function () {
- function Collision() {
- }
- Collision.prototype.collide = function (a, b, contacts) {
- // Circle (a is the circle)
- if(a.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- if(b.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- return this.circle2Circle(a, b, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- return this.circle2Segment(a, b, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- return this.circle2Poly(a, b, contacts);
- }
- }
- // Segment (a is the segment)
- if(a.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- if(b.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- return this.circle2Segment(b, a, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- return this.segment2Segment(a, b, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- return this.segment2Poly(a, b, contacts);
- }
- }
- // Poly (a is the poly)
- if(a.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- if(b.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- return this.circle2Poly(b, a, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- return this.segment2Poly(b, a, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- return this.poly2Poly(a, b, contacts);
- }
- }
- };
- Collision.prototype._circle2Circle = function (c1, r1, c2, r2, contactArr) {
- var rmax = r1 + r2;
- var t = new Phaser.Vec2();
- //var t = vec2.sub(c2, c1);
- Phaser.Vec2Utils.subtract(c2, c1, t);
- var distsq = t.lengthSq();
- if(distsq > rmax * rmax) {
- return 0;
- }
- var dist = Math.sqrt(distsq);
- var p = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(c1, t, 0.5 + (r1 - r2) * 0.5 / dist, p);
- //var p = vec2.mad(c1, t, 0.5 + (r1 - r2) * 0.5 / dist);
- var n = new Phaser.Vec2();
- //var n = (dist != 0) ? vec2.scale(t, 1 / dist) : vec2.zero;
- if(dist != 0) {
- Phaser.Vec2Utils.scale(t, 1 / dist, n);
- }
- var d = dist - rmax;
- contactArr.push(new Advanced.Contact(p, n, d, 0));
- return 1;
- };
- Collision.prototype.circle2Circle = function (circ1, circ2, contactArr) {
- return this._circle2Circle(circ1.tc, circ1.radius, circ2.tc, circ2.radius, contactArr);
- };
- Collision.prototype.circle2Segment = function (circ, seg, contactArr) {
- var rsum = circ.radius + seg.radius;
- // Normal distance from segment
- var dn = Phaser.Vec2Utils.dot(circ.tc, seg.tn) - Phaser.Vec2Utils.dot(seg.ta, seg.tn);
- var dist = (dn < 0 ? dn * -1 : dn) - rsum;
- if(dist > 0) {
- return 0;
- }
- // Tangential distance along segment
- var dt = Phaser.Vec2Utils.cross(circ.tc, seg.tn);
- var dtMin = Phaser.Vec2Utils.cross(seg.ta, seg.tn);
- var dtMax = Phaser.Vec2Utils.cross(seg.tb, seg.tn);
- if(dt < dtMin) {
- if(dt < dtMin - rsum) {
- return 0;
- }
- return this._circle2Circle(circ.tc, circ.radius, seg.ta, seg.radius, contactArr);
- } else if(dt > dtMax) {
- if(dt > dtMax + rsum) {
- return 0;
- }
- return this._circle2Circle(circ.tc, circ.radius, seg.tb, seg.radius, contactArr);
- }
- var n = new Phaser.Vec2();
- if(dn > 0) {
- n.copyFrom(seg.tn);
- } else {
- Phaser.Vec2Utils.negative(seg.tn, n);
- }
- //var n = (dn > 0) ? seg.tn : vec2.neg(seg.tn);
- var c1 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + dist * 0.5), c1);
- var c2 = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(n, c2);
- contactArr.push(new Advanced.Contact(c1, c2, dist, 0));
- //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + dist * 0.5)), vec2.neg(n), dist, 0));
- return 1;
- };
- Collision.prototype.circle2Poly = function (circ, poly, contactArr) {
- var minDist = -999999;
- var minIdx = -1;
- for(var i = 0; i < poly.verts.length; i++) {
- var plane = poly.tplanes[i];
- var dist = Phaser.Vec2Utils.dot(circ.tc, plane.normal) - plane.d - circ.radius;
- if(dist > 0) {
- return 0;
- } else if(dist > minDist) {
- minDist = dist;
- minIdx = i;
- }
- }
- var n = poly.tplanes[minIdx].normal;
- var a = poly.tverts[minIdx];
- var b = poly.tverts[(minIdx + 1) % poly.verts.length];
- var dta = Phaser.Vec2Utils.cross(a, n);
- var dtb = Phaser.Vec2Utils.cross(b, n);
- var dt = Phaser.Vec2Utils.cross(circ.tc, n);
- if(dt > dta) {
- return this._circle2Circle(circ.tc, circ.radius, a, 0, contactArr);
- } else if(dt < dtb) {
- return this._circle2Circle(circ.tc, circ.radius, b, 0, contactArr);
- }
- var c1 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + minDist * 0.5), c1);
- var c2 = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(n, c2);
- contactArr.push(new Advanced.Contact(c1, c2, minDist, 0));
- //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + minDist * 0.5)), vec2.neg(n), minDist, 0));
- return 1;
- };
- Collision.prototype.segmentPointDistanceSq = function (seg, p) {
- var w = new Phaser.Vec2();
- var d = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(p, seg.ta, w);
- Phaser.Vec2Utils.subtract(seg.tb, seg.ta, d);
- //var w = vec2.sub(p, seg.ta);
- //var d = vec2.sub(seg.tb, seg.ta);
- var proj = w.dot(d);
- if(proj <= 0) {
- return w.dot(w);
- }
- var vsq = d.dot(d);
- if(proj >= vsq) {
- return w.dot(w) - 2 * proj + vsq;
- }
- return w.dot(w) - proj * proj / vsq;
- };
- Collision.prototype.segment2Segment = // FIXME and optimise me lots!!!
- function (seg1, seg2, contactArr) {
- var d = [];
- d[0] = this.segmentPointDistanceSq(seg1, seg2.ta);
- d[1] = this.segmentPointDistanceSq(seg1, seg2.tb);
- d[2] = this.segmentPointDistanceSq(seg2, seg1.ta);
- d[3] = this.segmentPointDistanceSq(seg2, seg1.tb);
- var idx1 = d[0] < d[1] ? 0 : 1;
- var idx2 = d[2] < d[3] ? 2 : 3;
- var idxm = d[idx1] < d[idx2] ? idx1 : idx2;
- var s, t;
- var u = Phaser.Vec2Utils.subtract(seg1.tb, seg1.ta);
- var v = Phaser.Vec2Utils.subtract(seg2.tb, seg2.ta);
- switch(idxm) {
- case 0:
- s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.ta, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
- s = s < 0 ? 0 : (s > 1 ? 1 : s);
- t = 0;
- break;
- case 1:
- s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.tb, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
- s = s < 0 ? 0 : (s > 1 ? 1 : s);
- t = 1;
- break;
- case 2:
- s = 0;
- t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.ta, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
- t = t < 0 ? 0 : (t > 1 ? 1 : t);
- break;
- case 3:
- s = 1;
- t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.tb, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
- t = t < 0 ? 0 : (t > 1 ? 1 : t);
- break;
- }
- var minp1 = Phaser.Vec2Utils.multiplyAdd(seg1.ta, u, s);
- var minp2 = Phaser.Vec2Utils.multiplyAdd(seg2.ta, v, t);
- return this._circle2Circle(minp1, seg1.radius, minp2, seg2.radius, contactArr);
- };
- Collision.prototype.findPointsBehindSeg = // Identify vertexes that have penetrated the segment.
- function (contactArr, seg, poly, dist, coef) {
- var dta = Phaser.Vec2Utils.cross(seg.tn, seg.ta);
- var dtb = Phaser.Vec2Utils.cross(seg.tn, seg.tb);
- var n = new Phaser.Vec2();
- Phaser.Vec2Utils.scale(seg.tn, coef, n);
- //var n = vec2.scale(seg.tn, coef);
- for(var i = 0; i < poly.verts.length; i++) {
- var v = poly.tverts[i];
- if(Phaser.Vec2Utils.dot(v, n) < Phaser.Vec2Utils.dot(seg.tn, seg.ta) * coef + seg.radius) {
- var dt = Phaser.Vec2Utils.cross(seg.tn, v);
- if(dta >= dt && dt >= dtb) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly.id << 16) | i));
- }
- }
- }
- };
- Collision.prototype.segment2Poly = function (seg, poly, contactArr) {
- var seg_td = Phaser.Vec2Utils.dot(seg.tn, seg.ta);
- var seg_d1 = poly.distanceOnPlane(seg.tn, seg_td) - seg.radius;
- if(seg_d1 > 0) {
- return 0;
- }
- var n = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(seg.tn, n);
- var seg_d2 = poly.distanceOnPlane(n, -seg_td) - seg.radius;
- //var seg_d2 = poly.distanceOnPlane(vec2.neg(seg.tn), -seg_td) - seg.r;
- if(seg_d2 > 0) {
- return 0;
- }
- var poly_d = -999999;
- var poly_i = -1;
- for(var i = 0; i < poly.verts.length; i++) {
- var plane = poly.tplanes[i];
- var dist = seg.distanceOnPlane(plane.normal, plane.d);
- if(dist > 0) {
- return 0;
- }
- if(dist > poly_d) {
- poly_d = dist;
- poly_i = i;
- }
- }
- var poly_n = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(poly.tplanes[poly_i].normal, poly_n);
- //var poly_n = vec2.neg(poly.tplanes[poly_i].n);
- var va = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(seg.ta, poly_n, seg.radius, va);
- //var va = vec2.mad(seg.ta, poly_n, seg.r);
- var vb = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(seg.tb, poly_n, seg.radius, vb);
- //var vb = vec2.mad(seg.tb, poly_n, seg.r);
- if(poly.containPoint(va)) {
- contactArr.push(new Advanced.Contact(va, poly_n, poly_d, (seg.id << 16) | 0));
- }
- if(poly.containPoint(vb)) {
- contactArr.push(new Advanced.Contact(vb, poly_n, poly_d, (seg.id << 16) | 1));
- }
- // Floating point precision problems here.
- // This will have to do for now.
- poly_d -= 0.1;
- if(seg_d1 >= poly_d || seg_d2 >= poly_d) {
- if(seg_d1 > seg_d2) {
- this.findPointsBehindSeg(contactArr, seg, poly, seg_d1, 1);
- } else {
- this.findPointsBehindSeg(contactArr, seg, poly, seg_d2, -1);
- }
- }
- // If no other collision points are found, try colliding endpoints.
- if(contactArr.length == 0) {
- var poly_a = poly.tverts[poly_i];
- var poly_b = poly.tverts[(poly_i + 1) % poly.verts.length];
- if(this._circle2Circle(seg.ta, seg.radius, poly_a, 0, contactArr)) {
- return 1;
- }
- if(this._circle2Circle(seg.tb, seg.radius, poly_a, 0, contactArr)) {
- return 1;
- }
- if(this._circle2Circle(seg.ta, seg.radius, poly_b, 0, contactArr)) {
- return 1;
- }
- if(this._circle2Circle(seg.tb, seg.radius, poly_b, 0, contactArr)) {
- return 1;
- }
- }
- return contactArr.length;
- };
- Collision.prototype.findMSA = // Find the minimum separating axis for the given poly and plane list.
- function (poly, planes, num) {
- var min_dist = -999999;
- var min_index = -1;
- for(var i = 0; i < num; i++) {
- var dist = poly.distanceOnPlane(planes[i].normal, planes[i].d);
- if(dist > 0) {
- // no collision
- return {
- dist: 0,
- index: -1
- };
- } else if(dist > min_dist) {
- min_dist = dist;
- min_index = i;
- }
- }
- // new object - see what we can do here
- return {
- dist: min_dist,
- index: min_index
- };
- };
- Collision.prototype.findVertsFallback = function (contactArr, poly1, poly2, n, dist) {
- var num = 0;
- for(var i = 0; i < poly1.verts.length; i++) {
- var v = poly1.tverts[i];
- if(poly2.containPointPartial(v, n)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly1.id << 16) | i));
- num++;
- }
- }
- for(var i = 0; i < poly2.verts.length; i++) {
- var v = poly2.tverts[i];
- if(poly1.containPointPartial(v, n)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly2.id << 16) | i));
- num++;
- }
- }
- return num;
- };
- Collision.prototype.findVerts = // Find the overlapped vertices.
- function (contactArr, poly1, poly2, n, dist) {
- var num = 0;
- for(var i = 0; i < poly1.verts.length; i++) {
- var v = poly1.tverts[i];
- if(poly2.containPoint(v)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly1.id << 16) | i));
- num++;
- }
- }
- for(var i = 0; i < poly2.verts.length; i++) {
- var v = poly2.tverts[i];
- if(poly1.containPoint(v)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly2.id << 16) | i));
- num++;
- }
- }
- return num > 0 ? num : this.findVertsFallback(contactArr, poly1, poly2, n, dist);
- };
- Collision.prototype.poly2Poly = function (poly1, poly2, contactArr) {
- var msa1 = this.findMSA(poly2, poly1.tplanes, poly1.verts.length);
- if(msa1.index == -1) {
- console.log('poly2poly 0', msa1);
- return 0;
- }
- var msa2 = this.findMSA(poly1, poly2.tplanes, poly2.verts.length);
- if(msa2.index == -1) {
- console.log('poly2poly 1', msa2);
- return 0;
- }
- // Penetration normal direction should be from poly1 to poly2
- if(msa1.dist > msa2.dist) {
- return this.findVerts(contactArr, poly1, poly2, poly1.tplanes[msa1.index].normal, msa1.dist);
- }
- return this.findVerts(contactArr, poly1, poly2, Phaser.Vec2Utils.negative(poly2.tplanes[msa2.index].normal), msa2.dist);
- };
- return Collision;
- })();
- Advanced.Collision = Collision;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Space
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Space = (function () {
- function Space() {
- this.stepCount = 0;
- this.bodies = [];
- this.bodyHash = {
- };
- this.joints = [];
- this.jointHash = {
- };
- this.numContacts = 0;
- this.contactSolvers = [];
- //this.postSolve(arb) { };
- this.gravity = new Phaser.Vec2(0, 10);
- this.damping = 0;
- this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE;
- this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE;
- }
- Space.TIME_TO_SLEEP = 0.5;
- Space.SLEEP_LINEAR_TOLERANCE = 0.5;
- Space.SLEEP_ANGULAR_TOLERANCE = 2 * Phaser.GameMath.DEG_TO_RAD;
- Space.prototype.clear = function () {
- Advanced.Manager.shapeCounter = 0;
- Advanced.Manager.bodyCounter = 0;
- Advanced.Manager.jointCounter = 0;
- for(var i = 0; i < this.bodies.length; i++) {
- if(this.bodies[i]) {
- this.removeBody(this.bodies[i]);
- }
- }
- this.bodies = [];
- this.bodyHash = {
- };
- this.joints = [];
- this.jointHash = {
- };
- this.contactSolvers = [];
- this.stepCount = 0;
- };
- Space.prototype.addBody = function (body) {
- if(this.bodyHash[body.id] != undefined) {
- return;
- }
- var index = this.bodies.push(body) - 1;
- this.bodyHash[body.id] = index;
- body.awake(true);
- body.space = this;
- body.cacheData('addBody');
- };
- Space.prototype.removeBody = function (body) {
- if(this.bodyHash[body.id] == undefined) {
- return;
- }
- // Remove linked joints
- for(var i = 0; i < body.joints.length; i++) {
- if(body.joints[i]) {
- this.removeJoint(body.joints[i]);
- }
- }
- body.space = null;
- var index = this.bodyHash[body.id];
- delete this.bodyHash[body.id];
- delete this.bodies[index];
- };
- Space.prototype.addJoint = function (joint) {
- if(this.jointHash[joint.id] != undefined) {
- return;
- }
- joint.body1.awake(true);
- joint.body2.awake(true);
- var index = this.joints.push(joint) - 1;
- this.jointHash[joint.id] = index;
- var index = joint.body1.joints.push(joint) - 1;
- joint.body1.jointHash[joint.id] = index;
- var index = joint.body2.joints.push(joint) - 1;
- joint.body2.jointHash[joint.id] = index;
- };
- Space.prototype.removeJoint = function (joint) {
- if(this.jointHash[joint.id] == undefined) {
- return;
- }
- joint.body1.awake(true);
- joint.body2.awake(true);
- var index = joint.body1.jointHash[joint.id];
- delete joint.body1.jointHash[joint.id];
- delete joint.body1.joints[index];
- var index = joint.body2.jointHash[joint.id];
- delete joint.body2.jointHash[joint.id];
- delete joint.body2.joints[index];
- var index = this.jointHash[joint.id];
- delete this.jointHash[joint.id];
- delete this.joints[index];
- };
- Space.prototype.findShapeByPoint = function (p, refShape) {
- var firstShape;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- if(shape.pointQuery(p)) {
- if(!refShape) {
- return shape;
- }
- if(!firstShape) {
- firstShape = shape;
- }
- if(shape == refShape) {
- refShape = null;
- }
- }
- }
- }
- return firstShape;
- };
- Space.prototype.findBodyByPoint = function (p, refBody) {
- var firstBody;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- if(shape.pointQuery(p)) {
- if(!refBody) {
- return shape.body;
- }
- if(!firstBody) {
- firstBody = shape.body;
- }
- if(shape.body == refBody) {
- refBody = null;
- }
- break;
- }
- }
- }
- return firstBody;
- };
- Space.prototype.shapeById = function (id) {
- var shape;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- if(body.shapes[j].id == id) {
- return body.shapes[j];
- }
- }
- }
- return null;
- };
- Space.prototype.jointById = function (id) {
- var index = this.jointHash[id];
- if(index != undefined) {
- return this.joints[index];
- }
- return null;
- };
- Space.prototype.findVertexByPoint = function (p, minDist, refVertexId) {
- var firstVertexId = -1;
- refVertexId = refVertexId || -1;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- var index = shape.findVertexByPoint(p, minDist);
- if(index != -1) {
- var vertex = (shape.id << 16) | index;
- if(refVertexId == -1) {
- return vertex;
- }
- if(firstVertexId == -1) {
- firstVertexId = vertex;
- }
- if(vertex == refVertexId) {
- refVertexId = -1;
- }
- }
- }
- }
- return firstVertexId;
- };
- Space.prototype.findEdgeByPoint = function (p, minDist, refEdgeId) {
- var firstEdgeId = -1;
- refEdgeId = refEdgeId || -1;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- if(shape.type != Advanced.Manager.SHAPE_TYPE_POLY) {
- continue;
- }
- var index = shape.findEdgeByPoint(p, minDist);
- if(index != -1) {
- var edge = (shape.id << 16) | index;
- if(refEdgeId == -1) {
- return edge;
- }
- if(firstEdgeId == -1) {
- firstEdgeId = edge;
- }
- if(edge == refEdgeId) {
- refEdgeId = -1;
- }
- }
- }
- }
- return firstEdgeId;
- };
- Space.prototype.findJointByPoint = function (p, minDist, refJointId) {
- var firstJointId = -1;
- var dsq = minDist * minDist;
- refJointId = refJointId || -1;
- for(var i = 0; i < this.joints.length; i++) {
- var joint = this.joints[i];
- if(!joint) {
- continue;
- }
- var jointId = -1;
- if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor1()) < dsq) {
- jointId = (joint.id << 16 | 0);
- } else if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor2()) < dsq) {
- jointId = (joint.id << 16 | 1);
- }
- if(jointId != -1) {
- if(refJointId == -1) {
- return jointId;
- }
- if(firstJointId == -1) {
- firstJointId = jointId;
- }
- if(jointId == refJointId) {
- refJointId = -1;
- }
- }
- }
- return firstJointId;
- };
- Space.prototype.findContactSolver = function (shape1, shape2) {
- Advanced.Manager.write('findContactSolver. Length: ' + this._cl);
- for(var i = 0; i < this._cl; i++) {
- var contactSolver = this.contactSolvers[i];
- if(shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) {
- return contactSolver;
- }
- }
- return null;
- };
- Space.prototype.genTemporalContactSolvers = function () {
- Advanced.Manager.write('genTemporalContactSolvers');
- this._cl = 0;
- this.contactSolvers.length = 0;
- this.numContacts = 0;
- for(var body1Index = 0; body1Index < this._bl; body1Index++) {
- if(!this.bodies[body1Index]) {
- continue;
- }
- this.bodies[body1Index].stepCount = this.stepCount;
- for(var body2Index = 0; body2Index < this._bl; body2Index++) {
- if(this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) {
- continue;
- }
- Advanced.Manager.write('body1 and body2 intersect');
- for(var i = 0; i < this.bodies[body1Index].shapesLength; i++) {
- for(var j = 0; j < this.bodies[body2Index].shapesLength; j++) {
- this._shape1 = this.bodies[body1Index].shapes[i];
- this._shape2 = this.bodies[body2Index].shapes[j];
- var contactArr = [];
- if(!Advanced.Manager.collision.collide(this._shape1, this._shape2, contactArr)) {
- continue;
- }
- if(this._shape1.type > this._shape2.type) {
- var temp = this._shape1;
- this._shape1 = this._shape2;
- this._shape2 = temp;
- }
- this.numContacts += contactArr.length;
- // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers)
- var contactSolver = this.findContactSolver(this._shape1, this._shape2);
- Advanced.Manager.write('findContactSolver result: ' + contactSolver);
- if(contactSolver) {
- contactSolver.update(contactArr);
- this.contactSolvers.push(contactSolver);
- } else {
- Advanced.Manager.write('awake both bodies');
- this.bodies[body1Index].awake(true);
- this.bodies[body2Index].awake(true);
- var newContactSolver = new Advanced.ContactSolver(this._shape1, this._shape2);
- newContactSolver.contacts = contactArr;
- newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity);
- newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction);
- this.contactSolvers.push(newContactSolver);
- Advanced.Manager.write('new contact solver');
- }
- }
- }
- }
- }
- this._cl = this.contactSolvers.length;
- };
- Space.prototype.initSolver = function (warmStarting) {
- Advanced.Manager.write('initSolver');
- Advanced.Manager.write('contactSolvers.length: ' + this._cl);
- // Initialize contact solvers
- for(var c = 0; c < this._cl; c++) {
- this.contactSolvers[c].initSolver(this._deltaInv);
- // Warm starting (apply cached impulse)
- if(warmStarting) {
- this.contactSolvers[c].warmStart();
- }
- }
- // Initialize joint solver
- for(var j = 0; j < this.joints.length; j++) {
- if(this.joints[j]) {
- this.joints[j].initSolver(this._delta, warmStarting);
- }
- }
- // Warm starting (apply cached impulse)
- /*
- if (warmStarting)
- {
- for (var c = 0; c < this._cl; c++)
- {
- this.contactSolvers[c].warmStart();
- }
- }
- */
- };
- Space.prototype.velocitySolver = function (iterations) {
- Advanced.Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl);
- for(var i = 0; i < iterations; i++) {
- for(var j = 0; j < this._jl; j++) {
- if(this.joints[j]) {
- this.joints[j].solveVelocityConstraints();
- }
- }
- for(var c = 0; c < this._cl; c++) {
- this.contactSolvers[c].solveVelocityConstraints();
- }
- }
- };
- Space.prototype.positionSolver = function (iterations) {
- this._positionSolved = false;
- for(var i = 0; i < iterations; i++) {
- this._contactsOk = true;
- this._jointsOk = true;
- for(var c = 0; c < this._cl; c++) {
- this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk;
- }
- for(var j = 0; j < this._jl; j++) {
- if(this.joints[j]) {
- this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk;
- }
- }
- if(this._contactsOk && this._jointsOk) {
- // exit early if the position errors are small
- this._positionSolved = true;
- break;
- }
- }
- return this._positionSolved;
- };
- Space.prototype.step = // Step through the physics simulation
- function (dt, velocityIterations, positionIterations, warmStarting, allowSleep) {
- Advanced.Manager.clear();
- Advanced.Manager.write('Space step ' + this.stepCount);
- this._delta = dt;
- this._deltaInv = 1 / dt;
- this._bl = this.bodies.length;
- this._jl = this.joints.length;
- this.stepCount++;
- // 1) Generate Contact Solvers (into the this.contactSolvers array)
- this.genTemporalContactSolvers();
- Advanced.Manager.dump("Contact Solvers", this.bodies[1]);
- // 2) Initialize the Contact Solvers
- this.initSolver(warmStarting);
- Advanced.Manager.dump("Init Solver", this.bodies[1]);
- // 3) Intergrate velocity
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
- this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping);
- }
- }
- Advanced.Manager.dump("Update Velocity", this.bodies[1]);
- // 4) Awaken bodies via joints
- for(var j = 0; i < this._jl; j++) {
- if(!this.joints[j]) {
- continue;
- }
- // combine
- var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic;
- var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic;
- if(awake1 ^ awake2) {
- if(!awake1) {
- this.joints[j].body1.awake(true);
- }
- if(!awake2) {
- this.joints[j].body2.awake(true);
- }
- }
- }
- // 5) Iterative velocity constraints solver
- this.velocitySolver(velocityIterations);
- Advanced.Manager.dump("Velocity Solvers", this.bodies[1]);
- // 6) Intergrate position
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
- this.bodies[i].updatePosition(this._delta);
- }
- }
- Advanced.Manager.dump("Update Position", this.bodies[1]);
- // 7) Process breakable joint
- for(var i = 0; i < this._jl; i++) {
- if(this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) {
- this.removeJoint(this.joints[i]);
- }
- }
- // 8) Iterative position constraints solver (result stored in this._positionSolved)
- this.positionSolver(positionIterations);
- Advanced.Manager.dump("Position Solver", this.bodies[1]);
- // 9) Sync the Transforms
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i]) {
- this.bodies[i].syncTransform();
- }
- }
- Advanced.Manager.dump("Sync Transform", this.bodies[1]);
- // 10) Post solve collision callback
- if(this.postSolve) {
- for(var i = 0; i < this._cl; i++) {
- this.postSolve(this.contactSolvers[i]);
- }
- }
- // 11) Cache Body Data
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
- this.bodies[i].cacheData('post solve collision callback');
- }
- }
- Advanced.Manager.dump("Cache Data", this.bodies[1]);
- Advanced.Manager.writeAll();
- // 12) Process sleeping
- if(allowSleep) {
- this._minSleepTime = 999999;
- for(var i = 0; i < this._bl; i++) {
- if(!this.bodies[i] || this.bodies[i].isDynamic == false) {
- continue;
- }
- if(this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) {
- this.bodies[i].sleepTime = 0;
- this._minSleepTime = 0;
- } else {
- this.bodies[i].sleepTime += this._delta;
- this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime);
- }
- }
- if(this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) {
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i]) {
- this.bodies[i].awake(false);
- }
- }
- }
- }
- };
- return Space;
- })();
- Advanced.Space = Space;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Triangle
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Triangle = (function (_super) {
- __extends(Triangle, _super);
- function Triangle(x1, y1, x2, y2, x3, y3) {
- x1 = Advanced.Manager.pixelsToMeters(x1);
- y1 = Advanced.Manager.pixelsToMeters(y1);
- x2 = Advanced.Manager.pixelsToMeters(x2);
- y2 = Advanced.Manager.pixelsToMeters(y2);
- x3 = Advanced.Manager.pixelsToMeters(x3);
- y3 = Advanced.Manager.pixelsToMeters(y3);
- _super.call(this, [
- {
- x: x1,
- y: y1
- },
- {
- x: x2,
- y: y2
- },
- {
- x: x3,
- y: y3
- }
- ]);
- }
- return Triangle;
- })(Phaser.Physics.Advanced.Shapes.Poly);
- Shapes.Triangle = Triangle;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Box
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Box = (function (_super) {
- __extends(Box, _super);
- // Give in pixels
- function Box(x, y, width, height) {
- //x = Manager.pixelsToMeters(x);
- //y = Manager.pixelsToMeters(y);
- //width = Manager.pixelsToMeters(width);
- //height = Manager.pixelsToMeters(height);
- var hw = width * 0.5;
- var hh = height * 0.5;
- _super.call(this, [
- {
- x: -hw + x,
- y: +hh + y
- },
- {
- x: -hw + x,
- y: -hh + y
- },
- {
- x: +hw + x,
- y: -hh + y
- },
- {
- x: +hw + x,
- y: +hh + y
- }
- ]);
- }
- return Box;
- })(Phaser.Physics.Advanced.Shapes.Poly);
- Shapes.Box = Box;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Body
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Body = (function () {
- function Body(sprite, type, x, y) {
- if (typeof x === "undefined") { x = 0; }
- if (typeof y === "undefined") { y = 0; }
- this._tempVec2 = new Phaser.Vec2();
- // Shapes
- this.shapes = [];
- // Joints
- this.joints = [];
- this.jointHash = {
- };
- this.fixedRotation = false;
- this.categoryBits = 0x0001;
- this.maskBits = 0xFFFF;
- this.stepCount = 0;
- this.id = Phaser.Physics.Advanced.Manager.bodyCounter++;
- this.name = 'body' + this.id;
- this.type = type;
- if(sprite) {
- this.sprite = sprite;
- this.game = sprite.game;
- this.position = new Phaser.Vec2(Phaser.Physics.Advanced.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Advanced.Manager.pixelsToMeters(sprite.y));
- this.angle = sprite.rotation;
- } else {
- this.position = new Phaser.Vec2(Phaser.Physics.Advanced.Manager.pixelsToMeters(x), Phaser.Physics.Advanced.Manager.pixelsToMeters(y));
- this.angle = 0;
- }
- this.transform = new Phaser.Transform(this.position, this.angle);
- this.centroid = new Phaser.Vec2();
- this.velocity = new Phaser.Vec2();
- this.force = new Phaser.Vec2();
- this.angularVelocity = 0;
- this.torque = 0;
- this.linearDamping = 0;
- this.angularDamping = 0;
- this.sleepTime = 0;
- this.awaked = false;
- this.shapes = [];
- this.joints = [];
- this.jointHash = {
- };
- this.bounds = new Advanced.Bounds();
- this.fixedRotation = false;
- this.categoryBits = 0x0001;
- this.maskBits = 0xFFFF;
- this.stepCount = 0;
- }
- Body.prototype.toString = function () {
- return "[{Body (name=" + this.name + " velocity=" + this.velocity.toString() + " angularVelocity: " + this.angularVelocity + ")}]";
- };
- Body.prototype.duplicate = function () {
- //console.log('body duplicate called');
- //var body = new Body(this.type, this.transform.t, this.angle);
- //for (var i = 0; i < this.shapes.length; i++)
- //{
- // body.addShape(this.shapes[i].duplicate());
- //}
- //body.resetMassData();
- //return body;
- };
- Object.defineProperty(Body.prototype, "isDisabled", {
- get: function () {
- return this.type == Phaser.Types.BODY_DISABLED ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "isStatic", {
- get: function () {
- return this.type == Phaser.Types.BODY_STATIC ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "isKinetic", {
- get: function () {
- return this.type == Phaser.Types.BODY_KINETIC ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "isDynamic", {
- get: function () {
- return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Body.prototype.setType = function (type) {
- if(type == this.type) {
- return;
- }
- this.force.setTo(0, 0);
- this.velocity.setTo(0, 0);
- this.torque = 0;
- this.angularVelocity = 0;
- this.type = type;
- this.awake(true);
- };
- Body.prototype.addPoly = function (verts, elasticity, friction, density) {
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var poly = new Phaser.Physics.Advanced.Shapes.Poly(verts);
- poly.elasticity = elasticity;
- poly.friction = friction;
- poly.density = density;
- this.addShape(poly);
- this.resetMassData();
- return poly;
- };
- Body.prototype.addTriangle = function (x1, y1, x2, y2, x3, y3, elasticity, friction, density) {
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var tri = new Phaser.Physics.Advanced.Shapes.Triangle(x1, y1, x2, y2, x3, y3);
- tri.elasticity = elasticity;
- tri.friction = friction;
- tri.density = density;
- this.addShape(tri);
- this.resetMassData();
- return tri;
- };
- Body.prototype.addBox = function (x, y, width, height, elasticity, friction, density) {
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var box = new Phaser.Physics.Advanced.Shapes.Box(x, y, width, height);
- box.elasticity = elasticity;
- box.friction = friction;
- box.density = density;
- this.addShape(box);
- this.resetMassData();
- return box;
- };
- Body.prototype.addCircle = function (radius, x, y, elasticity, friction, density) {
- if (typeof x === "undefined") { x = 0; }
- if (typeof y === "undefined") { y = 0; }
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var circle = new Phaser.Physics.Advanced.Shapes.Circle(radius, x, y);
- circle.elasticity = elasticity;
- circle.friction = friction;
- circle.density = density;
- this.addShape(circle);
- this.resetMassData();
- return circle;
- };
- Body.prototype.addShape = function (shape) {
- // Check not already part of this body
- shape.body = this;
- this.shapes.push(shape);
- this.shapesLength = this.shapes.length;
- return shape;
- };
- Body.prototype.removeShape = function (shape) {
- var index = this.shapes.indexOf(shape);
- if(index != -1) {
- this.shapes.splice(index, 1);
- shape.body = undefined;
- }
- this.shapesLength = this.shapes.length;
- };
- Body.prototype.setMass = function (mass) {
- this.mass = mass;
- this.massInverted = mass > 0 ? 1 / mass : 0;
- };
- Body.prototype.setInertia = function (inertia) {
- this.inertia = inertia;
- this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
- };
- Body.prototype.setTransform = function (pos, angle) {
- this.transform.setTo(pos, angle);
- // inject the transform into this.position
- Advanced.Manager.write('setTransform: ' + this.position.toString());
- Advanced.Manager.write('centroid: ' + this.centroid.toString());
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- Advanced.Manager.write('post setTransform: ' + this.position.toString());
- //this.position.copyFrom(this.transform.transform(this.centroid));
- this.angle = angle;
- };
- Body.prototype.syncTransform = function () {
- Advanced.Manager.write('syncTransform:');
- Advanced.Manager.write('p: ' + this.position.toString());
- Advanced.Manager.write('centroid: ' + this.centroid.toString());
- Advanced.Manager.write('xf: ' + this.transform.toString());
- Advanced.Manager.write('a: ' + this.angle);
- this.transform.setRotation(this.angle);
- // OPTIMISE: Creating new vector
- Phaser.Vec2Utils.subtract(this.position, Phaser.TransformUtils.rotate(this.transform, this.centroid), this.transform.t);
- Advanced.Manager.write('--------------------');
- Advanced.Manager.write('xf: ' + this.transform.toString());
- Advanced.Manager.write('--------------------');
- };
- Body.prototype.getWorldPoint = function (p) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.transform(this.transform, p);
- };
- Body.prototype.getWorldVector = function (v) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.rotate(this.transform, v);
- };
- Body.prototype.getLocalPoint = function (p) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.untransform(this.transform, p);
- };
- Body.prototype.getLocalVector = function (v) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.unrotate(this.transform, v);
- };
- Body.prototype.setFixedRotation = function (flag) {
- this.fixedRotation = flag;
- this.resetMassData();
- };
- Body.prototype.resetMassData = function () {
- this.centroid.setTo(0, 0);
- this.mass = 0;
- this.massInverted = 0;
- this.inertia = 0;
- this.inertiaInverted = 0;
- if(this.isDynamic == false) {
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- //this.position.copyFrom(this.transform.transform(this.centroid));
- return;
- }
- var totalMassCentroid = new Phaser.Vec2(0, 0);
- var totalMass = 0;
- var totalInertia = 0;
- for(var i = 0; i < this.shapes.length; i++) {
- var shape = this.shapes[i];
- var centroid = shape.centroid();
- var mass = shape.area() * shape.density;
- var inertia = shape.inertia(mass);
- //console.log('rmd', centroid, shape);
- totalMassCentroid.multiplyAddByScalar(centroid, mass);
- totalMass += mass;
- totalInertia += inertia;
- }
- //this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
- Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
- this.setMass(totalMass);
- if(!this.fixedRotation) {
- //this.setInertia(totalInertia - totalMass * vec2.dot(this.centroid, this.centroid));
- this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
- }
- //console.log("mass = " + this.m + " inertia = " + this.i);
- // Move center of mass
- var oldPosition = Phaser.Vec2Utils.clone(this.position);
- //this.position.copyFrom(this.transform.transform(this.centroid));
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- // Update center of mass velocity
- //this.velocity.mad(vec2.perp(vec2.sub(this.position, old_p)), this.angularVelocity);
- oldPosition.subtract(this.position);
- this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
- };
- Body.prototype.resetJointAnchors = function () {
- for(var i = 0; i < this.joints.length; i++) {
- var joint = this.joints[i];
- if(!joint) {
- continue;
- }
- var anchor1 = joint.getWorldAnchor1();
- var anchor2 = joint.getWorldAnchor2();
- joint.setWorldAnchor1(anchor1);
- joint.setWorldAnchor2(anchor2);
- }
- };
- Body.prototype.cacheData = function (source) {
- if (typeof source === "undefined") { source = ''; }
- Advanced.Manager.write('cacheData -- start');
- Advanced.Manager.write('p: ' + this.position.toString());
- Advanced.Manager.write('xf: ' + this.transform.toString());
- this.bounds.clear();
- for(var i = 0; i < this.shapes.length; i++) {
- var shape = this.shapes[i];
- shape.cacheData(this.transform);
- this.bounds.addBounds(shape.bounds);
- }
- Advanced.Manager.write('bounds: ' + this.bounds.toString());
- Advanced.Manager.write('p: ' + this.position.toString());
- Advanced.Manager.write('xf: ' + this.transform.toString());
- Advanced.Manager.write('cacheData -- stop');
- };
- Body.prototype.updateVelocity = function (gravity, dt, damping) {
- // this.velocity = vec2.mad(this.velocity, vec2.mad(gravity, this.force, this.massInverted), dt);
- Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
- Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
- this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
- // Apply damping.
- // ODE: dv/dt + c * v = 0
- // Solution: v(t) = v0 * exp(-c * t)
- // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
- // v2 = exp(-c * dt) * v1
- // Taylor expansion:
- // v2 = (1.0f - c * dt) * v1
- this.velocity.scale(this.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
- this.angularVelocity *= this.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
- this.force.setTo(0, 0);
- this.torque = 0;
- };
- Body.prototype.inContact = function (body2) {
- if(!body2 || this.stepCount == body2.stepCount) {
- return false;
- }
- if(!(this.isAwake && this.isStatic == false) && !(body2.isAwake && body2.isStatic == false)) {
- return false;
- }
- if(this.isCollidable(body2) == false) {
- return false;
- }
- if(!this.bounds.intersectsBounds(body2.bounds)) {
- return false;
- }
- return true;
- };
- Body.prototype.clamp = function (v, min, max) {
- return v < min ? min : (v > max ? max : v);
- };
- Body.prototype.updatePosition = function (dt) {
- //console.log('body update pos', this.position.y);
- //console.log('pre add temp', this._tempVec2.y);
- //this.position.addself(vec2.scale(this.velocity, dt));
- this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
- //console.log('post add temp', this._tempVec2.y);
- //console.log('post add', this.position.y);
- this.angle += this.angularVelocity * dt;
- };
- Body.prototype.resetForce = function () {
- this.force.setTo(0, 0);
- this.torque = 0;
- };
- Body.prototype.applyForce = function (force, p) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.force.add(force);
- // this.f.addself(force);
- // this.torque += vec2.cross(vec2.sub(p, this.p), force);
- Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
- this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
- };
- Body.prototype.applyForceToCenter = function (force) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.force.add(force);
- };
- Body.prototype.applyTorque = function (torque) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.torque += torque;
- };
- Body.prototype.applyLinearImpulse = function (impulse, p) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.velocity.multiplyAddByScalar(impulse, this.massInverted);
- // this.angularVelocity += vec2.cross(vec2.sub(p, this.position), impulse) * this.inertiaInverted;
- Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
- this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
- };
- Body.prototype.applyAngularImpulse = function (impulse) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.angularVelocity += impulse * this.inertiaInverted;
- };
- Body.prototype.kineticEnergy = function () {
- var vsq = this.velocity.dot(this.velocity);
- var wsq = this.angularVelocity * this.angularVelocity;
- return 0.5 * (this.mass * vsq + this.inertia * wsq);
- };
- Object.defineProperty(Body.prototype, "isAwake", {
- get: function () {
- return this.awaked;
- },
- enumerable: true,
- configurable: true
- });
- Body.prototype.awake = function (flag) {
- this.awaked = flag;
- if(flag) {
- this.sleepTime = 0;
- } else {
- this.velocity.setTo(0, 0);
- this.angularVelocity = 0;
- this.force.setTo(0, 0);
- this.torque = 0;
- }
- };
- Body.prototype.isCollidable = function (other) {
- if(this == other) {
- return false;
- }
- if(this.isDynamic == false && other.isDynamic == false) {
- return false;
- }
- if(!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits)) {
- return false;
- }
- for(var i = 0; i < this.joints.length; i++) {
- var joint = this.joints[i];
- if(!this.joints[i] || (!this.joints[i].collideConnected && other.jointHash[this.joints[i].id] != undefined)) {
- return false;
- }
- }
- return true;
- };
- return Body;
- })();
- Advanced.Body = Body;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-///
///
///
///
diff --git a/Tests/physics/body1.js b/Tests/physics/body1.js
index 53aebce0..903c0f87 100644
--- a/Tests/physics/body1.js
+++ b/Tests/physics/body1.js
@@ -18,13 +18,6 @@
var walls;
var t;
function create() {
- //debug = document.createElement('textarea');
- //debug.style.position = 'absolute';
- //debug.style.left = '850px';
- //debug.style.top = '32px';
- //debug.style.width = '600px';
- //debug.style.height = '600px';
- //document.body.appendChild(debug);
//atari = game.add.sprite(200, 100, 'atari');
// need to get the physics bounds around the sprite center, regardless of origin
//atari.transform.origin.setTo(0.5, 0.5);
diff --git a/Tests/physics/body1.ts b/Tests/physics/body1.ts
index 6e87f57d..86cb69df 100644
--- a/Tests/physics/body1.ts
+++ b/Tests/physics/body1.ts
@@ -26,14 +26,6 @@
function create() {
- //debug = document.createElement('textarea');
- //debug.style.position = 'absolute';
- //debug.style.left = '850px';
- //debug.style.top = '32px';
- //debug.style.width = '600px';
- //debug.style.height = '600px';
- //document.body.appendChild(debug);
-
//atari = game.add.sprite(200, 100, 'atari');
// need to get the physics bounds around the sprite center, regardless of origin
diff --git a/Tests/physics/simple test 1.js b/Tests/physics/simple test 1.js
new file mode 100644
index 00000000..7ecb0802
--- /dev/null
+++ b/Tests/physics/simple test 1.js
@@ -0,0 +1,25 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render);
+ function init() {
+ // Using Phasers asset loader we load up a PNG from the assets folder
+ game.load.image('atari', 'assets/sprites/atari130xe.png');
+ game.load.image('ball', 'assets/sprites/shinyball.png');
+ game.load.start();
+ }
+ var atari;
+ var ball;
+ function create() {
+ // Add some gravity to the world, otherwise nothing will actually happen
+ game.physics.gravity.setTo(0, 10);
+ //atari = game.add.physicsSprite(220/2, 450, 'atari');
+ atari = game.add.physicsSprite(320, 450, 'atari');
+ // We'll make the atari sprite a static body, so it won't be influenced by gravity or other forces
+ atari.body.type = Phaser.Types.BODY_STATIC;
+ ball = game.add.physicsSprite(330, 0, 'ball', null, 0);
+ }
+ function render() {
+ Phaser.DebugUtils.renderPhysicsBody(atari.body);
+ Phaser.DebugUtils.renderPhysicsBody(ball.body);
+ }
+})();
diff --git a/Tests/physics/simple test 1.ts b/Tests/physics/simple test 1.ts
new file mode 100644
index 00000000..c35cc3c1
--- /dev/null
+++ b/Tests/physics/simple test 1.ts
@@ -0,0 +1,40 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render);
+
+ function init() {
+
+ // Using Phasers asset loader we load up a PNG from the assets folder
+ game.load.image('atari', 'assets/sprites/atari130xe.png');
+ game.load.image('ball', 'assets/sprites/shinyball.png');
+ game.load.start();
+
+ }
+
+ var atari: Phaser.Sprite;
+ var ball: Phaser.Sprite;
+
+ function create() {
+
+ // Add some gravity to the world, otherwise nothing will actually happen
+ game.physics.gravity.setTo(0, 10);
+
+ //atari = game.add.physicsSprite(220/2, 450, 'atari');
+ atari = game.add.physicsSprite(320, 450, 'atari');
+ // We'll make the atari sprite a static body, so it won't be influenced by gravity or other forces
+ atari.body.type = Phaser.Types.BODY_STATIC;
+
+ ball = game.add.physicsSprite(330, 0, 'ball', null, 0);
+
+ }
+
+ function render() {
+
+ Phaser.DebugUtils.renderPhysicsBody(atari.body);
+ Phaser.DebugUtils.renderPhysicsBody(ball.body);
+
+ }
+
+})();
diff --git a/Tests/scrollzones/blasteroids.js b/Tests/scrollzones/blasteroids.js
index 580e2761..cfdfe9cd 100644
--- a/Tests/scrollzones/blasteroids.js
+++ b/Tests/scrollzones/blasteroids.js
@@ -77,8 +77,8 @@
}
}
function render() {
- ship.body.renderDebugInfo(32, 32);
- }
+ //ship.body.renderDebugInfo(32, 32);
+ }
function recycleBullet(bullet) {
if(bullet.exists && bullet.x < -40 || bullet.x > 840 || bullet.y < -40 || bullet.y > 640) {
bullet.exists = false;
diff --git a/Tests/scrollzones/blasteroids.ts b/Tests/scrollzones/blasteroids.ts
index 84bad9e4..df050c54 100644
--- a/Tests/scrollzones/blasteroids.ts
+++ b/Tests/scrollzones/blasteroids.ts
@@ -122,7 +122,7 @@
function render() {
- ship.body.renderDebugInfo(32, 32);
+ //ship.body.renderDebugInfo(32, 32);
}
diff --git a/Tests/sprites/create sprite 1.js b/Tests/sprites/create sprite 1.js
index 2b5be685..31a73b0c 100644
--- a/Tests/sprites/create sprite 1.js
+++ b/Tests/sprites/create sprite 1.js
@@ -9,10 +9,7 @@
function create() {
// This will create a Sprite positioned at the top-left of the game (0,0)
// Try changing the 0, 0 values
- game.add.sprite(200, 100, 'bunny');
+ game.add.sprite(0, 0, 'bunny');
game.camera.texture.alpha = 0.5;
- //game.world.group.texture.flippedX = true;
- //game.world.group.transform.origin.setTo(game.stage.centerX, game.stage.centerY);
- //game.world.group.transform.skew.x = 1.2;
- }
+ }
})();
diff --git a/Tests/sprites/create sprite 1.ts b/Tests/sprites/create sprite 1.ts
index 6ea3aebf..a6d1bbb2 100644
--- a/Tests/sprites/create sprite 1.ts
+++ b/Tests/sprites/create sprite 1.ts
@@ -16,12 +16,9 @@
// This will create a Sprite positioned at the top-left of the game (0,0)
// Try changing the 0, 0 values
- game.add.sprite(200, 100, 'bunny');
+ game.add.sprite(0, 0, 'bunny');
game.camera.texture.alpha = 0.5;
- //game.world.group.texture.flippedX = true;
- //game.world.group.transform.origin.setTo(game.stage.centerX, game.stage.centerY);
- //game.world.group.transform.skew.x = 1.2;
}
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index 782a3b9c..d09681a8 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -316,7 +316,7 @@ module Phaser {
* @param {Number} height Desired height of this node.
* @param {Number} parent The parent branch or node. Pass null to create a root.
*/
- constructor(manager: Physics.PhysicsManager, x: number, y: number, width: number, height: number, parent?: QuadTree);
+ constructor(manager: Physics.Manager, x: number, y: number, width: number, height: number, parent?: QuadTree);
private _iterator;
private _ot;
private _i;
@@ -325,7 +325,7 @@ module Phaser {
private _l;
private _overlapProcessed;
private _checkObject;
- static physics: Physics.PhysicsManager;
+ static physics: Physics.Manager;
/**
* Flag for specifying that you want to add an object to the A list.
*/
@@ -2555,11 +2555,502 @@ module Phaser {
}
}
/**
-* Phaser - Physics - Body
+* Phaser - 2D Transform
+*
+* A 2D Transform
+*/
+module Phaser {
+ class Transform {
+ /**
+ * Creates a new 2D Transform object.
+ * @class Transform
+ * @constructor
+ * @return {Transform} This object
+ **/
+ constructor(pos: Vec2, angle: number);
+ public t: Vec2;
+ public c: number;
+ public s: number;
+ public angle: number;
+ public toString(): string;
+ public setTo(pos: Vec2, angle: number): Transform;
+ public setRotation(angle: number): Transform;
+ public setPosition(p: Vec2): Transform;
+ public identity(): Transform;
+ }
+}
+/**
+* Phaser - TransformUtils
+*
+* A collection of methods useful for manipulating and performing operations on 2D Transforms.
+*
+*/
+module Phaser {
+ class TransformUtils {
+ static rotate(t: Transform, v: Vec2, out?: Vec2): Vec2;
+ static unrotate(t: Transform, v: Vec2, out?: Vec2): Vec2;
+ static transform(t: Transform, v: Vec2, out?: Vec2): Vec2;
+ static untransform(t: Transform, v: Vec2, out?: Vec2): Vec2;
+ }
+}
+/**
+* Phaser - Advanced Physics - Joint
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ class Joint {
+ constructor(type: number, body1: Body, body2: Body, collideConnected);
+ public id: number;
+ public type: number;
+ public body1: Body;
+ public body2: Body;
+ public collideConnected;
+ public maxForce: number;
+ public breakable: bool;
+ public anchor1: Vec2;
+ public anchor2: Vec2;
+ public getWorldAnchor1(): Vec2;
+ public getWorldAnchor2(): Vec2;
+ public setWorldAnchor1(anchor1): void;
+ public setWorldAnchor2(anchor2): void;
+ }
+}
+/**
+* Phaser - Physics Manager
+*
+* The Physics Manager is responsible for looking after, creating and colliding
+* all of the physics bodies and joints in the world.
+*/
+module Phaser.Physics {
+ class Manager {
+ constructor(game: Game);
+ /**
+ * Local reference to Game.
+ */
+ public game: Game;
+ static debug: HTMLTextAreaElement;
+ static clear(): void;
+ static write(s: string): void;
+ static writeAll(): void;
+ static log: any[];
+ static dump(phase: string, body: Body): void;
+ static collision: Collision;
+ static SHAPE_TYPE_CIRCLE: number;
+ static SHAPE_TYPE_SEGMENT: number;
+ static SHAPE_TYPE_POLY: number;
+ static SHAPE_NUM_TYPES: number;
+ static JOINT_TYPE_ANGLE: number;
+ static JOINT_TYPE_REVOLUTE: number;
+ static JOINT_TYPE_WELD: number;
+ static JOINT_TYPE_WHEEL: number;
+ static JOINT_TYPE_PRISMATIC: number;
+ static JOINT_TYPE_DISTANCE: number;
+ static JOINT_TYPE_ROPE: number;
+ static JOINT_TYPE_MOUSE: number;
+ static JOINT_LINEAR_SLOP: number;
+ static JOINT_ANGULAR_SLOP: number;
+ static JOINT_MAX_LINEAR_CORRECTION: number;
+ static JOINT_MAX_ANGULAR_CORRECTION: number;
+ static JOINT_LIMIT_STATE_INACTIVE: number;
+ static JOINT_LIMIT_STATE_AT_LOWER: number;
+ static JOINT_LIMIT_STATE_AT_UPPER: number;
+ static JOINT_LIMIT_STATE_EQUAL_LIMITS: number;
+ static CONTACT_SOLVER_COLLISION_SLOP: number;
+ static CONTACT_SOLVER_BAUMGARTE: number;
+ static CONTACT_SOLVER_MAX_LINEAR_CORRECTION: number;
+ static bodyCounter: number;
+ static jointCounter: number;
+ static shapeCounter: number;
+ public space: Space;
+ public lastTime: number;
+ public frameRateHz: number;
+ public timeDelta: number;
+ public paused: bool;
+ public step: bool;
+ public velocityIterations: number;
+ public positionIterations: number;
+ public allowSleep: bool;
+ public warmStarting: bool;
+ public gravity: Vec2;
+ public update(): void;
+ public addBody(body: Body): void;
+ public removeBody(body: Body): void;
+ public addJoint(joint: IJoint): void;
+ public removeJoint(joint: IJoint): void;
+ public pixelsToMeters(value: number): number;
+ public metersToPixels(value: number): number;
+ static pixelsToMeters(value: number): number;
+ static metersToPixels(value: number): number;
+ static p2m(value: number): number;
+ static m2p(value: number): number;
+ static areaForCircle(radius_outer: number, radius_inner: number): number;
+ static inertiaForCircle(mass: number, center: Vec2, radius_outer: number, radius_inner: number): number;
+ static areaForSegment(a: Vec2, b: Vec2, radius: number): number;
+ static centroidForSegment(a: Vec2, b: Vec2): Vec2;
+ static inertiaForSegment(mass: number, a: Vec2, b: Vec2): number;
+ static areaForPoly(verts: Vec2[]): number;
+ static centroidForPoly(verts: Vec2[]): Vec2;
+ static inertiaForPoly(mass: number, verts: Vec2[], offset: Vec2): number;
+ static inertiaForBox(mass: number, w: number, h: number): number;
+ static createConvexHull(points): any[];
+ }
+}
+/**
+* Phaser - 2D AABB
+*
+* A 2D AABB object
+*/
+module Phaser.Physics {
+ class Bounds {
+ /**
+ * Creates a new 2D AABB object.
+ * @class Bounds
+ * @constructor
+ * @return {Bounds} This object
+ **/
+ constructor(mins?: Vec2, maxs?: Vec2);
+ public mins: Vec2;
+ public maxs: Vec2;
+ public toString(): string;
+ public setTo(mins: Vec2, maxs: Vec2): void;
+ public copy(b: Bounds): Bounds;
+ public clear(): Bounds;
+ public x : number;
+ public y : number;
+ public width : number;
+ public height : number;
+ public right : number;
+ public bottom : number;
+ public isEmpty(): bool;
+ public getPerimeter(): number;
+ public addPoint(p: Vec2): Bounds;
+ public addBounds(b: Bounds): Bounds;
+ public addBounds2(mins, maxs): Bounds;
+ public addExtents(center: Vec2, extent_x: number, extent_y: number): Bounds;
+ public expand(ax: number, ay: number): Bounds;
+ public containPoint(p: Vec2): bool;
+ public intersectsBounds(b: Bounds): bool;
+ static expand(b: Bounds, ax, ay);
+ }
+}
+/**
+* Phaser - Advanced Physics - IShape
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ interface IShape {
+ id: number;
+ type: number;
+ elasticity: number;
+ friction: number;
+ density: number;
+ body: Body;
+ bounds: Bounds;
+ area(): number;
+ centroid(): Vec2;
+ inertia(mass: number): number;
+ cacheData(xf: Transform);
+ pointQuery(p: Vec2): bool;
+ findEdgeByPoint(p: Vec2, minDist: number): number;
+ findVertexByPoint(p: Vec2, minDist: number): number;
+ verts: Vec2[];
+ planes: Plane[];
+ tverts: Vec2[];
+ tplanes: Plane[];
+ convexity: bool;
+ }
+}
+/**
+* Phaser - Advanced Physics - Shape
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ class Shape {
+ constructor(type: number);
+ public id: number;
+ public type: number;
+ public body: Body;
+ public verts: Vec2[];
+ public planes: Plane[];
+ public tverts: Vec2[];
+ public tplanes: Plane[];
+ public convexity: bool;
+ public elasticity: number;
+ public friction: number;
+ public density: number;
+ public bounds: Bounds;
+ public findEdgeByPoint(p: Vec2, minDist: number): number;
+ }
+}
+/**
+* Phaser - Advanced Physics - Contact
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ class Contact {
+ constructor(p, n, d, hash);
+ public hash;
+ public r1: Vec2;
+ public r2: Vec2;
+ public r1_local: Vec2;
+ public r2_local: Vec2;
+ public bounce: number;
+ public emn: number;
+ public emt: number;
+ public point;
+ public normal: Vec2;
+ public depth;
+ public lambdaNormal;
+ public lambdaTangential;
+ }
+}
+module Phaser.Physics {
+ class ContactSolver {
+ constructor(shape1, shape2);
+ public shape1;
+ public shape2;
+ public contacts: Contact[];
+ public elasticity: number;
+ public friction: number;
+ public update(newContactArr: Contact[]): void;
+ public initSolver(dt_inv): void;
+ public warmStart(): void;
+ public solveVelocityConstraints(): void;
+ public solvePositionConstraints(): bool;
+ public clamp(v, min, max);
+ }
+}
+/**
+* Phaser - Advanced Physics - Shape - Circle
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics.Shapes {
+ class Circle extends Shape implements IShape {
+ constructor(radius: number, x?: number, y?: number);
+ public radius: number;
+ public center: Vec2;
+ public tc: Vec2;
+ public finishVerts(): void;
+ public duplicate(): Circle;
+ public recenter(c: Vec2): void;
+ public transform(xf: Transform): void;
+ public untransform(xf: Transform): void;
+ public area(): number;
+ public centroid(): Vec2;
+ public inertia(mass: number): number;
+ public cacheData(xf: Transform): void;
+ public pointQuery(p: Vec2): bool;
+ public findVertexByPoint(p: Vec2, minDist: number): number;
+ public distanceOnPlane(n, d): void;
+ }
+}
+/**
+* Phaser - Advanced Physics - Plane
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ class Plane {
+ constructor(normal: Vec2, d: number);
+ public normal: Vec2;
+ public d: number;
+ }
+}
+/**
+* Phaser - Advanced Physics - Shapes - Convex Polygon
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics.Shapes {
+ class Poly extends Shape implements IShape {
+ constructor(verts?);
+ public finishVerts(): void;
+ public duplicate(): Poly;
+ public recenter(c): void;
+ public transform(xf: Transform): void;
+ public untransform(xf: Transform): void;
+ public area(): number;
+ public centroid(): Vec2;
+ public inertia(mass: number): number;
+ public cacheData(xf: Transform): void;
+ public pointQuery(p: Vec2): bool;
+ public findVertexByPoint(p: Vec2, minDist: number): number;
+ public findEdgeByPoint(p: Vec2, minDist: number): number;
+ public distanceOnPlane(n: Vec2, d: number): number;
+ public containPoint(p: Vec2): bool;
+ public containPointPartial(p, n): bool;
+ }
+}
+/**
+* Phaser - Advanced Physics - Shapes - Segment
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics.Shapes {
+ class Segment extends Shape implements IShape {
+ constructor(a, b, radius: number);
+ public a: Vec2;
+ public b: Vec2;
+ public radius: number;
+ public normal: Vec2;
+ public ta: Vec2;
+ public tb: Vec2;
+ public tn: Vec2;
+ public finishVerts(): void;
+ public duplicate(): Segment;
+ public recenter(c): void;
+ public transform(xf: Transform): void;
+ public untransform(xf: Transform): void;
+ public area(): number;
+ public centroid(): Vec2;
+ public inertia(mass: number): number;
+ public cacheData(xf: Transform): void;
+ public pointQuery(p: Vec2): bool;
+ public findVertexByPoint(p: Vec2, minDist: number): number;
+ public distanceOnPlane(n, d): number;
+ }
+}
+/**
+* Phaser - Advanced Physics - Collision Handlers
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ class Collision {
+ public collide(a, b, contacts: Contact[]): number;
+ private _circle2Circle(c1, r1, c2, r2, contactArr);
+ public circle2Circle(circ1: Shapes.Circle, circ2: Shapes.Circle, contactArr: Contact[]): number;
+ public circle2Segment(circ: Shapes.Circle, seg: Shapes.Segment, contactArr: Contact[]): number;
+ public circle2Poly(circ: Shapes.Circle, poly: Shapes.Poly, contactArr: Contact[]): number;
+ public segmentPointDistanceSq(seg: Shapes.Segment, p): number;
+ public segment2Segment(seg1: Shapes.Segment, seg2: Shapes.Segment, contactArr: Contact[]): number;
+ public findPointsBehindSeg(contactArr: Contact[], seg: Shapes.Segment, poly: Shapes.Poly, dist: number, coef: number): void;
+ public segment2Poly(seg: Shapes.Segment, poly: Shapes.Poly, contactArr: Contact[]): number;
+ public findMSA(poly: Shapes.Poly, planes: Plane[], num: number): {
+ dist: number;
+ index: number;
+ };
+ public findVertsFallback(contactArr: Contact[], poly1: Shapes.Poly, poly2: Shapes.Poly, n, dist: number): number;
+ public findVerts(contactArr: Contact[], poly1: Shapes.Poly, poly2: Shapes.Poly, n, dist: number): number;
+ public poly2Poly(poly1: Shapes.Poly, poly2: Shapes.Poly, contactArr: Contact[]): number;
+ }
+}
+/**
+* Phaser - Advanced Physics - Joint
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ interface IJoint {
+ id: number;
+ type: number;
+ body1: Body;
+ body2: Body;
+ collideConnected;
+ maxForce: number;
+ breakable: bool;
+ anchor1: Vec2;
+ anchor2: Vec2;
+ getWorldAnchor1();
+ getWorldAnchor2();
+ setWorldAnchor1(anchor1);
+ setWorldAnchor2(anchor2);
+ initSolver(dt, warmStarting);
+ solveVelocityConstraints();
+ solvePositionConstraints();
+ getReactionForce(dt_inv);
+ }
+}
+/**
+* Phaser - Advanced Physics - Space
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics {
+ class Space {
+ constructor(manager: Manager);
+ private _manager;
+ private _delta;
+ private _deltaInv;
+ private _bl;
+ private _jl;
+ private _cl;
+ private _linTolSqr;
+ private _angTolSqr;
+ private _minSleepTime;
+ private _positionSolved;
+ private _shape1;
+ private _shape2;
+ private _contactsOk;
+ private _jointsOk;
+ private bodyHash;
+ private jointHash;
+ static TIME_TO_SLEEP: number;
+ static SLEEP_LINEAR_TOLERANCE: number;
+ static SLEEP_ANGULAR_TOLERANCE: number;
+ public bodies: Body[];
+ public joints: IJoint[];
+ public numContacts: number;
+ public contactSolvers: ContactSolver[];
+ public postSolve;
+ public gravity: Vec2;
+ public damping: number;
+ public stepCount: number;
+ public clear(): void;
+ public addBody(body: Body): void;
+ public removeBody(body: Body): void;
+ public addJoint(joint: IJoint): void;
+ public removeJoint(joint: IJoint): void;
+ public findShapeByPoint(p, refShape);
+ public findBodyByPoint(p, refBody: Body);
+ public shapeById(id): IShape;
+ public jointById(id): IJoint;
+ public findVertexByPoint(p, minDist, refVertexId): number;
+ public findEdgeByPoint(p, minDist, refEdgeId): number;
+ public findJointByPoint(p, minDist, refJointId): number;
+ private findContactSolver(shape1, shape2);
+ private genTemporalContactSolvers();
+ private initSolver(warmStarting);
+ private velocitySolver(iterations);
+ private positionSolver(iterations);
+ public step(dt: number, velocityIterations: number, positionIterations: number, warmStarting: bool, allowSleep: bool): void;
+ }
+}
+/**
+* Phaser - Advanced Physics - Shapes - Triangle
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics.Shapes {
+ class Triangle extends Poly {
+ constructor(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number);
+ }
+}
+/**
+* Phaser - Advanced Physics - Shapes - Box
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
+*/
+module Phaser.Physics.Shapes {
+ class Box extends Poly {
+ constructor(x, y, width, height);
+ }
+}
+/**
+* Phaser - Advanced Physics - Body
+*
+* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics {
class Body {
- constructor(sprite: Sprite, type: number);
+ constructor(sprite: Sprite, type: number, x?: number, y?: number, shapeType?: number);
+ public toString(): string;
+ private _tempVec2;
/**
* Reference to Phaser.Game
*/
@@ -2569,6 +3060,14 @@ module Phaser.Physics {
*/
public sprite: Sprite;
/**
+ * The Body ID
+ */
+ public id: number;
+ /**
+ * The Body name
+ */
+ public name: string;
+ /**
* The type of Body (disabled, dynamic, static or kinematic)
* Disabled = skips all physics operations / tests (default)
* Dynamic = gives and receives impacts
@@ -2577,53 +3076,71 @@ module Phaser.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;
- public angularAcceleration: number;
- public angularDrag: number;
- public maxAngular: number;
- /**
- * Orientation of the object.
- * @type {number}
- */
- public facing: number;
- public touching: number;
- public allowCollisions: number;
- public wasTouching: number;
- public mass: number;
+ public angle: number;
+ public transform: Transform;
+ public centroid: Vec2;
public position: Vec2;
- public oldPosition: Vec2;
- public offset: Vec2;
- public bounds: Rectangle;
- private _width;
- private _height;
- public x : number;
- public y : number;
- public width : number;
- public height : number;
- public preUpdate(): void;
- public postUpdate(): void;
- public hullWidth : number;
- public hullHeight : number;
- public hullX : number;
- public hullY : number;
- public deltaXAbs : number;
- public deltaYAbs : number;
- public deltaX : number;
- public deltaY : number;
- public render(context: CanvasRenderingContext2D): void;
- /**
- * 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): void;
+ public velocity: Vec2;
+ public force: Vec2;
+ public angularVelocity: number;
+ public torque: number;
+ public linearDamping: number;
+ public angularDamping: number;
+ public sleepTime: number;
+ public awaked: bool;
+ public allowCollisions: number;
+ public shapes: IShape[];
+ public shapesLength: number;
+ public joints: IJoint[];
+ public jointHash: {};
+ public bounds: Bounds;
+ public mass: number;
+ public massInverted: number;
+ public inertia: number;
+ public inertiaInverted: number;
+ public fixedRotation: bool;
+ public categoryBits: number;
+ public maskBits: number;
+ public stepCount: number;
+ public space: Space;
+ public duplicate(): void;
+ public isDisabled : bool;
+ public isStatic : bool;
+ public isKinetic : bool;
+ public isDynamic : bool;
+ public setType(type: number): void;
+ public addPoly(verts, elasticity?: number, friction?: number, density?: number): Shapes.Poly;
+ public addTriangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, elasticity?: number, friction?: number, density?: number): Shapes.Triangle;
+ public addBox(x: number, y: number, width: number, height: number, elasticity?: number, friction?: number, density?: number): Shapes.Box;
+ public addCircle(radius: number, x?: number, y?: number, elasticity?: number, friction?: number, density?: number): Shapes.Circle;
+ public addShape(shape);
+ public removeShape(shape): void;
+ private setMass(mass);
+ private setInertia(inertia);
+ public setTransform(pos, angle): void;
+ public syncTransform(): void;
+ public getWorldPoint(p: Vec2): Vec2;
+ public getWorldVector(v: Vec2): Vec2;
+ public getLocalPoint(p: Vec2): Vec2;
+ public getLocalVector(v: Vec2): Vec2;
+ public setFixedRotation(flag): void;
+ public resetMassData(): void;
+ public resetJointAnchors(): void;
+ public cacheData(source?: string): void;
+ public updateVelocity(gravity, dt, damping): void;
+ public inContact(body2: Body): bool;
+ public clamp(v, min, max);
+ public updatePosition(dt: number): void;
+ public resetForce(): void;
+ public applyForce(force: Vec2, p: Vec2): void;
+ public applyForceToCenter(force: Vec2): void;
+ public applyTorque(torque: number): void;
+ public applyLinearImpulse(impulse: Vec2, p: Vec2): void;
+ public applyAngularImpulse(impulse: number): void;
+ public kineticEnergy(): number;
+ public isAwake : bool;
+ public awake(flag): void;
+ public isCollidable(other: Body): bool;
}
}
/**
@@ -2638,9 +3155,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 [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC)
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
+ * @param [shapeType] {number} The physics shape the body will consist of (either Box (0) or Circle (1), for custom types see body.addShape)
*/
- constructor(game: Game, x?: number, y?: number, key?: string, frame?, bodyType?: number);
+ constructor(game: Game, x?: number, y?: number, key?: string, frame?, bodyType?: number, shapeType?: number);
/**
* Reference to the main game object
*/
@@ -2767,7 +3285,7 @@ module Phaser {
*/
public preUpdate(): void;
/**
- * Override this function to update your class's position and appearance.
+ * Override this function to update your sprites position and appearance.
*/
public update(): void;
/**
@@ -5192,14 +5710,7 @@ module Phaser {
*/
public lifespan: number;
/**
- * Determines how quickly the particles come to rest on the ground.
- * Only used if the particle has gravity-like acceleration applied.
- * @default 500
- */
- public friction: number;
- /**
- * The particle's main update logic. Basically it checks to see if it should
- * be dead yet, and then has some special bounce behavior if there is some gravity on it.
+ * The particle's main update logic. Basically it checks to see if it should be dead yet.
*/
public update(): void;
/**
@@ -6149,6 +6660,17 @@ module Phaser {
*/
public sprite(x: number, y: number, key?: string, frame?, bodyType?: number): Sprite;
/**
+ * Create a new Sprite with the physics automatically created and set to DYNAMIC. The Sprite position offset is set to its center.
+ *
+ * @param x {number} X position of the new sprite.
+ * @param y {number} Y position of the new sprite.
+ * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite
+ * @param [frame] {string|number} If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name.
+ * @param [shapeType] The default body shape is either 0 for a Box or 1 for a Circle. See Sprite.body.addShape for custom shapes (polygons, etc)
+ * @returns {Sprite} The newly created sprite object.
+ */
+ public physicsSprite(x: number, y: number, key?: string, frame?, shapeType?: number): Sprite;
+ /**
* Create a new DynamicTexture with specific size.
*
* @param width {number} Width of the texture.
@@ -7040,196 +7562,6 @@ module Phaser {
}
}
/**
-* Phaser - CircleUtils
-*
-* A collection of methods useful for manipulating and comparing Circle objects.
-*
-* TODO:
-*/
-module Phaser {
- class CircleUtils {
- /**
- * 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}
- **/
- static clone(a: Circle, out?: Circle): Circle;
- /**
- * 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.
- **/
- static contains(a: Circle, x: number, y: number): bool;
- /**
- * 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.
- **/
- static containsPoint(a: Circle, point: Point): bool;
- /**
- * 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.
- **/
- static containsCircle(a: Circle, b: Circle): bool;
- /**
- * 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.
- **/
- static distanceBetween(a: Circle, target: any, round?: bool): number;
- /**
- * 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.
- **/
- static equals(a: Circle, b: Circle): bool;
- /**
- * 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.
- **/
- static intersects(a: Circle, b: Circle): bool;
- /**
- * 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.
- **/
- static circumferencePoint(a: Circle, angle: number, asDegrees?: bool, out?: Point): Point;
- static intersectsRectangle(c: Circle, r: Rectangle): bool;
- }
-}
-/**
-* 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.
-*/
-module Phaser.Physics {
- class PhysicsManager {
- constructor(game: Game, width: number, height: number);
- /**
- * Local private reference to Game.
- */
- public game: Game;
- /**
- * Physics object pool
- */
- public members: Group;
- private _drag;
- private _delta;
- private _velocityDelta;
- private _length;
- private _distance;
- private _tangent;
- private _separatedX;
- private _separatedY;
- private _overlap;
- private _maxOverlap;
- private _obj1Velocity;
- private _obj2Velocity;
- private _obj1NewVelocity;
- private _obj2NewVelocity;
- private _average;
- private _quadTree;
- private _quadTreeResult;
- public bounds: Rectangle;
- public gravity: Vec2;
- public drag: Vec2;
- public bounce: Vec2;
- public angularDrag: number;
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static OVERLAP_BIAS: number;
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static TILE_OVERLAP: bool;
- /**
- * @type {number}
- */
- public worldDivisions: number;
- public updateMotion(body: Body): void;
- /**
- * 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.
- */
- public computeVelocity(velocity: number, gravity?: number, acceleration?: number, drag?: number, max?: number): number;
- /**
- * 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 separate(body1: Body, body2: Body): bool;
- public checkHullIntersection(body1: Body, body2: Body): bool;
- /**
- * 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.
- */
- public separateBodyX(body1: Body, body2: Body): bool;
- /**
- * 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.
- */
- public separateBodyY(body1: Body, body2: Body): bool;
- /**
- * 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 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?, object2?, notifyCallback?, processCallback?, context?): bool;
- /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- public separateTile(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, collideUp: bool, collideDown: bool, separateX: bool, separateY: bool): bool;
- }
-}
-/**
* Phaser - World
*
* "This world is but a canvas to our imagination." - Henry David Thoreau
@@ -7268,10 +7600,10 @@ module Phaser {
*/
public bounds: Rectangle;
/**
- * Reference to the physics manager.
- * @type {Physics.PhysicsManager}
+ * The Gravity of the World (defaults to 0,0, or no gravity at all)
+ * @type {Vec2}
*/
- public physics: Physics.PhysicsManager;
+ public gravity: Vec2;
/**
* Object container stores every object created with `create*` methods.
* @type {Group}
@@ -7301,7 +7633,7 @@ module Phaser {
* @param height {number} New height of the world.
* @param [updateCameraBounds] {boolean} Update camera bounds automatically or not. Default to true.
*/
- public setSize(width: number, height: number, updateCameraBounds?: bool, updatePhysicsBounds?: bool): void;
+ public setSize(width: number, height: number, updateCameraBounds?: bool): void;
public width : number;
public height : number;
public centerX : number;
@@ -8957,6 +9289,11 @@ module Phaser {
class DebugUtils {
static game: Game;
/**
+ * Render context of stage's canvas.
+ * @type {CanvasRenderingContext2D}
+ */
+ static context: CanvasRenderingContext2D;
+ /**
* 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.
@@ -8964,7 +9301,7 @@ module Phaser {
*/
static renderSpriteInfo(sprite: Sprite, x: number, y: number, color?: string): void;
static renderSpriteBounds(sprite: Sprite, camera?: Camera, color?: string): void;
- static renderSpritePhysicsBody(sprite: Sprite, camera?: Camera, color?: string): void;
+ static renderPhysicsBody(body: Physics.Body, lineWidth?: number, fillStyle?: string, sleepStyle?: string): void;
}
}
/**
@@ -8999,16 +9336,6 @@ module Phaser {
*/
public _raf: RequestAnimationFrame;
/**
- * Max allowable accumulation.
- * @type {number}
- */
- private _maxAccumulation;
- /**
- * Total number of milliseconds elapsed since last update loop.
- * @type {number}
- */
- private _accumulator;
- /**
* Milliseconds of time per step of the game loop.
* @type {number}
*/
@@ -9123,6 +9450,11 @@ module Phaser {
*/
public world: World;
/**
+ * Reference to the physics manager.
+ * @type {Physics.Manager}
+ */
+ public physics: Physics.Manager;
+ /**
* Instance of repeatable random data generator helper.
* @type {RandomDataGenerator}
*/
@@ -9196,7 +9528,6 @@ module Phaser {
*/
public destroy(): void;
public paused : bool;
- public framerate : number;
/**
* 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.
@@ -9392,6 +9723,89 @@ module Phaser {
}
}
/**
+* Phaser - CircleUtils
+*
+* A collection of methods useful for manipulating and comparing Circle objects.
+*
+* TODO:
+*/
+module Phaser {
+ class CircleUtils {
+ /**
+ * 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}
+ **/
+ static clone(a: Circle, out?: Circle): Circle;
+ /**
+ * 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.
+ **/
+ static contains(a: Circle, x: number, y: number): bool;
+ /**
+ * 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.
+ **/
+ static containsPoint(a: Circle, point: Point): bool;
+ /**
+ * 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.
+ **/
+ static containsCircle(a: Circle, b: Circle): bool;
+ /**
+ * 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.
+ **/
+ static distanceBetween(a: Circle, target: any, round?: bool): number;
+ /**
+ * 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.
+ **/
+ static equals(a: Circle, b: Circle): bool;
+ /**
+ * 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.
+ **/
+ static intersects(a: Circle, b: Circle): bool;
+ /**
+ * 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.
+ **/
+ static circumferencePoint(a: Circle, angle: number, asDegrees?: bool, out?: Point): Point;
+ static intersectsRectangle(c: Circle, r: Rectangle): bool;
+ }
+}
+/**
* Phaser - Mat3Utils
*
* A collection of methods useful for manipulating and performing operations on Mat3 objects.
@@ -9424,694 +9838,6 @@ module Phaser {
}
}
/**
-* Phaser - 2D Transform
-*
-* A 2D Transform
-*/
-module Phaser {
- class Transform {
- /**
- * Creates a new 2D Transform object.
- * @class Transform
- * @constructor
- * @return {Transform} This object
- **/
- constructor(pos: Vec2, angle: number);
- public t: Vec2;
- public c: number;
- public s: number;
- public angle: number;
- public toString(): string;
- public setTo(pos: Vec2, angle: number): Transform;
- public setRotation(angle: number): Transform;
- public setPosition(p: Vec2): Transform;
- public identity(): Transform;
- }
-}
-/**
-* Phaser - TransformUtils
-*
-* A collection of methods useful for manipulating and performing operations on 2D Transforms.
-*
-*/
-module Phaser {
- class TransformUtils {
- static rotate(t: Transform, v: Vec2, out?: Vec2): Vec2;
- static unrotate(t: Transform, v: Vec2, out?: Vec2): Vec2;
- static transform(t: Transform, v: Vec2, out?: Vec2): Vec2;
- static untransform(t: Transform, v: Vec2, out?: Vec2): Vec2;
- }
-}
-/**
-* 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.
-*/
-module Phaser.Physics {
- class ArcadePhysics {
- constructor(game: Game, width: number, height: number);
- /**
- * Local private reference to Game.
- */
- public game: Game;
- /**
- * Physics object pool
- */
- public members: Group;
- private _drag;
- private _delta;
- private _velocityDelta;
- private _length;
- private _distance;
- private _tangent;
- private _separatedX;
- private _separatedY;
- private _overlap;
- private _maxOverlap;
- private _obj1Velocity;
- private _obj2Velocity;
- private _obj1NewVelocity;
- private _obj2NewVelocity;
- private _average;
- private _quadTree;
- private _quadTreeResult;
- public bounds: Rectangle;
- public gravity: Vec2;
- public drag: Vec2;
- public bounce: Vec2;
- public angularDrag: number;
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static OVERLAP_BIAS: number;
- /**
- * The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
- * @type {number}
- */
- static TILE_OVERLAP: bool;
- /**
- * @type {number}
- */
- public worldDivisions: number;
- public updateMotion(body: Body): void;
- /**
- * 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.
- */
- public computeVelocity(velocity: number, gravity?: number, acceleration?: number, drag?: number, max?: number): number;
- /**
- * 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 separate(body1: Body, body2: Body): bool;
- public checkHullIntersection(body1: Body, body2: Body): bool;
- /**
- * 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.
- */
- public separateBodyX(body1: Body, body2: Body): bool;
- /**
- * 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.
- */
- public separateBodyY(body1: Body, body2: Body): bool;
- /**
- * 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 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?, object2?, notifyCallback?, processCallback?, context?): bool;
- /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- public separateTile(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, collideUp: bool, collideDown: bool, separateX: bool, separateY: bool): bool;
- }
-}
-/**
-* Phaser - Advanced Physics - Joint
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Joint {
- constructor(type: number, body1: Body, body2: Body, collideConnected);
- public id: number;
- public type: number;
- public body1: Body;
- public body2: Body;
- public collideConnected;
- public maxForce: number;
- public breakable: bool;
- public anchor1: Vec2;
- public anchor2: Vec2;
- public getWorldAnchor1(): Vec2;
- public getWorldAnchor2(): Vec2;
- public setWorldAnchor1(anchor1): void;
- public setWorldAnchor2(anchor2): void;
- }
-}
-/**
-* Phaser - Advanced Physics Manager
-*
-* 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.
-*/
-module Phaser.Physics.Advanced {
- class Manager {
- constructor(game: Game);
- /**
- * Local reference to Game.
- */
- public game: Game;
- static debug: HTMLTextAreaElement;
- static clear(): void;
- static write(s: string): void;
- static writeAll(): void;
- static log: any[];
- static dump(phase: string, body: Body): void;
- static collision: Collision;
- static SHAPE_TYPE_CIRCLE: number;
- static SHAPE_TYPE_SEGMENT: number;
- static SHAPE_TYPE_POLY: number;
- static SHAPE_NUM_TYPES: number;
- static JOINT_TYPE_ANGLE: number;
- static JOINT_TYPE_REVOLUTE: number;
- static JOINT_TYPE_WELD: number;
- static JOINT_TYPE_WHEEL: number;
- static JOINT_TYPE_PRISMATIC: number;
- static JOINT_TYPE_DISTANCE: number;
- static JOINT_TYPE_ROPE: number;
- static JOINT_TYPE_MOUSE: number;
- static JOINT_LINEAR_SLOP: number;
- static JOINT_ANGULAR_SLOP: number;
- static JOINT_MAX_LINEAR_CORRECTION: number;
- static JOINT_MAX_ANGULAR_CORRECTION: number;
- static JOINT_LIMIT_STATE_INACTIVE: number;
- static JOINT_LIMIT_STATE_AT_LOWER: number;
- static JOINT_LIMIT_STATE_AT_UPPER: number;
- static JOINT_LIMIT_STATE_EQUAL_LIMITS: number;
- static CONTACT_SOLVER_COLLISION_SLOP: number;
- static CONTACT_SOLVER_BAUMGARTE: number;
- static CONTACT_SOLVER_MAX_LINEAR_CORRECTION: number;
- static bodyCounter: number;
- static jointCounter: number;
- static shapeCounter: number;
- public space: Space;
- public lastTime: number;
- public frameRateHz: number;
- public timeDelta: number;
- public paused: bool;
- public step: bool;
- public velocityIterations: number;
- public positionIterations: number;
- public allowSleep: bool;
- public warmStarting: bool;
- public update(): void;
- public pixelsToMeters(value: number): number;
- public metersToPixels(value: number): number;
- static pixelsToMeters(value: number): number;
- static metersToPixels(value: number): number;
- static p2m(value: number): number;
- static m2p(value: number): number;
- static areaForCircle(radius_outer: number, radius_inner: number): number;
- static inertiaForCircle(mass: number, center: Vec2, radius_outer: number, radius_inner: number): number;
- static areaForSegment(a: Vec2, b: Vec2, radius: number): number;
- static centroidForSegment(a: Vec2, b: Vec2): Vec2;
- static inertiaForSegment(mass: number, a: Vec2, b: Vec2): number;
- static areaForPoly(verts: Vec2[]): number;
- static centroidForPoly(verts: Vec2[]): Vec2;
- static inertiaForPoly(mass: number, verts: Vec2[], offset: Vec2): number;
- static inertiaForBox(mass: number, w: number, h: number): number;
- static createConvexHull(points): any[];
- }
-}
-/**
-* Phaser - 2D AABB
-*
-* A 2D AABB object
-*/
-module Phaser.Physics.Advanced {
- class Bounds {
- /**
- * Creates a new 2D AABB object.
- * @class Bounds
- * @constructor
- * @return {Bounds} This object
- **/
- constructor(mins?: Vec2, maxs?: Vec2);
- public mins: Vec2;
- public maxs: Vec2;
- public toString(): string;
- public setTo(mins: Vec2, maxs: Vec2): void;
- public copy(b: Bounds): Bounds;
- public clear(): Bounds;
- public x : number;
- public y : number;
- public width : number;
- public height : number;
- public isEmpty(): bool;
- public getPerimeter(): number;
- public addPoint(p: Vec2): Bounds;
- public addBounds(b: Bounds): Bounds;
- public addBounds2(mins, maxs): Bounds;
- public addExtents(center: Vec2, extent_x: number, extent_y: number): Bounds;
- public expand(ax: number, ay: number): Bounds;
- public containPoint(p: Vec2): bool;
- public intersectsBounds(b: Bounds): bool;
- static expand(b: Bounds, ax, ay);
- }
-}
-/**
-* Phaser - Advanced Physics - IShape
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- interface IShape {
- id: number;
- type: number;
- elasticity: number;
- friction: number;
- density: number;
- body: Body;
- bounds: Bounds;
- area(): number;
- centroid(): Vec2;
- inertia(mass: number): number;
- cacheData(xf: Transform);
- pointQuery(p: Vec2): bool;
- findEdgeByPoint(p: Vec2, minDist: number): number;
- findVertexByPoint(p: Vec2, minDist: number): number;
- verts: Vec2[];
- planes: Plane[];
- tverts: Vec2[];
- tplanes: Plane[];
- convexity: bool;
- }
-}
-/**
-* Phaser - Advanced Physics - Shape
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Shape {
- constructor(type: number);
- public id: number;
- public type: number;
- public body: Body;
- public verts: Vec2[];
- public planes: Plane[];
- public tverts: Vec2[];
- public tplanes: Plane[];
- public convexity: bool;
- public elasticity: number;
- public friction: number;
- public density: number;
- public bounds: Bounds;
- public findEdgeByPoint(p: Vec2, minDist: number): number;
- }
-}
-/**
-* Phaser - Advanced Physics - Contact
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Contact {
- constructor(p, n, d, hash);
- public hash;
- public r1: Vec2;
- public r2: Vec2;
- public r1_local: Vec2;
- public r2_local: Vec2;
- public bounce: number;
- public emn: number;
- public emt: number;
- public point;
- public normal: Vec2;
- public depth;
- public lambdaNormal;
- public lambdaTangential;
- }
-}
-module Phaser.Physics.Advanced {
- class ContactSolver {
- constructor(shape1, shape2);
- public shape1;
- public shape2;
- public contacts: Contact[];
- public elasticity: number;
- public friction: number;
- public update(newContactArr: Contact[]): void;
- public initSolver(dt_inv): void;
- public warmStart(): void;
- public solveVelocityConstraints(): void;
- public solvePositionConstraints(): bool;
- public clamp(v, min, max);
- }
-}
-/**
-* Phaser - Advanced Physics - Shape - Circle
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced.Shapes {
- class Circle extends Shape implements IShape {
- constructor(radius: number, x?: number, y?: number);
- public radius: number;
- public center: Vec2;
- public tc: Vec2;
- public finishVerts(): void;
- public duplicate(): Circle;
- public recenter(c: Vec2): void;
- public transform(xf: Transform): void;
- public untransform(xf: Transform): void;
- public area(): number;
- public centroid(): Vec2;
- public inertia(mass: number): number;
- public cacheData(xf: Transform): void;
- public pointQuery(p: Vec2): bool;
- public findVertexByPoint(p: Vec2, minDist: number): number;
- public distanceOnPlane(n, d): void;
- }
-}
-/**
-* Phaser - Advanced Physics - Plane
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Plane {
- constructor(normal: Vec2, d: number);
- public normal: Vec2;
- public d: number;
- }
-}
-/**
-* Phaser - Advanced Physics - Shapes - Convex Polygon
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced.Shapes {
- class Poly extends Shape implements IShape {
- constructor(verts?);
- public finishVerts(): void;
- public duplicate(): Poly;
- public recenter(c): void;
- public transform(xf: Transform): void;
- public untransform(xf: Transform): void;
- public area(): number;
- public centroid(): Vec2;
- public inertia(mass: number): number;
- public cacheData(xf: Transform): void;
- public pointQuery(p: Vec2): bool;
- public findVertexByPoint(p: Vec2, minDist: number): number;
- public findEdgeByPoint(p: Vec2, minDist: number): number;
- public distanceOnPlane(n: Vec2, d: number): number;
- public containPoint(p: Vec2): bool;
- public containPointPartial(p, n): bool;
- }
-}
-/**
-* Phaser - Advanced Physics - Shapes - Segment
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced.Shapes {
- class Segment extends Shape implements IShape {
- constructor(a, b, radius: number);
- public a: Vec2;
- public b: Vec2;
- public radius: number;
- public normal: Vec2;
- public ta: Vec2;
- public tb: Vec2;
- public tn: Vec2;
- public finishVerts(): void;
- public duplicate(): Segment;
- public recenter(c): void;
- public transform(xf: Transform): void;
- public untransform(xf: Transform): void;
- public area(): number;
- public centroid(): Vec2;
- public inertia(mass: number): number;
- public cacheData(xf: Transform): void;
- public pointQuery(p: Vec2): bool;
- public findVertexByPoint(p: Vec2, minDist: number): number;
- public distanceOnPlane(n, d): number;
- }
-}
-/**
-* Phaser - Advanced Physics - Collision Handlers
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Collision {
- constructor();
- public collide(a, b, contacts: Contact[]): number;
- private _circle2Circle(c1, r1, c2, r2, contactArr);
- public circle2Circle(circ1: Shapes.Circle, circ2: Shapes.Circle, contactArr: Contact[]): number;
- public circle2Segment(circ: Shapes.Circle, seg: Shapes.Segment, contactArr: Contact[]): number;
- public circle2Poly(circ: Shapes.Circle, poly: Shapes.Poly, contactArr: Contact[]): number;
- public segmentPointDistanceSq(seg: Shapes.Segment, p): number;
- public segment2Segment(seg1: Shapes.Segment, seg2: Shapes.Segment, contactArr: Contact[]): number;
- public findPointsBehindSeg(contactArr: Contact[], seg: Shapes.Segment, poly: Shapes.Poly, dist: number, coef: number): void;
- public segment2Poly(seg: Shapes.Segment, poly: Shapes.Poly, contactArr: Contact[]): number;
- public findMSA(poly: Shapes.Poly, planes: Plane[], num: number): {
- dist: number;
- index: number;
- };
- public findVertsFallback(contactArr: Contact[], poly1: Shapes.Poly, poly2: Shapes.Poly, n, dist: number): number;
- public findVerts(contactArr: Contact[], poly1: Shapes.Poly, poly2: Shapes.Poly, n, dist: number): number;
- public poly2Poly(poly1: Shapes.Poly, poly2: Shapes.Poly, contactArr: Contact[]): number;
- }
-}
-/**
-* Phaser - Advanced Physics - Joint
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- interface IJoint {
- id: number;
- type: number;
- body1: Body;
- body2: Body;
- collideConnected;
- maxForce: number;
- breakable: bool;
- anchor1: Vec2;
- anchor2: Vec2;
- getWorldAnchor1();
- getWorldAnchor2();
- setWorldAnchor1(anchor1);
- setWorldAnchor2(anchor2);
- initSolver(dt, warmStarting);
- solveVelocityConstraints();
- solvePositionConstraints();
- getReactionForce(dt_inv);
- }
-}
-/**
-* Phaser - Advanced Physics - Space
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Space {
- constructor();
- private _delta;
- private _deltaInv;
- private _bl;
- private _jl;
- private _cl;
- private _linTolSqr;
- private _angTolSqr;
- private _minSleepTime;
- private _positionSolved;
- private _shape1;
- private _shape2;
- private _contactsOk;
- private _jointsOk;
- static TIME_TO_SLEEP: number;
- static SLEEP_LINEAR_TOLERANCE: number;
- static SLEEP_ANGULAR_TOLERANCE: number;
- public bodies: Body[];
- private bodyHash;
- public joints: IJoint[];
- private jointHash;
- public numContacts: number;
- public contactSolvers: ContactSolver[];
- public postSolve;
- public gravity: Vec2;
- public damping: number;
- public stepCount: number;
- public clear(): void;
- public addBody(body: Body): void;
- public removeBody(body: Body): void;
- public addJoint(joint: IJoint): void;
- public removeJoint(joint: IJoint): void;
- public findShapeByPoint(p, refShape);
- public findBodyByPoint(p, refBody: Body);
- public shapeById(id): IShape;
- public jointById(id): IJoint;
- public findVertexByPoint(p, minDist, refVertexId): number;
- public findEdgeByPoint(p, minDist, refEdgeId): number;
- public findJointByPoint(p, minDist, refJointId): number;
- private findContactSolver(shape1, shape2);
- private genTemporalContactSolvers();
- private initSolver(warmStarting);
- private velocitySolver(iterations);
- private positionSolver(iterations);
- public step(dt: number, velocityIterations: number, positionIterations: number, warmStarting: bool, allowSleep: bool): void;
- }
-}
-/**
-* Phaser - Advanced Physics - Shapes - Triangle
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced.Shapes {
- class Triangle extends Poly {
- constructor(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number);
- }
-}
-/**
-* Phaser - Advanced Physics - Shapes - Box
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced.Shapes {
- class Box extends Poly {
- constructor(x, y, width, height);
- }
-}
-/**
-* Phaser - Advanced Physics - Body
-*
-* Based on the work Ju Hyung Lee started in JS PhyRus.
-*/
-module Phaser.Physics.Advanced {
- class Body {
- constructor(sprite: Sprite, type: number, x?: number, y?: number);
- public toString(): string;
- private _tempVec2;
- /**
- * Reference to Phaser.Game
- */
- public game: Game;
- /**
- * Reference to the parent Sprite
- */
- public sprite: Sprite;
- /**
- * The Body ID
- */
- public id: number;
- /**
- * The Body name
- */
- public name: string;
- /**
- * 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 angle: number;
- public transform: Transform;
- public centroid: Vec2;
- public position: Vec2;
- public velocity: Vec2;
- public force: Vec2;
- public angularVelocity: number;
- public torque: number;
- public linearDamping: number;
- public angularDamping: number;
- public sleepTime: number;
- public awaked: bool;
- public shapes: IShape[];
- public shapesLength: number;
- public joints: IJoint[];
- public jointHash: {};
- public bounds: Bounds;
- public mass: number;
- public massInverted: number;
- public inertia: number;
- public inertiaInverted: number;
- public fixedRotation: bool;
- public categoryBits: number;
- public maskBits: number;
- public stepCount: number;
- public space: Space;
- public duplicate(): void;
- public isDisabled : bool;
- public isStatic : bool;
- public isKinetic : bool;
- public isDynamic : bool;
- public setType(type: number): void;
- public addPoly(verts, elasticity?: number, friction?: number, density?: number): Shapes.Poly;
- public addTriangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, elasticity?: number, friction?: number, density?: number): Shapes.Triangle;
- public addBox(x: number, y: number, width: number, height: number, elasticity?: number, friction?: number, density?: number): Shapes.Box;
- public addCircle(radius: number, x?: number, y?: number, elasticity?: number, friction?: number, density?: number): Shapes.Circle;
- public addShape(shape);
- public removeShape(shape): void;
- private setMass(mass);
- private setInertia(inertia);
- public setTransform(pos, angle): void;
- public syncTransform(): void;
- public getWorldPoint(p: Vec2): Vec2;
- public getWorldVector(v: Vec2): Vec2;
- public getLocalPoint(p: Vec2): Vec2;
- public getLocalVector(v: Vec2): Vec2;
- public setFixedRotation(flag): void;
- public resetMassData(): void;
- public resetJointAnchors(): void;
- public cacheData(source?: string): void;
- public updateVelocity(gravity, dt, damping): void;
- public inContact(body2: Body): bool;
- public clamp(v, min, max);
- public updatePosition(dt: number): void;
- public resetForce(): void;
- public applyForce(force: Vec2, p: Vec2): void;
- public applyForceToCenter(force: Vec2): void;
- public applyTorque(torque: number): void;
- public applyLinearImpulse(impulse: Vec2, p: Vec2): void;
- public applyAngularImpulse(impulse: number): void;
- public kineticEnergy(): number;
- public isAwake : bool;
- public awake(flag): void;
- public isCollidable(other: Body): bool;
- }
-}
-/**
* Phaser - PixelUtils
*
* A collection of methods useful for manipulating pixels.
diff --git a/build/phaser.js b/build/phaser.js
index 96d3a9b8..661e4d30 100644
--- a/build/phaser.js
+++ b/build/phaser.js
@@ -708,20 +708,28 @@ var Phaser;
QuadTree._iterator = QuadTree._iterator.next;
continue;
}
- //if (QuadTree._object.body.bounds.checkHullIntersection(this._checkObject.body.bounds))
- if(QuadTree.physics.checkHullIntersection(QuadTree._object.body, this._checkObject.body)) {
- //Execute callback functions if they exist
- if((QuadTree._processingCallback == null) || QuadTree._processingCallback(QuadTree._object, this._checkObject)) {
- this._overlapProcessed = true;
- }
- if(this._overlapProcessed && (QuadTree._notifyCallback != null)) {
- if(QuadTree._callbackContext !== null) {
- QuadTree._notifyCallback.call(QuadTree._callbackContext, QuadTree._object, this._checkObject);
- } else {
- QuadTree._notifyCallback(QuadTree._object, this._checkObject);
- }
- }
+ /*
+ if (QuadTree.physics.checkHullIntersection(QuadTree._object.body, this._checkObject.body))
+ {
+ //Execute callback functions if they exist
+ if ((QuadTree._processingCallback == null) || QuadTree._processingCallback(QuadTree._object, this._checkObject))
+ {
+ this._overlapProcessed = true;
}
+
+ if (this._overlapProcessed && (QuadTree._notifyCallback != null))
+ {
+ if (QuadTree._callbackContext !== null)
+ {
+ QuadTree._notifyCallback.call(QuadTree._callbackContext, QuadTree._object, this._checkObject);
+ }
+ else
+ {
+ QuadTree._notifyCallback(QuadTree._object, this._checkObject);
+ }
+ }
+ }
+ */
QuadTree._iterator = QuadTree._iterator.next;
}
return this._overlapProcessed;
@@ -1587,7 +1595,7 @@ var Phaser;
if (typeof threshold === "undefined") { threshold = 30; }
var hsv = ColorUtils.RGBtoHSV(color);
if(threshold >= 359 || threshold <= 0) {
- throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()");
+ throw Error("ColorUtils Warning: Invalid threshold given to getSplitComplementHarmony()");
}
var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359);
var warmer = ColorUtils.game.math.wrapValue(hsv.hue, opposite - threshold, 359);
@@ -3195,7 +3203,7 @@ var Phaser;
this._prevRotation = this.rotation;
dirty = true;
}
- // If it has moved, updated the edges and center
+ // If it has moved, update the edges and center
if(dirty || this.parent.x != this._pos.x || this.parent.y != this._pos.y) {
this.center.x = this.parent.x + this._distance * this._scA.y;
this.center.y = this.parent.y + this._distance * this._scA.x;
@@ -4260,231 +4268,2817 @@ var Phaser;
}
*/
})(Phaser || (Phaser = {}));
+///
+///
+/**
+* Phaser - 2D Transform
+*
+* A 2D Transform
+*/
+var Phaser;
+(function (Phaser) {
+ var Transform = (function () {
+ /**
+ * Creates a new 2D Transform object.
+ * @class Transform
+ * @constructor
+ * @return {Transform} This object
+ **/
+ function Transform(pos, angle) {
+ this.t = Phaser.Vec2Utils.clone(pos);
+ this.c = Math.cos(angle);
+ this.s = Math.sin(angle);
+ this.angle = angle;
+ }
+ Transform.prototype.toString = function () {
+ return 't=' + this.t.toString() + ' c=' + this.c + ' s=' + this.s + ' a=' + this.angle;
+ };
+ Transform.prototype.setTo = function (pos, angle) {
+ this.t.copyFrom(pos);
+ this.c = Math.cos(angle);
+ this.s = Math.sin(angle);
+ return this;
+ };
+ Transform.prototype.setRotation = function (angle) {
+ if(angle !== this.angle) {
+ this.c = Math.cos(angle);
+ this.s = Math.sin(angle);
+ this.angle = angle;
+ }
+ return this;
+ };
+ Transform.prototype.setPosition = function (p) {
+ this.t.copyFrom(p);
+ return this;
+ };
+ Transform.prototype.identity = function () {
+ this.t.setTo(0, 0);
+ this.c = 1;
+ this.s = 0;
+ return this;
+ };
+ return Transform;
+ })();
+ Phaser.Transform = Transform;
+})(Phaser || (Phaser = {}));
+///
+///
+///
+/**
+* Phaser - TransformUtils
+*
+* A collection of methods useful for manipulating and performing operations on 2D Transforms.
+*
+*/
+var Phaser;
+(function (Phaser) {
+ var TransformUtils = (function () {
+ function TransformUtils() { }
+ TransformUtils.rotate = function rotate(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ //return new vec2(v.x * this.c - v.y * this.s, v.x * this.s + v.y * this.c);
+ return out.setTo(v.x * t.c - v.y * t.s, v.x * t.s + v.y * t.c);
+ };
+ TransformUtils.unrotate = function unrotate(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ //return new vec2(v.x * this.c + v.y * this.s, -v.x * this.s + v.y * this.c);
+ return out.setTo(v.x * t.c + v.y * t.s, -v.x * t.s + v.y * t.c);
+ };
+ TransformUtils.transform = function transform(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ //return new vec2(v.x * this.c - v.y * this.s + this.t.x, v.x * this.s + v.y * this.c + this.t.y);
+ return out.setTo(v.x * t.c - v.y * t.s + t.t.x, v.x * t.s + v.y * t.c + t.t.y);
+ };
+ TransformUtils.untransform = function untransform(t, v, out) {
+ if (typeof out === "undefined") { out = new Phaser.Vec2(); }
+ var px = v.x - t.t.x;
+ var py = v.y - t.t.y;
+ //return new vec2(px * this.c + py * this.s, -px * this.s + py * this.c);
+ return out.setTo(px * t.c + py * t.s, -px * t.s + py * t.c);
+ };
+ return TransformUtils;
+ })();
+ Phaser.TransformUtils = TransformUtils;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Joint
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Joint = (function () {
+ function Joint(type, body1, body2, collideConnected) {
+ this.id = Phaser.Physics.Manager.jointCounter++;
+ this.type = type;
+ this.body1 = body1;
+ this.body2 = body2;
+ this.collideConnected = collideConnected;
+ this.maxForce = 9999999999;
+ this.breakable = false;
+ }
+ Joint.prototype.getWorldAnchor1 = function () {
+ return this.body1.getWorldPoint(this.anchor1);
+ };
+ Joint.prototype.getWorldAnchor2 = function () {
+ return this.body2.getWorldPoint(this.anchor2);
+ };
+ Joint.prototype.setWorldAnchor1 = function (anchor1) {
+ this.anchor1 = this.body1.getLocalPoint(anchor1);
+ };
+ Joint.prototype.setWorldAnchor2 = function (anchor2) {
+ this.anchor2 = this.body2.getLocalPoint(anchor2);
+ };
+ return Joint;
+ })();
+ Physics.Joint = Joint;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Physics Manager
+ *
+ * The Physics Manager is responsible for looking after, creating and colliding
+ * all of the physics bodies and joints in the world.
+ */
+ (function (Physics) {
+ var Manager = (function () {
+ function Manager(game) {
+ this.lastTime = Date.now();
+ this.frameRateHz = 60;
+ this.timeDelta = 0;
+ this.paused = false;
+ this.step = false;
+ // step through the simulation (i.e. per click)
+ //public paused: bool = true;
+ //public step: bool = false; // step through the simulation (i.e. per click)
+ this.velocityIterations = 8;
+ this.positionIterations = 4;
+ this.allowSleep = true;
+ this.warmStarting = true;
+ this.game = game;
+ this.gravity = new Phaser.Vec2();
+ this.space = new Physics.Space(this);
+ Manager.collision = new Physics.Collision();
+ }
+ Manager.clear = function clear() {
+ //Manager.debug.textContent = "";
+ Manager.log = [];
+ };
+ Manager.write = function write(s) {
+ //Manager.debug.textContent += s + "\n";
+ };
+ Manager.writeAll = function writeAll() {
+ for(var i = 0; i < Manager.log.length; i++) {
+ //Manager.debug.textContent += Manager.log[i];
+ }
+ };
+ Manager.log = [];
+ Manager.dump = function dump(phase, body) {
+ /*
+ var s = "\n\nPhase: " + phase + "\n";
+ s += "Position: " + body.position.toString() + "\n";
+ s += "Velocity: " + body.velocity.toString() + "\n";
+ s += "Angle: " + body.angle + "\n";
+ s += "Force: " + body.force.toString() + "\n";
+ s += "Torque: " + body.torque + "\n";
+ s += "Bounds: " + body.bounds.toString() + "\n";
+ s += "Shape ***\n";
+ s += "Vert 0: " + body.shapes[0].verts[0].toString() + "\n";
+ s += "Vert 1: " + body.shapes[0].verts[1].toString() + "\n";
+ s += "Vert 2: " + body.shapes[0].verts[2].toString() + "\n";
+ s += "Vert 3: " + body.shapes[0].verts[3].toString() + "\n";
+ s += "TVert 0: " + body.shapes[0].tverts[0].toString() + "\n";
+ s += "TVert 1: " + body.shapes[0].tverts[1].toString() + "\n";
+ s += "TVert 2: " + body.shapes[0].tverts[2].toString() + "\n";
+ s += "TVert 3: " + body.shapes[0].tverts[3].toString() + "\n";
+ s += "Plane 0: " + body.shapes[0].planes[0].normal.toString() + "\n";
+ s += "Plane 1: " + body.shapes[0].planes[1].normal.toString() + "\n";
+ s += "Plane 2: " + body.shapes[0].planes[2].normal.toString() + "\n";
+ s += "Plane 3: " + body.shapes[0].planes[3].normal.toString() + "\n";
+ s += "TPlane 0: " + body.shapes[0].tplanes[0].normal.toString() + "\n";
+ s += "TPlane 1: " + body.shapes[0].tplanes[1].normal.toString() + "\n";
+ s += "TPlane 2: " + body.shapes[0].tplanes[2].normal.toString() + "\n";
+ s += "TPlane 3: " + body.shapes[0].tplanes[3].normal.toString() + "\n";
+
+ Manager.log.push(s);
+ */
+ };
+ Manager.SHAPE_TYPE_CIRCLE = 0;
+ Manager.SHAPE_TYPE_SEGMENT = 1;
+ Manager.SHAPE_TYPE_POLY = 2;
+ Manager.SHAPE_NUM_TYPES = 3;
+ Manager.JOINT_TYPE_ANGLE = 0;
+ Manager.JOINT_TYPE_REVOLUTE = 1;
+ Manager.JOINT_TYPE_WELD = 2;
+ Manager.JOINT_TYPE_WHEEL = 3;
+ Manager.JOINT_TYPE_PRISMATIC = 4;
+ Manager.JOINT_TYPE_DISTANCE = 5;
+ Manager.JOINT_TYPE_ROPE = 6;
+ Manager.JOINT_TYPE_MOUSE = 7;
+ Manager.JOINT_LINEAR_SLOP = 0.0008;
+ Manager.JOINT_ANGULAR_SLOP = 2 * 0.017453292519943294444444444444444;
+ Manager.JOINT_MAX_LINEAR_CORRECTION = 0.5;
+ Manager.JOINT_MAX_ANGULAR_CORRECTION = 8 * 0.017453292519943294444444444444444;
+ Manager.JOINT_LIMIT_STATE_INACTIVE = 0;
+ Manager.JOINT_LIMIT_STATE_AT_LOWER = 1;
+ Manager.JOINT_LIMIT_STATE_AT_UPPER = 2;
+ Manager.JOINT_LIMIT_STATE_EQUAL_LIMITS = 3;
+ Manager.CONTACT_SOLVER_COLLISION_SLOP = 0.0008;
+ Manager.CONTACT_SOLVER_BAUMGARTE = 0.28;
+ Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION = 1;
+ Manager.bodyCounter = 0;
+ Manager.jointCounter = 0;
+ Manager.shapeCounter = 0;
+ Manager.prototype.update = function () {
+ // Get these from Phaser.Time instead
+ var time = Date.now();
+ var frameTime = (time - this.lastTime) / 1000;
+ this.lastTime = time;
+ // if rAf - why?
+ frameTime = Math.floor(frameTime * 60 + 0.5) / 60;
+ //if (!mouseDown)
+ //{
+ // var p = canvasToWorld(mousePosition);
+ // var body = space.findBodyByPoint(p);
+ // //domCanvas.style.cursor = body ? "pointer" : "default";
+ //}
+ if(!this.paused || this.step) {
+ Manager.clear();
+ var h = 1 / this.frameRateHz;
+ this.timeDelta += frameTime;
+ if(this.step) {
+ this.step = false;
+ this.timeDelta = h;
+ }
+ for(var maxSteps = 4; maxSteps > 0 && this.timeDelta >= h; maxSteps--) {
+ this.space.step(h, this.velocityIterations, this.positionIterations, this.warmStarting, this.allowSleep);
+ this.timeDelta -= h;
+ }
+ if(this.timeDelta > h) {
+ this.timeDelta = 0;
+ }
+ }
+ //frameCount++;
+ };
+ Manager.prototype.addBody = function (body) {
+ this.space.addBody(body);
+ };
+ Manager.prototype.removeBody = function (body) {
+ this.space.removeBody(body);
+ };
+ Manager.prototype.addJoint = function (joint) {
+ this.space.addJoint(joint);
+ };
+ Manager.prototype.removeJoint = function (joint) {
+ this.space.removeJoint(joint);
+ };
+ Manager.prototype.pixelsToMeters = function (value) {
+ return value * 0.02;
+ };
+ Manager.prototype.metersToPixels = function (value) {
+ return value * 50;
+ };
+ Manager.pixelsToMeters = function pixelsToMeters(value) {
+ return value * 0.02;
+ };
+ Manager.metersToPixels = function metersToPixels(value) {
+ return value * 50;
+ };
+ Manager.p2m = function p2m(value) {
+ return value * 0.02;
+ };
+ Manager.m2p = function m2p(value) {
+ return value * 50;
+ };
+ Manager.areaForCircle = function areaForCircle(radius_outer, radius_inner) {
+ return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
+ };
+ Manager.inertiaForCircle = function inertiaForCircle(mass, center, radius_outer, radius_inner) {
+ return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
+ };
+ Manager.areaForSegment = function areaForSegment(a, b, radius) {
+ return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
+ };
+ Manager.centroidForSegment = function centroidForSegment(a, b) {
+ return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+ };
+ Manager.inertiaForSegment = function inertiaForSegment(mass, a, b) {
+ var distsq = Phaser.Vec2Utils.distanceSq(b, a);
+ var offset = Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+ return mass * (distsq / 12 + offset.lengthSq());
+ };
+ Manager.areaForPoly = function areaForPoly(verts) {
+ var area = 0;
+ for(var i = 0; i < verts.length; i++) {
+ area += Phaser.Vec2Utils.cross(verts[i], verts[(i + 1) % verts.length]);
+ }
+ return area / 2;
+ };
+ Manager.centroidForPoly = function centroidForPoly(verts) {
+ var area = 0;
+ var vsum = new Phaser.Vec2();
+ for(var i = 0; i < verts.length; i++) {
+ var v1 = verts[i];
+ var v2 = verts[(i + 1) % verts.length];
+ var cross = Phaser.Vec2Utils.cross(v1, v2);
+ area += cross;
+ // SO many vecs created here - unroll these bad boys
+ vsum.add(Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(v1, v2), cross));
+ }
+ return Phaser.Vec2Utils.scale(vsum, 1 / (3 * area));
+ };
+ Manager.inertiaForPoly = function inertiaForPoly(mass, verts, offset) {
+ var sum1 = 0;
+ var sum2 = 0;
+ for(var i = 0; i < verts.length; i++) {
+ var v1 = Phaser.Vec2Utils.add(verts[i], offset);
+ var v2 = Phaser.Vec2Utils.add(verts[(i + 1) % verts.length], offset);
+ var a = Phaser.Vec2Utils.cross(v2, v1);
+ var b = Phaser.Vec2Utils.dot(v1, v1) + Phaser.Vec2Utils.dot(v1, v2) + Phaser.Vec2Utils.dot(v2, v2);
+ sum1 += a * b;
+ sum2 += a;
+ }
+ return (mass * sum1) / (6 * sum2);
+ };
+ Manager.inertiaForBox = function inertiaForBox(mass, w, h) {
+ return mass * (w * w + h * h) / 12;
+ };
+ Manager.createConvexHull = // Create the convex hull using the Gift wrapping algorithm (http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)
+ function createConvexHull(points) {
+ // Find the right most point on the hull
+ var i0 = 0;
+ var x0 = points[0].x;
+ for(var i = 1; i < points.length; i++) {
+ var x = points[i].x;
+ if(x > x0 || (x == x0 && points[i].y < points[i0].y)) {
+ i0 = i;
+ x0 = x;
+ }
+ }
+ var n = points.length;
+ var hull = [];
+ var m = 0;
+ var ih = i0;
+ while(1) {
+ hull[m] = ih;
+ var ie = 0;
+ for(var j = 1; j < n; j++) {
+ if(ie == ih) {
+ ie = j;
+ continue;
+ }
+ var r = Phaser.Vec2Utils.subtract(points[ie], points[hull[m]]);
+ var v = Phaser.Vec2Utils.subtract(points[j], points[hull[m]]);
+ var c = Phaser.Vec2Utils.cross(r, v);
+ if(c < 0) {
+ ie = j;
+ }
+ // Collinearity check
+ if(c == 0 && v.lengthSq() > r.lengthSq()) {
+ ie = j;
+ }
+ }
+ m++;
+ ih = ie;
+ if(ie == i0) {
+ break;
+ }
+ }
+ // Copy vertices
+ var newPoints = [];
+ for(var i = 0; i < m; ++i) {
+ newPoints.push(points[hull[i]]);
+ }
+ return newPoints;
+ };
+ return Manager;
+ })();
+ Physics.Manager = Manager;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ /**
+ * Phaser - 2D AABB
+ *
+ * A 2D AABB object
+ */
+ (function (Physics) {
+ var Bounds = (function () {
+ /**
+ * Creates a new 2D AABB object.
+ * @class Bounds
+ * @constructor
+ * @return {Bounds} This object
+ **/
+ function Bounds(mins, maxs) {
+ if (typeof mins === "undefined") { mins = null; }
+ if (typeof maxs === "undefined") { maxs = null; }
+ if(mins) {
+ this.mins = Phaser.Vec2Utils.clone(mins);
+ } else {
+ this.mins = new Phaser.Vec2(999999, 999999);
+ }
+ if(maxs) {
+ this.maxs = Phaser.Vec2Utils.clone(maxs);
+ } else {
+ this.maxs = new Phaser.Vec2(999999, 999999);
+ }
+ }
+ Bounds.prototype.toString = function () {
+ return [
+ "mins:",
+ this.mins.toString(),
+ "maxs:",
+ this.maxs.toString()
+ ].join(" ");
+ };
+ Bounds.prototype.setTo = function (mins, maxs) {
+ this.mins.setTo(mins.x, mins.y);
+ this.maxs.setTo(maxs.x, maxs.y);
+ };
+ Bounds.prototype.copy = function (b) {
+ this.mins.copyFrom(b.mins);
+ this.maxs.copyFrom(b.maxs);
+ return this;
+ };
+ Bounds.prototype.clear = function () {
+ this.mins.setTo(999999, 999999);
+ this.maxs.setTo(-999999, -999999);
+ return this;
+ };
+ Object.defineProperty(Bounds.prototype, "x", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.mins.x);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "y", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.mins.y);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "width", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.maxs.x - this.mins.x);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "height", {
+ get: function () {
+ return Phaser.Physics.Manager.metersToPixels(this.maxs.y - this.mins.y);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "right", {
+ get: function () {
+ return this.x + this.width;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Bounds.prototype, "bottom", {
+ get: function () {
+ return this.y + this.height;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Bounds.prototype.isEmpty = function () {
+ return (this.mins.x > this.maxs.x || this.mins.y > this.maxs.y);
+ };
+ Bounds.prototype.getPerimeter = /*
+ public getCenter() {
+ return vec2.scale(vec2.add(this.mins, this.maxs), 0.5);
+ }
+
+ public getExtent() {
+ return vec2.scale(vec2.sub(this.maxs, this.mins), 0.5);
+ }
+ */
+ function () {
+ return (this.maxs.x - this.mins.x + this.maxs.y - this.mins.y) * 2;
+ };
+ Bounds.prototype.addPoint = function (p) {
+ if(this.mins.x > p.x) {
+ this.mins.x = p.x;
+ }
+ if(this.maxs.x < p.x) {
+ this.maxs.x = p.x;
+ }
+ if(this.mins.y > p.y) {
+ this.mins.y = p.y;
+ }
+ if(this.maxs.y < p.y) {
+ this.maxs.y = p.y;
+ }
+ return this;
+ };
+ Bounds.prototype.addBounds = function (b) {
+ if(this.mins.x > b.mins.x) {
+ this.mins.x = b.mins.x;
+ }
+ if(this.maxs.x < b.maxs.x) {
+ this.maxs.x = b.maxs.x;
+ }
+ if(this.mins.y > b.mins.y) {
+ this.mins.y = b.mins.y;
+ }
+ if(this.maxs.y < b.maxs.y) {
+ this.maxs.y = b.maxs.y;
+ }
+ return this;
+ };
+ Bounds.prototype.addBounds2 = function (mins, maxs) {
+ if(this.mins.x > mins.x) {
+ this.mins.x = mins.x;
+ }
+ if(this.maxs.x < maxs.x) {
+ this.maxs.x = maxs.x;
+ }
+ if(this.mins.y > mins.y) {
+ this.mins.y = mins.y;
+ }
+ if(this.maxs.y < maxs.y) {
+ this.maxs.y = maxs.y;
+ }
+ return this;
+ };
+ Bounds.prototype.addExtents = function (center, extent_x, extent_y) {
+ if(this.mins.x > center.x - extent_x) {
+ this.mins.x = center.x - extent_x;
+ }
+ if(this.maxs.x < center.x + extent_x) {
+ this.maxs.x = center.x + extent_x;
+ }
+ if(this.mins.y > center.y - extent_y) {
+ this.mins.y = center.y - extent_y;
+ }
+ if(this.maxs.y < center.y + extent_y) {
+ this.maxs.y = center.y + extent_y;
+ }
+ return this;
+ };
+ Bounds.prototype.expand = function (ax, ay) {
+ this.mins.x -= ax;
+ this.mins.y -= ay;
+ this.maxs.x += ax;
+ this.maxs.y += ay;
+ return this;
+ };
+ Bounds.prototype.containPoint = function (p) {
+ if(p.x < this.mins.x || p.x > this.maxs.x || p.y < this.mins.y || p.y > this.maxs.y) {
+ return false;
+ }
+ return true;
+ };
+ Bounds.prototype.intersectsBounds = function (b) {
+ if(this.mins.x > b.maxs.x || this.maxs.x < b.mins.x || this.mins.y > b.maxs.y || this.maxs.y < b.mins.y) {
+ return false;
+ }
+ return true;
+ };
+ Bounds.expand = function expand(b, ax, ay) {
+ var b = new Bounds(b.mins, b.maxs);
+ b.expand(ax, ay);
+ return b;
+ };
+ return Bounds;
+ })();
+ Physics.Bounds = Bounds;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ })(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shape
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Shape = (function () {
+ function Shape(type) {
+ this.id = Phaser.Physics.Manager.shapeCounter++;
+ this.type = type;
+ this.elasticity = 0.0;
+ this.friction = 1.0;
+ this.density = 1;
+ this.bounds = new Physics.Bounds();
+ }
+ Shape.prototype.findEdgeByPoint = // Over-ridden by ShapePoly
+ function (p, minDist) {
+ return -1;
+ };
+ return Shape;
+ })();
+ Physics.Shape = Shape;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Contact
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Contact = (function () {
+ function Contact(p, n, d, hash) {
+ this.hash = hash;
+ this.point = p;
+ this.normal = n;
+ this.depth = d;
+ this.lambdaNormal = 0;
+ this.lambdaTangential = 0;
+ this.r1 = new Phaser.Vec2();
+ this.r2 = new Phaser.Vec2();
+ this.r1_local = new Phaser.Vec2();
+ this.r2_local = new Phaser.Vec2();
+ }
+ return Contact;
+ })();
+ Physics.Contact = Contact;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
///
///
///
+ ///
+ ///
+ ///
+ ///
/**
- * Phaser - Physics - Body
+ * Phaser - Advanced Physics - ContactSolver
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ //-------------------------------------------------------------------------------------------------
+ // Contact Constraint
+ //
+ // Non-penetration constraint:
+ // C = dot(p2 - p1, n)
+ // Cdot = dot(v2 - v1, n)
+ // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
+ //
+ // impulse = JT * lambda = [ -n * lambda, -cross(r1, n) * lambda, n * lambda, cross(r1, n) * lambda ]
+ //
+ // Friction constraint:
+ // C = dot(p2 - p1, t)
+ // Cdot = dot(v2 - v1, t)
+ // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
+ //
+ // impulse = JT * lambda = [ -t * lambda, -cross(r1, t) * lambda, t * lambda, cross(r1, t) * lambda ]
+ //
+ // NOTE: lambda is an impulse in constraint space.
+ //-------------------------------------------------------------------------------------------------
+ (function (Physics) {
+ var ContactSolver = (function () {
+ function ContactSolver(shape1, shape2) {
+ this.shape1 = shape1;
+ this.shape2 = shape2;
+ this.contacts = [];
+ this.elasticity = 1;
+ this.friction = 1;
+ }
+ ContactSolver.prototype.update = function (newContactArr) {
+ for(var i = 0; i < newContactArr.length; i++) {
+ var newContact = newContactArr[i];
+ var k = -1;
+ for(var j = 0; j < this.contacts.length; j++) {
+ if(newContact.hash == this.contacts[j].hash) {
+ k = j;
+ break;
+ }
+ }
+ if(k > -1) {
+ newContact.lambdaNormal = this.contacts[k].lambdaNormal;
+ newContact.lambdaTangential = this.contacts[k].lambdaTangential;
+ }
+ }
+ this.contacts = newContactArr;
+ };
+ ContactSolver.prototype.initSolver = function (dt_inv) {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ var sum_m_inv = body1.massInverted + body2.massInverted;
+ for(var i = 0; i < this.contacts.length; i++) {
+ var con = this.contacts[i];
+ //console.log('initSolver con');
+ //console.log(con);
+ // Transformed r1, r2
+ Phaser.Vec2Utils.subtract(con.point, body1.position, con.r1);
+ Phaser.Vec2Utils.subtract(con.point, body2.position, con.r2);
+ //con.r1 = vec2.sub(con.point, body1.p);
+ //con.r2 = vec2.sub(con.point, body2.p);
+ // Local r1, r2
+ Phaser.TransformUtils.unrotate(body1.transform, con.r1, con.r1_local);
+ Phaser.TransformUtils.unrotate(body2.transform, con.r2, con.r2_local);
+ //con.r1_local = body1.transform.unrotate(con.r1);
+ //con.r2_local = body2.transform.unrotate(con.r2);
+ var n = con.normal;
+ var t = Phaser.Vec2Utils.perp(con.normal);
+ // invEMn = J * invM * JT
+ // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
+ var sn1 = Phaser.Vec2Utils.cross(con.r1, n);
+ var sn2 = Phaser.Vec2Utils.cross(con.r2, n);
+ var emn_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
+ con.emn = emn_inv == 0 ? 0 : 1 / emn_inv;
+ // invEMt = J * invM * JT
+ // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
+ var st1 = Phaser.Vec2Utils.cross(con.r1, t);
+ var st2 = Phaser.Vec2Utils.cross(con.r2, t);
+ var emt_inv = sum_m_inv + body1.inertiaInverted * st1 * st1 + body2.inertiaInverted * st2 * st2;
+ con.emt = emt_inv == 0 ? 0 : 1 / emt_inv;
+ // Linear velocities at contact point
+ // in 2D: cross(w, r) = perp(r) * w
+ var v1 = new Phaser.Vec2();
+ var v2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(con.r1), body1.angularVelocity, v1);
+ Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(con.r2), body2.angularVelocity, v2);
+ //var v1 = vec2.mad(body1.v, vec2.perp(con.r1), body1.w);
+ //var v2 = vec2.mad(body2.v, vec2.perp(con.r2), body2.w);
+ // relative velocity at contact point
+ var rv = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(v2, v1, rv);
+ //var rv = vec2.sub(v2, v1);
+ // bounce velocity dot n
+ con.bounce = Phaser.Vec2Utils.dot(rv, con.normal) * this.elasticity;
+ }
+ };
+ ContactSolver.prototype.warmStart = function () {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ for(var i = 0; i < this.contacts.length; i++) {
+ var con = this.contacts[i];
+ var n = con.normal;
+ var lambda_n = con.lambdaNormal;
+ var lambda_t = con.lambdaTangential;
+ // Apply accumulated impulses
+ //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
+ //var impulse = new vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
+ var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
+ //console.log('phaser warmStart impulse ' + i + ' = ' + impulse.toString());
+ body1.velocity.multiplyAddByScalar(impulse, -body1.massInverted);
+ //body1.v.mad(impulse, -body1.m_inv);
+ body1.angularVelocity -= Phaser.Vec2Utils.cross(con.r1, impulse) * body1.inertiaInverted;
+ //body1.w -= vec2.cross(con.r1, impulse) * body1.i_inv;
+ body2.velocity.multiplyAddByScalar(impulse, body2.massInverted);
+ //body2.v.mad(impulse, body2.m_inv);
+ body2.angularVelocity += Phaser.Vec2Utils.cross(con.r2, impulse) * body2.inertiaInverted;
+ //body2.w += vec2.cross(con.r2, impulse) * body2.i_inv;
+ }
+ };
+ ContactSolver.prototype.solveVelocityConstraints = function () {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ Physics.Manager.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
+ Physics.Manager.write('Shape 1: ' + this.shape1.type + ' Shape 2: ' + this.shape2.type);
+ var m1_inv = body1.massInverted;
+ var i1_inv = body1.inertiaInverted;
+ var m2_inv = body2.massInverted;
+ var i2_inv = body2.inertiaInverted;
+ Physics.Manager.write('m1_inv: ' + m1_inv);
+ Physics.Manager.write('i1_inv: ' + i1_inv);
+ Physics.Manager.write('m2_inv: ' + m2_inv);
+ Physics.Manager.write('i2_inv: ' + i2_inv);
+ for(var i = 0; i < this.contacts.length; i++) {
+ Physics.Manager.write('------------ solve con ' + i);
+ var con = this.contacts[i];
+ var n = con.normal;
+ var t = Phaser.Vec2Utils.perp(n);
+ var r1 = con.r1;
+ var r2 = con.r2;
+ // Linear velocities at contact point
+ // in 2D: cross(w, r) = perp(r) * w
+ var v1 = new Phaser.Vec2();
+ var v2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(r1), body1.angularVelocity, v1);
+ //var v1 = vec2.mad(body1.v, vec2.perp(r1), body1.w);
+ Physics.Manager.write('v1 ' + v1.toString());
+ Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(r2), body2.angularVelocity, v2);
+ //var v2 = vec2.mad(body2.v, vec2.perp(r2), body2.w);
+ Physics.Manager.write('v2 ' + v2.toString());
+ // Relative velocity at contact point
+ var rv = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(v2, v1, rv);
+ //var rv = vec2.sub(v2, v1);
+ Physics.Manager.write('rv ' + rv.toString());
+ // Compute normal constraint impulse + adding bounce as a velocity bias
+ // lambda_n = -EMn * J * V
+ var lambda_n = -con.emn * (Phaser.Vec2Utils.dot(n, rv) + con.bounce);
+ Physics.Manager.write('lambda_n: ' + lambda_n);
+ // Accumulate and clamp
+ var lambda_n_old = con.lambdaNormal;
+ con.lambdaNormal = Math.max(lambda_n_old + lambda_n, 0);
+ //con.lambdaNormal = this.clamp(lambda_n_old + lambda_n, 0);
+ lambda_n = con.lambdaNormal - lambda_n_old;
+ Physics.Manager.write('lambda_n clamped: ' + lambda_n);
+ // Compute frictional constraint impulse
+ // lambda_t = -EMt * J * V
+ var lambda_t = -con.emt * Phaser.Vec2Utils.dot(t, rv);
+ // Max friction constraint impulse (Coulomb's Law)
+ var lambda_t_max = con.lambdaNormal * this.friction;
+ // Accumulate and clamp
+ var lambda_t_old = con.lambdaTangential;
+ con.lambdaTangential = this.clamp(lambda_t_old + lambda_t, -lambda_t_max, lambda_t_max);
+ lambda_t = con.lambdaTangential - lambda_t_old;
+ // Apply the final impulses
+ //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
+ var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
+ Physics.Manager.write('impulse: ' + impulse.toString());
+ body1.velocity.multiplyAddByScalar(impulse, -m1_inv);
+ //body1.v.mad(impulse, -m1_inv);
+ body1.angularVelocity -= Phaser.Vec2Utils.cross(r1, impulse) * i1_inv;
+ //body1.w -= vec2.cross(r1, impulse) * i1_inv;
+ body2.velocity.multiplyAddByScalar(impulse, m2_inv);
+ //body2.v.mad(impulse, m2_inv);
+ body2.angularVelocity += Phaser.Vec2Utils.cross(r2, impulse) * i2_inv;
+ //body2.w += vec2.cross(r2, impulse) * i2_inv;
+ Physics.Manager.write('body1: ' + body1.toString());
+ Physics.Manager.write('body2: ' + body2.toString());
+ }
+ };
+ ContactSolver.prototype.solvePositionConstraints = function () {
+ var body1 = this.shape1.body;
+ var body2 = this.shape2.body;
+ Physics.Manager.write('solvePositionConstraints');
+ var m1_inv = body1.massInverted;
+ var i1_inv = body1.inertiaInverted;
+ var m2_inv = body2.massInverted;
+ var i2_inv = body2.inertiaInverted;
+ var sum_m_inv = m1_inv + m2_inv;
+ var max_penetration = 0;
+ for(var i = 0; i < this.contacts.length; i++) {
+ Physics.Manager.write('------------- solvePositionConstraints ' + i);
+ var con = this.contacts[i];
+ var n = con.normal;
+ var r1 = new Phaser.Vec2();
+ var r2 = new Phaser.Vec2();
+ // Transformed r1, r2
+ Phaser.Vec2Utils.rotate(con.r1_local, body1.angle, r1);
+ //var r1 = vec2.rotate(con.r1_local, body1.a);
+ Phaser.Vec2Utils.rotate(con.r2_local, body2.angle, r2);
+ //var r2 = vec2.rotate(con.r2_local, body2.a);
+ Physics.Manager.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
+ Physics.Manager.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
+ Physics.Manager.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
+ Physics.Manager.write('r2 rotated: r2.x = ' + r2.x + ' r2.y = ' + r2.y);
+ // Contact points (corrected)
+ var p1 = new Phaser.Vec2();
+ var p2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.add(body1.position, r1, p1);
+ //var p1 = vec2.add(body1.p, r1);
+ Phaser.Vec2Utils.add(body2.position, r2, p2);
+ //var p2 = vec2.add(body2.p, r2);
+ Physics.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ Physics.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
+ // Corrected delta vector
+ var dp = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(p2, p1, dp);
+ //var dp = vec2.sub(p2, p1);
+ // Position constraint
+ var c = Phaser.Vec2Utils.dot(dp, n) + con.depth;
+ var correction = this.clamp(Physics.Manager.CONTACT_SOLVER_BAUMGARTE * (c + Physics.Manager.CONTACT_SOLVER_COLLISION_SLOP), -Physics.Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
+ if(correction == 0) {
+ continue;
+ }
+ // We don't need max_penetration less than or equal slop
+ max_penetration = Math.max(max_penetration, -c);
+ // Compute lambda for position constraint
+ // Solve (J * invM * JT) * lambda = -C / dt
+ var sn1 = Phaser.Vec2Utils.cross(r1, n);
+ var sn2 = Phaser.Vec2Utils.cross(r2, n);
+ var em_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
+ var lambda_dt = em_inv == 0 ? 0 : -correction / em_inv;
+ // Apply correction impulses
+ var impulse_dt = new Phaser.Vec2();
+ Phaser.Vec2Utils.scale(n, lambda_dt, impulse_dt);
+ //var impulse_dt = vec2.scale(n, lambda_dt);
+ body1.position.multiplyAddByScalar(impulse_dt, -m1_inv);
+ //body1.p.mad(impulse_dt, -m1_inv);
+ body1.angle -= sn1 * lambda_dt * i1_inv;
+ body2.position.multiplyAddByScalar(impulse_dt, m2_inv);
+ //body2.p.mad(impulse_dt, m2_inv);
+ body2.angle += sn2 * lambda_dt * i2_inv;
+ Physics.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ Physics.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
+ }
+ Physics.Manager.write('max_penetration: ' + max_penetration);
+ return max_penetration <= Physics.Manager.CONTACT_SOLVER_COLLISION_SLOP * 3;
+ };
+ ContactSolver.prototype.clamp = function (v, min, max) {
+ return v < min ? min : (v > max ? max : v);
+ };
+ return ContactSolver;
+ })();
+ Physics.ContactSolver = ContactSolver;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shape - Circle
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Circle = (function (_super) {
+ __extends(Circle, _super);
+ function Circle(radius, x, y) {
+ if (typeof x === "undefined") { x = 0; }
+ if (typeof y === "undefined") { y = 0; }
+ _super.call(this, Physics.Manager.SHAPE_TYPE_CIRCLE);
+ x = Physics.Manager.pixelsToMeters(x);
+ y = Physics.Manager.pixelsToMeters(y);
+ radius = Physics.Manager.pixelsToMeters(radius);
+ this.center = new Phaser.Vec2(x, y);
+ this.radius = radius;
+ this.tc = new Phaser.Vec2();
+ this.finishVerts();
+ }
+ Circle.prototype.finishVerts = function () {
+ this.radius = Math.abs(this.radius);
+ };
+ Circle.prototype.duplicate = function () {
+ return new Circle(this.center.x, this.center.y, this.radius);
+ };
+ Circle.prototype.recenter = function (c) {
+ this.center.subtract(c);
+ };
+ Circle.prototype.transform = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.center, this.center);
+ //this.center = xf.transform(this.center);
+ };
+ Circle.prototype.untransform = function (xf) {
+ Phaser.TransformUtils.untransform(xf, this.center, this.center);
+ //this.center = xf.untransform(this.center);
+ };
+ Circle.prototype.area = function () {
+ return Physics.Manager.areaForCircle(this.radius, 0);
+ };
+ Circle.prototype.centroid = function () {
+ return Phaser.Vec2Utils.clone(this.center);
+ };
+ Circle.prototype.inertia = function (mass) {
+ return Physics.Manager.inertiaForCircle(mass, this.center, this.radius, 0);
+ };
+ Circle.prototype.cacheData = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.center, this.tc);
+ //this.tc = xf.transform(this.center);
+ this.bounds.mins.setTo(this.tc.x - this.radius, this.tc.y - this.radius);
+ this.bounds.maxs.setTo(this.tc.x + this.radius, this.tc.y + this.radius);
+ };
+ Circle.prototype.pointQuery = function (p) {
+ //return vec2.distsq(this.tc, p) < (this.r * this.r);
+ return Phaser.Vec2Utils.distanceSq(this.tc, p) < (this.radius * this.radius);
+ };
+ Circle.prototype.findVertexByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ if(Phaser.Vec2Utils.distanceSq(this.tc, p) < dsq) {
+ return 0;
+ }
+ return -1;
+ };
+ Circle.prototype.distanceOnPlane = function (n, d) {
+ Phaser.Vec2Utils.dot(n, this.tc) - this.radius - d;
+ };
+ return Circle;
+ })(Phaser.Physics.Shape);
+ Shapes.Circle = Circle;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Plane
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Plane = (function () {
+ function Plane(normal, d) {
+ this.normal = normal;
+ this.d = d;
+ }
+ return Plane;
+ })();
+ Physics.Plane = Plane;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Convex Polygon
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Poly = (function (_super) {
+ __extends(Poly, _super);
+ // Verts is an optional array of objects, the objects must have public x and y properties which will be used
+ // to seed this polygon (i.e. Vec2 objects, or just straight JS objects) and must wind COUNTER clockwise
+ function Poly(verts) {
+ _super.call(this, Physics.Manager.SHAPE_TYPE_POLY);
+ this.verts = [];
+ this.planes = [];
+ this.tverts = [];
+ this.tplanes = [];
+ if(verts) {
+ for(var i = 0; i < verts.length; i++) {
+ this.verts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
+ this.tverts[i] = this.verts[i];
+ //this.tverts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
+ this.tplanes[i] = new Phaser.Physics.Plane(new Phaser.Vec2(), 0);
+ }
+ }
+ this.finishVerts();
+ }
+ Poly.prototype.finishVerts = function () {
+ if(this.verts.length < 2) {
+ this.convexity = false;
+ this.planes = [];
+ return;
+ }
+ this.convexity = true;
+ this.tverts = [];
+ this.tplanes = [];
+ // Must be counter-clockwise verts
+ for(var i = 0; i < this.verts.length; i++) {
+ var a = this.verts[i];
+ var b = this.verts[(i + 1) % this.verts.length];
+ var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
+ this.planes[i] = new Phaser.Physics.Plane(n, Phaser.Vec2Utils.dot(n, a));
+ this.tverts[i] = Phaser.Vec2Utils.clone(this.verts[i])// reference???
+ ;
+ //this.tverts[i] = this.verts[i]; // reference???
+ this.tplanes[i] = new Phaser.Physics.Plane(new Phaser.Vec2(), 0);
+ }
+ for(var i = 0; i < this.verts.length; i++) {
+ //var b = this.verts[(i + 2) % this.verts.length];
+ //var n = this.planes[i].normal;
+ //var d = this.planes[i].d;
+ if(Phaser.Vec2Utils.dot(this.planes[i].normal, this.verts[(i + 2) % this.verts.length]) - this.planes[i].d > 0) {
+ this.convexity = false;
+ }
+ }
+ };
+ Poly.prototype.duplicate = function () {
+ return new Phaser.Physics.Shapes.Poly(this.verts);
+ };
+ Poly.prototype.recenter = function (c) {
+ for(var i = 0; i < this.verts.length; i++) {
+ this.verts[i].subtract(c);
+ }
+ };
+ Poly.prototype.transform = function (xf) {
+ for(var i = 0; i < this.verts.length; i++) {
+ this.verts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
+ //this.verts[i] = xf.transform(this.verts[i]);
+ }
+ };
+ Poly.prototype.untransform = function (xf) {
+ for(var i = 0; i < this.verts.length; i++) {
+ this.verts[i] = Phaser.TransformUtils.untransform(xf, this.verts[i]);
+ //this.verts[i] = xf.untransform(this.verts[i]);
+ }
+ };
+ Poly.prototype.area = function () {
+ return Physics.Manager.areaForPoly(this.verts);
+ };
+ Poly.prototype.centroid = function () {
+ return Physics.Manager.centroidForPoly(this.verts);
+ };
+ Poly.prototype.inertia = function (mass) {
+ return Physics.Manager.inertiaForPoly(mass, this.verts, new Phaser.Vec2());
+ };
+ Poly.prototype.cacheData = function (xf) {
+ this.bounds.clear();
+ var numVerts = this.verts.length;
+ Physics.Manager.write('----------- Poly cacheData = ' + numVerts);
+ if(numVerts == 0) {
+ return;
+ }
+ for(var i = 0; i < numVerts; i++) {
+ this.tverts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
+ //this.tverts[i] = xf.transform(this.verts[i]);
+ Physics.Manager.write('tvert' + i + ' = ' + this.tverts[i].toString());
+ }
+ if(numVerts < 2) {
+ this.bounds.addPoint(this.tverts[0]);
+ return;
+ }
+ for(var i = 0; i < numVerts; i++) {
+ var a = this.tverts[i];
+ var b = this.tverts[(i + 1) % numVerts];
+ var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
+ Physics.Manager.write('a = ' + a.toString());
+ Physics.Manager.write('b = ' + b.toString());
+ Physics.Manager.write('n = ' + n.toString());
+ this.tplanes[i].normal = n;
+ this.tplanes[i].d = Phaser.Vec2Utils.dot(n, a);
+ Physics.Manager.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
+ Physics.Manager.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
+ this.bounds.addPoint(a);
+ }
+ };
+ Poly.prototype.pointQuery = function (p) {
+ if(!this.bounds.containPoint(p)) {
+ return false;
+ }
+ return this.containPoint(p);
+ };
+ Poly.prototype.findVertexByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ for(var i = 0; i < this.tverts.length; i++) {
+ if(Phaser.Vec2Utils.distanceSq(this.tverts[i], p) < dsq) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ Poly.prototype.findEdgeByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ var numVerts = this.tverts.length;
+ for(var i = 0; i < this.tverts.length; i++) {
+ var v1 = this.tverts[i];
+ var v2 = this.tverts[(i + 1) % numVerts];
+ var n = this.tplanes[i].normal;
+ var dtv1 = Phaser.Vec2Utils.cross(v1, n);
+ var dtv2 = Phaser.Vec2Utils.cross(v2, n);
+ var dt = Phaser.Vec2Utils.cross(p, n);
+ if(dt > dtv1) {
+ if(Phaser.Vec2Utils.distanceSq(v1, p) < dsq) {
+ return i;
+ }
+ } else if(dt < dtv2) {
+ if(Phaser.Vec2Utils.distanceSq(v2, p) < dsq) {
+ return i;
+ }
+ } else {
+ var dist = Phaser.Vec2Utils.dot(n, p) - Phaser.Vec2Utils.dot(n, v1);
+ if(dist * dist < dsq) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ };
+ Poly.prototype.distanceOnPlane = function (n, d) {
+ var min = 999999;
+ for(var i = 0; i < this.verts.length; i++) {
+ min = Math.min(min, Phaser.Vec2Utils.dot(n, this.tverts[i]));
+ }
+ return min - d;
+ };
+ Poly.prototype.containPoint = function (p) {
+ for(var i = 0; i < this.verts.length; i++) {
+ var plane = this.tplanes[i];
+ if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
+ return false;
+ }
+ }
+ return true;
+ };
+ Poly.prototype.containPointPartial = function (p, n) {
+ for(var i = 0; i < this.verts.length; i++) {
+ var plane = this.tplanes[i];
+ if(Phaser.Vec2Utils.dot(plane.normal, n) < 0.0001) {
+ continue;
+ }
+ if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
+ return false;
+ }
+ }
+ return true;
+ };
+ return Poly;
+ })(Phaser.Physics.Shape);
+ Shapes.Poly = Poly;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Segment
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Segment = (function (_super) {
+ __extends(Segment, _super);
+ function Segment(a, b, radius) {
+ _super.call(this, Physics.Manager.SHAPE_TYPE_SEGMENT);
+ this.a = a.duplicate();
+ this.b = b.duplicate();
+ this.radius = radius;
+ this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(b, a));
+ this.normal.normalize();
+ this.ta = new Phaser.Vec2();
+ this.tb = new Phaser.Vec2();
+ this.tn = new Phaser.Vec2();
+ this.finishVerts();
+ }
+ Segment.prototype.finishVerts = function () {
+ this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.b, this.a));
+ this.normal.normalize();
+ this.radius = Math.abs(this.radius);
+ };
+ Segment.prototype.duplicate = function () {
+ return new Phaser.Physics.Shapes.Segment(this.a, this.b, this.radius);
+ };
+ Segment.prototype.recenter = function (c) {
+ this.a.subtract(c);
+ this.b.subtract(c);
+ };
+ Segment.prototype.transform = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.a, this.a);
+ Phaser.TransformUtils.transform(xf, this.b, this.b);
+ //this.a = xf.transform(this.a);
+ //this.b = xf.transform(this.b);
+ };
+ Segment.prototype.untransform = function (xf) {
+ Phaser.TransformUtils.untransform(xf, this.a, this.a);
+ Phaser.TransformUtils.untransform(xf, this.b, this.b);
+ //this.a = xf.untransform(this.a);
+ //this.b = xf.untransform(this.b);
+ };
+ Segment.prototype.area = function () {
+ return Physics.Manager.areaForSegment(this.a, this.b, this.radius);
+ };
+ Segment.prototype.centroid = function () {
+ return Physics.Manager.centroidForSegment(this.a, this.b);
+ };
+ Segment.prototype.inertia = function (mass) {
+ return Physics.Manager.inertiaForSegment(mass, this.a, this.b);
+ };
+ Segment.prototype.cacheData = function (xf) {
+ Phaser.TransformUtils.transform(xf, this.a, this.ta);
+ Phaser.TransformUtils.transform(xf, this.b, this.tb);
+ //this.ta = xf.transform(this.a);
+ //this.tb = xf.transform(this.b);
+ this.tn = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.tb, this.ta)).normalize();
+ var l;
+ var r;
+ var t;
+ var b;
+ if(this.ta.x < this.tb.x) {
+ l = this.ta.x;
+ r = this.tb.x;
+ } else {
+ l = this.tb.x;
+ r = this.ta.x;
+ }
+ if(this.ta.y < this.tb.y) {
+ b = this.ta.y;
+ t = this.tb.y;
+ } else {
+ b = this.tb.y;
+ t = this.ta.y;
+ }
+ this.bounds.mins.setTo(l - this.radius, b - this.radius);
+ this.bounds.maxs.setTo(r + this.radius, t + this.radius);
+ };
+ Segment.prototype.pointQuery = function (p) {
+ if(!this.bounds.containPoint(p)) {
+ return false;
+ }
+ var dn = Phaser.Vec2Utils.dot(this.tn, p) - Phaser.Vec2Utils.dot(this.ta, this.tn);
+ var dist = Math.abs(dn);
+ if(dist > this.radius) {
+ return false;
+ }
+ var dt = Phaser.Vec2Utils.cross(p, this.tn);
+ var dta = Phaser.Vec2Utils.cross(this.ta, this.tn);
+ var dtb = Phaser.Vec2Utils.cross(this.tb, this.tn);
+ if(dt <= dta) {
+ if(dt < dta - this.radius) {
+ return false;
+ }
+ return Phaser.Vec2Utils.distanceSq(this.ta, p) < (this.radius * this.radius);
+ } else if(dt > dtb) {
+ if(dt > dtb + this.radius) {
+ return false;
+ }
+ return Phaser.Vec2Utils.distanceSq(this.tb, p) < (this.radius * this.radius);
+ }
+ return true;
+ };
+ Segment.prototype.findVertexByPoint = function (p, minDist) {
+ var dsq = minDist * minDist;
+ if(Phaser.Vec2Utils.distanceSq(this.ta, p) < dsq) {
+ return 0;
+ }
+ if(Phaser.Vec2Utils.distanceSq(this.tb, p) < dsq) {
+ return 1;
+ }
+ return -1;
+ };
+ Segment.prototype.distanceOnPlane = function (n, d) {
+ var a = Phaser.Vec2Utils.dot(n, this.ta) - this.radius;
+ var b = Phaser.Vec2Utils.dot(n, this.tb) - this.radius;
+ return Math.min(a, b) - d;
+ };
+ return Segment;
+ })(Phaser.Physics.Shape);
+ Shapes.Segment = Segment;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Collision Handlers
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Collision = (function () {
+ function Collision() { }
+ Collision.prototype.collide = function (a, b, contacts) {
+ // Circle (a is the circle)
+ if(a.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ if(b.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ return this.circle2Circle(a, b, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ return this.circle2Segment(a, b, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ return this.circle2Poly(a, b, contacts);
+ }
+ }
+ // Segment (a is the segment)
+ if(a.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ if(b.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ return this.circle2Segment(b, a, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ return this.segment2Segment(a, b, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ return this.segment2Poly(a, b, contacts);
+ }
+ }
+ // Poly (a is the poly)
+ if(a.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ if(b.type == Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ return this.circle2Poly(b, a, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ return this.segment2Poly(b, a, contacts);
+ } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ return this.poly2Poly(a, b, contacts);
+ }
+ }
+ };
+ Collision.prototype._circle2Circle = function (c1, r1, c2, r2, contactArr) {
+ var rmax = r1 + r2;
+ var t = new Phaser.Vec2();
+ //var t = vec2.sub(c2, c1);
+ Phaser.Vec2Utils.subtract(c2, c1, t);
+ var distsq = t.lengthSq();
+ if(distsq > rmax * rmax) {
+ return 0;
+ }
+ var dist = Math.sqrt(distsq);
+ var p = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(c1, t, 0.5 + (r1 - r2) * 0.5 / dist, p);
+ //var p = vec2.mad(c1, t, 0.5 + (r1 - r2) * 0.5 / dist);
+ var n = new Phaser.Vec2();
+ //var n = (dist != 0) ? vec2.scale(t, 1 / dist) : vec2.zero;
+ if(dist != 0) {
+ Phaser.Vec2Utils.scale(t, 1 / dist, n);
+ }
+ var d = dist - rmax;
+ contactArr.push(new Physics.Contact(p, n, d, 0));
+ return 1;
+ };
+ Collision.prototype.circle2Circle = function (circ1, circ2, contactArr) {
+ return this._circle2Circle(circ1.tc, circ1.radius, circ2.tc, circ2.radius, contactArr);
+ };
+ Collision.prototype.circle2Segment = function (circ, seg, contactArr) {
+ var rsum = circ.radius + seg.radius;
+ // Normal distance from segment
+ var dn = Phaser.Vec2Utils.dot(circ.tc, seg.tn) - Phaser.Vec2Utils.dot(seg.ta, seg.tn);
+ var dist = (dn < 0 ? dn * -1 : dn) - rsum;
+ if(dist > 0) {
+ return 0;
+ }
+ // Tangential distance along segment
+ var dt = Phaser.Vec2Utils.cross(circ.tc, seg.tn);
+ var dtMin = Phaser.Vec2Utils.cross(seg.ta, seg.tn);
+ var dtMax = Phaser.Vec2Utils.cross(seg.tb, seg.tn);
+ if(dt < dtMin) {
+ if(dt < dtMin - rsum) {
+ return 0;
+ }
+ return this._circle2Circle(circ.tc, circ.radius, seg.ta, seg.radius, contactArr);
+ } else if(dt > dtMax) {
+ if(dt > dtMax + rsum) {
+ return 0;
+ }
+ return this._circle2Circle(circ.tc, circ.radius, seg.tb, seg.radius, contactArr);
+ }
+ var n = new Phaser.Vec2();
+ if(dn > 0) {
+ n.copyFrom(seg.tn);
+ } else {
+ Phaser.Vec2Utils.negative(seg.tn, n);
+ }
+ //var n = (dn > 0) ? seg.tn : vec2.neg(seg.tn);
+ var c1 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + dist * 0.5), c1);
+ var c2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(n, c2);
+ contactArr.push(new Physics.Contact(c1, c2, dist, 0));
+ //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + dist * 0.5)), vec2.neg(n), dist, 0));
+ return 1;
+ };
+ Collision.prototype.circle2Poly = function (circ, poly, contactArr) {
+ var minDist = -999999;
+ var minIdx = -1;
+ for(var i = 0; i < poly.verts.length; i++) {
+ var plane = poly.tplanes[i];
+ var dist = Phaser.Vec2Utils.dot(circ.tc, plane.normal) - plane.d - circ.radius;
+ if(dist > 0) {
+ return 0;
+ } else if(dist > minDist) {
+ minDist = dist;
+ minIdx = i;
+ }
+ }
+ var n = poly.tplanes[minIdx].normal;
+ var a = poly.tverts[minIdx];
+ var b = poly.tverts[(minIdx + 1) % poly.verts.length];
+ var dta = Phaser.Vec2Utils.cross(a, n);
+ var dtb = Phaser.Vec2Utils.cross(b, n);
+ var dt = Phaser.Vec2Utils.cross(circ.tc, n);
+ if(dt > dta) {
+ return this._circle2Circle(circ.tc, circ.radius, a, 0, contactArr);
+ } else if(dt < dtb) {
+ return this._circle2Circle(circ.tc, circ.radius, b, 0, contactArr);
+ }
+ var c1 = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + minDist * 0.5), c1);
+ var c2 = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(n, c2);
+ contactArr.push(new Physics.Contact(c1, c2, minDist, 0));
+ //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + minDist * 0.5)), vec2.neg(n), minDist, 0));
+ return 1;
+ };
+ Collision.prototype.segmentPointDistanceSq = function (seg, p) {
+ var w = new Phaser.Vec2();
+ var d = new Phaser.Vec2();
+ Phaser.Vec2Utils.subtract(p, seg.ta, w);
+ Phaser.Vec2Utils.subtract(seg.tb, seg.ta, d);
+ //var w = vec2.sub(p, seg.ta);
+ //var d = vec2.sub(seg.tb, seg.ta);
+ var proj = w.dot(d);
+ if(proj <= 0) {
+ return w.dot(w);
+ }
+ var vsq = d.dot(d);
+ if(proj >= vsq) {
+ return w.dot(w) - 2 * proj + vsq;
+ }
+ return w.dot(w) - proj * proj / vsq;
+ };
+ Collision.prototype.segment2Segment = // FIXME and optimise me lots!!!
+ function (seg1, seg2, contactArr) {
+ var d = [];
+ d[0] = this.segmentPointDistanceSq(seg1, seg2.ta);
+ d[1] = this.segmentPointDistanceSq(seg1, seg2.tb);
+ d[2] = this.segmentPointDistanceSq(seg2, seg1.ta);
+ d[3] = this.segmentPointDistanceSq(seg2, seg1.tb);
+ var idx1 = d[0] < d[1] ? 0 : 1;
+ var idx2 = d[2] < d[3] ? 2 : 3;
+ var idxm = d[idx1] < d[idx2] ? idx1 : idx2;
+ var s, t;
+ var u = Phaser.Vec2Utils.subtract(seg1.tb, seg1.ta);
+ var v = Phaser.Vec2Utils.subtract(seg2.tb, seg2.ta);
+ switch(idxm) {
+ case 0:
+ s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.ta, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
+ s = s < 0 ? 0 : (s > 1 ? 1 : s);
+ t = 0;
+ break;
+ case 1:
+ s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.tb, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
+ s = s < 0 ? 0 : (s > 1 ? 1 : s);
+ t = 1;
+ break;
+ case 2:
+ s = 0;
+ t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.ta, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
+ t = t < 0 ? 0 : (t > 1 ? 1 : t);
+ break;
+ case 3:
+ s = 1;
+ t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.tb, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
+ t = t < 0 ? 0 : (t > 1 ? 1 : t);
+ break;
+ }
+ var minp1 = Phaser.Vec2Utils.multiplyAdd(seg1.ta, u, s);
+ var minp2 = Phaser.Vec2Utils.multiplyAdd(seg2.ta, v, t);
+ return this._circle2Circle(minp1, seg1.radius, minp2, seg2.radius, contactArr);
+ };
+ Collision.prototype.findPointsBehindSeg = // Identify vertexes that have penetrated the segment.
+ function (contactArr, seg, poly, dist, coef) {
+ var dta = Phaser.Vec2Utils.cross(seg.tn, seg.ta);
+ var dtb = Phaser.Vec2Utils.cross(seg.tn, seg.tb);
+ var n = new Phaser.Vec2();
+ Phaser.Vec2Utils.scale(seg.tn, coef, n);
+ //var n = vec2.scale(seg.tn, coef);
+ for(var i = 0; i < poly.verts.length; i++) {
+ var v = poly.tverts[i];
+ if(Phaser.Vec2Utils.dot(v, n) < Phaser.Vec2Utils.dot(seg.tn, seg.ta) * coef + seg.radius) {
+ var dt = Phaser.Vec2Utils.cross(seg.tn, v);
+ if(dta >= dt && dt >= dtb) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly.id << 16) | i));
+ }
+ }
+ }
+ };
+ Collision.prototype.segment2Poly = function (seg, poly, contactArr) {
+ var seg_td = Phaser.Vec2Utils.dot(seg.tn, seg.ta);
+ var seg_d1 = poly.distanceOnPlane(seg.tn, seg_td) - seg.radius;
+ if(seg_d1 > 0) {
+ return 0;
+ }
+ var n = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(seg.tn, n);
+ var seg_d2 = poly.distanceOnPlane(n, -seg_td) - seg.radius;
+ //var seg_d2 = poly.distanceOnPlane(vec2.neg(seg.tn), -seg_td) - seg.r;
+ if(seg_d2 > 0) {
+ return 0;
+ }
+ var poly_d = -999999;
+ var poly_i = -1;
+ for(var i = 0; i < poly.verts.length; i++) {
+ var plane = poly.tplanes[i];
+ var dist = seg.distanceOnPlane(plane.normal, plane.d);
+ if(dist > 0) {
+ return 0;
+ }
+ if(dist > poly_d) {
+ poly_d = dist;
+ poly_i = i;
+ }
+ }
+ var poly_n = new Phaser.Vec2();
+ Phaser.Vec2Utils.negative(poly.tplanes[poly_i].normal, poly_n);
+ //var poly_n = vec2.neg(poly.tplanes[poly_i].n);
+ var va = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(seg.ta, poly_n, seg.radius, va);
+ //var va = vec2.mad(seg.ta, poly_n, seg.r);
+ var vb = new Phaser.Vec2();
+ Phaser.Vec2Utils.multiplyAdd(seg.tb, poly_n, seg.radius, vb);
+ //var vb = vec2.mad(seg.tb, poly_n, seg.r);
+ if(poly.containPoint(va)) {
+ contactArr.push(new Physics.Contact(va, poly_n, poly_d, (seg.id << 16) | 0));
+ }
+ if(poly.containPoint(vb)) {
+ contactArr.push(new Physics.Contact(vb, poly_n, poly_d, (seg.id << 16) | 1));
+ }
+ // Floating point precision problems here.
+ // This will have to do for now.
+ poly_d -= 0.1;
+ if(seg_d1 >= poly_d || seg_d2 >= poly_d) {
+ if(seg_d1 > seg_d2) {
+ this.findPointsBehindSeg(contactArr, seg, poly, seg_d1, 1);
+ } else {
+ this.findPointsBehindSeg(contactArr, seg, poly, seg_d2, -1);
+ }
+ }
+ // If no other collision points are found, try colliding endpoints.
+ if(contactArr.length == 0) {
+ var poly_a = poly.tverts[poly_i];
+ var poly_b = poly.tverts[(poly_i + 1) % poly.verts.length];
+ if(this._circle2Circle(seg.ta, seg.radius, poly_a, 0, contactArr)) {
+ return 1;
+ }
+ if(this._circle2Circle(seg.tb, seg.radius, poly_a, 0, contactArr)) {
+ return 1;
+ }
+ if(this._circle2Circle(seg.ta, seg.radius, poly_b, 0, contactArr)) {
+ return 1;
+ }
+ if(this._circle2Circle(seg.tb, seg.radius, poly_b, 0, contactArr)) {
+ return 1;
+ }
+ }
+ return contactArr.length;
+ };
+ Collision.prototype.findMSA = // Find the minimum separating axis for the given poly and plane list.
+ function (poly, planes, num) {
+ var min_dist = -999999;
+ var min_index = -1;
+ for(var i = 0; i < num; i++) {
+ var dist = poly.distanceOnPlane(planes[i].normal, planes[i].d);
+ if(dist > 0) {
+ // no collision
+ return {
+ dist: 0,
+ index: -1
+ };
+ } else if(dist > min_dist) {
+ min_dist = dist;
+ min_index = i;
+ }
+ }
+ // new object - see what we can do here
+ return {
+ dist: min_dist,
+ index: min_index
+ };
+ };
+ Collision.prototype.findVertsFallback = function (contactArr, poly1, poly2, n, dist) {
+ var num = 0;
+ for(var i = 0; i < poly1.verts.length; i++) {
+ var v = poly1.tverts[i];
+ if(poly2.containPointPartial(v, n)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly1.id << 16) | i));
+ num++;
+ }
+ }
+ for(var i = 0; i < poly2.verts.length; i++) {
+ var v = poly2.tverts[i];
+ if(poly1.containPointPartial(v, n)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly2.id << 16) | i));
+ num++;
+ }
+ }
+ return num;
+ };
+ Collision.prototype.findVerts = // Find the overlapped vertices.
+ function (contactArr, poly1, poly2, n, dist) {
+ var num = 0;
+ for(var i = 0; i < poly1.verts.length; i++) {
+ var v = poly1.tverts[i];
+ if(poly2.containPoint(v)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly1.id << 16) | i));
+ num++;
+ }
+ }
+ for(var i = 0; i < poly2.verts.length; i++) {
+ var v = poly2.tverts[i];
+ if(poly1.containPoint(v)) {
+ contactArr.push(new Physics.Contact(v, n, dist, (poly2.id << 16) | i));
+ num++;
+ }
+ }
+ return num > 0 ? num : this.findVertsFallback(contactArr, poly1, poly2, n, dist);
+ };
+ Collision.prototype.poly2Poly = function (poly1, poly2, contactArr) {
+ var msa1 = this.findMSA(poly2, poly1.tplanes, poly1.verts.length);
+ if(msa1.index == -1) {
+ console.log('poly2poly 0', msa1);
+ return 0;
+ }
+ var msa2 = this.findMSA(poly1, poly2.tplanes, poly2.verts.length);
+ if(msa2.index == -1) {
+ console.log('poly2poly 1', msa2);
+ return 0;
+ }
+ // Penetration normal direction should be from poly1 to poly2
+ if(msa1.dist > msa2.dist) {
+ return this.findVerts(contactArr, poly1, poly2, poly1.tplanes[msa1.index].normal, msa1.dist);
+ }
+ return this.findVerts(contactArr, poly1, poly2, Phaser.Vec2Utils.negative(poly2.tplanes[msa2.index].normal), msa2.dist);
+ };
+ return Collision;
+ })();
+ Physics.Collision = Collision;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ })(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Space
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Physics) {
+ var Space = (function () {
+ function Space(manager) {
+ this.postSolve = null;
+ this.stepCount = 0;
+ this._manager = manager;
+ this.bodies = [];
+ this.bodyHash = {
+ };
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.numContacts = 0;
+ this.contactSolvers = [];
+ this.gravity = this._manager.gravity;
+ this.damping = 0;
+ this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE;
+ this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE;
+ }
+ Space.TIME_TO_SLEEP = 0.5;
+ Space.SLEEP_LINEAR_TOLERANCE = 0.5;
+ Space.SLEEP_ANGULAR_TOLERANCE = 2 * 0.017453292519943294444444444444444;
+ Space.prototype.clear = function () {
+ Physics.Manager.shapeCounter = 0;
+ Physics.Manager.bodyCounter = 0;
+ Physics.Manager.jointCounter = 0;
+ for(var i = 0; i < this.bodies.length; i++) {
+ if(this.bodies[i]) {
+ this.removeBody(this.bodies[i]);
+ }
+ }
+ this.bodies = [];
+ this.bodyHash = {
+ };
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.contactSolvers = [];
+ this.stepCount = 0;
+ };
+ Space.prototype.addBody = function (body) {
+ if(this.bodyHash[body.id] != undefined) {
+ return;
+ }
+ var index = this.bodies.push(body) - 1;
+ this.bodyHash[body.id] = index;
+ body.awake(true);
+ body.space = this;
+ body.cacheData('addBody');
+ };
+ Space.prototype.removeBody = function (body) {
+ if(this.bodyHash[body.id] == undefined) {
+ return;
+ }
+ // Remove linked joints
+ for(var i = 0; i < body.joints.length; i++) {
+ if(body.joints[i]) {
+ this.removeJoint(body.joints[i]);
+ }
+ }
+ body.space = null;
+ var index = this.bodyHash[body.id];
+ delete this.bodyHash[body.id];
+ delete this.bodies[index];
+ };
+ Space.prototype.addJoint = function (joint) {
+ if(this.jointHash[joint.id] != undefined) {
+ return;
+ }
+ joint.body1.awake(true);
+ joint.body2.awake(true);
+ var index = this.joints.push(joint) - 1;
+ this.jointHash[joint.id] = index;
+ var index = joint.body1.joints.push(joint) - 1;
+ joint.body1.jointHash[joint.id] = index;
+ var index = joint.body2.joints.push(joint) - 1;
+ joint.body2.jointHash[joint.id] = index;
+ };
+ Space.prototype.removeJoint = function (joint) {
+ if(this.jointHash[joint.id] == undefined) {
+ return;
+ }
+ joint.body1.awake(true);
+ joint.body2.awake(true);
+ var index = joint.body1.jointHash[joint.id];
+ delete joint.body1.jointHash[joint.id];
+ delete joint.body1.joints[index];
+ var index = joint.body2.jointHash[joint.id];
+ delete joint.body2.jointHash[joint.id];
+ delete joint.body2.joints[index];
+ var index = this.jointHash[joint.id];
+ delete this.jointHash[joint.id];
+ delete this.joints[index];
+ };
+ Space.prototype.findShapeByPoint = function (p, refShape) {
+ var firstShape;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ if(shape.pointQuery(p)) {
+ if(!refShape) {
+ return shape;
+ }
+ if(!firstShape) {
+ firstShape = shape;
+ }
+ if(shape == refShape) {
+ refShape = null;
+ }
+ }
+ }
+ }
+ return firstShape;
+ };
+ Space.prototype.findBodyByPoint = function (p, refBody) {
+ var firstBody;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ if(shape.pointQuery(p)) {
+ if(!refBody) {
+ return shape.body;
+ }
+ if(!firstBody) {
+ firstBody = shape.body;
+ }
+ if(shape.body == refBody) {
+ refBody = null;
+ }
+ break;
+ }
+ }
+ }
+ return firstBody;
+ };
+ Space.prototype.shapeById = function (id) {
+ var shape;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ if(body.shapes[j].id == id) {
+ return body.shapes[j];
+ }
+ }
+ }
+ return null;
+ };
+ Space.prototype.jointById = function (id) {
+ var index = this.jointHash[id];
+ if(index != undefined) {
+ return this.joints[index];
+ }
+ return null;
+ };
+ Space.prototype.findVertexByPoint = function (p, minDist, refVertexId) {
+ var firstVertexId = -1;
+ refVertexId = refVertexId || -1;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ var index = shape.findVertexByPoint(p, minDist);
+ if(index != -1) {
+ var vertex = (shape.id << 16) | index;
+ if(refVertexId == -1) {
+ return vertex;
+ }
+ if(firstVertexId == -1) {
+ firstVertexId = vertex;
+ }
+ if(vertex == refVertexId) {
+ refVertexId = -1;
+ }
+ }
+ }
+ }
+ return firstVertexId;
+ };
+ Space.prototype.findEdgeByPoint = function (p, minDist, refEdgeId) {
+ var firstEdgeId = -1;
+ refEdgeId = refEdgeId || -1;
+ for(var i = 0; i < this.bodies.length; i++) {
+ var body = this.bodies[i];
+ if(!body) {
+ continue;
+ }
+ for(var j = 0; j < body.shapes.length; j++) {
+ var shape = body.shapes[j];
+ if(shape.type != Physics.Manager.SHAPE_TYPE_POLY) {
+ continue;
+ }
+ var index = shape.findEdgeByPoint(p, minDist);
+ if(index != -1) {
+ var edge = (shape.id << 16) | index;
+ if(refEdgeId == -1) {
+ return edge;
+ }
+ if(firstEdgeId == -1) {
+ firstEdgeId = edge;
+ }
+ if(edge == refEdgeId) {
+ refEdgeId = -1;
+ }
+ }
+ }
+ }
+ return firstEdgeId;
+ };
+ Space.prototype.findJointByPoint = function (p, minDist, refJointId) {
+ var firstJointId = -1;
+ var dsq = minDist * minDist;
+ refJointId = refJointId || -1;
+ for(var i = 0; i < this.joints.length; i++) {
+ var joint = this.joints[i];
+ if(!joint) {
+ continue;
+ }
+ var jointId = -1;
+ if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor1()) < dsq) {
+ jointId = (joint.id << 16 | 0);
+ } else if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor2()) < dsq) {
+ jointId = (joint.id << 16 | 1);
+ }
+ if(jointId != -1) {
+ if(refJointId == -1) {
+ return jointId;
+ }
+ if(firstJointId == -1) {
+ firstJointId = jointId;
+ }
+ if(jointId == refJointId) {
+ refJointId = -1;
+ }
+ }
+ }
+ return firstJointId;
+ };
+ Space.prototype.findContactSolver = function (shape1, shape2) {
+ Physics.Manager.write('findContactSolver. Length: ' + this._cl);
+ for(var i = 0; i < this._cl; i++) {
+ var contactSolver = this.contactSolvers[i];
+ if(shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) {
+ return contactSolver;
+ }
+ }
+ return null;
+ };
+ Space.prototype.genTemporalContactSolvers = function () {
+ Physics.Manager.write('genTemporalContactSolvers');
+ this._cl = 0;
+ this.contactSolvers.length = 0;
+ this.numContacts = 0;
+ for(var body1Index = 0; body1Index < this._bl; body1Index++) {
+ if(!this.bodies[body1Index]) {
+ continue;
+ }
+ this.bodies[body1Index].stepCount = this.stepCount;
+ for(var body2Index = 0; body2Index < this._bl; body2Index++) {
+ if(this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) {
+ continue;
+ }
+ Physics.Manager.write('body1 and body2 intersect');
+ for(var i = 0; i < this.bodies[body1Index].shapesLength; i++) {
+ for(var j = 0; j < this.bodies[body2Index].shapesLength; j++) {
+ this._shape1 = this.bodies[body1Index].shapes[i];
+ this._shape2 = this.bodies[body2Index].shapes[j];
+ var contactArr = [];
+ if(!Physics.Manager.collision.collide(this._shape1, this._shape2, contactArr)) {
+ continue;
+ }
+ if(this._shape1.type > this._shape2.type) {
+ var temp = this._shape1;
+ this._shape1 = this._shape2;
+ this._shape2 = temp;
+ }
+ this.numContacts += contactArr.length;
+ // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers)
+ var contactSolver = this.findContactSolver(this._shape1, this._shape2);
+ Physics.Manager.write('findContactSolver result: ' + contactSolver);
+ if(contactSolver) {
+ contactSolver.update(contactArr);
+ this.contactSolvers.push(contactSolver);
+ } else {
+ Physics.Manager.write('awake both bodies');
+ this.bodies[body1Index].awake(true);
+ this.bodies[body2Index].awake(true);
+ var newContactSolver = new Physics.ContactSolver(this._shape1, this._shape2);
+ newContactSolver.contacts = contactArr;
+ newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity);
+ newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction);
+ this.contactSolvers.push(newContactSolver);
+ Physics.Manager.write('new contact solver');
+ }
+ }
+ }
+ }
+ }
+ this._cl = this.contactSolvers.length;
+ };
+ Space.prototype.initSolver = function (warmStarting) {
+ Physics.Manager.write('initSolver');
+ Physics.Manager.write('contactSolvers.length: ' + this._cl);
+ // Initialize contact solvers
+ for(var c = 0; c < this._cl; c++) {
+ this.contactSolvers[c].initSolver(this._deltaInv);
+ // Warm starting (apply cached impulse)
+ if(warmStarting) {
+ this.contactSolvers[c].warmStart();
+ }
+ }
+ // Initialize joint solver
+ for(var j = 0; j < this.joints.length; j++) {
+ if(this.joints[j]) {
+ this.joints[j].initSolver(this._delta, warmStarting);
+ }
+ }
+ // Warm starting (apply cached impulse)
+ /*
+ if (warmStarting)
+ {
+ for (var c = 0; c < this._cl; c++)
+ {
+ this.contactSolvers[c].warmStart();
+ }
+ }
+ */
+ };
+ Space.prototype.velocitySolver = function (iterations) {
+ Physics.Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl);
+ for(var i = 0; i < iterations; i++) {
+ for(var j = 0; j < this._jl; j++) {
+ if(this.joints[j]) {
+ this.joints[j].solveVelocityConstraints();
+ }
+ }
+ for(var c = 0; c < this._cl; c++) {
+ this.contactSolvers[c].solveVelocityConstraints();
+ }
+ }
+ };
+ Space.prototype.positionSolver = function (iterations) {
+ this._positionSolved = false;
+ for(var i = 0; i < iterations; i++) {
+ this._contactsOk = true;
+ this._jointsOk = true;
+ for(var c = 0; c < this._cl; c++) {
+ this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk;
+ }
+ for(var j = 0; j < this._jl; j++) {
+ if(this.joints[j]) {
+ this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk;
+ }
+ }
+ if(this._contactsOk && this._jointsOk) {
+ // exit early if the position errors are small
+ this._positionSolved = true;
+ break;
+ }
+ }
+ return this._positionSolved;
+ };
+ Space.prototype.step = // Step through the physics simulation
+ function (dt, velocityIterations, positionIterations, warmStarting, allowSleep) {
+ Physics.Manager.clear();
+ Physics.Manager.write('Space step ' + this.stepCount);
+ this._delta = dt;
+ this._deltaInv = 1 / dt;
+ this._bl = this.bodies.length;
+ this._jl = this.joints.length;
+ this.stepCount++;
+ // 1) Generate Contact Solvers (into the this.contactSolvers array)
+ this.genTemporalContactSolvers();
+ Physics.Manager.dump("Contact Solvers", this.bodies[1]);
+ // 2) Initialize the Contact Solvers
+ this.initSolver(warmStarting);
+ Physics.Manager.dump("Init Solver", this.bodies[1]);
+ // 3) Intergrate velocity
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
+ this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping);
+ }
+ }
+ Physics.Manager.dump("Update Velocity", this.bodies[1]);
+ // 4) Awaken bodies via joints
+ for(var j = 0; i < this._jl; j++) {
+ if(!this.joints[j]) {
+ continue;
+ }
+ // combine
+ var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic;
+ var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic;
+ if(awake1 ^ awake2) {
+ if(!awake1) {
+ this.joints[j].body1.awake(true);
+ }
+ if(!awake2) {
+ this.joints[j].body2.awake(true);
+ }
+ }
+ }
+ // 5) Iterative velocity constraints solver
+ this.velocitySolver(velocityIterations);
+ Physics.Manager.dump("Velocity Solvers", this.bodies[1]);
+ // 6) Intergrate position
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
+ this.bodies[i].updatePosition(this._delta);
+ }
+ }
+ Physics.Manager.dump("Update Position", this.bodies[1]);
+ // 7) Process breakable joint
+ for(var i = 0; i < this._jl; i++) {
+ if(this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) {
+ this.removeJoint(this.joints[i]);
+ }
+ }
+ // 8) Iterative position constraints solver (result stored in this._positionSolved)
+ this.positionSolver(positionIterations);
+ Physics.Manager.dump("Position Solver", this.bodies[1]);
+ // 9) Sync the Transforms
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i]) {
+ this.bodies[i].syncTransform();
+ }
+ }
+ Physics.Manager.dump("Sync Transform", this.bodies[1]);
+ // 10) Post solve collision callback
+ if(this.postSolve) {
+ for(var i = 0; i < this._cl; i++) {
+ this.postSolve(this.contactSolvers[i]);
+ }
+ }
+ // 11) Cache Body Data
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
+ this.bodies[i].cacheData('post solve collision callback');
+ }
+ }
+ Physics.Manager.dump("Cache Data", this.bodies[1]);
+ Physics.Manager.writeAll();
+ // 12) Process sleeping
+ if(allowSleep) {
+ this._minSleepTime = 999999;
+ for(var i = 0; i < this._bl; i++) {
+ if(!this.bodies[i] || this.bodies[i].isDynamic == false) {
+ continue;
+ }
+ if(this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) {
+ this.bodies[i].sleepTime = 0;
+ this._minSleepTime = 0;
+ } else {
+ this.bodies[i].sleepTime += this._delta;
+ this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime);
+ }
+ }
+ if(this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) {
+ for(var i = 0; i < this._bl; i++) {
+ if(this.bodies[i]) {
+ this.bodies[i].awake(false);
+ }
+ }
+ }
+ }
+ };
+ return Space;
+ })();
+ Physics.Space = Space;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Triangle
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Triangle = (function (_super) {
+ __extends(Triangle, _super);
+ function Triangle(x1, y1, x2, y2, x3, y3) {
+ x1 = Physics.Manager.pixelsToMeters(x1);
+ y1 = Physics.Manager.pixelsToMeters(y1);
+ x2 = Physics.Manager.pixelsToMeters(x2);
+ y2 = Physics.Manager.pixelsToMeters(y2);
+ x3 = Physics.Manager.pixelsToMeters(x3);
+ y3 = Physics.Manager.pixelsToMeters(y3);
+ _super.call(this, [
+ {
+ x: x1,
+ y: y1
+ },
+ {
+ x: x2,
+ y: y2
+ },
+ {
+ x: x3,
+ y: y3
+ }
+ ]);
+ }
+ return Triangle;
+ })(Phaser.Physics.Shapes.Poly);
+ Shapes.Triangle = Triangle;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ (function (Physics) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Shapes - Box
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
+ */
+ (function (Shapes) {
+ var Box = (function (_super) {
+ __extends(Box, _super);
+ // Give in pixels
+ function Box(x, y, width, height) {
+ x = Physics.Manager.pixelsToMeters(x);
+ y = Physics.Manager.pixelsToMeters(y);
+ width = Physics.Manager.pixelsToMeters(width);
+ height = Physics.Manager.pixelsToMeters(height);
+ var hw = width * 0.5;
+ var hh = height * 0.5;
+ _super.call(this, [
+ {
+ x: -hw + x,
+ y: +hh + y
+ },
+ {
+ x: -hw + x,
+ y: -hh + y
+ },
+ {
+ x: +hw + x,
+ y: -hh + y
+ },
+ {
+ x: +hw + x,
+ y: +hh + y
+ }
+ ]);
+ }
+ return Box;
+ })(Phaser.Physics.Shapes.Poly);
+ Shapes.Box = Box;
+ })(Physics.Shapes || (Physics.Shapes = {}));
+ var Shapes = Physics.Shapes;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /**
+ * Phaser - Advanced Physics - Body
+ *
+ * Based on the work Ju Hyung Lee started in JS PhyRus.
*/
(function (Physics) {
var Body = (function () {
- function Body(sprite, type) {
- this.angularVelocity = 0;
- this.angularAcceleration = 0;
- this.angularDrag = 0;
- this.maxAngular = 10000;
- this.mass = 1;
- this._width = 0;
- this._height = 0;
- this.sprite = sprite;
- this.game = sprite.game;
+ function Body(sprite, type, x, y, shapeType) {
+ if (typeof x === "undefined") { x = 0; }
+ if (typeof y === "undefined") { y = 0; }
+ if (typeof shapeType === "undefined") { shapeType = 0; }
+ this._tempVec2 = new Phaser.Vec2();
+ // Shapes
+ this.shapes = [];
+ // Joints
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.fixedRotation = false;
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+ this.stepCount = 0;
+ this.id = Phaser.Physics.Manager.bodyCounter++;
+ this.name = 'body' + this.id;
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();
- this._width = sprite.width;
- this._height = sprite.height;
- // Body properties
- this.gravity = Phaser.Vec2Utils.clone(this.game.world.physics.gravity);
- this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce);
+ if(sprite) {
+ this.sprite = sprite;
+ this.game = sprite.game;
+ this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Manager.pixelsToMeters(sprite.y));
+ this.angle = sprite.rotation;
+ } else {
+ this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(x), Phaser.Physics.Manager.pixelsToMeters(y));
+ this.angle = 0;
+ }
+ this.transform = new Phaser.Transform(this.position, this.angle);
+ this.centroid = new Phaser.Vec2();
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.force = new Phaser.Vec2();
this.angularVelocity = 0;
- this.angularAcceleration = 0;
- this.angularDrag = 0;
- this.touching = Phaser.Types.NONE;
- this.wasTouching = Phaser.Types.NONE;
+ this.torque = 0;
+ this.linearDamping = 0;
+ this.angularDamping = 0;
+ this.sleepTime = 0;
+ this.awaked = false;
+ this.shapes = [];
+ this.joints = [];
+ this.jointHash = {
+ };
+ this.bounds = new Physics.Bounds();
this.allowCollisions = Phaser.Types.ANY;
- this.position = new Phaser.Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight);
- this.oldPosition = new Phaser.Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight);
- this.offset = new Phaser.Vec2();
+ this.fixedRotation = false;
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+ this.stepCount = 0;
+ if(sprite) {
+ if(shapeType == 0) {
+ this.addBox(0, 0, this.sprite.width, this.sprite.height, 1, 1, 1);
+ } else {
+ this.addCircle(Math.max(this.sprite.width, this.sprite.height) / 2, 0, 0, 1, 1, 1);
+ }
+ }
}
- Object.defineProperty(Body.prototype, "x", {
- get: function () {
- return this.sprite.x + this.offset.x;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "y", {
- get: function () {
- return this.sprite.y + this.offset.y;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "width", {
- get: function () {
- return this._width * this.sprite.transform.scale.x;
- },
- set: function (value) {
- this._width = value;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "height", {
- get: function () {
- return this._height * this.sprite.transform.scale.y;
- },
- set: function (value) {
- this._height = value;
- },
- enumerable: true,
- configurable: true
- });
- Body.prototype.preUpdate = function () {
- this.oldPosition.copyFrom(this.position);
- this.bounds.x = this.x;
- this.bounds.y = this.y;
- this.bounds.width = this.width;
- this.bounds.height = this.height;
+ Body.prototype.toString = function () {
+ return "[{Body (name=" + this.name + " velocity=" + this.velocity.toString() + " angularVelocity: " + this.angularVelocity + ")}]";
};
- 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.game.world.physics.updateMotion(this);
- this.wasTouching = this.touching;
- this.touching = Phaser.Types.NONE;
+ Body.prototype.duplicate = function () {
+ console.log('body duplicate called');
+ //var body = new Body(this.type, this.transform.t, this.angle);
+ //for (var i = 0; i < this.shapes.length; i++)
+ //{
+ // body.addShape(this.shapes[i].duplicate());
+ //}
+ //body.resetMassData();
+ //return body;
+ };
+ Object.defineProperty(Body.prototype, "isDisabled", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_DISABLED ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "isStatic", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_STATIC ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "isKinetic", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_KINETIC ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Body.prototype, "isDynamic", {
+ get: function () {
+ return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Body.prototype.setType = function (type) {
+ if(type == this.type) {
+ return;
}
- this.position.setTo(this.x, this.y);
+ this.force.setTo(0, 0);
+ this.velocity.setTo(0, 0);
+ this.torque = 0;
+ this.angularVelocity = 0;
+ this.type = type;
+ this.awake(true);
};
- 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();
+ Body.prototype.addPoly = function (verts, elasticity, friction, density) {
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var poly = new Phaser.Physics.Shapes.Poly(verts);
+ poly.elasticity = elasticity;
+ poly.friction = friction;
+ poly.density = density;
+ this.addShape(poly);
+ this.resetMassData();
+ return poly;
+ };
+ Body.prototype.addTriangle = function (x1, y1, x2, y2, x3, y3, elasticity, friction, density) {
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var tri = new Phaser.Physics.Shapes.Triangle(x1, y1, x2, y2, x3, y3);
+ tri.elasticity = elasticity;
+ tri.friction = friction;
+ tri.density = density;
+ this.addShape(tri);
+ this.resetMassData();
+ return tri;
+ };
+ Body.prototype.addBox = function (x, y, width, height, elasticity, friction, density) {
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var box = new Phaser.Physics.Shapes.Box(x, y, width, height);
+ box.elasticity = elasticity;
+ box.friction = friction;
+ box.density = density;
+ this.addShape(box);
+ this.resetMassData();
+ return box;
+ };
+ Body.prototype.addCircle = function (radius, x, y, elasticity, friction, density) {
+ if (typeof x === "undefined") { x = 0; }
+ if (typeof y === "undefined") { y = 0; }
+ if (typeof elasticity === "undefined") { elasticity = 1; }
+ if (typeof friction === "undefined") { friction = 1; }
+ if (typeof density === "undefined") { density = 1; }
+ var circle = new Phaser.Physics.Shapes.Circle(radius, x, y);
+ circle.elasticity = elasticity;
+ circle.friction = friction;
+ circle.density = density;
+ this.addShape(circle);
+ this.resetMassData();
+ return circle;
+ };
+ Body.prototype.addShape = function (shape) {
+ // Check not already part of this body
+ shape.body = this;
+ this.shapes.push(shape);
+ this.shapesLength = this.shapes.length;
+ return shape;
+ };
+ Body.prototype.removeShape = function (shape) {
+ var index = this.shapes.indexOf(shape);
+ if(index != -1) {
+ this.shapes.splice(index, 1);
+ shape.body = undefined;
}
- 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();
+ this.shapesLength = this.shapes.length;
+ };
+ Body.prototype.setMass = function (mass) {
+ this.mass = mass;
+ this.massInverted = mass > 0 ? 1 / mass : 0;
+ };
+ Body.prototype.setInertia = function (inertia) {
+ this.inertia = inertia;
+ this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
+ };
+ Body.prototype.setTransform = function (pos, angle) {
+ // inject the transform into this.position
+ this.transform.setTo(pos, angle);
+ Physics.Manager.write('setTransform: ' + this.position.toString());
+ Physics.Manager.write('centroid: ' + this.centroid.toString());
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ Physics.Manager.write('post setTransform: ' + this.position.toString());
+ //this.position.copyFrom(this.transform.transform(this.centroid));
+ this.angle = angle;
+ };
+ Body.prototype.syncTransform = function () {
+ Physics.Manager.write('syncTransform:');
+ Physics.Manager.write('p: ' + this.position.toString());
+ Physics.Manager.write('centroid: ' + this.centroid.toString());
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ Physics.Manager.write('a: ' + this.angle);
+ this.transform.setRotation(this.angle);
+ // OPTIMISE: Creating new vector
+ Phaser.Vec2Utils.subtract(this.position, Phaser.TransformUtils.rotate(this.transform, this.centroid), this.transform.t);
+ Physics.Manager.write('--------------------');
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ Physics.Manager.write('--------------------');
+ };
+ Body.prototype.getWorldPoint = function (p) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.transform(this.transform, p);
+ };
+ Body.prototype.getWorldVector = function (v) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.rotate(this.transform, v);
+ };
+ Body.prototype.getLocalPoint = function (p) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.untransform(this.transform, p);
+ };
+ Body.prototype.getLocalVector = function (v) {
+ // OPTIMISE: Creating new vector
+ return Phaser.TransformUtils.unrotate(this.transform, v);
+ };
+ Body.prototype.setFixedRotation = function (flag) {
+ this.fixedRotation = flag;
+ this.resetMassData();
+ };
+ Body.prototype.resetMassData = function () {
+ this.centroid.setTo(0, 0);
+ this.mass = 0;
+ this.massInverted = 0;
+ this.inertia = 0;
+ this.inertiaInverted = 0;
+ if(this.isDynamic == false) {
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ //this.position.copyFrom(this.transform.transform(this.centroid));
+ return;
}
- 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();
+ var totalMassCentroid = new Phaser.Vec2(0, 0);
+ var totalMass = 0;
+ var totalInertia = 0;
+ for(var i = 0; i < this.shapes.length; i++) {
+ var shape = this.shapes[i];
+ var centroid = shape.centroid();
+ var mass = shape.area() * shape.density;
+ var inertia = shape.inertia(mass);
+ //console.log('rmd', centroid, shape);
+ totalMassCentroid.multiplyAddByScalar(centroid, mass);
+ totalMass += mass;
+ totalInertia += inertia;
}
- 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();
+ //this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
+ Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
+ this.setMass(totalMass);
+ if(!this.fixedRotation) {
+ this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
+ }
+ // Move center of mass
+ var oldPosition = Phaser.Vec2Utils.clone(this.position);
+ Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
+ // Update center of mass velocity
+ oldPosition.subtract(this.position);
+ this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
+ };
+ Body.prototype.resetJointAnchors = function () {
+ for(var i = 0; i < this.joints.length; i++) {
+ var joint = this.joints[i];
+ if(!joint) {
+ continue;
+ }
+ var anchor1 = joint.getWorldAnchor1();
+ var anchor2 = joint.getWorldAnchor2();
+ joint.setWorldAnchor1(anchor1);
+ joint.setWorldAnchor2(anchor2);
}
};
- 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.sprite.texture.context.fillStyle = color;
- this.sprite.texture.context.fillText('Sprite: (' + this.sprite.width + ' x ' + this.sprite.height + ')', x, y);
- //this.sprite.texture.context.fillText('x: ' + this._sprite.frameBounds.x.toFixed(1) + ' y: ' + this._sprite.frameBounds.y.toFixed(1) + ' rotation: ' + this._sprite.rotation.toFixed(1), x, y + 14);
- this.sprite.texture.context.fillText('x: ' + this.bounds.x.toFixed(1) + ' y: ' + this.bounds.y.toFixed(1) + ' rotation: ' + this.sprite.transform.rotation.toFixed(0), x, y + 14);
- this.sprite.texture.context.fillText('vx: ' + this.velocity.x.toFixed(1) + ' vy: ' + this.velocity.y.toFixed(1), x, y + 28);
- this.sprite.texture.context.fillText('acx: ' + this.acceleration.x.toFixed(1) + ' acy: ' + this.acceleration.y.toFixed(1), x, y + 42);
- this.sprite.texture.context.fillText('angVx: ' + this.angularVelocity.toFixed(1) + ' angAc: ' + this.angularAcceleration.toFixed(1), x, y + 56);
+ Body.prototype.cacheData = function (source) {
+ if (typeof source === "undefined") { source = ''; }
+ Physics.Manager.write('cacheData -- start');
+ Physics.Manager.write('p: ' + this.position.toString());
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ this.bounds.clear();
+ for(var i = 0; i < this.shapes.length; i++) {
+ var shape = this.shapes[i];
+ shape.cacheData(this.transform);
+ this.bounds.addBounds(shape.bounds);
+ }
+ Physics.Manager.write('bounds: ' + this.bounds.toString());
+ Physics.Manager.write('p: ' + this.position.toString());
+ Physics.Manager.write('xf: ' + this.transform.toString());
+ Physics.Manager.write('cacheData -- stop');
+ };
+ Body.prototype.updateVelocity = function (gravity, dt, damping) {
+ Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
+ Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
+ this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
+ // Apply damping.
+ // ODE: dv/dt + c * v = 0
+ // Solution: v(t) = v0 * exp(-c * t)
+ // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
+ // v2 = exp(-c * dt) * v1
+ // Taylor expansion:
+ // v2 = (1.0f - c * dt) * v1
+ this.velocity.scale(this.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
+ this.angularVelocity *= this.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ };
+ Body.prototype.inContact = function (body2) {
+ if(!body2 || this.stepCount == body2.stepCount) {
+ return false;
+ }
+ if(!(this.isAwake && this.isStatic == false) && !(body2.isAwake && body2.isStatic == false)) {
+ return false;
+ }
+ if(this.isCollidable(body2) == false) {
+ return false;
+ }
+ if(!this.bounds.intersectsBounds(body2.bounds)) {
+ return false;
+ }
+ return true;
+ };
+ Body.prototype.clamp = function (v, min, max) {
+ return v < min ? min : (v > max ? max : v);
+ };
+ Body.prototype.updatePosition = function (dt) {
+ this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
+ this.angle += this.angularVelocity * dt;
+ if(this.sprite) {
+ this.sprite.x = this.position.x * 50;
+ this.sprite.y = this.position.y * 50;
+ // Obey fixed rotation?
+ this.sprite.rotation = this.game.math.radiansToDegrees(this.angle);
+ }
+ };
+ Body.prototype.resetForce = function () {
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ };
+ Body.prototype.applyForce = function (force, p) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.force.add(force);
+ Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
+ this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
+ };
+ Body.prototype.applyForceToCenter = function (force) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.force.add(force);
+ };
+ Body.prototype.applyTorque = function (torque) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.torque += torque;
+ };
+ Body.prototype.applyLinearImpulse = function (impulse, p) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.velocity.multiplyAddByScalar(impulse, this.massInverted);
+ Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
+ this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
+ };
+ Body.prototype.applyAngularImpulse = function (impulse) {
+ if(this.isDynamic == false) {
+ return;
+ }
+ if(this.isAwake == false) {
+ this.awake(true);
+ }
+ this.angularVelocity += impulse * this.inertiaInverted;
+ };
+ Body.prototype.kineticEnergy = function () {
+ var vsq = this.velocity.dot(this.velocity);
+ var wsq = this.angularVelocity * this.angularVelocity;
+ return 0.5 * (this.mass * vsq + this.inertia * wsq);
+ };
+ Object.defineProperty(Body.prototype, "isAwake", {
+ get: function () {
+ return this.awaked;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Body.prototype.awake = function (flag) {
+ this.awaked = flag;
+ if(flag) {
+ this.sleepTime = 0;
+ } else {
+ this.velocity.setTo(0, 0);
+ this.angularVelocity = 0;
+ this.force.setTo(0, 0);
+ this.torque = 0;
+ }
+ };
+ Body.prototype.isCollidable = function (other) {
+ if(this == other) {
+ return false;
+ }
+ if(this.isDynamic == false && other.isDynamic == false) {
+ return false;
+ }
+ if(!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits)) {
+ return false;
+ }
+ for(var i = 0; i < this.joints.length; i++) {
+ var joint = this.joints[i];
+ if(!this.joints[i] || (!this.joints[i].collideConnected && other.jointHash[this.joints[i].id] != undefined)) {
+ return false;
+ }
+ }
+ return true;
};
return Body;
})();
@@ -4514,14 +7108,20 @@ 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 [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC)
+ * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED)
+ * @param [shapeType] {number} The physics shape the body will consist of (either Box (0) or Circle (1), for custom types see body.addShape)
*/
- function Sprite(game, x, y, key, frame, bodyType) {
+ function Sprite(game, x, y, key, frame, bodyType, shapeType) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof key === "undefined") { key = null; }
if (typeof frame === "undefined") { frame = null; }
- if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; }
+ if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; }
+ if (typeof shapeType === "undefined") { shapeType = 0; }
+ /**
+ * Sprite physics body.
+ */
+ this.body = null;
/**
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
*/
@@ -4569,7 +7169,11 @@ var Phaser;
this.frame = frame;
}
}
- this.body = new Phaser.Physics.Body(this, bodyType);
+ if(bodyType !== Phaser.Types.BODY_DISABLED) {
+ this.body = new Phaser.Physics.Body(this, bodyType, 0, 0, shapeType);
+ this.game.physics.addBody(this.body);
+ this.transform.origin.setTo(0.5, 0.5);
+ }
this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
this.cameraView = new Phaser.Rectangle(x, y, this.width, this.height);
this.transform.setCache();
@@ -4654,8 +7258,6 @@ var Phaser;
this.transform.update();
this.worldView.x = (this.x * this.transform.scrollFactor.x) - (this.width * this.transform.origin.x);
this.worldView.y = (this.y * this.transform.scrollFactor.y) - (this.height * this.transform.origin.y);
- //this.worldView.x = this.x * this.transform.scrollFactor.x;
- //this.worldView.y = this.y * this.transform.scrollFactor.y;
this.worldView.width = this.width;
this.worldView.height = this.height;
if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) {
@@ -4663,7 +7265,7 @@ var Phaser;
}
};
Sprite.prototype.update = /**
- * Override this function to update your class's position and appearance.
+ * Override this function to update your sprites position and appearance.
*/
function () {
};
@@ -4672,7 +7274,6 @@ var Phaser;
*/
function () {
this.animations.update();
- this.body.postUpdate();
/*
if (this.worldBounds != null)
{
@@ -4960,8 +7561,8 @@ var Phaser;
*/
function reset(sprite, x, y) {
sprite.revive();
- sprite.body.touching = Phaser.Types.NONE;
- sprite.body.wasTouching = Phaser.Types.NONE;
+ //sprite.body.touching = Types.NONE;
+ //sprite.body.wasTouching = Types.NONE;
sprite.x = x;
sprite.y = y;
sprite.body.velocity.x = 0;
@@ -9436,11 +12037,9 @@ var Phaser;
_super.call(this, game);
this.body.type = Phaser.Types.BODY_DYNAMIC;
this.lifespan = 0;
- this.friction = 500;
}
Particle.prototype.update = /**
- * The particle's main update logic. Basically it checks to see if it should
- * be dead yet, and then has some special bounce behavior if there is some gravity on it.
+ * The particle's main update logic. Basically it checks to see if it should be dead yet.
*/
function () {
// Lifespan behavior
@@ -9451,30 +12050,6 @@ var Phaser;
if(this.lifespan <= 0) {
this.kill();
}
- //simpler bounce/spin behavior for now
- if(this.body.touching) {
- if(this.body.angularVelocity != 0) {
- this.body.angularVelocity = -this.body.angularVelocity;
- }
- }
- if(this.body.acceleration.y > 0)//special behavior for particles with gravity
- {
- if(this.body.touching & Phaser.Types.FLOOR) {
- this.body.drag.x = this.friction;
- if(!(this.body.wasTouching & Phaser.Types.FLOOR)) {
- if(this.body.velocity.y < -this.body.bounce.y * 10) {
- if(this.body.angularVelocity != 0) {
- this.body.angularVelocity *= -this.body.bounce.y;
- }
- } else {
- this.body.velocity.y = 0;
- this.body.angularVelocity = 0;
- }
- }
- } else {
- this.body.drag.x = 0;
- }
- }
};
Particle.prototype.onEmit = /**
* Triggered whenever this object is launched by a Emitter.
@@ -9591,16 +12166,16 @@ var Phaser;
}
}
if(collide > 0) {
- particle.body.allowCollisions = Phaser.Types.ANY;
+ //particle.body.allowCollisions = Types.ANY;
particle.body.type = Phaser.Types.BODY_DYNAMIC;
particle.width *= collide;
particle.height *= collide;
} else {
- particle.body.allowCollisions = Phaser.Types.NONE;
- }
+ //particle.body.allowCollisions = Types.NONE;
+ }
particle.exists = false;
// Center the origin for rotation assistance
- particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
+ //particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
this.add(particle);
i++;
}
@@ -9686,7 +12261,7 @@ var Phaser;
function () {
var particle = this.recycle(Phaser.Particle);
particle.lifespan = this.lifespan;
- particle.body.bounce.setTo(this.bounce, this.bounce);
+ //particle.body.bounce.setTo(this.bounce, this.bounce);
Phaser.SpriteUtils.reset(particle, this.x - (particle.width >> 1) + this.game.math.random() * this.width, this.y - (particle.height >> 1) + this.game.math.random() * this.height);
particle.visible = true;
if(this.minParticleSpeed.x != this.maxParticleSpeed.x) {
@@ -9699,7 +12274,7 @@ var Phaser;
} else {
particle.body.velocity.y = this.minParticleSpeed.y;
}
- particle.body.acceleration.y = this.gravity;
+ //particle.body.acceleration.y = this.gravity;
if(this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0) {
particle.body.angularVelocity = this.minRotation + this.game.math.random() * (this.maxRotation - this.minRotation);
} else {
@@ -9708,8 +12283,8 @@ var Phaser;
if(particle.body.angularVelocity != 0) {
particle.rotation = this.game.math.random() * 360 - 180;
}
- particle.body.drag.x = this.particleDrag.x;
- particle.body.drag.y = this.particleDrag.y;
+ //particle.body.drag.x = this.particleDrag.x;
+ //particle.body.drag.y = this.particleDrag.y;
particle.onEmit();
};
Emitter.prototype.setSize = /**
@@ -9764,9 +12339,9 @@ var Phaser;
* @param Object {object} The Object that you want to sync up with.
*/
function (object) {
- this.x = object.body.bounds.halfWidth - (this.width >> 1);
- this.y = object.body.bounds.halfHeight - (this.height >> 1);
- };
+ //this.x = object.body.bounds.halfWidth - (this.width >> 1);
+ //this.y = object.body.bounds.halfHeight - (this.height >> 1);
+ };
return Emitter;
})(Phaser.Group);
Phaser.Emitter = Emitter;
@@ -10275,16 +12850,15 @@ var Phaser;
// Loop through the tiles we've got and check overlaps accordingly (the results are stored in this._tempTileBlock)
this._tempBlockResults = [];
this.getTempBlock(this._tempTileX, this._tempTileY, this._tempTileW, this._tempTileH, true);
- Phaser.Physics.PhysicsManager.TILE_OVERLAP = false;
- for(var r = 0; r < this._tempTileBlock.length; r++) {
- if(this._game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true) {
- this._tempBlockResults.push({
- x: this._tempTileBlock[r].x,
- y: this._tempTileBlock[r].y,
- tile: this._tempTileBlock[r].tile
- });
- }
+ /*
+ for (var r = 0; r < this._tempTileBlock.length; r++)
+ {
+ if (this._game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true)
+ {
+ this._tempBlockResults.push({ x: this._tempTileBlock[r].x, y: this._tempTileBlock[r].y, tile: this._tempTileBlock[r].tile });
}
+ }
+ */
return this._tempBlockResults;
};
TilemapLayer.prototype.getTempBlock = /**
@@ -10989,9 +13563,25 @@ var Phaser;
function (x, y, key, frame, bodyType) {
if (typeof key === "undefined") { key = ''; }
if (typeof frame === "undefined") { frame = null; }
- if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; }
+ if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; }
return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, frame, bodyType));
};
+ GameObjectFactory.prototype.physicsSprite = /**
+ * Create a new Sprite with the physics automatically created and set to DYNAMIC. The Sprite position offset is set to its center.
+ *
+ * @param x {number} X position of the new sprite.
+ * @param y {number} Y position of the new sprite.
+ * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite
+ * @param [frame] {string|number} If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name.
+ * @param [shapeType] The default body shape is either 0 for a Box or 1 for a Circle. See Sprite.body.addShape for custom shapes (polygons, etc)
+ * @returns {Sprite} The newly created sprite object.
+ */
+ function (x, y, key, frame, shapeType) {
+ if (typeof key === "undefined") { key = ''; }
+ if (typeof frame === "undefined") { frame = null; }
+ if (typeof shapeType === "undefined") { shapeType = 0; }
+ return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, frame, Phaser.Types.BODY_DYNAMIC, shapeType));
+ };
GameObjectFactory.prototype.dynamicTexture = /**
* Create a new DynamicTexture with specific size.
*
@@ -12476,1111 +15066,11 @@ var Phaser;
})();
Phaser.TweenManager = TweenManager;
})(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;
- /**
- * @type {number}
- */
- this.worldDivisions = 6;
- 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.members = new Phaser.Group(game);
- }
- PhysicsManager.OVERLAP_BIAS = 4;
- PhysicsManager.TILE_OVERLAP = false;
- PhysicsManager.prototype.updateMotion = /*
- 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.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
- body.angularVelocity += this._velocityDelta;
- body.sprite.transform.rotation += 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;
- body.sprite.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;
- body.sprite.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.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 (body1, body2) {
- return ((body1.hullX + body1.hullWidth > body2.hullX) && (body1.hullX < body2.hullX + body2.hullWidth) && (body1.hullY + body1.hullHeight > body2.hullY) && (body1.hullY < body2.hullY + body2.hullHeight));
- };
- 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.sprite.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.sprite.active && (body1.deltaY < body2.deltaY)) {
- body2.position.x += body1.position.x - body1.oldPosition.x;
- }
- }
- return true;
- } else {
- return false;
- }
- };
- PhysicsManager.prototype.overlap = /*
- private TILEseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 = 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('------------------------------------------------');
-
- }
-
- private collideWorld(shape:IPhysicsShape) {
-
- // 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);
- }
- }
-
- }
-
- private separateX(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateY(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateXWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateYWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
- */
- /**
- * 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 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.
- */
- 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.worldDivisions;
- this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
- this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
- this._quadTreeResult = this._quadTree.execute();
- console.log('over', this._quadTreeResult);
- this._quadTree.destroy();
- this._quadTree = null;
- return this._quadTreeResult;
- };
- PhysicsManager.prototype.separateTile = /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- function (object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY) {
- //var separatedX: bool = this.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
- //var separatedY: bool = this.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
- //return separatedX || separatedY;
- return false;
- };
- return PhysicsManager;
- })();
- Physics.PhysicsManager = PhysicsManager;
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public separateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
- var objDelta: number = object.x - object.last.x;
- //var objDelta: number = object.collisionMask.deltaX;
-
- if (objDelta != 0)
- {
- // Check if the X hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objDeltaAbs: number = object.collisionMask.deltaXAbs;
- var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.x + object.width - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- //console.log('
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public separateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- var objDelta: number = object.y - object.last.y;
-
- if (objDelta != 0)
- {
- // Check if the Y hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.y + object.height - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public static NEWseparateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
-
- if (object.collisionMask.deltaX != 0)
- {
- // Check if the X hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- var maxOverlap: number = object.collisionMask.deltaXAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaX > 0)
- {
- //overlap = object.x + object.width - x;
- overlap = object.collisionMask.right - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (object.collisionMask.deltaX < 0)
- {
- //overlap = object.x - width - x;
- overlap = object.collisionMask.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public NEWseparateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- //var objDelta: number = object.y - object.last.y;
-
- if (object.collisionMask.deltaY != 0)
- {
- // Check if the Y hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- //var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object.collisionMask.deltaYAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaY > 0)
- {
- //overlap = object.y + object.height - y;
- overlap = object.collisionMask.bottom - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (object.collisionMask.deltaY < 0)
- {
- //overlap = object.y - height - y;
- overlap = object.collisionMask.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
///
///
///
///
-///
+///
/**
* Phaser - World
*
@@ -13618,13 +15108,11 @@ var Phaser;
*/
function () {
this.group = new Phaser.Group(this._game, 0);
- this.physics = new Phaser.Physics.PhysicsManager(this._game, this.width, this.height);
};
World.prototype.update = /**
* This is called automatically every frame, and is where main logic happens.
*/
function () {
- //this.physics.update();
this.group.update();
this.cameras.update();
};
@@ -13632,7 +15120,6 @@ var Phaser;
* This is called automatically every frame, and is where main logic happens.
*/
function () {
- //this.physics.postUpdate();
this.group.postUpdate();
this.cameras.postUpdate();
};
@@ -13640,7 +15127,6 @@ var Phaser;
* Clean up memory.
*/
function () {
- //this.physics.destroy();
this.group.destroy();
this.cameras.destroy();
};
@@ -13651,17 +15137,13 @@ var Phaser;
* @param height {number} New height of the world.
* @param [updateCameraBounds] {boolean} Update camera bounds automatically or not. Default to true.
*/
- function (width, height, updateCameraBounds, updatePhysicsBounds) {
+ function (width, height, updateCameraBounds) {
if (typeof updateCameraBounds === "undefined") { updateCameraBounds = true; }
- if (typeof updatePhysicsBounds === "undefined") { updatePhysicsBounds = true; }
this.bounds.width = width;
this.bounds.height = height;
if(updateCameraBounds == true) {
this._game.camera.setBounds(0, 0, width, height);
}
- if(updatePhysicsBounds == true) {
- //this.physics.bounds.copyFrom(this.bounds);
- }
// dispatch world resize event
};
Object.defineProperty(World.prototype, "width", {
@@ -13789,14 +15271,19 @@ var Phaser;
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
function (source, dest, speed, xSpeedMax, ySpeedMax) {
- var a = this.angleBetween(source, dest);
+ /*
+ var a: number = this.angleBetween(source, dest);
+
source.body.velocity.x = 0;
source.body.velocity.y = 0;
+
source.body.acceleration.x = Math.cos(a) * speed;
source.body.acceleration.y = Math.sin(a) * speed;
+
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
- };
+ */
+ };
Motion.prototype.moveTowardsMouse = /**
* Move the given Sprite towards the mouse pointer coordinates at a steady velocity
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
@@ -13830,14 +15317,19 @@ var Phaser;
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
function (source, speed, xSpeedMax, ySpeedMax) {
- var a = this.angleBetweenMouse(source);
+ /*
+ var a: number = this.angleBetweenMouse(source);
+
source.body.velocity.x = 0;
source.body.velocity.y = 0;
+
source.body.acceleration.x = Math.cos(a) * speed;
source.body.acceleration.y = Math.sin(a) * speed;
+
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
- };
+ */
+ };
Motion.prototype.moveTowardsPoint = /**
* Sets the x/y velocity on the source Sprite so it will move towards the target coordinates at the speed given (in pixels per second)
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
@@ -13873,14 +15365,19 @@ var Phaser;
* @param {number} ySpeedMax The maximum speed in pixels per second in which the sprite can move vertically
*/
function (source, target, speed, xSpeedMax, ySpeedMax) {
- var a = this.angleBetweenPoint(source, target);
+ /*
+ var a: number = this.angleBetweenPoint(source, target);
+
source.body.velocity.x = 0;
source.body.velocity.y = 0;
+
source.body.acceleration.x = Math.cos(a) * speed;
source.body.acceleration.y = Math.sin(a) * speed;
+
source.body.maxVelocity.x = xSpeedMax;
source.body.maxVelocity.y = ySpeedMax;
- };
+ */
+ };
Motion.prototype.distanceBetween = /**
* Find the distance between two Sprites, taking their origin into account
*
@@ -13963,17 +15460,29 @@ var Phaser;
* @return {Point} An Point where Point.x contains the velocity x value and Point.y contains the velocity y value
*/
function (parent, speed) {
- var a;
- if(parent.body.facing == Phaser.Types.LEFT) {
- a = this.game.math.degreesToRadians(180);
- } else if(parent.body.facing == Phaser.Types.RIGHT) {
- a = this.game.math.degreesToRadians(0);
- } else if(parent.body.facing == Phaser.Types.UP) {
- a = this.game.math.degreesToRadians(-90);
- } else if(parent.body.facing == Phaser.Types.DOWN) {
- a = this.game.math.degreesToRadians(90);
+ /*
+ var a: number;
+
+ if (parent.body.facing == Types.LEFT)
+ {
+ a = this.game.math.degreesToRadians(180);
}
- return new Phaser.Point(Math.cos(a) * speed, Math.sin(a) * speed);
+ else if (parent.body.facing == Types.RIGHT)
+ {
+ a = this.game.math.degreesToRadians(0);
+ }
+ else if (parent.body.facing == Types.UP)
+ {
+ a = this.game.math.degreesToRadians(-90);
+ }
+ else if (parent.body.facing == Types.DOWN)
+ {
+ a = this.game.math.degreesToRadians(90);
+ }
+
+ return new Point(Math.cos(a) * speed, Math.sin(a) * speed);
+ */
+ return new Phaser.Point();
};
Motion.prototype.angleBetweenMouse = /**
* Find the angle (in radians) between an Sprite and the mouse, taking their x/y and origin into account.
@@ -17064,14 +18573,14 @@ var Phaser;
*/
function renderSpriteInfo(sprite, x, y, color) {
if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y);
- DebugUtils.game.stage.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14);
- DebugUtils.game.stage.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28);
- DebugUtils.game.stage.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42);
- DebugUtils.game.stage.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56);
- DebugUtils.game.stage.context.fillText('cx: ' + sprite.cameraView.x + ' cy: ' + sprite.cameraView.y + ' cw: ' + sprite.cameraView.width + ' ch: ' + sprite.cameraView.height + ' cb: ' + sprite.cameraView.bottom + ' cr: ' + sprite.cameraView.right, x, y + 70);
- DebugUtils.game.stage.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 84);
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y);
+ DebugUtils.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14);
+ DebugUtils.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28);
+ DebugUtils.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42);
+ DebugUtils.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56);
+ DebugUtils.context.fillText('cx: ' + sprite.cameraView.x + ' cy: ' + sprite.cameraView.y + ' cw: ' + sprite.cameraView.width + ' ch: ' + sprite.cameraView.height + ' cb: ' + sprite.cameraView.bottom + ' cr: ' + sprite.cameraView.right, x, y + 70);
+ DebugUtils.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 84);
};
DebugUtils.renderSpriteBounds = function renderSpriteBounds(sprite, camera, color) {
if (typeof camera === "undefined") { camera = null; }
@@ -17079,23 +18588,36 @@ var Phaser;
if(camera == null) {
camera = DebugUtils.game.camera;
}
- //var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x);
- //var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y);
var dx = sprite.worldView.x;
var dy = sprite.worldView.y;
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillRect(dx, dy, sprite.width, sprite.height);
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillRect(dx, dy, sprite.width, sprite.height);
};
- DebugUtils.renderSpritePhysicsBody = function renderSpritePhysicsBody(sprite, camera, color) {
- if (typeof camera === "undefined") { camera = null; }
- if (typeof color === "undefined") { color = 'rgba(255,0,0,0.2)'; }
- if(camera == null) {
- camera = DebugUtils.game.camera;
+ DebugUtils.renderPhysicsBody = function renderPhysicsBody(body, lineWidth, fillStyle, sleepStyle) {
+ if (typeof lineWidth === "undefined") { lineWidth = 1; }
+ if (typeof fillStyle === "undefined") { fillStyle = 'rgba(0,255,0,0.2)'; }
+ if (typeof sleepStyle === "undefined") { sleepStyle = 'rgba(100,100,100,0.2)'; }
+ for(var s = 0; s < body.shapes.length; s++) {
+ DebugUtils.context.beginPath();
+ if(body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_POLY) {
+ var verts = body.shapes[s].tverts;
+ DebugUtils.context.moveTo((body.position.x + verts[0].x) * 50, (body.position.y + verts[0].y) * 50);
+ for(var i = 0; i < verts.length; i++) {
+ DebugUtils.context.lineTo((body.position.x + verts[i].x) * 50, (body.position.y + verts[i].y) * 50);
+ }
+ DebugUtils.context.lineTo((body.position.x + verts[verts.length - 1].x) * 50, (body.position.y + verts[verts.length - 1].y) * 50);
+ } else if(body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ var circle = body.shapes[s];
+ DebugUtils.context.arc(circle.tc.x * 50, circle.tc.y * 50, circle.radius * 50, 0, Math.PI * 2, false);
+ }
+ DebugUtils.context.closePath();
+ if(body.isAwake) {
+ DebugUtils.context.fillStyle = fillStyle;
+ } else {
+ DebugUtils.context.fillStyle = sleepStyle;
+ }
+ DebugUtils.context.fill();
}
- var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.body.x - (camera.worldView.x * sprite.transform.scrollFactor.x);
- var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.body.y - (camera.worldView.y * sprite.transform.scrollFactor.y);
- DebugUtils.game.stage.context.fillStyle = color;
- DebugUtils.game.stage.context.fillRect(dx, dy, sprite.body.width, sprite.body.height);
};
return DebugUtils;
})();
@@ -17167,16 +18689,6 @@ var Phaser;
if (typeof destroyCallback === "undefined") { destroyCallback = null; }
var _this = this;
/**
- * Max allowable accumulation.
- * @type {number}
- */
- this._maxAccumulation = 32;
- /**
- * Total number of milliseconds elapsed since last update loop.
- * @type {number}
- */
- this._accumulator = 0;
- /**
* Milliseconds of time per step of the game loop.
* @type {number}
*/
@@ -17291,15 +18803,16 @@ var Phaser;
this.rnd = new Phaser.RandomDataGenerator([
(Date.now() * Math.random()).toString()
]);
+ this.physics = new Phaser.Physics.Manager(this);
this.setRenderer(Phaser.Types.RENDERER_CANVAS);
this.world.boot();
this.stage.boot();
this.input.boot();
- this.framerate = 60;
this.isBooted = true;
// Set-up some static helper references
Phaser.DebugUtils.game = this;
Phaser.ColorUtils.game = this;
+ Phaser.DebugUtils.context = this.stage.context;
// Display the default game screen?
if(this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) {
this._raf = new Phaser.RequestAnimationFrame(this, this.bootLoop);
@@ -17359,15 +18872,8 @@ var Phaser;
this.tweens.update();
this.input.update();
this.stage.update();
- this._accumulator += this.time.delta;
- if(this._accumulator > this._maxAccumulation) {
- this._accumulator = this._maxAccumulation;
- }
- while(this._accumulator >= this._step) {
- this.time.elapsed = this.time.timeScale * (this._step / 1000);
- this.world.update();
- this._accumulator = this._accumulator - this._step;
- }
+ this.physics.update();
+ this.world.update();
if(this._loadComplete && this.onUpdateCallback) {
this.onUpdateCallback.call(this.callbackContext);
}
@@ -17523,19 +19029,6 @@ var Phaser;
enumerable: true,
configurable: true
});
- Object.defineProperty(Game.prototype, "framerate", {
- get: function () {
- return 1000 / this._step;
- },
- set: function (value) {
- this._step = 1000 / value;
- if(this._maxAccumulation < this._step) {
- this._maxAccumulation = this._step;
- }
- },
- enumerable: true,
- configurable: true
- });
Game.prototype.collide = /**
* 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.
@@ -17551,7 +19044,8 @@ var Phaser;
if (typeof objectOrGroup2 === "undefined") { objectOrGroup2 = null; }
if (typeof notifyCallback === "undefined") { notifyCallback = null; }
if (typeof context === "undefined") { context = this.callbackContext; }
- return this.world.physics.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.world.physics.separate, context);
+ //return this.world.physics.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, this.world.physics.separate, context);
+ return false;
};
Object.defineProperty(Game.prototype, "camera", {
get: function () {
@@ -17906,6 +19400,169 @@ var Phaser;
Phaser.Line = Line;
})(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 = {}));
+///
///
///
/**
@@ -18061,3795 +19718,6 @@ var Phaser;
Phaser.Mat3Utils = Mat3Utils;
})(Phaser || (Phaser = {}));
///
-///
-/**
-* Phaser - 2D Transform
-*
-* A 2D Transform
-*/
-var Phaser;
-(function (Phaser) {
- var Transform = (function () {
- /**
- * Creates a new 2D Transform object.
- * @class Transform
- * @constructor
- * @return {Transform} This object
- **/
- function Transform(pos, angle) {
- this.t = Phaser.Vec2Utils.clone(pos);
- this.c = Math.cos(angle);
- this.s = Math.sin(angle);
- this.angle = angle;
- }
- Transform.prototype.toString = function () {
- return 't=' + this.t.toString() + ' c=' + this.c + ' s=' + this.s + ' a=' + this.angle;
- };
- Transform.prototype.setTo = function (pos, angle) {
- this.t.copyFrom(pos);
- this.c = Math.cos(angle);
- this.s = Math.sin(angle);
- return this;
- };
- Transform.prototype.setRotation = function (angle) {
- if(angle !== this.angle) {
- this.c = Math.cos(angle);
- this.s = Math.sin(angle);
- this.angle = angle;
- }
- return this;
- };
- Transform.prototype.setPosition = function (p) {
- this.t.copyFrom(p);
- return this;
- };
- Transform.prototype.identity = function () {
- this.t.setTo(0, 0);
- this.c = 1;
- this.s = 0;
- return this;
- };
- return Transform;
- })();
- Phaser.Transform = Transform;
-})(Phaser || (Phaser = {}));
-///
-///
-///
-/**
-* Phaser - TransformUtils
-*
-* A collection of methods useful for manipulating and performing operations on 2D Transforms.
-*
-*/
-var Phaser;
-(function (Phaser) {
- var TransformUtils = (function () {
- function TransformUtils() { }
- TransformUtils.rotate = function rotate(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- //return new vec2(v.x * this.c - v.y * this.s, v.x * this.s + v.y * this.c);
- return out.setTo(v.x * t.c - v.y * t.s, v.x * t.s + v.y * t.c);
- };
- TransformUtils.unrotate = function unrotate(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- //return new vec2(v.x * this.c + v.y * this.s, -v.x * this.s + v.y * this.c);
- return out.setTo(v.x * t.c + v.y * t.s, -v.x * t.s + v.y * t.c);
- };
- TransformUtils.transform = function transform(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- //return new vec2(v.x * this.c - v.y * this.s + this.t.x, v.x * this.s + v.y * this.c + this.t.y);
- return out.setTo(v.x * t.c - v.y * t.s + t.t.x, v.x * t.s + v.y * t.c + t.t.y);
- };
- TransformUtils.untransform = function untransform(t, v, out) {
- if (typeof out === "undefined") { out = new Phaser.Vec2(); }
- var px = v.x - t.t.x;
- var py = v.y - t.t.y;
- //return new vec2(px * this.c + py * this.s, -px * this.s + py * this.c);
- return out.setTo(px * t.c + py * t.s, -px * t.s + py * t.c);
- };
- return TransformUtils;
- })();
- Phaser.TransformUtils = TransformUtils;
-})(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 ArcadePhysics = (function () {
- function ArcadePhysics(game, width, height) {
- this._length = 0;
- /**
- * @type {number}
- */
- this.worldDivisions = 6;
- 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.members = new Phaser.Group(game);
- }
- ArcadePhysics.OVERLAP_BIAS = 4;
- ArcadePhysics.TILE_OVERLAP = false;
- ArcadePhysics.prototype.updateMotion = /*
- 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.gravity.x, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
- body.angularVelocity += this._velocityDelta;
- body.sprite.transform.rotation += 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;
- body.sprite.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;
- body.sprite.y += this._delta;
- };
- ArcadePhysics.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;
- };
- ArcadePhysics.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;
- };
- ArcadePhysics.prototype.checkHullIntersection = function (body1, body2) {
- return ((body1.hullX + body1.hullWidth > body2.hullX) && (body1.hullX < body2.hullX + body2.hullWidth) && (body1.hullY + body1.hullHeight > body2.hullY) && (body1.hullY < body2.hullY + body2.hullHeight));
- };
- ArcadePhysics.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 + Physics.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;
- }
- };
- ArcadePhysics.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 + Physics.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.sprite.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.sprite.active && (body1.deltaY < body2.deltaY)) {
- body2.position.x += body1.position.x - body1.oldPosition.x;
- }
- }
- return true;
- } else {
- return false;
- }
- };
- ArcadePhysics.prototype.overlap = /*
- private TILEseparate(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 = 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('------------------------------------------------');
-
- }
-
- private collideWorld(shape:IPhysicsShape) {
-
- // 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);
- }
- }
-
- }
-
- private separateX(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateY(shapeA: IPhysicsShape, shapeB: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateXWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
-
- private separateYWall(shapeA: IPhysicsShape, distance: Vec2, tangent: Vec2) {
-
- 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 (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;
-
- }
- */
- /**
- * 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 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.
- */
- 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;
- }
-
- QuadTree.divisions = this.worldDivisions;
-
- this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
-
- this._quadTree.load(object1, object2, notifyCallback, processCallback, context);
-
- this._quadTreeResult = this._quadTree.execute();
-
- console.log('over', this._quadTreeResult);
-
- this._quadTree.destroy();
-
- this._quadTree = null;
-
- return this._quadTreeResult;
- */
- return false;
- };
- ArcadePhysics.prototype.separateTile = /**
- * Collision resolution specifically for GameObjects vs. Tiles.
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated
- */
- function (object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY) {
- //var separatedX: bool = this.separateTileX(object, x, y, width, height, mass, collideLeft, collideRight, separateX);
- //var separatedY: bool = this.separateTileY(object, x, y, width, height, mass, collideUp, collideDown, separateY);
- //return separatedX || separatedY;
- return false;
- };
- return ArcadePhysics;
- })();
- Physics.ArcadePhysics = ArcadePhysics;
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public separateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
- var objDelta: number = object.x - object.last.x;
- //var objDelta: number = object.collisionMask.deltaX;
-
- if (objDelta != 0)
- {
- // Check if the X hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objDeltaAbs: number = object.collisionMask.deltaXAbs;
- var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.x + object.width - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- //console.log('
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public separateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- var objDelta: number = object.y - object.last.y;
-
- if (objDelta != 0)
- {
- // Check if the Y hulls actually overlap
- var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- {
- var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (objDelta > 0)
- {
- overlap = object.y + object.height - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (objDelta < 0)
- {
- overlap = object.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- /**
- * Separates the two objects on their x axis
- * @param object The GameObject to separate
- * @param tile The Tile to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
- */
- /*
- public static NEWseparateTileX(object:Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the object delta
- var overlap: number = 0;
-
- if (object.collisionMask.deltaX != 0)
- {
- // Check if the X hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x - ((objDelta > 0) ? objDelta : 0), object.last.y, object.width + ((objDelta > 0) ? objDelta : -objDelta), object.height);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- var maxOverlap: number = object.collisionMask.deltaXAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaX > 0)
- {
- //overlap = object.x + object.width - x;
- overlap = object.collisionMask.right - x;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.RIGHT) || collideLeft == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.RIGHT;
- }
- }
- else if (object.collisionMask.deltaX < 0)
- {
- //overlap = object.x - width - x;
- overlap = object.collisionMask.x - width - x;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.LEFT) || collideRight == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.LEFT;
- }
-
- }
-
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.x = object.x - overlap;
- object.velocity.x = -(object.velocity.x * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
-
- }
- */
- /**
- * Separates the two objects on their y axis
- * @param object The first GameObject to separate
- * @param tile The second GameObject to separate
- * @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
- */
- /*
- public NEWseparateTileY(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideUp: bool, collideDown: bool, separate: bool): bool {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (object.immovable)
- {
- return false;
- }
-
- // First, get the two object deltas
- var overlap: number = 0;
- //var objDelta: number = object.y - object.last.y;
-
- if (object.collisionMask.deltaY != 0)
- {
- // Check if the Y hulls actually overlap
- //var objDeltaAbs: number = (objDelta > 0) ? objDelta : -objDelta;
- //var objBounds: Rectangle = new Rectangle(object.x, object.y - ((objDelta > 0) ? objDelta : 0), object.width, object.height + objDeltaAbs);
-
- //if ((objBounds.x + objBounds.width > x) && (objBounds.x < x + width) && (objBounds.y + objBounds.height > y) && (objBounds.y < y + height))
- if (object.collisionMask.intersectsRaw(x, x + width, y, y + height))
- {
- //var maxOverlap: number = objDeltaAbs + Collision.OVERLAP_BIAS;
- var maxOverlap: number = object.collisionMask.deltaYAbs + Collision.OVERLAP_BIAS;
-
- // If they did overlap (and can), figure out by how much and flip the corresponding flags
- if (object.collisionMask.deltaY > 0)
- {
- //overlap = object.y + object.height - y;
- overlap = object.collisionMask.bottom - y;
-
- if ((overlap > maxOverlap) || !(object.allowCollisions & Collision.DOWN) || collideUp == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.DOWN;
- }
- }
- else if (object.collisionMask.deltaY < 0)
- {
- //overlap = object.y - height - y;
- overlap = object.collisionMask.y - height - y;
-
- if ((-overlap > maxOverlap) || !(object.allowCollisions & Collision.UP) || collideDown == false)
- {
- overlap = 0;
- }
- else
- {
- object.touching |= Collision.UP;
- }
- }
- }
- }
-
- // TODO - with super low velocities you get lots of stuttering, set some kind of base minimum here
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (overlap != 0)
- {
- if (separate == true)
- {
- object.y = object.y - overlap;
- object.velocity.y = -(object.velocity.y * object.elasticity);
- }
-
- Collision.TILE_OVERLAP = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- */
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Joint
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Joint = (function () {
- function Joint(type, body1, body2, collideConnected) {
- this.id = Phaser.Physics.Advanced.Manager.jointCounter++;
- this.type = type;
- this.body1 = body1;
- this.body2 = body2;
- this.collideConnected = collideConnected;
- this.maxForce = 9999999999;
- this.breakable = false;
- }
- Joint.prototype.getWorldAnchor1 = function () {
- return this.body1.getWorldPoint(this.anchor1);
- };
- Joint.prototype.getWorldAnchor2 = function () {
- return this.body2.getWorldPoint(this.anchor2);
- };
- Joint.prototype.setWorldAnchor1 = function (anchor1) {
- this.anchor1 = this.body1.getLocalPoint(anchor1);
- };
- Joint.prototype.setWorldAnchor2 = function (anchor2) {
- this.anchor2 = this.body2.getLocalPoint(anchor2);
- };
- return Joint;
- })();
- Advanced.Joint = Joint;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics Manager
- *
- * 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 (Advanced) {
- var Manager = (function () {
- function Manager(game) {
- this.lastTime = Date.now();
- this.frameRateHz = 60;
- this.timeDelta = 0;
- //public paused: bool = false;
- //public step: bool = false; // step through the simulation (i.e. per click)
- this.paused = true;
- this.step = false;
- // step through the simulation (i.e. per click)
- this.velocityIterations = 8;
- this.positionIterations = 4;
- //public velocityIterations: number = 1;
- //public positionIterations: number = 1;
- this.allowSleep = true;
- this.warmStarting = true;
- this.game = game;
- this.space = new Advanced.Space();
- Manager.collision = new Advanced.Collision();
- }
- Manager.clear = function clear() {
- Manager.debug.textContent = "";
- Manager.log = [];
- };
- Manager.write = function write(s) {
- Manager.debug.textContent += s + "\n";
- };
- Manager.writeAll = function writeAll() {
- for(var i = 0; i < Manager.log.length; i++) {
- //Manager.debug.textContent += Manager.log[i];
- }
- };
- Manager.log = [];
- Manager.dump = function dump(phase, body) {
- var s = "\n\nPhase: " + phase + "\n";
- s += "Position: " + body.position.toString() + "\n";
- s += "Velocity: " + body.velocity.toString() + "\n";
- s += "Angle: " + body.angle + "\n";
- s += "Force: " + body.force.toString() + "\n";
- s += "Torque: " + body.torque + "\n";
- s += "Bounds: " + body.bounds.toString() + "\n";
- s += "Shape ***\n";
- s += "Vert 0: " + body.shapes[0].verts[0].toString() + "\n";
- s += "Vert 1: " + body.shapes[0].verts[1].toString() + "\n";
- s += "Vert 2: " + body.shapes[0].verts[2].toString() + "\n";
- s += "Vert 3: " + body.shapes[0].verts[3].toString() + "\n";
- s += "TVert 0: " + body.shapes[0].tverts[0].toString() + "\n";
- s += "TVert 1: " + body.shapes[0].tverts[1].toString() + "\n";
- s += "TVert 2: " + body.shapes[0].tverts[2].toString() + "\n";
- s += "TVert 3: " + body.shapes[0].tverts[3].toString() + "\n";
- s += "Plane 0: " + body.shapes[0].planes[0].normal.toString() + "\n";
- s += "Plane 1: " + body.shapes[0].planes[1].normal.toString() + "\n";
- s += "Plane 2: " + body.shapes[0].planes[2].normal.toString() + "\n";
- s += "Plane 3: " + body.shapes[0].planes[3].normal.toString() + "\n";
- s += "TPlane 0: " + body.shapes[0].tplanes[0].normal.toString() + "\n";
- s += "TPlane 1: " + body.shapes[0].tplanes[1].normal.toString() + "\n";
- s += "TPlane 2: " + body.shapes[0].tplanes[2].normal.toString() + "\n";
- s += "TPlane 3: " + body.shapes[0].tplanes[3].normal.toString() + "\n";
- Manager.log.push(s);
- };
- Manager.SHAPE_TYPE_CIRCLE = 0;
- Manager.SHAPE_TYPE_SEGMENT = 1;
- Manager.SHAPE_TYPE_POLY = 2;
- Manager.SHAPE_NUM_TYPES = 3;
- Manager.JOINT_TYPE_ANGLE = 0;
- Manager.JOINT_TYPE_REVOLUTE = 1;
- Manager.JOINT_TYPE_WELD = 2;
- Manager.JOINT_TYPE_WHEEL = 3;
- Manager.JOINT_TYPE_PRISMATIC = 4;
- Manager.JOINT_TYPE_DISTANCE = 5;
- Manager.JOINT_TYPE_ROPE = 6;
- Manager.JOINT_TYPE_MOUSE = 7;
- Manager.JOINT_LINEAR_SLOP = 0.0008;
- Manager.JOINT_ANGULAR_SLOP = 2 * Phaser.GameMath.DEG_TO_RAD;
- Manager.JOINT_MAX_LINEAR_CORRECTION = 0.5;
- Manager.JOINT_MAX_ANGULAR_CORRECTION = 8 * Phaser.GameMath.DEG_TO_RAD;
- Manager.JOINT_LIMIT_STATE_INACTIVE = 0;
- Manager.JOINT_LIMIT_STATE_AT_LOWER = 1;
- Manager.JOINT_LIMIT_STATE_AT_UPPER = 2;
- Manager.JOINT_LIMIT_STATE_EQUAL_LIMITS = 3;
- Manager.CONTACT_SOLVER_COLLISION_SLOP = 0.0008;
- Manager.CONTACT_SOLVER_BAUMGARTE = 0.28;
- Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION = 1;
- Manager.bodyCounter = 0;
- Manager.jointCounter = 0;
- Manager.shapeCounter = 0;
- Manager.prototype.update = function () {
- var time = Date.now();
- var frameTime = (time - this.lastTime) / 1000;
- this.lastTime = time;
- // if rAf - why?
- frameTime = Math.floor(frameTime * 60 + 0.5) / 60;
- //if (!mouseDown)
- //{
- // var p = canvasToWorld(mousePosition);
- // var body = space.findBodyByPoint(p);
- // //domCanvas.style.cursor = body ? "pointer" : "default";
- //}
- if(!this.paused || this.step) {
- Manager.clear();
- var h = 1 / this.frameRateHz;
- this.timeDelta += frameTime;
- if(this.step) {
- this.step = false;
- this.timeDelta = h;
- }
- for(var maxSteps = 4; maxSteps > 0 && this.timeDelta >= h; maxSteps--) {
- this.space.step(h, this.velocityIterations, this.positionIterations, this.warmStarting, this.allowSleep);
- this.timeDelta -= h;
- }
- if(this.timeDelta > h) {
- this.timeDelta = 0;
- }
- }
- //frameCount++;
- };
- Manager.prototype.pixelsToMeters = function (value) {
- return value * 0.02;
- };
- Manager.prototype.metersToPixels = function (value) {
- return value * 50;
- };
- Manager.pixelsToMeters = function pixelsToMeters(value) {
- return value * 0.02;
- };
- Manager.metersToPixels = function metersToPixels(value) {
- return value * 50;
- };
- Manager.p2m = function p2m(value) {
- return value * 0.02;
- };
- Manager.m2p = function m2p(value) {
- return value * 50;
- };
- Manager.areaForCircle = function areaForCircle(radius_outer, radius_inner) {
- return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
- };
- Manager.inertiaForCircle = function inertiaForCircle(mass, center, radius_outer, radius_inner) {
- return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
- };
- Manager.areaForSegment = function areaForSegment(a, b, radius) {
- return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
- };
- Manager.centroidForSegment = function centroidForSegment(a, b) {
- return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
- };
- Manager.inertiaForSegment = function inertiaForSegment(mass, a, b) {
- var distsq = Phaser.Vec2Utils.distanceSq(b, a);
- var offset = Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
- return mass * (distsq / 12 + offset.lengthSq());
- };
- Manager.areaForPoly = function areaForPoly(verts) {
- var area = 0;
- for(var i = 0; i < verts.length; i++) {
- area += Phaser.Vec2Utils.cross(verts[i], verts[(i + 1) % verts.length]);
- }
- return area / 2;
- };
- Manager.centroidForPoly = function centroidForPoly(verts) {
- var area = 0;
- var vsum = new Phaser.Vec2();
- for(var i = 0; i < verts.length; i++) {
- var v1 = verts[i];
- var v2 = verts[(i + 1) % verts.length];
- var cross = Phaser.Vec2Utils.cross(v1, v2);
- area += cross;
- // SO many vecs created here - unroll these bad boys
- vsum.add(Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(v1, v2), cross));
- }
- return Phaser.Vec2Utils.scale(vsum, 1 / (3 * area));
- };
- Manager.inertiaForPoly = function inertiaForPoly(mass, verts, offset) {
- var sum1 = 0;
- var sum2 = 0;
- for(var i = 0; i < verts.length; i++) {
- var v1 = Phaser.Vec2Utils.add(verts[i], offset);
- var v2 = Phaser.Vec2Utils.add(verts[(i + 1) % verts.length], offset);
- var a = Phaser.Vec2Utils.cross(v2, v1);
- var b = Phaser.Vec2Utils.dot(v1, v1) + Phaser.Vec2Utils.dot(v1, v2) + Phaser.Vec2Utils.dot(v2, v2);
- sum1 += a * b;
- sum2 += a;
- }
- return (mass * sum1) / (6 * sum2);
- };
- Manager.inertiaForBox = function inertiaForBox(mass, w, h) {
- return mass * (w * w + h * h) / 12;
- };
- Manager.createConvexHull = // Create the convex hull using the Gift wrapping algorithm (http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)
- function createConvexHull(points) {
- // Find the right most point on the hull
- var i0 = 0;
- var x0 = points[0].x;
- for(var i = 1; i < points.length; i++) {
- var x = points[i].x;
- if(x > x0 || (x == x0 && points[i].y < points[i0].y)) {
- i0 = i;
- x0 = x;
- }
- }
- var n = points.length;
- var hull = [];
- var m = 0;
- var ih = i0;
- while(1) {
- hull[m] = ih;
- var ie = 0;
- for(var j = 1; j < n; j++) {
- if(ie == ih) {
- ie = j;
- continue;
- }
- var r = Phaser.Vec2Utils.subtract(points[ie], points[hull[m]]);
- var v = Phaser.Vec2Utils.subtract(points[j], points[hull[m]]);
- var c = Phaser.Vec2Utils.cross(r, v);
- if(c < 0) {
- ie = j;
- }
- // Collinearity check
- if(c == 0 && v.lengthSq() > r.lengthSq()) {
- ie = j;
- }
- }
- m++;
- ih = ie;
- if(ie == i0) {
- break;
- }
- }
- // Copy vertices
- var newPoints = [];
- for(var i = 0; i < m; ++i) {
- newPoints.push(points[hull[i]]);
- }
- return newPoints;
- };
- return Manager;
- })();
- Advanced.Manager = Manager;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- /**
- * Phaser - 2D AABB
- *
- * A 2D AABB object
- */
- (function (Advanced) {
- var Bounds = (function () {
- /**
- * Creates a new 2D AABB object.
- * @class Bounds
- * @constructor
- * @return {Bounds} This object
- **/
- function Bounds(mins, maxs) {
- if (typeof mins === "undefined") { mins = null; }
- if (typeof maxs === "undefined") { maxs = null; }
- if(mins) {
- this.mins = Phaser.Vec2Utils.clone(mins);
- } else {
- this.mins = new Phaser.Vec2(999999, 999999);
- }
- if(maxs) {
- this.maxs = Phaser.Vec2Utils.clone(maxs);
- } else {
- this.maxs = new Phaser.Vec2(999999, 999999);
- }
- }
- Bounds.prototype.toString = function () {
- return [
- "mins:",
- this.mins.toString(),
- "maxs:",
- this.maxs.toString()
- ].join(" ");
- };
- Bounds.prototype.setTo = function (mins, maxs) {
- this.mins.setTo(mins.x, mins.y);
- this.maxs.setTo(maxs.x, maxs.y);
- };
- Bounds.prototype.copy = function (b) {
- this.mins.copyFrom(b.mins);
- this.maxs.copyFrom(b.maxs);
- return this;
- };
- Bounds.prototype.clear = function () {
- this.mins.setTo(999999, 999999);
- this.maxs.setTo(-999999, -999999);
- return this;
- };
- Object.defineProperty(Bounds.prototype, "x", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.mins.x);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Bounds.prototype, "y", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.mins.y);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Bounds.prototype, "width", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.maxs.x - this.mins.x);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Bounds.prototype, "height", {
- get: function () {
- return Phaser.Physics.Advanced.Manager.metersToPixels(this.maxs.y - this.mins.y);
- },
- enumerable: true,
- configurable: true
- });
- Bounds.prototype.isEmpty = function () {
- return (this.mins.x > this.maxs.x || this.mins.y > this.maxs.y);
- };
- Bounds.prototype.getPerimeter = /*
- public getCenter() {
- return vec2.scale(vec2.add(this.mins, this.maxs), 0.5);
- }
-
- public getExtent() {
- return vec2.scale(vec2.sub(this.maxs, this.mins), 0.5);
- }
- */
- function () {
- return (this.maxs.x - this.mins.x + this.maxs.y - this.mins.y) * 2;
- };
- Bounds.prototype.addPoint = function (p) {
- if(this.mins.x > p.x) {
- this.mins.x = p.x;
- }
- if(this.maxs.x < p.x) {
- this.maxs.x = p.x;
- }
- if(this.mins.y > p.y) {
- this.mins.y = p.y;
- }
- if(this.maxs.y < p.y) {
- this.maxs.y = p.y;
- }
- return this;
- };
- Bounds.prototype.addBounds = function (b) {
- if(this.mins.x > b.mins.x) {
- this.mins.x = b.mins.x;
- }
- if(this.maxs.x < b.maxs.x) {
- this.maxs.x = b.maxs.x;
- }
- if(this.mins.y > b.mins.y) {
- this.mins.y = b.mins.y;
- }
- if(this.maxs.y < b.maxs.y) {
- this.maxs.y = b.maxs.y;
- }
- return this;
- };
- Bounds.prototype.addBounds2 = function (mins, maxs) {
- if(this.mins.x > mins.x) {
- this.mins.x = mins.x;
- }
- if(this.maxs.x < maxs.x) {
- this.maxs.x = maxs.x;
- }
- if(this.mins.y > mins.y) {
- this.mins.y = mins.y;
- }
- if(this.maxs.y < maxs.y) {
- this.maxs.y = maxs.y;
- }
- return this;
- };
- Bounds.prototype.addExtents = function (center, extent_x, extent_y) {
- if(this.mins.x > center.x - extent_x) {
- this.mins.x = center.x - extent_x;
- }
- if(this.maxs.x < center.x + extent_x) {
- this.maxs.x = center.x + extent_x;
- }
- if(this.mins.y > center.y - extent_y) {
- this.mins.y = center.y - extent_y;
- }
- if(this.maxs.y < center.y + extent_y) {
- this.maxs.y = center.y + extent_y;
- }
- return this;
- };
- Bounds.prototype.expand = function (ax, ay) {
- this.mins.x -= ax;
- this.mins.y -= ay;
- this.maxs.x += ax;
- this.maxs.y += ay;
- return this;
- };
- Bounds.prototype.containPoint = function (p) {
- if(p.x < this.mins.x || p.x > this.maxs.x || p.y < this.mins.y || p.y > this.maxs.y) {
- return false;
- }
- return true;
- };
- Bounds.prototype.intersectsBounds = function (b) {
- if(this.mins.x > b.maxs.x || this.maxs.x < b.mins.x || this.mins.y > b.maxs.y || this.maxs.y < b.mins.y) {
- return false;
- }
- return true;
- };
- Bounds.expand = function expand(b, ax, ay) {
- var b = new Bounds(b.mins, b.maxs);
- b.expand(ax, ay);
- return b;
- };
- return Bounds;
- })();
- Advanced.Bounds = Bounds;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shape
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Shape = (function () {
- function Shape(type) {
- this.id = Phaser.Physics.Advanced.Manager.shapeCounter++;
- this.type = type;
- this.elasticity = 0.0;
- this.friction = 1.0;
- this.density = 1;
- this.bounds = new Advanced.Bounds();
- }
- Shape.prototype.findEdgeByPoint = // Over-ridden by ShapePoly
- function (p, minDist) {
- return -1;
- };
- return Shape;
- })();
- Advanced.Shape = Shape;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Contact
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Contact = (function () {
- function Contact(p, n, d, hash) {
- this.hash = hash;
- this.point = p;
- this.normal = n;
- this.depth = d;
- this.lambdaNormal = 0;
- this.lambdaTangential = 0;
- this.r1 = new Phaser.Vec2();
- this.r2 = new Phaser.Vec2();
- this.r1_local = new Phaser.Vec2();
- this.r2_local = new Phaser.Vec2();
- }
- return Contact;
- })();
- Advanced.Contact = Contact;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - ContactSolver
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- //-------------------------------------------------------------------------------------------------
- // Contact Constraint
- //
- // Non-penetration constraint:
- // C = dot(p2 - p1, n)
- // Cdot = dot(v2 - v1, n)
- // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
- //
- // impulse = JT * lambda = [ -n * lambda, -cross(r1, n) * lambda, n * lambda, cross(r1, n) * lambda ]
- //
- // Friction constraint:
- // C = dot(p2 - p1, t)
- // Cdot = dot(v2 - v1, t)
- // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
- //
- // impulse = JT * lambda = [ -t * lambda, -cross(r1, t) * lambda, t * lambda, cross(r1, t) * lambda ]
- //
- // NOTE: lambda is an impulse in constraint space.
- //-------------------------------------------------------------------------------------------------
- (function (Advanced) {
- var ContactSolver = (function () {
- function ContactSolver(shape1, shape2) {
- this.shape1 = shape1;
- this.shape2 = shape2;
- this.contacts = [];
- this.elasticity = 1;
- this.friction = 1;
- }
- ContactSolver.prototype.update = function (newContactArr) {
- for(var i = 0; i < newContactArr.length; i++) {
- var newContact = newContactArr[i];
- var k = -1;
- for(var j = 0; j < this.contacts.length; j++) {
- if(newContact.hash == this.contacts[j].hash) {
- k = j;
- break;
- }
- }
- if(k > -1) {
- newContact.lambdaNormal = this.contacts[k].lambdaNormal;
- newContact.lambdaTangential = this.contacts[k].lambdaTangential;
- }
- }
- this.contacts = newContactArr;
- };
- ContactSolver.prototype.initSolver = function (dt_inv) {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- var sum_m_inv = body1.massInverted + body2.massInverted;
- for(var i = 0; i < this.contacts.length; i++) {
- var con = this.contacts[i];
- //console.log('initSolver con');
- //console.log(con);
- // Transformed r1, r2
- Phaser.Vec2Utils.subtract(con.point, body1.position, con.r1);
- Phaser.Vec2Utils.subtract(con.point, body2.position, con.r2);
- //con.r1 = vec2.sub(con.point, body1.p);
- //con.r2 = vec2.sub(con.point, body2.p);
- // Local r1, r2
- Phaser.TransformUtils.unrotate(body1.transform, con.r1, con.r1_local);
- Phaser.TransformUtils.unrotate(body2.transform, con.r2, con.r2_local);
- //con.r1_local = body1.transform.unrotate(con.r1);
- //con.r2_local = body2.transform.unrotate(con.r2);
- var n = con.normal;
- var t = Phaser.Vec2Utils.perp(con.normal);
- // invEMn = J * invM * JT
- // J = [ -n, -cross(r1, n), n, cross(r2, n) ]
- var sn1 = Phaser.Vec2Utils.cross(con.r1, n);
- var sn2 = Phaser.Vec2Utils.cross(con.r2, n);
- var emn_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
- con.emn = emn_inv == 0 ? 0 : 1 / emn_inv;
- // invEMt = J * invM * JT
- // J = [ -t, -cross(r1, t), t, cross(r2, t) ]
- var st1 = Phaser.Vec2Utils.cross(con.r1, t);
- var st2 = Phaser.Vec2Utils.cross(con.r2, t);
- var emt_inv = sum_m_inv + body1.inertiaInverted * st1 * st1 + body2.inertiaInverted * st2 * st2;
- con.emt = emt_inv == 0 ? 0 : 1 / emt_inv;
- // Linear velocities at contact point
- // in 2D: cross(w, r) = perp(r) * w
- var v1 = new Phaser.Vec2();
- var v2 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(con.r1), body1.angularVelocity, v1);
- Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(con.r2), body2.angularVelocity, v2);
- //var v1 = vec2.mad(body1.v, vec2.perp(con.r1), body1.w);
- //var v2 = vec2.mad(body2.v, vec2.perp(con.r2), body2.w);
- // relative velocity at contact point
- var rv = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(v2, v1, rv);
- //var rv = vec2.sub(v2, v1);
- // bounce velocity dot n
- con.bounce = Phaser.Vec2Utils.dot(rv, con.normal) * this.elasticity;
- }
- };
- ContactSolver.prototype.warmStart = function () {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- for(var i = 0; i < this.contacts.length; i++) {
- var con = this.contacts[i];
- var n = con.normal;
- var lambda_n = con.lambdaNormal;
- var lambda_t = con.lambdaTangential;
- // Apply accumulated impulses
- //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
- //var impulse = new vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
- var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
- //console.log('phaser warmStart impulse ' + i + ' = ' + impulse.toString());
- body1.velocity.multiplyAddByScalar(impulse, -body1.massInverted);
- //body1.v.mad(impulse, -body1.m_inv);
- body1.angularVelocity -= Phaser.Vec2Utils.cross(con.r1, impulse) * body1.inertiaInverted;
- //body1.w -= vec2.cross(con.r1, impulse) * body1.i_inv;
- body2.velocity.multiplyAddByScalar(impulse, body2.massInverted);
- //body2.v.mad(impulse, body2.m_inv);
- body2.angularVelocity += Phaser.Vec2Utils.cross(con.r2, impulse) * body2.inertiaInverted;
- //body2.w += vec2.cross(con.r2, impulse) * body2.i_inv;
- }
- };
- ContactSolver.prototype.solveVelocityConstraints = function () {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- Advanced.Manager.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
- Advanced.Manager.write('Shape 1: ' + this.shape1.type + ' Shape 2: ' + this.shape2.type);
- var m1_inv = body1.massInverted;
- var i1_inv = body1.inertiaInverted;
- var m2_inv = body2.massInverted;
- var i2_inv = body2.inertiaInverted;
- Advanced.Manager.write('m1_inv: ' + m1_inv);
- Advanced.Manager.write('i1_inv: ' + i1_inv);
- Advanced.Manager.write('m2_inv: ' + m2_inv);
- Advanced.Manager.write('i2_inv: ' + i2_inv);
- for(var i = 0; i < this.contacts.length; i++) {
- Advanced.Manager.write('------------ solve con ' + i);
- var con = this.contacts[i];
- var n = con.normal;
- var t = Phaser.Vec2Utils.perp(n);
- var r1 = con.r1;
- var r2 = con.r2;
- // Linear velocities at contact point
- // in 2D: cross(w, r) = perp(r) * w
- var v1 = new Phaser.Vec2();
- var v2 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(r1), body1.angularVelocity, v1);
- //var v1 = vec2.mad(body1.v, vec2.perp(r1), body1.w);
- Advanced.Manager.write('v1 ' + v1.toString());
- Phaser.Vec2Utils.multiplyAdd(body2.velocity, Phaser.Vec2Utils.perp(r2), body2.angularVelocity, v2);
- //var v2 = vec2.mad(body2.v, vec2.perp(r2), body2.w);
- Advanced.Manager.write('v2 ' + v2.toString());
- // Relative velocity at contact point
- var rv = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(v2, v1, rv);
- //var rv = vec2.sub(v2, v1);
- Advanced.Manager.write('rv ' + rv.toString());
- // Compute normal constraint impulse + adding bounce as a velocity bias
- // lambda_n = -EMn * J * V
- var lambda_n = -con.emn * (Phaser.Vec2Utils.dot(n, rv) + con.bounce);
- Advanced.Manager.write('lambda_n: ' + lambda_n);
- // Accumulate and clamp
- var lambda_n_old = con.lambdaNormal;
- con.lambdaNormal = Math.max(lambda_n_old + lambda_n, 0);
- //con.lambdaNormal = this.clamp(lambda_n_old + lambda_n, 0);
- lambda_n = con.lambdaNormal - lambda_n_old;
- Advanced.Manager.write('lambda_n clamped: ' + lambda_n);
- // Compute frictional constraint impulse
- // lambda_t = -EMt * J * V
- var lambda_t = -con.emt * Phaser.Vec2Utils.dot(t, rv);
- // Max friction constraint impulse (Coulomb's Law)
- var lambda_t_max = con.lambdaNormal * this.friction;
- // Accumulate and clamp
- var lambda_t_old = con.lambdaTangential;
- con.lambdaTangential = this.clamp(lambda_t_old + lambda_t, -lambda_t_max, lambda_t_max);
- lambda_t = con.lambdaTangential - lambda_t_old;
- // Apply the final impulses
- //var impulse = vec2.rotate_vec(new vec2(lambda_n, lambda_t), n);
- var impulse = new Phaser.Vec2(lambda_n * n.x - lambda_t * n.y, lambda_t * n.x + lambda_n * n.y);
- Advanced.Manager.write('impulse: ' + impulse.toString());
- body1.velocity.multiplyAddByScalar(impulse, -m1_inv);
- //body1.v.mad(impulse, -m1_inv);
- body1.angularVelocity -= Phaser.Vec2Utils.cross(r1, impulse) * i1_inv;
- //body1.w -= vec2.cross(r1, impulse) * i1_inv;
- body2.velocity.multiplyAddByScalar(impulse, m2_inv);
- //body2.v.mad(impulse, m2_inv);
- body2.angularVelocity += Phaser.Vec2Utils.cross(r2, impulse) * i2_inv;
- //body2.w += vec2.cross(r2, impulse) * i2_inv;
- Advanced.Manager.write('body1: ' + body1.toString());
- Advanced.Manager.write('body2: ' + body2.toString());
- }
- };
- ContactSolver.prototype.solvePositionConstraints = function () {
- var body1 = this.shape1.body;
- var body2 = this.shape2.body;
- Advanced.Manager.write('solvePositionConstraints');
- var m1_inv = body1.massInverted;
- var i1_inv = body1.inertiaInverted;
- var m2_inv = body2.massInverted;
- var i2_inv = body2.inertiaInverted;
- var sum_m_inv = m1_inv + m2_inv;
- var max_penetration = 0;
- for(var i = 0; i < this.contacts.length; i++) {
- Advanced.Manager.write('------------- solvePositionConstraints ' + i);
- var con = this.contacts[i];
- var n = con.normal;
- var r1 = new Phaser.Vec2();
- var r2 = new Phaser.Vec2();
- // Transformed r1, r2
- Phaser.Vec2Utils.rotate(con.r1_local, body1.angle, r1);
- //var r1 = vec2.rotate(con.r1_local, body1.a);
- Phaser.Vec2Utils.rotate(con.r2_local, body2.angle, r2);
- //var r2 = vec2.rotate(con.r2_local, body2.a);
- Advanced.Manager.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
- Advanced.Manager.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
- Advanced.Manager.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
- Advanced.Manager.write('r2 rotated: r2.x = ' + r2.x + ' r2.y = ' + r2.y);
- // Contact points (corrected)
- var p1 = new Phaser.Vec2();
- var p2 = new Phaser.Vec2();
- Phaser.Vec2Utils.add(body1.position, r1, p1);
- //var p1 = vec2.add(body1.p, r1);
- Phaser.Vec2Utils.add(body2.position, r2, p2);
- //var p2 = vec2.add(body2.p, r2);
- Advanced.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
- Advanced.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
- // Corrected delta vector
- var dp = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(p2, p1, dp);
- //var dp = vec2.sub(p2, p1);
- // Position constraint
- var c = Phaser.Vec2Utils.dot(dp, n) + con.depth;
- var correction = this.clamp(Advanced.Manager.CONTACT_SOLVER_BAUMGARTE * (c + Advanced.Manager.CONTACT_SOLVER_COLLISION_SLOP), -Advanced.Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
- if(correction == 0) {
- continue;
- }
- // We don't need max_penetration less than or equal slop
- max_penetration = Math.max(max_penetration, -c);
- // Compute lambda for position constraint
- // Solve (J * invM * JT) * lambda = -C / dt
- var sn1 = Phaser.Vec2Utils.cross(r1, n);
- var sn2 = Phaser.Vec2Utils.cross(r2, n);
- var em_inv = sum_m_inv + body1.inertiaInverted * sn1 * sn1 + body2.inertiaInverted * sn2 * sn2;
- var lambda_dt = em_inv == 0 ? 0 : -correction / em_inv;
- // Apply correction impulses
- var impulse_dt = new Phaser.Vec2();
- Phaser.Vec2Utils.scale(n, lambda_dt, impulse_dt);
- //var impulse_dt = vec2.scale(n, lambda_dt);
- body1.position.multiplyAddByScalar(impulse_dt, -m1_inv);
- //body1.p.mad(impulse_dt, -m1_inv);
- body1.angle -= sn1 * lambda_dt * i1_inv;
- body2.position.multiplyAddByScalar(impulse_dt, m2_inv);
- //body2.p.mad(impulse_dt, m2_inv);
- body2.angle += sn2 * lambda_dt * i2_inv;
- Advanced.Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
- Advanced.Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
- }
- Advanced.Manager.write('max_penetration: ' + max_penetration);
- return max_penetration <= Advanced.Manager.CONTACT_SOLVER_COLLISION_SLOP * 3;
- };
- ContactSolver.prototype.clamp = function (v, min, max) {
- return v < min ? min : (v > max ? max : v);
- };
- return ContactSolver;
- })();
- Advanced.ContactSolver = ContactSolver;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shape - Circle
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Circle = (function (_super) {
- __extends(Circle, _super);
- function Circle(radius, x, y) {
- if (typeof x === "undefined") { x = 0; }
- if (typeof y === "undefined") { y = 0; }
- _super.call(this, Advanced.Manager.SHAPE_TYPE_CIRCLE);
- x = Advanced.Manager.pixelsToMeters(x);
- y = Advanced.Manager.pixelsToMeters(y);
- radius = Advanced.Manager.pixelsToMeters(radius);
- this.center = new Phaser.Vec2(x, y);
- this.radius = radius;
- this.tc = new Phaser.Vec2();
- this.finishVerts();
- }
- Circle.prototype.finishVerts = function () {
- this.radius = Math.abs(this.radius);
- };
- Circle.prototype.duplicate = function () {
- return new Circle(this.center.x, this.center.y, this.radius);
- };
- Circle.prototype.recenter = function (c) {
- this.center.subtract(c);
- };
- Circle.prototype.transform = function (xf) {
- Phaser.TransformUtils.transform(xf, this.center, this.center);
- //this.center = xf.transform(this.center);
- };
- Circle.prototype.untransform = function (xf) {
- Phaser.TransformUtils.untransform(xf, this.center, this.center);
- //this.center = xf.untransform(this.center);
- };
- Circle.prototype.area = function () {
- return Advanced.Manager.areaForCircle(this.radius, 0);
- };
- Circle.prototype.centroid = function () {
- return Phaser.Vec2Utils.clone(this.center);
- };
- Circle.prototype.inertia = function (mass) {
- return Advanced.Manager.inertiaForCircle(mass, this.center, this.radius, 0);
- };
- Circle.prototype.cacheData = function (xf) {
- Phaser.TransformUtils.transform(xf, this.center, this.tc);
- //this.tc = xf.transform(this.center);
- this.bounds.mins.setTo(this.tc.x - this.radius, this.tc.y - this.radius);
- this.bounds.maxs.setTo(this.tc.x + this.radius, this.tc.y + this.radius);
- };
- Circle.prototype.pointQuery = function (p) {
- //return vec2.distsq(this.tc, p) < (this.r * this.r);
- return Phaser.Vec2Utils.distanceSq(this.tc, p) < (this.radius * this.radius);
- };
- Circle.prototype.findVertexByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- if(Phaser.Vec2Utils.distanceSq(this.tc, p) < dsq) {
- return 0;
- }
- return -1;
- };
- Circle.prototype.distanceOnPlane = function (n, d) {
- Phaser.Vec2Utils.dot(n, this.tc) - this.radius - d;
- };
- return Circle;
- })(Phaser.Physics.Advanced.Shape);
- Shapes.Circle = Circle;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Plane
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Plane = (function () {
- function Plane(normal, d) {
- this.normal = normal;
- this.d = d;
- }
- return Plane;
- })();
- Advanced.Plane = Plane;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Convex Polygon
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Poly = (function (_super) {
- __extends(Poly, _super);
- // Verts is an optional array of objects, the objects must have public x and y properties which will be used
- // to seed this polygon (i.e. Vec2 objects, or just straight JS objects) and must wind COUNTER clockwise
- function Poly(verts) {
- _super.call(this, Advanced.Manager.SHAPE_TYPE_POLY);
- this.verts = [];
- this.planes = [];
- this.tverts = [];
- this.tplanes = [];
- if(verts) {
- for(var i = 0; i < verts.length; i++) {
- this.verts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
- this.tverts[i] = this.verts[i];
- //this.tverts[i] = new Phaser.Vec2(verts[i].x, verts[i].y);
- this.tplanes[i] = new Phaser.Physics.Advanced.Plane(new Phaser.Vec2(), 0);
- }
- }
- this.finishVerts();
- }
- Poly.prototype.finishVerts = function () {
- if(this.verts.length < 2) {
- this.convexity = false;
- this.planes = [];
- return;
- }
- this.convexity = true;
- this.tverts = [];
- this.tplanes = [];
- // Must be counter-clockwise verts
- for(var i = 0; i < this.verts.length; i++) {
- var a = this.verts[i];
- var b = this.verts[(i + 1) % this.verts.length];
- var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
- this.planes[i] = new Phaser.Physics.Advanced.Plane(n, Phaser.Vec2Utils.dot(n, a));
- this.tverts[i] = Phaser.Vec2Utils.clone(this.verts[i])// reference???
- ;
- //this.tverts[i] = this.verts[i]; // reference???
- this.tplanes[i] = new Phaser.Physics.Advanced.Plane(new Phaser.Vec2(), 0);
- }
- for(var i = 0; i < this.verts.length; i++) {
- //var b = this.verts[(i + 2) % this.verts.length];
- //var n = this.planes[i].normal;
- //var d = this.planes[i].d;
- if(Phaser.Vec2Utils.dot(this.planes[i].normal, this.verts[(i + 2) % this.verts.length]) - this.planes[i].d > 0) {
- this.convexity = false;
- }
- }
- };
- Poly.prototype.duplicate = function () {
- return new Phaser.Physics.Advanced.Shapes.Poly(this.verts);
- };
- Poly.prototype.recenter = function (c) {
- for(var i = 0; i < this.verts.length; i++) {
- this.verts[i].subtract(c);
- }
- };
- Poly.prototype.transform = function (xf) {
- for(var i = 0; i < this.verts.length; i++) {
- this.verts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
- //this.verts[i] = xf.transform(this.verts[i]);
- }
- };
- Poly.prototype.untransform = function (xf) {
- for(var i = 0; i < this.verts.length; i++) {
- this.verts[i] = Phaser.TransformUtils.untransform(xf, this.verts[i]);
- //this.verts[i] = xf.untransform(this.verts[i]);
- }
- };
- Poly.prototype.area = function () {
- return Advanced.Manager.areaForPoly(this.verts);
- };
- Poly.prototype.centroid = function () {
- return Advanced.Manager.centroidForPoly(this.verts);
- };
- Poly.prototype.inertia = function (mass) {
- return Advanced.Manager.inertiaForPoly(mass, this.verts, new Phaser.Vec2());
- };
- Poly.prototype.cacheData = function (xf) {
- this.bounds.clear();
- var numVerts = this.verts.length;
- Advanced.Manager.write('----------- Poly cacheData = ' + numVerts);
- if(numVerts == 0) {
- return;
- }
- for(var i = 0; i < numVerts; i++) {
- this.tverts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
- //this.tverts[i] = xf.transform(this.verts[i]);
- Advanced.Manager.write('tvert' + i + ' = ' + this.tverts[i].toString());
- }
- if(numVerts < 2) {
- this.bounds.addPoint(this.tverts[0]);
- return;
- }
- for(var i = 0; i < numVerts; i++) {
- var a = this.tverts[i];
- var b = this.tverts[(i + 1) % numVerts];
- var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
- Advanced.Manager.write('a = ' + a.toString());
- Advanced.Manager.write('b = ' + b.toString());
- Advanced.Manager.write('n = ' + n.toString());
- this.tplanes[i].normal = n;
- this.tplanes[i].d = Phaser.Vec2Utils.dot(n, a);
- Advanced.Manager.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
- Advanced.Manager.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
- this.bounds.addPoint(a);
- }
- };
- Poly.prototype.pointQuery = function (p) {
- if(!this.bounds.containPoint(p)) {
- return false;
- }
- return this.containPoint(p);
- };
- Poly.prototype.findVertexByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- for(var i = 0; i < this.tverts.length; i++) {
- if(Phaser.Vec2Utils.distanceSq(this.tverts[i], p) < dsq) {
- return i;
- }
- }
- return -1;
- };
- Poly.prototype.findEdgeByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- var numVerts = this.tverts.length;
- for(var i = 0; i < this.tverts.length; i++) {
- var v1 = this.tverts[i];
- var v2 = this.tverts[(i + 1) % numVerts];
- var n = this.tplanes[i].normal;
- var dtv1 = Phaser.Vec2Utils.cross(v1, n);
- var dtv2 = Phaser.Vec2Utils.cross(v2, n);
- var dt = Phaser.Vec2Utils.cross(p, n);
- if(dt > dtv1) {
- if(Phaser.Vec2Utils.distanceSq(v1, p) < dsq) {
- return i;
- }
- } else if(dt < dtv2) {
- if(Phaser.Vec2Utils.distanceSq(v2, p) < dsq) {
- return i;
- }
- } else {
- var dist = Phaser.Vec2Utils.dot(n, p) - Phaser.Vec2Utils.dot(n, v1);
- if(dist * dist < dsq) {
- return i;
- }
- }
- }
- return -1;
- };
- Poly.prototype.distanceOnPlane = function (n, d) {
- var min = 999999;
- for(var i = 0; i < this.verts.length; i++) {
- min = Math.min(min, Phaser.Vec2Utils.dot(n, this.tverts[i]));
- }
- return min - d;
- };
- Poly.prototype.containPoint = function (p) {
- for(var i = 0; i < this.verts.length; i++) {
- var plane = this.tplanes[i];
- if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
- return false;
- }
- }
- return true;
- };
- Poly.prototype.containPointPartial = function (p, n) {
- for(var i = 0; i < this.verts.length; i++) {
- var plane = this.tplanes[i];
- if(Phaser.Vec2Utils.dot(plane.normal, n) < 0.0001) {
- continue;
- }
- if(Phaser.Vec2Utils.dot(plane.normal, p) - plane.d > 0) {
- return false;
- }
- }
- return true;
- };
- return Poly;
- })(Phaser.Physics.Advanced.Shape);
- Shapes.Poly = Poly;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Segment
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Segment = (function (_super) {
- __extends(Segment, _super);
- function Segment(a, b, radius) {
- _super.call(this, Advanced.Manager.SHAPE_TYPE_SEGMENT);
- this.a = a.duplicate();
- this.b = b.duplicate();
- this.radius = radius;
- this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(b, a));
- this.normal.normalize();
- this.ta = new Phaser.Vec2();
- this.tb = new Phaser.Vec2();
- this.tn = new Phaser.Vec2();
- this.finishVerts();
- }
- Segment.prototype.finishVerts = function () {
- this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.b, this.a));
- this.normal.normalize();
- this.radius = Math.abs(this.radius);
- };
- Segment.prototype.duplicate = function () {
- return new Phaser.Physics.Advanced.Shapes.Segment(this.a, this.b, this.radius);
- };
- Segment.prototype.recenter = function (c) {
- this.a.subtract(c);
- this.b.subtract(c);
- };
- Segment.prototype.transform = function (xf) {
- Phaser.TransformUtils.transform(xf, this.a, this.a);
- Phaser.TransformUtils.transform(xf, this.b, this.b);
- //this.a = xf.transform(this.a);
- //this.b = xf.transform(this.b);
- };
- Segment.prototype.untransform = function (xf) {
- Phaser.TransformUtils.untransform(xf, this.a, this.a);
- Phaser.TransformUtils.untransform(xf, this.b, this.b);
- //this.a = xf.untransform(this.a);
- //this.b = xf.untransform(this.b);
- };
- Segment.prototype.area = function () {
- return Advanced.Manager.areaForSegment(this.a, this.b, this.radius);
- };
- Segment.prototype.centroid = function () {
- return Advanced.Manager.centroidForSegment(this.a, this.b);
- };
- Segment.prototype.inertia = function (mass) {
- return Advanced.Manager.inertiaForSegment(mass, this.a, this.b);
- };
- Segment.prototype.cacheData = function (xf) {
- Phaser.TransformUtils.transform(xf, this.a, this.ta);
- Phaser.TransformUtils.transform(xf, this.b, this.tb);
- //this.ta = xf.transform(this.a);
- //this.tb = xf.transform(this.b);
- this.tn = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.tb, this.ta)).normalize();
- var l;
- var r;
- var t;
- var b;
- if(this.ta.x < this.tb.x) {
- l = this.ta.x;
- r = this.tb.x;
- } else {
- l = this.tb.x;
- r = this.ta.x;
- }
- if(this.ta.y < this.tb.y) {
- b = this.ta.y;
- t = this.tb.y;
- } else {
- b = this.tb.y;
- t = this.ta.y;
- }
- this.bounds.mins.setTo(l - this.radius, b - this.radius);
- this.bounds.maxs.setTo(r + this.radius, t + this.radius);
- };
- Segment.prototype.pointQuery = function (p) {
- if(!this.bounds.containPoint(p)) {
- return false;
- }
- var dn = Phaser.Vec2Utils.dot(this.tn, p) - Phaser.Vec2Utils.dot(this.ta, this.tn);
- var dist = Math.abs(dn);
- if(dist > this.radius) {
- return false;
- }
- var dt = Phaser.Vec2Utils.cross(p, this.tn);
- var dta = Phaser.Vec2Utils.cross(this.ta, this.tn);
- var dtb = Phaser.Vec2Utils.cross(this.tb, this.tn);
- if(dt <= dta) {
- if(dt < dta - this.radius) {
- return false;
- }
- return Phaser.Vec2Utils.distanceSq(this.ta, p) < (this.radius * this.radius);
- } else if(dt > dtb) {
- if(dt > dtb + this.radius) {
- return false;
- }
- return Phaser.Vec2Utils.distanceSq(this.tb, p) < (this.radius * this.radius);
- }
- return true;
- };
- Segment.prototype.findVertexByPoint = function (p, minDist) {
- var dsq = minDist * minDist;
- if(Phaser.Vec2Utils.distanceSq(this.ta, p) < dsq) {
- return 0;
- }
- if(Phaser.Vec2Utils.distanceSq(this.tb, p) < dsq) {
- return 1;
- }
- return -1;
- };
- Segment.prototype.distanceOnPlane = function (n, d) {
- var a = Phaser.Vec2Utils.dot(n, this.ta) - this.radius;
- var b = Phaser.Vec2Utils.dot(n, this.tb) - this.radius;
- return Math.min(a, b) - d;
- };
- return Segment;
- })(Phaser.Physics.Advanced.Shape);
- Shapes.Segment = Segment;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Collision Handlers
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Collision = (function () {
- function Collision() {
- }
- Collision.prototype.collide = function (a, b, contacts) {
- // Circle (a is the circle)
- if(a.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- if(b.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- return this.circle2Circle(a, b, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- return this.circle2Segment(a, b, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- return this.circle2Poly(a, b, contacts);
- }
- }
- // Segment (a is the segment)
- if(a.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- if(b.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- return this.circle2Segment(b, a, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- return this.segment2Segment(a, b, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- return this.segment2Poly(a, b, contacts);
- }
- }
- // Poly (a is the poly)
- if(a.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- if(b.type == Advanced.Manager.SHAPE_TYPE_CIRCLE) {
- return this.circle2Poly(b, a, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_SEGMENT) {
- return this.segment2Poly(b, a, contacts);
- } else if(b.type == Advanced.Manager.SHAPE_TYPE_POLY) {
- return this.poly2Poly(a, b, contacts);
- }
- }
- };
- Collision.prototype._circle2Circle = function (c1, r1, c2, r2, contactArr) {
- var rmax = r1 + r2;
- var t = new Phaser.Vec2();
- //var t = vec2.sub(c2, c1);
- Phaser.Vec2Utils.subtract(c2, c1, t);
- var distsq = t.lengthSq();
- if(distsq > rmax * rmax) {
- return 0;
- }
- var dist = Math.sqrt(distsq);
- var p = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(c1, t, 0.5 + (r1 - r2) * 0.5 / dist, p);
- //var p = vec2.mad(c1, t, 0.5 + (r1 - r2) * 0.5 / dist);
- var n = new Phaser.Vec2();
- //var n = (dist != 0) ? vec2.scale(t, 1 / dist) : vec2.zero;
- if(dist != 0) {
- Phaser.Vec2Utils.scale(t, 1 / dist, n);
- }
- var d = dist - rmax;
- contactArr.push(new Advanced.Contact(p, n, d, 0));
- return 1;
- };
- Collision.prototype.circle2Circle = function (circ1, circ2, contactArr) {
- return this._circle2Circle(circ1.tc, circ1.radius, circ2.tc, circ2.radius, contactArr);
- };
- Collision.prototype.circle2Segment = function (circ, seg, contactArr) {
- var rsum = circ.radius + seg.radius;
- // Normal distance from segment
- var dn = Phaser.Vec2Utils.dot(circ.tc, seg.tn) - Phaser.Vec2Utils.dot(seg.ta, seg.tn);
- var dist = (dn < 0 ? dn * -1 : dn) - rsum;
- if(dist > 0) {
- return 0;
- }
- // Tangential distance along segment
- var dt = Phaser.Vec2Utils.cross(circ.tc, seg.tn);
- var dtMin = Phaser.Vec2Utils.cross(seg.ta, seg.tn);
- var dtMax = Phaser.Vec2Utils.cross(seg.tb, seg.tn);
- if(dt < dtMin) {
- if(dt < dtMin - rsum) {
- return 0;
- }
- return this._circle2Circle(circ.tc, circ.radius, seg.ta, seg.radius, contactArr);
- } else if(dt > dtMax) {
- if(dt > dtMax + rsum) {
- return 0;
- }
- return this._circle2Circle(circ.tc, circ.radius, seg.tb, seg.radius, contactArr);
- }
- var n = new Phaser.Vec2();
- if(dn > 0) {
- n.copyFrom(seg.tn);
- } else {
- Phaser.Vec2Utils.negative(seg.tn, n);
- }
- //var n = (dn > 0) ? seg.tn : vec2.neg(seg.tn);
- var c1 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + dist * 0.5), c1);
- var c2 = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(n, c2);
- contactArr.push(new Advanced.Contact(c1, c2, dist, 0));
- //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + dist * 0.5)), vec2.neg(n), dist, 0));
- return 1;
- };
- Collision.prototype.circle2Poly = function (circ, poly, contactArr) {
- var minDist = -999999;
- var minIdx = -1;
- for(var i = 0; i < poly.verts.length; i++) {
- var plane = poly.tplanes[i];
- var dist = Phaser.Vec2Utils.dot(circ.tc, plane.normal) - plane.d - circ.radius;
- if(dist > 0) {
- return 0;
- } else if(dist > minDist) {
- minDist = dist;
- minIdx = i;
- }
- }
- var n = poly.tplanes[minIdx].normal;
- var a = poly.tverts[minIdx];
- var b = poly.tverts[(minIdx + 1) % poly.verts.length];
- var dta = Phaser.Vec2Utils.cross(a, n);
- var dtb = Phaser.Vec2Utils.cross(b, n);
- var dt = Phaser.Vec2Utils.cross(circ.tc, n);
- if(dt > dta) {
- return this._circle2Circle(circ.tc, circ.radius, a, 0, contactArr);
- } else if(dt < dtb) {
- return this._circle2Circle(circ.tc, circ.radius, b, 0, contactArr);
- }
- var c1 = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(circ.tc, n, -(circ.radius + minDist * 0.5), c1);
- var c2 = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(n, c2);
- contactArr.push(new Advanced.Contact(c1, c2, minDist, 0));
- //contactArr.push(new Contact(vec2.mad(circ.tc, n, -(circ.r + minDist * 0.5)), vec2.neg(n), minDist, 0));
- return 1;
- };
- Collision.prototype.segmentPointDistanceSq = function (seg, p) {
- var w = new Phaser.Vec2();
- var d = new Phaser.Vec2();
- Phaser.Vec2Utils.subtract(p, seg.ta, w);
- Phaser.Vec2Utils.subtract(seg.tb, seg.ta, d);
- //var w = vec2.sub(p, seg.ta);
- //var d = vec2.sub(seg.tb, seg.ta);
- var proj = w.dot(d);
- if(proj <= 0) {
- return w.dot(w);
- }
- var vsq = d.dot(d);
- if(proj >= vsq) {
- return w.dot(w) - 2 * proj + vsq;
- }
- return w.dot(w) - proj * proj / vsq;
- };
- Collision.prototype.segment2Segment = // FIXME and optimise me lots!!!
- function (seg1, seg2, contactArr) {
- var d = [];
- d[0] = this.segmentPointDistanceSq(seg1, seg2.ta);
- d[1] = this.segmentPointDistanceSq(seg1, seg2.tb);
- d[2] = this.segmentPointDistanceSq(seg2, seg1.ta);
- d[3] = this.segmentPointDistanceSq(seg2, seg1.tb);
- var idx1 = d[0] < d[1] ? 0 : 1;
- var idx2 = d[2] < d[3] ? 2 : 3;
- var idxm = d[idx1] < d[idx2] ? idx1 : idx2;
- var s, t;
- var u = Phaser.Vec2Utils.subtract(seg1.tb, seg1.ta);
- var v = Phaser.Vec2Utils.subtract(seg2.tb, seg2.ta);
- switch(idxm) {
- case 0:
- s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.ta, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
- s = s < 0 ? 0 : (s > 1 ? 1 : s);
- t = 0;
- break;
- case 1:
- s = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg2.tb, seg1.ta), u) / Phaser.Vec2Utils.dot(u, u);
- s = s < 0 ? 0 : (s > 1 ? 1 : s);
- t = 1;
- break;
- case 2:
- s = 0;
- t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.ta, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
- t = t < 0 ? 0 : (t > 1 ? 1 : t);
- break;
- case 3:
- s = 1;
- t = Phaser.Vec2Utils.dot(Phaser.Vec2Utils.subtract(seg1.tb, seg2.ta), v) / Phaser.Vec2Utils.dot(v, v);
- t = t < 0 ? 0 : (t > 1 ? 1 : t);
- break;
- }
- var minp1 = Phaser.Vec2Utils.multiplyAdd(seg1.ta, u, s);
- var minp2 = Phaser.Vec2Utils.multiplyAdd(seg2.ta, v, t);
- return this._circle2Circle(minp1, seg1.radius, minp2, seg2.radius, contactArr);
- };
- Collision.prototype.findPointsBehindSeg = // Identify vertexes that have penetrated the segment.
- function (contactArr, seg, poly, dist, coef) {
- var dta = Phaser.Vec2Utils.cross(seg.tn, seg.ta);
- var dtb = Phaser.Vec2Utils.cross(seg.tn, seg.tb);
- var n = new Phaser.Vec2();
- Phaser.Vec2Utils.scale(seg.tn, coef, n);
- //var n = vec2.scale(seg.tn, coef);
- for(var i = 0; i < poly.verts.length; i++) {
- var v = poly.tverts[i];
- if(Phaser.Vec2Utils.dot(v, n) < Phaser.Vec2Utils.dot(seg.tn, seg.ta) * coef + seg.radius) {
- var dt = Phaser.Vec2Utils.cross(seg.tn, v);
- if(dta >= dt && dt >= dtb) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly.id << 16) | i));
- }
- }
- }
- };
- Collision.prototype.segment2Poly = function (seg, poly, contactArr) {
- var seg_td = Phaser.Vec2Utils.dot(seg.tn, seg.ta);
- var seg_d1 = poly.distanceOnPlane(seg.tn, seg_td) - seg.radius;
- if(seg_d1 > 0) {
- return 0;
- }
- var n = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(seg.tn, n);
- var seg_d2 = poly.distanceOnPlane(n, -seg_td) - seg.radius;
- //var seg_d2 = poly.distanceOnPlane(vec2.neg(seg.tn), -seg_td) - seg.r;
- if(seg_d2 > 0) {
- return 0;
- }
- var poly_d = -999999;
- var poly_i = -1;
- for(var i = 0; i < poly.verts.length; i++) {
- var plane = poly.tplanes[i];
- var dist = seg.distanceOnPlane(plane.normal, plane.d);
- if(dist > 0) {
- return 0;
- }
- if(dist > poly_d) {
- poly_d = dist;
- poly_i = i;
- }
- }
- var poly_n = new Phaser.Vec2();
- Phaser.Vec2Utils.negative(poly.tplanes[poly_i].normal, poly_n);
- //var poly_n = vec2.neg(poly.tplanes[poly_i].n);
- var va = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(seg.ta, poly_n, seg.radius, va);
- //var va = vec2.mad(seg.ta, poly_n, seg.r);
- var vb = new Phaser.Vec2();
- Phaser.Vec2Utils.multiplyAdd(seg.tb, poly_n, seg.radius, vb);
- //var vb = vec2.mad(seg.tb, poly_n, seg.r);
- if(poly.containPoint(va)) {
- contactArr.push(new Advanced.Contact(va, poly_n, poly_d, (seg.id << 16) | 0));
- }
- if(poly.containPoint(vb)) {
- contactArr.push(new Advanced.Contact(vb, poly_n, poly_d, (seg.id << 16) | 1));
- }
- // Floating point precision problems here.
- // This will have to do for now.
- poly_d -= 0.1;
- if(seg_d1 >= poly_d || seg_d2 >= poly_d) {
- if(seg_d1 > seg_d2) {
- this.findPointsBehindSeg(contactArr, seg, poly, seg_d1, 1);
- } else {
- this.findPointsBehindSeg(contactArr, seg, poly, seg_d2, -1);
- }
- }
- // If no other collision points are found, try colliding endpoints.
- if(contactArr.length == 0) {
- var poly_a = poly.tverts[poly_i];
- var poly_b = poly.tverts[(poly_i + 1) % poly.verts.length];
- if(this._circle2Circle(seg.ta, seg.radius, poly_a, 0, contactArr)) {
- return 1;
- }
- if(this._circle2Circle(seg.tb, seg.radius, poly_a, 0, contactArr)) {
- return 1;
- }
- if(this._circle2Circle(seg.ta, seg.radius, poly_b, 0, contactArr)) {
- return 1;
- }
- if(this._circle2Circle(seg.tb, seg.radius, poly_b, 0, contactArr)) {
- return 1;
- }
- }
- return contactArr.length;
- };
- Collision.prototype.findMSA = // Find the minimum separating axis for the given poly and plane list.
- function (poly, planes, num) {
- var min_dist = -999999;
- var min_index = -1;
- for(var i = 0; i < num; i++) {
- var dist = poly.distanceOnPlane(planes[i].normal, planes[i].d);
- if(dist > 0) {
- // no collision
- return {
- dist: 0,
- index: -1
- };
- } else if(dist > min_dist) {
- min_dist = dist;
- min_index = i;
- }
- }
- // new object - see what we can do here
- return {
- dist: min_dist,
- index: min_index
- };
- };
- Collision.prototype.findVertsFallback = function (contactArr, poly1, poly2, n, dist) {
- var num = 0;
- for(var i = 0; i < poly1.verts.length; i++) {
- var v = poly1.tverts[i];
- if(poly2.containPointPartial(v, n)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly1.id << 16) | i));
- num++;
- }
- }
- for(var i = 0; i < poly2.verts.length; i++) {
- var v = poly2.tverts[i];
- if(poly1.containPointPartial(v, n)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly2.id << 16) | i));
- num++;
- }
- }
- return num;
- };
- Collision.prototype.findVerts = // Find the overlapped vertices.
- function (contactArr, poly1, poly2, n, dist) {
- var num = 0;
- for(var i = 0; i < poly1.verts.length; i++) {
- var v = poly1.tverts[i];
- if(poly2.containPoint(v)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly1.id << 16) | i));
- num++;
- }
- }
- for(var i = 0; i < poly2.verts.length; i++) {
- var v = poly2.tverts[i];
- if(poly1.containPoint(v)) {
- contactArr.push(new Advanced.Contact(v, n, dist, (poly2.id << 16) | i));
- num++;
- }
- }
- return num > 0 ? num : this.findVertsFallback(contactArr, poly1, poly2, n, dist);
- };
- Collision.prototype.poly2Poly = function (poly1, poly2, contactArr) {
- var msa1 = this.findMSA(poly2, poly1.tplanes, poly1.verts.length);
- if(msa1.index == -1) {
- console.log('poly2poly 0', msa1);
- return 0;
- }
- var msa2 = this.findMSA(poly1, poly2.tplanes, poly2.verts.length);
- if(msa2.index == -1) {
- console.log('poly2poly 1', msa2);
- return 0;
- }
- // Penetration normal direction should be from poly1 to poly2
- if(msa1.dist > msa2.dist) {
- return this.findVerts(contactArr, poly1, poly2, poly1.tplanes[msa1.index].normal, msa1.dist);
- }
- return this.findVerts(contactArr, poly1, poly2, Phaser.Vec2Utils.negative(poly2.tplanes[msa2.index].normal), msa2.dist);
- };
- return Collision;
- })();
- Advanced.Collision = Collision;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Space
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Space = (function () {
- function Space() {
- this.stepCount = 0;
- this.bodies = [];
- this.bodyHash = {
- };
- this.joints = [];
- this.jointHash = {
- };
- this.numContacts = 0;
- this.contactSolvers = [];
- //this.postSolve(arb) { };
- this.gravity = new Phaser.Vec2(0, 10);
- this.damping = 0;
- this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE;
- this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE;
- }
- Space.TIME_TO_SLEEP = 0.5;
- Space.SLEEP_LINEAR_TOLERANCE = 0.5;
- Space.SLEEP_ANGULAR_TOLERANCE = 2 * Phaser.GameMath.DEG_TO_RAD;
- Space.prototype.clear = function () {
- Advanced.Manager.shapeCounter = 0;
- Advanced.Manager.bodyCounter = 0;
- Advanced.Manager.jointCounter = 0;
- for(var i = 0; i < this.bodies.length; i++) {
- if(this.bodies[i]) {
- this.removeBody(this.bodies[i]);
- }
- }
- this.bodies = [];
- this.bodyHash = {
- };
- this.joints = [];
- this.jointHash = {
- };
- this.contactSolvers = [];
- this.stepCount = 0;
- };
- Space.prototype.addBody = function (body) {
- if(this.bodyHash[body.id] != undefined) {
- return;
- }
- var index = this.bodies.push(body) - 1;
- this.bodyHash[body.id] = index;
- body.awake(true);
- body.space = this;
- body.cacheData('addBody');
- };
- Space.prototype.removeBody = function (body) {
- if(this.bodyHash[body.id] == undefined) {
- return;
- }
- // Remove linked joints
- for(var i = 0; i < body.joints.length; i++) {
- if(body.joints[i]) {
- this.removeJoint(body.joints[i]);
- }
- }
- body.space = null;
- var index = this.bodyHash[body.id];
- delete this.bodyHash[body.id];
- delete this.bodies[index];
- };
- Space.prototype.addJoint = function (joint) {
- if(this.jointHash[joint.id] != undefined) {
- return;
- }
- joint.body1.awake(true);
- joint.body2.awake(true);
- var index = this.joints.push(joint) - 1;
- this.jointHash[joint.id] = index;
- var index = joint.body1.joints.push(joint) - 1;
- joint.body1.jointHash[joint.id] = index;
- var index = joint.body2.joints.push(joint) - 1;
- joint.body2.jointHash[joint.id] = index;
- };
- Space.prototype.removeJoint = function (joint) {
- if(this.jointHash[joint.id] == undefined) {
- return;
- }
- joint.body1.awake(true);
- joint.body2.awake(true);
- var index = joint.body1.jointHash[joint.id];
- delete joint.body1.jointHash[joint.id];
- delete joint.body1.joints[index];
- var index = joint.body2.jointHash[joint.id];
- delete joint.body2.jointHash[joint.id];
- delete joint.body2.joints[index];
- var index = this.jointHash[joint.id];
- delete this.jointHash[joint.id];
- delete this.joints[index];
- };
- Space.prototype.findShapeByPoint = function (p, refShape) {
- var firstShape;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- if(shape.pointQuery(p)) {
- if(!refShape) {
- return shape;
- }
- if(!firstShape) {
- firstShape = shape;
- }
- if(shape == refShape) {
- refShape = null;
- }
- }
- }
- }
- return firstShape;
- };
- Space.prototype.findBodyByPoint = function (p, refBody) {
- var firstBody;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- if(shape.pointQuery(p)) {
- if(!refBody) {
- return shape.body;
- }
- if(!firstBody) {
- firstBody = shape.body;
- }
- if(shape.body == refBody) {
- refBody = null;
- }
- break;
- }
- }
- }
- return firstBody;
- };
- Space.prototype.shapeById = function (id) {
- var shape;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- if(body.shapes[j].id == id) {
- return body.shapes[j];
- }
- }
- }
- return null;
- };
- Space.prototype.jointById = function (id) {
- var index = this.jointHash[id];
- if(index != undefined) {
- return this.joints[index];
- }
- return null;
- };
- Space.prototype.findVertexByPoint = function (p, minDist, refVertexId) {
- var firstVertexId = -1;
- refVertexId = refVertexId || -1;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- var index = shape.findVertexByPoint(p, minDist);
- if(index != -1) {
- var vertex = (shape.id << 16) | index;
- if(refVertexId == -1) {
- return vertex;
- }
- if(firstVertexId == -1) {
- firstVertexId = vertex;
- }
- if(vertex == refVertexId) {
- refVertexId = -1;
- }
- }
- }
- }
- return firstVertexId;
- };
- Space.prototype.findEdgeByPoint = function (p, minDist, refEdgeId) {
- var firstEdgeId = -1;
- refEdgeId = refEdgeId || -1;
- for(var i = 0; i < this.bodies.length; i++) {
- var body = this.bodies[i];
- if(!body) {
- continue;
- }
- for(var j = 0; j < body.shapes.length; j++) {
- var shape = body.shapes[j];
- if(shape.type != Advanced.Manager.SHAPE_TYPE_POLY) {
- continue;
- }
- var index = shape.findEdgeByPoint(p, minDist);
- if(index != -1) {
- var edge = (shape.id << 16) | index;
- if(refEdgeId == -1) {
- return edge;
- }
- if(firstEdgeId == -1) {
- firstEdgeId = edge;
- }
- if(edge == refEdgeId) {
- refEdgeId = -1;
- }
- }
- }
- }
- return firstEdgeId;
- };
- Space.prototype.findJointByPoint = function (p, minDist, refJointId) {
- var firstJointId = -1;
- var dsq = minDist * minDist;
- refJointId = refJointId || -1;
- for(var i = 0; i < this.joints.length; i++) {
- var joint = this.joints[i];
- if(!joint) {
- continue;
- }
- var jointId = -1;
- if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor1()) < dsq) {
- jointId = (joint.id << 16 | 0);
- } else if(Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor2()) < dsq) {
- jointId = (joint.id << 16 | 1);
- }
- if(jointId != -1) {
- if(refJointId == -1) {
- return jointId;
- }
- if(firstJointId == -1) {
- firstJointId = jointId;
- }
- if(jointId == refJointId) {
- refJointId = -1;
- }
- }
- }
- return firstJointId;
- };
- Space.prototype.findContactSolver = function (shape1, shape2) {
- Advanced.Manager.write('findContactSolver. Length: ' + this._cl);
- for(var i = 0; i < this._cl; i++) {
- var contactSolver = this.contactSolvers[i];
- if(shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) {
- return contactSolver;
- }
- }
- return null;
- };
- Space.prototype.genTemporalContactSolvers = function () {
- Advanced.Manager.write('genTemporalContactSolvers');
- this._cl = 0;
- this.contactSolvers.length = 0;
- this.numContacts = 0;
- for(var body1Index = 0; body1Index < this._bl; body1Index++) {
- if(!this.bodies[body1Index]) {
- continue;
- }
- this.bodies[body1Index].stepCount = this.stepCount;
- for(var body2Index = 0; body2Index < this._bl; body2Index++) {
- if(this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) {
- continue;
- }
- Advanced.Manager.write('body1 and body2 intersect');
- for(var i = 0; i < this.bodies[body1Index].shapesLength; i++) {
- for(var j = 0; j < this.bodies[body2Index].shapesLength; j++) {
- this._shape1 = this.bodies[body1Index].shapes[i];
- this._shape2 = this.bodies[body2Index].shapes[j];
- var contactArr = [];
- if(!Advanced.Manager.collision.collide(this._shape1, this._shape2, contactArr)) {
- continue;
- }
- if(this._shape1.type > this._shape2.type) {
- var temp = this._shape1;
- this._shape1 = this._shape2;
- this._shape2 = temp;
- }
- this.numContacts += contactArr.length;
- // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers)
- var contactSolver = this.findContactSolver(this._shape1, this._shape2);
- Advanced.Manager.write('findContactSolver result: ' + contactSolver);
- if(contactSolver) {
- contactSolver.update(contactArr);
- this.contactSolvers.push(contactSolver);
- } else {
- Advanced.Manager.write('awake both bodies');
- this.bodies[body1Index].awake(true);
- this.bodies[body2Index].awake(true);
- var newContactSolver = new Advanced.ContactSolver(this._shape1, this._shape2);
- newContactSolver.contacts = contactArr;
- newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity);
- newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction);
- this.contactSolvers.push(newContactSolver);
- Advanced.Manager.write('new contact solver');
- }
- }
- }
- }
- }
- this._cl = this.contactSolvers.length;
- };
- Space.prototype.initSolver = function (warmStarting) {
- Advanced.Manager.write('initSolver');
- Advanced.Manager.write('contactSolvers.length: ' + this._cl);
- // Initialize contact solvers
- for(var c = 0; c < this._cl; c++) {
- this.contactSolvers[c].initSolver(this._deltaInv);
- // Warm starting (apply cached impulse)
- if(warmStarting) {
- this.contactSolvers[c].warmStart();
- }
- }
- // Initialize joint solver
- for(var j = 0; j < this.joints.length; j++) {
- if(this.joints[j]) {
- this.joints[j].initSolver(this._delta, warmStarting);
- }
- }
- // Warm starting (apply cached impulse)
- /*
- if (warmStarting)
- {
- for (var c = 0; c < this._cl; c++)
- {
- this.contactSolvers[c].warmStart();
- }
- }
- */
- };
- Space.prototype.velocitySolver = function (iterations) {
- Advanced.Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl);
- for(var i = 0; i < iterations; i++) {
- for(var j = 0; j < this._jl; j++) {
- if(this.joints[j]) {
- this.joints[j].solveVelocityConstraints();
- }
- }
- for(var c = 0; c < this._cl; c++) {
- this.contactSolvers[c].solveVelocityConstraints();
- }
- }
- };
- Space.prototype.positionSolver = function (iterations) {
- this._positionSolved = false;
- for(var i = 0; i < iterations; i++) {
- this._contactsOk = true;
- this._jointsOk = true;
- for(var c = 0; c < this._cl; c++) {
- this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk;
- }
- for(var j = 0; j < this._jl; j++) {
- if(this.joints[j]) {
- this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk;
- }
- }
- if(this._contactsOk && this._jointsOk) {
- // exit early if the position errors are small
- this._positionSolved = true;
- break;
- }
- }
- return this._positionSolved;
- };
- Space.prototype.step = // Step through the physics simulation
- function (dt, velocityIterations, positionIterations, warmStarting, allowSleep) {
- Advanced.Manager.clear();
- Advanced.Manager.write('Space step ' + this.stepCount);
- this._delta = dt;
- this._deltaInv = 1 / dt;
- this._bl = this.bodies.length;
- this._jl = this.joints.length;
- this.stepCount++;
- // 1) Generate Contact Solvers (into the this.contactSolvers array)
- this.genTemporalContactSolvers();
- Advanced.Manager.dump("Contact Solvers", this.bodies[1]);
- // 2) Initialize the Contact Solvers
- this.initSolver(warmStarting);
- Advanced.Manager.dump("Init Solver", this.bodies[1]);
- // 3) Intergrate velocity
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
- this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping);
- }
- }
- Advanced.Manager.dump("Update Velocity", this.bodies[1]);
- // 4) Awaken bodies via joints
- for(var j = 0; i < this._jl; j++) {
- if(!this.joints[j]) {
- continue;
- }
- // combine
- var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic;
- var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic;
- if(awake1 ^ awake2) {
- if(!awake1) {
- this.joints[j].body1.awake(true);
- }
- if(!awake2) {
- this.joints[j].body2.awake(true);
- }
- }
- }
- // 5) Iterative velocity constraints solver
- this.velocitySolver(velocityIterations);
- Advanced.Manager.dump("Velocity Solvers", this.bodies[1]);
- // 6) Intergrate position
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
- this.bodies[i].updatePosition(this._delta);
- }
- }
- Advanced.Manager.dump("Update Position", this.bodies[1]);
- // 7) Process breakable joint
- for(var i = 0; i < this._jl; i++) {
- if(this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) {
- this.removeJoint(this.joints[i]);
- }
- }
- // 8) Iterative position constraints solver (result stored in this._positionSolved)
- this.positionSolver(positionIterations);
- Advanced.Manager.dump("Position Solver", this.bodies[1]);
- // 9) Sync the Transforms
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i]) {
- this.bodies[i].syncTransform();
- }
- }
- Advanced.Manager.dump("Sync Transform", this.bodies[1]);
- // 10) Post solve collision callback
- if(this.postSolve) {
- for(var i = 0; i < this._cl; i++) {
- this.postSolve(this.contactSolvers[i]);
- }
- }
- // 11) Cache Body Data
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) {
- this.bodies[i].cacheData('post solve collision callback');
- }
- }
- Advanced.Manager.dump("Cache Data", this.bodies[1]);
- Advanced.Manager.writeAll();
- // 12) Process sleeping
- if(allowSleep) {
- this._minSleepTime = 999999;
- for(var i = 0; i < this._bl; i++) {
- if(!this.bodies[i] || this.bodies[i].isDynamic == false) {
- continue;
- }
- if(this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) {
- this.bodies[i].sleepTime = 0;
- this._minSleepTime = 0;
- } else {
- this.bodies[i].sleepTime += this._delta;
- this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime);
- }
- }
- if(this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) {
- for(var i = 0; i < this._bl; i++) {
- if(this.bodies[i]) {
- this.bodies[i].awake(false);
- }
- }
- }
- }
- };
- return Space;
- })();
- Advanced.Space = Space;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Triangle
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Triangle = (function (_super) {
- __extends(Triangle, _super);
- function Triangle(x1, y1, x2, y2, x3, y3) {
- x1 = Advanced.Manager.pixelsToMeters(x1);
- y1 = Advanced.Manager.pixelsToMeters(y1);
- x2 = Advanced.Manager.pixelsToMeters(x2);
- y2 = Advanced.Manager.pixelsToMeters(y2);
- x3 = Advanced.Manager.pixelsToMeters(x3);
- y3 = Advanced.Manager.pixelsToMeters(y3);
- _super.call(this, [
- {
- x: x1,
- y: y1
- },
- {
- x: x2,
- y: y2
- },
- {
- x: x3,
- y: y3
- }
- ]);
- }
- return Triangle;
- })(Phaser.Physics.Advanced.Shapes.Poly);
- Shapes.Triangle = Triangle;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- (function (Advanced) {
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Shapes - Box
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Shapes) {
- var Box = (function (_super) {
- __extends(Box, _super);
- // Give in pixels
- function Box(x, y, width, height) {
- //x = Manager.pixelsToMeters(x);
- //y = Manager.pixelsToMeters(y);
- //width = Manager.pixelsToMeters(width);
- //height = Manager.pixelsToMeters(height);
- var hw = width * 0.5;
- var hh = height * 0.5;
- _super.call(this, [
- {
- x: -hw + x,
- y: +hh + y
- },
- {
- x: -hw + x,
- y: -hh + y
- },
- {
- x: +hw + x,
- y: -hh + y
- },
- {
- x: +hw + x,
- y: +hh + y
- }
- ]);
- }
- return Box;
- })(Phaser.Physics.Advanced.Shapes.Poly);
- Shapes.Box = Box;
- })(Advanced.Shapes || (Advanced.Shapes = {}));
- var Shapes = Advanced.Shapes;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-var Phaser;
-(function (Phaser) {
- (function (Physics) {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /**
- * Phaser - Advanced Physics - Body
- *
- * Based on the work Ju Hyung Lee started in JS PhyRus.
- */
- (function (Advanced) {
- var Body = (function () {
- function Body(sprite, type, x, y) {
- if (typeof x === "undefined") { x = 0; }
- if (typeof y === "undefined") { y = 0; }
- this._tempVec2 = new Phaser.Vec2();
- // Shapes
- this.shapes = [];
- // Joints
- this.joints = [];
- this.jointHash = {
- };
- this.fixedRotation = false;
- this.categoryBits = 0x0001;
- this.maskBits = 0xFFFF;
- this.stepCount = 0;
- this.id = Phaser.Physics.Advanced.Manager.bodyCounter++;
- this.name = 'body' + this.id;
- this.type = type;
- if(sprite) {
- this.sprite = sprite;
- this.game = sprite.game;
- this.position = new Phaser.Vec2(Phaser.Physics.Advanced.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Advanced.Manager.pixelsToMeters(sprite.y));
- this.angle = sprite.rotation;
- } else {
- this.position = new Phaser.Vec2(Phaser.Physics.Advanced.Manager.pixelsToMeters(x), Phaser.Physics.Advanced.Manager.pixelsToMeters(y));
- this.angle = 0;
- }
- this.transform = new Phaser.Transform(this.position, this.angle);
- this.centroid = new Phaser.Vec2();
- this.velocity = new Phaser.Vec2();
- this.force = new Phaser.Vec2();
- this.angularVelocity = 0;
- this.torque = 0;
- this.linearDamping = 0;
- this.angularDamping = 0;
- this.sleepTime = 0;
- this.awaked = false;
- this.shapes = [];
- this.joints = [];
- this.jointHash = {
- };
- this.bounds = new Advanced.Bounds();
- this.fixedRotation = false;
- this.categoryBits = 0x0001;
- this.maskBits = 0xFFFF;
- this.stepCount = 0;
- }
- Body.prototype.toString = function () {
- return "[{Body (name=" + this.name + " velocity=" + this.velocity.toString() + " angularVelocity: " + this.angularVelocity + ")}]";
- };
- Body.prototype.duplicate = function () {
- //console.log('body duplicate called');
- //var body = new Body(this.type, this.transform.t, this.angle);
- //for (var i = 0; i < this.shapes.length; i++)
- //{
- // body.addShape(this.shapes[i].duplicate());
- //}
- //body.resetMassData();
- //return body;
- };
- Object.defineProperty(Body.prototype, "isDisabled", {
- get: function () {
- return this.type == Phaser.Types.BODY_DISABLED ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "isStatic", {
- get: function () {
- return this.type == Phaser.Types.BODY_STATIC ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "isKinetic", {
- get: function () {
- return this.type == Phaser.Types.BODY_KINETIC ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(Body.prototype, "isDynamic", {
- get: function () {
- return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
- },
- enumerable: true,
- configurable: true
- });
- Body.prototype.setType = function (type) {
- if(type == this.type) {
- return;
- }
- this.force.setTo(0, 0);
- this.velocity.setTo(0, 0);
- this.torque = 0;
- this.angularVelocity = 0;
- this.type = type;
- this.awake(true);
- };
- Body.prototype.addPoly = function (verts, elasticity, friction, density) {
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var poly = new Phaser.Physics.Advanced.Shapes.Poly(verts);
- poly.elasticity = elasticity;
- poly.friction = friction;
- poly.density = density;
- this.addShape(poly);
- this.resetMassData();
- return poly;
- };
- Body.prototype.addTriangle = function (x1, y1, x2, y2, x3, y3, elasticity, friction, density) {
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var tri = new Phaser.Physics.Advanced.Shapes.Triangle(x1, y1, x2, y2, x3, y3);
- tri.elasticity = elasticity;
- tri.friction = friction;
- tri.density = density;
- this.addShape(tri);
- this.resetMassData();
- return tri;
- };
- Body.prototype.addBox = function (x, y, width, height, elasticity, friction, density) {
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var box = new Phaser.Physics.Advanced.Shapes.Box(x, y, width, height);
- box.elasticity = elasticity;
- box.friction = friction;
- box.density = density;
- this.addShape(box);
- this.resetMassData();
- return box;
- };
- Body.prototype.addCircle = function (radius, x, y, elasticity, friction, density) {
- if (typeof x === "undefined") { x = 0; }
- if (typeof y === "undefined") { y = 0; }
- if (typeof elasticity === "undefined") { elasticity = 1; }
- if (typeof friction === "undefined") { friction = 1; }
- if (typeof density === "undefined") { density = 1; }
- var circle = new Phaser.Physics.Advanced.Shapes.Circle(radius, x, y);
- circle.elasticity = elasticity;
- circle.friction = friction;
- circle.density = density;
- this.addShape(circle);
- this.resetMassData();
- return circle;
- };
- Body.prototype.addShape = function (shape) {
- // Check not already part of this body
- shape.body = this;
- this.shapes.push(shape);
- this.shapesLength = this.shapes.length;
- return shape;
- };
- Body.prototype.removeShape = function (shape) {
- var index = this.shapes.indexOf(shape);
- if(index != -1) {
- this.shapes.splice(index, 1);
- shape.body = undefined;
- }
- this.shapesLength = this.shapes.length;
- };
- Body.prototype.setMass = function (mass) {
- this.mass = mass;
- this.massInverted = mass > 0 ? 1 / mass : 0;
- };
- Body.prototype.setInertia = function (inertia) {
- this.inertia = inertia;
- this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
- };
- Body.prototype.setTransform = function (pos, angle) {
- this.transform.setTo(pos, angle);
- // inject the transform into this.position
- Advanced.Manager.write('setTransform: ' + this.position.toString());
- Advanced.Manager.write('centroid: ' + this.centroid.toString());
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- Advanced.Manager.write('post setTransform: ' + this.position.toString());
- //this.position.copyFrom(this.transform.transform(this.centroid));
- this.angle = angle;
- };
- Body.prototype.syncTransform = function () {
- Advanced.Manager.write('syncTransform:');
- Advanced.Manager.write('p: ' + this.position.toString());
- Advanced.Manager.write('centroid: ' + this.centroid.toString());
- Advanced.Manager.write('xf: ' + this.transform.toString());
- Advanced.Manager.write('a: ' + this.angle);
- this.transform.setRotation(this.angle);
- // OPTIMISE: Creating new vector
- Phaser.Vec2Utils.subtract(this.position, Phaser.TransformUtils.rotate(this.transform, this.centroid), this.transform.t);
- Advanced.Manager.write('--------------------');
- Advanced.Manager.write('xf: ' + this.transform.toString());
- Advanced.Manager.write('--------------------');
- };
- Body.prototype.getWorldPoint = function (p) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.transform(this.transform, p);
- };
- Body.prototype.getWorldVector = function (v) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.rotate(this.transform, v);
- };
- Body.prototype.getLocalPoint = function (p) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.untransform(this.transform, p);
- };
- Body.prototype.getLocalVector = function (v) {
- // OPTIMISE: Creating new vector
- return Phaser.TransformUtils.unrotate(this.transform, v);
- };
- Body.prototype.setFixedRotation = function (flag) {
- this.fixedRotation = flag;
- this.resetMassData();
- };
- Body.prototype.resetMassData = function () {
- this.centroid.setTo(0, 0);
- this.mass = 0;
- this.massInverted = 0;
- this.inertia = 0;
- this.inertiaInverted = 0;
- if(this.isDynamic == false) {
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- //this.position.copyFrom(this.transform.transform(this.centroid));
- return;
- }
- var totalMassCentroid = new Phaser.Vec2(0, 0);
- var totalMass = 0;
- var totalInertia = 0;
- for(var i = 0; i < this.shapes.length; i++) {
- var shape = this.shapes[i];
- var centroid = shape.centroid();
- var mass = shape.area() * shape.density;
- var inertia = shape.inertia(mass);
- //console.log('rmd', centroid, shape);
- totalMassCentroid.multiplyAddByScalar(centroid, mass);
- totalMass += mass;
- totalInertia += inertia;
- }
- //this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
- Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
- this.setMass(totalMass);
- if(!this.fixedRotation) {
- //this.setInertia(totalInertia - totalMass * vec2.dot(this.centroid, this.centroid));
- this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
- }
- //console.log("mass = " + this.m + " inertia = " + this.i);
- // Move center of mass
- var oldPosition = Phaser.Vec2Utils.clone(this.position);
- //this.position.copyFrom(this.transform.transform(this.centroid));
- Phaser.TransformUtils.transform(this.transform, this.centroid, this.position);
- // Update center of mass velocity
- //this.velocity.mad(vec2.perp(vec2.sub(this.position, old_p)), this.angularVelocity);
- oldPosition.subtract(this.position);
- this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
- };
- Body.prototype.resetJointAnchors = function () {
- for(var i = 0; i < this.joints.length; i++) {
- var joint = this.joints[i];
- if(!joint) {
- continue;
- }
- var anchor1 = joint.getWorldAnchor1();
- var anchor2 = joint.getWorldAnchor2();
- joint.setWorldAnchor1(anchor1);
- joint.setWorldAnchor2(anchor2);
- }
- };
- Body.prototype.cacheData = function (source) {
- if (typeof source === "undefined") { source = ''; }
- Advanced.Manager.write('cacheData -- start');
- Advanced.Manager.write('p: ' + this.position.toString());
- Advanced.Manager.write('xf: ' + this.transform.toString());
- this.bounds.clear();
- for(var i = 0; i < this.shapes.length; i++) {
- var shape = this.shapes[i];
- shape.cacheData(this.transform);
- this.bounds.addBounds(shape.bounds);
- }
- Advanced.Manager.write('bounds: ' + this.bounds.toString());
- Advanced.Manager.write('p: ' + this.position.toString());
- Advanced.Manager.write('xf: ' + this.transform.toString());
- Advanced.Manager.write('cacheData -- stop');
- };
- Body.prototype.updateVelocity = function (gravity, dt, damping) {
- // this.velocity = vec2.mad(this.velocity, vec2.mad(gravity, this.force, this.massInverted), dt);
- Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
- Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
- this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
- // Apply damping.
- // ODE: dv/dt + c * v = 0
- // Solution: v(t) = v0 * exp(-c * t)
- // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
- // v2 = exp(-c * dt) * v1
- // Taylor expansion:
- // v2 = (1.0f - c * dt) * v1
- this.velocity.scale(this.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
- this.angularVelocity *= this.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
- this.force.setTo(0, 0);
- this.torque = 0;
- };
- Body.prototype.inContact = function (body2) {
- if(!body2 || this.stepCount == body2.stepCount) {
- return false;
- }
- if(!(this.isAwake && this.isStatic == false) && !(body2.isAwake && body2.isStatic == false)) {
- return false;
- }
- if(this.isCollidable(body2) == false) {
- return false;
- }
- if(!this.bounds.intersectsBounds(body2.bounds)) {
- return false;
- }
- return true;
- };
- Body.prototype.clamp = function (v, min, max) {
- return v < min ? min : (v > max ? max : v);
- };
- Body.prototype.updatePosition = function (dt) {
- //console.log('body update pos', this.position.y);
- //console.log('pre add temp', this._tempVec2.y);
- //this.position.addself(vec2.scale(this.velocity, dt));
- this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
- //console.log('post add temp', this._tempVec2.y);
- //console.log('post add', this.position.y);
- this.angle += this.angularVelocity * dt;
- };
- Body.prototype.resetForce = function () {
- this.force.setTo(0, 0);
- this.torque = 0;
- };
- Body.prototype.applyForce = function (force, p) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.force.add(force);
- // this.f.addself(force);
- // this.torque += vec2.cross(vec2.sub(p, this.p), force);
- Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
- this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
- };
- Body.prototype.applyForceToCenter = function (force) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.force.add(force);
- };
- Body.prototype.applyTorque = function (torque) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.torque += torque;
- };
- Body.prototype.applyLinearImpulse = function (impulse, p) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.velocity.multiplyAddByScalar(impulse, this.massInverted);
- // this.angularVelocity += vec2.cross(vec2.sub(p, this.position), impulse) * this.inertiaInverted;
- Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
- this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
- };
- Body.prototype.applyAngularImpulse = function (impulse) {
- if(this.isDynamic == false) {
- return;
- }
- if(this.isAwake == false) {
- this.awake(true);
- }
- this.angularVelocity += impulse * this.inertiaInverted;
- };
- Body.prototype.kineticEnergy = function () {
- var vsq = this.velocity.dot(this.velocity);
- var wsq = this.angularVelocity * this.angularVelocity;
- return 0.5 * (this.mass * vsq + this.inertia * wsq);
- };
- Object.defineProperty(Body.prototype, "isAwake", {
- get: function () {
- return this.awaked;
- },
- enumerable: true,
- configurable: true
- });
- Body.prototype.awake = function (flag) {
- this.awaked = flag;
- if(flag) {
- this.sleepTime = 0;
- } else {
- this.velocity.setTo(0, 0);
- this.angularVelocity = 0;
- this.force.setTo(0, 0);
- this.torque = 0;
- }
- };
- Body.prototype.isCollidable = function (other) {
- if(this == other) {
- return false;
- }
- if(this.isDynamic == false && other.isDynamic == false) {
- return false;
- }
- if(!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits)) {
- return false;
- }
- for(var i = 0; i < this.joints.length; i++) {
- var joint = this.joints[i];
- if(!this.joints[i] || (!this.joints[i].collideConnected && other.jointHash[this.joints[i].id] != undefined)) {
- return false;
- }
- }
- return true;
- };
- return Body;
- })();
- Advanced.Body = Body;
- })(Physics.Advanced || (Physics.Advanced = {}));
- var Advanced = Physics.Advanced;
- })(Phaser.Physics || (Phaser.Physics = {}));
- var Physics = Phaser.Physics;
-})(Phaser || (Phaser = {}));
-///
///
///
///