From 7aaa63e7a530e8b632e17f4c44cfd3bd134a0cd8 Mon Sep 17 00:00:00 2001 From: photonstorm Date: Tue, 25 Nov 2014 12:09:03 +0000 Subject: [PATCH] When you change State the P2 Physics world is no longer fully cleared. All of the bodies, springs, fixtures, materials and constraints are removed - but config settings such as gravity, restitution, the contact solver, etc are all retained. The P2.World object is only created the very first time you call Physics.startSystem. Every subsequent call hits P2.World.reset instead (#1292) --- README.md | 1 + src/physics/Physics.js | 48 ++++++++++++++++++-------- src/physics/p2/World.js | 75 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 7caecc526..97e68aa97 100644 --- a/README.md +++ b/README.md @@ -248,6 +248,7 @@ This fixes a bug in FF where it would use the default DOMMouseWheel (thanks @pns * Camera.totalInView is a new property that contains the total number of Sprites rendered that have `autoCull` set to true and are within the Cameras view. * Emitter.setScale fixed minX minY order presedence (thanks spayton) * Group.iterate can now accept undefined/null as the arguments (thanks @pnstickne #1353 @tasos-ch #1352) +* When you change State the P2 Physics world is no longer fully cleared. All of the bodies, springs, fixtures, materials and constraints are removed - but config settings such as gravity, restitution, the contact solver, etc are all retained. The P2.World object is only created the very first time you call Physics.startSystem. Every subsequent call hits P2.World.reset instead (#1292) ### Pixi 2.1.0 New Features diff --git a/src/physics/Physics.js b/src/physics/Physics.js index 08ae69158..1bdb6d057 100644 --- a/src/physics/Physics.js +++ b/src/physics/Physics.js @@ -6,8 +6,9 @@ /** * The Physics Manager is responsible for looking after all of the running physics systems. -* Phaser supports 3 physics systems: Arcade Physics, P2 and Ninja Physics (with Box2D and Chipmunk in development) -* Game Objects can belong to only 1 physics system, but you can have multiple systems active in a single game. +* Phaser supports 4 physics systems: Arcade Physics, P2, Ninja Physics and Box2D via a commercial plugin. +* +* Game Objects (such as Sprites) can only belong to 1 physics system, but you can have multiple systems active in a single game. * * For example you could have P2 managing a polygon-built terrain landscape that an vehicle drives over, while it could be firing bullets that use the * faster (due to being much simpler) Arcade Physics system. @@ -42,12 +43,12 @@ Phaser.Physics = function (game, config) { this.p2 = null; /** - * @property {Phaser.Physics.Ninja} ninja - The N+ Ninja Physics System. + * @property {Phaser.Physics.Ninja} ninja - The N+ Ninja Physics system. */ this.ninja = null; /** - * @property {Phaser.Physics.Box2D} box2d - The Box2D Physics system (to be done). + * @property {Phaser.Physics.Box2D} box2d - The Box2D Physics system. */ this.box2d = null; @@ -126,13 +127,22 @@ Phaser.Physics.prototype = { /** * This will create an instance of the requested physics simulation. * Phaser.Physics.Arcade is running by default, but all others need activating directly. + * * You can start the following physics systems: + * * Phaser.Physics.P2JS - A full-body advanced physics system by Stefan Hedman. * Phaser.Physics.NINJA - A port of Metanet Softwares N+ physics system. - * Phaser.Physics.BOX2D and Phaser.Physics.CHIPMUNK are still in development. + * Phaser.Physics.BOX2D - A commercial Phaser Plugin (see http://phaser.io) + * + * Both Ninja Physics and Box2D require their respective plugins to be loaded before you can start them. + * They are not bundled into the core Phaser library. + * + * If the physics world has already been created (i.e. in another state in your game) then + * calling startSystem will reset the physics world, not re-create it. If you need to start them again from their constructors + * then set Phaser.Physics.p2 (or whichever system you want to recreate) to `null` before calling `startSystem`. * * @method Phaser.Physics#startSystem - * @param {number} The physics system to start. + * @param {number} system - The physics system to start: Phaser.Physics.ARCADE, Phaser.Physics.P2JS, Phaser.Physics.NINJA or Phaser.Physics.BOX2D. */ startSystem: function (system) { @@ -142,19 +152,29 @@ Phaser.Physics.prototype = { } else if (system === Phaser.Physics.P2JS) { - this.p2 = new Phaser.Physics.P2(this.game, this.config); + if (this.p2 === null) + { + this.p2 = new Phaser.Physics.P2(this.game, this.config); + } + else + { + this.p2.reset(); + } } - if (system === Phaser.Physics.NINJA) + else if (system === Phaser.Physics.NINJA) { this.ninja = new Phaser.Physics.Ninja(this.game); } - else if (system === Phaser.Physics.BOX2D && this.box2d === null) + else if (system === Phaser.Physics.BOX2D) { - this.box2d = new Phaser.Physics.Box2D(this.game, this.config); - } - else if (system === Phaser.Physics.CHIPMUNK && this.chipmunk === null) - { - throw new Error('The Chipmunk physics system has not been implemented yet.'); + if (this.box2d === null) + { + this.box2d = new Phaser.Physics.Box2D(this.game, this.config); + } + else + { + this.box2d.reset(); + } } }, diff --git a/src/physics/p2/World.js b/src/physics/p2/World.js index 7461fb8bc..0a17ba360 100644 --- a/src/physics/p2/World.js +++ b/src/physics/p2/World.js @@ -671,7 +671,7 @@ Phaser.Physics.P2.prototype = { */ update: function () { - // Do nothing when the pysics engine was paused before + // Do nothing if the physics engine was paused before if (this.paused) { return; @@ -688,14 +688,84 @@ Phaser.Physics.P2.prototype = { }, + /** + * Called by Phaser.Physics when a State swap occurs. + * Starts the begin and end Contact listeners again. + * + * @method Phaser.Physics.P2#reset + */ + reset: function () { + + this.world.on("beginContact", this.beginContactHandler, this); + this.world.on("endContact", this.endContactHandler, this); + + this.nothingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(1); + this.boundsCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2); + this.everythingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2147483648); + + this._collisionGroupID = 2; + + this.setBoundsToWorld(true, true, true, true, false); + + }, + /** * Clears all bodies from the simulation, resets callbacks and resets the collision bitmask. + * + * The P2 world is also cleared: + * + * * Removes all solver equations + * * Removes all constraints + * * Removes all bodies + * * Removes all springs + * * Removes all contact materials + * + * This is called automatically when you switch state. * * @method Phaser.Physics.P2#clear */ clear: function () { - this.world.clear(); + this.world.time = 0; + this.world.fixedStepTime = 0; + + // Remove all solver equations + if (this.world.solver && this.world.solver.equations.length) + { + this.world.solver.removeAllEquations(); + } + + // Remove all constraints + var cs = this.world.constraints; + + for (var i = cs.length - 1; i >= 0; i--) + { + this.world.removeConstraint(cs[i]); + } + + // Remove all bodies + var bodies = this.world.bodies; + + for (var i = bodies.length - 1; i >= 0; i--) + { + this.world.removeBody(bodies[i]); + } + + // Remove all springs + var springs = this.world.springs; + + for (var i = springs.length - 1; i >= 0; i--) + { + this.world.removeSpring(springs[i]); + } + + // Remove all contact materials + var cms = this.world.contactMaterials; + + for (var i = cms.length - 1; i >= 0; i--) + { + this.world.removeContactMaterial(cms[i]); + } this.world.off("beginContact", this.beginContactHandler, this); this.world.off("endContact", this.endContactHandler, this); @@ -706,7 +776,6 @@ Phaser.Physics.P2.prototype = { this.collisionGroups = []; this._toRemove = []; - this._collisionGroupID = 2; this.boundsCollidesWith = []; },