diff --git a/Docs/Physics Comparison.xlsx b/Docs/Physics Comparison.xlsx
new file mode 100644
index 00000000..77032e13
Binary files /dev/null and b/Docs/Physics Comparison.xlsx differ
diff --git a/Phaser/Phaser.csproj b/Phaser/Phaser.csproj
index d3187e44..28a242aa 100644
--- a/Phaser/Phaser.csproj
+++ b/Phaser/Phaser.csproj
@@ -186,6 +186,14 @@
Net.ts
+
+
+
+ AdvancedPhysics.ts
+
+
+ ArcadePhysics.ts
+
Body.ts
@@ -270,6 +278,10 @@
OrientationScreen.ts
+
+
+ BodyUtils.ts
+
CircleUtils.ts
diff --git a/Phaser/Stage.ts b/Phaser/Stage.ts
index 1d925d4f..38f40717 100644
--- a/Phaser/Stage.ts
+++ b/Phaser/Stage.ts
@@ -169,6 +169,12 @@ module Phaser {
*/
public scaleMode: number;
+ /**
+ * If set to true the game will never pause when the browser or browser tab loses focuses
+ * @type {boolean}
+ */
+ public disableVisibilityChange: bool = false;
+
/**
* Stage boot
*/
@@ -230,6 +236,11 @@ module Phaser {
*/
private visibilityChange(event) {
+ if (this.disableVisibilityChange)
+ {
+ return;
+ }
+
if (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] == true || document['webkitHidden'] == true)
{
if (this._game.paused == false)
diff --git a/Phaser/components/Texture.ts b/Phaser/components/Texture.ts
index 593aef86..661f9a21 100644
--- a/Phaser/components/Texture.ts
+++ b/Phaser/components/Texture.ts
@@ -160,6 +160,13 @@ module Phaser.Components {
*/
public isDynamic: bool = false;
+ /**
+ * The crop rectangle allows you to control which part of the sprite texture is rendered without distorting it.
+ * Set to null to disable, set to a Phaser.Rectangle object to control the region that will be rendered, anything outside the rectangle is ignored.
+ * @type {Phaser.Rectangle}
+ */
+ public crop: Phaser.Rectangle;
+
/**
* Updates the texture being used to render the Sprite.
* Called automatically by SpriteUtils.loadTexture and SpriteUtils.loadDynamicTexture.
diff --git a/Phaser/components/sprite/Input.ts b/Phaser/components/sprite/Input.ts
index fb413d05..80ad9119 100644
--- a/Phaser/components/sprite/Input.ts
+++ b/Phaser/components/sprite/Input.ts
@@ -393,6 +393,7 @@ module Phaser.Components.Sprite {
if (this.bringToTop)
{
this._parent.bringToTop();
+ //this._parent.game.world.group.bringToTop(this._parent);
}
}
diff --git a/Phaser/core/Group.ts b/Phaser/core/Group.ts
index 65a87030..414ea363 100644
--- a/Phaser/core/Group.ts
+++ b/Phaser/core/Group.ts
@@ -151,7 +151,7 @@ module Phaser {
/**
* Override this function to handle any deleting or "shutdown" type operations you might need,
- * such as removing traditional Flash children like Basic objects.
+ * such as removing traditional children like Basic objects.
*/
public destroy() {
@@ -417,10 +417,10 @@ module Phaser {
* @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 [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)
* @returns {Sprite} The newly created sprite object.
*/
- public addNewSprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DYNAMIC): Sprite {
+ public addNewSprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DISABLED): Sprite {
return this.add(new Sprite(this.game, x, y, key, frame, bodyType));
}
@@ -527,7 +527,7 @@ module Phaser {
*/
public remove(object, splice: bool = false) {
- console.log('removing from group');
+ //console.log('removing from group: ', object.name);
this._i = this.members.indexOf(object);
@@ -546,7 +546,7 @@ module Phaser {
this.members[this._i] = null;
}
- console.log('nulled');
+ //console.log('nulled');
if (object['events'])
{
@@ -728,6 +728,12 @@ module Phaser {
*/
public sortHandler(obj1, obj2): number {
+ if (!obj1 || !obj2)
+ {
+ //console.log('null objects in sort', obj1, obj2);
+ return 0;
+ }
+
if (obj1[this._sortIndex] < obj2[this._sortIndex])
{
return this._sortOrder;
diff --git a/Phaser/gameobjects/Sprite.ts b/Phaser/gameobjects/Sprite.ts
index f3d2de24..77303a38 100644
--- a/Phaser/gameobjects/Sprite.ts
+++ b/Phaser/gameobjects/Sprite.ts
@@ -71,9 +71,9 @@ module Phaser {
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.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);
@@ -88,6 +88,7 @@ module Phaser {
this.scale = this.transform.scale;
this.alpha = this.texture.alpha;
this.origin = this.transform.origin;
+ this.crop = this.texture.crop;
}
@@ -255,6 +256,13 @@ module Phaser {
*/
public scale: Phaser.Vec2;
+ /**
+ * The crop rectangle allows you to control which part of the sprite texture is rendered without distorting it.
+ * Set to null to disable, set to a Phaser.Rectangle object to control the region that will be rendered, anything outside the rectangle is ignored.
+ * @type {Phaser.Rectangle}
+ */
+ public crop: Phaser.Rectangle;
+
/**
* The origin of the Sprite around which rotation and positioning takes place.
* This is a reference to Sprite.transform.origin
diff --git a/Phaser/physics/AdvancedPhysics.ts b/Phaser/physics/AdvancedPhysics.ts
new file mode 100644
index 00000000..c4010e83
--- /dev/null
+++ b/Phaser/physics/AdvancedPhysics.ts
@@ -0,0 +1,386 @@
+///
+///
+///
+///
+
+/**
+* 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 {
+
+ export class AdvancedPhysics {
+
+ constructor(game: Game) {
+
+ this.game = game;
+
+ this.gravity = new Phaser.Vec2;
+
+ this.space = new Space(this);
+
+ this.collision = new Collision();
+
+ }
+
+ public collision;
+
+ /**
+ * Local reference to Game.
+ */
+ public game: Game;
+
+ public static debug: HTMLTextAreaElement;
+
+ public static clear() {
+ //Manager.debug.textContent = "";
+ Manager.log = [];
+ }
+
+ public static write(s: string) {
+ //Manager.debug.textContent += s + "\n";
+ }
+
+ public static writeAll() {
+
+ for (var i = 0; i < Manager.log.length; i++)
+ {
+ //Manager.debug.textContent += Manager.log[i];
+ }
+
+ }
+
+ public static log = [];
+
+ 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";
+ 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);
+ */
+
+ }
+
+ public static collision: Collision;
+
+ public static SHAPE_TYPE_CIRCLE: number = 0;
+ public static SHAPE_TYPE_SEGMENT: number = 1;
+ public static SHAPE_TYPE_POLY: number = 2;
+ public static SHAPE_NUM_TYPES: number = 3;
+
+ public static JOINT_TYPE_ANGLE: number = 0;
+ public static JOINT_TYPE_REVOLUTE: number = 1;
+ public static JOINT_TYPE_WELD: number = 2;
+ public static JOINT_TYPE_WHEEL: number = 3;
+ public static JOINT_TYPE_PRISMATIC: number = 4;
+ public static JOINT_TYPE_DISTANCE: number = 5;
+ public static JOINT_TYPE_ROPE: number = 6;
+ public static JOINT_TYPE_MOUSE: number = 7;
+
+ public static JOINT_LINEAR_SLOP: number = 0.0008;
+ 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 * 0.017453292519943294444444444444444;
+
+ public static JOINT_LIMIT_STATE_INACTIVE: number = 0;
+ public static JOINT_LIMIT_STATE_AT_LOWER: number = 1;
+ public static JOINT_LIMIT_STATE_AT_UPPER: number = 2;
+ public static JOINT_LIMIT_STATE_EQUAL_LIMITS: number = 3;
+
+ public static CONTACT_SOLVER_COLLISION_SLOP: number = 0.0008;
+ public static CONTACT_SOLVER_BAUMGARTE: number = 0.28;
+ public static CONTACT_SOLVER_MAX_LINEAR_CORRECTION: number = 1;//Infinity;
+
+ public static bodyCounter: number = 0;
+ public static jointCounter: number = 0;
+ public static shapeCounter: number = 0;
+
+ public space: Space;
+ 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 step: bool = false; // step through the simulation (i.e. per click)
+ public velocityIterations: number = 8;
+ public positionIterations: number = 4;
+ 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;
+
+ // 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++;
+
+ }
+
+ 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;
+ }
+
+ public metersToPixels(value: number): number {
+ return value * 50;
+ }
+
+ public static pixelsToMeters(value: number): number {
+ return value * 0.02;
+ }
+
+ public static metersToPixels(value: number): number {
+ return value * 50;
+ }
+
+ public static p2m(value: number): number {
+ return value * 0.02;
+ }
+
+ public static m2p(value: number): number {
+ return value * 50;
+ }
+
+ public static areaForCircle(radius_outer: number, radius_inner: number): number {
+ return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
+ }
+
+ public static inertiaForCircle(mass: number, center: Phaser.Vec2, radius_outer: number, radius_inner: number): number {
+ return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
+ }
+
+ public static areaForSegment(a: Phaser.Vec2, b: Phaser.Vec2, radius: number): number {
+ return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
+ }
+
+ public static centroidForSegment(a: Phaser.Vec2, b: Phaser.Vec2): Phaser.Vec2 {
+ return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+ }
+
+ public static inertiaForSegment(mass: number, a: Phaser.Vec2, b: Phaser.Vec2): number {
+
+ var distsq = Phaser.Vec2Utils.distanceSq(b, a);
+ var offset: Phaser.Vec2 = Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+
+ return mass * (distsq / 12 + offset.lengthSq());
+
+ }
+
+ public static areaForPoly(verts: Phaser.Vec2[]): number {
+
+ 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;
+ }
+
+ public static centroidForPoly(verts: Phaser.Vec2[]): Phaser.Vec2 {
+
+ 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));
+
+ }
+
+ public static inertiaForPoly(mass: number, verts: Phaser.Vec2[], offset: Phaser.Vec2): number {
+
+ 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);
+
+ }
+
+ public static inertiaForBox(mass: number, w: number, h: number) {
+ return mass * (w * w + h * h) / 12;
+ }
+
+ // Create the convex hull using the Gift wrapping algorithm (http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)
+ public static 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;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/Phaser/physics/ArcadePhysics.ts b/Phaser/physics/ArcadePhysics.ts
new file mode 100644
index 00000000..00ae9b18
--- /dev/null
+++ b/Phaser/physics/ArcadePhysics.ts
@@ -0,0 +1,1121 @@
+///
+///
+///
+///
+///
+
+/**
+* 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 e3468674..325965af 100644
--- a/Phaser/physics/Body.ts
+++ b/Phaser/physics/Body.ts
@@ -3,7 +3,8 @@
///
///
///
-///
+///
+///
///
///
///
@@ -26,7 +27,7 @@ module Phaser.Physics {
constructor(sprite: Phaser.Sprite, type: number, x?: number = 0, y?: number = 0, shapeType?: number = 0) {
- this.id = Phaser.Physics.Manager.bodyCounter++;
+ this.id = Phaser.Physics.AdvancedPhysics.bodyCounter++;
this.name = 'body' + this.id;
this.type = type;
@@ -34,12 +35,12 @@ module Phaser.Physics {
{
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.position = new Phaser.Vec2(Phaser.Physics.AdvancedPhysics.pixelsToMeters(sprite.x), Phaser.Physics.AdvancedPhysics.pixelsToMeters(sprite.y));
this.angle = this.game.math.degreesToRadians(sprite.rotation);
}
else
{
- this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(x), Phaser.Physics.Manager.pixelsToMeters(y));
+ this.position = new Phaser.Vec2(Phaser.Physics.AdvancedPhysics.pixelsToMeters(x), Phaser.Physics.AdvancedPhysics.pixelsToMeters(y));
this.angle = 0;
}
@@ -71,11 +72,11 @@ module Phaser.Physics {
{
if (shapeType == 0)
{
- this.addBox(0, 0, this.sprite.width, this.sprite.height, 1, 1, 1);
+ Phaser.BodyUtils.addBox(this, 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);
+ Phaser.BodyUtils.addCircle(this, Math.max(this.sprite.width, this.sprite.height) / 2, 0, 0, 1, 1, 1);
}
}
@@ -193,22 +194,6 @@ module Phaser.Physics {
public stepCount: number = 0;
public space: Space;
- public duplicate() {
-
- console.log('body duplicate called');
-
- //var body = new Body(this.type, this.transform.t, this.rotation);
-
- //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;
@@ -243,61 +228,6 @@ module Phaser.Physics {
}
- 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) {
@@ -344,7 +274,7 @@ module Phaser.Physics {
public setPosition(x: number, y: number) {
- this._newPosition.setTo(this.game.physics.pixelsToMeters(x), this.game.physics.pixelsToMeters(y));
+ this._newPosition.setTo(Phaser.Physics.AdvancedPhysics.pixelsToMeters(x), Phaser.Physics.AdvancedPhysics.pixelsToMeters(y));
this.setTransform(this._newPosition, this.angle);
diff --git a/Phaser/physics/Bounds.ts b/Phaser/physics/Bounds.ts
index 7e054a07..8c3a72e5 100644
--- a/Phaser/physics/Bounds.ts
+++ b/Phaser/physics/Bounds.ts
@@ -72,19 +72,19 @@ module Phaser.Physics {
}
public get x(): number {
- return Phaser.Physics.Manager.metersToPixels(this.mins.x);
+ return AdvancedPhysics.metersToPixels(this.mins.x);
}
public get y(): number {
- return Phaser.Physics.Manager.metersToPixels(this.mins.y);
+ return AdvancedPhysics.metersToPixels(this.mins.y);
}
public get width(): number {
- return Phaser.Physics.Manager.metersToPixels(this.maxs.x - this.mins.x);
+ return AdvancedPhysics.metersToPixels(this.maxs.x - this.mins.x);
}
public get height(): number {
- return Phaser.Physics.Manager.metersToPixels(this.maxs.y - this.mins.y);
+ return AdvancedPhysics.metersToPixels(this.maxs.y - this.mins.y);
}
public get right(): number {
diff --git a/Phaser/physics/Collision.ts b/Phaser/physics/Collision.ts
index 8d749a06..3cb00ebd 100644
--- a/Phaser/physics/Collision.ts
+++ b/Phaser/physics/Collision.ts
@@ -5,7 +5,7 @@
///
///
///
-///
+///
///
///
@@ -22,51 +22,51 @@ module Phaser.Physics {
public collide(a, b, contacts: Contact[]) {
// Circle (a is the circle)
- if (a.type == Manager.SHAPE_TYPE_CIRCLE)
+ if (a.type == AdvancedPhysics.SHAPE_TYPE_CIRCLE)
{
- if (b.type == Manager.SHAPE_TYPE_CIRCLE)
+ if (b.type == AdvancedPhysics.SHAPE_TYPE_CIRCLE)
{
return this.circle2Circle(a, b, contacts);
}
- else if (b.type == Manager.SHAPE_TYPE_SEGMENT)
+ else if (b.type == AdvancedPhysics.SHAPE_TYPE_SEGMENT)
{
return this.circle2Segment(a, b, contacts);
}
- else if (b.type == Manager.SHAPE_TYPE_POLY)
+ else if (b.type == AdvancedPhysics.SHAPE_TYPE_POLY)
{
return this.circle2Poly(a, b, contacts);
}
}
// Segment (a is the segment)
- if (a.type == Manager.SHAPE_TYPE_SEGMENT)
+ if (a.type == AdvancedPhysics.SHAPE_TYPE_SEGMENT)
{
- if (b.type == Manager.SHAPE_TYPE_CIRCLE)
+ if (b.type == AdvancedPhysics.SHAPE_TYPE_CIRCLE)
{
return this.circle2Segment(b, a, contacts);
}
- else if (b.type == Manager.SHAPE_TYPE_SEGMENT)
+ else if (b.type == AdvancedPhysics.SHAPE_TYPE_SEGMENT)
{
return this.segment2Segment(a, b, contacts);
}
- else if (b.type == Manager.SHAPE_TYPE_POLY)
+ else if (b.type == AdvancedPhysics.SHAPE_TYPE_POLY)
{
return this.segment2Poly(a, b, contacts);
}
}
// Poly (a is the poly)
- if (a.type == Manager.SHAPE_TYPE_POLY)
+ if (a.type == AdvancedPhysics.SHAPE_TYPE_POLY)
{
- if (b.type == Manager.SHAPE_TYPE_CIRCLE)
+ if (b.type == AdvancedPhysics.SHAPE_TYPE_CIRCLE)
{
return this.circle2Poly(b, a, contacts);
}
- else if (b.type == Manager.SHAPE_TYPE_SEGMENT)
+ else if (b.type == AdvancedPhysics.SHAPE_TYPE_SEGMENT)
{
return this.segment2Poly(b, a, contacts);
}
- else if (b.type == Manager.SHAPE_TYPE_POLY)
+ else if (b.type == AdvancedPhysics.SHAPE_TYPE_POLY)
{
return this.poly2Poly(a, b, contacts);
}
diff --git a/Phaser/physics/Contact.ts b/Phaser/physics/Contact.ts
index 1ae8f776..fe6f544f 100644
--- a/Phaser/physics/Contact.ts
+++ b/Phaser/physics/Contact.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
///
diff --git a/Phaser/physics/ContactSolver.ts b/Phaser/physics/ContactSolver.ts
index 9db1a609..675e8b6b 100644
--- a/Phaser/physics/ContactSolver.ts
+++ b/Phaser/physics/ContactSolver.ts
@@ -1,7 +1,7 @@
///
///
///
-///
+///
///
///
///
@@ -190,22 +190,22 @@ module Phaser.Physics {
var body1: Body = this.shape1.body;
var body2: Body = this.shape2.body;
- Manager.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
- Manager.write('Shape 1: ' + this.shape1.type + ' Shape 2: ' + this.shape2.type);
+ AdvancedPhysics.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
+ AdvancedPhysics.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;
- Manager.write('m1_inv: ' + m1_inv);
- Manager.write('i1_inv: ' + i1_inv);
- Manager.write('m2_inv: ' + m2_inv);
- Manager.write('i2_inv: ' + i2_inv);
+ AdvancedPhysics.write('m1_inv: ' + m1_inv);
+ AdvancedPhysics.write('i1_inv: ' + i1_inv);
+ AdvancedPhysics.write('m2_inv: ' + m2_inv);
+ AdvancedPhysics.write('i2_inv: ' + i2_inv);
for (var i = 0; i < this.contacts.length; i++)
{
- Manager.write('------------ solve con ' + i);
+ AdvancedPhysics.write('------------ solve con ' + i);
var con: Contact = this.contacts[i];
var n: Phaser.Vec2 = con.normal;
@@ -222,25 +222,25 @@ module Phaser.Physics {
Phaser.Vec2Utils.multiplyAdd(body1.velocity, Phaser.Vec2Utils.perp(r1), body1.angularVelocity, v1);
//var v1 = vec2.mad(body1.v, vec2.perp(r1), body1.w);
- Manager.write('v1 ' + v1.toString());
+ AdvancedPhysics.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);
- Manager.write('v2 ' + v2.toString());
+ AdvancedPhysics.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);
- Manager.write('rv ' + rv.toString());
+ AdvancedPhysics.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);
- Manager.write('lambda_n: ' + lambda_n);
+ AdvancedPhysics.write('lambda_n: ' + lambda_n);
// Accumulate and clamp
var lambda_n_old = con.lambdaNormal;
@@ -248,7 +248,7 @@ module Phaser.Physics {
//con.lambdaNormal = this.clamp(lambda_n_old + lambda_n, 0);
lambda_n = con.lambdaNormal - lambda_n_old;
- Manager.write('lambda_n clamped: ' + lambda_n);
+ AdvancedPhysics.write('lambda_n clamped: ' + lambda_n);
// Compute frictional constraint impulse
// lambda_t = -EMt * J * V
@@ -266,7 +266,7 @@ module Phaser.Physics {
//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);
- Manager.write('impulse: ' + impulse.toString());
+ AdvancedPhysics.write('impulse: ' + impulse.toString());
body1.velocity.multiplyAddByScalar(impulse, -m1_inv);
//body1.v.mad(impulse, -m1_inv);
@@ -280,8 +280,8 @@ module Phaser.Physics {
body2.angularVelocity += Phaser.Vec2Utils.cross(r2, impulse) * i2_inv;
//body2.w += vec2.cross(r2, impulse) * i2_inv;
- Manager.write('body1: ' + body1.toString());
- Manager.write('body2: ' + body2.toString());
+ AdvancedPhysics.write('body1: ' + body1.toString());
+ AdvancedPhysics.write('body2: ' + body2.toString());
}
@@ -292,7 +292,7 @@ module Phaser.Physics {
var body1: Body = this.shape1.body;
var body2: Body = this.shape2.body;
- Manager.write('solvePositionConstraints');
+ AdvancedPhysics.write('solvePositionConstraints');
var m1_inv = body1.massInverted;
var i1_inv = body1.inertiaInverted;
@@ -304,7 +304,7 @@ module Phaser.Physics {
for (var i = 0; i < this.contacts.length; i++)
{
- Manager.write('------------- solvePositionConstraints ' + i);
+ AdvancedPhysics.write('------------- solvePositionConstraints ' + i);
var con:Contact = this.contacts[i];
var n:Phaser.Vec2 = con.normal;
@@ -316,10 +316,10 @@ module Phaser.Physics {
Phaser.Vec2Utils.rotate(con.r1_local, body1.angle, r1);
Phaser.Vec2Utils.rotate(con.r2_local, body2.angle, r2);
- Manager.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
- Manager.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
- Manager.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
- Manager.write('r2 rotated: r2.x = ' + r2.x + ' r2.y = ' + r2.y);
+ AdvancedPhysics.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
+ AdvancedPhysics.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
+ AdvancedPhysics.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
+ AdvancedPhysics.write('r2 rotated: r2.x = ' + r2.x + ' r2.y = ' + r2.y);
// Contact points (corrected)
var p1 = new Phaser.Vec2;
@@ -328,8 +328,8 @@ module Phaser.Physics {
Phaser.Vec2Utils.add(body1.position, r1, p1);
Phaser.Vec2Utils.add(body2.position, r2, p2);
- Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
- Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
+ AdvancedPhysics.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ AdvancedPhysics.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
// Corrected delta vector
var dp = new Phaser.Vec2;
@@ -338,7 +338,7 @@ module Phaser.Physics {
// Position constraint
var c = Phaser.Vec2Utils.dot(dp, n) + con.depth;
- var correction = this.clamp(Manager.CONTACT_SOLVER_BAUMGARTE * (c + Manager.CONTACT_SOLVER_COLLISION_SLOP), -Manager.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
+ var correction = this.clamp(AdvancedPhysics.CONTACT_SOLVER_BAUMGARTE * (c + AdvancedPhysics.CONTACT_SOLVER_COLLISION_SLOP), -AdvancedPhysics.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
if (correction == 0)
{
@@ -367,13 +367,13 @@ module Phaser.Physics {
body2.position.multiplyAddByScalar(impulse_dt, m2_inv);
body2.angle += sn2 * lambda_dt * i2_inv;
- Manager.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
- Manager.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
+ AdvancedPhysics.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ AdvancedPhysics.write('body2.pos.x=' + body2.position.x + ' y=' + body2.position.y);
}
- Manager.write('max_penetration: ' + max_penetration);
+ AdvancedPhysics.write('max_penetration: ' + max_penetration);
- return max_penetration <= Manager.CONTACT_SOLVER_COLLISION_SLOP * 3;
+ return max_penetration <= AdvancedPhysics.CONTACT_SOLVER_COLLISION_SLOP * 3;
}
diff --git a/Phaser/physics/Manager.ts b/Phaser/physics/Manager.ts
index 9b672efd..519e3cd8 100644
--- a/Phaser/physics/Manager.ts
+++ b/Phaser/physics/Manager.ts
@@ -14,15 +14,7 @@ module Phaser.Physics {
export class Manager {
constructor(game: Game) {
-
this.game = game;
-
- this.gravity = new Phaser.Vec2;
-
- this.space = new Space(this);
-
- Manager.collision = new Collision();
-
}
/**
@@ -85,297 +77,8 @@ module Phaser.Physics {
}
- public static collision: Collision;
-
- public static SHAPE_TYPE_CIRCLE: number = 0;
- public static SHAPE_TYPE_SEGMENT: number = 1;
- public static SHAPE_TYPE_POLY: number = 2;
- public static SHAPE_NUM_TYPES: number = 3;
-
- public static JOINT_TYPE_ANGLE: number = 0;
- public static JOINT_TYPE_REVOLUTE: number = 1;
- public static JOINT_TYPE_WELD: number = 2;
- public static JOINT_TYPE_WHEEL: number = 3;
- public static JOINT_TYPE_PRISMATIC: number = 4;
- public static JOINT_TYPE_DISTANCE: number = 5;
- public static JOINT_TYPE_ROPE: number = 6;
- public static JOINT_TYPE_MOUSE: number = 7;
-
- public static JOINT_LINEAR_SLOP: number = 0.0008;
- 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 * 0.017453292519943294444444444444444;
-
- public static JOINT_LIMIT_STATE_INACTIVE: number = 0;
- public static JOINT_LIMIT_STATE_AT_LOWER: number = 1;
- public static JOINT_LIMIT_STATE_AT_UPPER: number = 2;
- public static JOINT_LIMIT_STATE_EQUAL_LIMITS: number = 3;
-
- public static CONTACT_SOLVER_COLLISION_SLOP: number = 0.0008;
- public static CONTACT_SOLVER_BAUMGARTE: number = 0.28;
- public static CONTACT_SOLVER_MAX_LINEAR_CORRECTION: number = 1;//Infinity;
-
- public static bodyCounter: number = 0;
- public static jointCounter: number = 0;
- public static shapeCounter: number = 0;
-
- public space: Space;
- 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 step: bool = false; // step through the simulation (i.e. per click)
- public velocityIterations: number = 8;
- public positionIterations: number = 4;
- 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;
-
- // 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++;
-
- }
-
- 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;
- }
-
- public metersToPixels(value: number): number {
- return value * 50;
- }
-
- public static pixelsToMeters(value: number): number {
- return value * 0.02;
- }
-
- public static metersToPixels(value: number): number {
- return value * 50;
- }
-
- public static p2m(value: number): number {
- return value * 0.02;
- }
-
- public static m2p(value: number): number {
- return value * 50;
- }
-
- public static areaForCircle(radius_outer: number, radius_inner: number): number {
- return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
- }
-
- public static inertiaForCircle(mass: number, center: Phaser.Vec2, radius_outer: number, radius_inner: number): number {
- return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
- }
-
- public static areaForSegment(a: Phaser.Vec2, b: Phaser.Vec2, radius: number): number {
- return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
- }
-
- public static centroidForSegment(a: Phaser.Vec2, b: Phaser.Vec2): Phaser.Vec2 {
- return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
- }
-
- public static inertiaForSegment(mass: number, a: Phaser.Vec2, b: Phaser.Vec2): number {
-
- var distsq = Phaser.Vec2Utils.distanceSq(b, a);
- var offset: Phaser.Vec2 = Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
-
- return mass * (distsq / 12 + offset.lengthSq());
-
- }
-
- public static areaForPoly(verts: Phaser.Vec2[]): number {
-
- 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;
- }
-
- public static centroidForPoly(verts: Phaser.Vec2[]): Phaser.Vec2 {
-
- 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));
-
- }
-
- public static inertiaForPoly(mass: number, verts: Phaser.Vec2[], offset: Phaser.Vec2): number {
-
- 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);
-
- }
-
- public static inertiaForBox(mass: number, w: number, h: number) {
- return mass * (w * w + h * h) / 12;
- }
-
- // Create the convex hull using the Gift wrapping algorithm (http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)
- public static 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;
}
}
diff --git a/Phaser/physics/Plane.ts b/Phaser/physics/Plane.ts
index 3d15be03..f8fd4836 100644
--- a/Phaser/physics/Plane.ts
+++ b/Phaser/physics/Plane.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
/**
diff --git a/Phaser/physics/Space.ts b/Phaser/physics/Space.ts
index c9b3b809..030ceb32 100644
--- a/Phaser/physics/Space.ts
+++ b/Phaser/physics/Space.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
///
///
@@ -18,7 +18,7 @@ module Phaser.Physics {
export class Space {
- constructor(manager: Phaser.Physics.Manager) {
+ constructor(manager: Phaser.Physics.AdvancedPhysics) {
this._manager = manager;
@@ -39,7 +39,7 @@ module Phaser.Physics {
}
- private _manager: Phaser.Physics.Manager;
+ private _manager: Phaser.Physics.AdvancedPhysics;
// Delta Timer
private _delta: number;
@@ -85,9 +85,9 @@ module Phaser.Physics {
public clear() {
- Manager.shapeCounter = 0;
- Manager.bodyCounter = 0;
- Manager.jointCounter = 0;
+ AdvancedPhysics.shapeCounter = 0;
+ AdvancedPhysics.bodyCounter = 0;
+ AdvancedPhysics.jointCounter = 0;
for (var i = 0; i < this.bodies.length; i++)
{
@@ -379,7 +379,7 @@ module Phaser.Physics {
{
var shape = body.shapes[j];
- if (shape.type != Manager.SHAPE_TYPE_POLY)
+ if (shape.type != AdvancedPhysics.SHAPE_TYPE_POLY)
{
continue;
}
@@ -514,7 +514,7 @@ module Phaser.Physics {
var contactArr = [];
- if (!Manager.collision.collide(this._shape1, this._shape2, contactArr))
+ if (!AdvancedPhysics.collision.collide(this._shape1, this._shape2, contactArr))
{
continue;
}
diff --git a/Phaser/physics/joints/IJoint.ts b/Phaser/physics/joints/IJoint.ts
index fdeb393a..cb940a12 100644
--- a/Phaser/physics/joints/IJoint.ts
+++ b/Phaser/physics/joints/IJoint.ts
@@ -1,7 +1,7 @@
///
///
///
-///
+///
///
/**
diff --git a/Phaser/physics/joints/Joint.ts b/Phaser/physics/joints/Joint.ts
index 3f850959..48d8b277 100644
--- a/Phaser/physics/joints/Joint.ts
+++ b/Phaser/physics/joints/Joint.ts
@@ -1,7 +1,7 @@
///
///
///
-///
+///
///
/**
@@ -16,7 +16,7 @@ module Phaser.Physics {
constructor(type: number, body1:Phaser.Physics.Body, body2:Phaser.Physics.Body, collideConnected) {
- this.id = Phaser.Physics.Manager.jointCounter++;
+ this.id = AdvancedPhysics.jointCounter++;
this.type = type;
this.body1 = body1;
diff --git a/Phaser/physics/shapes/Box.ts b/Phaser/physics/shapes/Box.ts
index 3650e803..90743c74 100644
--- a/Phaser/physics/shapes/Box.ts
+++ b/Phaser/physics/shapes/Box.ts
@@ -1,5 +1,5 @@
///
-///
+///
///
///
///
@@ -19,10 +19,10 @@ module Phaser.Physics.Shapes {
console.log('Box px', x, y, width, height);
- x = Manager.pixelsToMeters(x);
- y = Manager.pixelsToMeters(y);
- width = Manager.pixelsToMeters(width);
- height = Manager.pixelsToMeters(height);
+ x = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x);
+ y = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y);
+ width = Phaser.Physics.AdvancedPhysics.pixelsToMeters(width);
+ height = Phaser.Physics.AdvancedPhysics.pixelsToMeters(height);
console.log('Box m', x, y, width, height);
diff --git a/Phaser/physics/shapes/Circle.ts b/Phaser/physics/shapes/Circle.ts
index 23997aa5..52a60fde 100644
--- a/Phaser/physics/shapes/Circle.ts
+++ b/Phaser/physics/shapes/Circle.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
///
@@ -16,11 +16,11 @@ module Phaser.Physics.Shapes {
constructor(radius: number, x?: number = 0, y?: number = 0) {
- super(Manager.SHAPE_TYPE_CIRCLE);
+ super(AdvancedPhysics.SHAPE_TYPE_CIRCLE);
- x = Manager.pixelsToMeters(x);
- y = Manager.pixelsToMeters(y);
- radius = Manager.pixelsToMeters(radius);
+ x = AdvancedPhysics.pixelsToMeters(x);
+ y = AdvancedPhysics.pixelsToMeters(y);
+ radius = AdvancedPhysics.pixelsToMeters(radius);
this.center = new Phaser.Vec2(x, y);
this.radius = radius;
@@ -58,7 +58,7 @@ module Phaser.Physics.Shapes {
}
public area(): number {
- return Manager.areaForCircle(this.radius, 0);
+ return AdvancedPhysics.areaForCircle(this.radius, 0);
}
public centroid(): Phaser.Vec2 {
@@ -66,7 +66,7 @@ module Phaser.Physics.Shapes {
}
public inertia(mass: number): number {
- return Manager.inertiaForCircle(mass, this.center, this.radius, 0);
+ return AdvancedPhysics.inertiaForCircle(mass, this.center, this.radius, 0);
}
public cacheData(xf: Transform) {
diff --git a/Phaser/physics/shapes/IShape.ts b/Phaser/physics/shapes/IShape.ts
index c1f0ddb4..08085b74 100644
--- a/Phaser/physics/shapes/IShape.ts
+++ b/Phaser/physics/shapes/IShape.ts
@@ -1,7 +1,7 @@
///
///
///
-///
+///
///
///
diff --git a/Phaser/physics/shapes/Poly.ts b/Phaser/physics/shapes/Poly.ts
index a11cdc6f..0119dc47 100644
--- a/Phaser/physics/shapes/Poly.ts
+++ b/Phaser/physics/shapes/Poly.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
///
///
@@ -19,7 +19,7 @@ module Phaser.Physics.Shapes {
// to seed this polygon (i.e. Vec2 objects, or just straight JS objects) and must wind COUNTER clockwise
constructor(verts?) {
- super(Manager.SHAPE_TYPE_POLY);
+ super(AdvancedPhysics.SHAPE_TYPE_POLY);
this.verts = [];
this.planes = [];
@@ -117,15 +117,15 @@ module Phaser.Physics.Shapes {
}
public area(): number {
- return Manager.areaForPoly(this.verts);
+ return AdvancedPhysics.areaForPoly(this.verts);
}
public centroid(): Phaser.Vec2 {
- return Manager.centroidForPoly(this.verts);
+ return AdvancedPhysics.centroidForPoly(this.verts);
}
public inertia(mass: number): number {
- return Manager.inertiaForPoly(mass, this.verts, new Phaser.Vec2);
+ return AdvancedPhysics.inertiaForPoly(mass, this.verts, new Phaser.Vec2);
}
public cacheData(xf:Transform) {
@@ -134,7 +134,7 @@ module Phaser.Physics.Shapes {
var numVerts = this.verts.length;
- Manager.write('----------- Poly cacheData = ' + numVerts);
+ AdvancedPhysics.write('----------- Poly cacheData = ' + numVerts);
if (numVerts == 0)
{
@@ -145,7 +145,7 @@ module Phaser.Physics.Shapes {
{
this.tverts[i] = Phaser.TransformUtils.transform(xf, this.verts[i]);
//this.tverts[i] = xf.transform(this.verts[i]);
- Manager.write('tvert' + i + ' = ' + this.tverts[i].toString());
+ AdvancedPhysics.write('tvert' + i + ' = ' + this.tverts[i].toString());
}
if (numVerts < 2)
@@ -160,15 +160,15 @@ module Phaser.Physics.Shapes {
var b = this.tverts[(i + 1) % numVerts];
var n = Phaser.Vec2Utils.normalize(Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(a, b)));
- Manager.write('a = ' + a.toString());
- Manager.write('b = ' + b.toString());
- Manager.write('n = ' + n.toString());
+ AdvancedPhysics.write('a = ' + a.toString());
+ AdvancedPhysics.write('b = ' + b.toString());
+ AdvancedPhysics.write('n = ' + n.toString());
this.tplanes[i].normal = n;
this.tplanes[i].d = Phaser.Vec2Utils.dot(n, a);
- Manager.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
- Manager.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
+ AdvancedPhysics.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
+ AdvancedPhysics.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
this.bounds.addPoint(a);
diff --git a/Phaser/physics/shapes/Segment.ts b/Phaser/physics/shapes/Segment.ts
index b949206e..7416c03b 100644
--- a/Phaser/physics/shapes/Segment.ts
+++ b/Phaser/physics/shapes/Segment.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
///
@@ -16,7 +16,7 @@ module Phaser.Physics.Shapes {
constructor(a, b, radius: number) {
- super(Manager.SHAPE_TYPE_SEGMENT);
+ super(AdvancedPhysics.SHAPE_TYPE_SEGMENT);
this.a = a.duplicate();
this.b = b.duplicate();
@@ -81,15 +81,15 @@ module Phaser.Physics.Shapes {
}
public area(): number {
- return Manager.areaForSegment(this.a, this.b, this.radius);
+ return AdvancedPhysics.areaForSegment(this.a, this.b, this.radius);
}
public centroid(): Phaser.Vec2 {
- return Manager.centroidForSegment(this.a, this.b);
+ return AdvancedPhysics.centroidForSegment(this.a, this.b);
}
public inertia(mass: number): number {
- return Manager.inertiaForSegment(mass, this.a, this.b);
+ return AdvancedPhysics.inertiaForSegment(mass, this.a, this.b);
}
public cacheData(xf:Transform) {
diff --git a/Phaser/physics/shapes/Shape.ts b/Phaser/physics/shapes/Shape.ts
index ed206c8e..edac5aa2 100644
--- a/Phaser/physics/shapes/Shape.ts
+++ b/Phaser/physics/shapes/Shape.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
///
///
@@ -17,7 +17,7 @@ module Phaser.Physics {
constructor(type: number) {
- this.id = Phaser.Physics.Manager.shapeCounter++;
+ this.id = AdvancedPhysics.shapeCounter++;
this.type = type;
this.elasticity = 0.0;
diff --git a/Phaser/physics/shapes/Triangle.ts b/Phaser/physics/shapes/Triangle.ts
index 8d78647d..03842876 100644
--- a/Phaser/physics/shapes/Triangle.ts
+++ b/Phaser/physics/shapes/Triangle.ts
@@ -1,5 +1,5 @@
///
-///
+///
///
///
///
@@ -16,12 +16,12 @@ module Phaser.Physics.Shapes {
constructor(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number) {
- x1 = Manager.pixelsToMeters(x1);
- y1 = Manager.pixelsToMeters(y1);
- x2 = Manager.pixelsToMeters(x2);
- y2 = Manager.pixelsToMeters(y2);
- x3 = Manager.pixelsToMeters(x3);
- y3 = Manager.pixelsToMeters(y3);
+ x1 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x1);
+ y1 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y1);
+ x2 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x2);
+ y2 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y2);
+ x3 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x3);
+ y3 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y3);
super([{ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }]);
diff --git a/Phaser/renderers/CanvasRenderer.ts b/Phaser/renderers/CanvasRenderer.ts
index a2aaa151..1d51ed71 100644
--- a/Phaser/renderers/CanvasRenderer.ts
+++ b/Phaser/renderers/CanvasRenderer.ts
@@ -459,6 +459,7 @@ module Phaser {
}
sprite.renderOrderID = this._count;
+
this._count++;
// Reset our temp vars
@@ -524,6 +525,18 @@ module Phaser {
this._dy -= (this._dh * sprite.transform.origin.y);
}
+ if (sprite.crop)
+ {
+ this._sx += sprite.crop.x * sprite.transform.scale.x;
+ this._sy += sprite.crop.y * sprite.transform.scale.y;
+ this._sw = sprite.crop.width * sprite.transform.scale.x;
+ this._sh = sprite.crop.height * sprite.transform.scale.y;
+ this._dx += sprite.crop.x * sprite.transform.scale.x;
+ this._dy += sprite.crop.y * sprite.transform.scale.y;
+ this._dw = sprite.crop.width * sprite.transform.scale.x;
+ this._dh = sprite.crop.height * sprite.transform.scale.y;
+ }
+
this._sx = Math.round(this._sx);
this._sy = Math.round(this._sy);
this._sw = Math.round(this._sw);
diff --git a/Phaser/sound/Sound.ts b/Phaser/sound/Sound.ts
index 2207784c..51915a43 100644
--- a/Phaser/sound/Sound.ts
+++ b/Phaser/sound/Sound.ts
@@ -75,7 +75,7 @@ module Phaser {
{
this._sound = this.game.cache.getSoundData(this.key);
this.totalDuration = this._sound.duration;
- console.log('sound has unlocked', this._sound);
+ //console.log('sound has unlocked', this._sound);
}
}
@@ -183,32 +183,32 @@ module Phaser {
if (this.currentTime >= this.duration)
{
- console.log(this.currentMarker, 'has hit duration');
+ //console.log(this.currentMarker, 'has hit duration');
if (this.usingWebAudio)
{
if (this.loop)
{
- console.log('loop1');
+ //console.log('loop1');
// won't work with markers, needs to reset the position
this.onLoop.dispatch(this);
if (this.currentMarker == '')
{
- console.log('loop2');
+ //console.log('loop2');
this.currentTime = 0;
this.startTime = this.game.time.now;
}
else
{
- console.log('loop3');
+ //console.log('loop3');
this.play(this.currentMarker, 0, this.volume, true, true);
}
}
else
{
- console.log('stopping, no loop for marker');
+ //console.log('stopping, no loop for marker');
this.stop();
}
}
@@ -241,7 +241,7 @@ module Phaser {
*/
public play(marker: string = '', position?: number = 0, volume?: number = 1, loop?: bool = false, forceRestart: bool = false) {
- console.log('play', marker, 'current is', this.currentMarker);
+ //console.log('play', marker, 'current is', this.currentMarker);
if (this.isPlaying == true && forceRestart == false && this.override == false)
{
@@ -251,7 +251,7 @@ module Phaser {
if (this.isPlaying && this.override)
{
- console.log('asked to play', marker, 'but already playing', this.currentMarker);
+ //console.log('asked to play', marker, 'but already playing', this.currentMarker);
if (this.usingWebAudio)
{
if (typeof this._sound.stop === 'undefined')
@@ -279,7 +279,7 @@ module Phaser {
this.loop = this.markers[marker].loop;
this.duration = this.markers[marker].duration * 1000;
- console.log('marker info loaded', this.loop, this.duration);
+ //console.log('marker info loaded', this.loop, this.duration);
this._tempMarker = marker;
this._tempPosition = this.position;
@@ -345,7 +345,7 @@ module Phaser {
this.stopTime = this.startTime + this.duration;
this.onPlay.dispatch(this);
- console.log('playing, start', this.startTime, 'stop');
+ //console.log('playing, start', this.startTime, 'stop');
}
else
@@ -459,7 +459,7 @@ module Phaser {
*/
public stop() {
- console.log('Sound.stop', this.currentMarker);
+ //console.log('Sound.stop', this.currentMarker);
if (this.isPlaying && this._sound)
{
diff --git a/Phaser/utils/BodyUtils.ts b/Phaser/utils/BodyUtils.ts
new file mode 100644
index 00000000..e43a770d
--- /dev/null
+++ b/Phaser/utils/BodyUtils.ts
@@ -0,0 +1,94 @@
+///
+///
+///
+///
+///
+
+/**
+* Phaser - BodyUtils
+*
+* A collection of methods useful for manipulating AdvancedPhysics Body objects.
+*/
+
+module Phaser {
+
+ export class BodyUtils {
+
+ static duplicate(source: Phaser.Physics.Body, output?: Phaser.Physics.Body): Phaser.Physics.Body {
+
+ /*
+ console.log('body duplicate called');
+
+ var newBody = new Phaser.Physics.Body(source.type, source.transform.t, source.rotation);
+
+ for (var i = 0; i < source.shapes.length; i++)
+ {
+ output.addShape(source.shapes[i].duplicate());
+ }
+
+ output.resetMassData();
+ */
+
+ return output;
+
+ }
+
+ static addPoly(body: Phaser.Physics.Body, 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;
+
+ body.addShape(poly);
+ body.resetMassData();
+
+ return poly;
+
+ }
+
+ static addTriangle(body: Phaser.Physics.Body, 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;
+
+ body.addShape(tri);
+ body.resetMassData();
+
+ return tri;
+
+ }
+
+ static addBox(body: Phaser.Physics.Body, 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;
+
+ body.addShape(box);
+ body.resetMassData();
+
+ return box;
+
+ }
+
+ static addCircle(body: Phaser.Physics.Body, 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;
+
+ body.addShape(circle);
+ body.resetMassData();
+
+ return circle;
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/Phaser/utils/DebugUtils.ts b/Phaser/utils/DebugUtils.ts
index add9178b..2864a1cd 100644
--- a/Phaser/utils/DebugUtils.ts
+++ b/Phaser/utils/DebugUtils.ts
@@ -124,7 +124,7 @@ module Phaser {
{
DebugUtils.context.beginPath();
- if (body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_POLY)
+ if (body.shapes[s].type == Phaser.Physics.AdvancedPhysics.SHAPE_TYPE_POLY)
{
var verts = body.shapes[s].tverts;
@@ -140,7 +140,7 @@ module Phaser {
// DebugUtils.context.lineTo(body.position.x * 50 + verts[0].x, body.position.y * 50 + verts[0].y);
DebugUtils.context.lineTo(verts[0].x * 50, verts[0].y * 50);
}
- else if (body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_CIRCLE)
+ else if (body.shapes[s].type == Phaser.Physics.AdvancedPhysics.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);
diff --git a/README.md b/README.md
index 72ae897e..581c90c3 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,6 @@ TODO:
* If stage.clear set to false and game pauses, when it unpauses you still see the pause arrow - resolve this
* Add clip support + shape options to Texture Component.
* Make sure I'm using Point and not Vec2 when it's not a directional vector I need
-* Bug with setting scale or anything on a Sprite inside a Group, or maybe group.addNewSprite issue
* 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
@@ -62,8 +61,16 @@ TODO:
* Stage lost to mute
* When game is paused Pointer shouldn't process targetObjects / change cursor
* Need to limit touch priority of items in groups?
-* Bring to Top doesn't seem to respect the group they are in
-* Add crop support
+* Check if it works from an iFrame
+* Bitmap Font support
+* Basic Window component (maybe a propogating Group?)
+* Put ArcadePhysics back in
+* Look at the N+ tile support maybe with ArcadePhysics?
+* Pixel-perfect click check
+* Check Flash atlas export is supported
+* Plug-in Support
+
+
V1.0.0
@@ -160,10 +167,10 @@ V1.0.0
* Added Phaser.Net for browser and network specific functions, currently includes query string parsing and updating methods.
* Added a new CSS3 Filters component. Apply blur, grayscale, sepia, brightness, contrast, hue rotation, invert, opacity and saturate filters to the games stage.
* Fixed the CircleUtils.contains and containsPoint methods.
-* Fixed issue with Input.speed values being too high on touch events.
-
-
-
+* Fixed issue with Input.speed values being too high on new touch events.
+* Added Sprite.bringToTop()
+* Added Stage.disableVisibilityChange to stop the auto pause/resume from ever firing.
+* Added crop support to the Texture component, so you can do Sprite.crop to restrict rendering to a specified Rectangle without distortion.
V0.9.6
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index e35c5c8c..b8ef4ab0 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -92,6 +92,10 @@
world sprite.ts
+
+
+ bring to top 1.ts
+
create group 1.ts
diff --git a/Tests/groups/bring to top 1.js b/Tests/groups/bring to top 1.js
new file mode 100644
index 00000000..8f8d5e7b
--- /dev/null
+++ b/Tests/groups/bring to top 1.js
@@ -0,0 +1,62 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
+ function init() {
+ game.load.image('beast', 'assets/pics/shadow_of_the_beast2_karamoon.png');
+ game.load.image('snot', 'assets/pics/nslide_snot.png');
+ game.load.image('atari1', 'assets/sprites/atari130xe.png');
+ game.load.image('sonic', 'assets/sprites/sonic_havok_sanity.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('disk', 'assets/sprites/oz_pov_melting_disk.png');
+ game.load.start();
+ }
+ var group1;
+ var group2;
+ var coke;
+ var disk;
+ function create() {
+ // Create a background image
+ game.add.sprite(0, 0, 'beast');
+ // Create a Group that will sit above the background image
+ group1 = game.add.group(11);
+ // Create a Group that will sit above Group 1
+ group2 = game.add.group(11);
+ // Now let's create some random sprites and enable them all for drag and 'bring to top'
+ for(var i = 0; i < 10; i++) {
+ //var tempSprite: Phaser.Sprite = group1.addNewSprite(game.stage.randomX, game.stage.randomY, 'atari1');
+ //var tempSprite: Phaser.Sprite = new Phaser.Sprite(game, game.stage.randomX, game.stage.randomY, 'atari1');
+ var tempSprite = game.add.sprite(game.stage.randomX, game.stage.randomY, 'atari1');
+ tempSprite.name = 'atari' + i;
+ tempSprite.input.start(i, false, true);
+ tempSprite.input.enableDrag(false, true);
+ group1.add(tempSprite);
+ // Sonics
+ //var tempSprite: Phaser.Sprite = group2.addNewSprite(game.stage.randomX, game.stage.randomY, 'sonic');
+ //var tempSprite: Phaser.Sprite = new Phaser.Sprite(game, game.stage.randomX, game.stage.randomY, 'sonic');
+ var tempSprite = game.add.sprite(game.stage.randomX, game.stage.randomY, 'sonic');
+ tempSprite.name = 'sonic' + i;
+ tempSprite.input.start(10 + i, false, true);
+ tempSprite.input.enableDrag(false, true);
+ group2.add(tempSprite);
+ }
+ // Add 2 control sprites into each group - these cannot be dragged but should be bought to the top each time
+ coke = group1.addNewSprite(100, 100, 'coke');
+ disk = group2.addNewSprite(400, 300, 'disk');
+ // Create a foreground image - everything should appear behind this, even when dragged
+ var snot = game.add.sprite(game.stage.centerX, game.stage.height, 'snot');
+ snot.origin.setTo(0.5, 1);
+ // You can click and drag any sprite but Sonic sprites should always appear above the Atari sprites
+ // and both types of sprite should only ever appear above the background and behind the
+ }
+ function update() {
+ if(game.input.keyboard.justReleased(Phaser.Keyboard.ONE)) {
+ coke.bringToTop();
+ }
+ if(game.input.keyboard.justReleased(Phaser.Keyboard.TWO)) {
+ disk.bringToTop();
+ }
+ }
+ function render() {
+ game.input.renderDebugInfo(32, 32);
+ }
+})();
diff --git a/Tests/phaser.js b/Tests/phaser.js
index 2cee6f41..a53e9d94 100644
--- a/Tests/phaser.js
+++ b/Tests/phaser.js
@@ -3659,7 +3659,8 @@ var Phaser;
this.startDrag(pointer);
}
if(this.bringToTop) {
- this._parent.group.bringToTop(this._parent);
+ //this._parent.bringToTop();
+ this._parent.game.world.group.bringToTop(this._parent);
}
}
// Consume the event?
@@ -3836,7 +3837,7 @@ var Phaser;
}
this.updateDrag(pointer);
if(this.bringToTop) {
- this._parent.group.bringToTop(this._parent);
+ this._parent.bringToTop();
}
this._parent.events.onDragStart.dispatch(this._parent, pointer);
};
@@ -7271,6 +7272,14 @@ var Phaser;
enumerable: true,
configurable: true
});
+ Sprite.prototype.bringToTop = /**
+ * Brings this Sprite to the top of its current Group, if set.
+ */
+ function () {
+ if(this.group) {
+ this.group.bringToTop(this);
+ }
+ };
Object.defineProperty(Sprite.prototype, "alpha", {
get: /**
* The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque.
@@ -8103,13 +8112,13 @@ var Phaser;
* @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 [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)
* @returns {Sprite} The newly created sprite object.
*/
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.add(new Phaser.Sprite(this.game, x, y, key, frame, bodyType));
};
Group.prototype.setObjectIDs = /**
@@ -8189,7 +8198,7 @@ var Phaser;
*/
function (object, splice) {
if (typeof splice === "undefined") { splice = false; }
- console.log('removing from group');
+ console.log('removing from group: ', object.name);
this._i = this.members.indexOf(object);
if(this._i < 0 || (this._i >= this.members.length)) {
return null;
@@ -8342,6 +8351,10 @@ var Phaser;
* @return {number} An integer value: -1 (Obj1 before Obj2), 0 (same), or 1 (Obj1 after Obj2).
*/
function (obj1, obj2) {
+ if(!obj1 || !obj2) {
+ //console.log('null objects in sort', obj1, obj2);
+ return 0;
+ }
if(obj1[this._sortIndex] < obj2[this._sortIndex]) {
return this._sortOrder;
} else if(obj1[this._sortIndex] > obj2[this._sortIndex]) {
@@ -14135,6 +14148,16 @@ var Phaser;
function (sprite) {
return this._world.group.add(sprite);
};
+ GameObjectFactory.prototype.existingGroup = /**
+ * Add an existing Group to the current world.
+ * Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
+ *
+ * @param group The Group to add to the Game World
+ * @return {Phaser.Group} The Group object
+ */
+ function (group) {
+ return this._world.group.add(group);
+ };
GameObjectFactory.prototype.existingButton = /**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
@@ -17621,7 +17644,9 @@ var Phaser;
//this.game.input.y = this.y * this.game.input.scale.y;
this.game.input.x = this.x;
this.game.input.y = this.y;
+ this.game.input.position.setTo(this.x, this.y);
this.game.input.onDown.dispatch(this);
+ this.game.input.resetSpeed(this.x, this.y);
}
this._stateReset = false;
this.totalTouches++;
@@ -18934,6 +18959,10 @@ var Phaser;
this.totalTrackedObjects = 0;
}
};
+ Input.prototype.resetSpeed = function (x, y) {
+ this._oldPosition.setTo(x, y);
+ this.speed.setTo(0, 0);
+ };
Object.defineProperty(Input.prototype, "totalInactivePointers", {
get: /**
* Get the total number of inactive Pointers
@@ -19870,6 +19899,24 @@ var Phaser;
DebugUtils.context.fillStyle = fillStyle;
DebugUtils.context.fillRect(rect.x, rect.y, rect.width, rect.height);
};
+ DebugUtils.renderCircle = function renderCircle(circle, fillStyle) {
+ if (typeof fillStyle === "undefined") { fillStyle = 'rgba(0,255,0,0.3)'; }
+ DebugUtils.context.fillStyle = fillStyle;
+ DebugUtils.context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2, false);
+ DebugUtils.context.fill();
+ };
+ DebugUtils.renderText = /**
+ * Render text
+ * @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 renderText(text, x, y, color) {
+ if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
+ DebugUtils.context.font = '16px Courier';
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillText(text, x, y);
+ };
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)'; }
@@ -20760,15 +20807,10 @@ var Phaser;
function contains(a, x, y) {
// Check if x/y are within the bounds first
if(x >= a.left && x <= a.right && y >= a.top && y <= a.bottom) {
- var dx = a.x - x;
- var dy = a.y - y;
- dx *= dx;
- dy *= dy;
- var radSqr = a.radius * a.radius;
- console.log('within bounds', dx, dy, radSqr);
- return (dx + dy) <= radSqr;
- //return (a.left * a.left + a.top * a.top) <= (a.radius * a.radius);
- }
+ var dx = (a.x - x) * (a.x - x);
+ var dy = (a.y - y) * (a.y - y);
+ return (dx + dy) <= (a.radius * a.radius);
+ }
return false;
};
CircleUtils.containsPoint = /**
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index c143276a..1838b989 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -3342,11 +3342,21 @@ module Phaser {
*/
public rotation : number;
/**
+ * Brings this Sprite to the top of its current Group, if set.
+ */
+ public bringToTop(): void;
+ /**
* The scale of the Sprite. A value of 1 is original scale. 0.5 is half size. 2 is double the size.
* This is a reference to Sprite.transform.scale
*/
public scale: Vec2;
/**
+ * The crop rectangle allows you to control which part of the sprite texture is rendered without distorting it.
+ * Set to null to disable, set to a Phaser.Rectangle object to control the region that will be rendered, anything outside the rectangle is ignored.
+ * @type {Phaser.Rectangle}
+ */
+ public crop: Rectangle;
+ /**
* The origin of the Sprite around which rotation and positioning takes place.
* This is a reference to Sprite.transform.origin
*/
@@ -3600,6 +3610,12 @@ module Phaser.Components {
*/
public isDynamic: bool;
/**
+ * The crop rectangle allows you to control which part of the sprite texture is rendered without distorting it.
+ * Set to null to disable, set to a Phaser.Rectangle object to control the region that will be rendered, anything outside the rectangle is ignored.
+ * @type {Phaser.Rectangle}
+ */
+ public crop: Rectangle;
+ /**
* Updates the texture being used to render the Sprite.
* Called automatically by SpriteUtils.loadTexture and SpriteUtils.loadDynamicTexture.
*/
@@ -3732,7 +3748,7 @@ module Phaser {
public getNextZIndex(): number;
/**
* Override this function to handle any deleting or "shutdown" type operations you might need,
- * such as removing traditional Flash children like Basic objects.
+ * such as removing traditional children like Basic objects.
*/
public destroy(): void;
/**
@@ -3782,7 +3798,7 @@ module Phaser {
* @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 [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)
* @returns {Sprite} The newly created sprite object.
*/
public addNewSprite(x: number, y: number, key?: string, frame?, bodyType?: number): Sprite;
@@ -6956,6 +6972,14 @@ module Phaser {
*/
public existingSprite(sprite: Sprite): Sprite;
/**
+ * Add an existing Group to the current world.
+ * Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
+ *
+ * @param group The Group to add to the Game World
+ * @return {Phaser.Group} The Group object
+ */
+ public existingGroup(group: Group): Group;
+ /**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
*
@@ -7693,6 +7717,11 @@ module Phaser {
*/
public scaleMode: number;
/**
+ * If set to true the game will never pause when the browser or browser tab loses focuses
+ * @type {boolean}
+ */
+ public disableVisibilityChange: bool;
+ /**
* Stage boot
*/
public boot(): void;
@@ -9571,6 +9600,8 @@ module Phaser {
* @type {Pointer}
**/
public activePointer: Pointer;
+ public inputObjects: any[];
+ public totalTrackedObjects: number;
/**
* The X coordinate of the most recently active pointer.
* This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values.
@@ -9597,8 +9628,6 @@ module Phaser {
* @method start
**/
public boot(): void;
- public inputObjects: any[];
- public totalTrackedObjects: number;
/**
* Adds a new game object to be tracked by the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
* @method addGameObject
@@ -9620,6 +9649,7 @@ module Phaser {
* @param hard {Boolean} A soft reset (hard = false) won't reset any signals that might be bound. A hard reset will.
**/
public reset(hard?: bool): void;
+ public resetSpeed(x: number, y: number): void;
/**
* Get the total number of inactive Pointers
* @method totalInactivePointers
@@ -9822,6 +9852,14 @@ module Phaser {
static renderPhysicsBodyInfo(body: Physics.Body, x: number, y: number, color?: string): void;
static renderSpriteBounds(sprite: Sprite, camera?: Camera, color?: string): void;
static renderRectangle(rect: Rectangle, fillStyle?: string): void;
+ static renderCircle(circle: Circle, fillStyle?: string): void;
+ /**
+ * Render text
+ * @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)
+ */
+ static renderText(text: string, x: number, y: number, color?: string): void;
static renderPhysicsBody(body: Physics.Body, lineWidth?: number, fillStyle?: string, sleepStyle?: string): void;
}
}
@@ -10378,6 +10416,20 @@ module Phaser {
static normalFromMat4(): void;
}
}
+interface IPoint {
+ getDist(): number;
+}
+module Shapes {
+ class Point implements IPoint {
+ public x: number;
+ public y: number;
+ constructor(x: number, y: number);
+ public getDist(): number;
+ static origin: Point;
+ }
+}
+var p: IPoint;
+var dist: number;
/**
* Phaser - PixelUtils
*
diff --git a/build/phaser.js b/build/phaser.js
index 2cee6f41..4bcb2159 100644
--- a/build/phaser.js
+++ b/build/phaser.js
@@ -3659,8 +3659,9 @@ var Phaser;
this.startDrag(pointer);
}
if(this.bringToTop) {
- this._parent.group.bringToTop(this._parent);
- }
+ this._parent.bringToTop();
+ //this._parent.game.world.group.bringToTop(this._parent);
+ }
}
// Consume the event?
return this.consumePointerEvent;
@@ -3836,7 +3837,7 @@ var Phaser;
}
this.updateDrag(pointer);
if(this.bringToTop) {
- this._parent.group.bringToTop(this._parent);
+ this._parent.bringToTop();
}
this._parent.events.onDragStart.dispatch(this._parent, pointer);
};
@@ -4412,12 +4413,95 @@ var Phaser;
})();
Phaser.TransformUtils = TransformUtils;
})(Phaser || (Phaser = {}));
+///
+///
+///
+///
+///
+/**
+* Phaser - BodyUtils
+*
+* A collection of methods useful for manipulating AdvancedPhysics Body objects.
+*/
+var Phaser;
+(function (Phaser) {
+ var BodyUtils = (function () {
+ function BodyUtils() { }
+ BodyUtils.duplicate = function duplicate(source, output) {
+ /*
+ console.log('body duplicate called');
+
+ var newBody = new Phaser.Physics.Body(source.type, source.transform.t, source.rotation);
+
+ for (var i = 0; i < source.shapes.length; i++)
+ {
+ output.addShape(source.shapes[i].duplicate());
+ }
+
+ output.resetMassData();
+ */
+ return output;
+ };
+ BodyUtils.addPoly = function addPoly(body, 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;
+ body.addShape(poly);
+ body.resetMassData();
+ return poly;
+ };
+ BodyUtils.addTriangle = function addTriangle(body, 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;
+ body.addShape(tri);
+ body.resetMassData();
+ return tri;
+ };
+ BodyUtils.addBox = function addBox(body, 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;
+ body.addShape(box);
+ body.resetMassData();
+ return box;
+ };
+ BodyUtils.addCircle = function addCircle(body, 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;
+ body.addShape(circle);
+ body.resetMassData();
+ return circle;
+ };
+ return BodyUtils;
+ })();
+ Phaser.BodyUtils = BodyUtils;
+})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
///
///
///
- ///
+ ///
///
/**
* Phaser - Advanced Physics - Joint
@@ -4427,7 +4511,7 @@ var Phaser;
(function (Physics) {
var Joint = (function () {
function Joint(type, body1, body2, collideConnected) {
- this.id = Phaser.Physics.Manager.jointCounter++;
+ this.id = Physics.AdvancedPhysics.jointCounter++;
this.type = type;
this.body1 = body1;
this.body2 = body2;
@@ -4454,274 +4538,6 @@ var Phaser;
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) {
///
///
@@ -4777,28 +4593,28 @@ var Phaser;
};
Object.defineProperty(Bounds.prototype, "x", {
get: function () {
- return Phaser.Physics.Manager.metersToPixels(this.mins.x);
+ return Physics.AdvancedPhysics.metersToPixels(this.mins.x);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Bounds.prototype, "y", {
get: function () {
- return Phaser.Physics.Manager.metersToPixels(this.mins.y);
+ return Physics.AdvancedPhysics.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);
+ return Physics.AdvancedPhysics.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);
+ return Physics.AdvancedPhysics.metersToPixels(this.maxs.y - this.mins.y);
},
enumerable: true,
configurable: true
@@ -4929,7 +4745,7 @@ var Phaser;
(function (Phaser) {
///
///
- ///
+ ///
///
///
///
@@ -4941,7 +4757,7 @@ var Phaser;
(function (Physics) {
var Shape = (function () {
function Shape(type) {
- this.id = Phaser.Physics.Manager.shapeCounter++;
+ this.id = Physics.AdvancedPhysics.shapeCounter++;
this.type = type;
this.elasticity = 0.0;
this.friction = 1.0;
@@ -4962,7 +4778,7 @@ var Phaser;
(function (Phaser) {
///
///
- ///
+ ///
///
///
/**
@@ -4995,7 +4811,7 @@ var Phaser;
///
///
///
- ///
+ ///
///
///
///
@@ -5123,18 +4939,18 @@ var Phaser;
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);
+ Physics.AdvancedPhysics.write('solveVelocityConstraints. Body1: ' + body1.name + ' Body2: ' + body2.name);
+ Physics.AdvancedPhysics.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);
+ Physics.AdvancedPhysics.write('m1_inv: ' + m1_inv);
+ Physics.AdvancedPhysics.write('i1_inv: ' + i1_inv);
+ Physics.AdvancedPhysics.write('m2_inv: ' + m2_inv);
+ Physics.AdvancedPhysics.write('i2_inv: ' + i2_inv);
for(var i = 0; i < this.contacts.length; i++) {
- Physics.Manager.write('------------ solve con ' + i);
+ Physics.AdvancedPhysics.write('------------ solve con ' + i);
var con = this.contacts[i];
var n = con.normal;
var t = Phaser.Vec2Utils.perp(n);
@@ -5146,25 +4962,25 @@ var Phaser;
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());
+ Physics.AdvancedPhysics.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());
+ Physics.AdvancedPhysics.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());
+ Physics.AdvancedPhysics.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);
+ Physics.AdvancedPhysics.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);
+ Physics.AdvancedPhysics.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);
@@ -5177,7 +4993,7 @@ var Phaser;
// 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());
+ Physics.AdvancedPhysics.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;
@@ -5186,14 +5002,14 @@ var Phaser;
//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());
+ Physics.AdvancedPhysics.write('body1: ' + body1.toString());
+ Physics.AdvancedPhysics.write('body2: ' + body2.toString());
}
};
ContactSolver.prototype.solvePositionConstraints = function () {
var body1 = this.shape1.body;
var body2 = this.shape2.body;
- Physics.Manager.write('solvePositionConstraints');
+ Physics.AdvancedPhysics.write('solvePositionConstraints');
var m1_inv = body1.massInverted;
var i1_inv = body1.inertiaInverted;
var m2_inv = body2.massInverted;
@@ -5201,7 +5017,7 @@ var Phaser;
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);
+ Physics.AdvancedPhysics.write('------------- solvePositionConstraints ' + i);
var con = this.contacts[i];
var n = con.normal;
var r1 = new Phaser.Vec2();
@@ -5209,23 +5025,23 @@ var Phaser;
// Transformed r1, r2
Phaser.Vec2Utils.rotate(con.r1_local, body1.angle, r1);
Phaser.Vec2Utils.rotate(con.r2_local, body2.angle, r2);
- 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);
+ Physics.AdvancedPhysics.write('r1_local.x = ' + con.r1_local.x + ' r1_local.y = ' + con.r1_local.y + ' angle: ' + body1.angle);
+ Physics.AdvancedPhysics.write('r1 rotated: r1.x = ' + r1.x + ' r1.y = ' + r1.y);
+ Physics.AdvancedPhysics.write('r2_local.x = ' + con.r2_local.x + ' r2_local.y = ' + con.r2_local.y + ' angle: ' + body2.angle);
+ Physics.AdvancedPhysics.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);
Phaser.Vec2Utils.add(body2.position, r2, p2);
- 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.AdvancedPhysics.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ Physics.AdvancedPhysics.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);
// 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);
+ var correction = this.clamp(Physics.AdvancedPhysics.CONTACT_SOLVER_BAUMGARTE * (c + Physics.AdvancedPhysics.CONTACT_SOLVER_COLLISION_SLOP), -Physics.AdvancedPhysics.CONTACT_SOLVER_MAX_LINEAR_CORRECTION, 0);
if(correction == 0) {
continue;
}
@@ -5244,11 +5060,11 @@ var Phaser;
body1.angle -= sn1 * lambda_dt * i1_inv;
body2.position.multiplyAddByScalar(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.AdvancedPhysics.write('body1.pos.x=' + body1.position.x + ' y=' + body1.position.y);
+ Physics.AdvancedPhysics.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;
+ Physics.AdvancedPhysics.write('max_penetration: ' + max_penetration);
+ return max_penetration <= Physics.AdvancedPhysics.CONTACT_SOLVER_COLLISION_SLOP * 3;
};
ContactSolver.prototype.clamp = function (v, min, max) {
return v < min ? min : (v > max ? max : v);
@@ -5264,7 +5080,7 @@ var Phaser;
(function (Physics) {
///
///
- ///
+ ///
///
///
/**
@@ -5278,10 +5094,10 @@ var Phaser;
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);
+ _super.call(this, Physics.AdvancedPhysics.SHAPE_TYPE_CIRCLE);
+ x = Physics.AdvancedPhysics.pixelsToMeters(x);
+ y = Physics.AdvancedPhysics.pixelsToMeters(y);
+ radius = Physics.AdvancedPhysics.pixelsToMeters(radius);
this.center = new Phaser.Vec2(x, y);
this.radius = radius;
this.tc = new Phaser.Vec2();
@@ -5305,13 +5121,13 @@ var Phaser;
//this.center = xf.untransform(this.center);
};
Circle.prototype.area = function () {
- return Physics.Manager.areaForCircle(this.radius, 0);
+ return Physics.AdvancedPhysics.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);
+ return Physics.AdvancedPhysics.inertiaForCircle(mass, this.center, this.radius, 0);
};
Circle.prototype.cacheData = function (xf) {
Phaser.TransformUtils.transform(xf, this.center, this.tc);
@@ -5345,7 +5161,7 @@ var Phaser;
(function (Phaser) {
///
///
- ///
+ ///
///
/**
* Phaser - Advanced Physics - Plane
@@ -5369,7 +5185,7 @@ var Phaser;
(function (Physics) {
///
///
- ///
+ ///
///
///
///
@@ -5384,7 +5200,7 @@ var Phaser;
// 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);
+ _super.call(this, Physics.AdvancedPhysics.SHAPE_TYPE_POLY);
this.verts = [];
this.planes = [];
this.tverts = [];
@@ -5449,25 +5265,25 @@ var Phaser;
}
};
Poly.prototype.area = function () {
- return Physics.Manager.areaForPoly(this.verts);
+ return Physics.AdvancedPhysics.areaForPoly(this.verts);
};
Poly.prototype.centroid = function () {
- return Physics.Manager.centroidForPoly(this.verts);
+ return Physics.AdvancedPhysics.centroidForPoly(this.verts);
};
Poly.prototype.inertia = function (mass) {
- return Physics.Manager.inertiaForPoly(mass, this.verts, new Phaser.Vec2());
+ return Physics.AdvancedPhysics.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);
+ Physics.AdvancedPhysics.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());
+ Physics.AdvancedPhysics.write('tvert' + i + ' = ' + this.tverts[i].toString());
}
if(numVerts < 2) {
this.bounds.addPoint(this.tverts[0]);
@@ -5477,13 +5293,13 @@ var Phaser;
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());
+ Physics.AdvancedPhysics.write('a = ' + a.toString());
+ Physics.AdvancedPhysics.write('b = ' + b.toString());
+ Physics.AdvancedPhysics.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());
+ Physics.AdvancedPhysics.write('tplanes' + i + ' n = ' + this.tplanes[i].normal.toString());
+ Physics.AdvancedPhysics.write('tplanes' + i + ' d = ' + this.tplanes[i].d.toString());
this.bounds.addPoint(a);
}
};
@@ -5570,7 +5386,7 @@ var Phaser;
(function (Physics) {
///
///
- ///
+ ///
///
///
/**
@@ -5582,7 +5398,7 @@ var Phaser;
var Segment = (function (_super) {
__extends(Segment, _super);
function Segment(a, b, radius) {
- _super.call(this, Physics.Manager.SHAPE_TYPE_SEGMENT);
+ _super.call(this, Physics.AdvancedPhysics.SHAPE_TYPE_SEGMENT);
this.a = a.duplicate();
this.b = b.duplicate();
this.radius = radius;
@@ -5618,13 +5434,13 @@ var Phaser;
//this.b = xf.untransform(this.b);
};
Segment.prototype.area = function () {
- return Physics.Manager.areaForSegment(this.a, this.b, this.radius);
+ return Physics.AdvancedPhysics.areaForSegment(this.a, this.b, this.radius);
};
Segment.prototype.centroid = function () {
- return Physics.Manager.centroidForSegment(this.a, this.b);
+ return Physics.AdvancedPhysics.centroidForSegment(this.a, this.b);
};
Segment.prototype.inertia = function (mass) {
- return Physics.Manager.inertiaForSegment(mass, this.a, this.b);
+ return Physics.AdvancedPhysics.inertiaForSegment(mass, this.a, this.b);
};
Segment.prototype.cacheData = function (xf) {
Phaser.TransformUtils.transform(xf, this.a, this.ta);
@@ -5710,7 +5526,7 @@ var Phaser;
///
///
///
- ///
+ ///
///
///
/**
@@ -5723,32 +5539,32 @@ var Phaser;
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) {
+ if(a.type == Physics.AdvancedPhysics.SHAPE_TYPE_CIRCLE) {
+ if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_CIRCLE) {
return this.circle2Circle(a, b, contacts);
- } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ } else if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_SEGMENT) {
return this.circle2Segment(a, b, contacts);
- } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ } else if(b.type == Physics.AdvancedPhysics.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) {
+ if(a.type == Physics.AdvancedPhysics.SHAPE_TYPE_SEGMENT) {
+ if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_CIRCLE) {
return this.circle2Segment(b, a, contacts);
- } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ } else if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_SEGMENT) {
return this.segment2Segment(a, b, contacts);
- } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ } else if(b.type == Physics.AdvancedPhysics.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) {
+ if(a.type == Physics.AdvancedPhysics.SHAPE_TYPE_POLY) {
+ if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_CIRCLE) {
return this.circle2Poly(b, a, contacts);
- } else if(b.type == Physics.Manager.SHAPE_TYPE_SEGMENT) {
+ } else if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_SEGMENT) {
return this.segment2Poly(b, a, contacts);
- } else if(b.type == Physics.Manager.SHAPE_TYPE_POLY) {
+ } else if(b.type == Physics.AdvancedPhysics.SHAPE_TYPE_POLY) {
return this.poly2Poly(a, b, contacts);
}
}
@@ -6081,7 +5897,7 @@ var Phaser;
(function (Phaser) {
///
///
- ///
+ ///
///
///
///
@@ -6116,9 +5932,9 @@ var Phaser;
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;
+ Physics.AdvancedPhysics.shapeCounter = 0;
+ Physics.AdvancedPhysics.bodyCounter = 0;
+ Physics.AdvancedPhysics.jointCounter = 0;
for(var i = 0; i < this.bodies.length; i++) {
if(this.bodies[i]) {
this.removeBody(this.bodies[i]);
@@ -6295,7 +6111,7 @@ var Phaser;
}
for(var j = 0; j < body.shapes.length; j++) {
var shape = body.shapes[j];
- if(shape.type != Physics.Manager.SHAPE_TYPE_POLY) {
+ if(shape.type != Physics.AdvancedPhysics.SHAPE_TYPE_POLY) {
continue;
}
var index = shape.findEdgeByPoint(p, minDist);
@@ -6374,7 +6190,7 @@ var Phaser;
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)) {
+ if(!Physics.AdvancedPhysics.collision.collide(this._shape1, this._shape2, contactArr)) {
continue;
}
if(this._shape1.type > this._shape2.type) {
@@ -6578,10 +6394,279 @@ var Phaser;
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 AdvancedPhysics = (function () {
+ function AdvancedPhysics(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);
+ this.collision = new Physics.Collision();
+ }
+ AdvancedPhysics.clear = function clear() {
+ //Manager.debug.textContent = "";
+ Physics.Manager.log = [];
+ };
+ AdvancedPhysics.write = function write(s) {
+ //Manager.debug.textContent += s + "\n";
+ };
+ AdvancedPhysics.writeAll = function writeAll() {
+ for(var i = 0; i < Physics.Manager.log.length; i++) {
+ //Manager.debug.textContent += Manager.log[i];
+ }
+ };
+ AdvancedPhysics.log = [];
+ AdvancedPhysics.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);
+ */
+ };
+ AdvancedPhysics.SHAPE_TYPE_CIRCLE = 0;
+ AdvancedPhysics.SHAPE_TYPE_SEGMENT = 1;
+ AdvancedPhysics.SHAPE_TYPE_POLY = 2;
+ AdvancedPhysics.SHAPE_NUM_TYPES = 3;
+ AdvancedPhysics.JOINT_TYPE_ANGLE = 0;
+ AdvancedPhysics.JOINT_TYPE_REVOLUTE = 1;
+ AdvancedPhysics.JOINT_TYPE_WELD = 2;
+ AdvancedPhysics.JOINT_TYPE_WHEEL = 3;
+ AdvancedPhysics.JOINT_TYPE_PRISMATIC = 4;
+ AdvancedPhysics.JOINT_TYPE_DISTANCE = 5;
+ AdvancedPhysics.JOINT_TYPE_ROPE = 6;
+ AdvancedPhysics.JOINT_TYPE_MOUSE = 7;
+ AdvancedPhysics.JOINT_LINEAR_SLOP = 0.0008;
+ AdvancedPhysics.JOINT_ANGULAR_SLOP = 2 * 0.017453292519943294444444444444444;
+ AdvancedPhysics.JOINT_MAX_LINEAR_CORRECTION = 0.5;
+ AdvancedPhysics.JOINT_MAX_ANGULAR_CORRECTION = 8 * 0.017453292519943294444444444444444;
+ AdvancedPhysics.JOINT_LIMIT_STATE_INACTIVE = 0;
+ AdvancedPhysics.JOINT_LIMIT_STATE_AT_LOWER = 1;
+ AdvancedPhysics.JOINT_LIMIT_STATE_AT_UPPER = 2;
+ AdvancedPhysics.JOINT_LIMIT_STATE_EQUAL_LIMITS = 3;
+ AdvancedPhysics.CONTACT_SOLVER_COLLISION_SLOP = 0.0008;
+ AdvancedPhysics.CONTACT_SOLVER_BAUMGARTE = 0.28;
+ AdvancedPhysics.CONTACT_SOLVER_MAX_LINEAR_CORRECTION = 1;
+ AdvancedPhysics.bodyCounter = 0;
+ AdvancedPhysics.jointCounter = 0;
+ AdvancedPhysics.shapeCounter = 0;
+ AdvancedPhysics.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) {
+ Physics.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++;
+ };
+ AdvancedPhysics.prototype.addBody = function (body) {
+ this.space.addBody(body);
+ };
+ AdvancedPhysics.prototype.removeBody = function (body) {
+ this.space.removeBody(body);
+ };
+ AdvancedPhysics.prototype.addJoint = function (joint) {
+ this.space.addJoint(joint);
+ };
+ AdvancedPhysics.prototype.removeJoint = function (joint) {
+ this.space.removeJoint(joint);
+ };
+ AdvancedPhysics.prototype.pixelsToMeters = function (value) {
+ return value * 0.02;
+ };
+ AdvancedPhysics.prototype.metersToPixels = function (value) {
+ return value * 50;
+ };
+ AdvancedPhysics.pixelsToMeters = function pixelsToMeters(value) {
+ return value * 0.02;
+ };
+ AdvancedPhysics.metersToPixels = function metersToPixels(value) {
+ return value * 50;
+ };
+ AdvancedPhysics.p2m = function p2m(value) {
+ return value * 0.02;
+ };
+ AdvancedPhysics.m2p = function m2p(value) {
+ return value * 50;
+ };
+ AdvancedPhysics.areaForCircle = function areaForCircle(radius_outer, radius_inner) {
+ return Math.PI * (radius_outer * radius_outer - radius_inner * radius_inner);
+ };
+ AdvancedPhysics.inertiaForCircle = function inertiaForCircle(mass, center, radius_outer, radius_inner) {
+ return mass * ((radius_outer * radius_outer + radius_inner * radius_inner) * 0.5 + center.lengthSq());
+ };
+ AdvancedPhysics.areaForSegment = function areaForSegment(a, b, radius) {
+ return radius * (Math.PI * radius + 2 * Phaser.Vec2Utils.distance(a, b));
+ };
+ AdvancedPhysics.centroidForSegment = function centroidForSegment(a, b) {
+ return Phaser.Vec2Utils.scale(Phaser.Vec2Utils.add(a, b), 0.5);
+ };
+ AdvancedPhysics.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());
+ };
+ AdvancedPhysics.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;
+ };
+ AdvancedPhysics.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));
+ };
+ AdvancedPhysics.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);
+ };
+ AdvancedPhysics.inertiaForBox = function inertiaForBox(mass, w, h) {
+ return mass * (w * w + h * h) / 12;
+ };
+ AdvancedPhysics.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 AdvancedPhysics;
+ })();
+ Physics.AdvancedPhysics = AdvancedPhysics;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
+var Phaser;
(function (Phaser) {
(function (Physics) {
///
- ///
+ ///
///
///
///
@@ -6594,12 +6679,12 @@ var Phaser;
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);
+ x1 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x1);
+ y1 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y1);
+ x2 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x2);
+ y2 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y2);
+ x3 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x3);
+ y3 = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y3);
_super.call(this, [
{
x: x1,
@@ -6627,7 +6712,7 @@ var Phaser;
(function (Phaser) {
(function (Physics) {
///
- ///
+ ///
///
///
///
@@ -6642,10 +6727,10 @@ var Phaser;
// Give in pixels
function Box(x, y, width, height) {
console.log('Box px', x, y, width, height);
- x = Physics.Manager.pixelsToMeters(x);
- y = Physics.Manager.pixelsToMeters(y);
- width = Physics.Manager.pixelsToMeters(width);
- height = Physics.Manager.pixelsToMeters(height);
+ x = Phaser.Physics.AdvancedPhysics.pixelsToMeters(x);
+ y = Phaser.Physics.AdvancedPhysics.pixelsToMeters(y);
+ width = Phaser.Physics.AdvancedPhysics.pixelsToMeters(width);
+ height = Phaser.Physics.AdvancedPhysics.pixelsToMeters(height);
console.log('Box m', x, y, width, height);
var hw = width * 0.5;
var hh = height * 0.5;
@@ -6684,7 +6769,8 @@ var Phaser;
///
///
///
- ///
+ ///
+ ///
///
///
///
@@ -6717,16 +6803,16 @@ var Phaser;
this.maskBits = 0xFFFF;
this.stepCount = 0;
this._newPosition = new Phaser.Vec2();
- this.id = Phaser.Physics.Manager.bodyCounter++;
+ this.id = Phaser.Physics.AdvancedPhysics.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.Manager.pixelsToMeters(sprite.x), Phaser.Physics.Manager.pixelsToMeters(sprite.y));
+ this.position = new Phaser.Vec2(Phaser.Physics.AdvancedPhysics.pixelsToMeters(sprite.x), Phaser.Physics.AdvancedPhysics.pixelsToMeters(sprite.y));
this.angle = this.game.math.degreesToRadians(sprite.rotation);
} else {
- this.position = new Phaser.Vec2(Phaser.Physics.Manager.pixelsToMeters(x), Phaser.Physics.Manager.pixelsToMeters(y));
+ this.position = new Phaser.Vec2(Phaser.Physics.AdvancedPhysics.pixelsToMeters(x), Phaser.Physics.AdvancedPhysics.pixelsToMeters(y));
this.angle = 0;
}
this.transform = new Phaser.Transform(this.position, this.angle);
@@ -6750,9 +6836,9 @@ var Phaser;
this.stepCount = 0;
if(sprite) {
if(shapeType == 0) {
- this.addBox(0, 0, this.sprite.width, this.sprite.height, 1, 1, 1);
+ Phaser.BodyUtils.addBox(this, 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);
+ Phaser.BodyUtils.addCircle(this, Math.max(this.sprite.width, this.sprite.height) / 2, 0, 0, 1, 1, 1);
}
}
}
@@ -6773,16 +6859,6 @@ var Phaser;
enumerable: true,
configurable: true
});
- Body.prototype.duplicate = function () {
- console.log('body duplicate called');
- //var body = new Body(this.type, this.transform.t, this.rotation);
- //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;
@@ -6822,56 +6898,6 @@ var Phaser;
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.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;
@@ -6896,7 +6922,7 @@ var Phaser;
this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
};
Body.prototype.setPosition = function (x, y) {
- this._newPosition.setTo(this.game.physics.pixelsToMeters(x), this.game.physics.pixelsToMeters(y));
+ this._newPosition.setTo(Phaser.Physics.AdvancedPhysics.pixelsToMeters(x), Phaser.Physics.AdvancedPhysics.pixelsToMeters(y));
this.setTransform(this._newPosition, this.angle);
};
Body.prototype.setTransform = function (pos, angle) {
@@ -7237,10 +7263,10 @@ var Phaser;
}
}
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.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();
@@ -7250,6 +7276,7 @@ var Phaser;
this.scale = this.transform.scale;
this.alpha = this.texture.alpha;
this.origin = this.transform.origin;
+ this.crop = this.texture.crop;
}
Object.defineProperty(Sprite.prototype, "rotation", {
get: /**
@@ -7271,6 +7298,14 @@ var Phaser;
enumerable: true,
configurable: true
});
+ Sprite.prototype.bringToTop = /**
+ * Brings this Sprite to the top of its current Group, if set.
+ */
+ function () {
+ if(this.group) {
+ this.group.bringToTop(this);
+ }
+ };
Object.defineProperty(Sprite.prototype, "alpha", {
get: /**
* The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque.
@@ -7924,7 +7959,7 @@ var Phaser;
};
Group.prototype.destroy = /**
* Override this function to handle any deleting or "shutdown" type operations you might need,
- * such as removing traditional Flash children like Basic objects.
+ * such as removing traditional children like Basic objects.
*/
function () {
if(this.members != null) {
@@ -8103,13 +8138,13 @@ var Phaser;
* @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 [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)
* @returns {Sprite} The newly created sprite object.
*/
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.add(new Phaser.Sprite(this.game, x, y, key, frame, bodyType));
};
Group.prototype.setObjectIDs = /**
@@ -8189,7 +8224,7 @@ var Phaser;
*/
function (object, splice) {
if (typeof splice === "undefined") { splice = false; }
- console.log('removing from group');
+ //console.log('removing from group: ', object.name);
this._i = this.members.indexOf(object);
if(this._i < 0 || (this._i >= this.members.length)) {
return null;
@@ -8200,7 +8235,7 @@ var Phaser;
} else {
this.members[this._i] = null;
}
- console.log('nulled');
+ //console.log('nulled');
if(object['events']) {
object['events'].onRemovedFromGroup.dispatch(object, this);
}
@@ -8342,6 +8377,10 @@ var Phaser;
* @return {number} An integer value: -1 (Obj1 before Obj2), 0 (same), or 1 (Obj1 after Obj2).
*/
function (obj1, obj2) {
+ if(!obj1 || !obj2) {
+ //console.log('null objects in sort', obj1, obj2);
+ return 0;
+ }
if(obj1[this._sortIndex] < obj2[this._sortIndex]) {
return this._sortOrder;
} else if(obj1[this._sortIndex] > obj2[this._sortIndex]) {
@@ -14135,6 +14174,16 @@ var Phaser;
function (sprite) {
return this._world.group.add(sprite);
};
+ GameObjectFactory.prototype.existingGroup = /**
+ * Add an existing Group to the current world.
+ * Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
+ *
+ * @param group The Group to add to the Game World
+ * @return {Phaser.Group} The Group object
+ */
+ function (group) {
+ return this._world.group.add(group);
+ };
GameObjectFactory.prototype.existingButton = /**
* Add an existing Button to the current world.
* Note: This doesn't check or update the objects reference to Game. If that is wrong, all kinds of things will break.
@@ -14280,8 +14329,8 @@ var Phaser;
if(key == this.key) {
this._sound = this.game.cache.getSoundData(this.key);
this.totalDuration = this._sound.duration;
- console.log('sound has unlocked', this._sound);
- }
+ //console.log('sound has unlocked', this._sound);
+ }
};
Object.defineProperty(Sound.prototype, "isDecoding", {
get: function () {
@@ -14320,22 +14369,22 @@ var Phaser;
if(this.isPlaying) {
this.currentTime = this.game.time.now - this.startTime;
if(this.currentTime >= this.duration) {
- console.log(this.currentMarker, 'has hit duration');
+ //console.log(this.currentMarker, 'has hit duration');
if(this.usingWebAudio) {
if(this.loop) {
- console.log('loop1');
+ //console.log('loop1');
// won't work with markers, needs to reset the position
this.onLoop.dispatch(this);
if(this.currentMarker == '') {
- console.log('loop2');
+ //console.log('loop2');
this.currentTime = 0;
this.startTime = this.game.time.now;
} else {
- console.log('loop3');
+ //console.log('loop3');
this.play(this.currentMarker, 0, this.volume, true, true);
}
} else {
- console.log('stopping, no loop for marker');
+ //console.log('stopping, no loop for marker');
this.stop();
}
} else {
@@ -14362,13 +14411,13 @@ var Phaser;
if (typeof volume === "undefined") { volume = 1; }
if (typeof loop === "undefined") { loop = false; }
if (typeof forceRestart === "undefined") { forceRestart = false; }
- console.log('play', marker, 'current is', this.currentMarker);
+ //console.log('play', marker, 'current is', this.currentMarker);
if(this.isPlaying == true && forceRestart == false && this.override == false) {
// Use Restart instead
return;
}
if(this.isPlaying && this.override) {
- console.log('asked to play', marker, 'but already playing', this.currentMarker);
+ //console.log('asked to play', marker, 'but already playing', this.currentMarker);
if(this.usingWebAudio) {
if(typeof this._sound.stop === 'undefined') {
this._sound.noteOff(0);
@@ -14386,7 +14435,7 @@ var Phaser;
this.volume = this.markers[marker].volume;
this.loop = this.markers[marker].loop;
this.duration = this.markers[marker].duration * 1000;
- console.log('marker info loaded', this.loop, this.duration);
+ //console.log('marker info loaded', this.loop, this.duration);
this._tempMarker = marker;
this._tempPosition = this.position;
this._tempVolume = this.volume;
@@ -14433,8 +14482,8 @@ var Phaser;
this.currentTime = 0;
this.stopTime = this.startTime + this.duration;
this.onPlay.dispatch(this);
- console.log('playing, start', this.startTime, 'stop');
- } else {
+ //console.log('playing, start', this.startTime, 'stop');
+ } else {
this.pendingPlayback = true;
if(this.game.cache.getSound(this.key) && this.game.cache.getSound(this.key).isDecoding == false) {
this.game.sound.decode(this.key, this);
@@ -14509,7 +14558,7 @@ var Phaser;
* Stop playing this sound.
*/
function () {
- console.log('Sound.stop', this.currentMarker);
+ //console.log('Sound.stop', this.currentMarker);
if(this.isPlaying && this._sound) {
if(this.usingWebAudio) {
if(typeof this._sound.stop === 'undefined') {
@@ -15683,6 +15732,11 @@ var Phaser;
* @type {boolean}
*/
this.disableBootScreen = false;
+ /**
+ * If set to true the game will never pause when the browser or browser tab loses focuses
+ * @type {boolean}
+ */
+ this.disableVisibilityChange = false;
this._game = game;
this.canvas = document.createElement('canvas');
this.canvas.width = width;
@@ -15769,6 +15823,9 @@ var Phaser;
* This method is called when the canvas elements visibility is changed.
*/
function (event) {
+ if(this.disableVisibilityChange) {
+ return;
+ }
if(event.type == 'pagehide' || event.type == 'blur' || document['hidden'] == true || document['webkitHidden'] == true) {
if(this._game.paused == false) {
this.pauseGame();
@@ -16167,6 +16224,73 @@ var Phaser;
})();
Phaser.TweenManager = TweenManager;
})(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.game = game;
+ }
+ 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.prototype.update = function () {
+ };
+ return Manager;
+ })();
+ Physics.Manager = Manager;
+ })(Phaser.Physics || (Phaser.Physics = {}));
+ var Physics = Phaser.Physics;
+})(Phaser || (Phaser = {}));
///
///
///
@@ -17621,7 +17745,9 @@ var Phaser;
//this.game.input.y = this.y * this.game.input.scale.y;
this.game.input.x = this.x;
this.game.input.y = this.y;
+ this.game.input.position.setTo(this.x, this.y);
this.game.input.onDown.dispatch(this);
+ this.game.input.resetSpeed(this.x, this.y);
}
this._stateReset = false;
this.totalTouches++;
@@ -18934,6 +19060,10 @@ var Phaser;
this.totalTrackedObjects = 0;
}
};
+ Input.prototype.resetSpeed = function (x, y) {
+ this._oldPosition.setTo(x, y);
+ this.speed.setTo(0, 0);
+ };
Object.defineProperty(Input.prototype, "totalInactivePointers", {
get: /**
* Get the total number of inactive Pointers
@@ -19613,6 +19743,16 @@ var Phaser;
this._dx -= (this._dw * sprite.transform.origin.x);
this._dy -= (this._dh * sprite.transform.origin.y);
}
+ if(sprite.crop) {
+ this._sx += sprite.crop.x * sprite.transform.scale.x;
+ this._sy += sprite.crop.y * sprite.transform.scale.y;
+ this._sw = sprite.crop.width * sprite.transform.scale.x;
+ this._sh = sprite.crop.height * sprite.transform.scale.y;
+ this._dx += sprite.crop.x * sprite.transform.scale.x;
+ this._dy += sprite.crop.y * sprite.transform.scale.y;
+ this._dw = sprite.crop.width * sprite.transform.scale.x;
+ this._dh = sprite.crop.height * sprite.transform.scale.y;
+ }
this._sx = Math.round(this._sx);
this._sy = Math.round(this._sy);
this._sw = Math.round(this._sw);
@@ -19870,13 +20010,31 @@ var Phaser;
DebugUtils.context.fillStyle = fillStyle;
DebugUtils.context.fillRect(rect.x, rect.y, rect.width, rect.height);
};
+ DebugUtils.renderCircle = function renderCircle(circle, fillStyle) {
+ if (typeof fillStyle === "undefined") { fillStyle = 'rgba(0,255,0,0.3)'; }
+ DebugUtils.context.fillStyle = fillStyle;
+ DebugUtils.context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2, false);
+ DebugUtils.context.fill();
+ };
+ DebugUtils.renderText = /**
+ * Render text
+ * @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 renderText(text, x, y, color) {
+ if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
+ DebugUtils.context.font = '16px Courier';
+ DebugUtils.context.fillStyle = color;
+ DebugUtils.context.fillText(text, x, y);
+ };
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.shapesLength; s++) {
DebugUtils.context.beginPath();
- if(body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_POLY) {
+ if(body.shapes[s].type == Phaser.Physics.AdvancedPhysics.SHAPE_TYPE_POLY) {
var verts = body.shapes[s].tverts;
// DebugUtils.context.moveTo(body.position.x * 50 + verts[0].x, body.position.y * 50 + verts[0].y);
DebugUtils.context.moveTo(verts[0].x * 50, verts[0].y * 50);
@@ -19886,7 +20044,7 @@ var Phaser;
}
// DebugUtils.context.lineTo(body.position.x * 50 + verts[0].x, body.position.y * 50 + verts[0].y);
DebugUtils.context.lineTo(verts[0].x * 50, verts[0].y * 50);
- } else if(body.shapes[s].type == Phaser.Physics.Manager.SHAPE_TYPE_CIRCLE) {
+ } else if(body.shapes[s].type == Phaser.Physics.AdvancedPhysics.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);
}
@@ -20760,15 +20918,10 @@ var Phaser;
function contains(a, x, y) {
// Check if x/y are within the bounds first
if(x >= a.left && x <= a.right && y >= a.top && y <= a.bottom) {
- var dx = a.x - x;
- var dy = a.y - y;
- dx *= dx;
- dy *= dy;
- var radSqr = a.radius * a.radius;
- console.log('within bounds', dx, dy, radSqr);
- return (dx + dy) <= radSqr;
- //return (a.left * a.left + a.top * a.top) <= (a.radius * a.radius);
- }
+ var dx = (a.x - x) * (a.x - x);
+ var dy = (a.y - y) * (a.y - y);
+ return (dx + dy) <= (a.radius * a.radius);
+ }
return false;
};
CircleUtils.containsPoint = /**
@@ -21050,6 +21203,957 @@ var Phaser;
})();
Phaser.Mat3Utils = Mat3Utils;
})(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 + 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 + 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 = {}));
///
///
///