diff --git a/README.md b/README.md
index 8ae0ef02..9634ff9a 100644
--- a/README.md
+++ b/README.md
@@ -214,6 +214,7 @@ Bug Fixes:
* You can now load in CSV Tilemaps again and they get created properly (fixes #391)
* Tilemap.putTile can now insert a tile into a null/blank area of the map (before it could only replace existing tiles)
* Tilemap.putTile now correctly re-calculates the collision data based on the new collideIndexes array (fixes #371)
+* Circle.circumferencePoint using the asDegrees parameter would apply degToRad instead of radToDeg (thanks Ziriax, fixes #509)
TO DO:
diff --git a/build/config.php b/build/config.php
index aa105f96..1281d836 100644
--- a/build/config.php
+++ b/build/config.php
@@ -135,14 +135,20 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -154,4 +160,12 @@
EOL;
+
+/*
+
+
+
+
+*/
+
?>
\ No newline at end of file
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index 44e3ac6b..79b54741 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -1450,7 +1450,7 @@ declare module Phaser {
static intersectsRectangle(c: Phaser.Circle, r: Phaser.Rectangle): boolean;
//methods
circumference(): number;
- circumferencePoint(angle: number, asDegrees: number, output?: Phaser.Point): Phaser.Point;
+ circumferencePoint(angle: number, asDegrees: boolean, output?: Phaser.Point): Phaser.Point;
clone(out: Phaser.Circle): Phaser.Circle;
contains(x: number, y: number): boolean;
copyFrom(source: any): Circle;
diff --git a/examples/wip/physics-1.js b/examples/wip/physics-1.js
new file mode 100644
index 00000000..b50fd293
--- /dev/null
+++ b/examples/wip/physics-1.js
@@ -0,0 +1,54 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('atari', 'assets/sprites/atari130xe.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+
+}
+
+var sprite1;
+var sprite2;
+
+function create() {
+
+ game.stage.backgroundColor = '#2d2d2d';
+
+ // This will check Sprite vs. Sprite collision
+
+ sprite1 = game.add.sprite(50, 200, 'atari');
+ sprite1.name = 'atari';
+
+ sprite2 = game.add.sprite(700, 220, 'mushroom');
+ sprite2.name = 'mushroom';
+
+ // Enable the physics bodies of both sprites
+ game.physics.enable([sprite1, sprite2]);
+
+ // And move 'em
+ sprite1.body.velocity.x = 100;
+ sprite2.body.velocity.x = -100;
+
+}
+
+function update() {
+
+ // object1, object2, collideCallback, processCallback, callbackContext
+ game.physics.arcade.collide(sprite1, sprite2, collisionHandler, null, this);
+
+}
+
+function collisionHandler (obj1, obj2) {
+
+ // The two sprites are colliding
+ game.stage.backgroundColor = '#992d2d';
+
+}
+
+function render() {
+
+ // game.debug.physicsBody(sprite1.body);
+ // game.debug.physicsBody(sprite2.body);
+
+}
\ No newline at end of file
diff --git a/src/animation/Animation.js b/src/animation/Animation.js
index e410ed21..74412c42 100644
--- a/src/animation/Animation.js
+++ b/src/animation/Animation.js
@@ -139,8 +139,6 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loop)
// Set-up some event listeners
this.game.onPause.add(this.onPause, this);
this.game.onResume.add(this.onResume, this);
-
- console.log('animation created', this);
};
diff --git a/src/core/Game.js b/src/core/Game.js
index 9a88793f..a3a244eb 100644
--- a/src/core/Game.js
+++ b/src/core/Game.js
@@ -172,7 +172,7 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
this.world = null;
/**
- * @property {Phaser.Physics.World} physics - Reference to the physics world.
+ * @property {Phaser.Physics} physics - Reference to the physics manager.
*/
this.physics = null;
@@ -414,7 +414,7 @@ Phaser.Game.prototype = {
this.tweens = new Phaser.TweenManager(this);
this.input = new Phaser.Input(this);
this.sound = new Phaser.SoundManager(this);
- this.physics = new Phaser.Physics.World(this, this.physicsConfig);
+ this.physics = new Phaser.Physics(this, this.physicsConfig);
this.particles = new Phaser.Particles(this);
this.plugins = new Phaser.PluginManager(this, this);
this.net = new Phaser.Net(this);
diff --git a/src/core/GameNoPhysics.js b/src/core/GameNoPhysics.js
deleted file mode 100644
index d4b69b6b..00000000
--- a/src/core/GameNoPhysics.js
+++ /dev/null
@@ -1,729 +0,0 @@
-/**
-* @author Richard Davey
-* @copyright 2014 Photon Storm Ltd.
-* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
-*/
-
-/**
-* Game constructor
-*
-* Instantiate a new Phaser.Game object.
-* @class Phaser.Game
-* @classdesc This is where the magic happens. The Game object is the heart of your game,
-* providing quick access to common functions and handling the boot process.
-* "Hell, there are no rules here - we're trying to accomplish something."
-* Thomas A. Edison
-* @constructor
-* @param {number} [width=800] - The width of your game in game pixels.
-* @param {number} [height=600] - The height of your game in game pixels.
-* @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all).
-* @param {string|HTMLElement} [parent=''] - The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself.
-* @param {object} [state=null] - The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null.
-* @param {boolean} [transparent=false] - Use a transparent canvas background or not.
-* @param {boolean} [antialias=true] - Draw all image textures anti-aliased or not. The default is for smooth textures, but disable if your game features pixel art.
-*/
-Phaser.Game = function (width, height, renderer, parent, state, transparent, antialias) {
-
- /**
- * @property {number} id - Phaser Game ID (for when Pixi supports multiple instances).
- */
- this.id = Phaser.GAMES.push(this) - 1;
-
- /**
- * @property {object} config - The Phaser.Game configuration object.
- */
- this.config = null;
-
- /**
- * @property {HTMLElement} parent - The Games DOM parent.
- * @default
- */
- this.parent = '';
-
- /**
- * @property {number} width - The Game width (in pixels).
- * @default
- */
- this.width = 800;
-
- /**
- * @property {number} height - The Game height (in pixels).
- * @default
- */
- this.height = 600;
-
- /**
- * @property {boolean} transparent - Use a transparent canvas background or not.
- * @default
- */
- this.transparent = false;
-
- /**
- * @property {boolean} antialias - Anti-alias graphics (in WebGL this helps with edges, in Canvas2D it retains pixel-art quality).
- * @default
- */
- this.antialias = true;
-
- /**
- * @property {number} renderer - The Pixi Renderer
- * @default
- */
- this.renderer = Phaser.AUTO;
-
- /**
- * @property {number} renderType - The Renderer this game will use. Either Phaser.AUTO, Phaser.CANVAS or Phaser.WEBGL.
- */
- this.renderType = Phaser.AUTO;
-
- /**
- * @property {number} state - The StateManager.
- */
- this.state = null;
-
- /**
- * @property {boolean} isBooted - Whether the game engine is booted, aka available.
- * @default
- */
- this.isBooted = false;
-
- /**
- * @property {boolean} id -Is game running or paused?
- * @default
- */
- this.isRunning = false;
-
- /**
- * @property {Phaser.RequestAnimationFrame} raf - Automatically handles the core game loop via requestAnimationFrame or setTimeout
- */
- this.raf = null;
-
- /**
- * @property {Phaser.GameObjectFactory} add - Reference to the Phaser.GameObjectFactory.
- */
- this.add = null;
-
- /**
- * @property {Phaser.GameObjectCreator} make - Reference to the GameObject Creator.
- */
- this.make = null;
-
- /**
- * @property {Phaser.Cache} cache - Reference to the assets cache.
- * @default
- */
- this.cache = null;
-
- /**
- * @property {Phaser.Input} input - Reference to the input manager
- * @default
- */
- this.input = null;
-
- /**
- * @property {Phaser.Loader} load - Reference to the assets loader.
- * @default
- */
- this.load = null;
-
- /**
- * @property {Phaser.Math} math - Reference to the math helper.
- */
- this.math = null;
-
- /**
- * @property {Phaser.Net} net - Reference to the network class.
- */
- this.net = null;
-
- /**
- * @property {Phaser.ScaleManager} scale - The game scale manager.
- */
- this.scale = null;
-
- /**
- * @property {Phaser.SoundManager} sound - Reference to the sound manager.
- */
- this.sound = null;
-
- /**
- * @property {Phaser.Stage} stage - Reference to the stage.
- */
- this.stage = null;
-
- /**
- * @property {Phaser.TimeManager} time - Reference to game clock.
- */
- this.time = null;
-
- /**
- * @property {Phaser.TweenManager} tweens - Reference to the tween manager.
- */
- this.tweens = null;
-
- /**
- * @property {Phaser.World} world - Reference to the world.
- */
- this.world = null;
-
- /**
- * @property {Phaser.RandomDataGenerator} rnd - Instance of repeatable random data generator helper.
- */
- this.rnd = null;
-
- /**
- * @property {Phaser.Device} device - Contains device information and capabilities.
- */
- this.device = null;
-
- /**
- * @property {Phaser.Physics.PhysicsManager} camera - A handy reference to world.camera.
- */
- this.camera = null;
-
- /**
- * @property {HTMLCanvasElement} canvas - A handy reference to renderer.view, the canvas that the game is being rendered in to.
- */
- this.canvas = null;
-
- /**
- * @property {Context} context - A handy reference to renderer.context (only set for CANVAS games, not WebGL)
- */
- this.context = null;
-
- /**
- * @property {Phaser.Utils.Debug} debug - A set of useful debug utilitie.
- */
- this.debug = null;
-
- /**
- * @property {boolean} stepping - Enable core loop stepping with Game.enableStep().
- * @default
- * @readonly
- */
- this.stepping = false;
-
- /**
- * @property {boolean} stepping - An internal property used by enableStep, but also useful to query from your own game objects.
- * @default
- * @readonly
- */
- this.pendingStep = false;
-
- /**
- * @property {number} stepCount - When stepping is enabled this contains the current step cycle.
- * @default
- * @readonly
- */
- this.stepCount = 0;
-
- /**
- * @property {boolean} _paused - Is game paused?
- * @private
- * @default
- */
- this._paused = false;
-
- /**
- * @property {boolean} _codePaused - Was the game paused via code or a visibility change?
- * @private
- * @default
- */
- this._codePaused = false;
-
- // Parse the configuration object (if any)
- if (arguments.length === 1 && typeof arguments[0] === 'object')
- {
- this.parseConfig(arguments[0]);
- }
- else
- {
- if (typeof width !== 'undefined')
- {
- this.width = width;
- }
-
- if (typeof height !== 'undefined')
- {
- this.height = height;
- }
-
- if (typeof renderer !== 'undefined')
- {
- this.renderer = renderer;
- this.renderType = renderer;
- }
-
- if (typeof parent !== 'undefined')
- {
- this.parent = parent;
- }
-
- if (typeof transparent !== 'undefined')
- {
- this.transparent = transparent;
- }
-
- if (typeof antialias !== 'undefined')
- {
- this.antialias = antialias;
- }
-
- this.state = new Phaser.StateManager(this, state);
- }
-
- var _this = this;
-
- this._onBoot = function () {
- return _this.boot();
- }
-
- if (document.readyState === 'complete' || document.readyState === 'interactive')
- {
- window.setTimeout(this._onBoot, 0);
- }
- else
- {
- document.addEventListener('DOMContentLoaded', this._onBoot, false);
- window.addEventListener('load', this._onBoot, false);
- }
-
- return this;
-
-};
-
-Phaser.Game.prototype = {
-
- /**
- * Parses a Game configuration object.
- *
- * @method Phaser.Game#parseConfig
- * @protected
- */
- parseConfig: function (config) {
-
- this.config = config;
-
- if (config['width'])
- {
- this.width = Phaser.Utils.parseDimension(config['width'], 0);
- }
-
- if (config['height'])
- {
- this.height = Phaser.Utils.parseDimension(config['height'], 1);
- }
-
- if (config['renderer'])
- {
- this.renderer = config['renderer'];
- this.renderType = config['renderer'];
- }
-
- if (config['parent'])
- {
- this.parent = config['parent'];
- }
-
- if (config['transparent'])
- {
- this.transparent = config['transparent'];
- }
-
- if (config['antialias'])
- {
- this.antialias = config['antialias'];
- }
-
- var state = null;
-
- if (config['state'])
- {
- state = config['state'];
- }
-
- this.state = new Phaser.StateManager(this, state);
-
- },
-
- /**
- * Initialize engine sub modules and start the game.
- *
- * @method Phaser.Game#boot
- * @protected
- */
- boot: function () {
-
- if (this.isBooted)
- {
- return;
- }
-
- if (!document.body)
- {
- window.setTimeout(this._onBoot, 20);
- }
- else
- {
- document.removeEventListener('DOMContentLoaded', this._onBoot);
- window.removeEventListener('load', this._onBoot);
-
- this.onPause = new Phaser.Signal();
- this.onResume = new Phaser.Signal();
-
- this.isBooted = true;
-
- this.device = new Phaser.Device(this);
- this.math = Phaser.Math;
- this.rnd = new Phaser.RandomDataGenerator([(Date.now() * Math.random()).toString()]);
-
- this.stage = new Phaser.Stage(this, this.width, this.height);
- this.scale = new Phaser.ScaleManager(this, this.width, this.height);
-
- this.setUpRenderer();
-
- this.device.checkFullScreenSupport();
-
- this.world = new Phaser.World(this);
- this.add = new Phaser.GameObjectFactory(this);
- this.make = new Phaser.GameObjectCreator(this);
- this.cache = new Phaser.Cache(this);
- this.load = new Phaser.Loader(this);
- this.time = new Phaser.Time(this);
- this.tweens = new Phaser.TweenManager(this);
- this.input = new Phaser.Input(this);
- this.sound = new Phaser.SoundManager(this);
- this.plugins = new Phaser.PluginManager(this, this);
- this.net = new Phaser.Net(this);
- this.debug = new Phaser.Utils.Debug(this);
-
- this.time.boot();
- this.stage.boot();
- this.world.boot();
- this.input.boot();
- this.sound.boot();
- this.state.boot();
-
- this.showDebugHeader();
-
- this.isRunning = true;
-
- if (this.config && this.config['forceSetTimeOut'])
- {
- this.raf = new Phaser.RequestAnimationFrame(this, this.config['forceSetTimeOut']);
- }
- else
- {
- this.raf = new Phaser.RequestAnimationFrame(this, false);
- }
-
- this.raf.start();
- }
-
- },
-
- /**
- * Displays a Phaser version debug header in the console.
- *
- * @method Phaser.Game#showDebugHeader
- * @protected
- */
- showDebugHeader: function () {
-
- var v = Phaser.DEV_VERSION;
- var r = 'Canvas';
- var a = 'HTML Audio';
-
- if (this.renderType == Phaser.WEBGL)
- {
- r = 'WebGL';
- }
- else if (this.renderType == Phaser.HEADLESS)
- {
- r = 'Headless';
- }
-
- if (this.device.webAudio)
- {
- a = 'WebAudio';
- }
-
- if (this.device.chrome)
- {
- var args = [
- '%c %c %c Phaser v' + v + ' - Renderer: ' + r + ' - Audio: ' + a + ' %c %c ',
- 'background: #00bff3',
- 'background: #0072bc',
- 'color: #ffffff; background: #003471',
- 'background: #0072bc',
- 'background: #00bff3'
- ];
-
- console.log.apply(console, args);
- }
- else
- {
- console.log('Phaser v' + v + '.np - Renderer: ' + r + ' - Audio: ' + a);
- }
-
- },
-
- /**
- * Checks if the device is capable of using the requested renderer and sets it up or an alternative if not.
- *
- * @method Phaser.Game#setUpRenderer
- * @protected
- */
- setUpRenderer: function () {
-
- if (this.device.trident)
- {
- // Pixi WebGL renderer on IE11 doesn't work correctly at the moment, the pre-multiplied alpha gets all washed out.
- // So we're forcing canvas for now until this is fixed, sorry. It's got to be better than no game appearing at all, right?
- this.renderType = Phaser.CANVAS;
- }
-
- if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false))
- {
- if (this.device.canvas)
- {
- if (this.renderType === Phaser.AUTO)
- {
- this.renderType = Phaser.CANVAS;
- }
-
- this.renderer = new PIXI.CanvasRenderer(this.width, this.height, this.canvas, this.transparent);
- this.context = this.renderer.context;
- }
- else
- {
- throw new Error('Phaser.Game - cannot create Canvas or WebGL context, aborting.');
- }
- }
- else
- {
- // They requested WebGL, and their browser supports it
- this.renderType = Phaser.WEBGL;
- this.renderer = new PIXI.WebGLRenderer(this.width, this.height, this.canvas, this.transparent, this.antialias);
- this.context = null;
- }
-
- if (!this.antialias)
- {
- this.stage.smoothed = false;
- }
-
- Phaser.Canvas.addToDOM(this.canvas, this.parent, true);
- Phaser.Canvas.setTouchAction(this.canvas);
-
- },
-
- /**
- * The core game loop.
- *
- * @method Phaser.Game#update
- * @protected
- * @param {number} time - The current time as provided by RequestAnimationFrame.
- */
- update: function (time) {
-
- this.time.update(time);
-
- if (this._paused)
- {
- this.input.update();
-
- if (this.renderType !== Phaser.HEADLESS)
- {
- this.renderer.render(this.stage);
- this.plugins.render();
- this.state.render();
-
- this.plugins.postRender();
- }
- }
- else
- {
- if (!this.pendingStep)
- {
- if (this.stepping)
- {
- this.pendingStep = true;
- }
-
- this.state.preUpdate();
- this.plugins.preUpdate();
- this.stage.preUpdate();
-
- this.stage.update();
- this.tweens.update();
- this.sound.update();
- this.input.update();
- this.state.update();
- this.plugins.update();
-
- this.stage.postUpdate();
- this.plugins.postUpdate();
- }
-
- if (this.renderType !== Phaser.HEADLESS)
- {
- this.renderer.render(this.stage);
- this.plugins.render();
- this.state.render();
-
- this.plugins.postRender();
- }
- }
-
- },
-
- /**
- * Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?)
- * Calling step will advance the game loop by one frame. This is extremely useful to hard to track down errors!
- *
- * @method Phaser.Game#enableStep
- */
- enableStep: function () {
-
- this.stepping = true;
- this.pendingStep = false;
- this.stepCount = 0;
-
- },
-
- /**
- * Disables core game loop stepping.
- *
- * @method Phaser.Game#disableStep
- */
- disableStep: function () {
-
- this.stepping = false;
- this.pendingStep = false;
-
- },
-
- /**
- * When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame.
- * This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress.
- *
- * @method Phaser.Game#step
- */
- step: function () {
-
- this.pendingStep = false;
- this.stepCount++;
-
- },
-
- /**
- * Nuke the entire game from orbit
- *
- * @method Phaser.Game#destroy
- */
- destroy: function () {
-
- this.raf.stop();
-
- this.input.destroy();
-
- this.state.destroy();
-
- this.state = null;
- this.cache = null;
- this.input = null;
- this.load = null;
- this.sound = null;
- this.stage = null;
- this.time = null;
- this.world = null;
- this.isBooted = false;
-
- },
-
- /**
- * Called by the Stage visibility handler.
- *
- * @method Phaser.Game#gamePaused
- */
- gamePaused: function (time) {
-
- // If the game is already paused it was done via game code, so don't re-pause it
- if (!this._paused)
- {
- this._paused = true;
- this.time.gamePaused(time);
- this.sound.setMute();
- this.onPause.dispatch(this);
- }
-
- },
-
- /**
- * Called by the Stage visibility handler.
- *
- * @method Phaser.Game#gameResumed
- */
- gameResumed: function (time) {
-
- // Game is paused, but wasn't paused via code, so resume it
- if (this._paused && !this._codePaused)
- {
- this._paused = false;
- this.time.gameResumed(time);
- this.input.reset();
- this.sound.unsetMute();
- this.onResume.dispatch(this);
- }
-
- }
-
-};
-
-Phaser.Game.prototype.constructor = Phaser.Game;
-
-/**
-* The paused state of the Game. A paused game doesn't update any of its subsystems.
-* When a game is paused the onPause event is dispatched. When it is resumed the onResume event is dispatched.
-* @name Phaser.Game#paused
-* @property {boolean} paused - Gets and sets the paused state of the Game.
-*/
-Object.defineProperty(Phaser.Game.prototype, "paused", {
-
- get: function () {
- return this._paused;
- },
-
- set: function (value) {
-
- if (value === true)
- {
- if (this._paused === false)
- {
- this._paused = true;
- this._codePaused = true;
- this.sound.mute = true;
- this.time.gamePaused();
- this.onPause.dispatch(this);
- }
- }
- else
- {
- if (this._paused)
- {
- this._paused = false;
- this._codePaused = false;
- this.input.reset();
- this.sound.mute = false;
- this.time.gameResumed();
- this.onResume.dispatch(this);
- }
- }
-
- }
-
-});
-
-/**
-* "Deleted code is debugged code." - Jeff Sickel
-*/
diff --git a/src/core/StateManager.js b/src/core/StateManager.js
index bffda116..2abbcd9b 100644
--- a/src/core/StateManager.js
+++ b/src/core/StateManager.js
@@ -286,10 +286,7 @@ Phaser.StateManager.prototype = {
this.game.world.destroy();
- if (this.game.physics)
- {
- this.game.physics.clear();
- }
+ this.game.physics.clear();
if (this._clearCache === true)
{
@@ -388,11 +385,7 @@ Phaser.StateManager.prototype = {
this.states[key].world = this.game.world;
this.states[key].particles = this.game.particles;
this.states[key].rnd = this.game.rnd;
-
- if (this.game.physics)
- {
- this.states[key].physics = this.game.physics;
- }
+ this.states[key].physics = this.game.physics;
},
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index a4e54fb4..b8582f5a 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -466,18 +466,11 @@ Phaser.Image.prototype.reset = function(x, y) {
* @memberof Phaser.Image
* @return {Phaser.Image} This instance.
*/
-Phaser.Image.prototype.bringToTop = function(child) {
+Phaser.Image.prototype.bringToTop = function() {
- if (typeof child === 'undefined')
+ if (this.parent)
{
- if (this.parent)
- {
- this.parent.bringToTop(this);
- }
- }
- else
- {
-
+ this.parent.bringToTop(this);
}
return this;
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 8dfc32e6..b7f75483 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -99,7 +99,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.input = null;
/**
- * @property {Phaser.Physics.Body|null} body - The Sprites physics Body. Will be null unless physics has been enabled via `Sprite.physicsEnabled = true`.
+ * @property {Phaser.Physics.Arcade.Body|Phaser.Physics.P2.Body|null} body - The Sprites physics Body. Will be null unless physics has been enabled via `Sprite.physicsEnabled = true`.
*/
this.body = null;
@@ -253,6 +253,11 @@ Phaser.Sprite.prototype.preUpdate = function() {
this.animations.update();
+ if (this.exists && this.body)
+ {
+ this.body.preUpdate();
+ }
+
// Update any Children
for (var i = 0, len = this.children.length; i < len; i++)
{
@@ -287,12 +292,9 @@ Phaser.Sprite.prototype.postUpdate = function() {
this.key.render();
}
- if (this.exists)
+ if (this.exists && this.body)
{
- if (this.body)
- {
- this.body.postUpdate();
- }
+ this.body.postUpdate();
}
// Fixed to Camera?
@@ -624,18 +626,11 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
* @memberof Phaser.Sprite
* @return (Phaser.Sprite) This instance.
*/
-Phaser.Sprite.prototype.bringToTop = function(child) {
+Phaser.Sprite.prototype.bringToTop = function() {
- if (typeof child === 'undefined')
+ if (this.parent)
{
- if (this.parent)
- {
- this.parent.bringToTop(this);
- }
- }
- else
- {
-
+ this.parent.bringToTop(this);
}
return this;
@@ -856,16 +851,15 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
});
/**
-* By default Sprites won't add themselves to the physics world. By setting physicsEnabled to true a Rectangle physics body is
+* By default Sprites won't add themselves to the physics simulation. By setting physicsEnabled to true a Rectangle physics body is
* attached to this Sprite matching its placement and dimensions, and will then start to process physics world updates.
* You can access all physics related properties via Sprite.body.
*
-* Important: Enabling a Sprite for physics will automatically set `Sprite.anchor` to 0.5 s0 the physics body is centered on the Sprite.
+* Important: Enabling a Sprite for physics will automatically set `Sprite.anchor` to 0.5 so the physics body is centered on the Sprite.
* If you need a different result then adjust or re-create the Body shape offsets manually, and/or reset the anchor after enabling physics.
*
* @name Phaser.Sprite#physicsEnabled
* @property {boolean} physicsEnabled - Set to true to add this Sprite to the physics world. Set to false to destroy the body and remove it from the physics world.
-*/
Object.defineProperty(Phaser.Sprite.prototype, "physicsEnabled", {
get: function () {
@@ -894,6 +888,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "physicsEnabled", {
}
});
+*/
/**
* Sprite.exists controls if the core game loop and physics update this Sprite or not.
diff --git a/src/geom/Circle.js b/src/geom/Circle.js
index c755f013..60511440 100644
--- a/src/geom/Circle.js
+++ b/src/geom/Circle.js
@@ -482,7 +482,7 @@ Phaser.Circle.circumferencePoint = function (a, angle, asDegrees, out) {
if (asDegrees === true)
{
- angle = Phaser.Math.radToDeg(angle);
+ angle = Phaser.Math.degToRad(angle);
}
out.x = a.x + a.radius * Math.cos(angle);
diff --git a/src/physics/Physics.js b/src/physics/Physics.js
new file mode 100644
index 00000000..d275a52a
--- /dev/null
+++ b/src/physics/Physics.js
@@ -0,0 +1,145 @@
+/**
+* @author Richard Davey
+* @copyright 2014 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* The Physics manager.
+*
+* @class Phaser.Physics
+*
+* @classdesc todo
+*
+* @constructor
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {object} [physicsConfig=null] - A physics configuration object to pass to the Physics world on creation.
+*/
+Phaser.Physics = function (game, config) {
+
+ /**
+ * @property {Phaser.Game} game - Local reference to game.
+ */
+ this.game = game;
+
+ this.config = config;
+
+ this.arcade = new Phaser.Physics.Arcade(game);
+
+ this.p2 = null;
+
+ this.box2d = null;
+
+ this.chipmunk = null;
+
+};
+
+/**
+* @const
+* @type {number}
+*/
+Phaser.Physics.ARCADE = 0;
+
+/**
+* @const
+* @type {number}
+*/
+Phaser.Physics.P2 = 1;
+
+/**
+* @const
+* @type {number}
+*/
+Phaser.Physics.BOX2D = 2;
+
+/**
+* @const
+* @type {number}
+*/
+Phaser.Physics.CHIPMUNK = 3;
+
+Phaser.Physics.prototype = {
+
+ startSystem: function (system) {
+
+ if (system === Phaser.Physics.ARCADE)
+ {
+ this.arcade = new Phaser.Physics.Arcade(this.game);
+ }
+ else if (system === Phaser.Physics.P2)
+ {
+ this.p2 = new Phaser.Physics.P2(this.game, this.config);
+ }
+ else if (system === Phaser.Physics.BOX2D)
+ {
+ // Coming soon
+ }
+ else if (system === Phaser.Physics.CHIPMUNK)
+ {
+ // Coming soon
+ }
+
+ },
+
+ // Enables a sprites physics body
+ enable: function (object, system) {
+
+ if (typeof system === 'undefined') { system = Phaser.Physics.ARCADE; }
+
+ var i = 1;
+
+ if (Array.isArray(object))
+ {
+ // Add to Group
+ i = object.length;
+ }
+ else
+ {
+ object = [object];
+ }
+
+ while (i--)
+ {
+ if (object[i].body === null)
+ {
+ if (system === Phaser.Physics.ARCADE)
+ {
+ object[i].body = new Phaser.Physics.Arcade.Body(object[i]);
+ }
+ else if (system === Phaser.Physics.P2)
+ {
+ object[i].body = new Phaser.Physics.P2.Body(this.game, object[i], object[i].x, object[i].y, 1);
+ object[i].anchor.set(0.5);
+ }
+ }
+ }
+
+ },
+
+ update: function () {
+
+ // ArcadePhysics doesn't have a core to update
+
+ if (this.p2)
+ {
+ this.p2.update();
+ }
+
+ },
+
+ setBoundsToWorld: function () {
+
+ },
+
+ clear: function () {
+
+ if (this.p2)
+ {
+ this.p2.clear();
+ }
+
+ }
+
+};
+
+Phaser.Physics.prototype.constructor = Phaser.Physics;
diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js
new file mode 100644
index 00000000..8ca528fa
--- /dev/null
+++ b/src/physics/arcade/Body.js
@@ -0,0 +1,635 @@
+/**
+* @author Richard Davey
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* The Physics Body is linked to a single Sprite. All physics operations should be performed against the body rather than
+* the Sprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.
+*
+* @class Phaser.Physics.Arcade.Body
+* @classdesc Arcade Physics Body Constructor
+* @constructor
+* @param {Phaser.Sprite} sprite - The Sprite object this physics body belongs to.
+*/
+Phaser.Physics.Arcade.Body = function (sprite) {
+
+ /**
+ * @property {Phaser.Sprite} sprite - Reference to the parent Sprite.
+ */
+ this.sprite = sprite;
+
+ /**
+ * @property {Phaser.Game} game - Local reference to game.
+ */
+ this.game = sprite.game;
+
+ /**
+ * @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position.
+ */
+ this.offset = new Phaser.Point();
+
+ /**
+ * @property {number} x - The x position of the physics body.
+ * @readonly
+ */
+ this.x = sprite.x;
+
+ /**
+ * @property {number} y - The y position of the physics body.
+ * @readonly
+ */
+ this.y = sprite.y;
+
+ /**
+ * @property {number} preX - The previous x position of the physics body.
+ * @readonly
+ */
+ this.preX = sprite.x;
+
+ /**
+ * @property {number} preY - The previous y position of the physics body.
+ * @readonly
+ */
+ this.preY = sprite.y;
+
+ /**
+ * @property {number} preRotation - The previous rotation of the physics body.
+ * @readonly
+ */
+ this.preRotation = sprite.angle;
+
+ /**
+ * @property {number} screenX - The x position of the physics body translated to screen space.
+ * @readonly
+ */
+ this.screenX = sprite.x;
+
+ /**
+ * @property {number} screenY - The y position of the physics body translated to screen space.
+ * @readonly
+ */
+ this.screenY = sprite.y;
+
+ /**
+ * @property {number} sourceWidth - The un-scaled original size.
+ * @readonly
+ */
+ this.sourceWidth = sprite.texture.frame.width;
+
+ /**
+ * @property {number} sourceHeight - The un-scaled original size.
+ * @readonly
+ */
+ this.sourceHeight = sprite.texture.frame.height;
+
+ /**
+ * @property {number} width - The calculated width of the physics body.
+ */
+ this.width = sprite.width;
+
+ /**
+ * @property .numInternal ID cache
+ */
+ this.height = sprite.height;
+
+ /**
+ * @property {number} halfWidth - The calculated width / 2 of the physics body.
+ */
+ this.halfWidth = Math.floor(sprite.width / 2);
+
+ /**
+ * @property {number} halfHeight - The calculated height / 2 of the physics body.
+ */
+ this.halfHeight = Math.floor(sprite.height / 2);
+
+ /**
+ * @property {Phaser.Point} center - The center coordinate of the Physics Body.
+ */
+ this.center = new Phaser.Point(this.x + this.halfWidth, this.y + this.halfHeight);
+
+ /**
+ * @property {number} _sx - Internal cache var.
+ * @private
+ */
+ this._sx = sprite.scale.x;
+
+ /**
+ * @property {number} _sy - Internal cache var.
+ * @private
+ */
+ this._sy = sprite.scale.y;
+
+ /**
+ * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body.
+ */
+ this.velocity = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} acceleration - The velocity in pixels per second sq. of the Body.
+ */
+ this.acceleration = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} drag - The drag applied to the motion of the Body.
+ */
+ this.drag = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} gravity - A private Gravity setting for the Body.
+ */
+ this.gravity = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.
+ */
+ this.bounce = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} maxVelocity - The maximum velocity in pixels per second sq. that the Body can reach.
+ * @default
+ */
+ this.maxVelocity = new Phaser.Point(10000, 10000);
+
+ /**
+ * @property {number} angularVelocity - The angular velocity in pixels per second sq. of the Body.
+ * @default
+ */
+ this.angularVelocity = 0;
+
+ /**
+ * @property {number} angularAcceleration - The angular acceleration in pixels per second sq. of the Body.
+ * @default
+ */
+ this.angularAcceleration = 0;
+
+ /**
+ * @property {number} angularDrag - The angular drag applied to the rotation of the Body.
+ * @default
+ */
+ this.angularDrag = 0;
+
+ /**
+ * @property {number} maxAngular - The maximum angular velocity in pixels per second sq. that the Body can reach.
+ * @default
+ */
+ this.maxAngular = 1000;
+
+ /**
+ * @property {number} mass - The mass of the Body.
+ * @default
+ */
+ this.mass = 1;
+
+ /**
+ * @property {boolean} skipQuadTree - If the Body is an irregular shape you can set this to true to avoid it being added to any QuadTrees.
+ * @default
+ */
+ this.skipQuadTree = false;
+
+ // Allow collision
+
+ /**
+ * Set the allowCollision properties to control which directions collision is processed for this Body.
+ * For example allowCollision.up = false means it won't collide when the collision happened while moving up.
+ * @property {object} allowCollision - An object containing allowed collision.
+ */
+ // This would be faster as an array
+ this.allowCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
+
+ /**
+ * This object is populated with boolean values when the Body collides with another.
+ * touching.up = true means the collision happened to the top of this Body for example.
+ * @property {object} touching - An object containing touching results.
+ */
+ // This would be faster as an array
+ this.touching = { none: true, up: false, down: false, left: false, right: false };
+
+ /**
+ * This object is populated with previous touching values from the bodies previous collision.
+ * @property {object} wasTouching - An object containing previous touching results.
+ */
+ // This would be faster as an array
+ this.wasTouching = { none: true, up: false, down: false, left: false, right: false };
+
+ /**
+ * @property {number} facing - A const reference to the direction the Body is traveling or facing.
+ * @default
+ */
+ this.facing = Phaser.NONE;
+
+ /**
+ * @property {boolean} immovable - An immovable Body will not receive any impacts from other bodies.
+ * @default
+ */
+ this.immovable = false;
+
+ /**
+ * @property {boolean} moves - Set to true to allow the Physics system to move this Body, other false to move it manually.
+ * @default
+ */
+ this.moves = true;
+
+ /**
+ * @property {number} rotation - The amount the Body is rotated.
+ * @default
+ */
+ this.rotation = 0;
+
+ /**
+ * @property {boolean} allowRotation - Allow this Body to be rotated? (via angularVelocity, etc)
+ * @default
+ */
+ this.allowRotation = true;
+
+ /**
+ * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity?
+ * @default
+ */
+ this.allowGravity = true;
+
+ /**
+ * This flag allows you to disable the custom x separation that takes place by Physics.Arcade.separate.
+ * Used in combination with your own collision processHandler you can create whatever type of collision response you need.
+ * @property {boolean} customSeparateX - Use a custom separation system or the built-in one?
+ * @default
+ */
+ this.customSeparateX = false;
+
+ /**
+ * This flag allows you to disable the custom y separation that takes place by Physics.Arcade.separate.
+ * Used in combination with your own collision processHandler you can create whatever type of collision response you need.
+ * @property {boolean} customSeparateY - Use a custom separation system or the built-in one?
+ * @default
+ */
+ this.customSeparateY = false;
+
+ /**
+ * When this body collides with another, the amount of overlap is stored here.
+ * @property {number} overlapX - The amount of horizontal overlap during the collision.
+ */
+ this.overlapX = 0;
+
+ /**
+ * When this body collides with another, the amount of overlap is stored here.
+ * @property {number} overlapY - The amount of vertical overlap during the collision.
+ */
+ this.overlapY = 0;
+
+ this.hull = new Phaser.Rectangle();
+
+ /**
+ * @property {Phaser.Rectangle} hullX - The dynamically calculated hull used during collision.
+ */
+ this.hullX = new Phaser.Rectangle();
+
+ /**
+ * @property {Phaser.Rectangle} hullY - The dynamically calculated hull used during collision.
+ */
+ this.hullY = new Phaser.Rectangle();
+
+ /**
+ * If a body is overlapping with another body, but neither of them are moving (maybe they spawned on-top of each other?) this is set to true.
+ * @property {boolean} embedded - Body embed value.
+ */
+ this.embedded = false;
+
+ /**
+ * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
+ * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
+ */
+ this.collideWorldBounds = false;
+
+ this.blocked = { up: false, down: false, left: false, right: false };
+
+};
+
+Phaser.Physics.Arcade.Body.prototype = {
+
+ /**
+ * Internal method.
+ *
+ * @method Phaser.Physics.Arcade#updateBounds
+ * @protected
+ */
+ updateBounds: function (centerX, centerY, scaleX, scaleY) {
+
+ if (scaleX != this._sx || scaleY != this._sy)
+ {
+ this.width = this.sourceWidth * scaleX;
+ this.height = this.sourceHeight * scaleY;
+ this.halfWidth = Math.floor(this.width / 2);
+ this.halfHeight = Math.floor(this.height / 2);
+ this._sx = scaleX;
+ this._sy = scaleY;
+ this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
+ }
+
+ },
+
+ /**
+ * Internal method.
+ *
+ * @method Phaser.Physics.Arcade#preUpdate
+ * @protected
+ */
+ preUpdate: function () {
+
+ // Store and reset collision flags
+ this.wasTouching.none = this.touching.none;
+ this.wasTouching.up = this.touching.up;
+ this.wasTouching.down = this.touching.down;
+ this.wasTouching.left = this.touching.left;
+ this.wasTouching.right = this.touching.right;
+
+ this.touching.none = true;
+ this.touching.up = false;
+ this.touching.down = false;
+ this.touching.left = false;
+ this.touching.right = false;
+
+ this.embedded = false;
+
+ this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x;
+ this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y;
+
+ this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
+ this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
+
+ this.preRotation = this.sprite.angle;
+
+ this.x = this.preX;
+ this.y = this.preY;
+ this.rotation = this.preRotation;
+
+ // this.overlapX = 0;
+ // this.overlapY = 0;
+
+ this.blocked.up = false;
+ this.blocked.down = false;
+ this.blocked.left = false;
+ this.blocked.right = false;
+
+ if (this.moves)
+ {
+ this.game.physics.arcade.updateMotion(this);
+
+ if (this.collideWorldBounds)
+ {
+ this.checkWorldBounds();
+ }
+ }
+
+ },
+
+ /**
+ * Internal method.
+ *
+ * @method Phaser.Physics.Arcade#postUpdate
+ * @protected
+ */
+ postUpdate: function () {
+
+ // if (this.overlapX !== 0)
+ // {
+ // this.x -= this.overlapX;
+ // }
+
+ // if (this.overlapY !== 0)
+ // {
+ // this.y -= this.overlapY;
+ // }
+
+ if (this.deltaX() < 0 && this.blocked.left === false)
+ {
+ this.facing = Phaser.LEFT;
+ this.sprite.x += this.deltaX();
+ }
+ else if (this.deltaX() > 0 && this.blocked.right === false)
+ {
+ this.facing = Phaser.RIGHT;
+ this.sprite.x += this.deltaX();
+ }
+
+ if (this.deltaY() < 0 && this.blocked.up === false)
+ {
+ this.facing = Phaser.UP;
+ this.sprite.y += this.deltaY();
+ }
+ else if (this.deltaY() > 0 && this.blocked.down === false)
+ {
+ this.facing = Phaser.DOWN;
+ this.sprite.y += this.deltaY();
+ }
+
+ this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
+
+ if (this.allowRotation)
+ {
+ this.sprite.angle += this.deltaZ();
+ }
+
+ },
+
+ /**
+ * Internal method.
+ *
+ * @method Phaser.Physics.Arcade#checkWorldBounds
+ * @protected
+ */
+ checkWorldBounds: function () {
+
+ if (this.x < this.game.world.bounds.x)
+ {
+ this.x = this.game.world.bounds.x;
+ this.velocity.x *= -this.bounce.x;
+ }
+ else if (this.right > this.game.world.bounds.right)
+ {
+ this.x = this.game.world.bounds.right - this.width;
+ this.velocity.x *= -this.bounce.x;
+ }
+
+ if (this.y < this.game.world.bounds.y)
+ {
+ this.y = this.game.world.bounds.y;
+ this.velocity.y *= -this.bounce.y;
+ }
+ else if (this.bottom > this.game.world.bounds.bottom)
+ {
+ this.y = this.game.world.bounds.bottom - this.height;
+ this.velocity.y *= -this.bounce.y;
+ }
+
+ },
+
+ /**
+ * You can modify the size of the physics Body to be any dimension you need.
+ * So it could be smaller or larger than the parent Sprite. You can also control the x and y offset, which
+ * is the position of the Body relative to the top-left of the Sprite.
+ *
+ * @method Phaser.Physics.Arcade#setSize
+ * @param {number} width - The width of the Body.
+ * @param {number} height - The height of the Body.
+ * @param {number} offsetX - The X offset of the Body from the Sprite position.
+ * @param {number} offsetY - The Y offset of the Body from the Sprite position.
+ */
+ setSize: function (width, height, offsetX, offsetY) {
+
+ offsetX = offsetX || this.offset.x;
+ offsetY = offsetY || this.offset.y;
+
+ this.sourceWidth = width;
+ this.sourceHeight = height;
+ this.width = this.sourceWidth * this._sx;
+ this.height = this.sourceHeight * this._sy;
+ this.halfWidth = Math.floor(this.width / 2);
+ this.halfHeight = Math.floor(this.height / 2);
+ this.offset.setTo(offsetX, offsetY);
+
+ this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
+
+ },
+
+ /**
+ * Resets all Body values (velocity, acceleration, rotation, etc)
+ *
+ * @method Phaser.Physics.Arcade#reset
+ */
+ reset: function () {
+
+ this.velocity.setTo(0, 0);
+ this.acceleration.setTo(0, 0);
+
+ this.angularVelocity = 0;
+ this.angularAcceleration = 0;
+ this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
+ this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
+ this.preRotation = this.sprite.angle;
+
+ this.x = this.preX;
+ this.y = this.preY;
+ this.rotation = this.preRotation;
+
+ this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
+
+ },
+
+ /**
+ * Returns the absolute delta x value.
+ *
+ * @method Phaser.Physics.Arcade.Body#deltaAbsX
+ * @return {number} The absolute delta value.
+ */
+ deltaAbsX: function () {
+ return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX());
+ },
+
+ /**
+ * Returns the absolute delta y value.
+ *
+ * @method Phaser.Physics.Arcade.Body#deltaAbsY
+ * @return {number} The absolute delta value.
+ */
+ deltaAbsY: function () {
+ return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY());
+ },
+
+ /**
+ * Returns the delta x value. The difference between Body.x now and in the previous step.
+ *
+ * @method Phaser.Physics.Arcade.Body#deltaX
+ * @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
+ */
+ deltaX: function () {
+ return this.x - this.preX;
+ },
+
+ /**
+ * Returns the delta y value. The difference between Body.y now and in the previous step.
+ *
+ * @method Phaser.Physics.Arcade.Body#deltaY
+ * @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
+ */
+ deltaY: function () {
+ return this.y - this.preY;
+ },
+
+ deltaZ: function () {
+ return this.rotation - this.preRotation;
+ }
+
+};
+
+/**
+* @name Phaser.Physics.Arcade.Body#bottom
+* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
+*/
+Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", {
+
+ /**
+ * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
+ * @method bottom
+ * @return {number}
+ */
+ get: function () {
+ return Math.floor(this.y + this.height);
+ },
+
+ /**
+ * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
+ * @method bottom
+ * @param {number} value
+ */
+ set: function (value) {
+
+ if (value <= this.y)
+ {
+ this.height = 0;
+ }
+ else
+ {
+ this.height = (this.y - value);
+ }
+
+ }
+
+});
+
+/**
+* @name Phaser.Physics.Arcade.Body#right
+* @property {number} right - The right value of this Body (same as Body.x + Body.width)
+*/
+Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
+
+ /**
+ * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
+ * However it does affect the width property.
+ * @method right
+ * @return {number}
+ */
+ get: function () {
+ return Math.floor(this.x + this.width);
+ },
+
+ /**
+ * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
+ * However it does affect the width property.
+ * @method right
+ * @param {number} value
+ */
+ set: function (value) {
+
+ if (value <= this.x)
+ {
+ this.width = 0;
+ }
+ else
+ {
+ this.width = this.x + value;
+ }
+
+ }
+
+});
diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/BrokenArcadePhysics.js
similarity index 100%
rename from src/physics/arcade/ArcadePhysics.js
rename to src/physics/arcade/BrokenArcadePhysics.js
diff --git a/src/physics/arcade/QuadTree.js b/src/physics/arcade/QuadTree.js
new file mode 100644
index 00000000..661b7326
--- /dev/null
+++ b/src/physics/arcade/QuadTree.js
@@ -0,0 +1,265 @@
+/**
+* @author Richard Davey
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+ * Javascript QuadTree
+ * @version 1.0
+ * @author Timo Hausmann
+ *
+ * @version 1.2, September 4th 2013
+ * @author Richard Davey
+ * The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked
+ * it massively to add node indexing, removed lots of temp. var creation and significantly
+ * increased performance as a result.
+ *
+ * Original version at https://github.com/timohausmann/quadtree-js/
+ */
+
+/**
+* @copyright © 2012 Timo Hausmann
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+ * QuadTree Constructor
+ *
+ * @class Phaser.Physics.Arcade.QuadTree
+ * @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked
+ * it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. Original version at https://github.com/timohausmann/quadtree-js/
+ * @constructor
+ * @param {Description} physicsManager - Description.
+ * @param {Description} x - Description.
+ * @param {Description} y - Description.
+ * @param {number} width - The width of your game in game pixels.
+ * @param {number} height - The height of your game in game pixels.
+ * @param {number} maxObjects - Description.
+ * @param {number} maxLevels - Description.
+ * @param {number} level - Description.
+ */
+Phaser.Physics.Arcade.QuadTree = function (physicsManager, x, y, width, height, maxObjects, maxLevels, level) {
+
+ this.physicsManager = physicsManager;
+ this.ID = physicsManager.quadTreeID;
+ physicsManager.quadTreeID++;
+
+ this.maxObjects = maxObjects || 10;
+ this.maxLevels = maxLevels || 4;
+ this.level = level || 0;
+
+ this.bounds = {
+ x: Math.round(x),
+ y: Math.round(y),
+ width: width,
+ height: height,
+ subWidth: Math.floor(width / 2),
+ subHeight: Math.floor(height / 2),
+ right: Math.round(x) + Math.floor(width / 2),
+ bottom: Math.round(y) + Math.floor(height / 2)
+ };
+
+ this.objects = [];
+ this.nodes = [];
+
+};
+
+Phaser.Physics.Arcade.QuadTree.prototype = {
+
+ /*
+ * Split the node into 4 subnodes
+ *
+ * @method Phaser.Physics.Arcade.QuadTree#split
+ */
+ split: function() {
+
+ this.level++;
+
+ // top right node
+ this.nodes[0] = new Phaser.Physics.Arcade.QuadTree(this.physicsManager, this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
+
+ // top left node
+ this.nodes[1] = new Phaser.Physics.Arcade.QuadTree(this.physicsManager, this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
+
+ // bottom left node
+ this.nodes[2] = new Phaser.Physics.Arcade.QuadTree(this.physicsManager, this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
+
+ // bottom right node
+ this.nodes[3] = new Phaser.Physics.Arcade.QuadTree(this.physicsManager, this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
+
+ },
+
+ /*
+ * Insert the object into the node. If the node
+ * exceeds the capacity, it will split and add all
+ * objects to their corresponding subnodes.
+ *
+ * @method Phaser.Physics.Arcade.QuadTree#insert
+ * @param {object} body - Description.
+ */
+ insert: function (body) {
+
+ var i = 0;
+ var index;
+
+ // if we have subnodes ...
+ if (this.nodes[0] != null)
+ {
+ index = this.getIndex(body);
+
+ if (index !== -1)
+ {
+ this.nodes[index].insert(body);
+ return;
+ }
+ }
+
+ this.objects.push(body);
+
+ if (this.objects.length > this.maxObjects && this.level < this.maxLevels)
+ {
+ // Split if we don't already have subnodes
+ if (this.nodes[0] == null)
+ {
+ this.split();
+ }
+
+ // Add objects to subnodes
+ while (i < this.objects.length)
+ {
+ index = this.getIndex(this.objects[i]);
+
+ if (index !== -1)
+ {
+ // this is expensive - see what we can do about it
+ this.nodes[index].insert(this.objects.splice(i, 1)[0]);
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+
+ },
+
+ /*
+ * Determine which node the object belongs to.
+ *
+ * @method Phaser.Physics.Arcade.QuadTree#getIndex
+ * @param {object} rect - Description.
+ * @return {number} index - Index of the subnode (0-3), or -1 if rect cannot completely fit within a subnode and is part of the parent node.
+ */
+ getIndex: function (rect) {
+
+ // default is that rect doesn't fit, i.e. it straddles the internal quadrants
+ var index = -1;
+
+ if (rect.x < this.bounds.right && rect.right < this.bounds.right)
+ {
+ if ((rect.y < this.bounds.bottom && rect.bottom < this.bounds.bottom))
+ {
+ // rect fits within the top-left quadrant of this quadtree
+ index = 1;
+ }
+ else if ((rect.y > this.bounds.bottom))
+ {
+ // rect fits within the bottom-left quadrant of this quadtree
+ index = 2;
+ }
+ }
+ else if (rect.x > this.bounds.right)
+ {
+ // rect can completely fit within the right quadrants
+ if ((rect.y < this.bounds.bottom && rect.bottom < this.bounds.bottom))
+ {
+ // rect fits within the top-right quadrant of this quadtree
+ index = 0;
+ }
+ else if ((rect.y > this.bounds.bottom))
+ {
+ // rect fits within the bottom-right quadrant of this quadtree
+ index = 3;
+ }
+ }
+
+ return index;
+
+ },
+
+ /*
+ * Return all objects that could collide with the given object.
+ *
+ * @method Phaser.Physics.Arcade.QuadTree#retrieve
+ * @param {object} rect - Description.
+ * @Return {array} - Array with all detected objects.
+ */
+ retrieve: function (sprite) {
+
+ var returnObjects = this.objects;
+
+ sprite.body.quadTreeIndex = this.getIndex(sprite.body);
+
+ // Temp store for the node IDs this sprite is in, we can use this for fast elimination later
+ sprite.body.quadTreeIDs.push(this.ID);
+
+ if (this.nodes[0])
+ {
+ // if rect fits into a subnode ..
+ if (sprite.body.quadTreeIndex !== -1)
+ {
+ returnObjects = returnObjects.concat(this.nodes[sprite.body.quadTreeIndex].retrieve(sprite));
+ }
+ else
+ {
+ // if rect does not fit into a subnode, check it against all subnodes (unrolled for speed)
+ returnObjects = returnObjects.concat(this.nodes[0].retrieve(sprite));
+ returnObjects = returnObjects.concat(this.nodes[1].retrieve(sprite));
+ returnObjects = returnObjects.concat(this.nodes[2].retrieve(sprite));
+ returnObjects = returnObjects.concat(this.nodes[3].retrieve(sprite));
+ }
+ }
+
+ return returnObjects;
+
+ },
+
+ /*
+ * Clear the quadtree.
+ * @method Phaser.Physics.Arcade.QuadTree#clear
+ */
+ clear: function () {
+
+ this.objects = [];
+
+ for (var i = 0, len = this.nodes.length; i < len; i++)
+ {
+ // if (typeof this.nodes[i] !== 'undefined')
+ if (this.nodes[i])
+ {
+ this.nodes[i].clear();
+ delete this.nodes[i];
+ }
+ }
+ }
+
+};
diff --git a/src/physics/arcade/TempSprite.js b/src/physics/arcade/TempSprite.js
new file mode 100644
index 00000000..de08e4c2
--- /dev/null
+++ b/src/physics/arcade/TempSprite.js
@@ -0,0 +1,1126 @@
+/**
+* @author Richard Davey
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* @class Phaser.Sprite
+*
+* @classdesc Create a new `Sprite` object. Sprites are the lifeblood of your game, used for nearly everything visual.
+*
+* At its most basic a Sprite consists of a set of coordinates and a texture that is rendered to the canvas.
+* They also contain additional properties allowing for physics motion (via Sprite.body), input handling (via Sprite.input),
+* events (via Sprite.events), animation (via Sprite.animations), camera culling and more. Please see the Examples for use cases.
+*
+* @constructor
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
+* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
+*/
+Phaser.Sprite = function (game, x, y, key, frame) {
+
+ x = x || 0;
+ y = y || 0;
+ key = key || null;
+ frame = frame || null;
+
+ /**
+ * @property {Phaser.Game} game - A reference to the currently running Game.
+ */
+ this.game = game;
+
+ /**
+ * @property {boolean} exists - If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all.
+ * @default
+ */
+ this.exists = true;
+
+ /**
+ * @property {boolean} alive - This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering.
+ * @default
+ */
+ this.alive = true;
+
+ /**
+ * @property {Phaser.Group} group - The parent Group of this Sprite. This is usually set after Sprite instantiation by the parent.
+ */
+ this.group = null;
+
+ /**
+ * @property {string} name - The user defined name given to this Sprite.
+ * @default
+ */
+ this.name = '';
+
+ /**
+ * @property {number} type - The const type of this object.
+ * @readonly
+ */
+ this.type = Phaser.SPRITE;
+
+ /**
+ * @property {number} renderOrderID - Used by the Renderer and Input Manager to control picking order.
+ * @default
+ */
+ this.renderOrderID = -1;
+
+ /**
+ * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+ * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+ * @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
+ * @default
+ */
+ this.lifespan = 0;
+
+ /**
+ * @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
+ */
+ this.events = new Phaser.Events(this);
+
+ /**
+ * @property {Phaser.AnimationManager} animations - This manages animations of the sprite. You can modify animations through it (see Phaser.AnimationManager)
+ */
+ this.animations = new Phaser.AnimationManager(this);
+
+ /**
+ * @property {Phaser.InputHandler} input - The Input Handler Component.
+ */
+ this.input = new Phaser.InputHandler(this);
+
+ /**
+ * @property {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
+ */
+ this.key = key;
+
+ /**
+ * @property {Phaser.Frame} currentFrame - A reference to the currently displayed frame.
+ */
+ this.currentFrame = null;
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ PIXI.Sprite.call(this, key);
+
+ this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ PIXI.Sprite.call(this, key.texture, key.textureFrame);
+
+ this.currentFrame = key.textureFrame;
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ PIXI.Sprite.call(this, key);
+
+ this.currentFrame = frame;
+ }
+ else
+ {
+ if (key === null || typeof key === 'undefined')
+ {
+ key = '__default';
+ this.key = key;
+ }
+ else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__missing';
+ this.key = key;
+ }
+
+ PIXI.Sprite.call(this, PIXI.TextureCache[key]);
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ this.animations.loadFrameData(this.game.cache.getFrameData(key));
+
+ if (frame !== null)
+ {
+ if (typeof frame === 'string')
+ {
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
+ }
+ }
+ }
+ else
+ {
+ this.currentFrame = this.game.cache.getFrame(key);
+ }
+ }
+
+ /**
+ * The rectangular area from the texture that will be rendered.
+ * @property {Phaser.Rectangle} textureRegion
+ */
+ this.textureRegion = new Phaser.Rectangle(this.texture.frame.x, this.texture.frame.y, this.texture.frame.width, this.texture.frame.height);
+
+ /**
+ * The anchor sets the origin point of the texture.
+ * The default is 0,0 this means the textures origin is the top left
+ * Setting than anchor to 0.5,0.5 means the textures origin is centered
+ * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
+ *
+ * @property {Phaser.Point} anchor - The anchor around which rotation and scaling takes place.
+ */
+ this.anchor = new Phaser.Point();
+
+ /**
+ * @property {number} x - The x coordinate in world space of this Sprite.
+ */
+ this.x = x;
+
+ /**
+ * @property {number} y - The y coordinate in world space of this Sprite.
+ */
+ this.y = y;
+
+ this.position.x = x;
+ this.position.y = y;
+
+ /**
+ * @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
+ */
+ this.world = new Phaser.Point(x, y);
+
+ /**
+ * Should this Sprite be automatically culled if out of range of the camera?
+ * A culled sprite has its renderable property set to 'false'.
+ *
+ * @property {boolean} autoCull - A flag indicating if the Sprite should be automatically camera culled or not.
+ * @default
+ */
+ this.autoCull = false;
+
+ /**
+ * @property {Phaser.Point} scale - The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
+ */
+ this.scale = new Phaser.Point(1, 1);
+
+ /**
+ * @property {object} _cache - A mini cache for storing all of the calculated values.
+ * @private
+ */
+ this._cache = {
+
+ dirty: false,
+
+ // Transform cache
+ a00: -1,
+ a01: -1,
+ a02: -1,
+ a10: -1,
+ a11: -1,
+ a12: -1,
+ id: -1,
+
+ // Input specific transform cache
+ i01: -1,
+ i10: -1,
+ idi: -1,
+
+ // Bounds check
+ left: null,
+ right: null,
+ top: null,
+ bottom: null,
+
+ // delta cache
+ prevX: x,
+ prevY: y,
+
+ // The previous calculated position
+ x: -1,
+ y: -1,
+
+ // The actual scale values based on the worldTransform
+ scaleX: 1,
+ scaleY: 1,
+
+ // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
+ width: this.currentFrame.sourceSizeW,
+ height: this.currentFrame.sourceSizeH,
+
+ // The actual width/height of the image if from a trimmed atlas, multiplied by the final calculated scale size
+ halfWidth: Math.floor(this.currentFrame.sourceSizeW / 2),
+ halfHeight: Math.floor(this.currentFrame.sourceSizeH / 2),
+
+ // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
+ calcWidth: -1,
+ calcHeight: -1,
+
+ // The current frame details
+ // frameID: this.currentFrame.uuid, frameWidth: this.currentFrame.width, frameHeight: this.currentFrame.height,
+ frameID: -1,
+ frameWidth: this.currentFrame.width,
+ frameHeight: this.currentFrame.height,
+
+ // If this sprite visible to the camera (regardless of being set to visible or not)
+ cameraVisible: true,
+
+ // Crop cache
+ cropX: 0,
+ cropY: 0,
+ cropWidth: this.currentFrame.sourceSizeW,
+ cropHeight: this.currentFrame.sourceSizeH
+
+ };
+
+ /**
+ * @property {Phaser.Point} offset - Corner point defaults. Should not typically be modified.
+ */
+ this.offset = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} center - A Point containing the center coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.center = new Phaser.Point(x + Math.floor(this._cache.width / 2), y + Math.floor(this._cache.height / 2));
+
+ /**
+ * @property {Phaser.Point} topLeft - A Point containing the top left coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.topLeft = new Phaser.Point(x, y);
+
+ /**
+ * @property {Phaser.Point} topRight - A Point containing the top right coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.topRight = new Phaser.Point(x + this._cache.width, y);
+
+ /**
+ * @property {Phaser.Point} bottomRight - A Point containing the bottom right coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.bottomRight = new Phaser.Point(x + this._cache.width, y + this._cache.height);
+
+ /**
+ * @property {Phaser.Point} bottomLeft - A Point containing the bottom left coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.bottomLeft = new Phaser.Point(x, y + this._cache.height);
+
+ /**
+ * This Rectangle object fully encompasses the Sprite and is updated in real-time.
+ * The bounds is the full bounding area after rotation and scale have been taken into account. It should not be modified directly.
+ * It's used for Camera culling and physics body alignment.
+ * @property {Phaser.Rectangle} bounds
+ */
+ this.bounds = new Phaser.Rectangle(x, y, this._cache.width, this._cache.height);
+
+ /**
+ * @property {Phaser.Physics.Arcade.Body} body - By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
+ */
+ this.body = new Phaser.Physics.Arcade.Body(this);
+
+ /**
+ * @property {number} health - Health value. Used in combination with damage() to allow for quick killing of Sprites.
+ */
+ this.health = 1;
+
+ /**
+ * @property {boolean} inWorld - This value is set to true if the Sprite is positioned within the World, otherwise false.
+ */
+ this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds);
+
+ /**
+ * @property {number} inWorldThreshold - A threshold value applied to the inWorld check. If you don't want a Sprite to be considered "out of the world" until at least 100px away for example then set it to 100.
+ * @default
+ */
+ this.inWorldThreshold = 0;
+
+ /**
+ * @property {boolean} outOfBoundsKill - If true the Sprite is killed as soon as Sprite.inWorld is false.
+ * @default
+ */
+ this.outOfBoundsKill = false;
+
+ /**
+ * @property {boolean} _outOfBoundsFired - Internal flag.
+ * @private
+ * @default
+ */
+ this._outOfBoundsFired = false;
+
+ /**
+ * A Sprite that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.
+ * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera.
+ * @default
+ */
+ this.fixedToCamera = false;
+
+ /**
+ * @property {Phaser.Point} cameraOffset - If this Sprite is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.
+ */
+ this.cameraOffset = new Phaser.Point();
+
+ /**
+ * You can crop the Sprites texture by modifying the crop properties. For example crop.width = 50 would set the Sprite to only render 50px wide.
+ * The crop is only applied if you have set Sprite.cropEnabled to true.
+ * @property {Phaser.Rectangle} crop - The crop Rectangle applied to the Sprite texture before rendering.
+ * @default
+ */
+ this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
+
+ /**
+ * @property {boolean} cropEnabled - If true the Sprite.crop property is used to crop the texture before render. Set to false to disable.
+ * @default
+ */
+ this.cropEnabled = false;
+
+ this.updateCache();
+ this.updateBounds();
+
+};
+
+// Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly)
+Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype);
+Phaser.Sprite.prototype.constructor = Phaser.Sprite;
+
+/**
+* Automatically called by World.preUpdate. Handles cache updates, lifespan checks, animation updates and physics updates.
+*
+* @method Phaser.Sprite#preUpdate
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.preUpdate = function() {
+
+ if (!this.exists || (this.group && !this.group.exists))
+ {
+ this.renderOrderID = -1;
+
+ // Skip children if not exists
+ return false;
+ }
+
+ if (this.lifespan > 0)
+ {
+ this.lifespan -= this.game.time.elapsed;
+
+ if (this.lifespan <= 0)
+ {
+ this.kill();
+ return false;
+ }
+ }
+
+ this._cache.dirty = false;
+
+ if (this.visible)
+ {
+ this.renderOrderID = this.game.world.currentRenderOrderID++;
+ }
+
+ this.updateCache();
+
+ this.updateAnimation();
+
+ this.updateCrop();
+
+ // Re-run the camera visibility check
+ if (this._cache.dirty || this.world.x !== this._cache.prevX || this.world.y !== this._cache.prevY)
+ {
+ this.updateBounds();
+ }
+
+ if (this.body)
+ {
+ this.body.preUpdate();
+ }
+
+ return true;
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateCache
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateCache = function() {
+
+ this._cache.prevX = this.world.x;
+ this._cache.prevY = this.world.y;
+
+ if (this.fixedToCamera)
+ {
+ this.x = this.game.camera.view.x + this.cameraOffset.x;
+ this.y = this.game.camera.view.y + this.cameraOffset.y;
+ }
+
+ this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
+
+ if (this.worldTransform[1] != this._cache.i01 || this.worldTransform[3] != this._cache.i10 || this.worldTransform[0] != this._cache.a00 || this.worldTransform[41] != this._cache.a11)
+ {
+ this._cache.a00 = this.worldTransform[0]; // scaleX a |a c tx|
+ this._cache.a01 = this.worldTransform[1]; // skewY c |b d ty|
+ this._cache.a10 = this.worldTransform[3]; // skewX b |0 0 1|
+ this._cache.a11 = this.worldTransform[4]; // scaleY d
+
+ this._cache.i01 = this.worldTransform[1]; // skewY c (remains non-modified for input checks)
+ this._cache.i10 = this.worldTransform[3]; // skewX b (remains non-modified for input checks)
+
+ this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit?
+ this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit?
+
+ this._cache.a01 *= -1;
+ this._cache.a10 *= -1;
+
+ this._cache.id = 1 / (this._cache.a00 * this._cache.a11 + this._cache.a01 * -this._cache.a10);
+ this._cache.idi = 1 / (this._cache.a00 * this._cache.a11 + this._cache.i01 * -this._cache.i10);
+
+ this._cache.dirty = true;
+ }
+
+ this._cache.a02 = this.worldTransform[2]; // translateX tx
+ this._cache.a12 = this.worldTransform[5]; // translateY ty
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateAnimation
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateAnimation = function() {
+
+ if (this.animations.update() || (this.currentFrame && this.currentFrame.uuid != this._cache.frameID))
+ {
+ this._cache.frameID = this.currentFrame.uuid;
+
+ this._cache.frameWidth = this.texture.frame.width;
+ this._cache.frameHeight = this.texture.frame.height;
+
+ this._cache.width = this.currentFrame.width;
+ this._cache.height = this.currentFrame.height;
+
+ this._cache.halfWidth = Math.floor(this._cache.width / 2);
+ this._cache.halfHeight = Math.floor(this._cache.height / 2);
+
+ this._cache.dirty = true;
+
+ }
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateCrop
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateCrop = function() {
+
+ // This only runs if crop is enabled
+ if (this.cropEnabled && (this.crop.width != this._cache.cropWidth || this.crop.height != this._cache.cropHeight || this.crop.x != this._cache.cropX || this.crop.y != this._cache.cropY))
+ {
+ this.crop.floorAll();
+
+ this._cache.cropX = this.crop.x;
+ this._cache.cropY = this.crop.y;
+ this._cache.cropWidth = this.crop.width;
+ this._cache.cropHeight = this.crop.height;
+
+ this.texture.frame = this.crop;
+ this.texture.width = this.crop.width;
+ this.texture.height = this.crop.height;
+
+ this.texture.updateFrame = true;
+
+ PIXI.Texture.frameUpdates.push(this.texture);
+ }
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateBounds
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateBounds = function() {
+
+ this.offset.setTo(this._cache.a02 - (this.anchor.x * this.width), this._cache.a12 - (this.anchor.y * this.height));
+
+ this.getLocalPosition(this.center, this.offset.x + (this.width / 2), this.offset.y + (this.height / 2));
+ this.getLocalPosition(this.topLeft, this.offset.x, this.offset.y);
+ this.getLocalPosition(this.topRight, this.offset.x + this.width, this.offset.y);
+ this.getLocalPosition(this.bottomLeft, this.offset.x, this.offset.y + this.height);
+ this.getLocalPosition(this.bottomRight, this.offset.x + this.width, this.offset.y + this.height);
+
+ this._cache.left = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
+ this._cache.right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
+ this._cache.top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
+ this._cache.bottom = Phaser.Math.max(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
+
+ this.bounds.setTo(this._cache.left, this._cache.top, this._cache.right - this._cache.left, this._cache.bottom - this._cache.top);
+
+ this.updateFrame = true;
+
+ if (this.inWorld === false)
+ {
+ // Sprite WAS out of the screen, is it still?
+ this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
+
+ if (this.inWorld)
+ {
+ // It's back again, reset the OOB check
+ this._outOfBoundsFired = false;
+ }
+ }
+ else
+ {
+ // Sprite WAS in the screen, has it now left?
+ this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
+
+ if (this.inWorld === false)
+ {
+ this.events.onOutOfBounds.dispatch(this);
+ this._outOfBoundsFired = true;
+
+ if (this.outOfBoundsKill)
+ {
+ this.kill();
+ }
+ }
+ }
+
+ this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.bounds, 0);
+
+ if (this.autoCull)
+ {
+ // Won't get rendered but will still get its transform updated
+ this.renderable = this._cache.cameraVisible;
+ }
+
+ // Update our physics bounds
+ if (this.body)
+ {
+ this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY);
+ }
+
+};
+
+/**
+* Gets the local position of a coordinate relative to the Sprite, factoring in rotation and scale.
+* Mostly only used internally.
+*
+* @method Phaser.Sprite#getLocalPosition
+* @memberof Phaser.Sprite
+* @param {Phaser.Point} p - The Point object to store the results in.
+* @param {number} x - x coordinate within the Sprite to translate.
+* @param {number} y - x coordinate within the Sprite to translate.
+* @param {number} sx - Scale factor to be applied.
+* @param {number} sy - Scale factor to be applied.
+* @return {Phaser.Point} The translated point.
+*/
+Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
+
+ p.x = ((this._cache.a11 * this._cache.id * x + -this._cache.a01 * this._cache.id * y + (this._cache.a12 * this._cache.a01 - this._cache.a02 * this._cache.a11) * this._cache.id) * this.scale.x) + this._cache.a02;
+ p.y = ((this._cache.a00 * this._cache.id * y + -this._cache.a10 * this._cache.id * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.a10) * this._cache.id) * this.scale.y) + this._cache.a12;
+
+ return p;
+
+};
+
+/**
+* Gets the local unmodified position of a coordinate relative to the Sprite, factoring in rotation and scale.
+* Mostly only used internally by the Input Manager, but also useful for custom hit detection.
+*
+* @method Phaser.Sprite#getLocalUnmodifiedPosition
+* @memberof Phaser.Sprite
+* @param {Phaser.Point} p - The Point object to store the results in.
+* @param {number} x - x coordinate within the Sprite to translate.
+* @param {number} y - x coordinate within the Sprite to translate.
+* @return {Phaser.Point} The translated point.
+*/
+Phaser.Sprite.prototype.getLocalUnmodifiedPosition = function(p, gx, gy) {
+
+ p.x = (this._cache.a11 * this._cache.idi * gx + -this._cache.i01 * this._cache.idi * gy + (this._cache.a12 * this._cache.i01 - this._cache.a02 * this._cache.a11) * this._cache.idi) + (this.anchor.x * this._cache.width);
+ p.y = (this._cache.a00 * this._cache.idi * gy + -this._cache.i10 * this._cache.idi * gx + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.i10) * this._cache.idi) + (this.anchor.y * this._cache.height);
+
+ return p;
+
+};
+
+/**
+* Resets the Sprite.crop value back to the frame dimensions.
+*
+* @method Phaser.Sprite#resetCrop
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.resetCrop = function() {
+
+ this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
+ this.texture.setFrame(this.crop);
+ this.cropEnabled = false;
+
+};
+
+/**
+* Internal function called by the World postUpdate cycle.
+*
+* @method Phaser.Sprite#postUpdate
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.postUpdate = function() {
+
+ if (this.key instanceof Phaser.BitmapData && this.key._dirty)
+ {
+ this.key.render();
+ }
+
+ if (this.exists)
+ {
+ // The sprite is positioned in this call, after taking into consideration motion updates and collision
+ if (this.body)
+ {
+ this.body.postUpdate();
+ }
+
+ if (this.fixedToCamera)
+ {
+ this._cache.x = this.game.camera.view.x + this.cameraOffset.x;
+ this._cache.y = this.game.camera.view.y + this.cameraOffset.y;
+ }
+ else
+ {
+ this._cache.x = this.x;
+ this._cache.y = this.y;
+ }
+
+ this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
+
+ this.position.x = this._cache.x;
+ this.position.y = this._cache.y;
+ }
+
+};
+
+/**
+* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
+*
+* @method Phaser.Sprite#loadTexture
+* @memberof Phaser.Sprite
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
+* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
+*/
+Phaser.Sprite.prototype.loadTexture = function (key, frame) {
+
+ this.key = key;
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ this.setTexture(key.texture);
+ this.currentFrame = key.textureFrame;
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ this.currentFrame = frame;
+ }
+ else
+ {
+ if (typeof key === 'undefined' || this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__default';
+ this.key = key;
+ }
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ this.animations.loadFrameData(this.game.cache.getFrameData(key));
+
+ if (typeof frame !== 'undefined')
+ {
+ if (typeof frame === 'string')
+ {
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
+ }
+ }
+ }
+ else
+ {
+ this.currentFrame = this.game.cache.getFrame(key);
+ this.setTexture(PIXI.TextureCache[key]);
+ }
+ }
+
+};
+
+/**
+* Moves the sprite so its center is located on the given x and y coordinates.
+* Doesn't change the anchor point of the sprite.
+*
+* @method Phaser.Sprite#centerOn
+* @memberof Phaser.Sprite
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.centerOn = function(x, y) {
+
+ this.x = x + (this.x - this.center.x);
+ this.y = y + (this.y - this.center.y);
+ return this;
+
+};
+
+/**
+* Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+* A resurrected Sprite has its alive, exists and visible properties all set to true.
+* It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
+*
+* @method Phaser.Sprite#revive
+* @memberof Phaser.Sprite
+* @param {number} [health=1] - The health to give the Sprite.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.revive = function(health) {
+
+ if (typeof health === 'undefined') { health = 1; }
+
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+ this.health = health;
+
+ if (this.events)
+ {
+ this.events.onRevived.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+* It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+* Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+* If you don't need this Sprite any more you should call Sprite.destroy instead.
+*
+* @method Phaser.Sprite#kill
+* @memberof Phaser.Sprite
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.kill = function() {
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ if (this.events)
+ {
+ this.events.onKilled.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+* and nulls its reference to game, freeing it up for garbage collection.
+*
+* @method Phaser.Sprite#destroy
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.destroy = function() {
+
+ if (this.filters)
+ {
+ this.filters = null;
+ }
+
+ if (this.group)
+ {
+ this.group.remove(this);
+ }
+
+ if (this.input)
+ {
+ this.input.destroy();
+ }
+
+ if (this.events)
+ {
+ this.events.destroy();
+ }
+
+ if (this.animations)
+ {
+ this.animations.destroy();
+ }
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ this.game = null;
+
+};
+
+/**
+* Damages the Sprite, this removes the given amount from the Sprites health property.
+* If health is then taken below zero Sprite.kill is called.
+*
+* @method Phaser.Sprite#damage
+* @memberof Phaser.Sprite
+* @param {number} amount - The amount to subtract from the Sprite.health value.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.damage = function(amount) {
+
+ if (this.alive)
+ {
+ this.health -= amount;
+
+ if (this.health < 0)
+ {
+ this.kill();
+ }
+ }
+
+ return this;
+
+};
+
+/**
+* Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+* sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+* If the Sprite has a physics body that too is reset.
+*
+* @method Phaser.Sprite#reset
+* @memberof Phaser.Sprite
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @param {number} [health=1] - The health to give the Sprite.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.reset = function(x, y, health) {
+
+ if (typeof health === 'undefined') { health = 1; }
+
+ this.x = x;
+ this.y = y;
+ this.position.x = this.x;
+ this.position.y = this.y;
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+ this.renderable = true;
+ this._outOfBoundsFired = false;
+
+ this.health = health;
+
+ if (this.body)
+ {
+ this.body.reset();
+ }
+
+ return this;
+
+};
+
+/**
+* Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+* bought to the top of that Group, not the entire display list.
+*
+* @method Phaser.Sprite#bringToTop
+* @memberof Phaser.Sprite
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.bringToTop = function() {
+
+ if (this.group)
+ {
+ this.group.bringToTop(this);
+ }
+ else
+ {
+ this.game.world.bringToTop(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Play an animation based on the given key. The animation should previously have been added via sprite.animations.add()
+* If the requested animation is already playing this request will be ignored. If you need to reset an already running animation do so directly on the Animation object itself.
+*
+* @method Phaser.Sprite#play
+* @memberof Phaser.Sprite
+* @param {string} name - The name of the animation to be played, e.g. "fire", "walk", "jump".
+* @param {number} [frameRate=null] - The framerate to play the animation at. The speed is given in frames per second. If not provided the previously set frameRate of the Animation is used.
+* @param {boolean} [loop=false] - Should the animation be looped after playback. If not provided the previously set loop value of the Animation is used.
+* @param {boolean} [killOnComplete=false] - If set to true when the animation completes (only happens if loop=false) the parent Sprite will be killed.
+* @return {Phaser.Animation} A reference to playing Animation instance.
+*/
+Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete) {
+
+ if (this.animations)
+ {
+ return this.animations.play(name, frameRate, loop, killOnComplete);
+ }
+
+};
+
+/**
+* Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation.
+* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90.
+* If you wish to work in radians instead of degrees use the property Sprite.rotation instead.
+* @name Phaser.Sprite#angle
+* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, 'angle', {
+
+ get: function() {
+ return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation));
+ },
+
+ set: function(value) {
+ this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value));
+ }
+
+});
+
+/**
+* @name Phaser.Sprite#frame
+* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "frame", {
+
+ get: function () {
+ return this.animations.frame;
+ },
+
+ set: function (value) {
+ this.animations.frame = value;
+ }
+
+});
+
+/**
+* @name Phaser.Sprite#frameName
+* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
+
+ get: function () {
+ return this.animations.frameName;
+ },
+
+ set: function (value) {
+ this.animations.frameName = value;
+ }
+
+});
+
+/**
+* @name Phaser.Sprite#inCamera
+* @property {boolean} inCamera - Is this sprite visible to the camera or not?
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
+
+ get: function () {
+ return this._cache.cameraVisible;
+ }
+
+});
+
+/**
+* The width of the sprite in pixels, setting this will actually modify the scale to acheive the value desired.
+* If you wish to crop the Sprite instead see the Sprite.crop value.
+*
+* @name Phaser.Sprite#width
+* @property {number} width - The width of the Sprite in pixels.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, 'width', {
+
+ get: function() {
+ return this.scale.x * this.currentFrame.width;
+ },
+
+ set: function(value) {
+
+ this.scale.x = value / this.currentFrame.width;
+ this._cache.scaleX = value / this.currentFrame.width;
+ this._width = value;
+
+ }
+
+});
+
+/**
+* The height of the sprite in pixels, setting this will actually modify the scale to acheive the value desired.
+* If you wish to crop the Sprite instead see the Sprite.crop value.
+*
+* @name Phaser.Sprite#height
+* @property {number} height - The height of the Sprite in pixels.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, 'height', {
+
+ get: function() {
+ return this.scale.y * this.currentFrame.height;
+ },
+
+ set: function(value) {
+
+ this.scale.y = value / this.currentFrame.height;
+ this._cache.scaleY = value / this.currentFrame.height;
+ this._height = value;
+
+ }
+
+});
+
+/**
+* By default a Sprite won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+* activated for this Sprite instance and it will then start to process click/touch events and more.
+*
+* @name Phaser.Sprite#inputEnabled
+* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
+
+ get: function () {
+
+ return (this.input.enabled);
+
+ },
+
+ set: function (value) {
+
+ if (value)
+ {
+ if (this.input.enabled === false)
+ {
+ this.input.start();
+ }
+ }
+ else
+ {
+ if (this.input.enabled)
+ {
+ this.input.stop();
+ }
+ }
+
+ }
+
+});
diff --git a/src/physics/arcade/World.js b/src/physics/arcade/World.js
new file mode 100644
index 00000000..576f7ae3
--- /dev/null
+++ b/src/physics/arcade/World.js
@@ -0,0 +1,1611 @@
+/**
+* @author Richard Davey
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* Arcade Physics constructor.
+*
+* @class Phaser.Physics.Arcade
+* @classdesc Arcade Physics Constructor
+* @constructor
+* @param {Phaser.Game} game reference to the current game instance.
+*/
+Phaser.Physics.Arcade = function (game) {
+
+ /**
+ * @property {Phaser.Game} game - Local reference to game.
+ */
+ this.game = game;
+
+ /**
+ * @property {Phaser.Point} gravity - The World gravity setting. Defaults to x: 0, y: 0, or no gravity.
+ */
+ this.gravity = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds.
+ */
+ this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
+
+ /**
+ * @property {number} maxObjects - Used by the QuadTree to set the maximum number of objects per quad.
+ */
+ this.maxObjects = 10;
+
+ /**
+ * @property {number} maxLevels - Used by the QuadTree to set the maximum number of iteration levels.
+ */
+ this.maxLevels = 4;
+
+ /**
+ * @property {number} OVERLAP_BIAS - A value added to the delta values during collision checks.
+ */
+ this.OVERLAP_BIAS = 4;
+
+ /**
+ * @property {Phaser.QuadTree} quadTree - The world QuadTree.
+ */
+ this.quadTree = new Phaser.Physics.Arcade.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
+
+ /**
+ * @property {number} quadTreeID - The QuadTree ID.
+ */
+ this.quadTreeID = 0;
+
+ // Avoid gc spikes by caching these values for re-use
+
+ /**
+ * @property {Phaser.Rectangle} _bounds1 - Internal cache var.
+ * @private
+ */
+ this._bounds1 = new Phaser.Rectangle();
+
+ /**
+ * @property {Phaser.Rectangle} _bounds2 - Internal cache var.
+ * @private
+ */
+ this._bounds2 = new Phaser.Rectangle();
+
+ /**
+ * @property {number} _overlap - Internal cache var.
+ * @private
+ */
+ this._overlap = 0;
+
+ /**
+ * @property {number} _maxOverlap - Internal cache var.
+ * @private
+ */
+ this._maxOverlap = 0;
+
+ /**
+ * @property {number} _velocity1 - Internal cache var.
+ * @private
+ */
+ this._velocity1 = 0;
+
+ /**
+ * @property {number} _velocity2 - Internal cache var.
+ * @private
+ */
+ this._velocity2 = 0;
+
+ /**
+ * @property {number} _newVelocity1 - Internal cache var.
+ * @private
+ */
+ this._newVelocity1 = 0;
+
+ /**
+ * @property {number} _newVelocity2 - Internal cache var.
+ * @private
+ */
+ this._newVelocity2 = 0;
+
+ /**
+ * @property {number} _average - Internal cache var.
+ * @private
+ */
+ this._average = 0;
+
+ /**
+ * @property {Array} _mapData - Internal cache var.
+ * @private
+ */
+ this._mapData = [];
+
+ /**
+ * @property {number} _mapTiles - Internal cache var.
+ * @private
+ */
+ this._mapTiles = 0;
+
+ /**
+ * @property {boolean} _result - Internal cache var.
+ * @private
+ */
+ this._result = false;
+
+ /**
+ * @property {number} _total - Internal cache var.
+ * @private
+ */
+ this._total = 0;
+
+ /**
+ * @property {number} _angle - Internal cache var.
+ * @private
+ */
+ this._angle = 0;
+
+ /**
+ * @property {number} _dx - Internal cache var.
+ * @private
+ */
+ this._dx = 0;
+
+ /**
+ * @property {number} _dy - Internal cache var.
+ * @private
+ */
+ this._dy = 0;
+
+};
+
+Phaser.Physics.Arcade.prototype = {
+
+ /**
+ * Called automatically by a Physics body, it updates all motion related values on the Body.
+ *
+ * @method Phaser.Physics.Arcade#updateMotion
+ * @param {Phaser.Physics.Arcade.Body} The Body object to be updated.
+ */
+ updateMotion: function (body) {
+
+ // If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html
+
+ // Rotation
+ this._velocityDelta = (this.computeVelocity(body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular, 0) - body.angularVelocity) * 0.5;
+ body.angularVelocity += this._velocityDelta;
+ body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
+ body.angularVelocity += this._velocityDelta;
+
+ if(body.allowGravity)
+ {
+ // Gravity was previously applied without taking physicsElapsed into account
+ // so it needs to be multiplied by 60 (fps) for compatibility with existing games
+ this._gravityX = (this.gravity.x + body.gravity.x) * 60;
+ this._gravityY = (this.gravity.y + body.gravity.y) * 60;
+ } else {
+ this._gravityX = this._gravityY = 0;
+ }
+
+ // Horizontal
+ this._velocityDelta = (this.computeVelocity(body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x, this._gravityX) - body.velocity.x) * 0.5;
+ body.velocity.x += this._velocityDelta;
+ body.x += (body.velocity.x * this.game.time.physicsElapsed);
+ body.velocity.x += this._velocityDelta;
+
+ // Vertical
+ this._velocityDelta = (this.computeVelocity(body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y, this._gravityY) - body.velocity.y) * 0.5;
+ body.velocity.y += this._velocityDelta;
+ body.y += (body.velocity.y * this.game.time.physicsElapsed);
+ body.velocity.y += this._velocityDelta;
+
+ },
+
+ /**
+ * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
+ *
+ * @method Phaser.Physics.Arcade#computeVelocity
+ * @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated.
+ * @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=10000] - An absolute value cap for the velocity.
+ * @param {number} gravity - The acceleration due to gravity. Gravity will not induce drag.
+ * @return {number} The altered Velocity value.
+ */
+ computeVelocity: function (body, velocity, acceleration, drag, max, gravity) {
+
+ max = max || 10000;
+
+ velocity += (acceleration + gravity) * this.game.time.physicsElapsed;
+
+ if (acceleration === 0 && drag !== 0)
+ {
+ this._drag = drag * this.game.time.physicsElapsed;
+
+ if (velocity - this._drag > 0)
+ {
+ velocity -= this._drag;
+ }
+ else if (velocity + this._drag < 0)
+ {
+ velocity += this._drag;
+ }
+ else
+ {
+ velocity = 0;
+ }
+ }
+
+ if (velocity > max)
+ {
+ velocity = max;
+ }
+ else if (velocity < -max)
+ {
+ velocity = -max;
+ }
+
+ return velocity;
+
+ },
+
+ /**
+ * Called automatically by the core game loop.
+ *
+ * @method Phaser.Physics.Arcade#preUpdate
+ * @protected
+ */
+ preUpdate: function () {
+
+ // Clear the tree
+ this.quadTree.clear();
+
+ // Create our tree which all of the Physics bodies will add themselves to
+ this.quadTreeID = 0;
+ this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
+
+ },
+
+ /**
+ * Called automatically by the core game loop.
+ *
+ * @method Phaser.Physics.Arcade#postUpdate
+ * @protected
+ */
+ postUpdate: function () {
+
+ // Clear the tree ready for the next update
+ this.quadTree.clear();
+
+ },
+
+ /**
+ * Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters.
+ * You can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks.
+ * Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.
+ *
+ * @method Phaser.Physics.Arcade#overlap
+ * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
+ * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
+ * @param {function} [overlapCallback=null] - An optional 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 specified them.
+ * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then overlapCallback will only be called if processCallback returns true.
+ * @param {object} [callbackContext] - The context in which to run the callbacks.
+ * @returns {boolean} True if an overlap occured otherwise false.
+ */
+ overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) {
+
+ overlapCallback = overlapCallback || null;
+ processCallback = processCallback || null;
+ callbackContext = callbackContext || overlapCallback;
+
+ this._result = false;
+ this._total = 0;
+
+ // Only test valid objects
+ if (object1 && object2 && object1.exists && object2.exists)
+ {
+ // SPRITES
+ if (object1.type == Phaser.SPRITE || object1.type == Phaser.TILESPRITE)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.overlapSpriteVsSprite(object1, object2, overlapCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.overlapSpriteVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
+ }
+ }
+ // GROUPS
+ else if (object1.type == Phaser.GROUP)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
+ }
+ }
+ // EMITTER
+ else if (object1.type == Phaser.EMITTER)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
+ }
+ }
+ }
+
+ return (this._total > 0);
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.overlap instead.
+ *
+ * @method Phaser.Physics.Arcade#overlapSpriteVsSprite
+ * @private
+ */
+ overlapSpriteVsSprite: function (sprite1, sprite2, overlapCallback, processCallback, callbackContext) {
+
+ this._result = Phaser.Rectangle.intersects(sprite1.body, sprite2.body);
+
+ if (this._result)
+ {
+ // They collided, is there a custom process callback?
+ if (processCallback)
+ {
+ if (processCallback.call(callbackContext, sprite1, sprite2))
+ {
+ this._total++;
+
+ if (overlapCallback)
+ {
+ overlapCallback.call(callbackContext, sprite1, sprite2);
+ }
+ }
+ }
+ else
+ {
+ this._total++;
+
+ if (overlapCallback)
+ {
+ overlapCallback.call(callbackContext, sprite1, sprite2);
+ }
+ }
+ }
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.overlap instead.
+ *
+ * @method Phaser.Physics.Arcade#overlapSpriteVsGroup
+ * @private
+ */
+ overlapSpriteVsGroup: function (sprite, group, overlapCallback, processCallback, callbackContext) {
+
+ if (group.length === 0)
+ {
+ return;
+ }
+
+ // What is the sprite colliding with in the quadtree?
+ this._potentials = this.quadTree.retrieve(sprite);
+
+ for (var i = 0, len = this._potentials.length; i < len; i++)
+ {
+ // We have our potential suspects, are they in this group?
+ if (this._potentials[i].sprite.group == group)
+ {
+ this._result = Phaser.Rectangle.intersects(sprite.body, this._potentials[i]);
+
+ if (this._result && processCallback)
+ {
+ this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite);
+ }
+
+ if (this._result)
+ {
+ this._total++;
+
+ if (overlapCallback)
+ {
+ overlapCallback.call(callbackContext, sprite, this._potentials[i].sprite);
+ }
+ }
+ }
+ }
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.overlap instead.
+ *
+ * @method Phaser.Physics.Arcade#overlapGroupVsGroup
+ * @private
+ */
+ overlapGroupVsGroup: function (group1, group2, overlapCallback, processCallback, callbackContext) {
+
+ if (group1.length === 0 || group2.length === 0)
+ {
+ return;
+ }
+
+ if (group1._container.first._iNext)
+ {
+ var currentNode = group1._container.first._iNext;
+
+ do
+ {
+ if (currentNode.exists)
+ {
+ this.overlapSpriteVsGroup(currentNode, group2, overlapCallback, processCallback, callbackContext);
+ }
+ currentNode = currentNode._iNext;
+ }
+ while (currentNode != group1._container.last._iNext);
+ }
+
+ },
+
+ /**
+ * Checks for collision between two game objects. The objects can be Sprites, Groups, Emitters or Tilemap Layers.
+ * You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
+ * The objects are also automatically separated.
+ *
+ * @method Phaser.Physics.Arcade#collide
+ * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap
+ * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap
+ * @param {function} [collideCallback=null] - An optional 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 specified them.
+ * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collideCallback will only be called if processCallback returns true.
+ * @param {object} [callbackContext] - The context in which to run the callbacks.
+ * @returns {boolean} True if a collision occured otherwise false.
+ */
+ collide: function (object1, object2, collideCallback, processCallback, callbackContext) {
+
+ collideCallback = collideCallback || null;
+ processCallback = processCallback || null;
+ callbackContext = callbackContext || collideCallback;
+
+ this._result = false;
+ this._total = 0;
+
+ // Only collide valid objects
+ if (object1 && object2 && object1.exists && object2.exists)
+ {
+ // SPRITES
+ if (object1.type == Phaser.SPRITE || object1.type == Phaser.TILESPRITE)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.TILEMAPLAYER)
+ {
+ this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ }
+ // GROUPS
+ else if (object1.type == Phaser.GROUP)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.TILEMAPLAYER)
+ {
+ this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ }
+ // TILEMAP LAYERS
+ else if (object1.type == Phaser.TILEMAPLAYER)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
+ }
+ }
+ // EMITTER
+ else if (object1.type == Phaser.EMITTER)
+ {
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
+ {
+ this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
+ {
+ this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ else if (object2.type == Phaser.TILEMAPLAYER)
+ {
+ this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
+ }
+ }
+ }
+
+ return (this._total > 0);
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
+ *
+ * @method Phaser.Physics.Arcade#collideSpriteVsTilemapLayer
+ * @private
+ */
+ collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
+
+ this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true);
+
+ if (this._mapData.length === 0)
+ {
+ return;
+ }
+
+ if (this._mapData.length > 1)
+ {
+ // console.log(' multi sep ---------------------------------------------------------------------------------------------');
+ this.separateTiles(sprite.body, this._mapData);
+ }
+ else
+ {
+ var i = 0;
+ if (this.separateTile(sprite.body, this._mapData[i]))
+ {
+ // They collided, is there a custom process callback?
+ if (processCallback)
+ {
+ if (processCallback.call(callbackContext, sprite, this._mapData[i]))
+ {
+ this._total++;
+
+ if (collideCallback)
+ {
+ collideCallback.call(callbackContext, sprite, this._mapData[i]);
+ }
+ }
+ }
+ else
+ {
+ this._total++;
+
+ if (collideCallback)
+ {
+ collideCallback.call(callbackContext, sprite, this._mapData[i]);
+ }
+ }
+ }
+ }
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
+ *
+ * @method Phaser.Physics.Arcade#collideGroupVsTilemapLayer
+ * @private
+ */
+ collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext) {
+
+ if (group.length === 0)
+ {
+ return;
+ }
+
+ if (group._container.first._iNext)
+ {
+ var currentNode = group._container.first._iNext;
+
+ do
+ {
+ if (currentNode.exists)
+ {
+ this.collideSpriteVsTilemapLayer(currentNode, tilemapLayer, collideCallback, processCallback, callbackContext);
+ }
+ currentNode = currentNode._iNext;
+ }
+ while (currentNode != group._container.last._iNext);
+ }
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
+ *
+ * @method Phaser.Physics.Arcade#collideSpriteVsSprite
+ * @private
+ */
+ collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext) {
+
+ this.separate(sprite1.body, sprite2.body);
+
+ if (this._result)
+ {
+ // They collided, is there a custom process callback?
+ if (processCallback)
+ {
+ if (processCallback.call(callbackContext, sprite1, sprite2))
+ {
+ this._total++;
+
+ if (collideCallback)
+ {
+ collideCallback.call(callbackContext, sprite1, sprite2);
+ }
+ }
+ }
+ else
+ {
+ this._total++;
+
+ if (collideCallback)
+ {
+ collideCallback.call(callbackContext, sprite1, sprite2);
+ }
+ }
+ }
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
+ *
+ * @method Phaser.Physics.Arcade#collideSpriteVsGroup
+ * @private
+ */
+ collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext) {
+
+ if (group.length === 0)
+ {
+ return;
+ }
+
+ // What is the sprite colliding with in the quadtree?
+ this._potentials = this.quadTree.retrieve(sprite);
+
+ for (var i = 0, len = this._potentials.length; i < len; i++)
+ {
+ // We have our potential suspects, are they in this group?
+ if (this._potentials[i].sprite.group == group)
+ {
+ this.separate(sprite.body, this._potentials[i]);
+
+ if (this._result && processCallback)
+ {
+ this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite);
+ }
+
+ if (this._result)
+ {
+ this._total++;
+
+ if (collideCallback)
+ {
+ collideCallback.call(callbackContext, sprite, this._potentials[i].sprite);
+ }
+ }
+ }
+ }
+
+ },
+
+ /**
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
+ *
+ * @method Phaser.Physics.Arcade#collideGroupVsGroup
+ * @private
+ */
+ collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext) {
+
+ if (group1.length === 0 || group2.length === 0)
+ {
+ return;
+ }
+
+ if (group1._container.first._iNext)
+ {
+ var currentNode = group1._container.first._iNext;
+
+ do
+ {
+ if (currentNode.exists)
+ {
+ this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext);
+ }
+ currentNode = currentNode._iNext;
+ }
+ while (currentNode != group1._container.last._iNext);
+ }
+
+ },
+
+ /**
+ * The core separation function to separate two physics bodies.
+ * @method Phaser.Physics.Arcade#separate
+ * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
+ * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ */
+ separate: function (body1, body2) {
+
+ this._result = (this.separateX(body1, body2) || this.separateY(body1, body2));
+
+ },
+
+ /**
+ * The core separation function to separate two physics bodies on the x axis.
+ * @method Phaser.Physics.Arcade#separateX
+ * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
+ * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ */
+ separateX: function (body1, body2) {
+
+ // Can't separate two immovable bodies
+ if (body1.immovable && body2.immovable)
+ {
+ return false;
+ }
+
+ this._overlap = 0;
+
+ // Check if the hulls actually overlap
+ if (Phaser.Rectangle.intersects(body1, body2))
+ {
+ this._maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + this.OVERLAP_BIAS;
+
+ if (body1.deltaX() === 0 && body2.deltaX() === 0)
+ {
+ // They overlap but neither of them are moving
+ body1.embedded = true;
+ body2.embedded = true;
+ }
+ else if (body1.deltaX() > body2.deltaX())
+ {
+ // Body1 is moving right and/or Body2 is moving left
+ this._overlap = body1.x + body1.width - body2.x;
+
+ if ((this._overlap > this._maxOverlap) || body1.allowCollision.right === false || body2.allowCollision.left === false)
+ {
+ this._overlap = 0;
+ }
+ else
+ {
+ body1.touching.right = true;
+ body2.touching.left = true;
+ }
+ }
+ else if (body1.deltaX() < body2.deltaX())
+ {
+ // Body1 is moving left and/or Body2 is moving right
+ this._overlap = body1.x - body2.width - body2.x;
+
+ if ((-this._overlap > this._maxOverlap) || body1.allowCollision.left === false || body2.allowCollision.right === false)
+ {
+ this._overlap = 0;
+ }
+ else
+ {
+ body1.touching.left = true;
+ body2.touching.right = true;
+ }
+ }
+
+ // Then adjust their positions and velocities accordingly (if there was any overlap)
+ if (this._overlap !== 0)
+ {
+ body1.overlapX = this._overlap;
+ body2.overlapX = this._overlap;
+
+ if (body1.customSeparateX || body2.customSeparateX)
+ {
+ return true;
+ }
+
+ this._velocity1 = body1.velocity.x;
+ this._velocity2 = body2.velocity.x;
+
+ if (!body1.immovable && !body2.immovable)
+ {
+ this._overlap *= 0.5;
+
+ body1.x = body1.x - this._overlap;
+ body2.x += this._overlap;
+
+ this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1);
+ this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1);
+ this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
+ this._newVelocity1 -= this._average;
+ this._newVelocity2 -= this._average;
+
+ body1.velocity.x = this._average + this._newVelocity1 * body1.bounce.x;
+ body2.velocity.x = this._average + this._newVelocity2 * body2.bounce.x;
+ }
+ else if (!body1.immovable)
+ {
+ body1.x = body1.x - this._overlap;
+ body1.velocity.x = this._velocity2 - this._velocity1 * body1.bounce.x;
+ }
+ else if (!body2.immovable)
+ {
+ body2.x += this._overlap;
+ body2.velocity.x = this._velocity1 - this._velocity2 * body2.bounce.x;
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+
+ },
+
+ /**
+ * The core separation function to separate two physics bodies on the y axis.
+ * @method Phaser.Physics.Arcade#separateY
+ * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
+ * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ */
+ separateY: function (body1, body2) {
+
+ // Can't separate two immovable or non-existing bodys
+ if (body1.immovable && body2.immovable)
+ {
+ return false;
+ }
+
+ this._overlap = 0;
+
+ // Check if the hulls actually overlap
+ if (Phaser.Rectangle.intersects(body1, body2))
+ {
+ this._maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + this.OVERLAP_BIAS;
+
+ if (body1.deltaY() === 0 && body2.deltaY() === 0)
+ {
+ // They overlap but neither of them are moving
+ body1.embedded = true;
+ body2.embedded = true;
+ }
+ else if (body1.deltaY() > body2.deltaY())
+ {
+ // Body1 is moving down and/or Body2 is moving up
+ this._overlap = body1.y + body1.height - body2.y;
+
+ if ((this._overlap > this._maxOverlap) || body1.allowCollision.down === false || body2.allowCollision.up === false)
+ {
+ this._overlap = 0;
+ }
+ else
+ {
+ body1.touching.down = true;
+ body2.touching.up = true;
+ }
+ }
+ else if (body1.deltaY() < body2.deltaY())
+ {
+ // Body1 is moving up and/or Body2 is moving down
+ this._overlap = body1.y - body2.height - body2.y;
+
+ if ((-this._overlap > this._maxOverlap) || body1.allowCollision.up === false || body2.allowCollision.down === false)
+ {
+ this._overlap = 0;
+ }
+ else
+ {
+ body1.touching.up = true;
+ body2.touching.down = true;
+ }
+ }
+
+ // Then adjust their positions and velocities accordingly (if there was any overlap)
+ if (this._overlap !== 0)
+ {
+ body1.overlapY = this._overlap;
+ body2.overlapY = this._overlap;
+
+ if (body1.customSeparateY || body2.customSeparateY)
+ {
+ return true;
+ }
+
+ this._velocity1 = body1.velocity.y;
+ this._velocity2 = body2.velocity.y;
+
+ if (!body1.immovable && !body2.immovable)
+ {
+ this._overlap *= 0.5;
+
+ body1.y = body1.y - this._overlap;
+ body2.y += this._overlap;
+
+ this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1);
+ this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1);
+ this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
+ this._newVelocity1 -= this._average;
+ this._newVelocity2 -= this._average;
+
+ body1.velocity.y = this._average + this._newVelocity1 * body1.bounce.y;
+ body2.velocity.y = this._average + this._newVelocity2 * body2.bounce.y;
+ }
+ else if (!body1.immovable)
+ {
+ body1.y = body1.y - this._overlap;
+ body1.velocity.y = this._velocity2 - this._velocity1 * body1.bounce.y;
+
+ // This is special case code that handles things like horizontal moving platforms you can ride
+ if (body2.moves)
+ {
+ body1.x += body2.x - body2.preX;
+ }
+ }
+ else if (!body2.immovable)
+ {
+ body2.y += this._overlap;
+ body2.velocity.y = this._velocity1 - this._velocity2 * body2.bounce.y;
+
+ // This is special case code that handles things like horizontal moving platforms you can ride
+ if (body1.moves)
+ {
+ body2.x += body1.x - body1.preX;
+ }
+ }
+
+ return true;
+ }
+
+ }
+
+ return false;
+
+ },
+
+ /**
+ * The core separation function to separate a physics body and an array of tiles.
+ * @method Phaser.Physics.Arcade#separateTiles
+ * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
+ * @param {Phaser.Tile} tile - The tile to collide against.
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ */
+ separateTiles: function (body, tiles) {
+
+ // Can't separate two immovable objects (tiles are always immovable)
+ if (body.immovable)
+ {
+ return false;
+ }
+
+ body.overlapX = 0;
+ body.overlapY = 0;
+
+ var tile;
+ var localOverlapX = 0;
+ var localOverlapY = 0;
+
+ for (var i = 0; i < tiles.length; i++)
+ {
+ tile = tiles[i];
+
+ if (Phaser.Rectangle.intersects(body, tile))
+ {
+ if (body.deltaX() < 0 && body.allowCollision.left && tile.tile.faceRight)
+ {
+ // LEFT
+ localOverlapX = body.x - tile.right;
+
+ if (localOverlapX >= body.deltaX())
+ {
+ // console.log('m left overlapX', localOverlapX, body.deltaX());
+ // use touching instead of blocked?
+ body.blocked.left = true;
+ body.touching.left = true;
+ body.touching.none = false;
+ }
+ }
+ else if (body.deltaX() > 0 && body.allowCollision.right && tile.tile.faceLeft)
+ {
+ // RIGHT
+ localOverlapX = body.right - tile.x;
+
+ // Distance check
+ if (localOverlapX <= body.deltaX())
+ {
+ // console.log('m right overlapX', localOverlapX, body.deltaX());
+ body.blocked.right = true;
+ body.touching.right = true;
+ body.touching.none = false;
+ }
+ }
+
+ if (body.deltaY() < 0 && body.allowCollision.up && tile.tile.faceBottom)
+ {
+ // UP
+ localOverlapY = body.y - tile.bottom;
+
+ // Distance check
+ if (localOverlapY >= body.deltaY())
+ {
+ // console.log('m up overlapY', localOverlapY, body.deltaY());
+ body.blocked.up = true;
+ body.touching.up = true;
+ body.touching.none = false;
+ }
+ }
+ else if (body.deltaY() > 0 && body.allowCollision.down && tile.tile.faceTop)
+ {
+ // DOWN
+ localOverlapY = body.bottom - tile.y;
+
+ if (localOverlapY <= body.deltaY())
+ {
+ // console.log('m down overlapY', localOverlapY, body.deltaY());
+ body.blocked.down = true;
+ body.touching.down = true;
+ body.touching.none = false;
+ }
+ }
+ }
+ }
+
+ if (localOverlapX !== 0)
+ {
+ body.overlapX = localOverlapX;
+ }
+
+ if (localOverlapY !== 0)
+ {
+ body.overlapY = localOverlapY;
+ }
+
+ if (body.touching.none)
+ {
+ return false;
+ }
+
+ // if (body.overlapX !== 0)
+ if (body.touching.left || body.touching.right)
+ {
+ body.x -= body.overlapX;
+ body.preX -= body.overlapX;
+
+ if (body.bounce.x === 0)
+ {
+ body.velocity.x = 0;
+ }
+ else
+ {
+ body.velocity.x = -body.velocity.x * body.bounce.x;
+ }
+ }
+
+ // if (body.overlapY !== 0)
+ if (body.touching.up || body.touching.down)
+ {
+ body.y -= body.overlapY;
+ body.preY -= body.overlapY;
+
+ if (body.bounce.y === 0)
+ {
+ body.velocity.y = 0;
+ }
+ else
+ {
+ body.velocity.y = -body.velocity.y * body.bounce.y;
+ }
+ }
+
+ return true;
+
+ },
+
+ /**
+ * The core separation function to separate a physics body and a tile.
+ * @method Phaser.Physics.Arcade#separateTile
+ * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
+ * @param {Phaser.Tile} tile - The tile to collide against.
+ * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ */
+ separateTile: function (body, tile) {
+
+ // Can't separate two immovable objects (tiles are always immovable)
+ if (body.immovable || Phaser.Rectangle.intersects(body, tile) === false)
+ {
+ // console.log('no intersects');
+ // console.log('tx', tile.x, 'ty', tile.y, 'tw', tile.width, 'th', tile.height, 'tr', tile.right, 'tb', tile.bottom);
+ // console.log('bx', body.x, 'by', body.y, 'bw', body.width, 'bh', body.height, 'br', body.right, 'bb', body.bottom);
+ return false;
+ }
+
+ // use body var instead
+ body.overlapX = 0;
+ body.overlapY = 0;
+
+ // Remember - this happens AFTER the body has been moved by the motion update, so it needs moving back again
+ // console.log('---------------------------------------------------------------------------------------------');
+ // console.log('tx', tile.x, 'ty', tile.y, 'tw', tile.width, 'th', tile.height, 'tr', tile.right, 'tb', tile.bottom);
+ // console.log('bx', body.x, 'by', body.y, 'bw', body.width, 'bh', body.height, 'br', body.right, 'bb', body.bottom);
+ // console.log(Phaser.Rectangle.intersects(body, tile));
+ // console.log('dx', body.deltaX(), 'dy', body.deltaY(), 'dax', body.deltaAbsX(), 'day', body.deltaAbsY(), 'cax', Math.ceil(body.deltaAbsX()), 'cay', Math.ceil(body.deltaAbsY()));
+
+ if (body.deltaX() < 0 && body.allowCollision.left && tile.tile.faceRight)
+ {
+ // LEFT
+ body.overlapX = body.x - tile.right;
+
+ if (body.overlapX >= body.deltaX())
+ {
+ // console.log('left overlapX', body.overlapX, body.deltaX());
+ // use touching instead of blocked?
+ body.blocked.left = true;
+ body.touching.left = true;
+ body.touching.none = false;
+ }
+ }
+ else if (body.deltaX() > 0 && body.allowCollision.right && tile.tile.faceLeft)
+ {
+ // RIGHT
+ body.overlapX = body.right - tile.x;
+
+ // Distance check
+ if (body.overlapX <= body.deltaX())
+ {
+ // console.log('right overlapX', body.overlapX, body.deltaX());
+ body.blocked.right = true;
+ body.touching.right = true;
+ body.touching.none = false;
+ }
+ }
+
+ if (body.deltaY() < 0 && body.allowCollision.up && tile.tile.faceBottom)
+ {
+ // UP
+ body.overlapY = body.y - tile.bottom;
+
+ // Distance check
+ if (body.overlapY >= body.deltaY())
+ {
+ // console.log('up overlapY', body.overlapY, body.deltaY());
+ body.blocked.up = true;
+ body.touching.up = true;
+ body.touching.none = false;
+ }
+ }
+ else if (body.deltaY() > 0 && body.allowCollision.down && tile.tile.faceTop)
+ {
+ // DOWN
+ body.overlapY = body.bottom - tile.y;
+
+ if (body.overlapY <= body.deltaY())
+ {
+ // console.log('down overlapY', body.overlapY, body.deltaY());
+ body.blocked.down = true;
+ body.touching.down = true;
+ body.touching.none = false;
+ }
+ }
+
+ // Separate in a single sweep
+
+ if (body.touching.none)
+ {
+ return false;
+ }
+
+ // if (body.overlapX !== 0)
+ if (body.touching.left || body.touching.right)
+ {
+ body.x -= body.overlapX;
+ body.preX -= body.overlapX;
+
+ if (body.bounce.x === 0)
+ {
+ body.velocity.x = 0;
+ }
+ else
+ {
+ body.velocity.x = -body.velocity.x * body.bounce.x;
+ }
+ }
+
+ // if (body.overlapY !== 0)
+ if (body.touching.up || body.touching.down)
+ {
+ body.y -= body.overlapY;
+ body.preY -= body.overlapY;
+
+ if (body.bounce.y === 0)
+ {
+ body.velocity.y = 0;
+ }
+ else
+ {
+ body.velocity.y = -body.velocity.y * body.bounce.y;
+ }
+ }
+
+ return true;
+
+ },
+
+ /**
+ * Move the given display object towards the destination object at a steady velocity.
+ * If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds.
+ * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.
+ * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
+ * Note: The display object doesn't stop moving once it reaches the destination coordinates.
+ * Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all)
+ *
+ * @method Phaser.Physics.Arcade#moveToObject
+ * @param {any} displayObject - The display object to move.
+ * @param {any} destination - The display object to move towards. Can be any object but must have visible x/y properties.
+ * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec)
+ * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms.
+ * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
+ */
+ moveToObject: function (displayObject, destination, speed, maxTime) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ if (typeof maxTime === 'undefined') { maxTime = 0; }
+
+ this._angle = Math.atan2(destination.y - displayObject.y, destination.x - displayObject.x);
+
+ if (maxTime > 0)
+ {
+ // We know how many pixels we need to move, but how fast?
+ speed = this.distanceBetween(displayObject, destination) / (maxTime / 1000);
+ }
+
+ displayObject.body.velocity.x = Math.cos(this._angle) * speed;
+ displayObject.body.velocity.y = Math.sin(this._angle) * speed;
+
+ return this._angle;
+
+ },
+
+ /**
+ * Move the given display object towards the pointer at a steady velocity. If no pointer is given it will use Phaser.Input.activePointer.
+ * If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
+ * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.
+ * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
+ * Note: The display object doesn't stop moving once it reaches the destination coordinates.
+ *
+ * @method Phaser.Physics.Arcade#moveToPointer
+ * @param {any} displayObject - The display object to move.
+ * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec)
+ * @param {Phaser.Pointer} [pointer] - The pointer to move towards. Defaults to Phaser.Input.activePointer.
+ * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms.
+ * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
+ */
+ moveToPointer: function (displayObject, speed, pointer, maxTime) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ pointer = pointer || this.game.input.activePointer;
+ if (typeof maxTime === 'undefined') { maxTime = 0; }
+
+ this._angle = this.angleToPointer(displayObject, pointer);
+
+ if (maxTime > 0)
+ {
+ // We know how many pixels we need to move, but how fast?
+ speed = this.distanceToPointer(displayObject, pointer) / (maxTime / 1000);
+ }
+
+ displayObject.body.velocity.x = Math.cos(this._angle) * speed;
+ displayObject.body.velocity.y = Math.sin(this._angle) * speed;
+
+ return this._angle;
+
+ },
+
+ /**
+ * Move the given display object towards the x/y coordinates at a steady velocity.
+ * If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
+ * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.
+ * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
+ * Note: The display object doesn't stop moving once it reaches the destination coordinates.
+ * Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all)
+ *
+ * @method Phaser.Physics.Arcade#moveToXY
+ * @param {any} displayObject - The display object to move.
+ * @param {number} x - The x coordinate to move towards.
+ * @param {number} y - The y coordinate to move towards.
+ * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec)
+ * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms.
+ * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
+ */
+ moveToXY: function (displayObject, x, y, speed, maxTime) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ if (typeof maxTime === 'undefined') { maxTime = 0; }
+
+ this._angle = Math.atan2(y - displayObject.y, x - displayObject.x);
+
+ if (maxTime > 0)
+ {
+ // We know how many pixels we need to move, but how fast?
+ speed = this.distanceToXY(displayObject, x, y) / (maxTime / 1000);
+ }
+
+ displayObject.body.velocity.x = Math.cos(this._angle) * speed;
+ displayObject.body.velocity.y = Math.sin(this._angle) * speed;
+
+ return this._angle;
+
+ },
+
+ /**
+ * Given the angle (in degrees) and speed calculate the velocity and return it as a Point object, or set it to the given point object.
+ * One way to use this is: velocityFromAngle(angle, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.
+ *
+ * @method Phaser.Physics.Arcade#velocityFromAngle
+ * @param {number} angle - The angle in degrees calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)
+ * @param {number} [speed=60] - The speed it will move, in pixels per second sq.
+ * @param {Phaser.Point|object} [point] - The Point object in which the x and y properties will be set to the calculated velocity.
+ * @return {Phaser.Point} - A Point where point.x contains the velocity x value and point.y contains the velocity y value.
+ */
+ velocityFromAngle: function (angle, speed, point) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ point = point || new Phaser.Point();
+
+ return point.setTo((Math.cos(this.game.math.degToRad(angle)) * speed), (Math.sin(this.game.math.degToRad(angle)) * speed));
+
+ },
+
+ /**
+ * Given the rotation (in radians) and speed calculate the velocity and return it as a Point object, or set it to the given point object.
+ * One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.
+ *
+ * @method Phaser.Physics.Arcade#velocityFromRotation
+ * @param {number} rotation - The angle in radians.
+ * @param {number} [speed=60] - The speed it will move, in pixels per second sq.
+ * @param {Phaser.Point|object} [point] - The Point object in which the x and y properties will be set to the calculated velocity.
+ * @return {Phaser.Point} - A Point where point.x contains the velocity x value and point.y contains the velocity y value.
+ */
+ velocityFromRotation: function (rotation, speed, point) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ point = point || new Phaser.Point();
+
+ return point.setTo((Math.cos(rotation) * speed), (Math.sin(rotation) * speed));
+
+ },
+
+ /**
+ * Given the rotation (in radians) and speed calculate the acceleration and return it as a Point object, or set it to the given point object.
+ * One way to use this is: accelerationFromRotation(rotation, 200, sprite.acceleration) which will set the values directly to the sprites acceleration and not create a new Point object.
+ *
+ * @method Phaser.Physics.Arcade#accelerationFromRotation
+ * @param {number} rotation - The angle in radians.
+ * @param {number} [speed=60] - The speed it will move, in pixels per second sq.
+ * @param {Phaser.Point|object} [point] - The Point object in which the x and y properties will be set to the calculated acceleration.
+ * @return {Phaser.Point} - A Point where point.x contains the acceleration x value and point.y contains the acceleration y value.
+ */
+ accelerationFromRotation: function (rotation, speed, point) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ point = point || new Phaser.Point();
+
+ return point.setTo((Math.cos(rotation) * speed), (Math.sin(rotation) * speed));
+
+ },
+
+ /**
+ * Sets the acceleration.x/y property on the display object so it will move towards the target at the given speed (in pixels per second sq.)
+ * You must give a maximum speed value, beyond which the display object won't go any faster.
+ * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
+ * Note: The display object doesn't stop moving once it reaches the destination coordinates.
+ *
+ * @method Phaser.Physics.Arcade#accelerateToObject
+ * @param {any} displayObject - The display object to move.
+ * @param {any} destination - The display object to move towards. Can be any object but must have visible x/y properties.
+ * @param {number} [speed=60] - The speed it will accelerate in pixels per second.
+ * @param {number} [xSpeedMax=500] - The maximum x velocity the display object can reach.
+ * @param {number} [ySpeedMax=500] - The maximum y velocity the display object can reach.
+ * @return {number} The angle (in radians) that the object should be visually set to in order to match its new trajectory.
+ */
+ accelerateToObject: function (displayObject, destination, speed, xSpeedMax, ySpeedMax) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ if (typeof xSpeedMax === 'undefined') { xSpeedMax = 1000; }
+ if (typeof ySpeedMax === 'undefined') { ySpeedMax = 1000; }
+
+ this._angle = this.angleBetween(displayObject, destination);
+
+ displayObject.body.acceleration.setTo(Math.cos(this._angle) * speed, Math.sin(this._angle) * speed);
+ displayObject.body.maxVelocity.setTo(xSpeedMax, ySpeedMax);
+
+ return this._angle;
+
+ },
+
+ /**
+ * Sets the acceleration.x/y property on the display object so it will move towards the target at the given speed (in pixels per second sq.)
+ * You must give a maximum speed value, beyond which the display object won't go any faster.
+ * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
+ * Note: The display object doesn't stop moving once it reaches the destination coordinates.
+ *
+ * @method Phaser.Physics.Arcade#accelerateToPointer
+ * @param {any} displayObject - The display object to move.
+ * @param {Phaser.Pointer} [pointer] - The pointer to move towards. Defaults to Phaser.Input.activePointer.
+ * @param {number} [speed=60] - The speed it will accelerate in pixels per second.
+ * @param {number} [xSpeedMax=500] - The maximum x velocity the display object can reach.
+ * @param {number} [ySpeedMax=500] - The maximum y velocity the display object can reach.
+ * @return {number} The angle (in radians) that the object should be visually set to in order to match its new trajectory.
+ */
+ accelerateToPointer: function (displayObject, pointer, speed, xSpeedMax, ySpeedMax) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ if (typeof pointer === 'undefined') { pointer = this.game.input.activePointer; }
+ if (typeof xSpeedMax === 'undefined') { xSpeedMax = 1000; }
+ if (typeof ySpeedMax === 'undefined') { ySpeedMax = 1000; }
+
+ this._angle = this.angleToPointer(displayObject, pointer);
+
+ displayObject.body.acceleration.setTo(Math.cos(this._angle) * speed, Math.sin(this._angle) * speed);
+ displayObject.body.maxVelocity.setTo(xSpeedMax, ySpeedMax);
+
+ return this._angle;
+
+ },
+
+ /**
+ * Sets the acceleration.x/y property on the display object so it will move towards the x/y coordinates at the given speed (in pixels per second sq.)
+ * You must give a maximum speed value, beyond which the display object won't go any faster.
+ * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
+ * Note: The display object doesn't stop moving once it reaches the destination coordinates.
+ *
+ * @method Phaser.Physics.Arcade#accelerateToXY
+ * @param {any} displayObject - The display object to move.
+ * @param {number} x - The x coordinate to accelerate towards.
+ * @param {number} y - The y coordinate to accelerate towards.
+ * @param {number} [speed=60] - The speed it will accelerate in pixels per second.
+ * @param {number} [xSpeedMax=500] - The maximum x velocity the display object can reach.
+ * @param {number} [ySpeedMax=500] - The maximum y velocity the display object can reach.
+ * @return {number} The angle (in radians) that the object should be visually set to in order to match its new trajectory.
+ */
+ accelerateToXY: function (displayObject, x, y, speed, xSpeedMax, ySpeedMax) {
+
+ if (typeof speed === 'undefined') { speed = 60; }
+ if (typeof xSpeedMax === 'undefined') { xSpeedMax = 1000; }
+ if (typeof ySpeedMax === 'undefined') { ySpeedMax = 1000; }
+
+ this._angle = this.angleToXY(displayObject, x, y);
+
+ displayObject.body.acceleration.setTo(Math.cos(this._angle) * speed, Math.sin(this._angle) * speed);
+ displayObject.body.maxVelocity.setTo(xSpeedMax, ySpeedMax);
+
+ return this._angle;
+
+ },
+
+ /**
+ * Find the distance between two display objects (like Sprites).
+ *
+ * @method Phaser.Physics.Arcade#distanceBetween
+ * @param {any} source - The Display Object to test from.
+ * @param {any} target - The Display Object to test to.
+ * @return {number} The distance between the source and target objects.
+ */
+ distanceBetween: function (source, target) {
+
+ this._dx = source.x - target.x;
+ this._dy = source.y - target.y;
+
+ return Math.sqrt(this._dx * this._dx + this._dy * this._dy);
+
+ },
+
+ /**
+ * Find the distance between a display object (like a Sprite) and the given x/y coordinates.
+ * The calculation is made from the display objects x/y coordinate. This may be the top-left if its anchor hasn't been changed.
+ * If you need to calculate from the center of a display object instead use the method distanceBetweenCenters()
+ *
+ * @method Phaser.Physics.Arcade#distanceToXY
+ * @param {any} displayObject - The Display Object to test from.
+ * @param {number} x - The x coordinate to move towards.
+ * @param {number} y - The y coordinate to move towards.
+ * @return {number} The distance between the object and the x/y coordinates.
+ */
+ distanceToXY: function (displayObject, x, y) {
+
+ this._dx = displayObject.x - x;
+ this._dy = displayObject.y - y;
+
+ return Math.sqrt(this._dx * this._dx + this._dy * this._dy);
+
+ },
+
+ /**
+ * Find the distance between a display object (like a Sprite) and a Pointer. If no Pointer is given the Input.activePointer is used.
+ * The calculation is made from the display objects x/y coordinate. This may be the top-left if its anchor hasn't been changed.
+ * If you need to calculate from the center of a display object instead use the method distanceBetweenCenters()
+ *
+ * @method Phaser.Physics.Arcade#distanceToPointer
+ * @param {any} displayObject - The Display Object to test from.
+ * @param {Phaser.Pointer} [pointer] - The Phaser.Pointer to test to. If none is given then Input.activePointer is used.
+ * @return {number} The distance between the object and the Pointer.
+ */
+ distanceToPointer: function (displayObject, pointer) {
+
+ pointer = pointer || this.game.input.activePointer;
+
+ this._dx = displayObject.x - pointer.x;
+ this._dy = displayObject.y - pointer.y;
+
+ return Math.sqrt(this._dx * this._dx + this._dy * this._dy);
+
+ },
+
+ /**
+ * Find the angle in radians between two display objects (like Sprites).
+ *
+ * @method Phaser.Physics.Arcade#angleBetween
+ * @param {any} source - The Display Object to test from.
+ * @param {any} target - The Display Object to test to.
+ * @return {number} The angle in radians between the source and target display objects.
+ */
+ angleBetween: function (source, target) {
+
+ this._dx = target.x - source.x;
+ this._dy = target.y - source.y;
+
+ return Math.atan2(this._dy, this._dx);
+
+ },
+
+ /**
+ * Find the angle in radians between a display object (like a Sprite) and the given x/y coordinate.
+ *
+ * @method Phaser.Physics.Arcade#angleToXY
+ * @param {any} displayObject - The Display Object to test from.
+ * @param {number} x - The x coordinate to get the angle to.
+ * @param {number} y - The y coordinate to get the angle to.
+ * @return {number} The angle in radians between displayObject.x/y to Pointer.x/y
+ */
+ angleToXY: function (displayObject, x, y) {
+
+ this._dx = x - displayObject.x;
+ this._dy = y - displayObject.y;
+
+ return Math.atan2(this._dy, this._dx);
+
+ },
+
+ /**
+ * Find the angle in radians between a display object (like a Sprite) and a Pointer, taking their x/y and center into account.
+ *
+ * @method Phaser.Physics.Arcade#angleToPointer
+ * @param {any} displayObject - The Display Object to test from.
+ * @param {Phaser.Pointer} [pointer] - The Phaser.Pointer to test to. If none is given then Input.activePointer is used.
+ * @return {number} The angle in radians between displayObject.x/y to Pointer.x/y
+ */
+ angleToPointer: function (displayObject, pointer) {
+
+ pointer = pointer || this.game.input.activePointer;
+
+ this._dx = pointer.worldX - displayObject.x;
+ this._dy = pointer.worldY - displayObject.y;
+
+ return Math.atan2(this._dy, this._dx);
+
+ }
+
+};
diff --git a/src/physics/Body.js b/src/physics/p2/Body.js
similarity index 100%
rename from src/physics/Body.js
rename to src/physics/p2/Body.js
diff --git a/src/physics/CollisionGroup.js b/src/physics/p2/CollisionGroup.js
similarity index 80%
rename from src/physics/CollisionGroup.js
rename to src/physics/p2/CollisionGroup.js
index 5f27ea57..f4270d3c 100644
--- a/src/physics/CollisionGroup.js
+++ b/src/physics/p2/CollisionGroup.js
@@ -7,11 +7,11 @@
/**
* Collision Group
*
-* @class Phaser.Physics.CollisionGroup
+* @class Phaser.Physics.P2.CollisionGroup
* @classdesc Physics Collision Group Constructor
* @constructor
*/
-Phaser.Physics.CollisionGroup = function (bitmask) {
+Phaser.Physics.P2.CollisionGroup = function (bitmask) {
/**
* @property {number} mask - The CollisionGroup bitmask.
diff --git a/src/physics/ContactMaterial.js b/src/physics/p2/ContactMaterial.js
similarity index 69%
rename from src/physics/ContactMaterial.js
rename to src/physics/p2/ContactMaterial.js
index 486f8558..4f1328e7 100644
--- a/src/physics/ContactMaterial.js
+++ b/src/physics/p2/ContactMaterial.js
@@ -7,25 +7,25 @@
/**
* Defines a physics material
*
-* @class Phaser.Physics.ContactMaterial
+* @class Phaser.Physics.P2.ContactMaterial
* @classdesc Physics ContactMaterial Constructor
* @constructor
-* @param {Phaser.Physics.Material} materialA
-* @param {Phaser.Physics.Material} materialB
+* @param {Phaser.Physics.P2.Material} materialA
+* @param {Phaser.Physics.P2.Material} materialB
* @param {object} [options]
*/
-Phaser.Physics.ContactMaterial = function (materialA, materialB, options) {
+Phaser.Physics.P2.ContactMaterial = function (materialA, materialB, options) {
/**
* @property {number} id - The contact material identifier.
*/
/**
- * @property {Phaser.Physics.Material} materialA - First material participating in the contact material.
+ * @property {Phaser.Physics.P2.Material} materialA - First material participating in the contact material.
*/
/**
- * @property {Phaser.Physics.Material} materialB - First second participating in the contact material.
+ * @property {Phaser.Physics.P2.Material} materialB - First second participating in the contact material.
*/
/**
@@ -60,5 +60,5 @@ Phaser.Physics.ContactMaterial = function (materialA, materialB, options) {
}
-Phaser.Physics.ContactMaterial.prototype = Object.create(p2.ContactMaterial.prototype);
-Phaser.Physics.ContactMaterial.prototype.constructor = Phaser.Physics.ContactMaterial;
+Phaser.Physics.P2.ContactMaterial.prototype = Object.create(p2.ContactMaterial.prototype);
+Phaser.Physics.P2.ContactMaterial.prototype.constructor = Phaser.Physics.P2.ContactMaterial;
diff --git a/src/physics/InversePointProxy.js b/src/physics/p2/InversePointProxy.js
similarity index 70%
rename from src/physics/InversePointProxy.js
rename to src/physics/p2/InversePointProxy.js
index c00d9af7..b2ccee2c 100644
--- a/src/physics/InversePointProxy.js
+++ b/src/physics/p2/InversePointProxy.js
@@ -7,26 +7,26 @@
/**
* A InversePointProxy is an internal class that allows for direct getter/setter style property access to Arrays and TypedArrays but inverses the values on set.
*
-* @class Phaser.Physics.InversePointProxy
+* @class Phaser.Physics.P2.InversePointProxy
* @classdesc InversePointProxy
* @constructor
* @param {Phaser.Game} game - A reference to the Phaser.Game instance.
* @param {any} destination - The object to bind to.
*/
-Phaser.Physics.InversePointProxy = function (game, destination) {
+Phaser.Physics.P2.InversePointProxy = function (game, destination) {
this.game = game;
this.destination = destination;
};
-Phaser.Physics.InversePointProxy.prototype.constructor = Phaser.Physics.InversePointProxy;
+Phaser.Physics.P2.InversePointProxy.prototype.constructor = Phaser.Physics.P2.InversePointProxy;
/**
-* @name Phaser.Physics.InversePointProxy#x
+* @name Phaser.Physics.P2.InversePointProxy#x
* @property {number} x - The x property of this InversePointProxy.
*/
-Object.defineProperty(Phaser.Physics.InversePointProxy.prototype, "x", {
+Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "x", {
get: function () {
@@ -43,10 +43,10 @@ Object.defineProperty(Phaser.Physics.InversePointProxy.prototype, "x", {
});
/**
-* @name Phaser.Physics.InversePointProxy#y
+* @name Phaser.Physics.P2.InversePointProxy#y
* @property {number} y - The y property of this InversePointProxy.
*/
-Object.defineProperty(Phaser.Physics.InversePointProxy.prototype, "y", {
+Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "y", {
get: function () {
diff --git a/src/physics/Material.js b/src/physics/p2/Material.js
similarity index 66%
rename from src/physics/Material.js
rename to src/physics/p2/Material.js
index 884ac525..08209361 100644
--- a/src/physics/Material.js
+++ b/src/physics/p2/Material.js
@@ -7,11 +7,11 @@
/**
* \o/ ~ "Because I'm a Material girl"
*
-* @class Phaser.Physics.Material
+* @class Phaser.Physics.P2.Material
* @classdesc Physics Material Constructor
* @constructor
*/
-Phaser.Physics.Material = function (name) {
+Phaser.Physics.P2.Material = function (name) {
/**
* @property {string} name - The user defined name given to this Material.
@@ -23,5 +23,5 @@ Phaser.Physics.Material = function (name) {
}
-Phaser.Physics.Material.prototype = Object.create(p2.Material.prototype);
-Phaser.Physics.Material.prototype.constructor = Phaser.Physics.Material;
+Phaser.Physics.P2.Material.prototype = Object.create(p2.Material.prototype);
+Phaser.Physics.P2.Material.prototype.constructor = Phaser.Physics.P2.Material;
diff --git a/src/physics/PointProxy.js b/src/physics/p2/PointProxy.js
similarity index 72%
rename from src/physics/PointProxy.js
rename to src/physics/p2/PointProxy.js
index 409ef782..1f2004a2 100644
--- a/src/physics/PointProxy.js
+++ b/src/physics/p2/PointProxy.js
@@ -7,26 +7,26 @@
/**
* A PointProxy is an internal class that allows for direct getter/setter style property access to Arrays and TypedArrays.
*
-* @class Phaser.Physics.PointProxy
+* @class Phaser.Physics.P2.PointProxy
* @classdesc PointProxy
* @constructor
* @param {Phaser.Game} game - A reference to the Phaser.Game instance.
* @param {any} destination - The object to bind to.
*/
-Phaser.Physics.PointProxy = function (game, destination) {
+Phaser.Physics.P2.PointProxy = function (game, destination) {
this.game = game;
this.destination = destination;
};
-Phaser.Physics.PointProxy.prototype.constructor = Phaser.Physics.PointProxy;
+Phaser.Physics.P2.PointProxy.prototype.constructor = Phaser.Physics.P2.PointProxy;
/**
-* @name Phaser.Physics.PointProxy#x
+* @name Phaser.Physics.P2.PointProxy#x
* @property {number} x - The x property of this PointProxy.
*/
-Object.defineProperty(Phaser.Physics.PointProxy.prototype, "x", {
+Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "x", {
get: function () {
@@ -43,10 +43,10 @@ Object.defineProperty(Phaser.Physics.PointProxy.prototype, "x", {
});
/**
-* @name Phaser.Physics.PointProxy#y
+* @name Phaser.Physics.P2.PointProxy#y
* @property {number} y - The y property of this PointProxy.
*/
-Object.defineProperty(Phaser.Physics.PointProxy.prototype, "y", {
+Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "y", {
get: function () {
diff --git a/src/physics/Spring.js b/src/physics/p2/Spring.js
similarity index 87%
rename from src/physics/Spring.js
rename to src/physics/p2/Spring.js
index 417f6923..58a6bb3a 100644
--- a/src/physics/Spring.js
+++ b/src/physics/p2/Spring.js
@@ -7,7 +7,7 @@
/**
* Creates a spring, connecting two bodies.
*
-* @class Phaser.Physics.Spring
+* @class Phaser.Physics.P2.Spring
* @classdesc Physics Spring Constructor
* @constructor
* @param {Phaser.Game} game - A reference to the current game.
@@ -21,7 +21,7 @@
* @param {Array} [localA] - Where to hook the spring to body A, in local body coordinates.
* @param {Array} [localB] - Where to hook the spring to body B, in local body coordinates.
*/
-Phaser.Physics.Spring = function (game, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB) {
+Phaser.Physics.P2.Spring = function (game, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB) {
/**
* @property {Phaser.Game} game - Local reference to game.
@@ -62,5 +62,5 @@ Phaser.Physics.Spring = function (game, bodyA, bodyB, restLength, stiffness, dam
}
-Phaser.Physics.Spring.prototype = Object.create(p2.Spring.prototype);
-Phaser.Physics.Spring.prototype.constructor = Phaser.Physics.Spring;
+Phaser.Physics.P2.Spring.prototype = Object.create(p2.Spring.prototype);
+Phaser.Physics.P2.Spring.prototype.constructor = Phaser.Physics.P2.Spring;
diff --git a/src/physics/World.js b/src/physics/p2/World.js
similarity index 81%
rename from src/physics/World.js
rename to src/physics/p2/World.js
index 4f8143dc..21e8ef87 100644
--- a/src/physics/World.js
+++ b/src/physics/p2/World.js
@@ -4,29 +4,24 @@
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
-/**
-* @class Phaser.Physics
-*/
-Phaser.Physics = {};
-
/**
* @const
* @type {number}
*/
-Phaser.Physics.LIME_CORONA_JSON = 0;
+Phaser.Physics.P2.LIME_CORONA_JSON = 0;
// Add an extra properties to p2 that we need
p2.Body.prototype.parent = null;
p2.Spring.prototype.parent = null;
/**
-* @class Phaser.Physics.World
+* @class Phaser.Physics.P2
* @classdesc Physics World Constructor
* @constructor
* @param {Phaser.Game} game - Reference to the current game instance.
* @param {object} [config] - Physics configuration object passed in from the game constructor.
*/
-Phaser.Physics.World = function (game, config) {
+Phaser.Physics.P2 = function (game, config) {
/**
* @property {Phaser.Game} game - Local reference to game.
@@ -45,7 +40,7 @@ Phaser.Physics.World = function (game, config) {
this.world = new p2.World(config);
/**
- * @property {array} materials - A local array of all created Materials.
+ * @property {array} materials - A local array of all created Materials.
* @protected
*/
this.materials = [];
@@ -53,7 +48,7 @@ Phaser.Physics.World = function (game, config) {
/**
* @property {Phaser.InversePointProxy} gravity - The gravity applied to all bodies each step.
*/
- this.gravity = new Phaser.Physics.InversePointProxy(game, this.world.gravity);
+ this.gravity = new Phaser.Physics.P2.InversePointProxy(game, this.world.gravity);
/**
* @property {p2.Body} bounds - The bounds body contains the 4 walls that border the World. Define or disable with setBounds.
@@ -149,9 +144,9 @@ Phaser.Physics.World = function (game, config) {
*/
this._collisionGroupID = 2;
- this.nothingCollisionGroup = new Phaser.Physics.CollisionGroup(1);
- this.boundsCollisionGroup = new Phaser.Physics.CollisionGroup(2);
- this.everythingCollisionGroup = new Phaser.Physics.CollisionGroup(2147483648);
+ 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.boundsCollidesWith = [];
@@ -162,12 +157,12 @@ Phaser.Physics.World = function (game, config) {
};
-Phaser.Physics.World.prototype = {
+Phaser.Physics.P2.prototype = {
/**
* Handles a p2 postStep event.
*
- * @method Phaser.Physics.World#postStepHandler
+ * @method Phaser.Physics.P2#postStepHandler
* @private
* @param {object} event - The event data.
*/
@@ -179,7 +174,7 @@ Phaser.Physics.World.prototype = {
* Fired after the Broadphase has collected collision pairs in the world.
* Inside the event handler, you can modify the pairs array as you like, to prevent collisions between objects that you don't want.
*
- * @method Phaser.Physics.World#postBroadphaseHandler
+ * @method Phaser.Physics.P2#postBroadphaseHandler
* @private
* @param {object} event - The event data.
*/
@@ -203,7 +198,7 @@ Phaser.Physics.World.prototype = {
/**
* Handles a p2 impact event.
*
- * @method Phaser.Physics.World#impactHandler
+ * @method Phaser.Physics.P2#impactHandler
* @private
* @param {object} event - The event data.
*/
@@ -242,7 +237,7 @@ Phaser.Physics.World.prototype = {
/**
* Handles a p2 begin contact event.
*
- * @method Phaser.Physics.World#beginContactHandler
+ * @method Phaser.Physics.P2#beginContactHandler
* @private
* @param {object} event - The event data.
*/
@@ -263,7 +258,7 @@ Phaser.Physics.World.prototype = {
/**
* Handles a p2 end contact event.
*
- * @method Phaser.Physics.World#endContactHandler
+ * @method Phaser.Physics.P2#endContactHandler
* @private
* @param {object} event - The event data.
*/
@@ -302,7 +297,7 @@ Phaser.Physics.World.prototype = {
* Sets the given material against the 4 bounds of this World.
*
* @method Phaser.Physics#setWorldMaterial
- * @param {Phaser.Physics.Material} material - The material to set.
+ * @param {Phaser.Physics.P2.Material} material - The material to set.
* @param {boolean} [left=true] - If true will set the material on the left bounds wall.
* @param {boolean} [right=true] - If true will set the material on the right bounds wall.
* @param {boolean} [top=true] - If true will set the material on the top bounds wall.
@@ -341,7 +336,7 @@ Phaser.Physics.World.prototype = {
* Sets the bounds of the Physics world to match the given world pixel dimensions.
* You can optionally set which 'walls' to create: left, right, top or bottom.
*
- * @method Phaser.Physics.World#setBounds
+ * @method Phaser.Physics.P2#setBounds
* @param {number} x - The x coordinate of the top-left corner of the bounds.
* @param {number} y - The y coordinate of the top-left corner of the bounds.
* @param {number} width - The width of the bounds.
@@ -449,7 +444,7 @@ Phaser.Physics.World.prototype = {
},
/**
- * @method Phaser.Physics.World#update
+ * @method Phaser.Physics.P2#update
*/
update: function () {
@@ -460,7 +455,7 @@ Phaser.Physics.World.prototype = {
/**
* Clears all bodies from the simulation.
*
- * @method Phaser.Physics.World#clear
+ * @method Phaser.Physics.P2#clear
*/
clear: function () {
@@ -471,7 +466,7 @@ Phaser.Physics.World.prototype = {
/**
* Clears all bodies from the simulation and unlinks World from Game. Should only be called on game shutdown. Call `clear` on a State change.
*
- * @method Phaser.Physics.World#destroy
+ * @method Phaser.Physics.P2#destroy
*/
destroy: function () {
@@ -484,8 +479,8 @@ Phaser.Physics.World.prototype = {
/**
* Add a body to the world.
*
- * @method Phaser.Physics.World#addBody
- * @param {Phaser.Physics.Body} body - The Body to add to the World.
+ * @method Phaser.Physics.P2#addBody
+ * @param {Phaser.Physics.P2.Body} body - The Body to add to the World.
* @return {boolean} True if the Body was added successfully, otherwise false.
*/
addBody: function (body) {
@@ -508,9 +503,9 @@ Phaser.Physics.World.prototype = {
/**
* Removes a body from the world.
*
- * @method Phaser.Physics.World#removeBody
- * @param {Phaser.Physics.Body} body - The Body to remove from the World.
- * @return {Phaser.Physics.Body} The Body that was removed.
+ * @method Phaser.Physics.P2#removeBody
+ * @param {Phaser.Physics.P2.Body} body - The Body to remove from the World.
+ * @return {Phaser.Physics.P2.Body} The Body that was removed.
*/
removeBody: function (body) {
@@ -525,9 +520,9 @@ Phaser.Physics.World.prototype = {
/**
* Adds a Spring to the world.
*
- * @method Phaser.Physics.World#addSpring
- * @param {Phaser.Physics.Spring} spring - The Spring to add to the World.
- * @return {Phaser.Physics.Spring} The Spring that was added.
+ * @method Phaser.Physics.P2#addSpring
+ * @param {Phaser.Physics.P2.Spring} spring - The Spring to add to the World.
+ * @return {Phaser.Physics.P2.Spring} The Spring that was added.
*/
addSpring: function (spring) {
@@ -542,9 +537,9 @@ Phaser.Physics.World.prototype = {
/**
* Removes a Spring from the world.
*
- * @method Phaser.Physics.World#removeSpring
- * @param {Phaser.Physics.Spring} spring - The Spring to remove from the World.
- * @return {Phaser.Physics.Spring} The Spring that was removed.
+ * @method Phaser.Physics.P2#removeSpring
+ * @param {Phaser.Physics.P2.Spring} spring - The Spring to remove from the World.
+ * @return {Phaser.Physics.P2.Spring} The Spring that was removed.
*/
removeSpring: function (spring) {
@@ -559,9 +554,9 @@ Phaser.Physics.World.prototype = {
/**
* Adds a Constraint to the world.
*
- * @method Phaser.Physics.World#addConstraint
- * @param {Phaser.Physics.Constraint} constraint - The Constraint to add to the World.
- * @return {Phaser.Physics.Constraint} The Constraint that was added.
+ * @method Phaser.Physics.P2#addConstraint
+ * @param {Phaser.Physics.P2.Constraint} constraint - The Constraint to add to the World.
+ * @return {Phaser.Physics.P2.Constraint} The Constraint that was added.
*/
addConstraint: function (constraint) {
@@ -576,9 +571,9 @@ Phaser.Physics.World.prototype = {
/**
* Removes a Constraint from the world.
*
- * @method Phaser.Physics.World#removeConstraint
- * @param {Phaser.Physics.Constraint} constraint - The Constraint to be removed from the World.
- * @return {Phaser.Physics.Constraint} The Constraint that was removed.
+ * @method Phaser.Physics.P2#removeConstraint
+ * @param {Phaser.Physics.P2.Constraint} constraint - The Constraint to be removed from the World.
+ * @return {Phaser.Physics.P2.Constraint} The Constraint that was removed.
*/
removeConstraint: function (constraint) {
@@ -593,9 +588,9 @@ Phaser.Physics.World.prototype = {
/**
* Adds a Contact Material to the world.
*
- * @method Phaser.Physics.World#addContactMaterial
- * @param {Phaser.Physics.ContactMaterial} material - The Contact Material to be added to the World.
- * @return {Phaser.Physics.ContactMaterial} The Contact Material that was added.
+ * @method Phaser.Physics.P2#addContactMaterial
+ * @param {Phaser.Physics.P2.ContactMaterial} material - The Contact Material to be added to the World.
+ * @return {Phaser.Physics.P2.ContactMaterial} The Contact Material that was added.
*/
addContactMaterial: function (material) {
@@ -610,9 +605,9 @@ Phaser.Physics.World.prototype = {
/**
* Removes a Contact Material from the world.
*
- * @method Phaser.Physics.World#removeContactMaterial
- * @param {Phaser.Physics.ContactMaterial} material - The Contact Material to be removed from the World.
- * @return {Phaser.Physics.ContactMaterial} The Contact Material that was removed.
+ * @method Phaser.Physics.P2#removeContactMaterial
+ * @param {Phaser.Physics.P2.ContactMaterial} material - The Contact Material to be removed from the World.
+ * @return {Phaser.Physics.P2.ContactMaterial} The Contact Material that was removed.
*/
removeContactMaterial: function (material) {
@@ -627,10 +622,10 @@ Phaser.Physics.World.prototype = {
/**
* Gets a Contact Material based on the two given Materials.
*
- * @method Phaser.Physics.World#getContactMaterial
- * @param {Phaser.Physics.Material} materialA - The first Material to search for.
- * @param {Phaser.Physics.Material} materialB - The second Material to search for.
- * @return {Phaser.Physics.ContactMaterial|boolean} The Contact Material or false if none was found matching the Materials given.
+ * @method Phaser.Physics.P2#getContactMaterial
+ * @param {Phaser.Physics.P2.Material} materialA - The first Material to search for.
+ * @param {Phaser.Physics.P2.Material} materialB - The second Material to search for.
+ * @return {Phaser.Physics.P2.ContactMaterial|boolean} The Contact Material or false if none was found matching the Materials given.
*/
getContactMaterial: function (materialA, materialB) {
@@ -641,9 +636,9 @@ Phaser.Physics.World.prototype = {
/**
* Sets the given Material against all Shapes owned by all the Bodies in the given array.
*
- * @method Phaser.Physics.World#setMaterial
- * @param {Phaser.Physics.Material} material - The Material to be applied to the given Bodies.
- * @param {array} bodies - An Array of Body objects that the given Material will be set on.
+ * @method Phaser.Physics.P2#setMaterial
+ * @param {Phaser.Physics.P2.Material} material - The Material to be applied to the given Bodies.
+ * @param {array} bodies - An Array of Body objects that the given Material will be set on.
*/
setMaterial: function (material, bodies) {
@@ -661,16 +656,16 @@ Phaser.Physics.World.prototype = {
* Materials are a way to control what happens when Shapes collide. Combine unique Materials together to create Contact Materials.
* Contact Materials have properties such as friction and restitution that allow for fine-grained collision control between different Materials.
*
- * @method Phaser.Physics.World#createMaterial
+ * @method Phaser.Physics.P2#createMaterial
* @param {string} [name] - Optional name of the Material. Each Material has a unique ID but string names are handy for debugging.
- * @param {Phaser.Physics.Body} [body] - Optional Body. If given it will assign the newly created Material to the Body shapes.
- * @return {Phaser.Physics.Material} The Material that was created. This is also stored in Phaser.Physics.World.materials.
+ * @param {Phaser.Physics.P2.Body} [body] - Optional Body. If given it will assign the newly created Material to the Body shapes.
+ * @return {Phaser.Physics.P2.Material} The Material that was created. This is also stored in Phaser.Physics.P2.materials.
*/
createMaterial: function (name, body) {
name = name || '';
- var material = new Phaser.Physics.Material(name);
+ var material = new Phaser.Physics.P2.Material(name);
this.materials.push(material);
@@ -686,18 +681,18 @@ Phaser.Physics.World.prototype = {
/**
* Creates a Contact Material from the two given Materials. You can then edit the properties of the Contact Material directly.
*
- * @method Phaser.Physics.World#createContactMaterial
- * @param {Phaser.Physics.Material} [materialA] - The first Material to create the ContactMaterial from. If undefined it will create a new Material object first.
- * @param {Phaser.Physics.Material} [materialB] - The second Material to create the ContactMaterial from. If undefined it will create a new Material object first.
+ * @method Phaser.Physics.P2#createContactMaterial
+ * @param {Phaser.Physics.P2.Material} [materialA] - The first Material to create the ContactMaterial from. If undefined it will create a new Material object first.
+ * @param {Phaser.Physics.P2.Material} [materialB] - The second Material to create the ContactMaterial from. If undefined it will create a new Material object first.
* @param {object} [options] - Material options object.
- * @return {Phaser.Physics.ContactMaterial} The Contact Material that was created.
+ * @return {Phaser.Physics.P2.ContactMaterial} The Contact Material that was created.
*/
createContactMaterial: function (materialA, materialB, options) {
if (typeof materialA === 'undefined') { materialA = this.createMaterial(); }
if (typeof materialB === 'undefined') { materialB = this.createMaterial(); }
- var contact = new Phaser.Physics.ContactMaterial(materialA, materialB, options);
+ var contact = new Phaser.Physics.P2.ContactMaterial(materialA, materialB, options);
return this.addContactMaterial(contact);
@@ -706,8 +701,8 @@ Phaser.Physics.World.prototype = {
/**
* Populates and returns an array of all current Bodies in the world.
*
- * @method Phaser.Physics.World#getBodies
- * @return {array} An array containing all current Bodies in the world.
+ * @method Phaser.Physics.P2#getBodies
+ * @return {array} An array containing all current Bodies in the world.
*/
getBodies: function () {
@@ -726,8 +721,8 @@ Phaser.Physics.World.prototype = {
/**
* Populates and returns an array of all current Springs in the world.
*
- * @method Phaser.Physics.World#getSprings
- * @return {array} An array containing all current Springs in the world.
+ * @method Phaser.Physics.P2#getSprings
+ * @return {array} An array containing all current Springs in the world.
*/
getSprings: function () {
@@ -746,8 +741,8 @@ Phaser.Physics.World.prototype = {
/**
* Populates and returns an array of all current Constraints in the world.
*
- * @method Phaser.Physics.World#getConstraints
- * @return {array} An array containing all current Constraints in the world.
+ * @method Phaser.Physics.P2#getConstraints
+ * @return {array} An array containing all current Constraints in the world.
*/
getConstraints: function () {
@@ -766,7 +761,7 @@ Phaser.Physics.World.prototype = {
/**
* Test if a world point overlaps bodies.
*
- * @method Phaser.Physics.World#hitTest
+ * @method Phaser.Physics.P2#hitTest
* @param {Phaser.Point} worldPoint - Point to use for intersection tests.
* @param {Array} bodies - A list of objects to check for intersection.
* @param {number} precision - Used for matching against particles and lines. Adds some margin to these infinitesimal objects.
@@ -779,7 +774,7 @@ Phaser.Physics.World.prototype = {
/**
* Converts the current world into a JSON object.
*
- * @method Phaser.Physics.World#toJSON
+ * @method Phaser.Physics.P2#toJSON
* @return {object} A JSON representation of the world.
*/
toJSON: function () {
@@ -814,7 +809,7 @@ Phaser.Physics.World.prototype = {
this._collisionGroupID++;
- var group = new Phaser.Physics.CollisionGroup(bitmask);
+ var group = new Phaser.Physics.P2.CollisionGroup(bitmask);
this.collisionGroups.push(group);
@@ -823,7 +818,7 @@ Phaser.Physics.World.prototype = {
},
/**
- * @method Phaser.Physics.World.prototype.createBody
+ * @method Phaser.Physics.P2.prototype.createBody
* @param {number} x - The x coordinate of Body.
* @param {number} y - The y coordinate of Body.
* @param {number} mass - The mass of the Body. A mass of 0 means a 'static' Body is created.
@@ -840,7 +835,7 @@ Phaser.Physics.World.prototype = {
if (typeof addToWorld === 'undefined') { addToWorld = false; }
- var body = new Phaser.Physics.Body(this.game, null, x, y, mass);
+ var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass);
if (data)
{
@@ -862,7 +857,7 @@ Phaser.Physics.World.prototype = {
},
/**
- * @method Phaser.Physics.World.prototype.createBody
+ * @method Phaser.Physics.P2.prototype.createBody
* @param {number} x - The x coordinate of Body.
* @param {number} y - The y coordinate of Body.
* @param {number} mass - The mass of the Body. A mass of 0 means a 'static' Body is created.
@@ -879,7 +874,7 @@ Phaser.Physics.World.prototype = {
if (typeof addToWorld === 'undefined') { addToWorld = false; }
- var body = new Phaser.Physics.Body(this.game, null, x, y, mass);
+ var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass);
if (data)
{
@@ -905,10 +900,10 @@ Phaser.Physics.World.prototype = {
};
/**
-* @name Phaser.Physics.World#friction
+* @name Phaser.Physics.P2#friction
* @property {number} friction - Friction between colliding bodies. This value is used if no matching ContactMaterial is found for a Material pair.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "friction", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "friction", {
get: function () {
@@ -925,10 +920,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "friction", {
});
/**
-* @name Phaser.Physics.World#restituion
+* @name Phaser.Physics.P2#restituion
* @property {number} restitution - Default coefficient of restitution between colliding bodies. This value is used if no matching ContactMaterial is found for a Material pair.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "restituion", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "restituion", {
get: function () {
@@ -945,10 +940,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "restituion", {
});
/**
-* @name Phaser.Physics.World#applySpringForces
+* @name Phaser.Physics.P2#applySpringForces
* @property {boolean} applySpringForces - Enable to automatically apply spring forces each step.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "applySpringForces", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "applySpringForces", {
get: function () {
@@ -965,10 +960,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "applySpringForces", {
});
/**
-* @name Phaser.Physics.World#applyDamping
+* @name Phaser.Physics.P2#applyDamping
* @property {boolean} applyDamping - Enable to automatically apply body damping each step.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "applyDamping", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "applyDamping", {
get: function () {
@@ -985,10 +980,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "applyDamping", {
});
/**
-* @name Phaser.Physics.World#applyGravity
+* @name Phaser.Physics.P2#applyGravity
* @property {boolean} applyGravity - Enable to automatically apply gravity each step.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "applyGravity", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "applyGravity", {
get: function () {
@@ -1005,10 +1000,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "applyGravity", {
});
/**
-* @name Phaser.Physics.World#solveConstraints
+* @name Phaser.Physics.P2#solveConstraints
* @property {boolean} solveConstraints - Enable/disable constraint solving in each step.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "solveConstraints", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "solveConstraints", {
get: function () {
@@ -1025,11 +1020,11 @@ Object.defineProperty(Phaser.Physics.World.prototype, "solveConstraints", {
});
/**
-* @name Phaser.Physics.World#time
+* @name Phaser.Physics.P2#time
* @property {boolean} time - The World time.
* @readonly
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "time", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "time", {
get: function () {
@@ -1040,10 +1035,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "time", {
});
/**
-* @name Phaser.Physics.World#emitImpactEvent
+* @name Phaser.Physics.P2#emitImpactEvent
* @property {boolean} emitImpactEvent - Set to true if you want to the world to emit the "impact" event. Turning this off could improve performance.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "emitImpactEvent", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "emitImpactEvent", {
get: function () {
@@ -1060,10 +1055,10 @@ Object.defineProperty(Phaser.Physics.World.prototype, "emitImpactEvent", {
});
/**
-* @name Phaser.Physics.World#enableBodySleeping
+* @name Phaser.Physics.P2#enableBodySleeping
* @property {boolean} enableBodySleeping - Enable / disable automatic body sleeping.
*/
-Object.defineProperty(Phaser.Physics.World.prototype, "enableBodySleeping", {
+Object.defineProperty(Phaser.Physics.P2.prototype, "enableBodySleeping", {
get: function () {
diff --git a/src/utils/Debug.js b/src/utils/Debug.js
index 949d2381..d1971365 100644
--- a/src/utils/Debug.js
+++ b/src/utils/Debug.js
@@ -117,7 +117,7 @@ Phaser.Utils.Debug.prototype = {
this.context = this.canvas.getContext('2d');
this.baseTexture = new PIXI.BaseTexture(this.canvas);
this.texture = new PIXI.Texture(this.baseTexture);
- this.textureFrame = new Phaser.Frame(0, 0, 0, this.game.width, this.game.height, 'debug', game.rnd.uuid());
+ this.textureFrame = new Phaser.Frame(0, 0, 0, this.game.width, this.game.height, 'debug', this.game.rnd.uuid());
this.sprite = this.game.make.image(0, 0, this.texture, this.textureFrame);
this.game.stage.addChild(this.sprite);
}