diff --git a/Phaser/components/animation/FrameData.ts b/Phaser/components/animation/FrameData.ts index e54c8a7e..5594fe12 100644 --- a/Phaser/components/animation/FrameData.ts +++ b/Phaser/components/animation/FrameData.ts @@ -93,12 +93,13 @@ module Phaser { */ public checkFrameName(name: string): bool { - if (this._frameNames[name]) + + if (this._frameNames[name] == null) { - return true; + return false; } - return false; + return true; } diff --git a/Phaser/components/sprite/Input.ts b/Phaser/components/sprite/Input.ts index 16d87575..c6e0a0b9 100644 --- a/Phaser/components/sprite/Input.ts +++ b/Phaser/components/sprite/Input.ts @@ -263,6 +263,7 @@ module Phaser.Components.Sprite { if (this.enabled) { + this.enabled = false; this.game.input.removeGameObject(this.indexID); } @@ -578,7 +579,9 @@ module Phaser.Components.Sprite { if (this.dragFromCenter) { // Move the sprite to the middle of the pointer - this._dragPoint.setTo(-this.sprite.worldView.halfWidth, -this.sprite.worldView.halfHeight); + //this._dragPoint.setTo(-this.sprite.worldView.halfWidth, -this.sprite.worldView.halfHeight); + //this._dragPoint.setTo(this.sprite.transform.center.x, this.sprite.transform.center.y); + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); } else { diff --git a/Phaser/core/Group.ts b/Phaser/core/Group.ts index 252962bb..8d1633ce 100644 --- a/Phaser/core/Group.ts +++ b/Phaser/core/Group.ts @@ -527,6 +527,8 @@ module Phaser { */ public remove(object, splice: bool = false) { + console.log('removing from group'); + this._i = this.members.indexOf(object); if (this._i < 0 || (this._i >= this.members.length)) @@ -544,6 +546,8 @@ module Phaser { this.members[this._i] = null; } + console.log('nulled'); + if (object['events']) { object['events'].onRemovedFromGroup.dispatch(object, this); @@ -615,7 +619,7 @@ module Phaser { public bringToTop(child): bool { // If child not in this group, or is already at the top of the group, return false - if (child.group.ID != this.ID || child.z == this._zCounter) + if (!child || child.group == null || child.group.ID != this.ID || child.z == this._zCounter) { return false; } diff --git a/Phaser/gameobjects/Tilemap.ts b/Phaser/gameobjects/Tilemap.ts index f7d2bc4c..14408fb6 100644 --- a/Phaser/gameobjects/Tilemap.ts +++ b/Phaser/gameobjects/Tilemap.ts @@ -229,6 +229,12 @@ module Phaser { { var layer: TilemapLayer = new TilemapLayer(this.game, this, key, Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight); + // Check it's a data layer + if (!json.layers[i].data) + { + continue; + } + layer.alpha = json.layers[i].opacity; layer.visible = json.layers[i].visible; layer.tileMargin = json.tilesets[0].margin; diff --git a/Phaser/input/Input.ts b/Phaser/input/Input.ts index 26231fee..6702aad9 100644 --- a/Phaser/input/Input.ts +++ b/Phaser/input/Input.ts @@ -507,6 +507,7 @@ module Phaser { if (this.inputObjects[index]) { + console.log('object removed from the input manager', index); this.inputObjects[index] = null; } diff --git a/Phaser/physics/advanced/Body.ts b/Phaser/physics/advanced/Body.ts index 0de64724..41bd828a 100644 --- a/Phaser/physics/advanced/Body.ts +++ b/Phaser/physics/advanced/Body.ts @@ -143,6 +143,9 @@ module Phaser.Physics.Advanced { // Shapes public shapes: IShape[] = []; + // Length of the shapes array + public shapesLength: number; + // Joints public joints: IJoint[] = []; public jointHash = {}; @@ -163,7 +166,7 @@ module Phaser.Physics.Advanced { public duplicate() { - //console.log('body duplicate called'); + console.log('body duplicate called'); //var body = new Body(this.type, this.transform.t, this.angle); @@ -274,6 +277,8 @@ module Phaser.Physics.Advanced { this.shapes.push(shape); + this.shapesLength = this.shapes.length; + return shape; } @@ -288,8 +293,9 @@ module Phaser.Physics.Advanced { shape.body = undefined; } - } + this.shapesLength = this.shapes.length; + } private setMass(mass) { @@ -307,8 +313,8 @@ module Phaser.Physics.Advanced { public setTransform(pos, angle) { - this.transform.setTo(pos, angle); // inject the transform into this.position + this.transform.setTo(pos, angle); Manager.write('setTransform: ' + this.position.toString()); Manager.write('centroid: ' + this.centroid.toString()); Phaser.TransformUtils.transform(this.transform, this.centroid, this.position); @@ -399,20 +405,14 @@ module Phaser.Physics.Advanced { if (!this.fixedRotation) { - //this.setInertia(totalInertia - totalMass * vec2.dot(this.centroid, this.centroid)); this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid)); } - //console.log("mass = " + this.m + " inertia = " + this.i); - // Move center of mass var oldPosition: Phaser.Vec2 = Phaser.Vec2Utils.clone(this.position); - //this.position.copyFrom(this.transform.transform(this.centroid)); Phaser.TransformUtils.transform(this.transform, this.centroid, this.position); // Update center of mass velocity - - //this.velocity.mad(vec2.perp(vec2.sub(this.position, old_p)), this.angularVelocity); oldPosition.subtract(this.position); this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity); @@ -462,7 +462,6 @@ module Phaser.Physics.Advanced { public updateVelocity(gravity, dt, damping) { - // this.velocity = vec2.mad(this.velocity, vec2.mad(gravity, this.force, this.massInverted), dt); Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2); Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity); @@ -513,17 +512,10 @@ module Phaser.Physics.Advanced { return v < min ? min : (v > max ? max : v); } - public updatePosition(dt) { + public updatePosition(dt:number) { - //console.log('body update pos', this.position.y); - //console.log('pre add temp', this._tempVec2.y); - - //this.position.addself(vec2.scale(this.velocity, dt)); this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2)); - //console.log('post add temp', this._tempVec2.y); - //console.log('post add', this.position.y); - this.angle += this.angularVelocity * dt; } @@ -547,10 +539,8 @@ module Phaser.Physics.Advanced { this.force.add(force); - // this.f.addself(force); - // this.torque += vec2.cross(vec2.sub(p, this.p), force); - Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2); + this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force); } @@ -601,8 +591,6 @@ module Phaser.Physics.Advanced { this.velocity.multiplyAddByScalar(impulse, this.massInverted); - // this.angularVelocity += vec2.cross(vec2.sub(p, this.position), impulse) * this.inertiaInverted; - Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2); this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted; diff --git a/Phaser/physics/advanced/Manager.ts b/Phaser/physics/advanced/Manager.ts index f7b3a6d0..7fa322d8 100644 --- a/Phaser/physics/advanced/Manager.ts +++ b/Phaser/physics/advanced/Manager.ts @@ -36,7 +36,7 @@ module Phaser.Physics.Advanced { } public static write(s: string) { - //Manager.debug.textContent += s + "\n"; + Manager.debug.textContent += s + "\n"; } public static writeAll() { @@ -119,10 +119,10 @@ module Phaser.Physics.Advanced { public lastTime: number = Date.now(); public frameRateHz: number = 60; public timeDelta: number = 0; - public paused: bool = false; - public step: bool = false; // step through the simulation (i.e. per click) - //public paused: bool = true; + //public paused: bool = false; //public step: bool = false; // step through the simulation (i.e. per click) + public paused: bool = true; + public step: bool = false; // step through the simulation (i.e. per click) public velocityIterations: number = 8; public positionIterations: number = 4; //public velocityIterations: number = 1; @@ -170,12 +170,6 @@ module Phaser.Physics.Advanced { { this.timeDelta = 0; } - - //if (sceneIndex < demoArr.length) - //{ - // demo = demoArr[sceneIndex]; - // demo.runFrame(); - //} } //frameCount++; diff --git a/Phaser/physics/advanced/Space.ts b/Phaser/physics/advanced/Space.ts index a83f17be..4eecf70e 100644 --- a/Phaser/physics/advanced/Space.ts +++ b/Phaser/physics/advanced/Space.ts @@ -20,33 +20,61 @@ module Phaser.Physics.Advanced { constructor() { - this.bodyArr = []; + this.bodies = []; this.bodyHash = {}; - this.jointArr = []; + this.joints = []; this.jointHash = {}; this.numContacts = 0; this.contactSolvers = []; - //this.postSolve(arb) { }; - this.gravity = new Phaser.Vec2(0, 10); this.damping = 0; + this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE; + this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE; + } + // Delta Timer + private _delta: number; + private _deltaInv: number; + + // Body array length + private _bl: number; + + // Joints array length + private _jl: number; + + // Contact Solvers array length + private _cl: number; + + private _linTolSqr: number; + private _angTolSqr: number; + + // Minimum sleep time (used in the sleep process solver) + private _minSleepTime: number; + + private _positionSolved: bool; + + private _shape1: IShape; + private _shape2: IShape; + private _contactsOk: bool; + private _jointsOk: bool; + + private bodyHash; + private jointHash; + public static TIME_TO_SLEEP = 0.5; public static SLEEP_LINEAR_TOLERANCE = 0.5; public static SLEEP_ANGULAR_TOLERANCE = 2 * Phaser.GameMath.DEG_TO_RAD; - public bodyArr: Body[]; - public bodyHash; - public jointArr: IJoint[]; - public jointHash; + public bodies: Body[]; + public joints: IJoint[]; public numContacts: number; public contactSolvers: ContactSolver[]; - public postSolve; + public postSolve = null; public gravity: Phaser.Vec2; public damping: number; public stepCount: number = 0; @@ -57,18 +85,18 @@ module Phaser.Physics.Advanced { Manager.bodyCounter = 0; Manager.jointCounter = 0; - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this.bodies.length; i++) { - if (this.bodyArr[i]) + if (this.bodies[i]) { - this.removeBody(this.bodyArr[i]); + this.removeBody(this.bodies[i]); } } - this.bodyArr = []; + this.bodies = []; this.bodyHash = {}; - this.jointArr = []; + this.joints = []; this.jointHash = {}; this.contactSolvers = []; @@ -84,7 +112,7 @@ module Phaser.Physics.Advanced { return; } - var index = this.bodyArr.push(body) - 1; + var index = this.bodies.push(body) - 1; this.bodyHash[body.id] = index; body.awake(true); @@ -100,7 +128,7 @@ module Phaser.Physics.Advanced { return; } - // Remove linked joint + // Remove linked joints for (var i = 0; i < body.joints.length; i++) { if (body.joints[i]) @@ -113,7 +141,7 @@ module Phaser.Physics.Advanced { var index = this.bodyHash[body.id]; delete this.bodyHash[body.id]; - delete this.bodyArr[index]; + delete this.bodies[index]; } @@ -127,7 +155,7 @@ module Phaser.Physics.Advanced { joint.body1.awake(true); joint.body2.awake(true); - var index = this.jointArr.push(joint) - 1; + var index = this.joints.push(joint) - 1; this.jointHash[joint.id] = index; var index = joint.body1.joints.push(joint) - 1; @@ -158,7 +186,7 @@ module Phaser.Physics.Advanced { var index = this.jointHash[joint.id]; delete this.jointHash[joint.id]; - delete this.jointArr[index]; + delete this.joints[index]; } @@ -166,9 +194,9 @@ module Phaser.Physics.Advanced { var firstShape; - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this.bodies.length; i++) { - var body = this.bodyArr[i]; + var body = this.bodies[i]; if (!body) { @@ -206,9 +234,9 @@ module Phaser.Physics.Advanced { var firstBody; - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this.bodies.length; i++) { - var body = this.bodyArr[i]; + var body = this.bodies[i]; if (!body) { @@ -245,14 +273,14 @@ module Phaser.Physics.Advanced { } - // TODO: Replace this function to shape hashing public shapeById(id) { var shape; - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this.bodies.length; i++) { - var body = this.bodyArr[i]; + var body: Body = this.bodies[i]; + if (!body) { continue; @@ -276,7 +304,7 @@ module Phaser.Physics.Advanced { if (index != undefined) { - return this.jointArr[index]; + return this.joints[index]; } return null; @@ -288,9 +316,9 @@ module Phaser.Physics.Advanced { refVertexId = refVertexId || -1; - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this.bodies.length; i++) { - var body = this.bodyArr[i]; + var body = this.bodies[i]; if (!body) { @@ -334,9 +362,9 @@ module Phaser.Physics.Advanced { refEdgeId = refEdgeId || -1; - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this.bodies.length; i++) { - var body = this.bodyArr[i]; + var body = this.bodies[i]; if (!body) { @@ -387,9 +415,9 @@ module Phaser.Physics.Advanced { refJointId = refJointId || -1; - for (var i = 0; i < this.jointArr.length; i++) + for (var i = 0; i < this.joints.length; i++) { - var joint = this.jointArr[i]; + var joint = this.joints[i]; if (!joint) { @@ -429,13 +457,13 @@ module Phaser.Physics.Advanced { return firstJointId; } - public findContactSolver(shape1, shape2) { + private findContactSolver(shape1:IShape, shape2:IShape):ContactSolver { - Manager.write('findContactSolver. Length: ' + this.contactSolvers.length); + Manager.write('findContactSolver. Length: ' + this._cl); - for (var i = 0; i < this.contactSolvers.length; i++) + for (var i = 0; i < this._cl; i++) { - var contactSolver = this.contactSolvers[i]; + var contactSolver: ContactSolver = this.contactSolvers[i]; if (shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) { @@ -444,363 +472,346 @@ module Phaser.Physics.Advanced { } return null; + } - public genTemporalContactSolvers() { + private genTemporalContactSolvers() { Manager.write('genTemporalContactSolvers'); - var newContactSolverArr = []; - var bl: number = this.bodyArr.length; - + this._cl = 0; + this.contactSolvers.length = 0; this.numContacts = 0; - for (var body1_index = 0; body1_index < bl; body1_index++) + for (var body1Index = 0; body1Index < this._bl; body1Index++) { - var body1: Body = this.bodyArr[body1_index]; - - if (!body1) + if (!this.bodies[body1Index]) { continue; } - body1.stepCount = this.stepCount; + this.bodies[body1Index].stepCount = this.stepCount; - for (var body2_index = 0; body2_index < bl; body2_index++) + for (var body2Index = 0; body2Index < this._bl; body2Index++) { - var body2: Body = this.bodyArr[body2_index]; - - if (body1.inContact(body2) == false) + if (this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) { continue; } Manager.write('body1 and body2 intersect'); - for (var i = 0; i < body1.shapes.length; i++) + for (var i = 0; i < this.bodies[body1Index].shapesLength; i++) { - for (var j = 0; j < body2.shapes.length; j++) + for (var j = 0; j < this.bodies[body2Index].shapesLength; j++) { - var shape1 = body1.shapes[i]; - var shape2 = body2.shapes[j]; + this._shape1 = this.bodies[body1Index].shapes[i]; + this._shape2 = this.bodies[body2Index].shapes[j]; var contactArr = []; - if (!Manager.collision.collide(shape1, shape2, contactArr)) + if (!Manager.collision.collide(this._shape1, this._shape2, contactArr)) { continue; } - if (shape1.type > shape2.type) + if (this._shape1.type > this._shape2.type) { - var temp = shape1; - shape1 = shape2; - shape2 = temp; + var temp = this._shape1; + this._shape1 = this._shape2; + this._shape2 = temp; } this.numContacts += contactArr.length; - var contactSolver = this.findContactSolver(shape1, shape2); + // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers) + var contactSolver: ContactSolver = this.findContactSolver(this._shape1, this._shape2); Manager.write('findContactSolver result: ' + contactSolver); if (contactSolver) { contactSolver.update(contactArr); - newContactSolverArr.push(contactSolver); + this.contactSolvers.push(contactSolver); } else { Manager.write('awake both bodies'); - body1.awake(true); - body2.awake(true); + this.bodies[body1Index].awake(true); + this.bodies[body2Index].awake(true); - var newContactSolver = new ContactSolver(shape1, shape2); + var newContactSolver = new ContactSolver(this._shape1, this._shape2); newContactSolver.contacts = contactArr; - newContactSolver.elasticity = Math.max(shape1.elasticity, shape2.elasticity); - newContactSolver.friction = Math.sqrt(shape1.friction * shape2.friction); - newContactSolverArr.push(newContactSolver); + newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity); + newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction); + + this.contactSolvers.push(newContactSolver); Manager.write('new contact solver'); - //console.log(newContactSolver); } } } } } - return newContactSolverArr; + this._cl = this.contactSolvers.length; } - public initSolver(dt, dt_inv, warmStarting) { + private initSolver(warmStarting) { Manager.write('initSolver'); - Manager.write('contactSolvers.length: ' + this.contactSolvers.length); - - //var t0 = Date.now(); + Manager.write('contactSolvers.length: ' + this._cl); // Initialize contact solvers - for (var i = 0; i < this.contactSolvers.length; i++) + for (var c = 0; c < this._cl; c++) { - this.contactSolvers[i].initSolver(dt_inv); + this.contactSolvers[c].initSolver(this._deltaInv); + + // Warm starting (apply cached impulse) + if (warmStarting) + { + this.contactSolvers[c].warmStart(); + } + } // Initialize joint solver - for (var i = 0; i < this.jointArr.length; i++) + for (var j = 0; j < this.joints.length; j++) { - if (this.jointArr[i]) + if (this.joints[j]) { - this.jointArr[i].initSolver(dt, warmStarting); + this.joints[j].initSolver(this._delta, warmStarting); } } // Warm starting (apply cached impulse) + /* if (warmStarting) { - for (var i = 0; i < this.contactSolvers.length; i++) + for (var c = 0; c < this._cl; c++) { - this.contactSolvers[i].warmStart(); + this.contactSolvers[c].warmStart(); } } + */ - //stats.timeInitSolver = Date.now() - t0; } - public velocitySolver(iteration) { + private velocitySolver(iterations:number) { - Manager.write('velocitySolver, iterations: ' + iteration + ' csa len: ' + this.contactSolvers.length); + Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl); - //var t0 = Date.now(); - - for (var i = 0; i < iteration; i++) + for (var i = 0; i < iterations; i++) { - for (var j = 0; j < this.jointArr.length; j++) + for (var j = 0; j < this._jl; j++) { - if (this.jointArr[j]) + if (this.joints[j]) { - this.jointArr[j].solveVelocityConstraints(); + this.joints[j].solveVelocityConstraints(); } } - for (var j = 0; j < this.contactSolvers.length; j++) + for (var c = 0; c < this._cl; c++) { - this.contactSolvers[j].solveVelocityConstraints(); + this.contactSolvers[c].solveVelocityConstraints(); } } } - public positionSolver(iteration) { + private positionSolver(iterations:number):bool { - var positionSolved = false; + this._positionSolved = false; - for (var i = 0; i < iteration; i++) + for (var i = 0; i < iterations; i++) { - var contactsOk = true; - var jointsOk = true; + this._contactsOk = true; + this._jointsOk = true; - for (var j = 0; j < this.contactSolvers.length; j++) + for (var c = 0; c < this._cl; c++) { - var contactOk = this.contactSolvers[j].solvePositionConstraints(); - contactsOk = contactOk && contactsOk; + this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk; } - for (var j = 0; j < this.jointArr.length; j++) + for (var j = 0; j < this._jl; j++) { - if (this.jointArr[j]) + if (this.joints[j]) { - var jointOk = this.jointArr[j].solvePositionConstraints(); - jointsOk = jointOk && jointsOk; + this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk; } } - if (contactsOk && jointsOk) + if (this._contactsOk && this._jointsOk) { // exit early if the position errors are small - positionSolved = true; + this._positionSolved = true; break; } } - return positionSolved; + return this._positionSolved; } - - - public step(dt, vel_iteration, pos_iteration, warmStarting, allowSleep) { + // Step through the physics simulation + public step(dt: number, velocityIterations: number, positionIterations: number, warmStarting: bool, allowSleep: bool) { Manager.clear(); Manager.write('Space step ' + this.stepCount); - var dt_inv: number = 1 / dt; - var bl: number = this.bodyArr.length; - var jl: number = this.jointArr.length; + this._delta = dt; + this._deltaInv = 1 / dt; + this._bl = this.bodies.length; + this._jl = this.joints.length; this.stepCount++; - // 1) Generate Contact Solvers - this.contactSolvers = this.genTemporalContactSolvers(); + // 1) Generate Contact Solvers (into the this.contactSolvers array) + this.genTemporalContactSolvers(); - Manager.dump("Contact Solvers", this.bodyArr[1]); + Manager.dump("Contact Solvers", this.bodies[1]); // 2) Initialize the Contact Solvers - this.initSolver(dt, dt_inv, warmStarting); + this.initSolver(warmStarting); - Manager.dump("Init Solver", this.bodyArr[1]); + Manager.dump("Init Solver", this.bodies[1]); // 3) Intergrate velocity - for (var i = 0; i < bl; i++) + for (var i = 0; i < this._bl; i++) { - if (this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) + if (this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { - this.bodyArr[i].updateVelocity(this.gravity, dt, this.damping); + this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping); } } - Manager.dump("Update Velocity", this.bodyArr[1]); + Manager.dump("Update Velocity", this.bodies[1]); - /* - // 4) Awaken bodies - for (var j = 0; i < jl; j++) + // 4) Awaken bodies via joints + for (var j = 0; i < this._jl; j++) { - var joint = this.jointArr[j]; - - if (!joint) + if (!this.joints[j]) { continue; } - var body1 = joint.body1; - var body2 = joint.body2; - - var awake1 = body1.isAwake && !body1.isStatic; - var awake2 = body2.isAwake && !body2.isStatic; + // combine + var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic; + var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic; if (awake1 ^ awake2) { if (!awake1) { - body1.awake(true); + this.joints[j].body1.awake(true); } - + if (!awake2) { - body2.awake(true); + this.joints[j].body2.awake(true); } } } - */ // 5) Iterative velocity constraints solver - this.velocitySolver(vel_iteration); + this.velocitySolver(velocityIterations); - Manager.dump("Velocity Solvers", this.bodyArr[1]); + Manager.dump("Velocity Solvers", this.bodies[1]); // 6) Intergrate position - for (var i = 0; i < bl; i++) + for (var i = 0; i < this._bl; i++) { - if (this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) + if (this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { - this.bodyArr[i].updatePosition(dt); + this.bodies[i].updatePosition(this._delta); } } - Manager.dump("Update Position", this.bodyArr[1]); + Manager.dump("Update Position", this.bodies[1]); // 7) Process breakable joint - for (var i = 0; i < jl; i++) + for (var i = 0; i < this._jl; i++) { - if (this.jointArr[i] && this.jointArr[i].breakable && (this.jointArr[i].getReactionForce(dt_inv).lengthSq() >= this.jointArr[i].maxForce * this.jointArr[i].maxForce)) + if (this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) { - this.removeJoint(this.jointArr[i]); + this.removeJoint(this.joints[i]); } } - // 8) Iterative position constraints solver - var positionSolved = this.positionSolver(pos_iteration); + // 8) Iterative position constraints solver (result stored in this._positionSolved) + this.positionSolver(positionIterations); - Manager.dump("Position Solver", this.bodyArr[1]); + Manager.dump("Position Solver", this.bodies[1]); // 9) Sync the Transforms - for (var i = 0; i < bl; i++) + for (var i = 0; i < this._bl; i++) { - if (this.bodyArr[i]) + if (this.bodies[i]) { - this.bodyArr[i].syncTransform(); + this.bodies[i].syncTransform(); } } - Manager.dump("Sync Transform", this.bodyArr[1]); + Manager.dump("Sync Transform", this.bodies[1]); // 10) Post solve collision callback - for (var i = 0; i < this.contactSolvers.length; i++) + if (this.postSolve) { - var arb = this.contactSolvers[i]; - // Re-enable this - //this.postSolve(arb); + for (var i = 0; i < this._cl; i++) + { + this.postSolve(this.contactSolvers[i]); + } } // 11) Cache Body Data - for (var i = 0; i < bl; i++) + for (var i = 0; i < this._bl; i++) { - if (this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) + if (this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { - this.bodyArr[i].cacheData('post solve collision callback'); + this.bodies[i].cacheData('post solve collision callback'); } } - Manager.dump("Cache Data", this.bodyArr[1]); + Manager.dump("Cache Data", this.bodies[1]); Manager.writeAll(); // 12) Process sleeping - /* if (allowSleep) { - var minSleepTime = 999999; + this._minSleepTime = 999999; - var linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE; - var angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE; - - for (var i = 0; i < bl; i++) + for (var i = 0; i < this._bl; i++) { - var body = this.bodyArr[i]; - - if (!this.bodyArr[i] || this.bodyArr[i].isDynamic == false) + if (!this.bodies[i] || this.bodies[i].isDynamic == false) { continue; } - if (body.angularVelocity * body.angularVelocity > angTolSqr || body.velocity.dot(body.velocity) > linTolSqr) + if (this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) { - body.sleepTime = 0; - minSleepTime = 0; + this.bodies[i].sleepTime = 0; + this._minSleepTime = 0; } else { - body.sleepTime += dt; - minSleepTime = Math.min(minSleepTime, body.sleepTime); + this.bodies[i].sleepTime += this._delta; + this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime); } } - if (positionSolved && minSleepTime >= Space.TIME_TO_SLEEP) + if (this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) { - for (var i = 0; i < this.bodyArr.length; i++) + for (var i = 0; i < this._bl; i++) { - var body = this.bodyArr[i]; - - if (!body) + if (this.bodies[i]) { - continue; + this.bodies[i].awake(false); } - - body.awake(false); } } } - */ } } diff --git a/README.md b/README.md index 6d5fe091..bd59ca53 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,10 @@ TODO: * 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 + * Sprite collision events * See which functions in the input component can move elsewhere (utils) @@ -117,6 +121,9 @@ V1.0.0 * Added Cache.getImageKeys (and similar) to return an array of all the keys for all currently cached objects. * Added Group.bringToTop feature. Will sort the Group, move the given sprites z-index to the top and shift the rest down by one. * Brand new Advanced Physics system added and working! Woohoo :) +* Fixed issue in Tilemap.parseTiledJSON where it would accidentally think image and object layers were map data. +* Fixed bug in Group.bringToTop if the child didn't have a group property yet. +* Fixed bug in FrameData.checkFrameName where the first index of the _frameNames array would be skipped. diff --git a/Tests/phaser.js b/Tests/phaser.js index ae3e1c09..96d3a9b8 100644 --- a/Tests/phaser.js +++ b/Tests/phaser.js @@ -2539,10 +2539,10 @@ var Phaser; * @return {boolean} True if frame with given name found, otherwise return false. */ function (name) { - if(this._frameNames[name]) { - return true; + if(this._frameNames[name] == null) { + return false; } - return false; + return true; }; FrameData.prototype.getFrameRange = /** * Get ranges of frames in an array. @@ -3534,6 +3534,7 @@ var Phaser; */ function () { if(this.enabled) { + this.enabled = false; this.game.input.removeGameObject(this.indexID); } }; @@ -3766,7 +3767,9 @@ var Phaser; this._pointerData[pointer.id].isDragged = true; if(this.dragFromCenter) { // Move the sprite to the middle of the pointer - this._dragPoint.setTo(-this.sprite.worldView.halfWidth, -this.sprite.worldView.halfHeight); + //this._dragPoint.setTo(-this.sprite.worldView.halfWidth, -this.sprite.worldView.halfHeight); + //this._dragPoint.setTo(this.sprite.transform.center.x, this.sprite.transform.center.y); + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); } else { this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); } @@ -5516,6 +5519,7 @@ var Phaser; */ function (object, splice) { if (typeof splice === "undefined") { splice = false; } + console.log('removing from group'); this._i = this.members.indexOf(object); if(this._i < 0 || (this._i >= this.members.length)) { return null; @@ -5526,6 +5530,7 @@ var Phaser; } else { this.members[this._i] = null; } + console.log('nulled'); if(object['events']) { object['events'].onRemovedFromGroup.dispatch(object, this); } @@ -5575,7 +5580,7 @@ var Phaser; }; Group.prototype.bringToTop = function (child) { // If child not in this group, or is already at the top of the group, return false - if(child.group.ID != this.ID || child.z == this._zCounter) { + if(!child || child.group == null || child.group.ID != this.ID || child.z == this._zCounter) { return false; } this.sort(); @@ -10716,6 +10721,10 @@ var Phaser; var json = JSON.parse(data); for(var i = 0; i < json.layers.length; i++) { var layer = new Phaser.TilemapLayer(this.game, this, key, Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight); + // Check it's a data layer + if(!json.layers[i].data) { + continue; + } layer.alpha = json.layers[i].opacity; layer.visible = json.layers[i].visible; layer.tileMargin = json.tilesets[0].margin; @@ -16166,6 +16175,7 @@ var Phaser; **/ function (index) { if(this.inputObjects[index]) { + console.log('object removed from the input manager', index); this.inputObjects[index] = null; } }; @@ -19155,11 +19165,11 @@ var Phaser; this.lastTime = Date.now(); this.frameRateHz = 60; this.timeDelta = 0; - this.paused = false; + //public paused: bool = false; + //public step: bool = false; // step through the simulation (i.e. per click) + this.paused = true; this.step = false; // step through the simulation (i.e. per click) - //public paused: bool = true; - //public step: bool = false; // step through the simulation (i.e. per click) this.velocityIterations = 8; this.positionIterations = 4; //public velocityIterations: number = 1; @@ -19175,8 +19185,8 @@ var Phaser; Manager.log = []; }; Manager.write = function write(s) { - //Manager.debug.textContent += s + "\n"; - }; + Manager.debug.textContent += s + "\n"; + }; Manager.writeAll = function writeAll() { for(var i = 0; i < Manager.log.length; i++) { //Manager.debug.textContent += Manager.log[i]; @@ -19263,12 +19273,7 @@ var Phaser; if(this.timeDelta > h) { this.timeDelta = 0; } - //if (sceneIndex < demoArr.length) - //{ - // demo = demoArr[sceneIndex]; - // demo.runFrame(); - //} - } + } //frameCount++; }; Manager.prototype.pixelsToMeters = function (value) { @@ -20803,10 +20808,10 @@ var Phaser; var Space = (function () { function Space() { this.stepCount = 0; - this.bodyArr = []; + this.bodies = []; this.bodyHash = { }; - this.jointArr = []; + this.joints = []; this.jointHash = { }; this.numContacts = 0; @@ -20814,6 +20819,8 @@ var Phaser; //this.postSolve(arb) { }; this.gravity = new Phaser.Vec2(0, 10); this.damping = 0; + this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE; + this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE; } Space.TIME_TO_SLEEP = 0.5; Space.SLEEP_LINEAR_TOLERANCE = 0.5; @@ -20822,15 +20829,15 @@ var Phaser; Advanced.Manager.shapeCounter = 0; Advanced.Manager.bodyCounter = 0; Advanced.Manager.jointCounter = 0; - for(var i = 0; i < this.bodyArr.length; i++) { - if(this.bodyArr[i]) { - this.removeBody(this.bodyArr[i]); + for(var i = 0; i < this.bodies.length; i++) { + if(this.bodies[i]) { + this.removeBody(this.bodies[i]); } } - this.bodyArr = []; + this.bodies = []; this.bodyHash = { }; - this.jointArr = []; + this.joints = []; this.jointHash = { }; this.contactSolvers = []; @@ -20840,7 +20847,7 @@ var Phaser; if(this.bodyHash[body.id] != undefined) { return; } - var index = this.bodyArr.push(body) - 1; + var index = this.bodies.push(body) - 1; this.bodyHash[body.id] = index; body.awake(true); body.space = this; @@ -20850,7 +20857,7 @@ var Phaser; if(this.bodyHash[body.id] == undefined) { return; } - // Remove linked joint + // Remove linked joints for(var i = 0; i < body.joints.length; i++) { if(body.joints[i]) { this.removeJoint(body.joints[i]); @@ -20859,7 +20866,7 @@ var Phaser; body.space = null; var index = this.bodyHash[body.id]; delete this.bodyHash[body.id]; - delete this.bodyArr[index]; + delete this.bodies[index]; }; Space.prototype.addJoint = function (joint) { if(this.jointHash[joint.id] != undefined) { @@ -20867,7 +20874,7 @@ var Phaser; } joint.body1.awake(true); joint.body2.awake(true); - var index = this.jointArr.push(joint) - 1; + var index = this.joints.push(joint) - 1; this.jointHash[joint.id] = index; var index = joint.body1.joints.push(joint) - 1; joint.body1.jointHash[joint.id] = index; @@ -20888,12 +20895,12 @@ var Phaser; delete joint.body2.joints[index]; var index = this.jointHash[joint.id]; delete this.jointHash[joint.id]; - delete this.jointArr[index]; + delete this.joints[index]; }; Space.prototype.findShapeByPoint = function (p, refShape) { var firstShape; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20916,8 +20923,8 @@ var Phaser; }; Space.prototype.findBodyByPoint = function (p, refBody) { var firstBody; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20939,11 +20946,10 @@ var Phaser; } return firstBody; }; - Space.prototype.shapeById = // TODO: Replace this function to shape hashing - function (id) { + Space.prototype.shapeById = function (id) { var shape; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20958,15 +20964,15 @@ var Phaser; Space.prototype.jointById = function (id) { var index = this.jointHash[id]; if(index != undefined) { - return this.jointArr[index]; + return this.joints[index]; } return null; }; Space.prototype.findVertexByPoint = function (p, minDist, refVertexId) { var firstVertexId = -1; refVertexId = refVertexId || -1; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20992,8 +20998,8 @@ var Phaser; Space.prototype.findEdgeByPoint = function (p, minDist, refEdgeId) { var firstEdgeId = -1; refEdgeId = refEdgeId || -1; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -21023,8 +21029,8 @@ var Phaser; var firstJointId = -1; var dsq = minDist * minDist; refJointId = refJointId || -1; - for(var i = 0; i < this.jointArr.length; i++) { - var joint = this.jointArr[i]; + for(var i = 0; i < this.joints.length; i++) { + var joint = this.joints[i]; if(!joint) { continue; } @@ -21049,8 +21055,8 @@ var Phaser; return firstJointId; }; Space.prototype.findContactSolver = function (shape1, shape2) { - Advanced.Manager.write('findContactSolver. Length: ' + this.contactSolvers.length); - for(var i = 0; i < this.contactSolvers.length; i++) { + Advanced.Manager.write('findContactSolver. Length: ' + this._cl); + for(var i = 0; i < this._cl; i++) { var contactSolver = this.contactSolvers[i]; if(shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) { return contactSolver; @@ -21060,255 +21066,221 @@ var Phaser; }; Space.prototype.genTemporalContactSolvers = function () { Advanced.Manager.write('genTemporalContactSolvers'); - var newContactSolverArr = []; - var bl = this.bodyArr.length; + this._cl = 0; + this.contactSolvers.length = 0; this.numContacts = 0; - for(var body1_index = 0; body1_index < bl; body1_index++) { - var body1 = this.bodyArr[body1_index]; - if(!body1) { + for(var body1Index = 0; body1Index < this._bl; body1Index++) { + if(!this.bodies[body1Index]) { continue; } - body1.stepCount = this.stepCount; - for(var body2_index = 0; body2_index < bl; body2_index++) { - var body2 = this.bodyArr[body2_index]; - if(body1.inContact(body2) == false) { + this.bodies[body1Index].stepCount = this.stepCount; + for(var body2Index = 0; body2Index < this._bl; body2Index++) { + if(this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) { continue; } Advanced.Manager.write('body1 and body2 intersect'); - for(var i = 0; i < body1.shapes.length; i++) { - for(var j = 0; j < body2.shapes.length; j++) { - var shape1 = body1.shapes[i]; - var shape2 = body2.shapes[j]; + for(var i = 0; i < this.bodies[body1Index].shapesLength; i++) { + for(var j = 0; j < this.bodies[body2Index].shapesLength; j++) { + this._shape1 = this.bodies[body1Index].shapes[i]; + this._shape2 = this.bodies[body2Index].shapes[j]; var contactArr = []; - if(!Advanced.Manager.collision.collide(shape1, shape2, contactArr)) { + if(!Advanced.Manager.collision.collide(this._shape1, this._shape2, contactArr)) { continue; } - if(shape1.type > shape2.type) { - var temp = shape1; - shape1 = shape2; - shape2 = temp; + if(this._shape1.type > this._shape2.type) { + var temp = this._shape1; + this._shape1 = this._shape2; + this._shape2 = temp; } this.numContacts += contactArr.length; - var contactSolver = this.findContactSolver(shape1, shape2); + // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers) + var contactSolver = this.findContactSolver(this._shape1, this._shape2); Advanced.Manager.write('findContactSolver result: ' + contactSolver); if(contactSolver) { contactSolver.update(contactArr); - newContactSolverArr.push(contactSolver); + this.contactSolvers.push(contactSolver); } else { Advanced.Manager.write('awake both bodies'); - body1.awake(true); - body2.awake(true); - var newContactSolver = new Advanced.ContactSolver(shape1, shape2); + this.bodies[body1Index].awake(true); + this.bodies[body2Index].awake(true); + var newContactSolver = new Advanced.ContactSolver(this._shape1, this._shape2); newContactSolver.contacts = contactArr; - newContactSolver.elasticity = Math.max(shape1.elasticity, shape2.elasticity); - newContactSolver.friction = Math.sqrt(shape1.friction * shape2.friction); - newContactSolverArr.push(newContactSolver); + newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity); + newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction); + this.contactSolvers.push(newContactSolver); Advanced.Manager.write('new contact solver'); - //console.log(newContactSolver); - } + } } } } } - return newContactSolverArr; + this._cl = this.contactSolvers.length; }; - Space.prototype.initSolver = function (dt, dt_inv, warmStarting) { + Space.prototype.initSolver = function (warmStarting) { Advanced.Manager.write('initSolver'); - Advanced.Manager.write('contactSolvers.length: ' + this.contactSolvers.length); - //var t0 = Date.now(); + Advanced.Manager.write('contactSolvers.length: ' + this._cl); // Initialize contact solvers - for(var i = 0; i < this.contactSolvers.length; i++) { - this.contactSolvers[i].initSolver(dt_inv); + for(var c = 0; c < this._cl; c++) { + this.contactSolvers[c].initSolver(this._deltaInv); + // Warm starting (apply cached impulse) + if(warmStarting) { + this.contactSolvers[c].warmStart(); + } } // Initialize joint solver - for(var i = 0; i < this.jointArr.length; i++) { - if(this.jointArr[i]) { - this.jointArr[i].initSolver(dt, warmStarting); + for(var j = 0; j < this.joints.length; j++) { + if(this.joints[j]) { + this.joints[j].initSolver(this._delta, warmStarting); } } // Warm starting (apply cached impulse) - if(warmStarting) { - for(var i = 0; i < this.contactSolvers.length; i++) { - this.contactSolvers[i].warmStart(); - } + /* + if (warmStarting) + { + for (var c = 0; c < this._cl; c++) + { + this.contactSolvers[c].warmStart(); } - //stats.timeInitSolver = Date.now() - t0; + } + */ }; - Space.prototype.velocitySolver = function (iteration) { - Advanced.Manager.write('velocitySolver, iterations: ' + iteration + ' csa len: ' + this.contactSolvers.length); - //var t0 = Date.now(); - for(var i = 0; i < iteration; i++) { - for(var j = 0; j < this.jointArr.length; j++) { - if(this.jointArr[j]) { - this.jointArr[j].solveVelocityConstraints(); + Space.prototype.velocitySolver = function (iterations) { + Advanced.Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl); + for(var i = 0; i < iterations; i++) { + for(var j = 0; j < this._jl; j++) { + if(this.joints[j]) { + this.joints[j].solveVelocityConstraints(); } } - for(var j = 0; j < this.contactSolvers.length; j++) { - this.contactSolvers[j].solveVelocityConstraints(); + for(var c = 0; c < this._cl; c++) { + this.contactSolvers[c].solveVelocityConstraints(); } } }; - Space.prototype.positionSolver = function (iteration) { - var positionSolved = false; - for(var i = 0; i < iteration; i++) { - var contactsOk = true; - var jointsOk = true; - for(var j = 0; j < this.contactSolvers.length; j++) { - var contactOk = this.contactSolvers[j].solvePositionConstraints(); - contactsOk = contactOk && contactsOk; + Space.prototype.positionSolver = function (iterations) { + this._positionSolved = false; + for(var i = 0; i < iterations; i++) { + this._contactsOk = true; + this._jointsOk = true; + for(var c = 0; c < this._cl; c++) { + this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk; } - for(var j = 0; j < this.jointArr.length; j++) { - if(this.jointArr[j]) { - var jointOk = this.jointArr[j].solvePositionConstraints(); - jointsOk = jointOk && jointsOk; + for(var j = 0; j < this._jl; j++) { + if(this.joints[j]) { + this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk; } } - if(contactsOk && jointsOk) { + if(this._contactsOk && this._jointsOk) { // exit early if the position errors are small - positionSolved = true; + this._positionSolved = true; break; } } - return positionSolved; + return this._positionSolved; }; - Space.prototype.step = function (dt, vel_iteration, pos_iteration, warmStarting, allowSleep) { + Space.prototype.step = // Step through the physics simulation + function (dt, velocityIterations, positionIterations, warmStarting, allowSleep) { Advanced.Manager.clear(); Advanced.Manager.write('Space step ' + this.stepCount); - var dt_inv = 1 / dt; - var bl = this.bodyArr.length; - var jl = this.jointArr.length; + this._delta = dt; + this._deltaInv = 1 / dt; + this._bl = this.bodies.length; + this._jl = this.joints.length; this.stepCount++; - // 1) Generate Contact Solvers - this.contactSolvers = this.genTemporalContactSolvers(); - Advanced.Manager.dump("Contact Solvers", this.bodyArr[1]); + // 1) Generate Contact Solvers (into the this.contactSolvers array) + this.genTemporalContactSolvers(); + Advanced.Manager.dump("Contact Solvers", this.bodies[1]); // 2) Initialize the Contact Solvers - this.initSolver(dt, dt_inv, warmStarting); - Advanced.Manager.dump("Init Solver", this.bodyArr[1]); + this.initSolver(warmStarting); + Advanced.Manager.dump("Init Solver", this.bodies[1]); // 3) Intergrate velocity - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) { - this.bodyArr[i].updateVelocity(this.gravity, dt, this.damping); + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { + this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping); } } - Advanced.Manager.dump("Update Velocity", this.bodyArr[1]); - /* - // 4) Awaken bodies - for (var j = 0; i < jl; j++) - { - var joint = this.jointArr[j]; - - if (!joint) - { - continue; + Advanced.Manager.dump("Update Velocity", this.bodies[1]); + // 4) Awaken bodies via joints + for(var j = 0; i < this._jl; j++) { + if(!this.joints[j]) { + continue; + } + // combine + var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic; + var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic; + if(awake1 ^ awake2) { + if(!awake1) { + this.joints[j].body1.awake(true); + } + if(!awake2) { + this.joints[j].body2.awake(true); + } + } } - - var body1 = joint.body1; - var body2 = joint.body2; - - var awake1 = body1.isAwake && !body1.isStatic; - var awake2 = body2.isAwake && !body2.isStatic; - - if (awake1 ^ awake2) - { - if (!awake1) - { - body1.awake(true); - } - - if (!awake2) - { - body2.awake(true); - } - } - } - */ // 5) Iterative velocity constraints solver - this.velocitySolver(vel_iteration); - Advanced.Manager.dump("Velocity Solvers", this.bodyArr[1]); + this.velocitySolver(velocityIterations); + Advanced.Manager.dump("Velocity Solvers", this.bodies[1]); // 6) Intergrate position - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) { - this.bodyArr[i].updatePosition(dt); + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { + this.bodies[i].updatePosition(this._delta); } } - Advanced.Manager.dump("Update Position", this.bodyArr[1]); + Advanced.Manager.dump("Update Position", this.bodies[1]); // 7) Process breakable joint - for(var i = 0; i < jl; i++) { - if(this.jointArr[i] && this.jointArr[i].breakable && (this.jointArr[i].getReactionForce(dt_inv).lengthSq() >= this.jointArr[i].maxForce * this.jointArr[i].maxForce)) { - this.removeJoint(this.jointArr[i]); + for(var i = 0; i < this._jl; i++) { + if(this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) { + this.removeJoint(this.joints[i]); } } - // 8) Iterative position constraints solver - var positionSolved = this.positionSolver(pos_iteration); - Advanced.Manager.dump("Position Solver", this.bodyArr[1]); + // 8) Iterative position constraints solver (result stored in this._positionSolved) + this.positionSolver(positionIterations); + Advanced.Manager.dump("Position Solver", this.bodies[1]); // 9) Sync the Transforms - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i]) { - this.bodyArr[i].syncTransform(); + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i]) { + this.bodies[i].syncTransform(); } } - Advanced.Manager.dump("Sync Transform", this.bodyArr[1]); + Advanced.Manager.dump("Sync Transform", this.bodies[1]); // 10) Post solve collision callback - for(var i = 0; i < this.contactSolvers.length; i++) { - var arb = this.contactSolvers[i]; - // Re-enable this - //this.postSolve(arb); - } - // 11) Cache Body Data - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) { - this.bodyArr[i].cacheData('post solve collision callback'); + if(this.postSolve) { + for(var i = 0; i < this._cl; i++) { + this.postSolve(this.contactSolvers[i]); } } - Advanced.Manager.dump("Cache Data", this.bodyArr[1]); + // 11) Cache Body Data + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { + this.bodies[i].cacheData('post solve collision callback'); + } + } + Advanced.Manager.dump("Cache Data", this.bodies[1]); Advanced.Manager.writeAll(); // 12) Process sleeping - /* - if (allowSleep) - { - var minSleepTime = 999999; - - var linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE; - var angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE; - - for (var i = 0; i < bl; i++) - { - var body = this.bodyArr[i]; - - if (!this.bodyArr[i] || this.bodyArr[i].isDynamic == false) - { - continue; + if(allowSleep) { + this._minSleepTime = 999999; + for(var i = 0; i < this._bl; i++) { + if(!this.bodies[i] || this.bodies[i].isDynamic == false) { + continue; + } + if(this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) { + this.bodies[i].sleepTime = 0; + this._minSleepTime = 0; + } else { + this.bodies[i].sleepTime += this._delta; + this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime); + } + } + if(this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) { + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i]) { + this.bodies[i].awake(false); + } + } + } } - - if (body.angularVelocity * body.angularVelocity > angTolSqr || body.velocity.dot(body.velocity) > linTolSqr) - { - body.sleepTime = 0; - minSleepTime = 0; - } - else - { - body.sleepTime += dt; - minSleepTime = Math.min(minSleepTime, body.sleepTime); - } - } - - if (positionSolved && minSleepTime >= Space.TIME_TO_SLEEP) - { - for (var i = 0; i < this.bodyArr.length; i++) - { - var body = this.bodyArr[i]; - - if (!body) - { - continue; - } - - body.awake(false); - } - } - } - */ - }; + }; return Space; })(); Advanced.Space = Space; @@ -21597,6 +21569,7 @@ var Phaser; // Check not already part of this body shape.body = this; this.shapes.push(shape); + this.shapesLength = this.shapes.length; return shape; }; Body.prototype.removeShape = function (shape) { @@ -21605,6 +21578,7 @@ var Phaser; this.shapes.splice(index, 1); shape.body = undefined; } + this.shapesLength = this.shapes.length; }; Body.prototype.setMass = function (mass) { this.mass = mass; diff --git a/build/phaser.d.ts b/build/phaser.d.ts index ee5d593d..782a3b9c 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -9944,13 +9944,26 @@ module Phaser.Physics.Advanced { module Phaser.Physics.Advanced { class Space { constructor(); + private _delta; + private _deltaInv; + private _bl; + private _jl; + private _cl; + private _linTolSqr; + private _angTolSqr; + private _minSleepTime; + private _positionSolved; + private _shape1; + private _shape2; + private _contactsOk; + private _jointsOk; static TIME_TO_SLEEP: number; static SLEEP_LINEAR_TOLERANCE: number; static SLEEP_ANGULAR_TOLERANCE: number; - public bodyArr: Body[]; - public bodyHash; - public jointArr: IJoint[]; - public jointHash; + public bodies: Body[]; + private bodyHash; + public joints: IJoint[]; + private jointHash; public numContacts: number; public contactSolvers: ContactSolver[]; public postSolve; @@ -9969,12 +9982,12 @@ module Phaser.Physics.Advanced { public findVertexByPoint(p, minDist, refVertexId): number; public findEdgeByPoint(p, minDist, refEdgeId): number; public findJointByPoint(p, minDist, refJointId): number; - public findContactSolver(shape1, shape2): ContactSolver; - public genTemporalContactSolvers(): any[]; - public initSolver(dt, dt_inv, warmStarting): void; - public velocitySolver(iteration): void; - public positionSolver(iteration): bool; - public step(dt, vel_iteration, pos_iteration, warmStarting, allowSleep): void; + private findContactSolver(shape1, shape2); + private genTemporalContactSolvers(); + private initSolver(warmStarting); + private velocitySolver(iterations); + private positionSolver(iterations); + public step(dt: number, velocityIterations: number, positionIterations: number, warmStarting: bool, allowSleep: bool): void; } } /** @@ -10045,6 +10058,7 @@ module Phaser.Physics.Advanced { public sleepTime: number; public awaked: bool; public shapes: IShape[]; + public shapesLength: number; public joints: IJoint[]; public jointHash: {}; public bounds: Bounds; @@ -10084,7 +10098,7 @@ module Phaser.Physics.Advanced { public updateVelocity(gravity, dt, damping): void; public inContact(body2: Body): bool; public clamp(v, min, max); - public updatePosition(dt): void; + public updatePosition(dt: number): void; public resetForce(): void; public applyForce(force: Vec2, p: Vec2): void; public applyForceToCenter(force: Vec2): void; diff --git a/build/phaser.js b/build/phaser.js index ae3e1c09..96d3a9b8 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -2539,10 +2539,10 @@ var Phaser; * @return {boolean} True if frame with given name found, otherwise return false. */ function (name) { - if(this._frameNames[name]) { - return true; + if(this._frameNames[name] == null) { + return false; } - return false; + return true; }; FrameData.prototype.getFrameRange = /** * Get ranges of frames in an array. @@ -3534,6 +3534,7 @@ var Phaser; */ function () { if(this.enabled) { + this.enabled = false; this.game.input.removeGameObject(this.indexID); } }; @@ -3766,7 +3767,9 @@ var Phaser; this._pointerData[pointer.id].isDragged = true; if(this.dragFromCenter) { // Move the sprite to the middle of the pointer - this._dragPoint.setTo(-this.sprite.worldView.halfWidth, -this.sprite.worldView.halfHeight); + //this._dragPoint.setTo(-this.sprite.worldView.halfWidth, -this.sprite.worldView.halfHeight); + //this._dragPoint.setTo(this.sprite.transform.center.x, this.sprite.transform.center.y); + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); } else { this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); } @@ -5516,6 +5519,7 @@ var Phaser; */ function (object, splice) { if (typeof splice === "undefined") { splice = false; } + console.log('removing from group'); this._i = this.members.indexOf(object); if(this._i < 0 || (this._i >= this.members.length)) { return null; @@ -5526,6 +5530,7 @@ var Phaser; } else { this.members[this._i] = null; } + console.log('nulled'); if(object['events']) { object['events'].onRemovedFromGroup.dispatch(object, this); } @@ -5575,7 +5580,7 @@ var Phaser; }; Group.prototype.bringToTop = function (child) { // If child not in this group, or is already at the top of the group, return false - if(child.group.ID != this.ID || child.z == this._zCounter) { + if(!child || child.group == null || child.group.ID != this.ID || child.z == this._zCounter) { return false; } this.sort(); @@ -10716,6 +10721,10 @@ var Phaser; var json = JSON.parse(data); for(var i = 0; i < json.layers.length; i++) { var layer = new Phaser.TilemapLayer(this.game, this, key, Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight); + // Check it's a data layer + if(!json.layers[i].data) { + continue; + } layer.alpha = json.layers[i].opacity; layer.visible = json.layers[i].visible; layer.tileMargin = json.tilesets[0].margin; @@ -16166,6 +16175,7 @@ var Phaser; **/ function (index) { if(this.inputObjects[index]) { + console.log('object removed from the input manager', index); this.inputObjects[index] = null; } }; @@ -19155,11 +19165,11 @@ var Phaser; this.lastTime = Date.now(); this.frameRateHz = 60; this.timeDelta = 0; - this.paused = false; + //public paused: bool = false; + //public step: bool = false; // step through the simulation (i.e. per click) + this.paused = true; this.step = false; // step through the simulation (i.e. per click) - //public paused: bool = true; - //public step: bool = false; // step through the simulation (i.e. per click) this.velocityIterations = 8; this.positionIterations = 4; //public velocityIterations: number = 1; @@ -19175,8 +19185,8 @@ var Phaser; Manager.log = []; }; Manager.write = function write(s) { - //Manager.debug.textContent += s + "\n"; - }; + Manager.debug.textContent += s + "\n"; + }; Manager.writeAll = function writeAll() { for(var i = 0; i < Manager.log.length; i++) { //Manager.debug.textContent += Manager.log[i]; @@ -19263,12 +19273,7 @@ var Phaser; if(this.timeDelta > h) { this.timeDelta = 0; } - //if (sceneIndex < demoArr.length) - //{ - // demo = demoArr[sceneIndex]; - // demo.runFrame(); - //} - } + } //frameCount++; }; Manager.prototype.pixelsToMeters = function (value) { @@ -20803,10 +20808,10 @@ var Phaser; var Space = (function () { function Space() { this.stepCount = 0; - this.bodyArr = []; + this.bodies = []; this.bodyHash = { }; - this.jointArr = []; + this.joints = []; this.jointHash = { }; this.numContacts = 0; @@ -20814,6 +20819,8 @@ var Phaser; //this.postSolve(arb) { }; this.gravity = new Phaser.Vec2(0, 10); this.damping = 0; + this._linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE; + this._angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE; } Space.TIME_TO_SLEEP = 0.5; Space.SLEEP_LINEAR_TOLERANCE = 0.5; @@ -20822,15 +20829,15 @@ var Phaser; Advanced.Manager.shapeCounter = 0; Advanced.Manager.bodyCounter = 0; Advanced.Manager.jointCounter = 0; - for(var i = 0; i < this.bodyArr.length; i++) { - if(this.bodyArr[i]) { - this.removeBody(this.bodyArr[i]); + for(var i = 0; i < this.bodies.length; i++) { + if(this.bodies[i]) { + this.removeBody(this.bodies[i]); } } - this.bodyArr = []; + this.bodies = []; this.bodyHash = { }; - this.jointArr = []; + this.joints = []; this.jointHash = { }; this.contactSolvers = []; @@ -20840,7 +20847,7 @@ var Phaser; if(this.bodyHash[body.id] != undefined) { return; } - var index = this.bodyArr.push(body) - 1; + var index = this.bodies.push(body) - 1; this.bodyHash[body.id] = index; body.awake(true); body.space = this; @@ -20850,7 +20857,7 @@ var Phaser; if(this.bodyHash[body.id] == undefined) { return; } - // Remove linked joint + // Remove linked joints for(var i = 0; i < body.joints.length; i++) { if(body.joints[i]) { this.removeJoint(body.joints[i]); @@ -20859,7 +20866,7 @@ var Phaser; body.space = null; var index = this.bodyHash[body.id]; delete this.bodyHash[body.id]; - delete this.bodyArr[index]; + delete this.bodies[index]; }; Space.prototype.addJoint = function (joint) { if(this.jointHash[joint.id] != undefined) { @@ -20867,7 +20874,7 @@ var Phaser; } joint.body1.awake(true); joint.body2.awake(true); - var index = this.jointArr.push(joint) - 1; + var index = this.joints.push(joint) - 1; this.jointHash[joint.id] = index; var index = joint.body1.joints.push(joint) - 1; joint.body1.jointHash[joint.id] = index; @@ -20888,12 +20895,12 @@ var Phaser; delete joint.body2.joints[index]; var index = this.jointHash[joint.id]; delete this.jointHash[joint.id]; - delete this.jointArr[index]; + delete this.joints[index]; }; Space.prototype.findShapeByPoint = function (p, refShape) { var firstShape; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20916,8 +20923,8 @@ var Phaser; }; Space.prototype.findBodyByPoint = function (p, refBody) { var firstBody; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20939,11 +20946,10 @@ var Phaser; } return firstBody; }; - Space.prototype.shapeById = // TODO: Replace this function to shape hashing - function (id) { + Space.prototype.shapeById = function (id) { var shape; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20958,15 +20964,15 @@ var Phaser; Space.prototype.jointById = function (id) { var index = this.jointHash[id]; if(index != undefined) { - return this.jointArr[index]; + return this.joints[index]; } return null; }; Space.prototype.findVertexByPoint = function (p, minDist, refVertexId) { var firstVertexId = -1; refVertexId = refVertexId || -1; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -20992,8 +20998,8 @@ var Phaser; Space.prototype.findEdgeByPoint = function (p, minDist, refEdgeId) { var firstEdgeId = -1; refEdgeId = refEdgeId || -1; - for(var i = 0; i < this.bodyArr.length; i++) { - var body = this.bodyArr[i]; + for(var i = 0; i < this.bodies.length; i++) { + var body = this.bodies[i]; if(!body) { continue; } @@ -21023,8 +21029,8 @@ var Phaser; var firstJointId = -1; var dsq = minDist * minDist; refJointId = refJointId || -1; - for(var i = 0; i < this.jointArr.length; i++) { - var joint = this.jointArr[i]; + for(var i = 0; i < this.joints.length; i++) { + var joint = this.joints[i]; if(!joint) { continue; } @@ -21049,8 +21055,8 @@ var Phaser; return firstJointId; }; Space.prototype.findContactSolver = function (shape1, shape2) { - Advanced.Manager.write('findContactSolver. Length: ' + this.contactSolvers.length); - for(var i = 0; i < this.contactSolvers.length; i++) { + Advanced.Manager.write('findContactSolver. Length: ' + this._cl); + for(var i = 0; i < this._cl; i++) { var contactSolver = this.contactSolvers[i]; if(shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2) { return contactSolver; @@ -21060,255 +21066,221 @@ var Phaser; }; Space.prototype.genTemporalContactSolvers = function () { Advanced.Manager.write('genTemporalContactSolvers'); - var newContactSolverArr = []; - var bl = this.bodyArr.length; + this._cl = 0; + this.contactSolvers.length = 0; this.numContacts = 0; - for(var body1_index = 0; body1_index < bl; body1_index++) { - var body1 = this.bodyArr[body1_index]; - if(!body1) { + for(var body1Index = 0; body1Index < this._bl; body1Index++) { + if(!this.bodies[body1Index]) { continue; } - body1.stepCount = this.stepCount; - for(var body2_index = 0; body2_index < bl; body2_index++) { - var body2 = this.bodyArr[body2_index]; - if(body1.inContact(body2) == false) { + this.bodies[body1Index].stepCount = this.stepCount; + for(var body2Index = 0; body2Index < this._bl; body2Index++) { + if(this.bodies[body1Index].inContact(this.bodies[body2Index]) == false) { continue; } Advanced.Manager.write('body1 and body2 intersect'); - for(var i = 0; i < body1.shapes.length; i++) { - for(var j = 0; j < body2.shapes.length; j++) { - var shape1 = body1.shapes[i]; - var shape2 = body2.shapes[j]; + for(var i = 0; i < this.bodies[body1Index].shapesLength; i++) { + for(var j = 0; j < this.bodies[body2Index].shapesLength; j++) { + this._shape1 = this.bodies[body1Index].shapes[i]; + this._shape2 = this.bodies[body2Index].shapes[j]; var contactArr = []; - if(!Advanced.Manager.collision.collide(shape1, shape2, contactArr)) { + if(!Advanced.Manager.collision.collide(this._shape1, this._shape2, contactArr)) { continue; } - if(shape1.type > shape2.type) { - var temp = shape1; - shape1 = shape2; - shape2 = temp; + if(this._shape1.type > this._shape2.type) { + var temp = this._shape1; + this._shape1 = this._shape2; + this._shape2 = temp; } this.numContacts += contactArr.length; - var contactSolver = this.findContactSolver(shape1, shape2); + // Result stored in this._contactSolver (see what we can do about generating some re-usable solvers) + var contactSolver = this.findContactSolver(this._shape1, this._shape2); Advanced.Manager.write('findContactSolver result: ' + contactSolver); if(contactSolver) { contactSolver.update(contactArr); - newContactSolverArr.push(contactSolver); + this.contactSolvers.push(contactSolver); } else { Advanced.Manager.write('awake both bodies'); - body1.awake(true); - body2.awake(true); - var newContactSolver = new Advanced.ContactSolver(shape1, shape2); + this.bodies[body1Index].awake(true); + this.bodies[body2Index].awake(true); + var newContactSolver = new Advanced.ContactSolver(this._shape1, this._shape2); newContactSolver.contacts = contactArr; - newContactSolver.elasticity = Math.max(shape1.elasticity, shape2.elasticity); - newContactSolver.friction = Math.sqrt(shape1.friction * shape2.friction); - newContactSolverArr.push(newContactSolver); + newContactSolver.elasticity = Math.max(this._shape1.elasticity, this._shape2.elasticity); + newContactSolver.friction = Math.sqrt(this._shape1.friction * this._shape2.friction); + this.contactSolvers.push(newContactSolver); Advanced.Manager.write('new contact solver'); - //console.log(newContactSolver); - } + } } } } } - return newContactSolverArr; + this._cl = this.contactSolvers.length; }; - Space.prototype.initSolver = function (dt, dt_inv, warmStarting) { + Space.prototype.initSolver = function (warmStarting) { Advanced.Manager.write('initSolver'); - Advanced.Manager.write('contactSolvers.length: ' + this.contactSolvers.length); - //var t0 = Date.now(); + Advanced.Manager.write('contactSolvers.length: ' + this._cl); // Initialize contact solvers - for(var i = 0; i < this.contactSolvers.length; i++) { - this.contactSolvers[i].initSolver(dt_inv); + for(var c = 0; c < this._cl; c++) { + this.contactSolvers[c].initSolver(this._deltaInv); + // Warm starting (apply cached impulse) + if(warmStarting) { + this.contactSolvers[c].warmStart(); + } } // Initialize joint solver - for(var i = 0; i < this.jointArr.length; i++) { - if(this.jointArr[i]) { - this.jointArr[i].initSolver(dt, warmStarting); + for(var j = 0; j < this.joints.length; j++) { + if(this.joints[j]) { + this.joints[j].initSolver(this._delta, warmStarting); } } // Warm starting (apply cached impulse) - if(warmStarting) { - for(var i = 0; i < this.contactSolvers.length; i++) { - this.contactSolvers[i].warmStart(); - } + /* + if (warmStarting) + { + for (var c = 0; c < this._cl; c++) + { + this.contactSolvers[c].warmStart(); } - //stats.timeInitSolver = Date.now() - t0; + } + */ }; - Space.prototype.velocitySolver = function (iteration) { - Advanced.Manager.write('velocitySolver, iterations: ' + iteration + ' csa len: ' + this.contactSolvers.length); - //var t0 = Date.now(); - for(var i = 0; i < iteration; i++) { - for(var j = 0; j < this.jointArr.length; j++) { - if(this.jointArr[j]) { - this.jointArr[j].solveVelocityConstraints(); + Space.prototype.velocitySolver = function (iterations) { + Advanced.Manager.write('velocitySolver, iterations: ' + iterations + ' csa len: ' + this._cl); + for(var i = 0; i < iterations; i++) { + for(var j = 0; j < this._jl; j++) { + if(this.joints[j]) { + this.joints[j].solveVelocityConstraints(); } } - for(var j = 0; j < this.contactSolvers.length; j++) { - this.contactSolvers[j].solveVelocityConstraints(); + for(var c = 0; c < this._cl; c++) { + this.contactSolvers[c].solveVelocityConstraints(); } } }; - Space.prototype.positionSolver = function (iteration) { - var positionSolved = false; - for(var i = 0; i < iteration; i++) { - var contactsOk = true; - var jointsOk = true; - for(var j = 0; j < this.contactSolvers.length; j++) { - var contactOk = this.contactSolvers[j].solvePositionConstraints(); - contactsOk = contactOk && contactsOk; + Space.prototype.positionSolver = function (iterations) { + this._positionSolved = false; + for(var i = 0; i < iterations; i++) { + this._contactsOk = true; + this._jointsOk = true; + for(var c = 0; c < this._cl; c++) { + this._contactsOk = this.contactSolvers[c].solvePositionConstraints() && this._contactsOk; } - for(var j = 0; j < this.jointArr.length; j++) { - if(this.jointArr[j]) { - var jointOk = this.jointArr[j].solvePositionConstraints(); - jointsOk = jointOk && jointsOk; + for(var j = 0; j < this._jl; j++) { + if(this.joints[j]) { + this._jointsOk = this.joints[j].solvePositionConstraints() && this._jointsOk; } } - if(contactsOk && jointsOk) { + if(this._contactsOk && this._jointsOk) { // exit early if the position errors are small - positionSolved = true; + this._positionSolved = true; break; } } - return positionSolved; + return this._positionSolved; }; - Space.prototype.step = function (dt, vel_iteration, pos_iteration, warmStarting, allowSleep) { + Space.prototype.step = // Step through the physics simulation + function (dt, velocityIterations, positionIterations, warmStarting, allowSleep) { Advanced.Manager.clear(); Advanced.Manager.write('Space step ' + this.stepCount); - var dt_inv = 1 / dt; - var bl = this.bodyArr.length; - var jl = this.jointArr.length; + this._delta = dt; + this._deltaInv = 1 / dt; + this._bl = this.bodies.length; + this._jl = this.joints.length; this.stepCount++; - // 1) Generate Contact Solvers - this.contactSolvers = this.genTemporalContactSolvers(); - Advanced.Manager.dump("Contact Solvers", this.bodyArr[1]); + // 1) Generate Contact Solvers (into the this.contactSolvers array) + this.genTemporalContactSolvers(); + Advanced.Manager.dump("Contact Solvers", this.bodies[1]); // 2) Initialize the Contact Solvers - this.initSolver(dt, dt_inv, warmStarting); - Advanced.Manager.dump("Init Solver", this.bodyArr[1]); + this.initSolver(warmStarting); + Advanced.Manager.dump("Init Solver", this.bodies[1]); // 3) Intergrate velocity - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) { - this.bodyArr[i].updateVelocity(this.gravity, dt, this.damping); + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { + this.bodies[i].updateVelocity(this.gravity, this._delta, this.damping); } } - Advanced.Manager.dump("Update Velocity", this.bodyArr[1]); - /* - // 4) Awaken bodies - for (var j = 0; i < jl; j++) - { - var joint = this.jointArr[j]; - - if (!joint) - { - continue; + Advanced.Manager.dump("Update Velocity", this.bodies[1]); + // 4) Awaken bodies via joints + for(var j = 0; i < this._jl; j++) { + if(!this.joints[j]) { + continue; + } + // combine + var awake1 = this.joints[j].body1.isAwake && !this.joints[j].body1.isStatic; + var awake2 = this.joints[j].body2.isAwake && !this.joints[j].body2.isStatic; + if(awake1 ^ awake2) { + if(!awake1) { + this.joints[j].body1.awake(true); + } + if(!awake2) { + this.joints[j].body2.awake(true); + } + } } - - var body1 = joint.body1; - var body2 = joint.body2; - - var awake1 = body1.isAwake && !body1.isStatic; - var awake2 = body2.isAwake && !body2.isStatic; - - if (awake1 ^ awake2) - { - if (!awake1) - { - body1.awake(true); - } - - if (!awake2) - { - body2.awake(true); - } - } - } - */ // 5) Iterative velocity constraints solver - this.velocitySolver(vel_iteration); - Advanced.Manager.dump("Velocity Solvers", this.bodyArr[1]); + this.velocitySolver(velocityIterations); + Advanced.Manager.dump("Velocity Solvers", this.bodies[1]); // 6) Intergrate position - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) { - this.bodyArr[i].updatePosition(dt); + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { + this.bodies[i].updatePosition(this._delta); } } - Advanced.Manager.dump("Update Position", this.bodyArr[1]); + Advanced.Manager.dump("Update Position", this.bodies[1]); // 7) Process breakable joint - for(var i = 0; i < jl; i++) { - if(this.jointArr[i] && this.jointArr[i].breakable && (this.jointArr[i].getReactionForce(dt_inv).lengthSq() >= this.jointArr[i].maxForce * this.jointArr[i].maxForce)) { - this.removeJoint(this.jointArr[i]); + for(var i = 0; i < this._jl; i++) { + if(this.joints[i] && this.joints[i].breakable && (this.joints[i].getReactionForce(this._deltaInv).lengthSq() >= this.joints[i].maxForce * this.joints[i].maxForce)) { + this.removeJoint(this.joints[i]); } } - // 8) Iterative position constraints solver - var positionSolved = this.positionSolver(pos_iteration); - Advanced.Manager.dump("Position Solver", this.bodyArr[1]); + // 8) Iterative position constraints solver (result stored in this._positionSolved) + this.positionSolver(positionIterations); + Advanced.Manager.dump("Position Solver", this.bodies[1]); // 9) Sync the Transforms - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i]) { - this.bodyArr[i].syncTransform(); + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i]) { + this.bodies[i].syncTransform(); } } - Advanced.Manager.dump("Sync Transform", this.bodyArr[1]); + Advanced.Manager.dump("Sync Transform", this.bodies[1]); // 10) Post solve collision callback - for(var i = 0; i < this.contactSolvers.length; i++) { - var arb = this.contactSolvers[i]; - // Re-enable this - //this.postSolve(arb); - } - // 11) Cache Body Data - for(var i = 0; i < bl; i++) { - if(this.bodyArr[i] && this.bodyArr[i].isDynamic && this.bodyArr[i].isAwake) { - this.bodyArr[i].cacheData('post solve collision callback'); + if(this.postSolve) { + for(var i = 0; i < this._cl; i++) { + this.postSolve(this.contactSolvers[i]); } } - Advanced.Manager.dump("Cache Data", this.bodyArr[1]); + // 11) Cache Body Data + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i] && this.bodies[i].isDynamic && this.bodies[i].isAwake) { + this.bodies[i].cacheData('post solve collision callback'); + } + } + Advanced.Manager.dump("Cache Data", this.bodies[1]); Advanced.Manager.writeAll(); // 12) Process sleeping - /* - if (allowSleep) - { - var minSleepTime = 999999; - - var linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE; - var angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE; - - for (var i = 0; i < bl; i++) - { - var body = this.bodyArr[i]; - - if (!this.bodyArr[i] || this.bodyArr[i].isDynamic == false) - { - continue; + if(allowSleep) { + this._minSleepTime = 999999; + for(var i = 0; i < this._bl; i++) { + if(!this.bodies[i] || this.bodies[i].isDynamic == false) { + continue; + } + if(this.bodies[i].angularVelocity * this.bodies[i].angularVelocity > this._angTolSqr || this.bodies[i].velocity.dot(this.bodies[i].velocity) > this._linTolSqr) { + this.bodies[i].sleepTime = 0; + this._minSleepTime = 0; + } else { + this.bodies[i].sleepTime += this._delta; + this._minSleepTime = Math.min(this._minSleepTime, this.bodies[i].sleepTime); + } + } + if(this._positionSolved && this._minSleepTime >= Space.TIME_TO_SLEEP) { + for(var i = 0; i < this._bl; i++) { + if(this.bodies[i]) { + this.bodies[i].awake(false); + } + } + } } - - if (body.angularVelocity * body.angularVelocity > angTolSqr || body.velocity.dot(body.velocity) > linTolSqr) - { - body.sleepTime = 0; - minSleepTime = 0; - } - else - { - body.sleepTime += dt; - minSleepTime = Math.min(minSleepTime, body.sleepTime); - } - } - - if (positionSolved && minSleepTime >= Space.TIME_TO_SLEEP) - { - for (var i = 0; i < this.bodyArr.length; i++) - { - var body = this.bodyArr[i]; - - if (!body) - { - continue; - } - - body.awake(false); - } - } - } - */ - }; + }; return Space; })(); Advanced.Space = Space; @@ -21597,6 +21569,7 @@ var Phaser; // Check not already part of this body shape.body = this; this.shapes.push(shape); + this.shapesLength = this.shapes.length; return shape; }; Body.prototype.removeShape = function (shape) { @@ -21605,6 +21578,7 @@ var Phaser; this.shapes.splice(index, 1); shape.body = undefined; } + this.shapesLength = this.shapes.length; }; Body.prototype.setMass = function (mass) { this.mass = mass;