diff --git a/build/custom/ninja.js b/build/custom/ninja.js new file mode 100644 index 000000000..c30556265 --- /dev/null +++ b/build/custom/ninja.js @@ -0,0 +1,5370 @@ +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Ninja Physics constructor. +* +* The Ninja Physics system was created in Flash by Metanet Software and ported to JavaScript by Richard Davey. +* +* @class Phaser.Physics.Ninja +* @classdesc Ninja Physics Constructor +* @constructor +* @param {Phaser.Game} game reference to the current game instance. +*/ +Phaser.Physics.Ninja = function (game) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + this.time = this.game.time; + + /** + * @property {number} gravity - The World gravity setting. + */ + this.gravity = 0.2; + + /** + * @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 {Phaser.QuadTree} quadTree - The world QuadTree. + */ + // this.quadTree = new Phaser.Physics.Ninja.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 {Array} _mapData - Internal cache var. + * @private + */ + this._mapData = []; + +}; + +Phaser.Physics.Ninja.prototype.constructor = Phaser.Physics.Ninja; + +Phaser.Physics.Ninja.prototype = { + + /** + * This will create a Ninja Physics AABB body on the given game object. Its dimensions will match the width and height of the object at the point it is created. + * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. + * + * @method Phaser.Physics.Ninja#enableAABB + * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. + */ + enableAABB: function (object) { + + this.enable(object, 1); + + }, + + /** + * This will create a Ninja Physics Circle body on the given game object. + * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. + * + * @method Phaser.Physics.Ninja#enableCircle + * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. + * @param {number} radius - The radius of the Circle. + */ + enableCircle: function (object, radius) { + + this.enable(object, 2, 0, radius); + + }, + + /** + * This will create a Ninja Physics Tile body on the given game object. There are 34 different types of tile you can create, including 45 degree slopes, + * convex and concave circles and more. The id parameter controls which Tile type is created, but you can also change it at run-time. + * Note that for all degree based tile types they need to have an equal width and height. If the given object doesn't have equal width and height it will use the width. + * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. + * + * @method Phaser.Physics.Ninja#enableTile + * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. + * @param {number} [id=1] - The type of Tile this will use, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. + */ + enableTile: function (object, id) { + + this.enable(object, 3, id); + + }, + + /** + * This will create a Ninja Physics Tile body on the given game object. There are 34 different types of tile you can create, including 45 degree slopes, + * convex and concave circles and more. The id parameter controls which Tile type is created, but you can also change it at run-time. + * Note that for all degree based tile types they need to have an equal width and height. If the given object doesn't have equal width and height it will use the width. + * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. + * + * @method Phaser.Physics.Ninja#enable + * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. + * @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile. + * @param {number} [id=1] - If this body is using a Tile shape, you can set the Tile id here, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. + * @param {number} [radius=0] - If this body is using a Circle shape this controls the radius. + */ + enable: function (object, type, id, radius) { + + if (typeof type === 'undefined') { type = 1; } + if (typeof id === 'undefined') { id = 1; } + + var i = 1; + + if (Array.isArray(object)) + { + // Add to Group + i = object.length; + } + else + { + object = [object]; + } + + while (i--) + { + if (object[i].body === null) + { + object[i].body = new Phaser.Physics.Ninja.Body(this, object[i], type, id, radius); + object[i].anchor.set(0.5); + } + } + + }, + + /** + * Updates the size of this physics world. + * + * @method Phaser.Physics.Ninja#setBounds + * @param {number} x - Top left most corner of the world. + * @param {number} y - Top left most corner of the world. + * @param {number} width - New width of the world. Can never be smaller than the Game.width. + * @param {number} height - New height of the world. Can never be smaller than the Game.height. + */ + setBounds: function (x, y, width, height) { + + this.bounds.setTo(x, y, width, height); + + }, + + /** + * Updates the size of this physics world to match the size of the game world. + * + * @method Phaser.Physics.Ninja#setBoundsToWorld + */ + setBoundsToWorld: function () { + + this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height); + + }, + + /** + * Called automatically by a Physics body, it updates all motion related values on the Body. + * + * @method Phaser.Physics.Ninja#updateMotion + * @param {Phaser.Physics.Ninja.Body} The Body object to be updated. + update: function () { + }, + */ + + /** + * 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. + * The second parameter can be an array of objects, of differing types. + * + * @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|array} object2 - The second object or array of objects to check. Can be 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; + + if (Array.isArray(object2)) + { + for (var i = 0, len = object2.length; i < len; i++) + { + this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true); + } + } + else + { + this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true); + } + + return (this._total > 0); + + }, + + /** + * Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions. + * The second parameter can be an array of objects, of differing types. + * The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead. + * An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place, + * giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped. + * The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called. + * + * @method Phaser.Physics.Ninja#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|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. + * @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. 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 collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. + * @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; + + if (Array.isArray(object2)) + { + for (var i = 0, len = object2.length; i < len; i++) + { + this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false); + } + } + else + { + this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false); + } + + return (this._total > 0); + + }, + + /** + * Internal collision handler. + * + * @method Phaser.Physics.Arcade#collideHandler + * @private + * @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. Can also be an array of objects to check. + * @param {function} collideCallback - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them. + * @param {function} processCallback - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. + * @param {object} callbackContext - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Just run an overlap or a full collision. + */ + collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) { + + // Only collide valid objects + if (typeof object2 === 'undefined' && (object1.type === Phaser.GROUP || object1.type === Phaser.EMITTER)) + { + this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, overlapOnly); + return; + } + + 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, overlapOnly); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + 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, overlapOnly); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + 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, overlapOnly); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.TILEMAPLAYER) + { + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); + } + } + } + + }, + + /** + * An internal function. Use Phaser.Physics.Arcade.collide instead. + * + * @method Phaser.Physics.Arcade#collideSpriteVsSprite + * @private + */ + collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) { + + if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, sprite1, sprite2); + } + + this._total++; + } + + }, + + /** + * An internal function. Use Phaser.Physics.Arcade.collide instead. + * + * @method Phaser.Physics.Arcade#collideSpriteVsGroup + * @private + */ + collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) { + + if (group.length === 0) + { + return; + } + + // What is the sprite colliding with in the quadtree? + // this.quadTree.clear(); + + // this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); + + // this.quadTree.populate(group); + + // this._potentials = this.quadTree.retrieve(sprite); + + for (var i = 0, len = group.children.length; i < len; i++) + { + // We have our potential suspects, are they in this group? + if (group.children[i].exists && group.children[i].body && this.separate(sprite.body, group.children[i].body, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, group.children[i]); + } + + this._total++; + } + } + + }, + + /** + * An internal function. Use Phaser.Physics.Arcade.collide instead. + * + * @method Phaser.Physics.Arcade#collideGroupVsSelf + * @private + */ + collideGroupVsSelf: function (group, collideCallback, processCallback, callbackContext, overlapOnly) { + + if (group.length === 0) + { + return; + } + + var len = group.children.length; + + for (var i = 0; i < len; i++) + { + for (var j = i + 1; j <= len; j++) + { + if (group.children[i] && group.children[j] && group.children[i].exists && group.children[j].exists) + { + this.collideSpriteVsSprite(group.children[i], group.children[j], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + + }, + + /** + * An internal function. Use Phaser.Physics.Arcade.collide instead. + * + * @method Phaser.Physics.Arcade#collideGroupVsGroup + * @private + */ + collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) { + + if (group1.length === 0 || group2.length === 0) + { + return; + } + + for (var i = 0, len = group1.children.length; i < len; i++) + { + if (group1.children[i].exists) + { + this.collideSpriteVsGroup(group1.children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + + }, + + /** + * 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. + * @param {function} [processCallback=null] - UN-USED: A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true. + * @param {object} [callbackContext] - UN-USED: The context in which to run the process callback. + * @returns {boolean} Returns true if the bodies collided, otherwise false. + */ + separate: function (body1, body2, processCallback, callbackContext, overlapOnly) { + + if (body1.type !== Phaser.Physics.NINJA || body2.type !== Phaser.Physics.NINJA) + { + return false; + } + + if (body1.aabb && body2.aabb) + { + return body1.aabb.collideAABBVsAABB(body2.aabb); + } + + if (body1.aabb && body2.tile) + { + return body1.aabb.collideAABBVsTile(body2.tile); + } + + if (body1.tile && body2.aabb) + { + return body2.aabb.collideAABBVsTile(body1.tile); + } + + if (body1.circle && body2.tile) + { + return body1.circle.collideCircleVsTile(body2.tile); + } + + if (body1.tile && body2.circle) + { + return body2.circle.collideCircleVsTile(body1.tile); + } + + } + +}; + +/** +* @author Richard Davey +* @copyright 2014 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, bounce values etc all on the Body. +* +* @class Phaser.Physics.Ninja.Body +* @classdesc Ninja Physics Body Constructor +* @constructor +* @param {Phaser.Physics.Ninja} system - The physics system this Body belongs to. +* @param {Phaser.Sprite} sprite - The Sprite object this physics body belongs to. +* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile. +* @param {number} [id=1] - If this body is using a Tile shape, you can set the Tile id here, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. +* @param {number} [radius=16] - If this body is using a Circle shape this controls the radius. +*/ +Phaser.Physics.Ninja.Body = function (system, sprite, type, id, radius) { + + if (typeof type === 'undefined') { type = 1; } + if (typeof id === 'undefined') { id = 1; } + if (typeof radius === 'undefined') { radius = 16; } + + /** + * @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 {number} type - The type of physics system this body belongs to. + */ + this.type = Phaser.Physics.NINJA; + + /** + * @property {Phaser.Physics.Ninja} system - The parent physics system. + */ + this.system = system; + + /** + * @property {Phaser.Physics.Ninja.AABB} aabb - The AABB object this body is using for collision. + */ + this.aabb = null; + + /** + * @property {Phaser.Physics.Ninja.Tile} tile - The Tile object this body is using for collision. + */ + this.tile = null; + + /** + * @property {Phaser.Physics.Ninja.Circle} circle - The Circle object this body is using for collision. + */ + this.circle = null; + + /** + * @property {object} shape - A local reference to the body shape. + */ + this.shape = null; + + // Setting drag to 0 and friction to 0 means you get a normalised speed (px psec) + + /** + * @property {number} drag - The drag applied to this object as it moves. + * @default + */ + this.drag = 1; + + /** + * @property {number} friction - The friction applied to this object as it moves. + * @default + */ + this.friction = 0.05; + + /** + * @property {number} gravityScale - How much of the world gravity should be applied to this object? 1 = all of it, 0.5 = 50%, etc. + * @default + */ + this.gravityScale = 1; + + /** + * @property {number} bounce - The bounciness of this object when it collides. A value between 0 and 1. We recommend setting it to 0.999 to avoid jittering. + * @default + */ + this.bounce = 0.3; + + /** + * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body. + */ + this.velocity = new Phaser.Point(); + + /** + * @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; + + /** + * @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; + + /** + * 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 = 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.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.wasTouching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * @property {number} maxSpeed - The maximum speed this body can travel at (taking drag and friction into account) + * @default + */ + this.maxSpeed = 8; + + var sx = sprite.x; + var sy = sprite.y; + + if (sprite.anchor.x === 0) + { + sx += (sprite.width * 0.5); + } + + if (sprite.anchor.y === 0) + { + sy += (sprite.height * 0.5); + } + + if (type === 1) + { + this.aabb = new Phaser.Physics.Ninja.AABB(this, sx, sy, sprite.width, sprite.height); + this.shape = this.aabb; + } + else if (type === 2) + { + this.circle = new Phaser.Physics.Ninja.Circle(this, sx, sy, radius); + this.shape = this.circle; + } + else if (type === 3) + { + this.tile = new Phaser.Physics.Ninja.Tile(this, sx, sy, sprite.width, sprite.height, id); + this.shape = this.tile; + } + +}; + +Phaser.Physics.Ninja.Body.prototype = { + + /** + * Internal method. + * + * @method Phaser.Physics.Ninja.Body#updateBounds + * @protected + */ + updateBounds: function (centerX, centerY, scaleX, scaleY) { + }, + + /** + * Internal method. + * + * @method Phaser.Physics.Ninja.Body#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.shape.integrate(); + + if (this.collideWorldBounds) + { + this.shape.collideWorldBounds(); + } + + this.speed = Math.sqrt(this.shape.velocity.x * this.shape.velocity.x + this.shape.velocity.y * this.shape.velocity.y); + this.angle = Math.atan2(this.shape.velocity.y, this.shape.velocity.x); + + }, + + /** + * Internal method. + * + * @method Phaser.Physics.Ninja.Body#postUpdate + * @protected + */ + postUpdate: function () { + + if (this.sprite.type === Phaser.TILESPRITE) + { + // TileSprites don't use their anchor property, so we need to adjust the coordinates + this.sprite.x = this.shape.pos.x - this.shape.xw; + this.sprite.y = this.shape.pos.y - this.shape.yw; + } + else + { + this.sprite.x = this.shape.pos.x; + this.sprite.y = this.shape.pos.y; + } + + }, + + /** + * Stops all movement of this body. + * + * @method Phaser.Physics.Ninja.Body#setZeroVelocity + */ + setZeroVelocity: function () { + + this.shape.oldpos.x = this.shape.pos.x; + this.shape.oldpos.y = this.shape.pos.y; + + }, + + /** + * Moves the Body forwards based on its current angle and the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveTo + * @param {number} speed - The speed at which it should move forwards. + * @param {number} angle - The angle in which it should move, given in degrees. + */ + moveTo: function (speed, angle) { + + var magnitude = speed * this.game.time.physicsElapsed; + var angle = this.game.math.degToRad(angle); + + this.shape.pos.x = this.shape.oldpos.x + (magnitude * Math.cos(angle)); + this.shape.pos.y = this.shape.oldpos.y + (magnitude * Math.sin(angle)); + + }, + + /** + * Moves the Body backwards based on its current angle and the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveBackward + * @param {number} speed - The speed at which it should move backwards. + * @param {number} angle - The angle in which it should move, given in degrees. + */ + moveFrom: function (speed, angle) { + + var magnitude = -speed * this.game.time.physicsElapsed; + var angle = this.game.math.degToRad(angle); + + this.shape.pos.x = this.shape.oldpos.x + (magnitude * Math.cos(angle)); + this.shape.pos.y = this.shape.oldpos.y + (magnitude * Math.sin(angle)); + + }, + + /** + * If this Body is dynamic then this will move it to the left by setting its x velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveLeft + * @param {number} speed - The speed at which it should move to the left, in pixels per second. + */ + moveLeft: function (speed) { + + var fx = -speed * this.game.time.physicsElapsed; + + this.shape.pos.x = this.shape.oldpos.x + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.x - this.shape.oldpos.x + fx)); + + }, + + /** + * If this Body is dynamic then this will move it to the right by setting its x velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveRight + * @param {number} speed - The speed at which it should move to the right, in pixels per second. + */ + moveRight: function (speed) { + + var fx = speed * this.game.time.physicsElapsed; + + this.shape.pos.x = this.shape.oldpos.x + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.x - this.shape.oldpos.x + fx)); + + }, + + /** + * If this Body is dynamic then this will move it up by setting its y velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveUp + * @param {number} speed - The speed at which it should move up, in pixels per second. + */ + moveUp: function (speed) { + + var fx = -speed * this.game.time.physicsElapsed; + + this.shape.pos.y = this.shape.oldpos.y + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.y - this.shape.oldpos.y + fx)); + + }, + + /** + * If this Body is dynamic then this will move it down by setting its y velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveDown + * @param {number} speed - The speed at which it should move down, in pixels per second. + */ + moveDown: function (speed) { + + var fx = speed * this.game.time.physicsElapsed; + + this.shape.pos.y = this.shape.oldpos.y + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.y - this.shape.oldpos.y + fx)); + + }, + + /** + * Resets all Body values (velocity, acceleration, rotation, etc) + * + * @method Phaser.Physics.Ninja.Body#reset + */ + reset: function () { + }, + +}; + +/** +* @name Phaser.Physics.Ninja.Body#x +* @property {number} x - The x position. +*/ +Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "x", { + + /** + * The x position. + * @method x + * @return {number} + */ + get: function () { + return this.shape.pos.x; + }, + + /** + * The x position. + * @method x + * @param {number} value + */ + set: function (value) { + this.shape.pos.x = value; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Body#y +* @property {number} y - The y position. +*/ +Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "y", { + + /** + * The y position. + * @method y + * @return {number} + */ + get: function () { + return this.shape.pos.y; + }, + + /** + * The y position. + * @method y + * @param {number} value + */ + set: function (value) { + this.shape.pos.y = value; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Body#width +* @property {number} width - The width of this Body +* @readonly +*/ +Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "width", { + + /** + * The width of this Body + * @method width + * @return {number} + * @readonly + */ + get: function () { + return this.shape.width; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Body#height +* @property {number} height - The height of this Body +* @readonly +*/ +Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "height", { + + /** + * The height of this Body + * @method height + * @return {number} + * @readonly + */ + get: function () { + return this.shape.height; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Body#bottom +* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height) +* @readonly +*/ +Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "bottom", { + + /** + * The sum of the y and height properties. + * @method bottom + * @return {number} + * @readonly + */ + get: function () { + return this.shape.pos.y + this.shape.height; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Body#right +* @property {number} right - The right value of this Body (same as Body.x + Body.width) +* @readonly +*/ +Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "right", { + + /** + * The sum of the x and width properties. + * @method right + * @return {number} + * @readonly + */ + get: function () { + return this.shape.pos.x + this.shape.width; + } + +}); + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Ninja Physics AABB constructor. +* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. +* +* @class Phaser.Physics.Ninja.AABB +* @classdesc Arcade Physics Constructor +* @constructor +* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. +* @param {number} x - The x coordinate to create this shape at. +* @param {number} y - The y coordinate to create this shape at. +* @param {number} width - The width of this AABB. +* @param {number} height - The height of this AABB. +*/ +Phaser.Physics.Ninja.AABB = function (body, x, y, width, height) { + + /** + * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. + */ + this.body = body; + + /** + * @property {Phaser.Physics.Ninja} system - A reference to the physics system. + */ + this.system = body.system; + + /** + * @property {Phaser.Point} pos - The position of this object. + */ + this.pos = new Phaser.Point(x, y); + + /** + * @property {Phaser.Point} oldpos - The position of this object in the previous update. + */ + this.oldpos = new Phaser.Point(x, y); + + /** + * @property {number} xw - Half the width. + * @readonly + */ + this.xw = Math.abs(width / 2); + + /** + * @property {number} xw - Half the height. + * @readonly + */ + this.yw = Math.abs(height / 2); + + /** + * @property {number} width - The width. + * @readonly + */ + this.width = width; + + /** + * @property {number} height - The height. + * @readonly + */ + this.height = height; + + /** + * @property {number} oH - Internal var. + * @private + */ + this.oH = 0; + + /** + * @property {number} oV - Internal var. + * @private + */ + this.oV = 0; + + /** + * @property {Phaser.Point} velocity - The velocity of this object. + */ + this.velocity = new Phaser.Point(); + + /** + * @property {object} aabbTileProjections - All of the collision response handlers. + */ + this.aabbTileProjections = {}; + + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL] = this.projAABB_Full; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG] = this.projAABB_45Deg; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE] = this.projAABB_Concave; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX] = this.projAABB_Convex; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs] = this.projAABB_22DegS; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb] = this.projAABB_22DegB; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs] = this.projAABB_67DegS; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb] = this.projAABB_67DegB; + this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF] = this.projAABB_Half; + +}; + +Phaser.Physics.Ninja.AABB.prototype.constructor = Phaser.Physics.Ninja.AABB; + +Phaser.Physics.Ninja.AABB.COL_NONE = 0; +Phaser.Physics.Ninja.AABB.COL_AXIS = 1; +Phaser.Physics.Ninja.AABB.COL_OTHER = 2; + +Phaser.Physics.Ninja.AABB.prototype = { + + /** + * Updates this AABBs position. + * + * @method Phaser.Physics.Ninja.AABB#integrate + */ + integrate: function () { + + var px = this.pos.x; + var py = this.pos.y; + + // integrate + this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); + this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); + + // store + this.velocity.set(this.pos.x - px, this.pos.y - py); + this.oldpos.set(px, py); + + }, + + /** + * Process a world collision and apply the resulting forces. + * + * @method Phaser.Physics.Ninja.AABB#reportCollisionVsWorld + * @param {number} px - The tangent velocity + * @param {number} py - The tangent velocity + * @param {number} dx - Collision normal + * @param {number} dy - Collision normal + * @param {number} obj - Object this AABB collided with + */ + reportCollisionVsWorld: function (px, py, dx, dy, obj) { + + var p = this.pos; + var o = this.oldpos; + + // Calc velocity + var vx = p.x - o.x; + var vy = p.y - o.y; + + // Find component of velocity parallel to collision normal + var dp = (vx * dx + vy * dy); + var nx = dp * dx; //project velocity onto collision normal + + var ny = dp * dy; //nx,ny is normal velocity + + var tx = vx - nx; //px,py is tangent velocity + var ty = vy - ny; + + // We only want to apply collision response forces if the object is travelling into, and not out of, the collision + var b, bx, by, fx, fy; + + if (dp < 0) + { + fx = tx * this.body.friction; + fy = ty * this.body.friction; + + b = 1 + this.body.bounce; + + bx = (nx * b); + by = (ny * b); + + if (dx === 1) + { + this.body.touching.left = true; + } + else if (dx === -1) + { + this.body.touching.right = true; + } + + if (dy === 1) + { + this.body.touching.up = true; + } + else if (dy === -1) + { + this.body.touching.down = true; + } + } + else + { + // Moving out of collision, do not apply forces + bx = by = fx = fy = 0; + } + + // Project object out of collision + p.x += px; + p.y += py; + + // Apply bounce+friction impulses which alter velocity + o.x += px + bx + fx; + o.y += py + by + fy; + + }, + + /** + * Process a body collision and apply the resulting forces. + * + * @method Phaser.Physics.Ninja.AABB#reportCollisionVsBody + * @param {number} px - The tangent velocity + * @param {number} py - The tangent velocity + * @param {number} dx - Collision normal + * @param {number} dy - Collision normal + * @param {number} obj - Object this AABB collided with + */ + reportCollisionVsBody: function (px, py, dx, dy, obj) { + + // Here - we check if obj is immovable, etc and then we canswap the p/o values below depending on which is heavy + // But then still need to work out how to split force + + var p = this.pos; + var o = this.oldpos; + + // Calc velocity + var vx = p.x - o.x; + var vy = p.y - o.y; + + // Find component of velocity parallel to collision normal + var dp = (vx * dx + vy * dy); + var nx = dp * dx; //project velocity onto collision normal + + var ny = dp * dy; //nx,ny is normal velocity + + var tx = vx - nx; //px,py is tangent velocity + var ty = vy - ny; + + // We only want to apply collision response forces if the object is travelling into, and not out of, the collision + var b, bx, by, fx, fy; + + if (dp < 0) + { + fx = tx * this.body.friction; + fy = ty * this.body.friction; + + b = 1 + this.body.bounce; + + bx = (nx * b); + by = (ny * b); + } + else + { + // Moving out of collision, do not apply forces + bx = by = fx = fy = 0; + } + + // working version + // p.x += px; + // p.y += py; + // o.x += px + bx + fx; + // o.y += py + by + fy; + + // Project object out of collision (applied to the position value) + p.x += px; + p.y += py; + + // obj.pos.x += px; + // obj.pos.y += py; + + + // Apply bounce+friction impulses which alter velocity (applied to old position, thus setting a sort of velocity up) + var rx = px + bx + fx; + var ry = py + by + fy; + + // let's pretend obj is immovable + // rx *= -1; + // ry *= -1; + + + // Now let's share the load + o.x += rx; + o.y += ry; + + // work out objs velocity + + + // rx *= -1; + // ry *= -1; + + // obj.oldpos.x += rx; + // obj.oldpos.y += ry; + + + // console.log(this.body.sprite.name, 'o.x', rx, ry, obj); + + }, + + /** + * Collides this AABB against the world bounds. + * + * @method Phaser.Physics.Ninja.AABB#collideWorldBounds + */ + collideWorldBounds: function () { + + var dx = this.system.bounds.x - (this.pos.x - this.xw); + + if (0 < dx) + { + this.reportCollisionVsWorld(dx, 0, 1, 0, null); + } + else + { + dx = (this.pos.x + this.xw) - this.system.bounds.width; + + if (0 < dx) + { + this.reportCollisionVsWorld(-dx, 0, -1, 0, null); + } + } + + var dy = this.system.bounds.y - (this.pos.y - this.yw); + + if (0 < dy) + { + this.reportCollisionVsWorld(0, dy, 0, 1, null); + } + else + { + dy = (this.pos.y + this.yw) - this.system.bounds.height; + + if (0 < dy) + { + this.reportCollisionVsWorld(0, -dy, 0, -1, null); + } + } + + }, + + /** + * Collides this AABB against a AABB. + * + * @method Phaser.Physics.Ninja.AABB#collideAABBVsAABB + * @param {Phaser.Physics.Ninja.AABB} aabb - The AABB to collide against. + */ + collideAABBVsAABB: function (aabb) { + + var pos = this.pos; + var c = aabb; + + var tx = c.pos.x; + var ty = c.pos.y; + var txw = c.xw; + var tyw = c.yw; + + var dx = pos.x - tx;//tile->obj delta + var px = (txw + this.xw) - Math.abs(dx);//penetration depth in x + + if (0 < px) + { + var dy = pos.y - ty;//tile->obj delta + var py = (tyw + this.yw) - Math.abs(dy);//pen depth in y + + if (0 < py) + { + //object may be colliding with tile; call tile-specific collision function + + //calculate projection vectors + if (px < py) + { + //project in x + if (dx < 0) + { + //project to the left + px *= -1; + py = 0; + } + else + { + //proj to right + py = 0; + } + } + else + { + //project in y + if (dy < 0) + { + //project up + px = 0; + py *= -1; + } + else + { + //project down + px = 0; + } + } + + // return this.aabbTileProjections[1](px, py, this, c); + + var l = Math.sqrt(px * px + py * py); + // this.reportCollisionVsWorld(px, py, px / l, py / l, c); + this.reportCollisionVsBody(px, py, px / l, py / l, c); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + + } + } + + return false; + + }, + + /** + * Collides this AABB against a Tile. + * + * @method Phaser.Physics.Ninja.AABB#collideAABBVsTile + * @param {Phaser.Physics.Ninja.Tile} tile - The Tile to collide against. + */ + collideAABBVsTile: function (tile) { + + var pos = this.pos; + var c = tile; + + var tx = c.pos.x; + var ty = c.pos.y; + var txw = c.xw; + var tyw = c.yw; + + var dx = pos.x - tx;//tile->obj delta + var px = (txw + this.xw) - Math.abs(dx);//penetration depth in x + + if (0 < px) + { + var dy = pos.y - ty;//tile->obj delta + var py = (tyw + this.yw) - Math.abs(dy);//pen depth in y + + if (0 < py) + { + //object may be colliding with tile; call tile-specific collision function + + //calculate projection vectors + if (px < py) + { + //project in x + if (dx < 0) + { + //project to the left + px *= -1; + py = 0; + } + else + { + //proj to right + py = 0; + } + } + else + { + //project in y + if (dy < 0) + { + //project up + px = 0; + py *= -1; + } + else + { + //project down + px = 0; + } + } + + return this.resolveTile(px, py, this, c); + } + } + + return false; + + }, + + /** + * Resolves tile collision. + * + * @method Phaser.Physics.Ninja.AABB#resolveTile + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} body - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} tile - The Tile involved in the collision. + * @return {boolean} True if the collision was processed, otherwise false. + */ + resolveTile: function (x, y, body, tile) { + + if (0 < tile.id) + { + return this.aabbTileProjections[tile.type](x, y, body, tile); + } + else + { + // console.warn("Ninja.AABB.resolveTile was called with an empty (or unknown) tile!: id=" + tile.id + ")"); + return false; + } + + }, + + /** + * Resolves Full tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_Full + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_Full: function (x, y, obj, t) { + + var l = Math.sqrt(x * x + y * y); + obj.reportCollisionVsWorld(x, y, x / l, y / l, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + + }, + + /** + * Resolves Half tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_Half + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_Half: function (x, y, obj, t) { + + //signx or signy must be 0; the other must be -1 or 1 + //calculate the projection vector for the half-edge, and then + //(if collision is occuring) pick the minimum + + var sx = t.signx; + var sy = t.signy; + + var ox = (obj.pos.x - (sx*obj.xw)) - t.pos.x;//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (sy*obj.yw)) - t.pos.y;//point on the AABB, relative to the tile center + + //we perform operations analogous to the 45deg tile, except we're using + //an axis-aligned slope instead of an angled one.. + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + if (lenP < lenN) + { + //project along axis; note that we're assuming that this tile is horizontal OR vertical + //relative to the AABB's current tile, and not diagonal OR the current tile. + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + else + { + //note that we could use -= instead of -dp + obj.reportCollisionVsWorld(sx,sy,t.signx, t.signy, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + } + + return Phaser.Physics.Ninja.AABB.COL_NONE; + + }, + + /** + * Resolves 45 Degree tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_45Deg + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_45Deg: function (x, y, obj, t) { + + var signx = t.signx; + var signy = t.signy; + + var ox = (obj.pos.x - (signx*obj.xw)) - t.pos.x;//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (signy*obj.yw)) - t.pos.y;//point on the AABB, relative to the tile center + + var sx = t.sx; + var sy = t.sy; + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + if (lenP < lenN) + { + //project along axis + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + else + { + //project along slope + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + } + + return Phaser.Physics.Ninja.AABB.COL_NONE; + }, + + /** + * Resolves 22 Degree tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_22DegS + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_22DegS: function (x, y, obj, t) { + + var signx = t.signx; + var signy = t.signy; + + //first we need to check to make sure we're colliding with the slope at all + var py = obj.pos.y - (signy*obj.yw); + var penY = t.pos.y - py;//this is the vector from the innermost point on the box to the highest point on + //the tile; if it is positive, this means the box is above the tile and + //no collision is occuring + if (0 < (penY*signy)) + { + var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope + + var sx = t.sx;//get slope unit normal + var sy = t.sy; + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + var aY = Math.abs(penY); + + if (lenP < lenN) + { + if (aY < lenP) + { + obj.reportCollisionVsWorld(0, penY, 0, penY/aY, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + else + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + } + else + { + if (aY < lenN) + { + obj.reportCollisionVsWorld(0, penY, 0, penY/aY, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + } + } + } + + //if we've reached this point, no collision has occured + return Phaser.Physics.Ninja.AABB.COL_NONE; + }, + + /** + * Resolves 22 Degree tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_22DegB + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_22DegB: function (x, y, obj, t) { + + var signx = t.signx; + var signy = t.signy; + + var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope + + var sx = t.sx;//get slope unit normal + var sy = t.sy; + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + if (lenP < lenN) + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + + } + + return Phaser.Physics.Ninja.AABB.COL_NONE; + + }, + + /** + * Resolves 67 Degree tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_67DegS + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_67DegS: function (x, y, obj, t) { + + var signx = t.signx; + var signy = t.signy; + + var px = obj.pos.x - (signx*obj.xw); + var penX = t.pos.x - px; + + if (0 < (penX*signx)) + { + var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope + + var sx = t.sx;//get slope unit normal + var sy = t.sy; + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need to project it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + var aX = Math.abs(penX); + + if (lenP < lenN) + { + if (aX < lenP) + { + obj.reportCollisionVsWorld(penX, 0, penX/aX, 0, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + else + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + } + else + { + if (aX < lenN) + { + obj.reportCollisionVsWorld(penX, 0, penX/aX, 0, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + } + } + } + + //if we've reached this point, no collision has occured + return Phaser.Physics.Ninja.AABB.COL_NONE; + + }, + + /** + * Resolves 67 Degree tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_67DegB + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_67DegB: function (x, y, obj, t) { + + var signx = t.signx; + var signy = t.signy; + + var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope + + var sx = t.sx;//get slope unit normal + var sy = t.sy; + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + if (lenP < lenN) + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + } + + return Phaser.Physics.Ninja.AABB.COL_NONE; + }, + + /** + * Resolves Convex tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_Convex + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_Convex: function (x, y, obj, t) { + + //if distance from "innermost" corner of AABB is less than than tile radius, + //collision is occuring and we need to project + + var signx = t.signx; + var signy = t.signy; + + var ox = (obj.pos.x - (signx * obj.xw)) - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the circle center to + var oy = (obj.pos.y - (signy * obj.yw)) - (t.pos.y - (signy * t.yw));//the AABB + var len = Math.sqrt(ox * ox + oy * oy); + + var twid = t.xw * 2; + var rad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var pen = rad - len; + + if (((signx * ox) < 0) || ((signy * oy) < 0)) + { + //the test corner is "outside" the 1/4 of the circle we're interested in + var lenP = Math.sqrt(x * x + y * y); + obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS;//we need to report + } + else if (0 < pen) + { + //project along corner->circle vector + ox /= len; + oy /= len; + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + + return Phaser.Physics.Ninja.AABB.COL_NONE; + + }, + + /** + * Resolves Concave tile collision. + * + * @method Phaser.Physics.Ninja.AABB#projAABB_Concave + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projAABB_Concave: function (x, y, obj, t) { + + //if distance from "innermost" corner of AABB is further than tile radius, + //collision is occuring and we need to project + + var signx = t.signx; + var signy = t.signy; + + var ox = (t.pos.x + (signx * t.xw)) - (obj.pos.x - (signx * obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the + var oy = (t.pos.y + (signy * t.yw)) - (obj.pos.y - (signy * obj.yw));//circle's center + + var twid = t.xw * 2; + var rad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var len = Math.sqrt(ox * ox + oy * oy); + var pen = len - rad; + + if (0 < pen) + { + //collision; we need to either project along the axes, or project along corner->circlecenter vector + + var lenP = Math.sqrt(x * x + y * y); + + if (lenP < pen) + { + //it's shorter to move along axis directions + obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); + + return Phaser.Physics.Ninja.AABB.COL_AXIS; + } + else + { + //project along corner->circle vector + ox /= len;//len should never be 0, since if it IS 0, rad should be > than len + oy /= len;//and we should never reach here + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.AABB.COL_OTHER; + } + + } + + return Phaser.Physics.Ninja.AABB.COL_NONE; + + } + +} + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Ninja Physics Tile constructor. +* A Tile is defined by its width, height and type. It's type can include slope data, such as 45 degree slopes, or convex slopes. +* Understand that for any type including a slope (types 2 to 29) the Tile must be SQUARE, i.e. have an equal width and height. +* Also note that as Tiles are primarily used for levels they have gravity disabled and world bounds collision disabled by default. +* +* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. +* +* @class Phaser.Physics.Ninja.Tile +* @classdesc The Ninja Physics Tile class. Based on code by Metanet Software. +* @constructor +* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. +* @param {number} x - The x coordinate to create this shape at. +* @param {number} y - The y coordinate to create this shape at. +* @param {number} width - The width of this AABB. +* @param {number} height - The height of this AABB. +* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile. +*/ +Phaser.Physics.Ninja.Tile = function (body, x, y, width, height, type) { + + if (typeof type === 'undefined') { type = Phaser.Physics.Ninja.Tile.EMPTY; } + + /** + * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. + */ + this.body = body; + + /** + * @property {Phaser.Physics.Ninja} system - A reference to the physics system. + */ + this.system = body.system; + + /** + * @property {number} id - The ID of this Tile. + * @readonly + */ + this.id = type; + + /** + * @property {number} type - The type of this Tile. + * @readonly + */ + this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY; + + /** + * @property {Phaser.Point} pos - The position of this object. + */ + this.pos = new Phaser.Point(x, y); + + /** + * @property {Phaser.Point} oldpos - The position of this object in the previous update. + */ + this.oldpos = new Phaser.Point(x, y); + + if (this.id > 1 && this.id < 30) + { + // Tile Types 2 to 29 require square tile dimensions, so use the width as the base + height = width; + } + + /** + * @property {number} xw - Half the width. + * @readonly + */ + this.xw = Math.abs(width / 2); + + /** + * @property {number} xw - Half the height. + * @readonly + */ + this.yw = Math.abs(height / 2); + + /** + * @property {number} width - The width. + * @readonly + */ + this.width = width; + + /** + * @property {number} height - The height. + * @readonly + */ + this.height = height; + + /** + * @property {Phaser.Point} velocity - The velocity of this object. + */ + this.velocity = new Phaser.Point(); + + /** + * @property {number} signx - Internal var. + * @private + */ + this.signx = 0; + + /** + * @property {number} signy - Internal var. + * @private + */ + this.signy = 0; + + /** + * @property {number} sx - Internal var. + * @private + */ + this.sx = 0; + + /** + * @property {number} sy - Internal var. + * @private + */ + this.sy = 0; + + // By default Tiles disable gravity and world bounds collision + this.body.gravityScale = 0; + this.body.collideWorldBounds = false; + + if (this.id > 0) + { + this.setType(this.id); + } + +}; + +Phaser.Physics.Ninja.Tile.prototype.constructor = Phaser.Physics.Ninja.Tile; + +Phaser.Physics.Ninja.Tile.prototype = { + + /** + * Updates this objects position. + * + * @method Phaser.Physics.Ninja.Tile#integrate + */ + integrate: function () { + + var px = this.pos.x; + var py = this.pos.y; + + this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); + this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); + + this.velocity.set(this.pos.x - px, this.pos.y - py); + this.oldpos.set(px, py); + + }, + + /** + * Tiles cannot collide with the world bounds, it's up to you to keep them where you want them. But we need this API stub to satisfy the Body. + * + * @method Phaser.Physics.Ninja.Tile#collideWorldBounds + */ + collideWorldBounds: function () { + + var dx = this.system.bounds.x - (this.pos.x - this.xw); + + if (0 < dx) + { + this.reportCollisionVsWorld(dx, 0, 1, 0, null); + } + else + { + dx = (this.pos.x + this.xw) - this.system.bounds.width; + + if (0 < dx) + { + this.reportCollisionVsWorld(-dx, 0, -1, 0, null); + } + } + + var dy = this.system.bounds.y - (this.pos.y - this.yw); + + if (0 < dy) + { + this.reportCollisionVsWorld(0, dy, 0, 1, null); + } + else + { + dy = (this.pos.y + this.yw) - this.system.bounds.height; + + if (0 < dy) + { + this.reportCollisionVsWorld(0, -dy, 0, -1, null); + } + } + + }, + + /** + * Process a world collision and apply the resulting forces. + * + * @method Phaser.Physics.Ninja.Tile#reportCollisionVsWorld + * @param {number} px - The tangent velocity + * @param {number} py - The tangent velocity + * @param {number} dx - Collision normal + * @param {number} dy - Collision normal + * @param {number} obj - Object this Tile collided with + */ + reportCollisionVsWorld: function (px, py, dx, dy, obj) { + + var p = this.pos; + var o = this.oldpos; + + // Calc velocity + var vx = p.x - o.x; + var vy = p.y - o.y; + + // Find component of velocity parallel to collision normal + var dp = (vx * dx + vy * dy); + var nx = dp * dx; //project velocity onto collision normal + + var ny = dp * dy; //nx,ny is normal velocity + + var tx = vx - nx; //px,py is tangent velocity + var ty = vy - ny; + + // We only want to apply collision response forces if the object is travelling into, and not out of, the collision + var b, bx, by, fx, fy; + + if (dp < 0) + { + fx = tx * this.body.friction; + fy = ty * this.body.friction; + + b = 1 + this.body.bounce; + + bx = (nx * b); + by = (ny * b); + + if (dx === 1) + { + this.body.touching.left = true; + } + else if (dx === -1) + { + this.body.touching.right = true; + } + + if (dy === 1) + { + this.body.touching.up = true; + } + else if (dy === -1) + { + this.body.touching.down = true; + } + } + else + { + // Moving out of collision, do not apply forces + bx = by = fx = fy = 0; + } + + // Project object out of collision + p.x += px; + p.y += py; + + // Apply bounce+friction impulses which alter velocity + o.x += px + bx + fx; + o.y += py + by + fy; + + }, + + /** + * Tiles cannot collide with the world bounds, it's up to you to keep them where you want them. But we need this API stub to satisfy the Body. + * + * @method Phaser.Physics.Ninja.Tile#setType + * @param {number} id - The type of Tile this will use, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. + */ + setType: function (id) { + + if (id === Phaser.Physics.Ninja.Tile.EMPTY) + { + this.clear(); + } + else + { + this.id = id; + this.updateType(); + } + + return this; + + }, + + /** + * Sets this tile to be empty. + * + * @method Phaser.Physics.Ninja.Tile#clear + */ + clear: function () { + + this.id = Phaser.Physics.Ninja.Tile.EMPTY; + this.updateType(); + + }, + + /** + * This converts a tile from implicitly-defined (via id), to explicit (via properties). + * Don't call directly, instead of setType. + * + * @method Phaser.Physics.Ninja.Tile#updateType + * @private + */ + updateType: function () { + + if (this.id === 0) + { + //EMPTY + this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY; + this.signx = 0; + this.signy = 0; + this.sx = 0; + this.sy = 0; + + return true; + } + + //tile is non-empty; collide + if (this.id < Phaser.Physics.Ninja.Tile.TYPE_45DEG) + { + //FULL + this.type = Phaser.Physics.Ninja.Tile.TYPE_FULL; + this.signx = 0; + this.signy = 0; + this.sx = 0; + this.sy = 0; + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONCAVE) + { + // 45deg + this.type = Phaser.Physics.Ninja.Tile.TYPE_45DEG; + + if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn) + { + this.signx = 1; + this.signy = -1; + this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal + this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn) + { + this.signx = -1; + this.signy = -1; + this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal + this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp) + { + this.signx = -1; + this.signy = 1; + this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal + this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp) + { + this.signx = 1; + this.signy = 1; + this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal + this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) + } + else + { + return false; + } + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONVEX) + { + // Concave + this.type = Phaser.Physics.Ninja.Tile.TYPE_CONCAVE; + + if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpn) + { + this.signx = 1; + this.signy = -1; + this.sx = 0; + this.sy = 0; + } + else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnn) + { + this.signx = -1; + this.signy = -1; + this.sx = 0; + this.sy = 0; + } + else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnp) + { + this.signx = -1; + this.signy = 1; + this.sx = 0; + this.sy = 0; + } + else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpp) + { + this.signx = 1; + this.signy = 1; + this.sx = 0; + this.sy = 0; + } + else + { + return false; + } + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGs) + { + // Convex + this.type = Phaser.Physics.Ninja.Tile.TYPE_CONVEX; + + if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpn) + { + this.signx = 1; + this.signy = -1; + this.sx = 0; + this.sy = 0; + } + else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnn) + { + this.signx = -1; + this.signy = -1; + this.sx = 0; + this.sy = 0; + } + else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnp) + { + this.signx = -1; + this.signy = 1; + this.sx = 0; + this.sy = 0; + } + else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpp) + { + this.signx = 1; + this.signy = 1; + this.sx = 0; + this.sy = 0; + } + else + { + return false; + } + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGb) + { + // 22deg small + this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGs; + + if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS) + { + this.signx = 1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS) + { + this.signx = -1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS) + { + this.signx = -1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS) + { + this.signx = 1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else + { + return false; + } + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGs) + { + // 22deg big + this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGb; + + if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB) + { + this.signx = 1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB) + { + this.signx = -1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB) + { + this.signx = -1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB) + { + this.signx = 1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 1) / slen; + this.sy = (this.signy * 2) / slen; + } + else + { + return false; + } + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGb) + { + // 67deg small + this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGs; + + if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS) + { + this.signx = 1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS) + { + this.signx = -1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS) + { + this.signx = -1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS) + { + this.signx = 1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else + { + return false; + } + } + else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_HALF) + { + // 67deg big + this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGb; + + if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB) + { + this.signx = 1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB) + { + this.signx = -1; + this.signy = -1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB) + { + this.signx = -1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB) + { + this.signx = 1; + this.signy = 1; + var slen = Math.sqrt(2 * 2 + 1 * 1); + this.sx = (this.signx * 2) / slen; + this.sy = (this.signy * 1) / slen; + } + else + { + return false; + } + } + else + { + // Half-full tile + this.type = Phaser.Physics.Ninja.Tile.TYPE_HALF; + + if (this.id == Phaser.Physics.Ninja.Tile.HALFd) + { + this.signx = 0; + this.signy = -1; + this.sx = this.signx; + this.sy = this.signy; + } + else if (this.id == Phaser.Physics.Ninja.Tile.HALFu) + { + this.signx = 0; + this.signy = 1; + this.sx = this.signx; + this.sy = this.signy; + } + else if (this.id == Phaser.Physics.Ninja.Tile.HALFl) + { + this.signx = 1; + this.signy = 0; + this.sx = this.signx; + this.sy = this.signy; + } + else if (this.id == Phaser.Physics.Ninja.Tile.HALFr) + { + this.signx = -1; + this.signy = 0; + this.sx = this.signx; + this.sy = this.signy; + } + else + { + return false; + } + } + } + +} + +/** +* @name Phaser.Physics.Ninja.Tile#x +* @property {number} x - The x position. +*/ +Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "x", { + + /** + * The x position. + * @method x + * @return {number} + */ + get: function () { + return this.pos.x - this.xw; + }, + + /** + * The x position. + * @method x + * @param {number} value + */ + set: function (value) { + this.pos.x = value; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Tile#y +* @property {number} y - The y position. +*/ +Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "y", { + + /** + * The y position. + * @method y + * @return {number} + */ + get: function () { + return this.pos.y - this.yw; + }, + + /** + * The y position. + * @method y + * @param {number} value + */ + set: function (value) { + this.pos.y = value; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Tile#bottom +* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height) +* @readonly +*/ +Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "bottom", { + + /** + * The sum of the y and height properties. + * @method bottom + * @return {number} + * @readonly + */ + get: function () { + return this.pos.y + this.yw; + } + +}); + +/** +* @name Phaser.Physics.Ninja.Tile#right +* @property {number} right - The right value of this Body (same as Body.x + Body.width) +* @readonly +*/ +Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "right", { + + /** + * The sum of the x and width properties. + * @method right + * @return {number} + * @readonly + */ + get: function () { + return this.pos.x + this.xw; + } + +}); + +Phaser.Physics.Ninja.Tile.EMPTY = 0; +Phaser.Physics.Ninja.Tile.FULL = 1;//fullAABB tile +Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn = 2;//45-degree triangle, whose normal is (+ve,-ve) +Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn = 3;//(+ve,+ve) +Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp = 4;//(-ve,+ve) +Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp = 5;//(-ve,-ve) +Phaser.Physics.Ninja.Tile.CONCAVEpn = 6;//1/4-circle cutout +Phaser.Physics.Ninja.Tile.CONCAVEnn = 7; +Phaser.Physics.Ninja.Tile.CONCAVEnp = 8; +Phaser.Physics.Ninja.Tile.CONCAVEpp = 9; +Phaser.Physics.Ninja.Tile.CONVEXpn = 10;//1/4/circle +Phaser.Physics.Ninja.Tile.CONVEXnn = 11; +Phaser.Physics.Ninja.Tile.CONVEXnp = 12; +Phaser.Physics.Ninja.Tile.CONVEXpp = 13; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS = 14;//22.5 degree slope +Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS = 15; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS = 16; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS = 17; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB = 18; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB = 19; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB = 20; +Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB = 21; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS = 22;//67.5 degree slope +Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS = 23; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS = 24; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS = 25; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB = 26; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB = 27; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB = 28; +Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB = 29; +Phaser.Physics.Ninja.Tile.HALFd = 30;//half-full tiles +Phaser.Physics.Ninja.Tile.HALFr = 31; +Phaser.Physics.Ninja.Tile.HALFu = 32; +Phaser.Physics.Ninja.Tile.HALFl = 33; + +Phaser.Physics.Ninja.Tile.TYPE_EMPTY = 0; +Phaser.Physics.Ninja.Tile.TYPE_FULL = 1; +Phaser.Physics.Ninja.Tile.TYPE_45DEG = 2; +Phaser.Physics.Ninja.Tile.TYPE_CONCAVE = 6; +Phaser.Physics.Ninja.Tile.TYPE_CONVEX = 10; +Phaser.Physics.Ninja.Tile.TYPE_22DEGs = 14; +Phaser.Physics.Ninja.Tile.TYPE_22DEGb = 18; +Phaser.Physics.Ninja.Tile.TYPE_67DEGs = 22; +Phaser.Physics.Ninja.Tile.TYPE_67DEGb = 26; +Phaser.Physics.Ninja.Tile.TYPE_HALF = 30; + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Ninja Physics Circle constructor. +* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. +* +* @class Phaser.Physics.Ninja.Circle +* @classdesc Arcade Physics Constructor +* @constructor +* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. +* @param {number} x - The x coordinate to create this shape at. +* @param {number} y - The y coordinate to create this shape at. +* @param {number} radius - The radius of this Circle. +*/ +Phaser.Physics.Ninja.Circle = function (body, x, y, radius) { + + /** + * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. + */ + this.body = body; + + /** + * @property {Phaser.Physics.Ninja} system - A reference to the physics system. + */ + this.system = body.system; + + /** + * @property {Phaser.Point} pos - The position of this object. + */ + this.pos = new Phaser.Point(x, y); + + /** + * @property {Phaser.Point} oldpos - The position of this object in the previous update. + */ + this.oldpos = new Phaser.Point(x, y); + + /** + * @property {number} radius - The radius of this circle shape. + */ + this.radius = radius; + + /** + * @property {number} width - The width. + * @readonly + */ + this.width = radius * 2; + + /** + * @property {number} height - The height. + * @readonly + */ + this.height = radius * 2; + + /** + * @property {number} oH - Internal var. + * @private + */ + this.oH = 0; + + /** + * @property {number} oV - Internal var. + * @private + */ + this.oV = 0; + + /** + * @property {Phaser.Point} velocity - The velocity of this object. + */ + this.velocity = new Phaser.Point(); + + /** + * @property {object} circleTileProjections - All of the collision response handlers. + */ + this.circleTileProjections = {}; + + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL] = this.projCircle_Full; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG] = this.projCircle_45Deg; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE] = this.projCircle_Concave; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX] = this.projCircle_Convex; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs] = this.projCircle_22DegS; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb] = this.projCircle_22DegB; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs] = this.projCircle_67DegS; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb] = this.projCircle_67DegB; + this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF] = this.projCircle_Half; + +} + +Phaser.Physics.Ninja.Circle.prototype.constructor = Phaser.Physics.Ninja.Circle; + +Phaser.Physics.Ninja.Circle.COL_NONE = 0; +Phaser.Physics.Ninja.Circle.COL_AXIS = 1; +Phaser.Physics.Ninja.Circle.COL_OTHER = 2; + +Phaser.Physics.Ninja.Circle.prototype = { + + /** + * Updates this Circles position. + * + * @method Phaser.Physics.Ninja.Circle#integrate + */ + integrate: function () { + + var px = this.pos.x; + var py = this.pos.y; + + // integrate + this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); + this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); + + // store + this.velocity.set(this.pos.x - px, this.pos.y - py); + this.oldpos.set(px, py); + + }, + + /** + * Process a world collision and apply the resulting forces. + * + * @method Phaser.Physics.Ninja.Circle#reportCollisionVsWorld + * @param {number} px - The tangent velocity + * @param {number} py - The tangent velocity + * @param {number} dx - Collision normal + * @param {number} dy - Collision normal + * @param {number} obj - Object this Circle collided with + */ + reportCollisionVsWorld: function (px, py, dx, dy, obj) { + + var p = this.pos; + var o = this.oldpos; + + // Calc velocity + var vx = p.x - o.x; + var vy = p.y - o.y; + + // Find component of velocity parallel to collision normal + var dp = (vx * dx + vy * dy); + var nx = dp * dx; //project velocity onto collision normal + + var ny = dp * dy; //nx,ny is normal velocity + + var tx = vx - nx; //px,py is tangent velocity + var ty = vy - ny; + + // We only want to apply collision response forces if the object is travelling into, and not out of, the collision + var b, bx, by, fx, fy; + + if (dp < 0) + { + fx = tx * this.body.friction; + fy = ty * this.body.friction; + + b = 1 + this.body.bounce; + + bx = (nx * b); + by = (ny * b); + + if (dx === 1) + { + this.body.touching.left = true; + } + else if (dx === -1) + { + this.body.touching.right = true; + } + + if (dy === 1) + { + this.body.touching.up = true; + } + else if (dy === -1) + { + this.body.touching.down = true; + } + } + else + { + // Moving out of collision, do not apply forces + bx = by = fx = fy = 0; + } + + // Project object out of collision + p.x += px; + p.y += py; + + // Apply bounce+friction impulses which alter velocity + o.x += px + bx + fx; + o.y += py + by + fy; + + }, + + /** + * Collides this Circle against the world bounds. + * + * @method Phaser.Physics.Ninja.Circle#collideWorldBounds + */ + collideWorldBounds: function () { + + var dx = this.system.bounds.x - (this.pos.x - this.xw); + + if (0 < dx) + { + this.reportCollisionVsWorld(dx, 0, 1, 0, null); + } + else + { + dx = (this.pos.x + this.xw) - this.system.bounds.width; + + if (0 < dx) + { + this.reportCollisionVsWorld(-dx, 0, -1, 0, null); + } + } + + var dy = this.system.bounds.y - (this.pos.y - this.yw); + + if (0 < dy) + { + this.reportCollisionVsWorld(0, dy, 0, 1, null); + } + else + { + dy = (this.pos.y + this.yw) - this.system.bounds.height; + + if (0 < dy) + { + this.reportCollisionVsWorld(0, -dy, 0, -1, null); + } + } + + }, + + /** + * Collides this Circle with a Tile. + * + * @method Phaser.Physics.Ninja.Circle#collideCircleVsTile + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {boolean} True if they collide, otherwise false. + */ + collideCircleVsTile: function (tile) { + + var pos = this.pos; + var r = this.radius; + var c = tile; + + var tx = c.pos.x; + var ty = c.pos.y; + var txw = c.xw; + var tyw = c.yw; + + var dx = pos.x - tx; // tile->obj delta + var px = (txw + r) - Math.abs(dx); // penetration depth in x + + if (0 < px) + { + var dy = pos.y - ty; // tile->obj delta + var py = (tyw + r) - Math.abs(dy); // pen depth in y + + if (0 < py) + { + // object may be colliding with tile + + // determine grid/voronoi region of circle center + this.oH = 0; + this.oV = 0; + + if (dx < -txw) + { + // circle is on left side of tile + this.oH = -1; + } + else if (txw < dx) + { + // circle is on right side of tile + this.oH = 1; + } + + if (dy < -tyw) + { + // circle is on top side of tile + this.oV = -1; + } + else if (tyw < dy) + { + // circle is on bottom side of tile + this.oV = 1; + } + + return this.resolveCircleTile(px, py, this.oH, this.oV, this, c); + + } + } + }, + + /** + * Resolves tile collision. + * + * @method Phaser.Physics.Ninja.Circle#resolveCircleTile + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + resolveCircleTile: function (x, y, oH, oV, obj, t) { + + if (0 < t.id) + { + return this.circleTileProjections[t.type](x, y, oH, oV, obj, t); + } + else + { + // console.log("ResolveCircleTile() was called with an empty (or unknown) tile!: ID=" + t.id + ")"); + return false; + } + + }, + + /** + * Resolves Full tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_Full + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_Full: function (x, y, oH, oV, obj, t) { + + //if we're colliding vs. the current cell, we need to project along the + //smallest penetration vector. + //if we're colliding vs. horiz. or vert. neighb, we simply project horiz/vert + //if we're colliding diagonally, we need to collide vs. tile corner + + if (oH == 0) + { + if (oV == 0) + { + //collision with current cell + if (x < y) + { + //penetration in x is smaller; project in x + var dx = obj.pos.x - t.pos.x;//get sign for projection along x-axis + + //NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?) + if (dx < 0) + { + obj.reportCollisionVsWorld(-x, 0, -1, 0, t); + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(x, 0, 1, 0, t); + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + } + else + { + //penetration in y is smaller; project in y + var dy = obj.pos.y - t.pos.y;//get sign for projection along y-axis + + //NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?) + if (dy < 0) + { + obj.reportCollisionVsWorld(0, -y, 0, -1, t); + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(0, y, 0, 1, t); + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + } + } + else + { + //collision with vertical neighbor + obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + } + else if (oV == 0) + { + //collision with horizontal neighbor + obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //diagonal collision + + //get diag vertex position + var vx = t.pos.x + (oH * t.xw); + var vy = t.pos.y + (oV * t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx * dx + dy * dy); + var pen = obj.radius - len; + + if (0 < pen) + { + //vertex is in the circle; project outward + if (len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + + }, + + /** + * Resolves 45 Degree tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_45Deg + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_45Deg: function (x, y, oH, oV, obj, t) { + + //if we're colliding diagonally: + // -if obj is in the diagonal pointed to by the slope normal: we can't collide, do nothing + // -else, collide vs. the appropriate vertex + //if obj is in this tile: perform collision as for aabb-ve-45deg + //if obj is horiz OR very neighb in direction of slope: collide only vs. slope + //if obj is horiz or vert neigh against direction of slope: collide vs. face + + var signx = t.signx; + var signy = t.signy; + var lenP; + + if (oH == 0) + { + if (oV == 0) + { + //colliding with current tile + + var sx = t.sx; + var sy = t.sy; + + var ox = (obj.pos.x - (sx * obj.radius)) - t.pos.x;//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (sy * obj.radius)) - t.pos.y;//point on the circle, relative to the tile center + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the innermost point is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox * sx) + (oy * sy); + + if (dp < 0) + { + //collision; project delta onto slope and use this as the slope penetration vector + sx *= -dp;//(sx,sy) is now the penetration vector + sy *= -dp; + + //find the smallest axial projection vector + if (x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + + //get sign for projection along x-axis + if ((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + + //get sign for projection along y-axis + if ((obj.pos.y - t.pos.y) < 0) + { + y *= -1; + } + } + + var lenN = Math.sqrt(sx * sx + sy * sy); + + if (lenP < lenN) + { + obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + + } + else + { + //colliding vertically + if ((signy * oV) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y + (oV * t.yw));//point on the circle, relative to the closest tile vert + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the vertex, otherwise by the normal. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronoi region, or that of the vertex. + var perp = (ox * -sy) + (oy * sx); + if (0 < (perp * signx * signy)) + { + //collide vs. vertex + var len = Math.sqrt(ox * ox + oy * oy); + var pen = obj.radius - len; + if (0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox * sx) + (oy * sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + if (0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + } + else if (oV == 0) + { + //colliding horizontally + if ((signx * oH) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var ox = obj.pos.x - (t.pos.x + (oH * t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//point on the circle, relative to the closest tile vert + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the normal, otherwise by the vertex. + //(NOTE: this is the opposite logic of the vertical case; + // for vertical, if the perp prod and the slope's slope agree, it's outside. + // for horizontal, if the perp prod and the slope's slope agree, circle is inside. + // ..but this is only a property of flahs' coord system (i.e the rules might swap + // in righthanded systems)) + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox * -sy) + (oy * sx); + if ((perp * signx * signy) < 0) + { + //collide vs. vertex + var len = Math.sqrt(ox * ox + oy * oy); + var pen = obj.radius - len; + if (0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox * sx) + (oy * sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + if (0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + else + { + //colliding diagonally + if (0 < ((signx * oH) + (signy * oV))) + { + //the dotprod of slope normal and cell offset is strictly positive, + //therefore obj is in the diagonal neighb pointed at by the normal, and + //it cannot possibly reach/touch/penetrate the slope + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else + { + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x + (oH * t.xw); + var vy = t.pos.y + (oV * t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx * dx + dy * dy); + var pen = obj.radius - len; + if (0 < pen) + { + //vertex is in the circle; project outward + if (len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + }, + + /** + * Resolves Concave tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_Concave + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_Concave: function (x, y, oH, oV, obj, t) { + + //if we're colliding diagonally: + // -if obj is in the diagonal pointed to by the slope normal: we can't collide, do nothing + // -else, collide vs. the appropriate vertex + //if obj is in this tile: perform collision as for aabb + //if obj is horiz OR very neighb in direction of slope: collide vs vert + //if obj is horiz or vert neigh against direction of slope: collide vs. face + + var signx = t.signx; + var signy = t.signy; + var lenP; + + if (oH == 0) + { + if (oV == 0) + { + //colliding with current tile + + var ox = (t.pos.x + (signx * t.xw)) - obj.pos.x;//(ox,oy) is the vector from the circle to + var oy = (t.pos.y + (signy * t.yw)) - obj.pos.y;//tile-circle's center + + var twid = t.xw * 2; + var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var len = Math.sqrt(ox * ox + oy * oy); + var pen = (len + obj.radius) - trad; + + if (0 < pen) + { + //find the smallest axial projection vector + if (x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + + //get sign for projection along x-axis + if ((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + + //get sign for projection along y-axis + if ((obj.pos.y - t.pos.y) < 0) + { + y *= -1; + } + } + + + if (lenP < pen) + { + obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we can assume that len >0, because if we're here then + //(len + obj.radius) > trad, and since obj.radius <= trad + //len MUST be > 0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + + } + else + { + //colliding vertically + if ((signy * oV) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we could only be colliding vs the vertical tip + + //get diag vertex position + var vx = t.pos.x - (signx * t.xw); + var vy = t.pos.y + (oV * t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx * dx + dy * dy); + var pen = obj.radius - len; + if (0 < pen) + { + //vertex is in the circle; project outward + if (len == 0) + { + //project out vertically + dx = 0; + dy = oV; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + else if (oV == 0) + { + //colliding horizontally + if ((signx * oH) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we could only be colliding vs the horizontal tip + + //get diag vertex position + var vx = t.pos.x + (oH * t.xw); + var vy = t.pos.y - (signy * t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx * dx + dy * dy); + var pen = obj.radius - len; + if (0 < pen) + { + //vertex is in the circle; project outward + if (len == 0) + { + //project out horizontally + dx = oH; + dy = 0; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + else + { + //colliding diagonally + if (0 < ((signx * oH) + (signy * oV))) + { + //the dotprod of slope normal and cell offset is strictly positive, + //therefore obj is in the diagonal neighb pointed at by the normal, and + //it cannot possibly reach/touch/penetrate the slope + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else + { + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x + (oH * t.xw); + var vy = t.pos.y + (oV * t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx * dx + dy * dy); + var pen = obj.radius - len; + if (0 < pen) + { + //vertex is in the circle; project outward + if (len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + + }, + + /** + * Resolves Convex tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_Convex + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_Convex: function (x, y, oH, oV, obj, t) { + + //if the object is horiz AND/OR vertical neighbor in the normal (signx,signy) + //direction, collide vs. tile-circle only. + //if we're colliding diagonally: + // -else, collide vs. the appropriate vertex + //if obj is in this tile: perform collision as for aabb + //if obj is horiz or vert neigh against direction of slope: collide vs. face + + var signx = t.signx; + var signy = t.signy; + var lenP; + + if (oH == 0) + { + if (oV == 0) + { + //colliding with current tile + + + var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to + var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center + + var twid = t.xw * 2; + var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var len = Math.sqrt(ox * ox + oy * oy); + var pen = (trad + obj.radius) - len; + + if (0 < pen) + { + //find the smallest axial projection vector + if (x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + + //get sign for projection along x-axis + if ((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + + //get sign for projection along y-axis + if ((obj.pos.y - t.pos.y) < 0) + { + y *= -1; + } + } + + + if (lenP < pen) + { + obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //note: len should NEVER be == 0, because if it is, + //projeciton by an axis shoudl always be shorter, and we should + //never arrive here + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + + } + } + } + else + { + //colliding vertically + if ((signy * oV) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //obj in neighboring cell pointed at by tile normal; + //we could only be colliding vs the tile-circle surface + + var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to + var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center + + var twid = t.xw * 2; + var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var len = Math.sqrt(ox * ox + oy * oy); + var pen = (trad + obj.radius) - len; + + if (0 < pen) + { + + //note: len should NEVER be == 0, because if it is, + //obj is not in a neighboring cell! + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + else if (oV == 0) + { + //colliding horizontally + if ((signx * oH) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //obj in neighboring cell pointed at by tile normal; + //we could only be colliding vs the tile-circle surface + + var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to + var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center + + var twid = t.xw * 2; + var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var len = Math.sqrt(ox * ox + oy * oy); + var pen = (trad + obj.radius) - len; + + if (0 < pen) + { + + //note: len should NEVER be == 0, because if it is, + //obj is not in a neighboring cell! + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + else + { + //colliding diagonally + if (0 < ((signx * oH) + (signy * oV))) + { + //obj in diag neighb cell pointed at by tile normal; + //we could only be colliding vs the tile-circle surface + + var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to + var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center + + var twid = t.xw * 2; + var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; + //note that this should be precomputed at compile-time since it's constant + + var len = Math.sqrt(ox * ox + oy * oy); + var pen = (trad + obj.radius) - len; + + if (0 < pen) + { + + //note: len should NEVER be == 0, because if it is, + //obj is not in a neighboring cell! + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x + (oH * t.xw); + var vy = t.pos.y + (oV * t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx * dx + dy * dy); + var pen = obj.radius - len; + if (0 < pen) + { + //vertex is in the circle; project outward + if (len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + + }, + + /** + * Resolves Half tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_Half + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_Half: function (x,y,oH,oV,obj,t) { + + //if obj is in a neighbor pointed at by the halfedge normal, + //we'll never collide (i.e if the normal is (0,1) and the obj is in the DL.D, or R neighbors) + // + //if obj is in a neigbor perpendicular to the halfedge normal, it might + //collide with the halfedge-vertex, or with the halfedge side. + // + //if obj is in a neigb pointing opposite the halfedge normal, obj collides with edge + // + //if obj is in a diagonal (pointing away from the normal), obj collides vs vertex + // + //if obj is in the halfedge cell, it collides as with aabb + + var signx = t.signx; + var signy = t.signy; + + var celldp = (oH*signx + oV*signy);//this tells us about the configuration of cell-offset relative to tile normal + if(0 < celldp) + { + //obj is in "far" (pointed-at-by-normal) neighbor of halffull tile, and will never hit + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else if(oH == 0) + { + if(oV == 0) + { + //colliding with current tile + var r = obj.radius; + var ox = (obj.pos.x - (signx*r)) - t.pos.x;//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (signy*r)) - t.pos.y;//point on the circle, relative to the tile center + + + //we perform operations analogous to the 45deg tile, except we're using + //an axis-aligned slope instead of an angled one.. + var sx = signx; + var sy = signy; + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + + var lenN = Math.sqrt(sx*sx + sy*sy); + var lenP = Math.sqrt(x*x + y*y); + + if(lenP < lenN) + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP,t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.signx,t.signy); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + return true; + } + + } + else + { + //colliding vertically + + if(celldp == 0) + { + + var r = obj.radius; + var dx = obj.pos.x - t.pos.x; + + //we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex + //or halfedge side + if((dx*signx) < 0) + { + //collision with halfedge side + obj.reportCollisionVsWorld(0,y*oV,0,oV,t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //collision with halfedge vertex + var dy = obj.pos.y - (t.pos.y + oV*t.yw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = signx / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + } + else + { + //due to the first conditional (celldp >0), we know we're in the cell "opposite" the normal, and so + //we can only collide with the cell edge + //collision with vertical neighbor + obj.reportCollisionVsWorld(0,y*oV,0,oV,t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + + } + } + else if(oV == 0) + { + //colliding horizontally + if(celldp == 0) + { + + var r = obj.radius; + var dy = obj.pos.y - t.pos.y; + + //we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex + //or halfedge side + if((dy*signy) < 0) + { + //collision with halfedge side + obj.reportCollisionVsWorld(x*oH,0,oH,0,t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //collision with halfedge vertex + var dx = obj.pos.x - (t.pos.x + oH*t.xw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = signx / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + } + else + { + //due to the first conditional (celldp >0), we know w're in the cell "opposite" the normal, and so + //we can only collide with the cell edge + obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + } + else + { + //colliding diagonally; we know, due to the initial (celldp >0) test which has failed + //if we've reached this point, that we're in a diagonal neighbor on the non-normal side, so + //we could only be colliding with the cell vertex, if at all. + + //get diag vertex position + var vx = t.pos.x + (oH*t.xw); + var vy = t.pos.y + (oV*t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + + }, + + /** + * Resolves 22 Degree tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_22DegS + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_22DegS: function (x,y,oH,oV,obj,t) { + + //if the object is in a cell pointed at by signy, no collision will ever occur + //otherwise, + // + //if we're colliding diagonally: + // -collide vs. the appropriate vertex + //if obj is in this tile: collide vs slope or vertex + //if obj is horiz neighb in direction of slope: collide vs. slope or vertex + //if obj is horiz neighb against the slope: + // if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face) + // else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert) + //if obj is vert neighb against direction of slope: collide vs. face + + var signx = t.signx; + var signy = t.signy; + + if(0 < (signy*oV)) + { + //object will never collide vs tile, it can't reach that far + + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else if(oH == 0) + { + if(oV == 0) + { + //colliding with current tile + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var r = obj.radius; + var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the tile corner + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the vertex, otherwise by the normal or axially. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + + var perp = (ox*-sy) + (oy*sx); + if(0 < (perp*signx*signy)) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = r - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope or vs axis + ox -= r*sx;//this gives us the vector from + oy -= r*sy;//a point on the slope to the innermost point on the circle + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + + //find the smallest axial projection vector + if(x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + //get sign for projection along x-axis + if((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + //get sign for projection along y-axis + if((obj.pos.y - t.pos.y)< 0) + { + y *= -1; + } + } + + if(lenP < lenN) + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + } + + } + else + { + //colliding vertically; we can assume that (signy*oV) < 0 + //due to the first conditional far above + + obj.reportCollisionVsWorld(0,y*oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + } + else if(oV == 0) + { + //colliding horizontally + if((signx*oH) < 0) + { + //colliding with face/edge OR with corner of wedge, depending on our position vertically + + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x - (signx*t.xw); + var vy = t.pos.y; + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + if((dy*signy) < 0) + { + //colliding vs face + obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding vs. vertex + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + else + { + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var ox = obj.pos.x - (t.pos.x + (oH*t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the closest tile vert + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the normal, otherwise by the vertex. + //(NOTE: this is the opposite logic of the vertical case; + // for vertical, if the perp prod and the slope's slope agree, it's outside. + // for horizontal, if the perp prod and the slope's slope agree, circle is inside. + // ..but this is only a property of flahs' coord system (i.e the rules might swap + // in righthanded systems)) + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox*-sy) + (oy*sx); + if((perp*signx*signy) < 0) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = obj.radius - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox*sx) + (oy*sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + + if(0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx*pen, sy*pen, sx, sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + else + { + + //colliding diagonally; due to the first conditional above, + //obj is vertically offset against slope, and offset in either direction horizontally + + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x + (oH*t.xw); + var vy = t.pos.y + (oV*t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + + }, + + /** + * Resolves 22 Degree tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_22DegB + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_22DegB: function (x,y,oH, oV, obj,t) { + + //if we're colliding diagonally: + // -if we're in the cell pointed at by the normal, collide vs slope, else + // collide vs. the appropriate corner/vertex + // + //if obj is in this tile: collide as with aabb + // + //if obj is horiz or vertical neighbor AGAINST the slope: collide with edge + // + //if obj is horiz neighb in direction of slope: collide vs. slope or vertex or edge + // + //if obj is vert neighb in direction of slope: collide vs. slope or vertex + + var signx = t.signx; + var signy = t.signy; + + if(oH == 0) + { + if(oV == 0) + { + //colliding with current cell + + var sx = t.sx; + var sy = t.sy; + + var r = obj.radius; + var ox = (obj.pos.x - (sx*r)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (sy*r)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + + //find the smallest axial projection vector + if(x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + //get sign for projection along x-axis + if((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + //get sign for projection along y-axis + if((obj.pos.y - t.pos.y)< 0) + { + y *= -1; + } + } + + if(lenP < lenN) + { + obj.reportCollisionVsWorld(x, y, x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + else + { + //colliding vertically + + if((signy*oV) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y + (signy*t.yw));//point on the circle, relative to the closest tile vert + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the vertex, otherwise by the normal. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox*-sy) + (oy*sx); + if(0 < (perp*signx*signy)) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = obj.radius - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox*sx) + (oy*sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + if(0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx*pen, sy*pen,sx, sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + } + else if(oV == 0) + { + //colliding horizontally + + if((signx*oH) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding with edge, slope, or vertex + + var ox = obj.pos.x - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the closest tile vert + + if((oy*signy) < 0) + { + //we're colliding with the halfface + obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding with the vertex or slope + + var sx = t.sx; + var sy = t.sy; + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the slope, otherwise by the vertex. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox*-sy) + (oy*sx); + if((perp*signx*signy) < 0) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = obj.radius - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox*sx) + (oy*sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + if(0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + } + else + { + //colliding diagonally + if( 0 < ((signx*oH) + (signy*oV)) ) + { + //the dotprod of slope normal and cell offset is strictly positive, + //therefore obj is in the diagonal neighb pointed at by the normal. + + //collide vs slope + + //we should really precalc this at compile time, but for now, fuck it + var slen = Math.sqrt(2*2 + 1*1);//the raw slope is (-2,-1) + var sx = (signx*1) / slen;//get slope _unit_ normal; + var sy = (signy*2) / slen;//raw RH normal is (1,-2) + + var r = obj.radius; + var ox = (obj.pos.x - (sx*r)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (sy*r)) - (t.pos.y + (signy*t.yw));//point on the circle, relative to a point on the slope + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + //(sx,sy)*-dp is the projection vector + obj.reportCollisionVsWorld(-sx*dp, -sy*dp, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else + { + //collide vs the appropriate vertex + var vx = t.pos.x + (oH*t.xw); + var vy = t.pos.y + (oV*t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + }, + + /** + * Resolves 67 Degree tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_67DegS + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_67DegS: function (x,y,oH,oV,obj,t) { + + //if the object is in a cell pointed at by signx, no collision will ever occur + //otherwise, + // + //if we're colliding diagonally: + // -collide vs. the appropriate vertex + //if obj is in this tile: collide vs slope or vertex or axis + //if obj is vert neighb in direction of slope: collide vs. slope or vertex + //if obj is vert neighb against the slope: + // if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face) + // else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert) + //if obj is horiz neighb against direction of slope: collide vs. face + + var signx = t.signx; + var signy = t.signy; + + if(0 < (signx*oH)) + { + //object will never collide vs tile, it can't reach that far + + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else if(oH == 0) + { + if(oV == 0) + { + //colliding with current tile + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var r = obj.radius; + var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the tile corner + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the normal or axis, otherwise by the corner/vertex + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronoi region, or that of the vertex. + + var perp = (ox*-sy) + (oy*sx); + if((perp*signx*signy) < 0) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = r - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope or vs axis + ox -= r*sx;//this gives us the vector from + oy -= r*sy;//a point on the slope to the innermost point on the circle + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + + //find the smallest axial projection vector + if(x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + //get sign for projection along x-axis + if((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + //get sign for projection along y-axis + if((obj.pos.y - t.pos.y)< 0) + { + y *= -1; + } + } + + if(lenP < lenN) + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS + } + else + { + obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + + } + else + { + //colliding vertically + + if((signy*oV) < 0) + { + //colliding with face/edge OR with corner of wedge, depending on our position vertically + + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x; + var vy = t.pos.y - (signy*t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + if((dx*signx) < 0) + { + //colliding vs face + obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding vs. vertex + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + else + { + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var sx = t.sx; + var sy = t.sy; + + var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y + (oV*t.yw));//point on the circle, relative to the closest tile vert + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the vertex, otherwise by the normal. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox*-sy) + (oy*sx); + if(0 < (perp*signx*signy)) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = obj.radius - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox*sx) + (oy*sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + + if(0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + } + else if(oV == 0) + { + //colliding horizontally; we can assume that (signy*oV) < 0 + //due to the first conditional far above + + obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding diagonally; due to the first conditional above, + //obj is vertically offset against slope, and offset in either direction horizontally + + //collide vs. vertex + //get diag vertex position + var vx = t.pos.x + (oH*t.xw); + var vy = t.pos.y + (oV*t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + + }, + + /** + * Resolves 67 Degree tile collision. + * + * @method Phaser.Physics.Ninja.Circle#projCircle_67DegB + * @param {number} x - Penetration depth on the x axis. + * @param {number} y - Penetration depth on the y axis. + * @param {number} oH - Grid / voronoi region. + * @param {number} oV - Grid / voronoi region. + * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. + * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. + * @return {number} The result of the collision. + */ + projCircle_67DegB: function (x,y,oH, oV, obj,t) { + + //if we're colliding diagonally: + // -if we're in the cell pointed at by the normal, collide vs slope, else + // collide vs. the appropriate corner/vertex + // + //if obj is in this tile: collide as with aabb + // + //if obj is horiz or vertical neighbor AGAINST the slope: collide with edge + // + //if obj is vert neighb in direction of slope: collide vs. slope or vertex or halfedge + // + //if obj is horiz neighb in direction of slope: collide vs. slope or vertex + + var signx = t.signx; + var signy = t.signy; + + if(oH == 0) + { + if(oV == 0) + { + //colliding with current cell + + var sx = t.sx; + var sy = t.sy; + + var r = obj.radius; + var ox = (obj.pos.x - (sx*r)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (sy*r)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + sx *= -dp;//(sx,sy) is now the projection vector + sy *= -dp; + + var lenN = Math.sqrt(sx*sx + sy*sy); + + //find the smallest axial projection vector + if(x < y) + { + //penetration in x is smaller + lenP = x; + y = 0; + //get sign for projection along x-axis + if((obj.pos.x - t.pos.x) < 0) + { + x *= -1; + } + } + else + { + //penetration in y is smaller + lenP = y; + x = 0; + //get sign for projection along y-axis + if((obj.pos.y - t.pos.y)< 0) + { + y *= -1; + } + } + + if(lenP < lenN) + { + obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + } + else + { + //colliding vertically + + if((signy*oV) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding with edge, slope, or vertex + + var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y + (signy*t.yw));//point on the circle, relative to the closest tile vert + + if((ox*signx) < 0) + { + //we're colliding with the halfface + obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //colliding with the vertex or slope + + var sx = t.sx; + var sy = t.sy; + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the vertex, otherwise by the slope. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox*-sy) + (oy*sx); + if(0 < (perp*signx*signy)) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = obj.radius - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox*sx) + (oy*sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + if(0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx*pen, sy*pen, sx, sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + } + } + else if(oV == 0) + { + //colliding horizontally + + if((signx*oH) < 0) + { + //colliding with face/edge + obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); + + return Phaser.Physics.Ninja.Circle.COL_AXIS; + } + else + { + //we could only be colliding vs the slope OR a vertex + //look at the vector form the closest vert to the circle to decide + + var slen = Math.sqrt(2*2 + 1*1);//the raw slope is (-2,-1) + var sx = (signx*2) / slen;//get slope _unit_ normal; + var sy = (signy*1) / slen;//raw RH normal is (1,-2) + + var ox = obj.pos.x - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost + var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the closest tile vert + + //if the component of (ox,oy) parallel to the normal's righthand normal + //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) + //then we project by the slope, otherwise by the vertex. + //note that this is simply a VERY tricky/weird method of determining + //if the circle is in side the slope/face's voronio region, or that of the vertex. + var perp = (ox*-sy) + (oy*sx); + if((perp*signx*signy) < 0) + { + //collide vs. vertex + var len = Math.sqrt(ox*ox + oy*oy); + var pen = obj.radius - len; + if(0 < pen) + { + //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 + ox /= len; + oy /= len; + + obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + else + { + //collide vs. slope + + //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're + //penetrating the slope. note that this method of penetration calculation doesn't hold + //in general (i.e it won't work if the circle is in the slope), but works in this case + //because we know the circle is in a neighboring cell + var dp = (ox*sx) + (oy*sy); + var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. + if(0 < pen) + { + //collision; circle out along normal by penetration amount + obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + } + } + } + else + { + //colliding diagonally + if( 0 < ((signx*oH) + (signy*oV)) ) + { + //the dotprod of slope normal and cell offset is strictly positive, + //therefore obj is in the diagonal neighb pointed at by the normal. + + //collide vs slope + + var sx = t.sx; + var sy = t.sy; + + var r = obj.radius; + var ox = (obj.pos.x - (sx*r)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost + var oy = (obj.pos.y - (sy*r)) - (t.pos.y - (signy*t.yw));//point on the circle, relative to a point on the slope + + //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope + //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) + var dp = (ox*sx) + (oy*sy); + + if(dp < 0) + { + //collision; project delta onto slope and use this to displace the object + //(sx,sy)*-dp is the projection vector + + obj.reportCollisionVsWorld(-sx*dp, -sy*dp, t.sx, t.sy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + else + { + + //collide vs the appropriate vertex + var vx = t.pos.x + (oH*t.xw); + var vy = t.pos.y + (oV*t.yw); + + var dx = obj.pos.x - vx;//calc vert->circle vector + var dy = obj.pos.y - vy; + + var len = Math.sqrt(dx*dx + dy*dy); + var pen = obj.radius - len; + if(0 < pen) + { + //vertex is in the circle; project outward + if(len == 0) + { + //project out by 45deg + dx = oH / Math.SQRT2; + dy = oV / Math.SQRT2; + } + else + { + dx /= len; + dy /= len; + } + + obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); + + return Phaser.Physics.Ninja.Circle.COL_OTHER; + } + + } + } + + return Phaser.Physics.Ninja.Circle.COL_NONE; + } + +} diff --git a/build/custom/ninja.min.js b/build/custom/ninja.min.js new file mode 100644 index 000000000..737a9be48 --- /dev/null +++ b/build/custom/ninja.min.js @@ -0,0 +1,3 @@ +/* Ninja Physics for Phaser v2.0.0 - http://phaser.io - @photonstorm - (c) 2014 Photon Storm Ltd. */ +Phaser.Physics.Ninja=function(a){this.game=a,this.time=this.game.time,this.gravity=.2,this.bounds=new Phaser.Rectangle(0,0,a.world.width,a.world.height),this._mapData=[]},Phaser.Physics.Ninja.prototype.constructor=Phaser.Physics.Ninja,Phaser.Physics.Ninja.prototype={enableAABB:function(a){this.enable(a,1)},enableCircle:function(a,b){this.enable(a,2,0,b)},enableTile:function(a,b){this.enable(a,3,b)},enable:function(a,b,c,d){"undefined"==typeof b&&(b=1),"undefined"==typeof c&&(c=1);var e=1;for(Array.isArray(a)?e=a.length:a=[a];e--;)null===a[e].body&&(a[e].body=new Phaser.Physics.Ninja.Body(this,a[e],b,c,d),a[e].anchor.set(.5))},setBounds:function(a,b,c,d){this.bounds.setTo(a,b,c,d)},setBoundsToWorld:function(){this.bounds.setTo(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height)},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!1);else this.collideHandler(a,b,c,d,e,!1);return this._total>0},collideHandler:function(a,b,c,d,e,f){return"undefined"!=typeof b||a.type!==Phaser.GROUP&&a.type!==Phaser.EMITTER?void(a&&b&&a.exists&&b.exists&&(a.type==Phaser.SPRITE||a.type==Phaser.TILESPRITE?b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsSprite(a,b,c,d,e,f):b.type==Phaser.GROUP||b.type==Phaser.EMITTER?this.collideSpriteVsGroup(a,b,c,d,e,f):b.type==Phaser.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,b,c,d,e):a.type==Phaser.GROUP?b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsGroup(b,a,c,d,e,f):b.type==Phaser.GROUP||b.type==Phaser.EMITTER?this.collideGroupVsGroup(a,b,c,d,e,f):b.type==Phaser.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,d,e):a.type==Phaser.TILEMAPLAYER?b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsTilemapLayer(b,a,c,d,e):(b.type==Phaser.GROUP||b.type==Phaser.EMITTER)&&this.collideGroupVsTilemapLayer(b,a,c,d,e):a.type==Phaser.EMITTER&&(b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsGroup(b,a,c,d,e,f):b.type==Phaser.GROUP||b.type==Phaser.EMITTER?this.collideGroupVsGroup(a,b,c,d,e,f):b.type==Phaser.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,d,e)))):void this.collideGroupVsSelf(a,c,d,e,f)},collideSpriteVsSprite:function(a,b,c,d,e,f){this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++)},collideSpriteVsGroup:function(a,b,c,d,e,f){if(0!==b.length)for(var g=0,h=b.children.length;h>g;g++)b.children[g].exists&&b.children[g].body&&this.separate(a.body,b.children[g].body,d,e,f)&&(c&&c.call(e,a,b.children[g]),this._total++)},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a.children[g]&&a.children[h]&&a.children[g].exists&&a.children[h].exists&&this.collideSpriteVsSprite(a.children[g],a.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length)for(var g=0,h=a.children.length;h>g;g++)a.children[g].exists&&this.collideSpriteVsGroup(a.children[g],b,c,d,e,f)},separate:function(a,b){return a.type!==Phaser.Physics.NINJA||b.type!==Phaser.Physics.NINJA?!1:a.aabb&&b.aabb?a.aabb.collideAABBVsAABB(b.aabb):a.aabb&&b.tile?a.aabb.collideAABBVsTile(b.tile):a.tile&&b.aabb?b.aabb.collideAABBVsTile(a.tile):a.circle&&b.tile?a.circle.collideCircleVsTile(b.tile):a.tile&&b.circle?b.circle.collideCircleVsTile(a.tile):void 0}},Phaser.Physics.Ninja.Body=function(a,b,c,d,e){"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1),"undefined"==typeof e&&(e=16),this.sprite=b,this.game=b.game,this.type=Phaser.Physics.NINJA,this.system=a,this.aabb=null,this.tile=null,this.circle=null,this.shape=null,this.drag=1,this.friction=.05,this.gravityScale=1,this.bounce=.3,this.velocity=new Phaser.Point,this.skipQuadTree=!1,this.facing=Phaser.NONE,this.immovable=!1,this.collideWorldBounds=!0,this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.maxSpeed=8;var f=b.x,g=b.y;0===b.anchor.x&&(f+=.5*b.width),0===b.anchor.y&&(g+=.5*b.height),1===c?(this.aabb=new Phaser.Physics.Ninja.AABB(this,f,g,b.width,b.height),this.shape=this.aabb):2===c?(this.circle=new Phaser.Physics.Ninja.Circle(this,f,g,e),this.shape=this.circle):3===c&&(this.tile=new Phaser.Physics.Ninja.Tile(this,f,g,b.width,b.height,d),this.shape=this.tile)},Phaser.Physics.Ninja.Body.prototype={updateBounds:function(){},preUpdate:function(){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=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.shape.integrate(),this.collideWorldBounds&&this.shape.collideWorldBounds(),this.speed=Math.sqrt(this.shape.velocity.x*this.shape.velocity.x+this.shape.velocity.y*this.shape.velocity.y),this.angle=Math.atan2(this.shape.velocity.y,this.shape.velocity.x)},postUpdate:function(){this.sprite.type===Phaser.TILESPRITE?(this.sprite.x=this.shape.pos.x-this.shape.xw,this.sprite.y=this.shape.pos.y-this.shape.yw):(this.sprite.x=this.shape.pos.x,this.sprite.y=this.shape.pos.y)},setZeroVelocity:function(){this.shape.oldpos.x=this.shape.pos.x,this.shape.oldpos.y=this.shape.pos.y},moveTo:function(a,b){var c=a*this.game.time.physicsElapsed,b=this.game.math.degToRad(b);this.shape.pos.x=this.shape.oldpos.x+c*Math.cos(b),this.shape.pos.y=this.shape.oldpos.y+c*Math.sin(b)},moveFrom:function(a,b){var c=-a*this.game.time.physicsElapsed,b=this.game.math.degToRad(b);this.shape.pos.x=this.shape.oldpos.x+c*Math.cos(b),this.shape.pos.y=this.shape.oldpos.y+c*Math.sin(b)},moveLeft:function(a){var b=-a*this.game.time.physicsElapsed;this.shape.pos.x=this.shape.oldpos.x+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.x-this.shape.oldpos.x+b))},moveRight:function(a){var b=a*this.game.time.physicsElapsed;this.shape.pos.x=this.shape.oldpos.x+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.x-this.shape.oldpos.x+b))},moveUp:function(a){var b=-a*this.game.time.physicsElapsed;this.shape.pos.y=this.shape.oldpos.y+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.y-this.shape.oldpos.y+b))},moveDown:function(a){var b=a*this.game.time.physicsElapsed;this.shape.pos.y=this.shape.oldpos.y+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.y-this.shape.oldpos.y+b))},reset:function(){}},Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"x",{get:function(){return this.shape.pos.x},set:function(a){this.shape.pos.x=a}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"y",{get:function(){return this.shape.pos.y},set:function(a){this.shape.pos.y=a}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"width",{get:function(){return this.shape.width}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"height",{get:function(){return this.shape.height}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"bottom",{get:function(){return this.shape.pos.y+this.shape.height}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"right",{get:function(){return this.shape.pos.x+this.shape.width}}),Phaser.Physics.Ninja.AABB=function(a,b,c,d,e){this.body=a,this.system=a.system,this.pos=new Phaser.Point(b,c),this.oldpos=new Phaser.Point(b,c),this.xw=Math.abs(d/2),this.yw=Math.abs(e/2),this.width=d,this.height=e,this.oH=0,this.oV=0,this.velocity=new Phaser.Point,this.aabbTileProjections={},this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL]=this.projAABB_Full,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG]=this.projAABB_45Deg,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE]=this.projAABB_Concave,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX]=this.projAABB_Convex,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs]=this.projAABB_22DegS,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb]=this.projAABB_22DegB,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs]=this.projAABB_67DegS,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb]=this.projAABB_67DegB,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF]=this.projAABB_Half},Phaser.Physics.Ninja.AABB.prototype.constructor=Phaser.Physics.Ninja.AABB,Phaser.Physics.Ninja.AABB.COL_NONE=0,Phaser.Physics.Ninja.AABB.COL_AXIS=1,Phaser.Physics.Ninja.AABB.COL_OTHER=2,Phaser.Physics.Ninja.AABB.prototype={integrate:function(){var a=this.pos.x,b=this.pos.y;this.pos.x+=this.body.drag*this.pos.x-this.body.drag*this.oldpos.x,this.pos.y+=this.body.drag*this.pos.y-this.body.drag*this.oldpos.y+this.system.gravity*this.body.gravityScale,this.velocity.set(this.pos.x-a,this.pos.y-b),this.oldpos.set(a,b)},reportCollisionVsWorld:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},reportCollisionVsBody:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e):f=g=h=i=0,j.x+=a,j.y+=b;var s=a+f+h,t=b+g+i;k.x+=s,k.y+=t},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.width,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.height,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},collideAABBVsAABB:function(a){var b=this.pos,c=a,d=c.pos.x,e=c.pos.y,f=c.xw,g=c.yw,h=b.x-d,i=f+this.xw-Math.abs(h);if(i>0){var j=b.y-e,k=g+this.yw-Math.abs(j);if(k>0){k>i?0>h?(i*=-1,k=0):k=0:0>j?(i=0,k*=-1):i=0;var l=Math.sqrt(i*i+k*k);return this.reportCollisionVsBody(i,k,i/l,k/l,c),Phaser.Physics.Ninja.AABB.COL_AXIS}}return!1},collideAABBVsTile:function(a){var b=this.pos,c=a,d=c.pos.x,e=c.pos.y,f=c.xw,g=c.yw,h=b.x-d,i=f+this.xw-Math.abs(h);if(i>0){var j=b.y-e,k=g+this.yw-Math.abs(j);if(k>0)return k>i?0>h?(i*=-1,k=0):k=0:0>j?(i=0,k*=-1):i=0,this.resolveTile(i,k,this,c)}return!1},resolveTile:function(a,b,c,d){return 0i){e*=-i,f*=-i;var j=Math.sqrt(e*e+f*f),k=Math.sqrt(a*a+b*b);return j>k?(c.reportCollisionVsWorld(a,b,a/k,b/k,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(e,f,d.signx,d.signy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_45Deg:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-d.pos.x,h=c.pos.y-f*c.yw-d.pos.y,i=d.sx,j=d.sy,k=g*i+h*j;if(0>k){i*=-k,j*=-k;var l=Math.sqrt(i*i+j*j),m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(i,j,d.sx,d.sy),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_22DegS:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.y-f*c.yw,h=d.pos.y-g;if(h*f>0){var i=c.pos.x-e*c.xw-(d.pos.x+e*d.xw),j=c.pos.y-f*c.yw-(d.pos.y-f*d.yw),k=d.sx,l=d.sy,m=i*k+j*l;if(0>m){k*=-m,l*=-m;var n=Math.sqrt(k*k+l*l),o=Math.sqrt(a*a+b*b),p=Math.abs(h);return n>o?o>p?(c.reportCollisionVsWorld(0,h,0,h/p,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(a,b,a/o,b/o,d),Phaser.Physics.Ninja.AABB.COL_AXIS):n>p?(c.reportCollisionVsWorld(0,h,0,h/p,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(k,l,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_22DegB:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-(d.pos.x-e*d.xw),h=c.pos.y-f*c.yw-(d.pos.y+f*d.yw),i=d.sx,j=d.sy,k=g*i+h*j;if(0>k){i*=-k,j*=-k;var l=Math.sqrt(i*i+j*j),m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(i,j,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_67DegS:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw,h=d.pos.x-g;if(h*e>0){var i=c.pos.x-e*c.xw-(d.pos.x-e*d.xw),j=c.pos.y-f*c.yw-(d.pos.y+f*d.yw),k=d.sx,l=d.sy,m=i*k+j*l;if(0>m){k*=-m,l*=-m;var n=Math.sqrt(k*k+l*l),o=Math.sqrt(a*a+b*b),p=Math.abs(h);return n>o?o>p?(c.reportCollisionVsWorld(h,0,h/p,0,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(a,b,a/o,b/o,d),Phaser.Physics.Ninja.AABB.COL_AXIS):n>p?(c.reportCollisionVsWorld(h,0,h/p,0,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(k,l,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_67DegB:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-(d.pos.x+e*d.xw),h=c.pos.y-f*c.yw-(d.pos.y-f*d.yw),i=d.sx,j=d.sy,k=g*i+h*j;if(0>k){i*=-k,j*=-k;var l=Math.sqrt(i*i+j*j),m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(i,j,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_Convex:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-(d.pos.x-e*d.xw),h=c.pos.y-f*c.yw-(d.pos.y-f*d.yw),i=Math.sqrt(g*g+h*h),j=2*d.xw,k=Math.sqrt(j*j+0),l=k-i;if(0>e*g||0>f*h){var m=Math.sqrt(a*a+b*b);return c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS}return l>0?(g/=i,h/=i,c.reportCollisionVsWorld(g*l,h*l,g,h,d),Phaser.Physics.Ninja.AABB.COL_OTHER):Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_Concave:function(a,b,c,d){var e=d.signx,f=d.signy,g=d.pos.x+e*d.xw-(c.pos.x-e*c.xw),h=d.pos.y+f*d.yw-(c.pos.y-f*c.yw),i=2*d.xw,j=Math.sqrt(i*i+0),k=Math.sqrt(g*g+h*h),l=k-j;if(l>0){var m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(g/=k,h/=k,c.reportCollisionVsWorld(g*l,h*l,g,h,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE}},Phaser.Physics.Ninja.Tile=function(a,b,c,d,e,f){"undefined"==typeof f&&(f=Phaser.Physics.Ninja.Tile.EMPTY),this.body=a,this.system=a.system,this.id=f,this.type=Phaser.Physics.Ninja.Tile.TYPE_EMPTY,this.pos=new Phaser.Point(b,c),this.oldpos=new Phaser.Point(b,c),this.id>1&&this.id<30&&(e=d),this.xw=Math.abs(d/2),this.yw=Math.abs(e/2),this.width=d,this.height=e,this.velocity=new Phaser.Point,this.signx=0,this.signy=0,this.sx=0,this.sy=0,this.body.gravityScale=0,this.body.collideWorldBounds=!1,this.id>0&&this.setType(this.id)},Phaser.Physics.Ninja.Tile.prototype.constructor=Phaser.Physics.Ninja.Tile,Phaser.Physics.Ninja.Tile.prototype={integrate:function(){var a=this.pos.x,b=this.pos.y;this.pos.x+=this.body.drag*this.pos.x-this.body.drag*this.oldpos.x,this.pos.y+=this.body.drag*this.pos.y-this.body.drag*this.oldpos.y+this.system.gravity*this.body.gravityScale,this.velocity.set(this.pos.x-a,this.pos.y-b),this.oldpos.set(a,b)},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.width,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.height,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},reportCollisionVsWorld:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},setType:function(a){return a===Phaser.Physics.Ninja.Tile.EMPTY?this.clear():(this.id=a,this.updateType()),this},clear:function(){this.id=Phaser.Physics.Ninja.Tile.EMPTY,this.updateType()},updateType:function(){if(0===this.id)return this.type=Phaser.Physics.Ninja.Tile.TYPE_EMPTY,this.signx=0,this.signy=0,this.sx=0,this.sy=0,!0;if(this.idn?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.width,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.height,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},collideCircleVsTile:function(a){var b=this.pos,c=this.radius,d=a,e=d.pos.x,f=d.pos.y,g=d.xw,h=d.yw,i=b.x-e,j=g+c-Math.abs(i);if(j>0){var k=b.y-f,l=h+c-Math.abs(k);if(l>0)return this.oH=0,this.oV=0,-g>i?this.oH=-1:i>g&&(this.oH=1),-h>k?this.oV=-1:k>h&&(this.oV=1),this.resolveCircleTile(j,l,this.oH,this.oV,this,d)}},resolveCircleTile:function(a,b,c,d,e,f){return 0a){var g=e.pos.x-f.pos.x;return 0>g?(e.reportCollisionVsWorld(-a,0,-1,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(a,0,1,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS)}var h=e.pos.y-f.pos.y;return 0>h?(e.reportCollisionVsWorld(0,-b,0,-1,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(0,b,0,1,f),Phaser.Physics.Ninja.Circle.COL_AXIS)}return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS}if(0==d)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var i=f.pos.x+c*f.xw,j=f.pos.y+d*f.yw,g=e.pos.x-i,h=e.pos.y-j,k=Math.sqrt(g*g+h*h),l=e.radius-k;return l>0?(0==k?(g=c/Math.SQRT2,h=d/Math.SQRT2):(g/=k,h/=k),e.reportCollisionVsWorld(g*l,h*l,g,h,f),Phaser.Physics.Ninja.Circle.COL_OTHER):Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_45Deg:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0==c)if(0==d){var j=f.sx,k=f.sy,l=e.pos.x-j*e.radius-f.pos.x,m=e.pos.y-k*e.radius-f.pos.y,n=l*j+m*k;if(0>n){j*=-n,k*=-n,b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1));var o=Math.sqrt(j*j+k*k);return o>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(j,k,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,l=e.pos.x-(f.pos.x-h*f.xw),m=e.pos.y-(f.pos.y+d*f.yw),p=l*-k+m*j;if(p*h*i>0){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*j+m*k,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(j*r,k*r,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else if(0==d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,l=e.pos.x-(f.pos.x+c*f.xw),m=e.pos.y-(f.pos.y-i*f.yw),p=l*-k+m*j;if(0>p*h*i){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*j+m*k,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(j*r,k*r,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(h*c+i*d>0)return Phaser.Physics.Ninja.Circle.COL_NONE;var s=f.pos.x+c*f.xw,t=f.pos.y+d*f.yw,u=e.pos.x-s,v=e.pos.y-t,q=Math.sqrt(u*u+v*v),r=e.radius-q;if(r>0)return 0==q?(u=c/Math.SQRT2,v=d/Math.SQRT2):(u/=q,v/=q),e.reportCollisionVsWorld(u*r,v*r,u,v,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_Concave:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0==c){if(0==d){var j=f.pos.x+h*f.xw-e.pos.x,k=f.pos.y+i*f.yw-e.pos.y,l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=n+e.radius-m;return o>0?(b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),o>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER)):Phaser.Physics.Ninja.Circle.COL_NONE}if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var p=f.pos.x-h*f.xw,q=f.pos.y+d*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0==n?(r=0,s=d):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(0==d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var p=f.pos.x+c*f.xw,q=f.pos.y-i*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0==n?(r=c,s=0):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{if(h*c+i*d>0)return Phaser.Physics.Ninja.Circle.COL_NONE;var p=f.pos.x+c*f.xw,q=f.pos.y+d*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0==n?(r=c/Math.SQRT2,s=d/Math.SQRT2):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_Convex:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0==c)if(0==d){var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),o>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}else{if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER +}else if(0==d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(h*c+i*d>0){var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var p=f.pos.x+c*f.xw,q=f.pos.y+d*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0==n?(r=c/Math.SQRT2,s=d/Math.SQRT2):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_Half:function(a,b,c,d,e,f){var g=f.signx,h=f.signy,i=c*g+d*h;if(i>0)return Phaser.Physics.Ninja.Circle.COL_NONE;if(0==c)if(0==d){var j=e.radius,k=e.pos.x-g*j-f.pos.x,l=e.pos.y-h*j-f.pos.y,m=g,n=h,o=k*m+l*n;if(0>o){m*=-o,n*=-o;var p=Math.sqrt(m*m+n*n),q=Math.sqrt(a*a+b*b);return p>q?(e.reportCollisionVsWorld(a,b,a/q,b/q,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(m,n,f.signx,f.signy),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0!=i)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=e.radius,r=e.pos.x-f.pos.x;if(0>r*g)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var s=e.pos.y-(f.pos.y+d*f.yw),t=Math.sqrt(r*r+s*s),u=e.radius-t;if(u>0)return 0==t?(r=g/Math.SQRT2,s=d/Math.SQRT2):(r/=t,s/=t),e.reportCollisionVsWorld(r*u,s*u,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(0==d){if(0!=i)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=e.radius,s=e.pos.y-f.pos.y;if(0>s*h)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var r=e.pos.x-(f.pos.x+c*f.xw),t=Math.sqrt(r*r+s*s),u=e.radius-t;if(u>0)return 0==t?(r=g/Math.SQRT2,s=d/Math.SQRT2):(r/=t,s/=t),e.reportCollisionVsWorld(r*u,s*u,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var v=f.pos.x+c*f.xw,w=f.pos.y+d*f.yw,r=e.pos.x-v,s=e.pos.y-w,t=Math.sqrt(r*r+s*s),u=e.radius-t;if(u>0)return 0==t?(r=c/Math.SQRT2,s=d/Math.SQRT2):(r/=t,s/=t),e.reportCollisionVsWorld(r*u,s*u,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_22DegS:function(a,b,c,d,e,f){var g=f.signx,h=f.signy;if(h*d>0)return Phaser.Physics.Ninja.Circle.COL_NONE;if(0==c){if(0!=d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var i=f.sx,j=f.sy,k=e.radius,l=e.pos.x-(f.pos.x-g*f.xw),m=e.pos.y-f.pos.y,n=l*-j+m*i;if(n*g*h>0){var o=Math.sqrt(l*l+m*m),p=k-o;if(p>0)return l/=o,m/=o,e.reportCollisionVsWorld(l*p,m*p,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{l-=k*i,m-=k*j;var q=l*i+m*j;if(0>q){i*=-q,j*=-q;var r=Math.sqrt(i*i+j*j);return b>a?(lenP=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(lenP=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),r>lenP?(e.reportCollisionVsWorld(a,b,a/lenP,b/lenP,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(i,j,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}}else if(0==d)if(0>g*c){var s=f.pos.x-g*f.xw,t=f.pos.y,u=e.pos.x-s,v=e.pos.y-t;if(0>v*h)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var o=Math.sqrt(u*u+v*v),p=e.radius-o;if(p>0)return 0==o?(u=c/Math.SQRT2,v=d/Math.SQRT2):(u/=o,v/=o),e.reportCollisionVsWorld(u*p,v*p,u,v,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var i=f.sx,j=f.sy,l=e.pos.x-(f.pos.x+c*f.xw),m=e.pos.y-(f.pos.y-h*f.yw),n=l*-j+m*i;if(0>n*g*h){var o=Math.sqrt(l*l+m*m),p=e.radius-o;if(p>0)return l/=o,m/=o,e.reportCollisionVsWorld(l*p,m*p,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var q=l*i+m*j,p=e.radius-Math.abs(q);if(p>0)return e.reportCollisionVsWorld(i*p,j*p,i,j,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{var s=f.pos.x+c*f.xw,t=f.pos.y+d*f.yw,u=e.pos.x-s,v=e.pos.y-t,o=Math.sqrt(u*u+v*v),p=e.radius-o;if(p>0)return 0==o?(u=c/Math.SQRT2,v=d/Math.SQRT2):(u/=o,v/=o),e.reportCollisionVsWorld(u*p,v*p,u,v,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_22DegB:function(a,b,c,d,e,f){var g=f.signx,h=f.signy;if(0==c)if(0==d){var i=f.sx,j=f.sy,k=e.radius,l=e.pos.x-i*k-(f.pos.x-g*f.xw),m=e.pos.y-j*k-(f.pos.y+h*f.yw),n=l*i+m*j;if(0>n){i*=-n,j*=-n;var o=Math.sqrt(i*i+j*j);return b>a?(lenP=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(lenP=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),o>lenP?(e.reportCollisionVsWorld(a,b,a/lenP,b/lenP,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(i,j,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>h*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var i=f.sx,j=f.sy,l=e.pos.x-(f.pos.x-g*f.xw),m=e.pos.y-(f.pos.y+h*f.yw),p=l*-j+m*i;if(p*g*h>0){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*i+m*j,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(i*r,j*r,i,j,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else if(0==d){if(0>g*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var l=e.pos.x-(f.pos.x+g*f.xw),m=e.pos.y-f.pos.y;if(0>m*h)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var i=f.sx,j=f.sy,p=l*-j+m*i;if(0>p*g*h){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*i+m*j,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(i*r,j*r,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(g*c+h*d>0){var s=Math.sqrt(5),i=1*g/s,j=2*h/s,k=e.radius,l=e.pos.x-i*k-(f.pos.x-g*f.xw),m=e.pos.y-j*k-(f.pos.y+h*f.yw),n=l*i+m*j;return 0>n?(e.reportCollisionVsWorld(-i*n,-j*n,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER):Phaser.Physics.Ninja.Circle.COL_NONE}var t=f.pos.x+c*f.xw,u=f.pos.y+d*f.yw,v=e.pos.x-t,w=e.pos.y-u,q=Math.sqrt(v*v+w*w),r=e.radius-q;if(r>0)return 0==q?(v=c/Math.SQRT2,w=d/Math.SQRT2):(v/=q,w/=q),e.reportCollisionVsWorld(v*r,w*r,v,w,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_67DegS:function(a,b,c,d,e,f){var g=f.signx,h=f.signy;if(g*c>0)return Phaser.Physics.Ninja.Circle.COL_NONE;if(0==c)if(0==d){var i=f.sx,j=f.sy,k=e.radius,l=e.pos.x-f.pos.x,m=e.pos.y-(f.pos.y-h*f.yw),n=l*-j+m*i;if(0>n*g*h){var o=Math.sqrt(l*l+m*m),p=k-o;if(p>0)return l/=o,m/=o,e.reportCollisionVsWorld(l*p,m*p,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{l-=k*i,m-=k*j;var q=l*i+m*j;if(0>q){i*=-q,j*=-q;var r=Math.sqrt(i*i+j*j);return b>a?(lenP=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(lenP=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),r>lenP?(e.reportCollisionVsWorld(a,b,a/lenP,b/lenP,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(i,j,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}}else if(0>h*d){var s=f.pos.x,t=f.pos.y-h*f.yw,u=e.pos.x-s,v=e.pos.y-t;if(0>u*g)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var o=Math.sqrt(u*u+v*v),p=e.radius-o;if(p>0)return 0==o?(u=c/Math.SQRT2,v=d/Math.SQRT2):(u/=o,v/=o),e.reportCollisionVsWorld(u*p,v*p,u,v,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var i=f.sx,j=f.sy,l=e.pos.x-(f.pos.x-g*f.xw),m=e.pos.y-(f.pos.y+d*f.yw),n=l*-j+m*i;if(n*g*h>0){var o=Math.sqrt(l*l+m*m),p=e.radius-o;if(p>0)return l/=o,m/=o,e.reportCollisionVsWorld(l*p,m*p,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var q=l*i+m*j,p=e.radius-Math.abs(q);if(p>0)return e.reportCollisionVsWorld(i*p,j*p,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(0==d)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var s=f.pos.x+c*f.xw,t=f.pos.y+d*f.yw,u=e.pos.x-s,v=e.pos.y-t,o=Math.sqrt(u*u+v*v),p=e.radius-o;if(p>0)return 0==o?(u=c/Math.SQRT2,v=d/Math.SQRT2):(u/=o,v/=o),e.reportCollisionVsWorld(u*p,v*p,u,v,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_67DegB:function(a,b,c,d,e,f){var g=f.signx,h=f.signy;if(0==c)if(0==d){var i=f.sx,j=f.sy,k=e.radius,l=e.pos.x-i*k-(f.pos.x+g*f.xw),m=e.pos.y-j*k-(f.pos.y-h*f.yw),n=l*i+m*j;if(0>n){i*=-n,j*=-n;var o=Math.sqrt(i*i+j*j);return b>a?(lenP=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(lenP=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),o>lenP?(e.reportCollisionVsWorld(a,b,a/lenP,b/lenP,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(i,j,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>h*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var l=e.pos.x-f.pos.x,m=e.pos.y-(f.pos.y+h*f.yw);if(0>l*g)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var i=f.sx,j=f.sy,p=l*-j+m*i;if(p*g*h>0){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*i+m*j,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(i*r,j*r,i,j,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else if(0==d){if(0>g*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var s=Math.sqrt(5),i=2*g/s,j=1*h/s,l=e.pos.x-(f.pos.x+g*f.xw),m=e.pos.y-(f.pos.y-h*f.yw),p=l*-j+m*i;if(0>p*g*h){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*i+m*j,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(i*r,j*r,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(g*c+h*d>0){var i=f.sx,j=f.sy,k=e.radius,l=e.pos.x-i*k-(f.pos.x+g*f.xw),m=e.pos.y-j*k-(f.pos.y-h*f.yw),n=l*i+m*j;return 0>n?(e.reportCollisionVsWorld(-i*n,-j*n,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER):Phaser.Physics.Ninja.Circle.COL_NONE}var t=f.pos.x+c*f.xw,u=f.pos.y+d*f.yw,v=e.pos.x-t,w=e.pos.y-u,q=Math.sqrt(v*v+w*w),r=e.radius-q;if(r>0)return 0==q?(v=c/Math.SQRT2,w=d/Math.SQRT2):(v/=q,w/=q),e.reportCollisionVsWorld(v*r,w*r,v,w,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE}}; \ No newline at end of file diff --git a/build/custom/p2.js b/build/custom/p2.js index cfd12f507..31a74fa91 100644 --- a/build/custom/p2.js +++ b/build/custom/p2.js @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.p2=e():"undefined"!=typeof global?self.p2=e():"undefined"!=typeof self&&(self.p2=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0; - np.frictionCoefficient = mu; + np.enableFriction = cm.friction > 0; + np.frictionCoefficient = cm.friction; var reducedMass; if(bi.motionState == Body.STATIC || bi.motionState == Body.KINEMATIC) reducedMass = bj.mass; @@ -10060,9 +10111,13 @@ World.prototype.runNarrowphase = function(np,bi,si,xi,ai,bj,sj,xj,aj,mu,restitut reducedMass = bi.mass; else reducedMass = (bi.mass*bj.mass)/(bi.mass+bj.mass); - np.slipForce = mu*glen*reducedMass; - np.restitution = restitution; - np.surfaceVelocity = surfaceVelocity; + np.slipForce = cm.friction*glen*reducedMass; + np.restitution = cm.restitution; + np.surfaceVelocity = cm.surfaceVelocity; + np.frictionStiffness = cm.frictionStiffness; + np.frictionRelaxation = cm.frictionRelaxation; + np.stiffness = cm.stiffness; + np.relaxation = cm.relaxation; var resolver = np[si.type | sj.type], numContacts = 0; @@ -10659,4 +10714,2937 @@ World.prototype.hitTest = function(worldPoint,bodies,precision){ },{"../../package.json":8,"../collision/Broadphase":10,"../collision/NaiveBroadphase":12,"../collision/Narrowphase":13,"../constraints/DistanceConstraint":17,"../constraints/LockConstraint":19,"../constraints/PrismaticConstraint":20,"../constraints/RevoluteConstraint":21,"../events/EventEmitter":28,"../material/ContactMaterial":29,"../material/Material":30,"../math/vec2":33,"../objects/Body":34,"../objects/Spring":35,"../shapes/Capsule":37,"../shapes/Circle":38,"../shapes/Convex":39,"../shapes/Line":41,"../shapes/Particle":42,"../shapes/Plane":43,"../shapes/Rectangle":44,"../solver/GSSolver":46,"../utils/Utils":50}]},{},[36]) (36) }); -; \ No newline at end of file +; +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* @const +* @type {number} +*/ +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.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.P2 = function (game, config) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + if (typeof config === 'undefined') + { + config = { gravity: [0, 0], broadphase: new p2.SAPBroadphase() }; + } + + /** + * @property {p2.World} game - The p2 World in which the simulation is run. + * @protected + */ + this.world = new p2.World(config); + + /** + * @property {array} materials - A local array of all created Materials. + * @protected + */ + this.materials = []; + + /** + * @property {Phaser.InversePointProxy} gravity - The gravity applied to all bodies each step. + */ + 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. + */ + this.bounds = null; + + /** + * @property {array} _wallShapes - The wall bounds shapes. + * @private + */ + this._wallShapes = [ null, null, null, null ]; + + /** + * @property {Phaser.Signal} onBodyAdded - Dispatched when a new Body is added to the World. + */ + this.onBodyAdded = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onBodyRemoved - Dispatched when a Body is removed from the World. + */ + this.onBodyRemoved = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onSpringAdded - Dispatched when a new Spring is added to the World. + */ + this.onSpringAdded = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onSpringRemoved - Dispatched when a Spring is removed from the World. + */ + this.onSpringRemoved = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onConstraintAdded - Dispatched when a new Constraint is added to the World. + */ + this.onConstraintAdded = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onConstraintRemoved - Dispatched when a Constraint is removed from the World. + */ + this.onConstraintRemoved = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onContactMaterialAdded - Dispatched when a new ContactMaterial is added to the World. + */ + this.onContactMaterialAdded = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onContactMaterialRemoved - Dispatched when a ContactMaterial is removed from the World. + */ + this.onContactMaterialRemoved = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onPostStep - Dispatched after the World.step() + */ + this.onPostStep = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onPostBroadphase - Dispatched after the Broadphase has collected collision pairs in the world. + */ + this.onPostBroadphase = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onImpact - Dispatched when a first contact is created between two bodies. This event is fired after the step has been done. + */ + this.onImpact = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onBeginContact - Dispatched when a first contact is created between two bodies. This event is fired before the step has been done. + */ + this.onBeginContact = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onEndContact - Dispatched when final contact occurs between two bodies. This event is fired before the step has been done. + */ + this.onEndContact = new Phaser.Signal(); + + // Hook into the World events + this.world.on("postStep", this.postStepHandler, this); + this.world.on("postBroadphase", this.postBroadphaseHandler, this); + this.world.on("impact", this.impactHandler, this); + this.world.on("beginContact", this.beginContactHandler, this); + this.world.on("endContact", this.endContactHandler, this); + + /** + * @property {array} collisionGroups - Internal var. + */ + this.collisionGroups = []; + + /** + * @property {number} _collisionGroupID - Internal var. + * @private + */ + this._collisionGroupID = 2; + + 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 = []; + + // Group vs. Group callbacks + + // By default we want everything colliding with everything + this.setBoundsToWorld(true, true, true, true, false); + +}; + +Phaser.Physics.P2.prototype = { + + /** + * Handles a p2 postStep event. + * + * @method Phaser.Physics.P2#postStepHandler + * @private + * @param {object} event - The event data. + */ + postStepHandler: function (event) { + + }, + + /** + * 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.P2#postBroadphaseHandler + * @private + * @param {object} event - The event data. + */ + postBroadphaseHandler: function (event) { + + // Body.id 1 is always the World bounds object + + for (var i = 0; i < event.pairs.length; i += 2) + { + var a = event.pairs[i]; + var b = event.pairs[i+1]; + + if (a.id !== 1 && b.id !== 1) + { + // console.log('postBroadphaseHandler', a, b); + } + } + + }, + + /** + * Handles a p2 impact event. + * + * @method Phaser.Physics.P2#impactHandler + * @private + * @param {object} event - The event data. + */ + impactHandler: function (event) { + + if (event.bodyA.parent && event.bodyB.parent) + { + // Body vs. Body callbacks + var a = event.bodyA.parent; + var b = event.bodyB.parent; + + if (a._bodyCallbacks[event.bodyB.id]) + { + a._bodyCallbacks[event.bodyB.id].call(a._bodyCallbackContext[event.bodyB.id], a, b, event.shapeA, event.shapeB); + } + + if (b._bodyCallbacks[event.bodyA.id]) + { + b._bodyCallbacks[event.bodyA.id].call(b._bodyCallbackContext[event.bodyA.id], b, a, event.shapeB, event.shapeA); + } + + // Body vs. Group callbacks + if (a._groupCallbacks[event.shapeB.collisionGroup]) + { + a._groupCallbacks[event.shapeB.collisionGroup].call(a._groupCallbackContext[event.shapeB.collisionGroup], a, b, event.shapeA, event.shapeB); + } + + if (b._groupCallbacks[event.shapeA.collisionGroup]) + { + b._groupCallbacks[event.shapeA.collisionGroup].call(b._groupCallbackContext[event.shapeA.collisionGroup], b, a, event.shapeB, event.shapeA); + } + } + + }, + + /** + * Handles a p2 begin contact event. + * + * @method Phaser.Physics.P2#beginContactHandler + * @private + * @param {object} event - The event data. + */ + beginContactHandler: function (event) { + + // console.log('beginContactHandler'); + // console.log(event); + + if (event.bodyA.id > 1 && event.bodyB.id > 1) + { + // console.log('beginContactHandler'); + // console.log(event.bodyA.parent.sprite.key); + // console.log(event.bodyB.parent.sprite.key); + } + + }, + + /** + * Handles a p2 end contact event. + * + * @method Phaser.Physics.P2#endContactHandler + * @private + * @param {object} event - The event data. + */ + endContactHandler: function (event) { + + // console.log('endContactHandler'); + // console.log(event); + + + if (event.bodyA.id > 1 && event.bodyB.id > 1) + { + // console.log('endContactHandler'); + // console.log(event); + } + + }, + + /** + * Sets the bounds of the Physics world to match the Game.World dimensions. + * You can optionally set which 'walls' to create: left, right, top or bottom. + * + * @method Phaser.Physics#setBoundsToWorld + * @param {boolean} [left=true] - If true will create the left bounds wall. + * @param {boolean} [right=true] - If true will create the right bounds wall. + * @param {boolean} [top=true] - If true will create the top bounds wall. + * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. + * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group. + */ + setBoundsToWorld: function (left, right, top, bottom, setCollisionGroup) { + + this.setBounds(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, left, right, top, bottom, setCollisionGroup); + + }, + + /** + * Sets the given material against the 4 bounds of this World. + * + * @method Phaser.Physics#setWorldMaterial + * @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. + * @param {boolean} [bottom=true] - If true will set the material on the bottom bounds wall. + */ + setWorldMaterial: function (material, left, right, top, bottom) { + + if (typeof left === 'undefined') { left = true; } + if (typeof right === 'undefined') { right = true; } + if (typeof top === 'undefined') { top = true; } + if (typeof bottom === 'undefined') { bottom = true; } + + if (left && this._wallShapes[0]) + { + this._wallShapes[0].material = material; + } + + if (right && this._wallShapes[1]) + { + this._wallShapes[1].material = material; + } + + if (top && this._wallShapes[2]) + { + this._wallShapes[2].material = material; + } + + if (bottom && this._wallShapes[3]) + { + this._wallShapes[3].material = material; + } + + }, + + /** + * 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.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. + * @param {number} height - The height of the bounds. + * @param {boolean} [left=true] - If true will create the left bounds wall. + * @param {boolean} [right=true] - If true will create the right bounds wall. + * @param {boolean} [top=true] - If true will create the top bounds wall. + * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. + * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group. + */ + setBounds: function (x, y, width, height, left, right, top, bottom, setCollisionGroup) { + + if (typeof left === 'undefined') { left = true; } + if (typeof right === 'undefined') { right = true; } + if (typeof top === 'undefined') { top = true; } + if (typeof bottom === 'undefined') { bottom = true; } + if (typeof setCollisionGroup === 'undefined') { setCollisionGroup = true; } + + var hw = (width / 2); + var hh = (height / 2); + var cx = hw + x; + var cy = hh + y; + + if (this.bounds !== null) + { + if (this.bounds.world) + { + this.world.removeBody(this.bounds); + } + + var i = this.bounds.shapes.length; + + while (i--) + { + var shape = this.bounds.shapes[i]; + this.bounds.removeShape(shape); + } + + this.bounds.position[0] = this.game.math.px2pi(cx); + this.bounds.position[1] = this.game.math.px2pi(cy); + } + else + { + this.bounds = new p2.Body({ mass: 0, position:[this.game.math.px2pi(cx), this.game.math.px2pi(cy)] }); + } + + if (left) + { + this._wallShapes[0] = new p2.Plane(); + + if (setCollisionGroup) + { + this._wallShapes[0].collisionGroup = this.boundsCollisionGroup.mask; + // this._wallShapes[0].collisionGroup = this.everythingCollisionGroup.mask; + // this._wallShapes[0].collisionMask = this.everythingCollisionGroup.mask; + } + + this.bounds.addShape(this._wallShapes[0], [this.game.math.px2pi(-hw), 0], 1.5707963267948966 ); + } + + if (right) + { + this._wallShapes[1] = new p2.Plane(); + + if (setCollisionGroup) + { + this._wallShapes[1].collisionGroup = this.boundsCollisionGroup.mask; + // this._wallShapes[1].collisionGroup = this.everythingCollisionGroup.mask; + // this._wallShapes[1].collisionMask = this.everythingCollisionGroup.mask; + } + + this.bounds.addShape(this._wallShapes[1], [this.game.math.px2pi(hw), 0], -1.5707963267948966 ); + } + + if (top) + { + this._wallShapes[2] = new p2.Plane(); + + if (setCollisionGroup) + { + this._wallShapes[2].collisionGroup = this.boundsCollisionGroup.mask; + // this._wallShapes[2].collisionGroup = this.everythingCollisionGroup.mask; + // this._wallShapes[2].collisionMask = this.everythingCollisionGroup.mask; + } + + this.bounds.addShape(this._wallShapes[2], [0, this.game.math.px2pi(-hh)], -3.141592653589793 ); + } + + if (bottom) + { + this._wallShapes[3] = new p2.Plane(); + + if (setCollisionGroup) + { + this._wallShapes[3].collisionGroup = this.boundsCollisionGroup.mask; + // this._wallShapes[3].collisionGroup = this.everythingCollisionGroup.mask; + // this._wallShapes[3].collisionMask = this.everythingCollisionGroup.mask; + } + + this.bounds.addShape(this._wallShapes[3], [0, this.game.math.px2pi(hh)] ); + } + + this.world.addBody(this.bounds); + + }, + + /** + * @method Phaser.Physics.P2#update + */ + update: function () { + + this.world.step(1 / 60); + + }, + + /** + * Clears all bodies from the simulation. + * + * @method Phaser.Physics.P2#clear + */ + clear: function () { + + this.world.clear(); + + }, + + /** + * 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.P2#destroy + */ + destroy: function () { + + this.world.clear(); + + this.game = null; + + }, + + /** + * Add a body 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) { + + if (body.data.world) + { + return false; + } + else + { + this.world.addBody(body.data); + + this.onBodyAdded.dispatch(body); + + return true; + } + + }, + + /** + * Removes a body from the world. + * + * @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) { + + this.world.removeBody(body.data); + + this.onBodyRemoved.dispatch(body); + + return body; + + }, + + /** + * Adds a Spring to the world. + * + * @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) { + + this.world.addSpring(spring); + + this.onSpringAdded.dispatch(spring); + + return spring; + + }, + + /** + * Removes a Spring from the world. + * + * @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) { + + this.world.removeSpring(spring); + + this.onSpringRemoved.dispatch(spring); + + return spring; + + }, + + /** + * Adds a Constraint to the world. + * + * @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) { + + this.world.addConstraint(constraint); + + this.onConstraintAdded.dispatch(constraint); + + return constraint; + + }, + + /** + * Removes a Constraint from the world. + * + * @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) { + + this.world.removeConstraint(constraint); + + this.onConstraintRemoved.dispatch(constraint); + + return constraint; + + }, + + /** + * Adds a Contact Material to the world. + * + * @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) { + + this.world.addContactMaterial(material); + + this.onContactMaterialAdded.dispatch(material); + + return material; + + }, + + /** + * Removes a Contact Material from the world. + * + * @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) { + + this.world.removeContactMaterial(material); + + this.onContactMaterialRemoved.dispatch(material); + + return material; + + }, + + /** + * Gets a Contact Material based on the two given Materials. + * + * @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) { + + return this.world.getContactMaterial(materialA, materialB); + + }, + + /** + * Sets the given Material against all Shapes owned by all the Bodies in the given array. + * + * @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) { + + var i = bodies.length; + + while (i--) + { + bodies.setMaterial(material); + } + + }, + + /** + * Creates a Material. Materials are applied to Shapes owned by a Body and can be set with Body.setMaterial(). + * 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.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.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.P2.Material(name); + + this.materials.push(material); + + if (typeof body !== 'undefined') + { + body.setMaterial(material); + } + + return material; + + }, + + /** + * Creates a Contact Material from the two given Materials. You can then edit the properties of the Contact Material directly. + * + * @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.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.P2.ContactMaterial(materialA, materialB, options); + + return this.addContactMaterial(contact); + + }, + + /** + * Populates and returns an array of all current Bodies in the world. + * + * @method Phaser.Physics.P2#getBodies + * @return {array} An array containing all current Bodies in the world. + */ + getBodies: function () { + + var output = []; + var i = this.world.bodies.length; + + while (i--) + { + output.push(this.world.bodies[i].parent); + } + + return output; + + }, + + /** + * Populates and returns an array of all current Springs in the world. + * + * @method Phaser.Physics.P2#getSprings + * @return {array} An array containing all current Springs in the world. + */ + getSprings: function () { + + var output = []; + var i = this.world.springs.length; + + while (i--) + { + output.push(this.world.springs[i]); + } + + return output; + + }, + + /** + * Populates and returns an array of all current Constraints in the world. + * + * @method Phaser.Physics.P2#getConstraints + * @return {array} An array containing all current Constraints in the world. + */ + getConstraints: function () { + + var output = []; + var i = this.world.constraints.length; + + while (i--) + { + output.push(this.world.springs[i]); + } + + return output; + + }, + + /** + * Test if a world point overlaps bodies. + * + * @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. + * @return {Array} Array of bodies that overlap the point. + */ + hitTest: function (worldPoint, bodies, precision) { + + }, + + /** + * Converts the current world into a JSON object. + * + * @method Phaser.Physics.P2#toJSON + * @return {object} A JSON representation of the world. + */ + toJSON: function () { + + this.world.toJSON(); + + }, + + createCollisionGroup: function () { + + var bitmask = Math.pow(2, this._collisionGroupID); + + if (this._wallShapes[0]) + { + this._wallShapes[0].collisionMask = this._wallShapes[0].collisionMask | bitmask; + } + + if (this._wallShapes[1]) + { + this._wallShapes[1].collisionMask = this._wallShapes[1].collisionMask | bitmask; + } + + if (this._wallShapes[2]) + { + this._wallShapes[2].collisionMask = this._wallShapes[2].collisionMask | bitmask; + } + + if (this._wallShapes[3]) + { + this._wallShapes[3].collisionMask = this._wallShapes[3].collisionMask | bitmask; + } + + this._collisionGroupID++; + + var group = new Phaser.Physics.P2.CollisionGroup(bitmask); + + this.collisionGroups.push(group); + + return group; + + }, + + /** + * @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. + * @param {boolean} [addToWorld=false] - Automatically add this Body to the world? (usually false as it won't have any shapes on construction). + * @param {object} options - An object containing the build options: + * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. + * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. + * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. + * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon. + * Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...], + * or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers. + */ + createBody: function (x, y, mass, addToWorld, options, data) { + + if (typeof addToWorld === 'undefined') { addToWorld = false; } + + var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass); + + if (data) + { + var result = body.addPolygon(options, data); + + if (!result) + { + return false; + } + } + + if (addToWorld) + { + this.world.addBody(body.data); + } + + return body; + + }, + + /** + * @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. + * @param {boolean} [addToWorld=false] - Automatically add this Body to the world? (usually false as it won't have any shapes on construction). + * @param {object} options - An object containing the build options: + * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. + * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. + * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. + * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon. + * Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...], + * or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers. + */ + createParticle: function (x, y, mass, addToWorld, options, data) { + + if (typeof addToWorld === 'undefined') { addToWorld = false; } + + var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass); + + if (data) + { + var result = body.addPolygon(options, data); + + if (!result) + { + return false; + } + } + + if (addToWorld) + { + this.world.addBody(body.data); + } + + return body; + + }, + + + +}; + +/** +* @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.P2.prototype, "friction", { + + get: function () { + + return this.world.defaultFriction; + + }, + + set: function (value) { + + this.world.defaultFriction = value; + + } + +}); + +/** +* @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.P2.prototype, "restituion", { + + get: function () { + + return this.world.defaultRestitution; + + }, + + set: function (value) { + + this.world.defaultRestitution = value; + + } + +}); + +/** +* @name Phaser.Physics.P2#applySpringForces +* @property {boolean} applySpringForces - Enable to automatically apply spring forces each step. +*/ +Object.defineProperty(Phaser.Physics.P2.prototype, "applySpringForces", { + + get: function () { + + return this.world.applySpringForces; + + }, + + set: function (value) { + + this.world.applySpringForces = value; + + } + +}); + +/** +* @name Phaser.Physics.P2#applyDamping +* @property {boolean} applyDamping - Enable to automatically apply body damping each step. +*/ +Object.defineProperty(Phaser.Physics.P2.prototype, "applyDamping", { + + get: function () { + + return this.world.applyDamping; + + }, + + set: function (value) { + + this.world.applyDamping = value; + + } + +}); + +/** +* @name Phaser.Physics.P2#applyGravity +* @property {boolean} applyGravity - Enable to automatically apply gravity each step. +*/ +Object.defineProperty(Phaser.Physics.P2.prototype, "applyGravity", { + + get: function () { + + return this.world.applyGravity; + + }, + + set: function (value) { + + this.world.applyGravity = value; + + } + +}); + +/** +* @name Phaser.Physics.P2#solveConstraints +* @property {boolean} solveConstraints - Enable/disable constraint solving in each step. +*/ +Object.defineProperty(Phaser.Physics.P2.prototype, "solveConstraints", { + + get: function () { + + return this.world.solveConstraints; + + }, + + set: function (value) { + + this.world.solveConstraints = value; + + } + +}); + +/** +* @name Phaser.Physics.P2#time +* @property {boolean} time - The World time. +* @readonly +*/ +Object.defineProperty(Phaser.Physics.P2.prototype, "time", { + + get: function () { + + return this.world.time; + + } + +}); + +/** +* @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.P2.prototype, "emitImpactEvent", { + + get: function () { + + return this.world.emitImpactEvent; + + }, + + set: function (value) { + + this.world.emitImpactEvent = value; + + } + +}); + +/** +* @name Phaser.Physics.P2#enableBodySleeping +* @property {boolean} enableBodySleeping - Enable / disable automatic body sleeping. +*/ +Object.defineProperty(Phaser.Physics.P2.prototype, "enableBodySleeping", { + + get: function () { + + return this.world.enableBodySleeping; + + }, + + set: function (value) { + + this.world.enableBodySleeping = value; + + } + +}); + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* A PointProxy is an internal class that allows for direct getter/setter style property access to Arrays and TypedArrays. +* +* @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.P2.PointProxy = function (game, destination) { + + this.game = game; + this.destination = destination; + +}; + +Phaser.Physics.P2.PointProxy.prototype.constructor = Phaser.Physics.P2.PointProxy; + +/** +* @name Phaser.Physics.P2.PointProxy#x +* @property {number} x - The x property of this PointProxy. +*/ +Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "x", { + + get: function () { + + return this.destination[0]; + + }, + + set: function (value) { + + this.destination[0] = this.game.math.px2p(value); + + } + +}); + +/** +* @name Phaser.Physics.P2.PointProxy#y +* @property {number} y - The y property of this PointProxy. +*/ +Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "y", { + + get: function () { + + return this.destination[1]; + + }, + + set: function (value) { + + this.destination[1] = this.game.math.px2p(value); + + } + +}); + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* 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.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.P2.InversePointProxy = function (game, destination) { + + this.game = game; + this.destination = destination; + +}; + +Phaser.Physics.P2.InversePointProxy.prototype.constructor = Phaser.Physics.P2.InversePointProxy; + +/** +* @name Phaser.Physics.P2.InversePointProxy#x +* @property {number} x - The x property of this InversePointProxy. +*/ +Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "x", { + + get: function () { + + return this.destination[0]; + + }, + + set: function (value) { + + this.destination[0] = this.game.math.px2p(-value); + + } + +}); + +/** +* @name Phaser.Physics.P2.InversePointProxy#y +* @property {number} y - The y property of this InversePointProxy. +*/ +Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "y", { + + get: function () { + + return this.destination[1]; + + }, + + set: function (value) { + + this.destination[1] = this.game.math.px2p(-value); + + } + +}); + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* The Physics Body is typically linked to a single Sprite and defines properties that determine how the physics body is simulated. +* These properties affect how the body reacts to forces, what forces it generates on itself (to simulate friction), and how it reacts to collisions in the scene. +* In most cases, the properties are used to simulate physical effects. Each body also has its own property values that determine exactly how it reacts to forces and collisions in the scene. +* By default a single Rectangle shape is added to the Body that matches the dimensions of the parent Sprite. See addShape, removeShape, clearShapes to add extra shapes around the Body. +* Note: When bound to a Sprite to avoid single-pixel jitters on mobile devices we strongly recommend using Sprite sizes that are even on both axis, i.e. 128x128 not 127x127. +* +* @class Phaser.Physics.Body +* @classdesc Physics Body Constructor +* @constructor +* @param {Phaser.Game} game - Game reference to the currently running game. +* @param {Phaser.Sprite} [sprite] - The Sprite object this physics body belongs to. +* @param {number} [x=0] - The x coordinate of this Body. +* @param {number} [y=0] - The y coordinate of this Body. +* @param {number} [mass=1] - The default mass of this Body (0 = static). +*/ +Phaser.Physics.Body = function (game, sprite, x, y, mass) { + + sprite = sprite || null; + x = x || 0; + y = y || 0; + if (typeof mass === 'undefined') { mass = 1; } + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + /** + * @property {Phaser.Sprite} sprite - Reference to the parent Sprite. + */ + this.sprite = sprite; + + /** + * @property {number} type - The type of physics system this body belongs to. + */ + this.type = Phaser.Physics.P2; + + /** + * @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position. + */ + this.offset = new Phaser.Point(); + + /** + * @property {p2.Body} data - The p2 Body data. + * @protected + */ + this.data = new p2.Body({ position:[this.px2pi(x), this.px2pi(y)], mass: mass }); + this.data.parent = this; + + /** + * @property {Phaser.InversePointProxy} velocity - The velocity of the body. Set velocity.x to a negative value to move to the left, position to the right. velocity.y negative values move up, positive move down. + */ + this.velocity = new Phaser.Physics.InversePointProxy(this.game, this.data.velocity); + + /** + * @property {Phaser.InversePointProxy} force - The force applied to the body. + */ + this.force = new Phaser.Physics.InversePointProxy(this.game, this.data.force); + + /** + * @property {Phaser.Point} gravity - A locally applied gravity force to the Body. Applied directly before the world step. NOTE: Not currently implemented. + */ + this.gravity = new Phaser.Point(); + + /** + * A Body can be set to collide against the World bounds automatically if this is set to true. Otherwise it will leave the World. + * Note that this only applies if your World has bounds! The response to the collision should be managed via CollisionMaterials. + * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds? + */ + this.collideWorldBounds = true; + + /** + * @property {Phaser.Signal} onImpact - Dispatched when the shape/s of this Body impact with another. The event will be sent 2 parameters, this Body and the impact Body. + */ + this.onImpact = new Phaser.Signal(); + + /** + * @property {array} collidesWith - Array of CollisionGroups that this Bodies shapes collide with. + * @private + */ + this.collidesWith = []; + + /** + * @property {array} _bodyCallbacks - Array of Body callbacks. + * @private + */ + this._bodyCallbacks = []; + + /** + * @property {array} _bodyCallbackContext - Array of Body callback contexts. + * @private + */ + this._bodyCallbackContext = []; + + /** + * @property {array} _groupCallbacks - Array of Group callbacks. + * @private + */ + this._groupCallbacks = []; + + /** + * @property {array} _bodyCallbackContext - Array of Grouo callback contexts. + * @private + */ + this._groupCallbackContext = []; + + // Set-up the default shape + if (sprite) + { + this.setRectangleFromSprite(sprite); + + this.game.physics.addBody(this); + } + +}; + +Phaser.Physics.Body.prototype = { + + /** + * Sets a callback to be fired any time this Body impacts with the given Body. The impact test is performed against body.id values. + * The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body. + * + * @method Phaser.Physics.Body#createBodyCallback + * @param {Phaser.Physics.Body} body - The Body to send impact events for. + * @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback. + * @param {object} callbackContext - The context under which the callback will fire. + */ + createBodyCallback: function (body, callback, callbackContext) { + + this._bodyCallbacks[body.data.id] = callback; + this._bodyCallbackContext[body.data.id] = callbackContext; + + }, + + /** + * Sets a callback to be fired any time this Body impacts with the given Group. The impact test is performed against shape.collisionGroup values. + * The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body. + * This callback will only fire if this Body has been assigned a collision group. + * + * @method Phaser.Physics.Body#createGroupCallback + * @param {Phaser.Physics.CollisionGroup} group - The Group to send impact events for. + * @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback. + * @param {object} callbackContext - The context under which the callback will fire. + */ + createGroupCallback: function (group, callback, callbackContext) { + + this._groupCallbacks[group.mask] = callback; + this._groupCallbackContext[group.mask] = callbackContext; + + }, + + /** + * Gets the collision bitmask from the groups this body collides with. + * + * @method Phaser.Physics.Body#getCollisionMask + * @return {number} The bitmask. + */ + getCollisionMask: function () { + + var mask = 0; + + if (this.collideWorldBounds) + { + mask = this.game.physics.boundsCollisionGroup.mask; + } + + for (var i = 0; i < this.collidesWith.length; i++) + { + mask = mask | this.collidesWith[i].mask; + } + + return mask; + + }, + + /** + * Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified. + * This also resets the collisionMask. + * + * @method Phaser.Physics.Body#setCollisionGroup + * @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group that this Bodies shapes will use. + * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision group will be added to all Shapes in this Body. + */ + setCollisionGroup: function (group, shape) { + + var mask = this.getCollisionMask(); + + if (typeof shape === 'undefined') + { + for (var i = this.data.shapes.length - 1; i >= 0; i--) + { + this.data.shapes[i].collisionGroup = group.mask; + this.data.shapes[i].collisionMask = mask; + } + } + else + { + shape.collisionGroup = group.mask; + shapes.collisionMask = mask; + } + + }, + + /** + * Clears the collision data from the shapes in this Body. Optionally clears Group and/or Mask. + * + * @method Phaser.Physics.Body#clearCollision + * @param {boolean} [clearGroup=true] - Clear the collisionGroup value from the shape/s? + * @param {boolean} [clearMask=true] - Clear the collisionMask value from the shape/s? + * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision data will be cleared from all Shapes in this Body. + */ + clearCollision: function (clearGroup, clearMask, shape) { + + if (typeof shape === 'undefined') + { + for (var i = this.data.shapes.length - 1; i >= 0; i--) + { + if (clearGroup) + { + this.data.shapes[i].collisionGroup = null; + } + + if (clearMask) + { + this.data.shapes[i].collisionMask = null; + } + } + } + else + { + if (clearGroup) + { + shapes.collisionGroup = null; + } + + if (clearMask) + { + shapes.collisionMask = null; + } + } + + if (clearGroup) + { + this.collidesWith.length = 0; + } + + }, + + /** + * Adds the given CollisionGroup, or array of CollisionGroups, to the list of groups that this body will collide with and updates the collision masks. + * + * @method Phaser.Physics.Body#collides + * @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group or Array of Collision Groups that this Bodies shapes will collide with. + * @param {function} [callback] - Optional callback that will be triggered when this Body impacts with the given Group. + * @param {object} [callbackContext] - The context under which the callback will be called. + * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision mask will be added to all Shapes in this Body. + */ + collides: function (group, callback, callbackContext, shape) { + + if (Array.isArray(group)) + { + for (var i = 0; i < group.length; i++) + { + if (this.collidesWith.indexOf(group[i]) === -1) + { + this.collidesWith.push(group[i]); + + if (callback) + { + this.createGroupCallback(group[i], callback, callbackContext); + } + } + } + } + else + { + if (this.collidesWith.indexOf(group) === -1) + { + this.collidesWith.push(group); + + if (callback) + { + this.createGroupCallback(group, callback, callbackContext); + } + } + } + + var mask = this.getCollisionMask(); + + if (typeof shape === 'undefined') + { + for (var i = this.data.shapes.length - 1; i >= 0; i--) + { + this.data.shapes[i].collisionMask = mask; + } + } + else + { + shape.collisionMask = mask; + } + + }, + + /** + * Moves the shape offsets so their center of mass becomes the body center of mass. + * + * @method Phaser.Physics.Body#adjustCenterOfMass + */ + adjustCenterOfMass: function () { + + this.data.adjustCenterOfMass(); + + }, + + /** + * Apply damping, see http://code.google.com/p/bullet/issues/detail?id=74 for details. + * + * @method Phaser.Physics.Body#applyDamping + * @param {number} dt - Current time step. + */ + applyDamping: function (dt) { + + this.data.applyDamping(dt); + + }, + + /** + * Apply force to a world point. This could for example be a point on the RigidBody surface. Applying force this way will add to Body.force and Body.angularForce. + * + * @method Phaser.Physics.Body#applyForce + * @param {number} force - The force to add. + * @param {number} worldX - The world x point to apply the force on. + * @param {number} worldY - The world y point to apply the force on. + */ + applyForce: function (force, worldX, worldY) { + + this.data.applyForce(force, [this.px2p(worldX), this.px2p(worldY)]); + + }, + + /** + * Sets the force on the body to zero. + * + * @method Phaser.Physics.Body#setZeroForce + */ + setZeroForce: function () { + + this.data.setZeroForce(); + + }, + + /** + * If this Body is dynamic then this will zero its angular velocity. + * + * @method Phaser.Physics.Body#setZeroRotation + */ + setZeroRotation: function () { + + this.data.angularVelocity = 0; + + }, + + /** + * If this Body is dynamic then this will zero its velocity on both axis. + * + * @method Phaser.Physics.Body#setZeroVelocity + */ + setZeroVelocity: function () { + + this.data.velocity[0] = 0; + this.data.velocity[1] = 0; + + }, + + /** + * Sets the Body damping and angularDamping to zero. + * + * @method Phaser.Physics.Body#setZeroDamping + */ + setZeroDamping: function () { + + this.data.damping = 0; + this.data.angularDamping = 0; + + }, + + /** + * Transform a world point to local body frame. + * + * @method Phaser.Physics.Body#toLocalFrame + * @param {Float32Array|Array} out - The vector to store the result in. + * @param {Float32Array|Array} worldPoint - The input world vector. + */ + toLocalFrame: function (out, worldPoint) { + + return this.data.toLocalFrame(out, worldPoint); + + }, + + /** + * Transform a local point to world frame. + * + * @method Phaser.Physics.Body#toWorldFrame + * @param {Array} out - The vector to store the result in. + * @param {Array} localPoint - The input local vector. + */ + toWorldFrame: function (out, localPoint) { + + return this.data.toWorldFrame(out, localPoint); + + }, + + /** + * This will rotate the Body by the given speed to the left (counter-clockwise). + * + * @method Phaser.Physics.Body#rotateLeft + * @param {number} speed - The speed at which it should rotate. + */ + rotateLeft: function (speed) { + + this.data.angularVelocity = this.px2p(-speed); + + }, + + /** + * This will rotate the Body by the given speed to the left (clockwise). + * + * @method Phaser.Physics.Body#rotateRight + * @param {number} speed - The speed at which it should rotate. + */ + rotateRight: function (speed) { + + this.data.angularVelocity = this.px2p(speed); + + }, + + /** + * Moves the Body forwards based on its current angle and the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveForward + * @param {number} speed - The speed at which it should move forwards. + */ + moveForward: function (speed) { + + var magnitude = this.px2pi(-speed); + var angle = this.data.angle + Math.PI / 2; + + this.data.velocity[0] = magnitude * Math.cos(angle); + this.data.velocity[1] = magnitude * Math.sin(angle); + + }, + + /** + * Moves the Body backwards based on its current angle and the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveBackward + * @param {number} speed - The speed at which it should move backwards. + */ + moveBackward: function (speed) { + + var magnitude = this.px2pi(-speed); + var angle = this.data.angle + Math.PI / 2; + + this.data.velocity[0] = -(magnitude * Math.cos(angle)); + this.data.velocity[1] = -(magnitude * Math.sin(angle)); + + }, + + /** + * Applies a force to the Body that causes it to 'thrust' forwards, based on its current angle and the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#thrust + * @param {number} speed - The speed at which it should thrust. + */ + thrust: function (speed) { + + var magnitude = this.px2pi(-speed); + var angle = this.data.angle + Math.PI / 2; + + this.data.force[0] += magnitude * Math.cos(angle); + this.data.force[1] += magnitude * Math.sin(angle); + + }, + + /** + * Applies a force to the Body that causes it to 'thrust' backwards (in reverse), based on its current angle and the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#rever + * @param {number} speed - The speed at which it should reverse. + */ + reverse: function (speed) { + + var magnitude = this.px2pi(-speed); + var angle = this.data.angle + Math.PI / 2; + + this.data.force[0] -= magnitude * Math.cos(angle); + this.data.force[1] -= magnitude * Math.sin(angle); + + }, + + /** + * If this Body is dynamic then this will move it to the left by setting its x velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveLeft + * @param {number} speed - The speed at which it should move to the left, in pixels per second. + */ + moveLeft: function (speed) { + + this.data.velocity[0] = this.px2pi(-speed); + + }, + + /** + * If this Body is dynamic then this will move it to the right by setting its x velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveRight + * @param {number} speed - The speed at which it should move to the right, in pixels per second. + */ + moveRight: function (speed) { + + this.data.velocity[0] = this.px2pi(speed); + + }, + + /** + * If this Body is dynamic then this will move it up by setting its y velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveUp + * @param {number} speed - The speed at which it should move up, in pixels per second. + */ + moveUp: function (speed) { + + this.data.velocity[1] = this.px2pi(-speed); + + }, + + /** + * If this Body is dynamic then this will move it down by setting its y velocity to the given speed. + * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). + * + * @method Phaser.Physics.Body#moveDown + * @param {number} speed - The speed at which it should move down, in pixels per second. + */ + moveDown: function (speed) { + + this.data.velocity[1] = this.px2pi(speed); + + }, + + /** + * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished. + * + * @method Phaser.Physics.Body#preUpdate + * @protected + */ + preUpdate: function () { + }, + + /** + * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished. + * + * @method Phaser.Physics.Body#postUpdate + * @protected + */ + postUpdate: function () { + + this.sprite.x = this.p2pxi(this.data.position[0]); + this.sprite.y = this.p2pxi(this.data.position[1]); + + if (!this.fixedRotation) + { + this.sprite.rotation = this.data.angle; + } + + }, + + /** + * Resets the Body force, velocity (linear and angular) and rotation. Optionally resets damping and mass. + * + * @method Phaser.Physics.Body#reset + * @param {number} x - The new x position of the Body. + * @param {number} y - The new x position of the Body. + * @param {boolean} [resetDamping=false] - Resets the linear and angular damping. + * @param {boolean} [resetMass=false] - Sets the Body mass back to 1. + */ + reset: function (x, y, resetDamping, resetMass) { + + if (typeof resetDamping === 'undefined') { resetDamping = false; } + if (typeof resetMass === 'undefined') { resetMass = false; } + + this.setZeroForce(); + this.setZeroVelocity(); + this.setZeroRotation(); + + if (resetDamping) + { + this.setZeroDamping(); + } + + if (resetMass) + { + this.mass = 1; + } + + this.x = x; + this.y = y; + + }, + + /** + * Adds this physics body to the world. + * + * @method Phaser.Physics.Body#addToWorld + */ + addToWorld: function () { + + if (this.data.world !== this.game.physics.world) + { + this.game.physics.addBody(this); + } + + }, + + /** + * Removes this physics body from the world. + * + * @method Phaser.Physics.Body#removeFromWorld + */ + removeFromWorld: function () { + + if (this.data.world === this.game.physics.world) + { + this.game.physics.removeBody(this); + } + + }, + + /** + * Destroys this Body and all references it holds to other objects. + * + * @method Phaser.Physics.Body#destroy + */ + destroy: function () { + + this.removeFromWorld(); + + this.clearShapes(); + + this.sprite = null; + + /* + this.collideCallback = null; + this.collideCallbackContext = null; + */ + + }, + + /** + * Removes all Shapes from this Body. + * + * @method Phaser.Physics.Body#clearShapes + */ + clearShapes: function () { + + for (var i = this.data.shapes.length - 1; i >= 0; i--) + { + var shape = this.data.shapes[i]; + this.data.removeShape(shape); + } + + }, + + /** + * Add a shape to the body. You can pass a local transform when adding a shape, so that the shape gets an offset and an angle relative to the body center of mass. + * Will automatically update the mass properties and bounding radius. + * + * @method Phaser.Physics.Body#addShape + * @param {*} shape - The shape to add to the body. + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Circle|p2.Rectangle|p2.Plane|p2.Line|p2.Particle} The shape that was added to the body. + */ + addShape: function (shape, offsetX, offsetY, rotation) { + + if (typeof offsetX === 'undefined') { offsetX = 0; } + if (typeof offsetY === 'undefined') { offsetY = 0; } + if (typeof rotation === 'undefined') { rotation = 0; } + + this.data.addShape(shape, [this.px2pi(offsetX), this.px2pi(offsetY)], rotation); + + return shape; + + }, + + /** + * Adds a Circle shape to this Body. You can control the offset from the center of the body and the rotation. + * + * @method Phaser.Physics.Body#addCircle + * @param {number} radius - The radius of this circle (in pixels) + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Circle} The Circle shape that was added to the Body. + */ + addCircle: function (radius, offsetX, offsetY, rotation) { + + var shape = new p2.Circle(this.px2p(radius)); + + return this.addShape(shape, offsetX, offsetY, rotation); + + }, + + /** + * Adds a Rectangle shape to this Body. You can control the offset from the center of the body and the rotation. + * + * @method Phaser.Physics.Body#addRectangle + * @param {number} width - The width of the rectangle in pixels. + * @param {number} height - The height of the rectangle in pixels. + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Rectangle} The Rectangle shape that was added to the Body. + */ + addRectangle: function (width, height, offsetX, offsetY, rotation) { + + var shape = new p2.Rectangle(this.px2p(width), this.px2p(height)); + + return this.addShape(shape, offsetX, offsetY, rotation); + + }, + + /** + * Adds a Plane shape to this Body. The plane is facing in the Y direction. You can control the offset from the center of the body and the rotation. + * + * @method Phaser.Physics.Body#addPlane + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Plane} The Plane shape that was added to the Body. + */ + addPlane: function (offsetX, offsetY, rotation) { + + var shape = new p2.Plane(); + + return this.addShape(shape, offsetX, offsetY, rotation); + + }, + + /** + * Adds a Particle shape to this Body. You can control the offset from the center of the body and the rotation. + * + * @method Phaser.Physics.Body#addParticle + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Particle} The Particle shape that was added to the Body. + */ + addParticle: function (offsetX, offsetY, rotation) { + + var shape = new p2.Particle(); + + return this.addShape(shape, offsetX, offsetY, rotation); + + }, + + /** + * Adds a Line shape to this Body. + * The line shape is along the x direction, and stretches from [-length/2, 0] to [length/2,0]. + * You can control the offset from the center of the body and the rotation. + * + * @method Phaser.Physics.Body#addLine + * @param {number} length - The length of this line (in pixels) + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Line} The Line shape that was added to the Body. + */ + addLine: function (length, offsetX, offsetY, rotation) { + + var shape = new p2.Line(this.px2p(length)); + + return this.addShape(shape, offsetX, offsetY, rotation); + + }, + + /** + * Adds a Capsule shape to this Body. + * You can control the offset from the center of the body and the rotation. + * + * @method Phaser.Physics.Body#addCapsule + * @param {number} length - The distance between the end points in pixels. + * @param {number} radius - Radius of the capsule in radians. + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Capsule} The Capsule shape that was added to the Body. + */ + addCapsule: function (length, radius, offsetX, offsetY, rotation) { + + var shape = new p2.Capsule(this.px2p(length), radius); + + return this.addShape(shape, offsetX, offsetY, rotation); + + }, + + /** + * Reads a polygon shape path, and assembles convex shapes from that and puts them at proper offset points. The shape must be simple and without holes. + * This function expects the x.y values to be given in pixels. If you want to provide them at p2 world scales then call Body.data.fromPolygon directly. + * + * @method Phaser.Physics.Body#addPolygon + * @param {object} options - An object containing the build options: + * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. + * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. + * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. + * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon. + * Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...], + * or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers. + * @return {boolean} True on success, else false. + */ + addPolygon: function (options, points) { + + options = options || {}; + + points = Array.prototype.slice.call(arguments, 1); + + var path = []; + + // Did they pass in a single array of points? + if (points.length === 1 && Array.isArray(points[0])) + { + path = points[0].slice(0); + } + else if (Array.isArray(points[0])) + { + path = points[0].slice(0); + // for (var i = 0, len = points[0].length; i < len; i += 2) + // { + // path.push([points[0][i], points[0][i + 1]]); + // } + } + else if (typeof points[0] === 'number') + { + // console.log('addPolygon --- We\'ve a list of numbers'); + // We've a list of numbers + for (var i = 0, len = points.length; i < len; i += 2) + { + path.push([points[i], points[i + 1]]); + } + } + + // console.log('addPolygon PATH pre'); + // console.log(path[1]); + // console.table(path); + + // top and tail + var idx = path.length - 1; + + if ( path[idx][0] === path[0][0] && path[idx][1] === path[0][1] ) + { + path.pop(); + } + + // Now process them into p2 values + for (var p = 0; p < path.length; p++) + { + path[p][0] = this.px2pi(path[p][0]); + path[p][1] = this.px2pi(path[p][1]); + } + + // console.log('addPolygon PATH POST'); + // console.log(path[1]); + // console.table(path); + + return this.data.fromPolygon(path, options); + + }, + + /** + * Remove a shape from the body. Will automatically update the mass properties and bounding radius. + * + * @method Phaser.Physics.Body#removeShape + * @param {p2.Circle|p2.Rectangle|p2.Plane|p2.Line|p2.Particle} shape - The shape to remove from the body. + * @return {boolean} True if the shape was found and removed, else false. + */ + removeShape: function (shape) { + + return this.data.removeShape(shape); + + }, + + /** + * Clears any previously set shapes. Then creates a new Circle shape and adds it to this Body. + * + * @method Phaser.Physics.Body#setCircle + * @param {number} radius - The radius of this circle (in pixels) + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + */ + setCircle: function (radius, offsetX, offsetY, rotation) { + + this.clearShapes(); + + this.addCircle(radius, offsetX, offsetY, rotation); + + }, + + /** + * Clears any previously set shapes. The creates a new Rectangle shape at the given size and offset, and adds it to this Body. + * If you wish to create a Rectangle to match the size of a Sprite or Image see Body.setRectangleFromSprite. + * + * @method Phaser.Physics.Body#setRectangle + * @param {number} [width=16] - The width of the rectangle in pixels. + * @param {number} [height=16] - The height of the rectangle in pixels. + * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. + * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. + * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. + * @return {p2.Rectangle} The Rectangle shape that was added to the Body. + */ + setRectangle: function (width, height, offsetX, offsetY, rotation) { + + if (typeof width === 'undefined') { width = 16; } + if (typeof height === 'undefined') { height = 16; } + + this.clearShapes(); + + return this.addRectangle(width, height, offsetX, offsetY, rotation); + + }, + + /** + * Clears any previously set shapes. + * Then creates a Rectangle shape sized to match the dimensions and orientation of the Sprite given. + * If no Sprite is given it defaults to using the parent of this Body. + * + * @method Phaser.Physics.Body#setRectangleFromSprite + * @param {Phaser.Sprite|Phaser.Image} [sprite] - The Sprite on which the Rectangle will get its dimensions. + * @return {p2.Rectangle} The Rectangle shape that was added to the Body. + */ + setRectangleFromSprite: function (sprite) { + + if (typeof sprite === 'undefined') { sprite = this.sprite; } + + this.clearShapes(); + + return this.addRectangle(sprite.width, sprite.height, 0, 0, sprite.rotation); + + }, + + /** + * Adds the given Material to all Shapes that belong to this Body. + * If you only wish to apply it to a specific Shape in this Body then provide that as the 2nd parameter. + * + * @method Phaser.Physics.Body#setMaterial + * @param {Phaser.Physics.Material} material - The Material that will be applied. + * @param {p2.Shape} [shape] - An optional Shape. If not provided the Material will be added to all Shapes in this Body. + */ + setMaterial: function (material, shape) { + + if (typeof shape === 'undefined') + { + for (var i = this.data.shapes.length - 1; i >= 0; i--) + { + this.data.shapes[i].material = material; + } + } + else + { + shape.material = material; + } + + }, + + /** + * Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body. + * + * @method Phaser.Physics.Body#loadPolygon + * @param {string} key - The key of the Physics Data file as stored in Game.Cache. + * @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from. + * @param {object} options - An object containing the build options. Note that this isn't used if the data file contains multiple shapes. + * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. + * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. + * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. + * @return {boolean} True on success, else false. + */ + loadPolygon: function (key, object, options) { + + var data = this.game.cache.getPhysicsData(key, object); + + if (data.length === 1) + { + var temp = []; + + data = data.pop() + // We've a list of numbers + for (var i = 0, len = data.shape.length; i < len; i += 2) + { + temp.push([data.shape[i], data.shape[i + 1]]); + } + + return this.addPolygon(options, temp); + } + else + { + // We've multiple Convex shapes, they should be CCW automatically + var cm = p2.vec2.create(); + + for (var i = 0; i < data.length; i++) + { + var vertices = []; + + for (var s = 0; s < data[i].shape.length; s += 2) + { + vertices.push([ this.px2pi(data[i].shape[s]), this.px2pi(data[i].shape[s + 1]) ]); + } + + var c = new p2.Convex(vertices); + + // Move all vertices so its center of mass is in the local center of the convex + for (var j = 0; j !== c.vertices.length; j++) + { + var v = c.vertices[j]; + p2.vec2.sub(v, v, c.centerOfMass); + } + + p2.vec2.scale(cm, c.centerOfMass, 1); + + cm[0] -= this.px2pi(this.sprite.width / 2); + cm[1] -= this.px2pi(this.sprite.height / 2); + + c.updateTriangles(); + c.updateCenterOfMass(); + c.updateBoundingRadius(); + + this.data.addShape(c, cm); + } + + // this.data.adjustCenterOfMass(); + this.data.aabbNeedsUpdate = true; + + return true; + } + + return false; + + }, + + /** + * Reads the physics data from a physics data file stored in the Game.Cache. + * It will add the shape data to this Body, as well as set the density (mass), friction and bounce (restitution) values. + * + * @method Phaser.Physics.Body#loadPolygon + * @param {string} key - The key of the Physics Data file as stored in Game.Cache. + * @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from. + * @param {object} options - An object containing the build options: + * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. + * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. + * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. + * @return {boolean} True on success, else false. + */ + loadData: function (key, object, options) { + + var data = game.cache.getPhysicsData(key, object); + + if (data && data.shape) + { + this.mass = data.density; + // set friction + bounce here + this.loadPolygon(key, object); + } + + }, + + /** + * Convert p2 physics value (meters) to pixel scale. + * + * @method Phaser.Physics.Body#p2px + * @param {number} v - The value to convert. + * @return {number} The scaled value. + */ + p2px: function (v) { + + return v *= 20; + + }, + + /** + * Convert pixel value to p2 physics scale (meters). + * + * @method Phaser.Physics.Body#px2p + * @param {number} v - The value to convert. + * @return {number} The scaled value. + */ + px2p: function (v) { + + return v * 0.05; + + }, + + /** + * Convert p2 physics value (meters) to pixel scale and inverses it. + * + * @method Phaser.Physics.Body#p2pxi + * @param {number} v - The value to convert. + * @return {number} The scaled value. + */ + p2pxi: function (v) { + + return v *= -20; + + }, + + /** + * Convert pixel value to p2 physics scale (meters) and inverses it. + * + * @method Phaser.Physics.Body#px2pi + * @param {number} v - The value to convert. + * @return {number} The scaled value. + */ + px2pi: function (v) { + + return v * -0.05; + + } + +}; + +Phaser.Physics.Body.prototype.constructor = Phaser.Physics.Body; + +/** +* @name Phaser.Physics.Body#static +* @property {boolean} static - Returns true if the Body is static. Setting Body.static to 'false' will make it dynamic. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "static", { + + get: function () { + + return (this.data.motionState === Phaser.STATIC); + + }, + + set: function (value) { + + if (value && this.data.motionState !== Phaser.STATIC) + { + this.data.motionState = Phaser.STATIC; + this.mass = 0; + } + else if (!value && this.data.motionState === Phaser.STATIC) + { + this.data.motionState = Phaser.DYNAMIC; + + if (this.mass === 0) + { + this.mass = 1; + } + } + + } + +}); + +/** +* @name Phaser.Physics.Body#dynamic +* @property {boolean} dynamic - Returns true if the Body is dynamic. Setting Body.dynamic to 'false' will make it static. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "dynamic", { + + get: function () { + + return (this.data.motionState === Phaser.DYNAMIC); + + }, + + set: function (value) { + + if (value && this.data.motionState !== Phaser.DYNAMIC) + { + this.data.motionState = Phaser.DYNAMIC; + + if (this.mass === 0) + { + this.mass = 1; + } + } + else if (!value && this.data.motionState === Phaser.DYNAMIC) + { + this.data.motionState = Phaser.STATIC; + this.mass = 0; + } + + } + +}); + +/** +* @name Phaser.Physics.Body#kinematic +* @property {boolean} kinematic - Returns true if the Body is kinematic. Setting Body.kinematic to 'false' will make it static. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "kinematic", { + + get: function () { + + return (this.data.motionState === Phaser.KINEMATIC); + + }, + + set: function (value) { + + if (value && this.data.motionState !== Phaser.KINEMATIC) + { + this.data.motionState = Phaser.KINEMATIC; + this.mass = 4; + } + else if (!value && this.data.motionState === Phaser.KINEMATIC) + { + this.data.motionState = Phaser.STATIC; + this.mass = 0; + } + + } + +}); + +/** +* @name Phaser.Physics.Body#allowSleep +* @property {boolean} allowSleep - +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "allowSleep", { + + get: function () { + + return this.data.allowSleep; + + }, + + set: function (value) { + + if (value !== this.data.allowSleep) + { + this.data.allowSleep = value; + } + + } + +}); + +/** +* The angle of the Body 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 Body.angle = 450 is the same as Body.angle = 90. +* If you wish to work in radians instead of degrees use the property Body.rotation instead. Working in radians is faster as it doesn't have to convert values. +* +* @name Phaser.Physics.Body#angle +* @property {number} angle - The angle of this Body in degrees. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "angle", { + + get: function() { + + return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.data.angle)); + + }, + + set: function(value) { + + this.data.angle = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); + + } + +}); + +/** +* Damping is specified as a value between 0 and 1, which is the proportion of velocity lost per second. +* @name Phaser.Physics.Body#angularDamping +* @property {number} angularDamping - The angular damping acting acting on the body. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "angularDamping", { + + get: function () { + + return this.data.angularDamping; + + }, + + set: function (value) { + + this.data.angularDamping = value; + + } + +}); + +/** +* @name Phaser.Physics.Body#angularForce +* @property {number} angularForce - The angular force acting on the body. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "angularForce", { + + get: function () { + + return this.data.angularForce; + + }, + + set: function (value) { + + this.data.angularForce = value; + + } + +}); + +/** +* @name Phaser.Physics.Body#angularVelocity +* @property {number} angularVelocity - The angular velocity of the body. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "angularVelocity", { + + get: function () { + + return this.data.angularVelocity; + + }, + + set: function (value) { + + this.data.angularVelocity = value; + + } + +}); + +/** +* Damping is specified as a value between 0 and 1, which is the proportion of velocity lost per second. +* @name Phaser.Physics.Body#damping +* @property {number} damping - The linear damping acting on the body in the velocity direction. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "damping", { + + get: function () { + + return this.data.damping; + + }, + + set: function (value) { + + this.data.damping = value; + + } + +}); + +/** +* @name Phaser.Physics.Body#fixedRotation +* @property {boolean} fixedRotation - +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "fixedRotation", { + + get: function () { + + return this.data.fixedRotation; + + }, + + set: function (value) { + + if (value !== this.data.fixedRotation) + { + this.data.fixedRotation = value; + // update anything? + } + + } + +}); + +/** +* @name Phaser.Physics.Body#inertia +* @property {number} inertia - The inertia of the body around the Z axis.. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "inertia", { + + get: function () { + + return this.data.inertia; + + }, + + set: function (value) { + + this.data.inertia = value; + + } + +}); + +/** +* @name Phaser.Physics.Body#mass +* @property {number} mass - +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "mass", { + + get: function () { + + return this.data.mass; + + }, + + set: function (value) { + + if (value !== this.data.mass) + { + this.data.mass = value; + this.data.updateMassProperties(); + + if (value === 0) + { + // this.static = true; + } + } + + } + +}); + +/** +* @name Phaser.Physics.Body#motionState +* @property {number} motionState - The type of motion this body has. Should be one of: Body.STATIC (the body does not move), Body.DYNAMIC (body can move and respond to collisions) and Body.KINEMATIC (only moves according to its .velocity). +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "motionState", { + + get: function () { + + return this.data.motionState; + + }, + + set: function (value) { + + if (value !== this.data.motionState) + { + this.data.motionState = value; + // update? + } + + } + +}); + +/** +* The angle of the Body in radians. +* If you wish to work in degrees instead of radians use the Body.angle property instead. Working in radians is faster as it doesn't have to convert values. +* +* @name Phaser.Physics.Body#rotation +* @property {number} rotation - The angle of this Body in radians. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "rotation", { + + get: function() { + + return this.data.angle; + + }, + + set: function(value) { + + this.data.angle = value; + + } + +}); + +/** +* @name Phaser.Physics.Body#sleepSpeedLimit +* @property {number} sleepSpeedLimit - . +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "sleepSpeedLimit", { + + get: function () { + + return this.data.sleepSpeedLimit; + + }, + + set: function (value) { + + this.data.sleepSpeedLimit = value; + + } + +}); + +/** +* @name Phaser.Physics.Body#x +* @property {number} x - The x coordinate of this Body. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "x", { + + get: function () { + + return this.p2pxi(this.data.position[0]); + + }, + + set: function (value) { + + this.data.position[0] = this.px2pi(value); + + } + +}); + +/** +* @name Phaser.Physics.Body#y +* @property {number} y - The y coordinate of this Body. +*/ +Object.defineProperty(Phaser.Physics.Body.prototype, "y", { + + get: function () { + + return this.p2pxi(this.data.position[1]); + + }, + + set: function (value) { + + this.data.position[1] = this.px2pi(value); + + } + +}); + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Creates a spring, connecting two bodies. +* +* @class Phaser.Physics.P2.Spring +* @classdesc Physics Spring Constructor +* @constructor +* @param {Phaser.Game} game - A reference to the current game. +* @param {p2.Body} bodyA - First connected body. +* @param {p2.Body} bodyB - Second connected body. +* @param {number} [restLength=1] - Rest length of the spring. A number > 0. +* @param {number} [stiffness=100] - Stiffness of the spring. A number >= 0. +* @param {number} [damping=1] - Damping of the spring. A number >= 0. +* @param {Array} [worldA] - Where to hook the spring to body A, in world coordinates, i.e. [32, 32]. +* @param {Array} [worldB] - Where to hook the spring to body B, in world coordinates, i.e. [32, 32]. +* @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.P2.Spring = function (game, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + if (typeof restLength === 'undefined') { restLength = 1; } + if (typeof stiffness === 'undefined') { stiffness = 100; } + if (typeof damping === 'undefined') { damping = 1; } + + var options = { + restLength: restLength, + stiffness: stiffness, + damping: damping + }; + + if (typeof worldA !== 'undefined' && worldA !== null) + { + options.worldAnchorA = [ game.math.px2p(worldA[0]), game.math.px2p(worldA[1]) ]; + } + + if (typeof worldB !== 'undefined' && worldB !== null) + { + options.worldAnchorB = [ game.math.px2p(worldB[0]), game.math.px2p(worldB[1]) ]; + } + + if (typeof localA !== 'undefined' && localA !== null) + { + options.localAnchorA = [ game.math.px2p(localA[0]), game.math.px2p(localA[1]) ]; + } + + if (typeof localB !== 'undefined' && localB !== null) + { + options.localAnchorB = [ game.math.px2p(localB[0]), game.math.px2p(localB[1]) ]; + } + + p2.Spring.call(this, bodyA, bodyB, options); + +} + +Phaser.Physics.P2.Spring.prototype = Object.create(p2.Spring.prototype); +Phaser.Physics.P2.Spring.prototype.constructor = Phaser.Physics.P2.Spring; + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* \o/ ~ "Because I'm a Material girl" +* +* @class Phaser.Physics.P2.Material +* @classdesc Physics Material Constructor +* @constructor +*/ +Phaser.Physics.P2.Material = function (name) { + + /** + * @property {string} name - The user defined name given to this Material. + * @default + */ + this.name = name; + + p2.Material.call(this); + +} + +Phaser.Physics.P2.Material.prototype = Object.create(p2.Material.prototype); +Phaser.Physics.P2.Material.prototype.constructor = Phaser.Physics.P2.Material; + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Defines a physics material +* +* @class Phaser.Physics.P2.ContactMaterial +* @classdesc Physics ContactMaterial Constructor +* @constructor +* @param {Phaser.Physics.P2.Material} materialA +* @param {Phaser.Physics.P2.Material} materialB +* @param {object} [options] +*/ +Phaser.Physics.P2.ContactMaterial = function (materialA, materialB, options) { + + /** + * @property {number} id - The contact material identifier. + */ + + /** + * @property {Phaser.Physics.P2.Material} materialA - First material participating in the contact material. + */ + + /** + * @property {Phaser.Physics.P2.Material} materialB - First second participating in the contact material. + */ + + /** + * @property {number} [friction=0.3] - Friction to use in the contact of these two materials. + */ + + /** + * @property {number} [restitution=0.0] - Restitution to use in the contact of these two materials. + */ + + /** + * @property {number} [stiffness=1e7] - Stiffness of the resulting ContactEquation that this ContactMaterial generate. + */ + + /** + * @property {number} [relaxation=3] - Relaxation of the resulting ContactEquation that this ContactMaterial generate. + */ + + /** + * @property {number} [frictionStiffness=1e7] - Stiffness of the resulting FrictionEquation that this ContactMaterial generate. + */ + + /** + * @property {number} [frictionRelaxation=3] - Relaxation of the resulting FrictionEquation that this ContactMaterial generate. + */ + + /** + * @property {number} [surfaceVelocity=0] - Will add surface velocity to this material. If bodyA rests on top if bodyB, and the surface velocity is positive, bodyA will slide to the right. + */ + + p2.ContactMaterial.call(this, materialA, materialB, options); + +} + +Phaser.Physics.P2.ContactMaterial.prototype = Object.create(p2.ContactMaterial.prototype); +Phaser.Physics.P2.ContactMaterial.prototype.constructor = Phaser.Physics.P2.ContactMaterial; + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Collision Group +* +* @class Phaser.Physics.P2.CollisionGroup +* @classdesc Physics Collision Group Constructor +* @constructor +*/ +Phaser.Physics.P2.CollisionGroup = function (bitmask) { + + /** + * @property {number} mask - The CollisionGroup bitmask. + */ + this.mask = bitmask; + +} diff --git a/build/custom/p2.min.js b/build/custom/p2.min.js index 269906df1..0af762a19 100644 --- a/build/custom/p2.min.js +++ b/build/custom/p2.min.js @@ -1,5 +1,5 @@ /* p2.js custom build for Phaser v2.0.0 - http://phaser.io - @photonstorm - (c) 2014 Photon Storm Ltd. */ -!function(a){"object"==typeof exports?module.exports=a():"function"==typeof define&&define.amd?define(a):"undefined"!=typeof window?window.p2=a():"undefined"!=typeof global?self.p2=a():"undefined"!=typeof self&&(self.p2=a())}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0&&(e=1/Math.sqrt(e),a[0]=b[0]*e,a[1]=b[1]*e),a},d.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]},d.cross=function(a,b,c){var d=b[0]*c[1]-b[1]*c[0];return a[0]=a[1]=0,a[2]=d,a},d.lerp=function(a,b,c,d){var e=b[0],f=b[1];return a[0]=e+d*(c[0]-e),a[1]=f+d*(c[1]-f),a},d.transformMat2=function(a,b,c){var d=b[0],e=b[1];return a[0]=d*c[0]+e*c[1],a[1]=d*c[2]+e*c[3],a},d.forEach=function(){var a=new Float32Array(2);return function(b,c,d,e,f,g){var h,i;for(c||(c=2),d||(d=0),i=e?Math.min(e*c+d,b.length):b.length,h=d;i>h;h+=c)a[0]=b[h],a[1]=b[h+1],f(a,a,g),b[h]=a[0],b[h+1]=a[1];return b}}(),d.str=function(a){return"vec2("+a[0]+", "+a[1]+")"},"undefined"!=typeof c&&(c.vec2=d)},{}],3:[function(a,b){function c(){}var d=a("./Scalar");b.exports=c,c.lineInt=function(a,b,c){c=c||0;var e,f,g,h,i,j,k,l=[0,0];return e=a[1][1]-a[0][1],f=a[0][0]-a[1][0],g=e*a[0][0]+f*a[0][1],h=b[1][1]-b[0][1],i=b[0][0]-b[1][0],j=h*b[0][0]+i*b[0][1],k=e*i-h*f,d.eq(k,0,c)||(l[0]=(i*g-f*j)/k,l[1]=(e*j-h*g)/k),l},c.segmentsIntersect=function(a,b,c,d){var e=b[0]-a[0],f=b[1]-a[1],g=d[0]-c[0],h=d[1]-c[1];if(g*f-h*e==0)return!1;var i=(e*(c[1]-a[1])+f*(a[0]-c[0]))/(g*f-h*e),j=(g*(a[1]-c[1])+h*(c[0]-a[0]))/(h*e-g*f);return i>=0&&1>=i&&j>=0&&1>=j}},{"./Scalar":6}],4:[function(a,b){function c(){}b.exports=c,c.area=function(a,b,c){return(b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])},c.left=function(a,b,d){return c.area(a,b,d)>0},c.leftOn=function(a,b,d){return c.area(a,b,d)>=0},c.right=function(a,b,d){return c.area(a,b,d)<0},c.rightOn=function(a,b,d){return c.area(a,b,d)<=0};var d=[],e=[];c.collinear=function(a,b,f,g){if(g){var h=d,i=e;h[0]=b[0]-a[0],h[1]=b[1]-a[1],i[0]=f[0]-b[0],i[1]=f[1]-b[1];var j=h[0]*i[0]+h[1]*i[1],k=Math.sqrt(h[0]*h[0]+h[1]*h[1]),l=Math.sqrt(i[0]*i[0]+i[1]*i[1]),m=Math.acos(j/(k*l));return g>m}return 0==c.area(a,b,f)},c.sqdist=function(a,b){var c=b[0]-a[0],d=b[1]-a[1];return c*c+d*d}},{}],5:[function(a,b){function c(){this.vertices=[]}function d(a,b,c,d,e){e=e||0;var f=b[1]-a[1],h=a[0]-b[0],i=f*a[0]+h*a[1],j=d[1]-c[1],k=c[0]-d[0],l=j*c[0]+k*c[1],m=f*k-j*h;return g.eq(m,0,e)?[0,0]:[(k*i-h*l)/m,(f*l-j*i)/m]}var e=a("./Line"),f=a("./Point"),g=a("./Scalar");b.exports=c,c.prototype.at=function(a){var b=this.vertices,c=b.length;return b[0>a?a%c+c:a%c]},c.prototype.first=function(){return this.vertices[0]},c.prototype.last=function(){return this.vertices[this.vertices.length-1]},c.prototype.clear=function(){this.vertices.length=0},c.prototype.append=function(a,b,c){if("undefined"==typeof b)throw new Error("From is not given!");if("undefined"==typeof c)throw new Error("To is not given!");if(b>c-1)throw new Error("lol1");if(c>a.vertices.length)throw new Error("lol2");if(0>b)throw new Error("lol3");for(var d=b;c>d;d++)this.vertices.push(a.vertices[d])},c.prototype.makeCCW=function(){for(var a=0,b=this.vertices,c=1;cb[a][0])&&(a=c);f.left(this.at(a-1),this.at(a),this.at(a+1))||this.reverse()},c.prototype.reverse=function(){for(var a=[],b=0,c=this.vertices.length;b!==c;b++)a.push(this.vertices.pop());this.vertices=a},c.prototype.isReflex=function(a){return f.right(this.at(a-1),this.at(a),this.at(a+1))};var h=[],i=[];c.prototype.canSee=function(a,b){var c,d,g=h,j=i;if(f.leftOn(this.at(a+1),this.at(a),this.at(b))&&f.rightOn(this.at(a-1),this.at(a),this.at(b)))return!1;d=f.sqdist(this.at(a),this.at(b));for(var k=0;k!==this.vertices.length;++k)if((k+1)%this.vertices.length!==a&&k!==a&&f.leftOn(this.at(a),this.at(b),this.at(k+1))&&f.rightOn(this.at(a),this.at(b),this.at(k))&&(g[0]=this.at(a),g[1]=this.at(b),j[0]=this.at(k),j[1]=this.at(k+1),c=e.lineInt(g,j),f.sqdist(this.at(a),c)a)for(var f=a;b>=f;f++)e.vertices.push(this.vertices[f]);else{for(var f=0;b>=f;f++)e.vertices.push(this.vertices[f]);for(var f=a;f0?this.slice(a):[this]},c.prototype.slice=function(a){if(0==a.length)return[this];if(a instanceof Array&&a.length&&a[0]instanceof Array&&2==a[0].length&&a[0][0]instanceof Array){for(var b=[this],c=0;cc;c++)if(e.segmentsIntersect(a[b],a[b+1],a[c],a[c+1]))return!1;for(var b=1;bh)return console.warn("quickDecomp: max level ("+h+") reached."),a;for(var x=0;xo&&(n=o,k=l,r=y))),f.left(v.at(x+1),v.at(x),v.at(y+1))&&f.rightOn(v.at(x+1),v.at(x),v.at(y))&&(l=d(v.at(x+1),v.at(x),v.at(y),v.at(y+1)),f.left(v.at(x-1),v.at(x),l)&&(o=f.sqdist(v.vertices[x],l),m>o&&(m=o,j=l,q=y)));if(r==(q+1)%this.vertices.length)l[0]=(k[0]+j[0])/2,l[1]=(k[1]+j[1])/2,e.push(l),q>x?(t.append(v,x,q+1),t.vertices.push(l),u.vertices.push(l),0!=r&&u.append(v,r,v.vertices.length),u.append(v,0,x+1)):(0!=x&&t.append(v,x,v.vertices.length),t.append(v,0,q+1),t.vertices.push(l),u.vertices.push(l),u.append(v,r,x+1));else{if(r>q&&(q+=this.vertices.length),p=Number.MAX_VALUE,r>q)return a;for(var y=r;q>=y;++y)f.leftOn(v.at(x-1),v.at(x),v.at(y))&&f.rightOn(v.at(x+1),v.at(x),v.at(y))&&(o=f.sqdist(v.at(x),v.at(y)),p>o&&(p=o,s=y%this.vertices.length));s>x?(t.append(v,x,s+1),0!=s&&u.append(v,s,w.length),u.append(v,0,x+1)):(0!=x&&t.append(v,x,w.length),t.append(v,0,s+1),u.append(v,s,x+1))}return t.vertices.length3&&c>=0;--c)f.collinear(this.at(c-1),this.at(c),this.at(c+1),a)&&(this.vertices.splice(c%this.vertices.length,1),c--,b++);return b}},{"./Line":3,"./Point":4,"./Scalar":6}],6:[function(a,b){function c(){}b.exports=c,c.eq=function(a,b,c){return c=c||0,Math.abs(a-b) (http://steffe.se)",keywords:["p2.js","p2","physics","engine","2d"],main:"./src/p2.js",engines:{node:"*"},repository:{type:"git",url:"https://github.com/schteppe/p2.js.git"},bugs:{url:"https://github.com/schteppe/p2.js/issues"},licenses:[{type:"MIT"}],devDependencies:{jshint:"latest",nodeunit:"latest",grunt:"~0.4.0","grunt-contrib-jshint":"~0.1.1","grunt-contrib-nodeunit":"~0.1.2","grunt-contrib-concat":"~0.1.3","grunt-contrib-uglify":"*","grunt-browserify":"*",browserify:"*"},dependencies:{underscore:"*","poly-decomp":"git://github.com/schteppe/poly-decomp.js","gl-matrix":"2.0.0",jsonschema:"*"}}},{}],9:[function(a,b){function c(a){this.lowerBound=d.create(),a&&a.lowerBound&&d.copy(this.lowerBound,a.lowerBound),this.upperBound=d.create(),a&&a.upperBound&&d.copy(this.upperBound,a.upperBound)}{var d=a("../math/vec2");a("../utils/Utils")}b.exports=c;var e=d.create();c.prototype.setFromPoints=function(a,b,c){var f=this.lowerBound,g=this.upperBound;d.set(f,Number.MAX_VALUE,Number.MAX_VALUE),d.set(g,-Number.MAX_VALUE,-Number.MAX_VALUE);for(var h=0;hj;j++)i[j]>g[j]&&(g[j]=i[j]),i[j]b;b++)a.lowerBound[b]this.upperBound[b]&&(this.upperBound[b]=a.upperBound[b])},c.prototype.overlaps=function(a){var b=this.lowerBound,c=this.upperBound,d=a.lowerBound,e=a.upperBound;return(d[0]<=c[0]&&c[0]<=e[0]||b[0]<=e[0]&&e[0]<=c[0])&&(d[1]<=c[1]&&c[1]<=e[1]||b[1]<=e[1]&&e[1]<=c[1])}},{"../math/vec2":33,"../utils/Utils":50}],10:[function(a,b){function c(a){this.type=a,this.result=[],this.world=null}var d=a("../math/vec2"),e=a("../objects/Body");b.exports=c,c.prototype.setWorld=function(a){this.world=a},c.prototype.getCollisionPairs=function(){throw new Error("getCollisionPairs must be implemented in a subclass!")};var f=d.create();c.boundingRadiusCheck=function(a,b){d.sub(f,a.position,b.position);var c=d.squaredLength(f),e=a.boundingRadius+b.boundingRadius;return e*e>=c},c.aabbCheck=function(a,b){return a.aabbNeedsUpdate&&a.updateAABB(),b.aabbNeedsUpdate&&b.updateAABB(),a.aabb.overlaps(b.aabb)},c.canCollide=function(a,b){return a.motionState==e.STATIC&&b.motionState==e.STATIC?!1:a.motionState==e.KINEMATIC&&b.motionState==e.STATIC||a.motionState==e.STATIC&&b.motionState==e.KINEMATIC?!1:a.motionState==e.KINEMATIC&&b.motionState==e.KINEMATIC?!1:a.sleepState==e.SLEEPING&&b.sleepState==e.SLEEPING?!1:!0},c.NAIVE=1,c.SAP=2},{"../math/vec2":33,"../objects/Body":34}],11:[function(a,b){function d(a,b,c,d,e,f){h.apply(this),e=e||10,f=f||10,this.binsizeX=(b-a)/e,this.binsizeY=(d-c)/f,this.nx=e,this.ny=f,this.xmin=a,this.ymin=c,this.xmax=b,this.ymax=d}{var e=a("../shapes/Circle"),f=a("../shapes/Plane"),g=a("../shapes/Particle"),h=a("../collision/Broadphase");a("../math/vec2")}b.exports=d,d.prototype=new h,d.prototype.getBinIndex=function(a,b){var c=this.nx,d=this.ny,e=this.xmin,f=this.ymin,g=this.xmax,h=this.ymax,i=Math.floor(c*(a-e)/(g-e)),j=Math.floor(d*(b-f)/(h-f));return i*d+j},d.prototype.getCollisionPairs=function(a){for(var b=[],d=a.bodies,i=i=d.length,j=this.binsizeX,k=this.binsizeY,l=[],m=nx*ny,n=0;m>n;n++)l.push([]);for(var o=nx/(xmax-xmin),p=ny/(ymax-ymin),n=0;n!==i;n++){var q=d[n],r=q.shape;if(void 0!==r)if(r instanceof e)for(var s=q.position[0],t=q.position[1],u=r.radius,v=Math.floor(o*(s-u-xmin)),w=Math.floor(p*(t-u-ymin)),x=Math.floor(o*(s+u-xmin)),y=Math.floor(p*(t+u-ymin)),z=v;x>=z;z++)for(var A=w;y>=A;A++){var B=z,C=A;B*(ny-1)+C>=0&&m>B*(ny-1)+C&&l[B*(ny-1)+C].push(q)}else{if(!(r instanceof f))throw new Error("Shape not supported in GridBroadphase!");if(0==q.angle)for(var t=q.position[1],z=0;z!==m&&t>ymin+k*(z-1);z++)for(var A=0;nx>A;A++){var B=A,C=Math.floor(p*(k*z-ymin));l[B*(ny-1)+C].push(q)}else if(q.angle==.5*Math.PI)for(var s=q.position[0],z=0;z!==m&&s>xmin+j*(z-1);z++)for(var A=0;ny>A;A++){var C=A,B=Math.floor(o*(j*z-xmin));l[B*(ny-1)+C].push(q)}else for(var z=0;z!==m;z++)l[z].push(q)}}for(var n=0;n!==m;n++)for(var D=l[n],z=0,E=D.length;z!==E;z++)for(var q=D[z],r=q.shape,A=0;A!==z;A++){var F=D[A],G=F.shape;r instanceof e?G instanceof e?c=h.circleCircle(q,F):G instanceof g?c=h.circleParticle(q,F):G instanceof f&&(c=h.circlePlane(q,F)):r instanceof g?G instanceof e&&(c=h.circleParticle(F,q)):r instanceof f&&G instanceof e&&(c=h.circlePlane(F,q))}return b}},{"../collision/Broadphase":10,"../math/vec2":33,"../shapes/Circle":38,"../shapes/Particle":42,"../shapes/Plane":43}],12:[function(a,b){function c(){d.call(this,d.NAIVE),this.useBoundingBoxes=!1}{var d=(a("../shapes/Circle"),a("../shapes/Plane"),a("../shapes/Shape"),a("../shapes/Particle"),a("../collision/Broadphase"));a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.getCollisionPairs=function(a){var b,c,e,f,g=a.bodies,h=this.result,i=this.useBoundingBoxes?d.aabbCheck:d.boundingRadiusCheck;for(h.length=0,b=0,Ncolliding=g.length;b!==Ncolliding;b++)for(e=g[b],c=0;b>c;c++)f=g[c],d.canCollide(e,f)&&i(e,f)&&h.push(e,f);return h}},{"../collision/Broadphase":10,"../math/vec2":33,"../shapes/Circle":38,"../shapes/Particle":42,"../shapes/Plane":43,"../shapes/Shape":45}],13:[function(a,b){function c(){this.contactEquations=[],this.frictionEquations=[],this.enableFriction=!0,this.slipForce=10,this.frictionCoefficient=.3,this.surfaceVelocity=0,this.reuseObjects=!0,this.reusableContactEquations=[],this.reusableFrictionEquations=[],this.restitution=0,this.collidingBodiesLastStep={keys:[]}}function d(a){for(var b=0,c=a.keys.length;c>b;b++)delete a[a.keys[b]];a.keys.length=0}function e(a,b){g.set(a.vertices[0],.5*-b.length,-b.radius),g.set(a.vertices[1],.5*b.length,-b.radius),g.set(a.vertices[2],.5*b.length,b.radius),g.set(a.vertices[3],.5*-b.length,b.radius)}function f(a,b,c,d){for(var e=Q,f=R,j=S,k=T,l=a,m=b.vertices,n=null,o=0;o!==m.length+1;o++){var p=m[o%m.length],q=m[(o+1)%m.length];g.rotate(e,p,d),g.rotate(f,q,d),i(e,e,c),i(f,f,c),h(j,e,l),h(k,f,l);var r=g.crossLength(j,k);if(null===n&&(n=r),0>=r*n)return!1;n=r}return!0}var g=a("../math/vec2"),h=g.sub,i=g.add,j=g.dot,k=a("../utils/Utils"),l=a("../equations/ContactEquation"),m=a("../equations/FrictionEquation"),n=a("../shapes/Circle"),o=a("../shapes/Shape"),p=a("../objects/Body"),q=a("../shapes/Rectangle");b.exports=c;var r=g.fromValues(0,1),s=g.fromValues(0,0),t=g.fromValues(0,0),u=g.fromValues(0,0),v=g.fromValues(0,0),w=g.fromValues(0,0),x=g.fromValues(0,0),y=g.fromValues(0,0),z=g.fromValues(0,0),A=g.fromValues(0,0),B=g.fromValues(0,0),C=g.fromValues(0,0),D=g.fromValues(0,0),E=g.fromValues(0,0),F=g.fromValues(0,0),G=g.fromValues(0,0),H=g.fromValues(0,0),I=g.fromValues(0,0),J=g.fromValues(0,0),K=[];c.prototype.collidedLastStep=function(a,b){var c=a.id,d=b.id;if(c>d){var e=c;c=d,d=e}return!!this.collidingBodiesLastStep[c+" "+d]},c.prototype.reset=function(){d(this.collidingBodiesLastStep);for(var a=0;a!==this.contactEquations.length;a++){var b=this.contactEquations[a],c=b.bi.id,e=b.bj.id;if(c>e){var f=c;c=e,e=f}var g=c+" "+e;this.collidingBodiesLastStep[g]||(this.collidingBodiesLastStep[g]=!0,this.collidingBodiesLastStep.keys.push(g))}if(this.reuseObjects){var h=this.contactEquations,i=this.frictionEquations,j=this.reusableFrictionEquations,l=this.reusableContactEquations;k.appendArray(l,h),k.appendArray(j,i)}this.contactEquations.length=this.frictionEquations.length=0},c.prototype.createContactEquation=function(a,b,c,d){var e=this.reusableContactEquations.length?this.reusableContactEquations.pop():new l(a,b);return e.bi=a,e.bj=b,e.shapeA=c,e.shapeB=d,e.restitution=this.restitution,e.firstImpact=!this.collidedLastStep(a,b),e.enabled=!0,a.allowSleep&&a.motionState==p.DYNAMIC&&b.motionState!=p.STATIC&&b.sleepState!==p.SLEEPY&&a.wakeUp(),b.allowSleep&&b.motionState==p.DYNAMIC&&a.motionState!=p.STATIC&&a.sleepState!==p.SLEEPY&&b.wakeUp(),e},c.prototype.createFrictionEquation=function(a,b,c,d){var e=this.reusableFrictionEquations.length?this.reusableFrictionEquations.pop():new m(a,b);return e.bi=a,e.bj=b,e.shapeA=c,e.shapeB=d,e.setSlipForce(this.slipForce),e.frictionCoefficient=this.frictionCoefficient,e.relativeVelocity=this.surfaceVelocity,e.enabled=!0,e},c.prototype.createFrictionFromContact=function(a){var b=this.createFrictionEquation(a.bi,a.bj,a.shapeA,a.shapeB);return g.copy(b.ri,a.ri),g.copy(b.rj,a.rj),g.rotate(b.t,a.ni,-Math.PI/2),b.contactEquation=a,b},c.prototype[o.LINE|o.CONVEX]=c.prototype.convexLine=function(a,b,c,d,e,f,g,h,i){return i?!1:0},c.prototype[o.LINE|o.RECTANGLE]=c.prototype.lineRectangle=function(a,b,c,d,e,f,g,h,i){return i?!1:0};var L=new q(1,1),M=g.create();c.prototype[o.CAPSULE|o.CONVEX]=c.prototype[o.CAPSULE|o.RECTANGLE]=c.prototype.convexCapsule=function(a,b,c,d,f,h,i,j,k){var l=M;g.set(l,h.length/2,0),g.rotate(l,l,j),g.add(l,l,i);var m=this.circleConvex(f,h,l,j,a,b,c,d,k,h.radius);g.set(l,-h.length/2,0),g.rotate(l,l,j),g.add(l,l,i);var n=this.circleConvex(f,h,l,j,a,b,c,d,k,h.radius);if(k&&(m||n))return!0;var o=L;e(o,h);var p=this.convexConvex(a,b,c,d,f,o,i,j,k);return p+m+n},c.prototype[o.CAPSULE|o.LINE]=c.prototype.lineCapsule=function(a,b,c,d,e,f,g,h,i){return i?!1:0};var N=g.create(),O=g.create(),P=new q(1,1);c.prototype[o.CAPSULE|o.CAPSULE]=c.prototype.capsuleCapsule=function(a,b,c,d,f,h,i,j,k){for(var l=N,m=O,n=0,o=0;2>o;o++){g.set(l,(0==o?-1:1)*b.length/2,0),g.rotate(l,l,d),g.add(l,l,c);for(var p=0;2>p;p++){g.set(m,(0==p?-1:1)*h.length/2,0),g.rotate(m,m,j),g.add(m,m,i);var q=this.circleCircle(a,b,l,d,f,h,m,j,k,b.radius,h.radius);if(k&&q)return!0;n+=q}}var r=P;e(r,b);var s=this.convexCapsule(a,r,c,d,f,h,i,j,k);if(k&&s)return!0;n+=s,e(r,h);var t=this.convexCapsule(f,r,i,j,a,b,c,d,k);return k&&t?!0:n+=t},c.prototype[o.LINE|o.LINE]=c.prototype.lineLine=function(a,b,c,d,e,f,g,h,i){return i?!1:0},c.prototype[o.PLANE|o.LINE]=c.prototype.planeLine=function(a,b,c,d,e,f,k,l,m){var n=s,o=t,p=u,q=v,B=w,C=x,D=y,E=z,F=A,G=K;numContacts=0,g.set(n,-f.length/2,0),g.set(o,f.length/2,0),g.rotate(p,n,l),g.rotate(q,o,l),i(p,p,k),i(q,q,k),g.copy(n,p),g.copy(o,q),h(B,o,n),g.normalize(C,B),g.rotate(F,C,-Math.PI/2),g.rotate(E,r,d),G[0]=n,G[1]=o;for(var H=0;HJ){if(m)return!0;var L=this.createContactEquation(a,e,b,f);numContacts++,g.copy(L.ni,E),g.normalize(L.ni,L.ni),g.scale(D,E,J),h(L.ri,I,D),h(L.ri,L.ri,a.position),h(L.rj,I,k),i(L.rj,L.rj,k),h(L.rj,L.rj,e.position),this.contactEquations.push(L),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(L))}}return numContacts},c.prototype[o.PARTICLE|o.CAPSULE]=c.prototype.particleCapsule=function(a,b,c,d,e,f,g,h,i){return this.circleLine(a,b,c,d,e,f,g,h,i,f.radius,0)},c.prototype[o.CIRCLE|o.LINE]=c.prototype.circleLine=function(a,b,c,d,e,f,k,l,m,n,o){var p=f,q=l,r=e,G=k,H=c,I=a,J=b,n=n||0,o="undefined"!=typeof o?o:J.radius,L=s,M=t,N=u,O=v,P=w,Q=x,R=y,S=z,T=A,U=B,V=C,W=D,X=E,Y=F,Z=K;g.set(S,-p.length/2,0),g.set(T,p.length/2,0),g.rotate(U,S,q),g.rotate(V,T,q),i(U,U,G),i(V,V,G),g.copy(S,U),g.copy(T,V),h(Q,T,S),g.normalize(R,Q),g.rotate(P,R,-Math.PI/2),h(W,H,S);var $=j(W,P);if(h(O,S,G),h(X,H,G),Math.abs($)ab&&bb>_){if(m)return!0;var cb=this.createContactEquation(I,r,b,f);return g.scale(cb.ni,L,-1),g.normalize(cb.ni,cb.ni),g.scale(cb.ri,cb.ni,o),i(cb.ri,cb.ri,H),h(cb.ri,cb.ri,I.position),h(cb.rj,N,G),i(cb.rj,cb.rj,G),h(cb.rj,cb.rj,r.position),this.contactEquations.push(cb),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(cb)),1}}Z[0]=S,Z[1]=T;for(var db=0;dbW&&(g.copy(Q,O),S=W,g.scale(N,K,W),g.add(N,N,O),R=!0)}}if(R){if(m)return!0;var X=this.createContactEquation(y,q,b,j);return g.sub(X.ni,Q,x),g.normalize(X.ni,X.ni),g.scale(X.ri,X.ni,n),i(X.ri,X.ri,x),h(X.ri,X.ri,y.position),h(X.rj,N,r),i(X.rj,X.rj,r),h(X.rj,X.rj,q.position),this.contactEquations.push(X),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(X)),1}if(n>0)for(var T=0;TW&&(Q=W,g.scale(N,H,W),g.add(N,N,z),g.copy(P,H),R=!0)}if(R){var X=this.createContactEquation(A,q,b,k);return g.scale(X.ni,P,-1),g.normalize(X.ni,X.ni),g.set(X.ri,0,0),i(X.ri,X.ri,z),h(X.ri,X.ri,A.position),h(X.rj,N,r),i(X.rj,X.rj,r),h(X.rj,X.rj,q.position),this.contactEquations.push(X),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(X)),1}return 0},c.prototype[o.CIRCLE]=c.prototype.circleCircle=function(a,b,c,d,e,f,j,k,l,m,n){var o=a,p=b,q=c,r=e,t=f,u=j,v=s,m=m||p.radius,n=n||t.radius;h(v,c,j);var w=m+n;if(g.squaredLength(v)>w*w)return 0;if(l)return!0;var x=this.createContactEquation(o,r,b,f);return h(x.ni,u,q),g.normalize(x.ni,x.ni),g.scale(x.ri,x.ni,m),g.scale(x.rj,x.ni,-n),i(x.ri,x.ri,q),h(x.ri,x.ri,o.position),i(x.rj,x.rj,u),h(x.rj,x.rj,r.position),this.contactEquations.push(x),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(x)),1},c.prototype[o.PLANE|o.CONVEX]=c.prototype[o.PLANE|o.RECTANGLE]=c.prototype.planeConvex=function(a,b,c,d,e,f,k,l,m){var n=e,o=k,p=f,q=l,v=a,w=b,x=c,y=d,z=s,A=t,B=u,C=0;g.rotate(A,r,y);for(var D=0;D=2)break}}return C},c.prototype.convexPlane=function(a,b,c,d,e,f,g,h,i){return console.warn("Narrowphase.prototype.convexPlane is deprecated. Use planeConvex instead!"),this.planeConvex(e,f,g,h,a,b,c,d,i)},c.prototype[o.PARTICLE|o.PLANE]=c.prototype.particlePlane=function(a,b,c,d,e,f,i,k,l){var m=a,n=c,o=e,p=i,q=k,u=s,v=t;q=q||0,h(u,n,p),g.rotate(v,r,q);var w=j(u,v);if(w>0)return 0;if(l)return!0;var x=this.createContactEquation(o,m,f,b);return g.copy(x.ni,v),g.scale(u,x.ni,w),h(x.ri,n,u),h(x.ri,x.ri,o.position),h(x.rj,n,m.position),this.contactEquations.push(x),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(x)),1},c.prototype[o.CIRCLE|o.PARTICLE]=c.prototype.circleParticle=function(a,b,c,d,e,f,j,k,l){var m=a,n=b,o=c,p=e,q=j,r=s;if(h(r,q,o),g.squaredLength(r)>n.radius*n.radius)return 0;if(l)return!0;var t=this.createContactEquation(m,p,b,f);return g.copy(t.ni,r),g.normalize(t.ni,t.ni),g.scale(t.ri,t.ni,n.radius),i(t.ri,t.ri,o),h(t.ri,t.ri,m.position),h(t.rj,q,p.position),this.contactEquations.push(t),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(t)),1};{var U=new n(1),V=g.create(),W=g.create();g.create()}c.prototype[o.PLANE|o.CAPSULE]=c.prototype.planeCapsule=function(a,b,c,d,e,f,h,j,k){var l=V,m=W,n=U;g.set(l,-f.length/2,0),g.rotate(l,l,j),i(l,l,h),g.set(m,f.length/2,0),g.rotate(m,m,j),i(m,m,h),n.radius=f.radius;var o=this.circlePlane(e,n,l,0,a,b,c,d,k),p=this.circlePlane(e,n,m,0,a,b,c,d,k);return k?o||p:o+p},c.prototype.capsulePlane=function(a,b,c,d,e,f,g,h,i){return console.warn("Narrowphase.prototype.capsulePlane() is deprecated. Use .planeCapsule() instead!"),this.planeCapsule(e,f,g,h,a,b,c,d,i)},c.prototype[o.CIRCLE|o.PLANE]=c.prototype.circlePlane=function(a,b,c,d,e,f,k,l,m){var n=a,o=b,p=c,q=e,v=k,w=l;w=w||0;var x=s,y=t,z=u;h(x,p,v),g.rotate(y,r,w);var A=j(y,x);if(A>o.radius)return 0;if(m)return!0;var B=this.createContactEquation(q,n,f,b);return g.copy(B.ni,y),g.scale(B.rj,B.ni,-o.radius),i(B.rj,B.rj,p),h(B.rj,B.rj,n.position),g.scale(z,B.ni,A),h(B.ri,x,z),i(B.ri,B.ri,v),h(B.ri,B.ri,q.position),this.contactEquations.push(B),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(B)),1},c.convexPrecision=1e-10,c.prototype[o.CONVEX]=c.prototype[o.CONVEX|o.RECTANGLE]=c.prototype[o.RECTANGLE]=c.prototype.convexConvex=function(a,b,d,e,f,k,l,m,n,o){var p=s,q=t,r=u,x=v,B=w,C=y,D=z,E=A,F=0,o=o||c.convexPrecision,G=c.findSeparatingAxis(b,d,e,k,l,m,p);if(!G)return 0;h(D,l,d),j(p,D)>0&&g.scale(p,p,-1);var H=c.getClosestEdge(b,e,p,!0),I=c.getClosestEdge(k,m,p);if(-1==H||-1==I)return 0;for(var J=0;2>J;J++){var K=H,L=I,M=b,N=k,O=d,P=l,Q=e,R=m,S=a,T=f;if(0==J){var U;U=K,K=L,L=U,U=M,M=N,N=U,U=O,O=P,P=U,U=Q,Q=R,R=U,U=S,S=T,T=U}for(var V=L;L+2>V;V++){var W=N.vertices[(V+N.vertices.length)%N.vertices.length];g.rotate(q,W,R),i(q,q,P);for(var X=0,Y=K-1;K+2>Y;Y++){var Z=M.vertices[(Y+M.vertices.length)%M.vertices.length],$=M.vertices[(Y+1+M.vertices.length)%M.vertices.length];g.rotate(r,Z,Q),g.rotate(x,$,Q),i(r,r,O),i(x,x,O),h(B,x,r),g.rotate(E,B,-Math.PI/2),g.normalize(E,E),h(D,q,r);var _=j(E,D);o>=_&&X++}if(3==X){if(n)return!0;var ab=this.createContactEquation(S,T,M,N);F++;var Z=M.vertices[K%M.vertices.length],$=M.vertices[(K+1)%M.vertices.length];g.rotate(r,Z,Q),g.rotate(x,$,Q),i(r,r,O),i(x,x,O),h(B,x,r),g.rotate(ab.ni,B,-Math.PI/2),g.normalize(ab.ni,ab.ni),h(D,q,r);var _=j(ab.ni,D);g.scale(C,ab.ni,_),h(ab.ri,q,O),h(ab.ri,ab.ri,C),i(ab.ri,ab.ri,O),h(ab.ri,ab.ri,S.position),h(ab.rj,q,P),i(ab.rj,ab.rj,P),h(ab.rj,ab.rj,T.position),this.contactEquations.push(ab),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(ab))}}}return F};var X=g.fromValues(0,0);c.projectConvexOntoAxis=function(a,b,c,d,e){var f,h,i=null,k=null,l=X;g.rotate(l,d,-c);for(var m=0;mi)&&(i=h),(null===k||k>h)&&(k=h);if(k>i){var n=k;k=i,i=n}var o=j(b,d);g.set(e,k+o,i+o)};var Y=g.fromValues(0,0),Z=g.fromValues(0,0),$=g.fromValues(0,0),_=g.fromValues(0,0),ab=g.fromValues(0,0),bb=g.fromValues(0,0);c.findSeparatingAxis=function(a,b,d,e,f,i,j){for(var k=null,l=!1,m=!1,n=Y,o=Z,p=$,q=_,r=ab,s=bb,t=0;2!==t;t++){var u=a,v=d;1===t&&(u=e,v=i);for(var w=0;w!==u.vertices.length;w++){g.rotate(o,u.vertices[w],v),g.rotate(p,u.vertices[(w+1)%u.vertices.length],v),h(n,p,o),g.rotate(q,n,-Math.PI/2),g.normalize(q,q),c.projectConvexOntoAxis(a,b,d,q,r),c.projectConvexOntoAxis(e,f,i,q,s);var x=r,y=s,z=!1;r[0]>s[0]&&(y=r,x=s,z=!0);var A=y[0]-x[1];l=0>A,(null===k||A>k)&&(g.copy(j,q),k=A,m=l)}}return m};var cb=g.fromValues(0,0),db=g.fromValues(0,0),eb=g.fromValues(0,0);c.getClosestEdge=function(a,b,c,d){var e=cb,f=db,i=eb;g.rotate(e,c,-b),d&&g.scale(e,e,-1);for(var k=-1,l=a.vertices.length,m=Math.PI/2,n=0;n!==l;n++){h(f,a.vertices[(n+1)%l],a.vertices[n%l]),g.rotate(i,f,-m),g.normalize(i,i);var o=j(i,e);(-1==k||o>maxDot)&&(k=n%l,maxDot=o)}return k};var fb=g.create(),gb=g.create(),hb=g.create(),ib=g.create(),jb=g.create(),kb=g.create(),lb=g.create();c.prototype[o.CIRCLE|o.HEIGHTFIELD]=c.prototype.circleHeightfield=function(a,b,c,d,e,f,j,k,l,m){var n=f.data,m=m||b.radius,o=f.elementWidth,p=gb,q=fb,r=jb,s=lb,t=kb,u=hb,v=ib,w=Math.floor((c[0]-m-j[0])/o),x=Math.ceil((c[0]+m-j[0])/o);0>w&&(w=0),x>=n.length&&(x=n.length-1);for(var y=n[w],z=n[x],A=w;x>A;A++)n[A]y&&(y=n[A]); -if(c[1]-m>y)return l?!1:0;c[1]+mA;A++){g.set(u,A*o,n[A]),g.set(v,(A+1)*o,n[A+1]),g.add(u,u,j),g.add(v,v,j),g.sub(t,v,u),g.rotate(t,t,Math.PI/2),g.normalize(t,t),g.scale(q,t,-m),g.add(q,q,c),g.sub(p,q,u);var D=g.dot(p,t);if(q[0]>=u[0]&&q[0]=D&&(C===!1||Math.abs(D)0)for(var A=w;x>=A;A++)if(g.set(u,A*o,n[A]),g.add(u,u,j),g.sub(p,c,u),g.squaredLength(p)c;c++)this.root.insert(a[c]);else this.root.insert(a)},c.prototype.clear=function(){this.root.clear()},c.prototype.retrieve=function(a){var b=this.root.retrieve(a).slice(0);return b},c.prototype.getCollisionPairs=function(a){var b=[];this.insert(a.bodies);for(var c=0;c!==a.bodies.length;c++)for(var d=a.bodies[c],e=this.retrieve(d),f=0,h=e.length;f!==h;f++){var i=e[f];if(d!==i){for(var j=!1,k=0,l=b.length;l>k;k+=2){var m=b[k],n=b[k+1];if(m==i&&n==d||n==i&&m==d){j=!0;break}}!j&&g.boundingRadiusCheck(d,i)&&b.push(d,i)}}return this.clear(),b},d.prototype.classConstructor=d,d.prototype.children=null,d.prototype.depth=0,d.prototype.maxChildren=4,d.prototype.maxDepth=4,d.TOP_LEFT=0,d.TOP_RIGHT=1,d.BOTTOM_LEFT=2,d.BOTTOM_RIGHT=3,d.prototype.insert=function(a){if(this.nodes.length){var b=this.findIndex(a);return void this.nodes[b].insert(a)}this.children.push(a);var c=this.children.length;if(!(this.depth>=this.maxDepth)&&c>this.maxChildren){this.subdivide();for(var d=0;c>d;d++)this.insert(this.children[d]);this.children.length=0}},d.prototype.retrieve=function(a){if(this.nodes.length){var b=this.findIndex(a);return this.nodes[b].retrieve(a)}return this.children},d.prototype.findIndex=function(a){var b=this.bounds,c=a.position[0]-a.boundingRadius>b.x+b.width/2?!1:!0,e=a.position[1]-a.boundingRadius>b.y+b.height/2?!1:!0;a instanceof f&&(c=e=!1);var g=d.TOP_LEFT;return c?e||(g=d.BOTTOM_LEFT):g=e?d.TOP_RIGHT:d.BOTTOM_RIGHT,g},d.prototype.subdivide=function(){var a=this.depth+1,b=this.bounds.x,c=this.bounds.y,e=this.bounds.width/2,f=this.bounds.height/2,g=b+e,h=c+f;this.nodes[d.TOP_LEFT]=new this.classConstructor({x:b,y:c,width:e,height:f},a),this.nodes[d.TOP_RIGHT]=new this.classConstructor({x:g,y:c,width:e,height:f},a),this.nodes[d.BOTTOM_LEFT]=new this.classConstructor({x:b,y:h,width:e,height:f},a),this.nodes[d.BOTTOM_RIGHT]=new this.classConstructor({x:g,y:h,width:e,height:f},a)},d.prototype.clear=function(){this.children.length=0;for(var a=this.nodes.length,b=0;a>b;b++)this.nodes[b].clear();this.nodes.length=0},e.prototype=new d,e.prototype.classConstructor=e,e.prototype.stuckChildren=null,e.prototype.out=[],e.prototype.insert=function(a){if(this.nodes.length){var b=this.findIndex(a),c=this.nodes[b];return void(!(a instanceof f)&&a.position[0]-a.boundingRadius>=c.bounds.x&&a.position[0]+a.boundingRadius<=c.bounds.x+c.bounds.width&&a.position[1]-a.boundingRadius>=c.bounds.y&&a.position[1]+a.boundingRadius<=c.bounds.y+c.bounds.height?this.nodes[b].insert(a):this.stuckChildren.push(a))}this.children.push(a);var d=this.children.length;if(this.depththis.maxChildren){this.subdivide();for(var e=0;d>e;e++)this.insert(this.children[e]);this.children.length=0}},e.prototype.getChildren=function(){return this.children.concat(this.stuckChildren)},e.prototype.retrieve=function(a){var b=this.out;if(b.length=0,this.nodes.length){var c=this.findIndex(a);b.push.apply(b,this.nodes[c].retrieve(a))}return b.push.apply(b,this.stuckChildren),b.push.apply(b,this.children),b},e.prototype.clear=function(){this.stuckChildren.length=0,this.children.length=0;var a=this.nodes.length;if(a){for(var b=0;a>b;b++)this.nodes[b].clear();this.nodes.length=0}}},{"../collision/Broadphase":10,"../shapes/Plane":43}],15:[function(a,b){function c(){e.call(this,e.SAP),this.axisListX=[],this.axisListY=[],this.world=null;var a=this.axisListX,b=this.axisListY;this._addBodyHandler=function(c){a.push(c.body),b.push(c.body)},this._removeBodyHandler=function(c){var d=a.indexOf(c.body);-1!==d&&a.splice(d,1),d=b.indexOf(c.body),-1!==d&&b.splice(d,1)}}{var d=(a("../shapes/Circle"),a("../shapes/Plane"),a("../shapes/Shape"),a("../shapes/Particle"),a("../utils/Utils")),e=a("../collision/Broadphase");a("../math/vec2")}b.exports=c,c.prototype=new e,c.prototype.setWorld=function(a){this.axisListX.length=this.axisListY.length=0,d.appendArray(this.axisListX,a.bodies),d.appendArray(this.axisListY,a.bodies),a.off("addBody",this._addBodyHandler).off("removeBody",this._removeBodyHandler),a.on("addBody",this._addBodyHandler).on("removeBody",this._removeBodyHandler),this.world=a},c.sortAxisListX=function(a){for(var b=1,c=a.length;c>b;b++){for(var d=a[b],e=b-1;e>=0&&!(a[e].aabb.lowerBound[0]<=d.aabb.lowerBound[0]);e--)a[e+1]=a[e];a[e+1]=d}return a},c.sortAxisListY=function(a){for(var b=1,c=a.length;c>b;b++){for(var d=a[b],e=b-1;e>=0&&!(a[e].aabb.lowerBound[1]<=d.aabb.lowerBound[1]);e--)a[e+1]=a[e];a[e+1]=d}return a};var f={keys:[]};c.prototype.getCollisionPairs=function(){{var a,b,d=this.axisListX,g=this.axisListY,h=this.result;this.axisIndex}for(h.length=0,a=0;a!==d.length;a++){var i=d[a];i.aabbNeedsUpdate&&i.updateAABB()}for(c.sortAxisListX(d),c.sortAxisListY(g),a=0,N=d.length;a!==N;a++){var j=d[a];for(b=a+1;N>b;b++){var k=d[b];if(!c.checkBounds(j,k,0))break;if(e.canCollide(j,k)){var l=j.idb;b++){var k=g[b];if(!c.checkBounds(j,k,1))break;if(e.canCollide(j,k)){var l=j.idc)g.scale(e.ni,i,-1),g.sub(e.ri,j,h.position),g.sub(e.rj,k,o.position),g.scale(n,i,c),g.add(e.ri,e.ri,n),-1==a.indexOf(e)&&a.push(e);else{var u=a.indexOf(e);-1!=u&&a.splice(u,1)}if(this.lowerLimitEnabled&&d>s)g.scale(f.ni,i,1),g.sub(f.ri,j,h.position),g.sub(f.rj,k,o.position),g.scale(n,i,d),g.sub(f.rj,f.rj,n),-1==a.indexOf(f)&&a.push(f);else{var u=a.indexOf(f);-1!=u&&a.splice(u,1)}},c.prototype.enableMotor=function(){this.motorEnabled||(this.equations.push(this.motorEquation),this.motorEnabled=!0)},c.prototype.disableMotor=function(){if(this.motorEnabled){var a=this.equations.indexOf(this.motorEquation);this.equations.splice(a,1),this.motorEnabled=!1}}},{"../equations/ContactEquation":23,"../equations/Equation":24,"../equations/RotationalLockEquation":26,"../math/vec2":33,"./Constraint":16}],21:[function(a,b){function c(a,b,c,n,o){d.call(this,a,c,d.REVOLUTE),o=this.maxForce="undefined"!=typeof o?o:Number.MAX_VALUE,this.pivotA=b,this.pivotB=n;var p=this.equations=[new e(a,c,-o,o),new e(a,c,-o,o)],q=p[0],r=p[1];q.computeGq=function(){return h.rotate(i,b,a.angle),h.rotate(j,n,c.angle),h.add(m,c.position,j),h.sub(m,m,a.position),h.sub(m,m,i),h.dot(m,k)},r.computeGq=function(){return h.rotate(i,b,a.angle),h.rotate(j,n,c.angle),h.add(m,c.position,j),h.sub(m,m,a.position),h.sub(m,m,i),h.dot(m,l)},r.minForce=q.minForce=-o,r.maxForce=q.maxForce=o,this.motorEquation=new f(a,c),this.motorEnabled=!1,this.angle=0,this.lowerLimitEnabled=!1,this.upperLimitEnabled=!1,this.lowerLimit=0,this.upperLimit=0,this.upperLimitEquation=new g(a,c),this.lowerLimitEquation=new g(a,c),this.upperLimitEquation.minForce=0,this.lowerLimitEquation.maxForce=0}var d=a("./Constraint"),e=a("../equations/Equation"),f=a("../equations/RotationalVelocityEquation"),g=a("../equations/RotationalLockEquation"),h=a("../math/vec2");b.exports=c;var i=h.create(),j=h.create(),k=h.fromValues(1,0),l=h.fromValues(0,1),m=h.create();c.prototype=new d,c.prototype.update=function(){var a=this.bodyA,b=this.bodyB,c=this.pivotA,d=this.pivotB,e=this.equations,f=(e[0],e[1],e[0]),g=e[1],m=this.upperLimit,n=this.lowerLimit,o=this.upperLimitEquation,p=this.lowerLimitEquation,q=this.angle=b.angle-a.angle;if(this.upperLimitEnabled&&q>m)o.angle=m,-1==e.indexOf(o)&&e.push(o);else{var r=e.indexOf(o);-1!=r&&e.splice(r,1)}if(this.lowerLimitEnabled&&n>q)p.angle=n,-1==e.indexOf(p)&&e.push(p);else{var r=e.indexOf(p);-1!=r&&e.splice(r,1)}h.rotate(i,c,a.angle),h.rotate(j,d,b.angle),f.G[0]=-1,f.G[1]=0,f.G[2]=-h.crossLength(i,k),f.G[3]=1,f.G[4]=0,f.G[5]=h.crossLength(j,k),g.G[0]=0,g.G[1]=-1,g.G[2]=-h.crossLength(i,l),g.G[3]=0,g.G[4]=1,g.G[5]=h.crossLength(j,l)},c.prototype.enableMotor=function(){this.motorEnabled||(this.equations.push(this.motorEquation),this.motorEnabled=!0)},c.prototype.disableMotor=function(){if(this.motorEnabled){var a=this.equations.indexOf(this.motorEquation);this.equations.splice(a,1),this.motorEnabled=!1}},c.prototype.motorIsEnabled=function(){return!!this.motorEnabled},c.prototype.setMotorSpeed=function(a){if(this.motorEnabled){var b=this.equations.indexOf(this.motorEquation);this.equations[b].relativeVelocity=a}},c.prototype.getMotorSpeed=function(){return this.motorEnabled?this.motorEquation.relativeVelocity:!1}},{"../equations/Equation":24,"../equations/RotationalLockEquation":26,"../equations/RotationalVelocityEquation":27,"../math/vec2":33,"./Constraint":16}],22:[function(a,b){function c(a,b,c){c=c||{},d.call(this,a,b,-Number.MAX_VALUE,Number.MAX_VALUE),this.angle=c.angle||0,this.ratio="number"==typeof c.ratio?c.ratio:1,this.setRatio(this.ratio)}{var d=a("./Equation");a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.constructor=c,c.prototype.computeGq=function(){return this.ratio*this.bi.angle-this.bj.angle+this.angle},c.prototype.setRatio=function(a){var b=this.G;b[2]=a,b[5]=-1,this.ratio=a}},{"../math/vec2":33,"./Equation":24}],23:[function(a,b){function c(a,b){d.call(this,a,b,0,Number.MAX_VALUE),this.ri=e.create(),this.penetrationVec=e.create(),this.rj=e.create(),this.ni=e.create(),this.restitution=0,this.firstImpact=!1,this.shapeA=null,this.shapeB=null}{var d=a("./Equation"),e=a("../math/vec2");a("../math/mat2")}b.exports=c,c.prototype=new d,c.prototype.constructor=c,c.prototype.computeB=function(a,b,c){var d=this.bi,f=this.bj,g=this.ri,h=this.rj,i=d.position,j=f.position,k=this.penetrationVec,l=this.ni,m=this.G,n=e.crossLength(g,l),o=e.crossLength(h,l);m[0]=-l[0],m[1]=-l[1],m[2]=-n,m[3]=l[0],m[4]=l[1],m[5]=o,e.add(k,j,h),e.sub(k,k,i),e.sub(k,k,g);var p,q;this.firstImpact&&0!==this.restitution?(q=0,p=1/b*(1+this.restitution)*this.computeGW()):(p=this.computeGW(),q=e.dot(l,k));var r=this.computeGiMf(),s=-q*a-p*b-c*r;return s}},{"../math/mat2":31,"../math/vec2":33,"./Equation":24}],24:[function(a,b){function c(a,b,c,d){this.minForce="undefined"==typeof c?-1e6:c,this.maxForce="undefined"==typeof d?1e6:d,this.bi=a,this.bj=b,this.stiffness=1e6,this.relaxation=4,this.G=new g.ARRAY_TYPE(6);for(var e=0;6>e;e++)this.G[e]=0;this.offset=0,this.a=0,this.b=0,this.eps=0,this.h=0,this.updateSpookParams(1/60),this.multiplier=0,this.relativeVelocity=0,this.enabled=!0}function d(a,b,c,d,e){return a[0]*b[0]+a[1]*b[1]+a[2]*c+a[3]*d[0]+a[4]*d[1]+a[5]*e}b.exports=c;var e=a("../math/vec2"),f=a("../math/mat2"),g=a("../utils/Utils");c.prototype.constructor=c,c.prototype.updateSpookParams=function(a){var b=this.stiffness,c=this.relaxation,d=a;this.a=4/(d*(1+4*c)),this.b=4*c/(1+4*c),this.eps=4/(d*d*b*(1+4*c)),this.h=a},c.prototype.computeB=function(a,b,c){var d=this.computeGW(),e=this.computeGq(),f=this.computeGiMf();return-e*a-d*b-f*c};var h=e.create(),i=e.create();c.prototype.computeGq=function(){var a=this.G,b=this.bi,c=this.bj,e=(b.position,c.position,b.angle),f=c.angle;return d(a,h,e,i,f)+this.offset};e.create(),e.create();c.prototype.transformedGmult=function(a,b,c,e,f){return d(a,b,c,e,f)},c.prototype.computeGW=function(){var a=this.G,b=this.bi,c=this.bj,d=b.velocity,e=c.velocity,f=b.angularVelocity,g=c.angularVelocity;return this.transformedGmult(a,d,f,e,g)+this.relativeVelocity},c.prototype.computeGWlambda=function(){var a=this.G,b=this.bi,c=this.bj,e=b.vlambda,f=c.vlambda,g=b.wlambda,h=c.wlambda;return d(a,e,g,f,h)};var j=e.create(),k=e.create();c.prototype.computeGiMf=function(){var a=this.bi,b=this.bj,c=a.force,d=a.angularForce,f=b.force,g=b.angularForce,h=a.invMass,i=b.invMass,l=a.invInertia,m=b.invInertia,n=this.G;return e.scale(j,c,h),e.scale(k,f,i),this.transformedGmult(n,j,d*l,k,g*m)},c.prototype.computeGiMGt=function(){var a=this.bi,b=this.bj,c=a.invMass,d=b.invMass,e=a.invInertia,f=b.invInertia,g=this.G;return g[0]*g[0]*c+g[1]*g[1]*c+g[2]*g[2]*e+g[3]*g[3]*d+g[4]*g[4]*d+g[5]*g[5]*f};{var l=e.create(),m=e.create(),n=e.create();e.create(),e.create(),e.create(),f.create(),f.create()}c.prototype.addToWlambda=function(a){var b=this.bi,c=this.bj,d=l,f=m,g=n,h=this.G;f[0]=h[0],f[1]=h[1],g[0]=h[3],g[1]=h[4],e.scale(d,f,b.invMass*a),e.add(b.vlambda,b.vlambda,d),e.scale(d,g,c.invMass*a),e.add(c.vlambda,c.vlambda,d),b.wlambda+=b.invInertia*h[2]*a,c.wlambda+=c.invInertia*h[5]*a},c.prototype.computeInvC=function(a){return 1/(this.computeGiMGt()+a)}},{"../math/mat2":31,"../math/vec2":33,"../utils/Utils":50}],25:[function(a,b){function c(a,b,c){e.call(this,a,b,-c,c),this.ri=d.create(),this.rj=d.create(),this.t=d.create(),this.contactEquation=null,this.shapeA=null,this.shapeB=null,this.frictionCoefficient=.3}{var d=(a("../math/mat2"),a("../math/vec2")),e=a("./Equation");a("../utils/Utils")}b.exports=c,c.prototype=new e,c.prototype.constructor=c,c.prototype.setSlipForce=function(a){this.maxForce=a,this.minForce=-a},c.prototype.computeB=function(a,b,c){var e=(this.bi,this.bj,this.ri),f=this.rj,g=this.t,h=this.G;h[0]=-g[0],h[1]=-g[1],h[2]=-d.crossLength(e,g),h[3]=g[0],h[4]=g[1],h[5]=d.crossLength(f,g);var i=this.computeGW(),j=this.computeGiMf(),k=-i*b-c*j;return k}},{"../math/mat2":31,"../math/vec2":33,"../utils/Utils":50,"./Equation":24}],26:[function(a,b){function c(a,b,c){c=c||{},d.call(this,a,b,-Number.MAX_VALUE,Number.MAX_VALUE),this.angle=c.angle||0;var e=this.G;e[2]=1,e[5]=-1}var d=a("./Equation"),e=a("../math/vec2");b.exports=c,c.prototype=new d,c.prototype.constructor=c;var f=e.create(),g=e.create(),h=e.fromValues(1,0),i=e.fromValues(0,1);c.prototype.computeGq=function(){return e.rotate(f,h,this.bi.angle+this.angle),e.rotate(g,i,this.bj.angle),e.dot(f,g)}},{"../math/vec2":33,"./Equation":24}],27:[function(a,b){function c(a,b){d.call(this,a,b,-Number.MAX_VALUE,Number.MAX_VALUE),this.relativeVelocity=1,this.ratio=1}{var d=a("./Equation");a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.constructor=c,c.prototype.computeB=function(a,b,c){var d=this.G;d[2]=-1,d[5]=this.ratio;var e=this.computeGiMf(),f=this.computeGW(),g=-f*b-c*e;return g}},{"../math/vec2":33,"./Equation":24}],28:[function(a,b){var c=function(){};b.exports=c,c.prototype={constructor:c,on:function(a,b,c){b.context=c||this,void 0===this._listeners&&(this._listeners={});var d=this._listeners;return void 0===d[a]&&(d[a]=[]),-1===d[a].indexOf(b)&&d[a].push(b),this},has:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},off:function(a,b){if(void 0===this._listeners)return this;var c=this._listeners,d=c[a].indexOf(b);return-1!==d&&c[a].splice(d,1),this},emit:function(a){if(void 0===this._listeners)return this;var b=this._listeners,c=b[a.type];if(void 0!==c){a.target=this;for(var d=0,e=c.length;e>d;d++){var f=c[d];f.call(f.context,a)}}return this}}},{}],29:[function(a,b){function c(a,b,e){if(e=e||{},!(a instanceof d&&b instanceof d))throw new Error("First two arguments must be Material instances.");this.id=c.idCounter++,this.materialA=a,this.materialB=b,this.friction="undefined"!=typeof e.friction?Number(e.friction):.3,this.restitution="undefined"!=typeof e.restitution?Number(e.restitution):0,this.stiffness="undefined"!=typeof e.stiffness?Number(e.stiffness):1e7,this.relaxation="undefined"!=typeof e.relaxation?Number(e.relaxation):3,this.frictionStiffness="undefined"!=typeof e.frictionStiffness?Number(e.frictionStiffness):1e7,this.frictionRelaxation="undefined"!=typeof e.frictionRelaxation?Number(e.frictionRelaxation):3,this.surfaceVelocity="undefined"!=typeof e.surfaceVelocity?Number(e.surfaceVelocity):0}var d=a("./Material");b.exports=c,c.idCounter=0},{"./Material":30}],30:[function(a,b){function c(){this.id=c.idCounter++}b.exports=c,c.idCounter=0},{}],31:[function(a,b){var c=a("../../node_modules/gl-matrix/src/gl-matrix/mat2").mat2;b.exports=c},{"../../node_modules/gl-matrix/src/gl-matrix/mat2":1}],32:[function(a,b){var c={};c.GetArea=function(a){if(a.length<6)return 0;for(var b=a.length-2,c=0,d=0;b>d;d+=2)c+=(a[d+2]-a[d])*(a[d+1]+a[d+3]);return c+=(a[0]-a[b])*(a[b+1]+a[1]),.5*-c},c.Triangulate=function(a){var b=a.length>>1;if(3>b)return[];for(var d=[],e=[],f=0;b>f;f++)e.push(f);for(var f=0,g=b;g>3;){var h=e[(f+0)%g],i=e[(f+1)%g],j=e[(f+2)%g],k=a[2*h],l=a[2*h+1],m=a[2*i],n=a[2*i+1],o=a[2*j],p=a[2*j+1],q=!1;if(c._convex(k,l,m,n,o,p)){q=!0;for(var r=0;g>r;r++){var s=e[r];if(s!=h&&s!=i&&s!=j&&c._PointInTriangle(a[2*s],a[2*s+1],k,l,m,n,o,p)){q=!1;break}}}if(q)d.push(h,i,j),e.splice((f+1)%g,1),g--,f=0;else if(f++>3*g)break}return d.push(e[0],e[1],e[2]),d},c._PointInTriangle=function(a,b,c,d,e,f,g,h){var i=g-c,j=h-d,k=e-c,l=f-d,m=a-c,n=b-d,o=i*i+j*j,p=i*k+j*l,q=i*m+j*n,r=k*k+l*l,s=k*m+l*n,t=1/(o*r-p*p),u=(r*q-p*s)*t,v=(o*s-p*q)*t;return u>=0&&v>=0&&1>u+v},c._convex=function(a,b,c,d,e,f){return(b-d)*(e-c)+(c-a)*(f-d)>=0},b.exports=c},{}],33:[function(a,b){var c=a("../../node_modules/gl-matrix/src/gl-matrix/vec2").vec2;c.getX=function(a){return a[0]},c.getY=function(a){return a[1]},c.crossLength=function(a,b){return a[0]*b[1]-a[1]*b[0]},c.crossVZ=function(a,b,d){return c.rotate(a,b,-Math.PI/2),c.scale(a,a,d),a},c.crossZV=function(a,b,d){return c.rotate(a,d,Math.PI/2),c.scale(a,a,b),a},c.rotate=function(a,b,c){var d=Math.cos(c),e=Math.sin(c),f=b[0],g=b[1];a[0]=d*f-e*g,a[1]=e*f+d*g},c.toLocalFrame=function(a,b,d,e){c.copy(a,b),c.sub(a,a,d),c.rotate(a,a,-e)},c.toGlobalFrame=function(a,b,d,e){c.copy(a,b),c.rotate(a,a,e),c.add(a,a,d)},c.centroid=function(a,b,d,e){return c.add(a,b,d),c.add(a,a,e),c.scale(a,a,1/3),a},b.exports=c},{"../../node_modules/gl-matrix/src/gl-matrix/vec2":2}],34:[function(a,b){function c(a){a=a||{},h.call(this),this.id=++c._idCounter,this.world=null,this.shapes=[],this.shapeOffsets=[],this.shapeAngles=[],this.mass=a.mass||0,this.invMass=0,this.inertia=0,this.invInertia=0,this.fixedRotation=!!a.fixedRotation||!1,this.position=d.fromValues(0,0),a.position&&d.copy(this.position,a.position),this.interpolatedPosition=d.fromValues(0,0),this.velocity=d.fromValues(0,0),a.velocity&&d.copy(this.velocity,a.velocity),this.vlambda=d.fromValues(0,0),this.wlambda=0,this.angle=a.angle||0,this.angularVelocity=a.angularVelocity||0,this.force=d.create(),a.force&&d.copy(this.force,a.force),this.angularForce=a.angularForce||0,this.damping="number"==typeof a.damping?a.damping:.1,this.angularDamping="number"==typeof a.angularDamping?a.angularDamping:.1,this.motionState=0==this.mass?c.STATIC:c.DYNAMIC,this.boundingRadius=0,this.aabb=new g,this.aabbNeedsUpdate=!0,this.allowSleep=!1,this.sleepState=c.AWAKE,this.sleepSpeedLimit=.1,this.sleepTimeLimit=1,this.gravityScale=1,this.timeLastSleepy=0,this.concavePath=null,this.lastDampingScale=1,this.lastAngularDampingScale=1,this.lastDampingTimeStep=-1,this.updateMassProperties()}var d=a("../math/vec2"),e=a("poly-decomp"),f=a("../shapes/Convex"),g=a("../collision/AABB"),h=a("../events/EventEmitter");b.exports=c,c.prototype=new h,c._idCounter=0,c.prototype.setDensity=function(a){var b=this.getArea();this.mass=b*a,this.updateMassProperties()},c.prototype.getArea=function(){for(var a=0,b=0;be&&(e=h+i)}this.boundingRadius=e},c.prototype.addShape=function(a,b,c){c=c||0,b=b?d.fromValues(b[0],b[1]):d.fromValues(0,0),this.shapes.push(a),this.shapeOffsets.push(b),this.shapeAngles.push(c),this.updateMassProperties(),this.updateBoundingRadius(),this.aabbNeedsUpdate=!0},c.prototype.removeShape=function(a){var b=this.shapes.indexOf(a);return-1!=b?(this.shapes.splice(b,1),this.shapeOffsets.splice(b,1),this.shapeAngles.splice(b,1),this.aabbNeedsUpdate=!0,!0):!1},c.prototype.updateMassProperties=function(){if(this.motionState==c.STATIC||this.motionState==c.KINEMATIC)this.mass=Number.MAX_VALUE,this.invMass=0,this.inertia=Number.MAX_VALUE,this.invInertia=0;else{var a=this.shapes,b=a.length,e=this.mass/b,f=0;if(this.fixedRotation)this.inertia=Number.MAX_VALUE,this.invInertia=0;else{for(var g=0;b>g;g++){var h=a[g],i=d.squaredLength(this.shapeOffsets[g]),j=h.computeMomentOfInertia(e);f+=j+e*i}this.inertia=f,this.invInertia=f>0?1/f:0}this.invMass=1/this.mass}};var k=d.create();c.prototype.applyForce=function(a,b){var c=k;d.sub(c,b,this.position),d.add(this.force,this.force,a);var e=d.crossLength(c,a);this.angularForce+=e},c.prototype.toLocalFrame=function(a,b){d.toLocalFrame(a,b,this.position,this.angle)},c.prototype.toWorldFrame=function(a,b){d.toGlobalFrame(a,b,this.position,this.angle)},c.prototype.fromPolygon=function(a,b){b=b||{};for(var c=this.shapes.length;c>=0;--c)this.removeShape(this.shapes[c]);var g=new e.Polygon;if(g.vertices=a,g.makeCCW(),"number"==typeof b.removeCollinearPoints&&g.removeCollinearPoints(b.removeCollinearPoints),"undefined"==typeof b.skipSimpleCheck&&!g.isSimple())return!1;this.concavePath=g.vertices.slice(0);for(var c=0;ce?(this.sleepState=c.SLEEPY,this.timeLastSleepy=a,this.emit(c.sleepyEvent)):b===c.SLEEPY&&e>f?this.wakeUp():b===c.SLEEPY&&a-this.timeLastSleepy>this.sleepTimeLimit&&this.sleep()}},c.sleepyEvent={type:"sleepy"},c.sleepEvent={type:"sleep"},c.wakeUpEvent={type:"wakeup"},c.DYNAMIC=1,c.STATIC=2,c.KINEMATIC=4,c.AWAKE=0,c.SLEEPY=1,c.SLEEPING=2},{"../collision/AABB":9,"../events/EventEmitter":28,"../math/vec2":33,"../shapes/Convex":39,"poly-decomp":7}],35:[function(a,b){function c(a,b,c){c=c||{},this.restLength="number"==typeof c.restLength?c.restLength:1,this.stiffness=c.stiffness||100,this.damping=c.damping||1,this.bodyA=a,this.bodyB=b,this.localAnchorA=d.fromValues(0,0),this.localAnchorB=d.fromValues(0,0),c.localAnchorA&&d.copy(this.localAnchorA,c.localAnchorA),c.localAnchorB&&d.copy(this.localAnchorB,c.localAnchorB),c.worldAnchorA&&this.setWorldAnchorA(c.worldAnchorA),c.worldAnchorB&&this.setWorldAnchorB(c.worldAnchorB)}var d=a("../math/vec2");b.exports=c,c.prototype.setWorldAnchorA=function(a){this.bodyA.toLocalFrame(this.localAnchorA,a)},c.prototype.setWorldAnchorB=function(a){this.bodyB.toLocalFrame(this.localAnchorB,a)},c.prototype.getWorldAnchorA=function(a){this.bodyA.toWorldFrame(a,this.localAnchorA)},c.prototype.getWorldAnchorB=function(a){this.bodyB.toWorldFrame(a,this.localAnchorB) -};var e=d.create(),f=d.create(),g=d.create(),h=d.create(),i=d.create(),j=d.create(),k=d.create(),l=d.create(),m=d.create();c.prototype.applyForce=function(){var a=this.stiffness,b=this.damping,c=this.restLength,n=this.bodyA,o=this.bodyB,p=e,q=f,r=g,s=h,t=m,u=i,v=j,w=k,x=l;this.getWorldAnchorA(u),this.getWorldAnchorB(v),d.sub(w,u,n.position),d.sub(x,v,o.position),d.sub(p,v,u);var y=d.len(p);d.normalize(q,p),d.sub(r,o.velocity,n.velocity),d.crossZV(t,o.angularVelocity,x),d.add(r,r,t),d.crossZV(t,n.angularVelocity,w),d.sub(r,r,t),d.scale(s,q,-a*(y-c)-b*d.dot(r,q)),d.sub(n.force,n.force,s),d.add(o.force,o.force,s);var z=d.crossLength(w,s),A=d.crossLength(x,s);n.angularForce-=z,o.angularForce+=A}},{"../math/vec2":33}],36:[function(a,b){b.exports={AABB:a("./collision/AABB"),AngleLockEquation:a("./equations/AngleLockEquation"),Body:a("./objects/Body"),Broadphase:a("./collision/Broadphase"),Capsule:a("./shapes/Capsule"),Circle:a("./shapes/Circle"),Constraint:a("./constraints/Constraint"),ContactEquation:a("./equations/ContactEquation"),ContactMaterial:a("./material/ContactMaterial"),Convex:a("./shapes/Convex"),DistanceConstraint:a("./constraints/DistanceConstraint"),Equation:a("./equations/Equation"),EventEmitter:a("./events/EventEmitter"),FrictionEquation:a("./equations/FrictionEquation"),GearConstraint:a("./constraints/GearConstraint"),GridBroadphase:a("./collision/GridBroadphase"),GSSolver:a("./solver/GSSolver"),Heightfield:a("./shapes/Heightfield"),Island:a("./solver/IslandSolver"),IslandSolver:a("./solver/IslandSolver"),Line:a("./shapes/Line"),LockConstraint:a("./constraints/LockConstraint"),Material:a("./material/Material"),Narrowphase:a("./collision/Narrowphase"),NaiveBroadphase:a("./collision/NaiveBroadphase"),Particle:a("./shapes/Particle"),Plane:a("./shapes/Plane"),RevoluteConstraint:a("./constraints/RevoluteConstraint"),PrismaticConstraint:a("./constraints/PrismaticConstraint"),Rectangle:a("./shapes/Rectangle"),RotationalVelocityEquation:a("./equations/RotationalVelocityEquation"),SAPBroadphase:a("./collision/SAPBroadphase"),Shape:a("./shapes/Shape"),Solver:a("./solver/Solver"),Spring:a("./objects/Spring"),Utils:a("./utils/Utils"),World:a("./world/World"),QuadTree:a("./collision/QuadTree").QuadTree,vec2:a("./math/vec2"),version:a("../package.json").version}},{"../package.json":8,"./collision/AABB":9,"./collision/Broadphase":10,"./collision/GridBroadphase":11,"./collision/NaiveBroadphase":12,"./collision/Narrowphase":13,"./collision/QuadTree":14,"./collision/SAPBroadphase":15,"./constraints/Constraint":16,"./constraints/DistanceConstraint":17,"./constraints/GearConstraint":18,"./constraints/LockConstraint":19,"./constraints/PrismaticConstraint":20,"./constraints/RevoluteConstraint":21,"./equations/AngleLockEquation":22,"./equations/ContactEquation":23,"./equations/Equation":24,"./equations/FrictionEquation":25,"./equations/RotationalVelocityEquation":27,"./events/EventEmitter":28,"./material/ContactMaterial":29,"./material/Material":30,"./math/vec2":33,"./objects/Body":34,"./objects/Spring":35,"./shapes/Capsule":37,"./shapes/Circle":38,"./shapes/Convex":39,"./shapes/Heightfield":40,"./shapes/Line":41,"./shapes/Particle":42,"./shapes/Plane":43,"./shapes/Rectangle":44,"./shapes/Shape":45,"./solver/GSSolver":46,"./solver/IslandSolver":48,"./solver/Solver":49,"./utils/Utils":50,"./world/World":51}],37:[function(a,b){function c(a,b){this.length=a||1,this.radius=b||1,d.call(this,d.CAPSULE)}var d=a("./Shape"),e=a("../math/vec2");b.exports=c,c.prototype=new d,c.prototype.computeMomentOfInertia=function(a){var b=this.radius,c=this.length+b,d=2*b;return a*(d*d+c*c)/12},c.prototype.updateBoundingRadius=function(){this.boundingRadius=this.radius+this.length/2},c.prototype.updateArea=function(){this.area=Math.PI*this.radius*this.radius+2*this.radius*this.length};var f=e.create();c.prototype.computeAABB=function(a,b,c){var d=this.radius;e.set(f,this.length,0),e.rotate(f,f,c),e.set(a.upperBound,Math.max(f[0]+d,-f[0]+d),Math.max(f[1]+d,-f[1]+d)),e.set(a.lowerBound,Math.min(f[0]-d,-f[0]-d),Math.min(f[1]-d,-f[1]-d)),e.add(a.lowerBound,a.lowerBound,b),e.add(a.upperBound,a.upperBound,b)}},{"../math/vec2":33,"./Shape":45}],38:[function(a,b){function c(a){this.radius=a||1,d.call(this,d.CIRCLE)}var d=a("./Shape"),e=a("../math/vec2");b.exports=c,c.prototype=new d,c.prototype.computeMomentOfInertia=function(a){var b=this.radius;return a*b*b/2},c.prototype.updateBoundingRadius=function(){this.boundingRadius=this.radius},c.prototype.updateArea=function(){this.area=Math.PI*this.radius*this.radius},c.prototype.computeAABB=function(a,b){var c=this.radius;e.set(a.upperBound,c,c),e.set(a.lowerBound,-c,-c),b&&(e.add(a.lowerBound,a.lowerBound,b),e.add(a.upperBound,a.upperBound,b))}},{"../math/vec2":33,"./Shape":45}],39:[function(a,b){function c(a){this.vertices=[];for(var b=0;bg;f=g,g++){var h=this.vertices[f],i=this.vertices[g],j=Math.abs(e.crossLength(h,i)),k=e.dot(i,i)+e.dot(i,h)+e.dot(h,h);b+=j*k,c+=j}return a/6*(b/c)},c.prototype.updateBoundingRadius=function(){for(var a=this.vertices,b=0,c=0;c!==a.length;c++){var d=e.squaredLength(a[c]);d>b&&(b=d)}this.boundingRadius=Math.sqrt(b)},c.triangleArea=function(a,b,c){return.5*((b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1]))},c.prototype.updateArea=function(){this.updateTriangles(),this.area=0;for(var a=this.triangles,b=this.vertices,d=0;d!==a.length;d++){var e=a[d],f=b[e[0]],g=b[e[1]],h=b[e[2]],i=c.triangleArea(f,g,h);this.area+=i}},c.prototype.computeAABB=function(a,b,c){a.setFromPoints(this.vertices,b,c)}},{"../math/polyk":32,"../math/vec2":33,"./Shape":45,"poly-decomp":7}],40:[function(a,b){function c(a,b,c){this.data=a,this.maxValue=b,this.elementWidth=c,d.call(this,d.HEIGHTFIELD)}{var d=a("./Shape");a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.computeMomentOfInertia=function(){return Number.MAX_VALUE},c.prototype.updateBoundingRadius=function(){this.boundingRadius=Number.MAX_VALUE},c.prototype.updateArea=function(){for(var a=this.data,b=0,c=0;cf)){var D=u?r:z.eps,E=c.iterateEquation(C,z,D,y,x,w,v,a,f,j,this.useNormalForceForFriction);B+=Math.abs(E)}if(k>=B*B)break}for(A=0;A!==o;A++)n[A].addConstraintVelocity()}},c.iterateEquation=function(a,b,c,d,e,f,g,i,j,k,l){var m=d[a],n=e[a],o=f[a],p=b.computeGWlambda();l&&b instanceof h&&j==k&&(b.maxForce=b.contactEquation.multiplier*b.frictionCoefficient*i,b.minForce=-b.contactEquation.multiplier*b.frictionCoefficient*i);var q=b.maxForce,r=b.minForce;g&&(m=0);var s=n*(m-p-c*o),t=o+s;return r*i>t?s=r*i-o:t>q*i&&(s=q*i-o),f[a]+=s,b.multiplier=f[a]/i,b.addToWlambda(s),s}},{"../equations/FrictionEquation":25,"../math/vec2":33,"../utils/Utils":50,"./Solver":49}],47:[function(a,b){function c(){this.equations=[],this.bodies=[]}b.exports=c,c.prototype.reset=function(){this.equations.length=this.bodies.length=0},c.prototype.getBodies=function(){for(var a=[],b=[],c=this.equations,d=0;d!==c.length;d++){var e=c[d];-1===b.indexOf(e.bi.id)&&(a.push(e.bi),b.push(e.bi.id)),-1===b.indexOf(e.bj.id)&&(a.push(e.bj),b.push(e.bj.id))}return a},c.prototype.solve=function(a,b){var c=[];b.removeAllEquations();for(var d=this.equations.length,e=0;e!==d;e++)b.addEquation(this.equations[e]);for(var f=this.getBodies(),g=f.length,e=0;e!==g;e++)c.push(f[e]);b.solve(a,{bodies:c})}},{}],48:[function(a,b){function c(a,b){g.call(this,b,g.ISLAND);this.subsolver=a,this.numIslands=0,this._nodePool=[],this._islandPool=[],this.beforeSolveIslandEvent={type:"beforeSolveIsland",island:null}}function d(a){for(var b=a.length,c=0;c!==b;c++){var d=a[c];if(!d.visited&&d.body.motionState!=j)return d}return!1}function e(a,b,c){b.push(a.body);for(var d=a.eqs.length,e=0;e!==d;e++){var f=a.eqs[e];-1===c.indexOf(f)&&c.push(f)}}function f(a,b,c,e){for(k.length=0,k.push(a),a.visited=!0,b(a,c,e);k.length;)for(var f,g=k.pop();f=d(g.children);)f.visited=!0,b(f,c,e),k.push(f)}var g=a("./Solver"),h=(a("../math/vec2"),a("../solver/Island")),i=a("../objects/Body"),j=i.STATIC;b.exports=c,c.prototype=new g;var k=[],l=[],m=[],n=[],o=[];c.prototype.solve=function(a,b){var c=l,g=b.bodies,i=this.equations,j=i.length,k=g.length,p=(this.subsolver,this._workers,this._workerData,this._workerIslandGroups,this._islandPool);l.length=0;for(var q=0;q!==k;q++)c.push(this._nodePool.length?this._nodePool.pop():{body:g[q],children:[],eqs:[],visited:!1});for(var q=0;q!==k;q++){var r=c[q];r.body=g[q],r.children.length=0,r.eqs.length=0,r.visited=!1}for(var s=0;s!==j;s++){var t=i[s],q=g.indexOf(t.bi),u=g.indexOf(t.bj),v=c[q],w=c[u];v.children.push(w),v.eqs.push(t),w.children.push(v),w.eqs.push(t)}var x,y=0,z=m,A=n;z.length=0,A.length=0;var B=o;for(B.length=0;x=d(c);){var C=p.length?p.pop():new h;z.length=0,A.length=0,f(x,e,A,z);for(var D=z.length,q=0;q!==D;q++){var t=z[q];C.equations.push(t)}y++,B.push(C)}this.numIslands=y;for(var E=this.beforeSolveIslandEvent,q=0;qd;d++)a[d]=a[d+c];a.length=e},c.ARRAY_TYPE=Float32Array||Array},{}],51:[function(a,b){function c(a){n.apply(this),a=a||{},this.springs=[],this.bodies=[],this.solver=a.solver||new d,this.narrowphase=new x(this),this.gravity=a.gravity||f.fromValues(0,-9.78),this.doProfiling=a.doProfiling||!1,this.lastStepTime=0,this.broadphase=a.broadphase||new e,this.broadphase.setWorld(this),this.constraints=[],this.defaultFriction=.3,this.defaultRestitution=0,this.lastTimeStep=1/60,this.applySpringForces=!0,this.applyDamping=!0,this.applyGravity=!0,this.solveConstraints=!0,this.contactMaterials=[],this.time=0,this.fixedStepTime=0,this.emitImpactEvent=!0,this._constraintIdCounter=0,this._bodyIdCounter=0,this.postStepEvent={type:"postStep"},this.addBodyEvent={type:"addBody",body:null},this.removeBodyEvent={type:"removeBody",body:null},this.addSpringEvent={type:"addSpring",spring:null},this.impactEvent={type:"impact",bodyA:null,bodyB:null,shapeA:null,shapeB:null,contactEquation:null},this.postBroadphaseEvent={type:"postBroadphase",pairs:null},this.enableBodySleeping=!1,this.beginContactEvent={type:"beginContact",shapeA:null,shapeB:null,bodyA:null,bodyB:null,contactEquations:[]},this.endContactEvent={type:"endContact",shapeA:null,shapeB:null,bodyA:null,bodyB:null},this.preSolveEvent={type:"preSolve",contactEquations:null,frictionEquations:null},this.overlappingShapesLastState={keys:[]},this.overlappingShapesCurrentState={keys:[]},this.overlappingShapeLookup={keys:[]}}var d=a("../solver/GSSolver"),e=a("../collision/NaiveBroadphase"),f=a("../math/vec2"),g=a("../shapes/Circle"),h=a("../shapes/Rectangle"),i=a("../shapes/Convex"),j=a("../shapes/Line"),k=a("../shapes/Plane"),l=a("../shapes/Capsule"),m=a("../shapes/Particle"),n=a("../events/EventEmitter"),o=a("../objects/Body"),p=a("../objects/Spring"),q=a("../material/Material"),r=a("../material/ContactMaterial"),s=a("../constraints/DistanceConstraint"),t=a("../constraints/LockConstraint"),u=a("../constraints/RevoluteConstraint"),v=a("../constraints/PrismaticConstraint"),w=a("../../package.json"),x=(a("../collision/Broadphase"),a("../collision/Narrowphase")),y=a("../utils/Utils");b.exports=c;var z=w.version.split(".").slice(0,2).join(".");if("undefined"==typeof performance&&(performance={}),!performance.now){var A=Date.now();performance.timing&&performance.timing.navigationStart&&(A=performance.timing.navigationStart),performance.now=function(){return Date.now()-A}}c.prototype=new Object(n.prototype),c.prototype.addConstraint=function(a){this.constraints.push(a)},c.prototype.addContactMaterial=function(a){this.contactMaterials.push(a)},c.prototype.removeContactMaterial=function(a){var b=this.contactMaterials.indexOf(a);-1!==b&&y.splice(this.contactMaterials,b,1)},c.prototype.getContactMaterial=function(a,b){for(var c=this.contactMaterials,d=0,e=c.length;d!==e;d++){var f=c[d];if(f.materialA===a&&f.materialB===b||f.materialA===b&&f.materialB===a)return f}return!1},c.prototype.removeConstraint=function(a){var b=this.constraints.indexOf(a);-1!==b&&y.splice(this.constraints,b,1)};{var B=(f.create(),f.create(),f.create(),f.create(),f.create(),f.create(),f.create()),C=f.fromValues(0,0),D=f.fromValues(0,0);f.fromValues(0,0)}c.prototype.step=function(a,b,c){if(c=c||10,b=b||0,0==b)this.internalStep(a),this.time+=a;else{var d=Math.floor((this.time+b)/a)-Math.floor(this.time/a);d=Math.min(d,c);for(var e=0;d>e;e++)this.internalStep(a);this.time+=b,this.fixedStepTime+=d*a;for(var f=this.time-this.fixedStepTime-a,g=0;g!==this.bodies.length;g++){var h=this.bodies[g];h.interpolatedPosition[0]=h.position[0]+h.velocity[0]*f,h.interpolatedPosition[1]=h.position[1]+h.velocity[1]*f}}},c.prototype.internalStep=function(a){{var b,d,e=this,g=this.doProfiling,h=this.springs.length,i=this.springs,j=this.bodies,k=this.gravity,l=this.solver,m=this.bodies.length,n=this.broadphase,p=this.narrowphase,q=this.constraints,r=B,s=(f.scale,f.add);f.rotate}this.lastTimeStep=a,g&&(b=performance.now());var t=f.length(this.gravity);if(this.applyGravity)for(var u=0;u!==m;u++){var v=j[u],w=v.force;v.motionState==o.DYNAMIC&&(f.scale(r,k,v.mass*v.gravityScale),s(w,w,r))}if(this.applySpringForces)for(var u=0;u!==h;u++){var x=i[u];x.applyForce()}if(this.applyDamping)for(var u=0;u!==m;u++){var v=j[u];v.motionState==o.DYNAMIC&&v.applyDamping(a)}var y=n.getCollisionPairs(this);this.postBroadphaseEvent.pairs=y,this.emit(this.postBroadphaseEvent),p.reset(this);for(var u=0,z=y.length;u!==z;u+=2)for(var A=y[u],C=y[u+1],D=0,E=A.shapes.length;D!==E;D++)for(var F=A.shapes[D],G=A.shapeOffsets[D],H=A.shapeAngles[D],I=0,J=C.shapes.length;I!==J;I++){var K=C.shapes[I],L=C.shapeOffsets[I],M=C.shapeAngles[I],N=this.defaultFriction,O=this.defaultRestitution,P=0;if(F.material&&K.material){var Q=this.getContactMaterial(F.material,K.material);Q&&(N=Q.friction,O=Q.restitution,P=Q.surfaceVelocity)}this.runNarrowphase(p,A,F,G,H,C,K,L,M,N,O,P,t)}for(var R=this.overlappingShapesLastState,u=0;u!==R.keys.length;u++){var S=R.keys[u];if(R[S]===!0&&!this.overlappingShapesCurrentState[S]){var T=this.endContactEvent;T.shapeA=R[S+"_shapeA"],T.shapeB=R[S+"_shapeB"],T.bodyA=R[S+"_bodyA"],T.bodyB=R[S+"_bodyB"],this.emit(T)}}for(var u=0;u!==R.keys.length;u++)delete R[R.keys[u]];R.keys.length=0;for(var U=this.overlappingShapesCurrentState,u=0;u!==U.keys.length;u++)R[U.keys[u]]=U[U.keys[u]],R.keys.push(U.keys[u]);for(var u=0;u!==U.keys.length;u++)delete U[U.keys[u]];U.keys.length=0;var V=this.preSolveEvent;V.contactEquations=p.contactEquations,V.frictionEquations=p.frictionEquations,this.emit(V),l.addEquations(p.contactEquations),l.addEquations(p.frictionEquations);var W=q.length;for(u=0;u!==W;u++){var X=q[u];X.update(),l.addEquations(X.equations)}this.solveConstraints&&l.solve(a,this),l.removeAllEquations();for(var u=0;u!==m;u++){var Y=j[u];Y.sleepState!==o.SLEEPING&&Y.motionState!=o.STATIC&&c.integrateBody(Y,a)}for(var u=0;u!==m;u++)j[u].setZeroForce();if(g&&(d=performance.now(),e.lastStepTime=d-b),this.emitImpactEvent)for(var Z=this.impactEvent,u=0;u!==p.contactEquations.length;u++){var $=p.contactEquations[u];$.firstImpact&&(Z.bodyA=$.bi,Z.bodyB=$.bj,Z.shapeA=$.shapeA,Z.shapeB=$.shapeB,Z.contactEquation=$,this.emit(Z))}if(this.enableBodySleeping)for(u=0;u!==m;u++)j[u].sleepTick(this.time);this.emit(this.postStepEvent)};var E=f.create(),F=f.create();c.integrateBody=function(a,b){var c=a.invMass,d=a.force,e=a.position,g=a.velocity;a.fixedRotation||(a.angularVelocity+=a.angularForce*a.invInertia*b,a.angle+=a.angularVelocity*b),f.scale(E,d,b*c),f.add(g,E,g),f.scale(F,g,b),f.add(e,e,F),a.aabbNeedsUpdate=!0},c.prototype.runNarrowphase=function(a,b,c,d,e,g,h,i,j,k,l,m,n){if(0!==(c.collisionGroup&h.collisionMask)&&0!==(h.collisionGroup&c.collisionMask)){f.rotate(C,d,b.angle),f.rotate(D,i,g.angle),f.add(C,C,b.position),f.add(D,D,g.position);var p=e+b.angle,q=j+g.angle;a.enableFriction=k>0,a.frictionCoefficient=k;var r;r=b.motionState==o.STATIC||b.motionState==o.KINEMATIC?g.mass:g.motionState==o.STATIC||g.motionState==o.KINEMATIC?b.mass:b.mass*g.mass/(b.mass+g.mass),a.slipForce=k*n*r,a.restitution=l,a.surfaceVelocity=m;var s=a[c.type|h.type],t=0;if(s){var u=c.sensor||h.sensor;if(t=c.type=0;b--)this.removeConstraint(a[b]);for(var c=this.bodies,b=c.length-1;b>=0;b--)this.removeBody(c[b]);for(var d=this.springs,b=d.length-1;b>=0;b--)this.removeSpring(d[b]);for(var e=this.contactMaterials,b=e.length-1;b>=0;b--)this.removeContactMaterial(e[b])},c.prototype.clone=function(){var a=new c;return a.fromJSON(this.toJSON()),a};var G=f.create(),H=f.fromValues(0,0),I=f.fromValues(0,0);c.prototype.hitTest=function(a,b,c){c=c||0;var d=new o({position:a}),e=new m,h=a,j=0,n=G,p=H,q=I;d.addShape(e);for(var r=this.narrowphase,s=[],t=0,u=b.length;t!==u;t++)for(var v=b[t],w=0,x=v.shapes.length;w!==x;w++){var y=v.shapes[w],z=v.shapeOffsets[w]||p,A=v.shapeAngles[w]||0;f.rotate(n,z,v.angle),f.add(n,n,v.position);var B=A+v.angle;(y instanceof g&&r.circleParticle(v,y,n,B,d,e,h,j,!0)||y instanceof i&&r.particleConvex(d,e,h,j,v,y,n,B,!0)||y instanceof k&&r.particlePlane(d,e,h,j,v,y,n,B,!0)||y instanceof l&&r.particleCapsule(d,e,h,j,v,y,n,B,!0)||y instanceof m&&f.squaredLength(f.sub(q,n,a))0&&(e=1/Math.sqrt(e),a[0]=b[0]*e,a[1]=b[1]*e),a},d.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]},d.cross=function(a,b,c){var d=b[0]*c[1]-b[1]*c[0];return a[0]=a[1]=0,a[2]=d,a},d.lerp=function(a,b,c,d){var e=b[0],f=b[1];return a[0]=e+d*(c[0]-e),a[1]=f+d*(c[1]-f),a},d.transformMat2=function(a,b,c){var d=b[0],e=b[1];return a[0]=d*c[0]+e*c[1],a[1]=d*c[2]+e*c[3],a},d.forEach=function(){var a=new Float32Array(2);return function(b,c,d,e,f,g){var h,i;for(c||(c=2),d||(d=0),i=e?Math.min(e*c+d,b.length):b.length,h=d;i>h;h+=c)a[0]=b[h],a[1]=b[h+1],f(a,a,g),b[h]=a[0],b[h+1]=a[1];return b}}(),d.str=function(a){return"vec2("+a[0]+", "+a[1]+")"},"undefined"!=typeof c&&(c.vec2=d)},{}],3:[function(a,b){function c(){}var d=a("./Scalar");b.exports=c,c.lineInt=function(a,b,c){c=c||0;var e,f,g,h,i,j,k,l=[0,0];return e=a[1][1]-a[0][1],f=a[0][0]-a[1][0],g=e*a[0][0]+f*a[0][1],h=b[1][1]-b[0][1],i=b[0][0]-b[1][0],j=h*b[0][0]+i*b[0][1],k=e*i-h*f,d.eq(k,0,c)||(l[0]=(i*g-f*j)/k,l[1]=(e*j-h*g)/k),l},c.segmentsIntersect=function(a,b,c,d){var e=b[0]-a[0],f=b[1]-a[1],g=d[0]-c[0],h=d[1]-c[1];if(g*f-h*e==0)return!1;var i=(e*(c[1]-a[1])+f*(a[0]-c[0]))/(g*f-h*e),j=(g*(a[1]-c[1])+h*(c[0]-a[0]))/(h*e-g*f);return i>=0&&1>=i&&j>=0&&1>=j}},{"./Scalar":6}],4:[function(a,b){function c(){}b.exports=c,c.area=function(a,b,c){return(b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])},c.left=function(a,b,d){return c.area(a,b,d)>0},c.leftOn=function(a,b,d){return c.area(a,b,d)>=0},c.right=function(a,b,d){return c.area(a,b,d)<0},c.rightOn=function(a,b,d){return c.area(a,b,d)<=0};var d=[],e=[];c.collinear=function(a,b,f,g){if(g){var h=d,i=e;h[0]=b[0]-a[0],h[1]=b[1]-a[1],i[0]=f[0]-b[0],i[1]=f[1]-b[1];var j=h[0]*i[0]+h[1]*i[1],k=Math.sqrt(h[0]*h[0]+h[1]*h[1]),l=Math.sqrt(i[0]*i[0]+i[1]*i[1]),m=Math.acos(j/(k*l));return g>m}return 0==c.area(a,b,f)},c.sqdist=function(a,b){var c=b[0]-a[0],d=b[1]-a[1];return c*c+d*d}},{}],5:[function(a,b){function c(){this.vertices=[]}function d(a,b,c,d,e){e=e||0;var f=b[1]-a[1],h=a[0]-b[0],i=f*a[0]+h*a[1],j=d[1]-c[1],k=c[0]-d[0],l=j*c[0]+k*c[1],m=f*k-j*h;return g.eq(m,0,e)?[0,0]:[(k*i-h*l)/m,(f*l-j*i)/m]}var e=a("./Line"),f=a("./Point"),g=a("./Scalar");b.exports=c,c.prototype.at=function(a){var b=this.vertices,c=b.length;return b[0>a?a%c+c:a%c]},c.prototype.first=function(){return this.vertices[0]},c.prototype.last=function(){return this.vertices[this.vertices.length-1]},c.prototype.clear=function(){this.vertices.length=0},c.prototype.append=function(a,b,c){if("undefined"==typeof b)throw new Error("From is not given!");if("undefined"==typeof c)throw new Error("To is not given!");if(b>c-1)throw new Error("lol1");if(c>a.vertices.length)throw new Error("lol2");if(0>b)throw new Error("lol3");for(var d=b;c>d;d++)this.vertices.push(a.vertices[d])},c.prototype.makeCCW=function(){for(var a=0,b=this.vertices,c=1;cb[a][0])&&(a=c);f.left(this.at(a-1),this.at(a),this.at(a+1))||this.reverse()},c.prototype.reverse=function(){for(var a=[],b=0,c=this.vertices.length;b!==c;b++)a.push(this.vertices.pop());this.vertices=a},c.prototype.isReflex=function(a){return f.right(this.at(a-1),this.at(a),this.at(a+1))};var h=[],i=[];c.prototype.canSee=function(a,b){var c,d,g=h,j=i;if(f.leftOn(this.at(a+1),this.at(a),this.at(b))&&f.rightOn(this.at(a-1),this.at(a),this.at(b)))return!1;d=f.sqdist(this.at(a),this.at(b));for(var k=0;k!==this.vertices.length;++k)if((k+1)%this.vertices.length!==a&&k!==a&&f.leftOn(this.at(a),this.at(b),this.at(k+1))&&f.rightOn(this.at(a),this.at(b),this.at(k))&&(g[0]=this.at(a),g[1]=this.at(b),j[0]=this.at(k),j[1]=this.at(k+1),c=e.lineInt(g,j),f.sqdist(this.at(a),c)a)for(var f=a;b>=f;f++)e.vertices.push(this.vertices[f]);else{for(var f=0;b>=f;f++)e.vertices.push(this.vertices[f]);for(var f=a;f0?this.slice(a):[this]},c.prototype.slice=function(a){if(0==a.length)return[this];if(a instanceof Array&&a.length&&a[0]instanceof Array&&2==a[0].length&&a[0][0]instanceof Array){for(var b=[this],c=0;cc;c++)if(e.segmentsIntersect(a[b],a[b+1],a[c],a[c+1]))return!1;for(var b=1;bh)return console.warn("quickDecomp: max level ("+h+") reached."),a;for(var x=0;xo&&(n=o,k=l,r=y))),f.left(v.at(x+1),v.at(x),v.at(y+1))&&f.rightOn(v.at(x+1),v.at(x),v.at(y))&&(l=d(v.at(x+1),v.at(x),v.at(y),v.at(y+1)),f.left(v.at(x-1),v.at(x),l)&&(o=f.sqdist(v.vertices[x],l),m>o&&(m=o,j=l,q=y)));if(r==(q+1)%this.vertices.length)l[0]=(k[0]+j[0])/2,l[1]=(k[1]+j[1])/2,e.push(l),q>x?(t.append(v,x,q+1),t.vertices.push(l),u.vertices.push(l),0!=r&&u.append(v,r,v.vertices.length),u.append(v,0,x+1)):(0!=x&&t.append(v,x,v.vertices.length),t.append(v,0,q+1),t.vertices.push(l),u.vertices.push(l),u.append(v,r,x+1));else{if(r>q&&(q+=this.vertices.length),p=Number.MAX_VALUE,r>q)return a;for(var y=r;q>=y;++y)f.leftOn(v.at(x-1),v.at(x),v.at(y))&&f.rightOn(v.at(x+1),v.at(x),v.at(y))&&(o=f.sqdist(v.at(x),v.at(y)),p>o&&(p=o,s=y%this.vertices.length));s>x?(t.append(v,x,s+1),0!=s&&u.append(v,s,w.length),u.append(v,0,x+1)):(0!=x&&t.append(v,x,w.length),t.append(v,0,s+1),u.append(v,s,x+1))}return t.vertices.length3&&c>=0;--c)f.collinear(this.at(c-1),this.at(c),this.at(c+1),a)&&(this.vertices.splice(c%this.vertices.length,1),c--,b++);return b}},{"./Line":3,"./Point":4,"./Scalar":6}],6:[function(a,b){function c(){}b.exports=c,c.eq=function(a,b,c){return c=c||0,Math.abs(a-b) (http://steffe.se)",keywords:["p2.js","p2","physics","engine","2d"],main:"./src/p2.js",engines:{node:"*"},repository:{type:"git",url:"https://github.com/schteppe/p2.js.git"},bugs:{url:"https://github.com/schteppe/p2.js/issues"},licenses:[{type:"MIT"}],devDependencies:{jshint:"latest",nodeunit:"latest",grunt:"~0.4.0","grunt-contrib-jshint":"~0.1.1","grunt-contrib-nodeunit":"~0.1.2","grunt-contrib-concat":"~0.1.3","grunt-contrib-uglify":"*","grunt-browserify":"*",browserify:"*"},dependencies:{underscore:"*","poly-decomp":"git://github.com/schteppe/poly-decomp.js","gl-matrix":"2.0.0",jsonschema:"*"}}},{}],9:[function(a,b){function c(a){this.lowerBound=d.create(),a&&a.lowerBound&&d.copy(this.lowerBound,a.lowerBound),this.upperBound=d.create(),a&&a.upperBound&&d.copy(this.upperBound,a.upperBound)}{var d=a("../math/vec2");a("../utils/Utils")}b.exports=c;var e=d.create();c.prototype.setFromPoints=function(a,b,c){var f=this.lowerBound,g=this.upperBound;d.set(f,Number.MAX_VALUE,Number.MAX_VALUE),d.set(g,-Number.MAX_VALUE,-Number.MAX_VALUE);for(var h=0;hj;j++)i[j]>g[j]&&(g[j]=i[j]),i[j]b;b++)a.lowerBound[b]this.upperBound[b]&&(this.upperBound[b]=a.upperBound[b])},c.prototype.overlaps=function(a){var b=this.lowerBound,c=this.upperBound,d=a.lowerBound,e=a.upperBound;return(d[0]<=c[0]&&c[0]<=e[0]||b[0]<=e[0]&&e[0]<=c[0])&&(d[1]<=c[1]&&c[1]<=e[1]||b[1]<=e[1]&&e[1]<=c[1])}},{"../math/vec2":33,"../utils/Utils":50}],10:[function(a,b){function c(a){this.type=a,this.result=[],this.world=null}var d=a("../math/vec2"),e=a("../objects/Body");b.exports=c,c.prototype.setWorld=function(a){this.world=a},c.prototype.getCollisionPairs=function(){throw new Error("getCollisionPairs must be implemented in a subclass!")};var f=d.create();c.boundingRadiusCheck=function(a,b){d.sub(f,a.position,b.position);var c=d.squaredLength(f),e=a.boundingRadius+b.boundingRadius;return e*e>=c},c.aabbCheck=function(a,b){return a.aabbNeedsUpdate&&a.updateAABB(),b.aabbNeedsUpdate&&b.updateAABB(),a.aabb.overlaps(b.aabb)},c.canCollide=function(a,b){return a.motionState==e.STATIC&&b.motionState==e.STATIC?!1:a.motionState==e.KINEMATIC&&b.motionState==e.STATIC||a.motionState==e.STATIC&&b.motionState==e.KINEMATIC?!1:a.motionState==e.KINEMATIC&&b.motionState==e.KINEMATIC?!1:a.sleepState==e.SLEEPING&&b.sleepState==e.SLEEPING?!1:!0},c.NAIVE=1,c.SAP=2},{"../math/vec2":33,"../objects/Body":34}],11:[function(a,b){function d(a,b,c,d,e,f){h.apply(this),e=e||10,f=f||10,this.binsizeX=(b-a)/e,this.binsizeY=(d-c)/f,this.nx=e,this.ny=f,this.xmin=a,this.ymin=c,this.xmax=b,this.ymax=d}{var e=a("../shapes/Circle"),f=a("../shapes/Plane"),g=a("../shapes/Particle"),h=a("../collision/Broadphase");a("../math/vec2")}b.exports=d,d.prototype=new h,d.prototype.getBinIndex=function(a,b){var c=this.nx,d=this.ny,e=this.xmin,f=this.ymin,g=this.xmax,h=this.ymax,i=Math.floor(c*(a-e)/(g-e)),j=Math.floor(d*(b-f)/(h-f));return i*d+j},d.prototype.getCollisionPairs=function(a){for(var b=[],d=a.bodies,i=i=d.length,j=this.binsizeX,k=this.binsizeY,l=[],m=nx*ny,n=0;m>n;n++)l.push([]);for(var o=nx/(xmax-xmin),p=ny/(ymax-ymin),n=0;n!==i;n++){var q=d[n],r=q.shape;if(void 0!==r)if(r instanceof e)for(var s=q.position[0],t=q.position[1],u=r.radius,v=Math.floor(o*(s-u-xmin)),w=Math.floor(p*(t-u-ymin)),x=Math.floor(o*(s+u-xmin)),y=Math.floor(p*(t+u-ymin)),z=v;x>=z;z++)for(var A=w;y>=A;A++){var B=z,C=A;B*(ny-1)+C>=0&&m>B*(ny-1)+C&&l[B*(ny-1)+C].push(q)}else{if(!(r instanceof f))throw new Error("Shape not supported in GridBroadphase!");if(0==q.angle)for(var t=q.position[1],z=0;z!==m&&t>ymin+k*(z-1);z++)for(var A=0;nx>A;A++){var B=A,C=Math.floor(p*(k*z-ymin));l[B*(ny-1)+C].push(q)}else if(q.angle==.5*Math.PI)for(var s=q.position[0],z=0;z!==m&&s>xmin+j*(z-1);z++)for(var A=0;ny>A;A++){var C=A,B=Math.floor(o*(j*z-xmin));l[B*(ny-1)+C].push(q)}else for(var z=0;z!==m;z++)l[z].push(q)}}for(var n=0;n!==m;n++)for(var D=l[n],z=0,E=D.length;z!==E;z++)for(var q=D[z],r=q.shape,A=0;A!==z;A++){var F=D[A],G=F.shape;r instanceof e?G instanceof e?c=h.circleCircle(q,F):G instanceof g?c=h.circleParticle(q,F):G instanceof f&&(c=h.circlePlane(q,F)):r instanceof g?G instanceof e&&(c=h.circleParticle(F,q)):r instanceof f&&G instanceof e&&(c=h.circlePlane(F,q))}return b}},{"../collision/Broadphase":10,"../math/vec2":33,"../shapes/Circle":38,"../shapes/Particle":42,"../shapes/Plane":43}],12:[function(a,b){function c(){d.call(this,d.NAIVE),this.useBoundingBoxes=!1}{var d=(a("../shapes/Circle"),a("../shapes/Plane"),a("../shapes/Shape"),a("../shapes/Particle"),a("../collision/Broadphase"));a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.getCollisionPairs=function(a){var b,c,e,f,g=a.bodies,h=this.result,i=this.useBoundingBoxes?d.aabbCheck:d.boundingRadiusCheck;for(h.length=0,b=0,Ncolliding=g.length;b!==Ncolliding;b++)for(e=g[b],c=0;b>c;c++)f=g[c],d.canCollide(e,f)&&i(e,f)&&h.push(e,f);return h}},{"../collision/Broadphase":10,"../math/vec2":33,"../shapes/Circle":38,"../shapes/Particle":42,"../shapes/Plane":43,"../shapes/Shape":45}],13:[function(a,b){function c(){this.contactEquations=[],this.frictionEquations=[],this.enableFriction=!0,this.slipForce=10,this.frictionCoefficient=.3,this.surfaceVelocity=0,this.reuseObjects=!0,this.reusableContactEquations=[],this.reusableFrictionEquations=[],this.restitution=0,this.stiffness=1e7,this.relaxation=3,this.frictionStiffness=1e7,this.frictionRelaxation=3,this.collidingBodiesLastStep={keys:[]}}function d(a){for(var b=0,c=a.keys.length;c>b;b++)delete a[a.keys[b]];a.keys.length=0}function e(a,b){g.set(a.vertices[0],.5*-b.length,-b.radius),g.set(a.vertices[1],.5*b.length,-b.radius),g.set(a.vertices[2],.5*b.length,b.radius),g.set(a.vertices[3],.5*-b.length,b.radius)}function f(a,b,c,d){for(var e=Q,f=R,j=S,k=T,l=a,m=b.vertices,n=null,o=0;o!==m.length+1;o++){var p=m[o%m.length],q=m[(o+1)%m.length];g.rotate(e,p,d),g.rotate(f,q,d),i(e,e,c),i(f,f,c),h(j,e,l),h(k,f,l);var r=g.crossLength(j,k);if(null===n&&(n=r),0>=r*n)return!1;n=r}return!0}var g=a("../math/vec2"),h=g.sub,i=g.add,j=g.dot,k=a("../utils/Utils"),l=a("../equations/ContactEquation"),m=a("../equations/FrictionEquation"),n=a("../shapes/Circle"),o=a("../shapes/Shape"),p=a("../objects/Body"),q=a("../shapes/Rectangle");b.exports=c;var r=g.fromValues(0,1),s=g.fromValues(0,0),t=g.fromValues(0,0),u=g.fromValues(0,0),v=g.fromValues(0,0),w=g.fromValues(0,0),x=g.fromValues(0,0),y=g.fromValues(0,0),z=g.fromValues(0,0),A=g.fromValues(0,0),B=g.fromValues(0,0),C=g.fromValues(0,0),D=g.fromValues(0,0),E=g.fromValues(0,0),F=g.fromValues(0,0),G=g.fromValues(0,0),H=g.fromValues(0,0),I=g.fromValues(0,0),J=g.fromValues(0,0),K=[];c.prototype.collidedLastStep=function(a,b){var c=a.id,d=b.id;if(c>d){var e=c;c=d,d=e}return!!this.collidingBodiesLastStep[c+" "+d]},c.prototype.reset=function(){d(this.collidingBodiesLastStep);for(var a=0;a!==this.contactEquations.length;a++){var b=this.contactEquations[a],c=b.bi.id,e=b.bj.id;if(c>e){var f=c;c=e,e=f}var g=c+" "+e;this.collidingBodiesLastStep[g]||(this.collidingBodiesLastStep[g]=!0,this.collidingBodiesLastStep.keys.push(g))}if(this.reuseObjects){var h=this.contactEquations,i=this.frictionEquations,j=this.reusableFrictionEquations,l=this.reusableContactEquations;k.appendArray(l,h),k.appendArray(j,i)}this.contactEquations.length=this.frictionEquations.length=0},c.prototype.createContactEquation=function(a,b,c,d){var e=this.reusableContactEquations.length?this.reusableContactEquations.pop():new l(a,b);return e.bi=a,e.bj=b,e.shapeA=c,e.shapeB=d,e.restitution=this.restitution,e.firstImpact=!this.collidedLastStep(a,b),e.stiffness=this.stiffness,e.relaxation=this.relaxation,e.enabled=!0,a.allowSleep&&a.motionState==p.DYNAMIC&&b.motionState!=p.STATIC&&b.sleepState!==p.SLEEPY&&a.wakeUp(),b.allowSleep&&b.motionState==p.DYNAMIC&&a.motionState!=p.STATIC&&a.sleepState!==p.SLEEPY&&b.wakeUp(),e},c.prototype.createFrictionEquation=function(a,b,c,d){var e=this.reusableFrictionEquations.length?this.reusableFrictionEquations.pop():new m(a,b);return e.bi=a,e.bj=b,e.shapeA=c,e.shapeB=d,e.setSlipForce(this.slipForce),e.frictionCoefficient=this.frictionCoefficient,e.relativeVelocity=this.surfaceVelocity,e.enabled=!0,e.frictionStiffness=this.frictionStiffness,e.frictionRelaxation=this.frictionRelaxation,e},c.prototype.createFrictionFromContact=function(a){var b=this.createFrictionEquation(a.bi,a.bj,a.shapeA,a.shapeB);return g.copy(b.ri,a.ri),g.copy(b.rj,a.rj),g.rotate(b.t,a.ni,-Math.PI/2),b.contactEquation=a,b},c.prototype[o.LINE|o.CONVEX]=c.prototype.convexLine=function(a,b,c,d,e,f,g,h,i){return i?!1:0},c.prototype[o.LINE|o.RECTANGLE]=c.prototype.lineRectangle=function(a,b,c,d,e,f,g,h,i){return i?!1:0};var L=new q(1,1),M=g.create();c.prototype[o.CAPSULE|o.CONVEX]=c.prototype[o.CAPSULE|o.RECTANGLE]=c.prototype.convexCapsule=function(a,b,c,d,f,h,i,j,k){var l=M;g.set(l,h.length/2,0),g.rotate(l,l,j),g.add(l,l,i);var m=this.circleConvex(f,h,l,j,a,b,c,d,k,h.radius);g.set(l,-h.length/2,0),g.rotate(l,l,j),g.add(l,l,i);var n=this.circleConvex(f,h,l,j,a,b,c,d,k,h.radius);if(k&&(m||n))return!0;var o=L;e(o,h);var p=this.convexConvex(a,b,c,d,f,o,i,j,k);return p+m+n},c.prototype[o.CAPSULE|o.LINE]=c.prototype.lineCapsule=function(a,b,c,d,e,f,g,h,i){return i?!1:0};var N=g.create(),O=g.create(),P=new q(1,1);c.prototype[o.CAPSULE|o.CAPSULE]=c.prototype.capsuleCapsule=function(a,b,c,d,f,h,i,j,k){for(var l=N,m=O,n=0,o=0;2>o;o++){g.set(l,(0==o?-1:1)*b.length/2,0),g.rotate(l,l,d),g.add(l,l,c);for(var p=0;2>p;p++){g.set(m,(0==p?-1:1)*h.length/2,0),g.rotate(m,m,j),g.add(m,m,i);var q=this.circleCircle(a,b,l,d,f,h,m,j,k,b.radius,h.radius);if(k&&q)return!0;n+=q}}var r=P;e(r,b);var s=this.convexCapsule(a,r,c,d,f,h,i,j,k);if(k&&s)return!0;n+=s,e(r,h);var t=this.convexCapsule(f,r,i,j,a,b,c,d,k);return k&&t?!0:n+=t},c.prototype[o.LINE|o.LINE]=c.prototype.lineLine=function(a,b,c,d,e,f,g,h,i){return i?!1:0},c.prototype[o.PLANE|o.LINE]=c.prototype.planeLine=function(a,b,c,d,e,f,k,l,m){var n=s,o=t,p=u,q=v,B=w,C=x,D=y,E=z,F=A,G=K;numContacts=0,g.set(n,-f.length/2,0),g.set(o,f.length/2,0),g.rotate(p,n,l),g.rotate(q,o,l),i(p,p,k),i(q,q,k),g.copy(n,p),g.copy(o,q),h(B,o,n),g.normalize(C,B),g.rotate(F,C,-Math.PI/2),g.rotate(E,r,d),G[0]=n,G[1]=o;for(var H=0;HJ){if(m)return!0;var L=this.createContactEquation(a,e,b,f);numContacts++,g.copy(L.ni,E),g.normalize(L.ni,L.ni),g.scale(D,E,J),h(L.ri,I,D),h(L.ri,L.ri,a.position),h(L.rj,I,k),i(L.rj,L.rj,k),h(L.rj,L.rj,e.position),this.contactEquations.push(L),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(L))}}return numContacts},c.prototype[o.PARTICLE|o.CAPSULE]=c.prototype.particleCapsule=function(a,b,c,d,e,f,g,h,i){return this.circleLine(a,b,c,d,e,f,g,h,i,f.radius,0)},c.prototype[o.CIRCLE|o.LINE]=c.prototype.circleLine=function(a,b,c,d,e,f,k,l,m,n,o){var p=f,q=l,r=e,G=k,H=c,I=a,J=b,n=n||0,o="undefined"!=typeof o?o:J.radius,L=s,M=t,N=u,O=v,P=w,Q=x,R=y,S=z,T=A,U=B,V=C,W=D,X=E,Y=F,Z=K;g.set(S,-p.length/2,0),g.set(T,p.length/2,0),g.rotate(U,S,q),g.rotate(V,T,q),i(U,U,G),i(V,V,G),g.copy(S,U),g.copy(T,V),h(Q,T,S),g.normalize(R,Q),g.rotate(P,R,-Math.PI/2),h(W,H,S);var $=j(W,P);if(h(O,S,G),h(X,H,G),Math.abs($)ab&&bb>_){if(m)return!0;var cb=this.createContactEquation(I,r,b,f);return g.scale(cb.ni,L,-1),g.normalize(cb.ni,cb.ni),g.scale(cb.ri,cb.ni,o),i(cb.ri,cb.ri,H),h(cb.ri,cb.ri,I.position),h(cb.rj,N,G),i(cb.rj,cb.rj,G),h(cb.rj,cb.rj,r.position),this.contactEquations.push(cb),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(cb)),1}}Z[0]=S,Z[1]=T;for(var db=0;dbW&&(g.copy(Q,O),S=W,g.scale(N,K,W),g.add(N,N,O),R=!0)}}if(R){if(m)return!0;var X=this.createContactEquation(y,q,b,j);return g.sub(X.ni,Q,x),g.normalize(X.ni,X.ni),g.scale(X.ri,X.ni,n),i(X.ri,X.ri,x),h(X.ri,X.ri,y.position),h(X.rj,N,r),i(X.rj,X.rj,r),h(X.rj,X.rj,q.position),this.contactEquations.push(X),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(X)),1}if(n>0)for(var T=0;TW&&(Q=W,g.scale(N,H,W),g.add(N,N,z),g.copy(P,H),R=!0)}if(R){var X=this.createContactEquation(A,q,b,k);return g.scale(X.ni,P,-1),g.normalize(X.ni,X.ni),g.set(X.ri,0,0),i(X.ri,X.ri,z),h(X.ri,X.ri,A.position),h(X.rj,N,r),i(X.rj,X.rj,r),h(X.rj,X.rj,q.position),this.contactEquations.push(X),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(X)),1}return 0},c.prototype[o.CIRCLE]=c.prototype.circleCircle=function(a,b,c,d,e,f,j,k,l,m,n){var o=a,p=b,q=c,r=e,t=f,u=j,v=s,m=m||p.radius,n=n||t.radius;h(v,c,j);var w=m+n;if(g.squaredLength(v)>w*w)return 0;if(l)return!0;var x=this.createContactEquation(o,r,b,f);return h(x.ni,u,q),g.normalize(x.ni,x.ni),g.scale(x.ri,x.ni,m),g.scale(x.rj,x.ni,-n),i(x.ri,x.ri,q),h(x.ri,x.ri,o.position),i(x.rj,x.rj,u),h(x.rj,x.rj,r.position),this.contactEquations.push(x),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(x)),1},c.prototype[o.PLANE|o.CONVEX]=c.prototype[o.PLANE|o.RECTANGLE]=c.prototype.planeConvex=function(a,b,c,d,e,f,k,l,m){var n=e,o=k,p=f,q=l,v=a,w=b,x=c,y=d,z=s,A=t,B=u,C=0;g.rotate(A,r,y);for(var D=0;D=2)break}}return C},c.prototype.convexPlane=function(a,b,c,d,e,f,g,h,i){return console.warn("Narrowphase.prototype.convexPlane is deprecated. Use planeConvex instead!"),this.planeConvex(e,f,g,h,a,b,c,d,i)},c.prototype[o.PARTICLE|o.PLANE]=c.prototype.particlePlane=function(a,b,c,d,e,f,i,k,l){var m=a,n=c,o=e,p=i,q=k,u=s,v=t;q=q||0,h(u,n,p),g.rotate(v,r,q);var w=j(u,v);if(w>0)return 0;if(l)return!0;var x=this.createContactEquation(o,m,f,b);return g.copy(x.ni,v),g.scale(u,x.ni,w),h(x.ri,n,u),h(x.ri,x.ri,o.position),h(x.rj,n,m.position),this.contactEquations.push(x),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(x)),1},c.prototype[o.CIRCLE|o.PARTICLE]=c.prototype.circleParticle=function(a,b,c,d,e,f,j,k,l){var m=a,n=b,o=c,p=e,q=j,r=s;if(h(r,q,o),g.squaredLength(r)>n.radius*n.radius)return 0;if(l)return!0;var t=this.createContactEquation(m,p,b,f);return g.copy(t.ni,r),g.normalize(t.ni,t.ni),g.scale(t.ri,t.ni,n.radius),i(t.ri,t.ri,o),h(t.ri,t.ri,m.position),h(t.rj,q,p.position),this.contactEquations.push(t),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(t)),1};{var U=new n(1),V=g.create(),W=g.create();g.create()}c.prototype[o.PLANE|o.CAPSULE]=c.prototype.planeCapsule=function(a,b,c,d,e,f,h,j,k){var l=V,m=W,n=U;g.set(l,-f.length/2,0),g.rotate(l,l,j),i(l,l,h),g.set(m,f.length/2,0),g.rotate(m,m,j),i(m,m,h),n.radius=f.radius;var o=this.circlePlane(e,n,l,0,a,b,c,d,k),p=this.circlePlane(e,n,m,0,a,b,c,d,k);return k?o||p:o+p},c.prototype.capsulePlane=function(a,b,c,d,e,f,g,h,i){return console.warn("Narrowphase.prototype.capsulePlane() is deprecated. Use .planeCapsule() instead!"),this.planeCapsule(e,f,g,h,a,b,c,d,i)},c.prototype[o.CIRCLE|o.PLANE]=c.prototype.circlePlane=function(a,b,c,d,e,f,k,l,m){var n=a,o=b,p=c,q=e,v=k,w=l;w=w||0;var x=s,y=t,z=u;h(x,p,v),g.rotate(y,r,w);var A=j(y,x);if(A>o.radius)return 0;if(m)return!0;var B=this.createContactEquation(q,n,f,b);return g.copy(B.ni,y),g.scale(B.rj,B.ni,-o.radius),i(B.rj,B.rj,p),h(B.rj,B.rj,n.position),g.scale(z,B.ni,A),h(B.ri,x,z),i(B.ri,B.ri,v),h(B.ri,B.ri,q.position),this.contactEquations.push(B),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(B)),1},c.convexPrecision=1e-10,c.prototype[o.CONVEX]=c.prototype[o.CONVEX|o.RECTANGLE]=c.prototype[o.RECTANGLE]=c.prototype.convexConvex=function(a,b,d,e,f,k,l,m,n,o){var p=s,q=t,r=u,x=v,B=w,C=y,D=z,E=A,F=0,o=o||c.convexPrecision,G=c.findSeparatingAxis(b,d,e,k,l,m,p);if(!G)return 0;h(D,l,d),j(p,D)>0&&g.scale(p,p,-1);var H=c.getClosestEdge(b,e,p,!0),I=c.getClosestEdge(k,m,p);if(-1==H||-1==I)return 0;for(var J=0;2>J;J++){var K=H,L=I,M=b,N=k,O=d,P=l,Q=e,R=m,S=a,T=f;if(0==J){var U;U=K,K=L,L=U,U=M,M=N,N=U,U=O,O=P,P=U,U=Q,Q=R,R=U,U=S,S=T,T=U}for(var V=L;L+2>V;V++){var W=N.vertices[(V+N.vertices.length)%N.vertices.length];g.rotate(q,W,R),i(q,q,P);for(var X=0,Y=K-1;K+2>Y;Y++){var Z=M.vertices[(Y+M.vertices.length)%M.vertices.length],$=M.vertices[(Y+1+M.vertices.length)%M.vertices.length];g.rotate(r,Z,Q),g.rotate(x,$,Q),i(r,r,O),i(x,x,O),h(B,x,r),g.rotate(E,B,-Math.PI/2),g.normalize(E,E),h(D,q,r);var _=j(E,D);o>=_&&X++}if(3==X){if(n)return!0;var ab=this.createContactEquation(S,T,M,N);F++;var Z=M.vertices[K%M.vertices.length],$=M.vertices[(K+1)%M.vertices.length];g.rotate(r,Z,Q),g.rotate(x,$,Q),i(r,r,O),i(x,x,O),h(B,x,r),g.rotate(ab.ni,B,-Math.PI/2),g.normalize(ab.ni,ab.ni),h(D,q,r);var _=j(ab.ni,D);g.scale(C,ab.ni,_),h(ab.ri,q,O),h(ab.ri,ab.ri,C),i(ab.ri,ab.ri,O),h(ab.ri,ab.ri,S.position),h(ab.rj,q,P),i(ab.rj,ab.rj,P),h(ab.rj,ab.rj,T.position),this.contactEquations.push(ab),this.enableFriction&&this.frictionEquations.push(this.createFrictionFromContact(ab))}}}return F};var X=g.fromValues(0,0);c.projectConvexOntoAxis=function(a,b,c,d,e){var f,h,i=null,k=null,l=X;g.rotate(l,d,-c);for(var m=0;mi)&&(i=h),(null===k||k>h)&&(k=h);if(k>i){var n=k;k=i,i=n}var o=j(b,d);g.set(e,k+o,i+o)};var Y=g.fromValues(0,0),Z=g.fromValues(0,0),$=g.fromValues(0,0),_=g.fromValues(0,0),ab=g.fromValues(0,0),bb=g.fromValues(0,0);c.findSeparatingAxis=function(a,b,d,e,f,i,j){for(var k=null,l=!1,m=!1,n=Y,o=Z,p=$,q=_,r=ab,s=bb,t=0;2!==t;t++){var u=a,v=d;1===t&&(u=e,v=i);for(var w=0;w!==u.vertices.length;w++){g.rotate(o,u.vertices[w],v),g.rotate(p,u.vertices[(w+1)%u.vertices.length],v),h(n,p,o),g.rotate(q,n,-Math.PI/2),g.normalize(q,q),c.projectConvexOntoAxis(a,b,d,q,r),c.projectConvexOntoAxis(e,f,i,q,s);var x=r,y=s,z=!1;r[0]>s[0]&&(y=r,x=s,z=!0);var A=y[0]-x[1];l=0>A,(null===k||A>k)&&(g.copy(j,q),k=A,m=l)}}return m};var cb=g.fromValues(0,0),db=g.fromValues(0,0),eb=g.fromValues(0,0);c.getClosestEdge=function(a,b,c,d){var e=cb,f=db,i=eb;g.rotate(e,c,-b),d&&g.scale(e,e,-1);for(var k=-1,l=a.vertices.length,m=Math.PI/2,n=0;n!==l;n++){h(f,a.vertices[(n+1)%l],a.vertices[n%l]),g.rotate(i,f,-m),g.normalize(i,i);var o=j(i,e);(-1==k||o>maxDot)&&(k=n%l,maxDot=o)}return k};var fb=g.create(),gb=g.create(),hb=g.create(),ib=g.create(),jb=g.create(),kb=g.create(),lb=g.create();c.prototype[o.CIRCLE|o.HEIGHTFIELD]=c.prototype.circleHeightfield=function(a,b,c,d,e,f,j,k,l,m){var n=f.data,m=m||b.radius,o=f.elementWidth,p=gb,q=fb,r=jb,s=lb,t=kb,u=hb,v=ib,w=Math.floor((c[0]-m-j[0])/o),x=Math.ceil((c[0]+m-j[0])/o); +0>w&&(w=0),x>=n.length&&(x=n.length-1);for(var y=n[w],z=n[x],A=w;x>A;A++)n[A]y&&(y=n[A]);if(c[1]-m>y)return l?!1:0;c[1]+mA;A++){g.set(u,A*o,n[A]),g.set(v,(A+1)*o,n[A+1]),g.add(u,u,j),g.add(v,v,j),g.sub(t,v,u),g.rotate(t,t,Math.PI/2),g.normalize(t,t),g.scale(q,t,-m),g.add(q,q,c),g.sub(p,q,u);var D=g.dot(p,t);if(q[0]>=u[0]&&q[0]=D&&(C===!1||Math.abs(D)0)for(var A=w;x>=A;A++)if(g.set(u,A*o,n[A]),g.add(u,u,j),g.sub(p,c,u),g.squaredLength(p)c;c++)this.root.insert(a[c]);else this.root.insert(a)},c.prototype.clear=function(){this.root.clear()},c.prototype.retrieve=function(a){var b=this.root.retrieve(a).slice(0);return b},c.prototype.getCollisionPairs=function(a){var b=[];this.insert(a.bodies);for(var c=0;c!==a.bodies.length;c++)for(var d=a.bodies[c],e=this.retrieve(d),f=0,h=e.length;f!==h;f++){var i=e[f];if(d!==i){for(var j=!1,k=0,l=b.length;l>k;k+=2){var m=b[k],n=b[k+1];if(m==i&&n==d||n==i&&m==d){j=!0;break}}!j&&g.boundingRadiusCheck(d,i)&&b.push(d,i)}}return this.clear(),b},d.prototype.classConstructor=d,d.prototype.children=null,d.prototype.depth=0,d.prototype.maxChildren=4,d.prototype.maxDepth=4,d.TOP_LEFT=0,d.TOP_RIGHT=1,d.BOTTOM_LEFT=2,d.BOTTOM_RIGHT=3,d.prototype.insert=function(a){if(this.nodes.length){var b=this.findIndex(a);return void this.nodes[b].insert(a)}this.children.push(a);var c=this.children.length;if(!(this.depth>=this.maxDepth)&&c>this.maxChildren){this.subdivide();for(var d=0;c>d;d++)this.insert(this.children[d]);this.children.length=0}},d.prototype.retrieve=function(a){if(this.nodes.length){var b=this.findIndex(a);return this.nodes[b].retrieve(a)}return this.children},d.prototype.findIndex=function(a){var b=this.bounds,c=a.position[0]-a.boundingRadius>b.x+b.width/2?!1:!0,e=a.position[1]-a.boundingRadius>b.y+b.height/2?!1:!0;a instanceof f&&(c=e=!1);var g=d.TOP_LEFT;return c?e||(g=d.BOTTOM_LEFT):g=e?d.TOP_RIGHT:d.BOTTOM_RIGHT,g},d.prototype.subdivide=function(){var a=this.depth+1,b=this.bounds.x,c=this.bounds.y,e=this.bounds.width/2,f=this.bounds.height/2,g=b+e,h=c+f;this.nodes[d.TOP_LEFT]=new this.classConstructor({x:b,y:c,width:e,height:f},a),this.nodes[d.TOP_RIGHT]=new this.classConstructor({x:g,y:c,width:e,height:f},a),this.nodes[d.BOTTOM_LEFT]=new this.classConstructor({x:b,y:h,width:e,height:f},a),this.nodes[d.BOTTOM_RIGHT]=new this.classConstructor({x:g,y:h,width:e,height:f},a)},d.prototype.clear=function(){this.children.length=0;for(var a=this.nodes.length,b=0;a>b;b++)this.nodes[b].clear();this.nodes.length=0},e.prototype=new d,e.prototype.classConstructor=e,e.prototype.stuckChildren=null,e.prototype.out=[],e.prototype.insert=function(a){if(this.nodes.length){var b=this.findIndex(a),c=this.nodes[b];return void(!(a instanceof f)&&a.position[0]-a.boundingRadius>=c.bounds.x&&a.position[0]+a.boundingRadius<=c.bounds.x+c.bounds.width&&a.position[1]-a.boundingRadius>=c.bounds.y&&a.position[1]+a.boundingRadius<=c.bounds.y+c.bounds.height?this.nodes[b].insert(a):this.stuckChildren.push(a))}this.children.push(a);var d=this.children.length;if(this.depththis.maxChildren){this.subdivide();for(var e=0;d>e;e++)this.insert(this.children[e]);this.children.length=0}},e.prototype.getChildren=function(){return this.children.concat(this.stuckChildren)},e.prototype.retrieve=function(a){var b=this.out;if(b.length=0,this.nodes.length){var c=this.findIndex(a);b.push.apply(b,this.nodes[c].retrieve(a))}return b.push.apply(b,this.stuckChildren),b.push.apply(b,this.children),b},e.prototype.clear=function(){this.stuckChildren.length=0,this.children.length=0;var a=this.nodes.length;if(a){for(var b=0;a>b;b++)this.nodes[b].clear();this.nodes.length=0}}},{"../collision/Broadphase":10,"../shapes/Plane":43}],15:[function(a,b){function c(){e.call(this,e.SAP),this.axisListX=[],this.axisListY=[],this.world=null;var a=this.axisListX,b=this.axisListY;this._addBodyHandler=function(c){a.push(c.body),b.push(c.body)},this._removeBodyHandler=function(c){var d=a.indexOf(c.body);-1!==d&&a.splice(d,1),d=b.indexOf(c.body),-1!==d&&b.splice(d,1)}}{var d=(a("../shapes/Circle"),a("../shapes/Plane"),a("../shapes/Shape"),a("../shapes/Particle"),a("../utils/Utils")),e=a("../collision/Broadphase");a("../math/vec2")}b.exports=c,c.prototype=new e,c.prototype.setWorld=function(a){this.axisListX.length=this.axisListY.length=0,d.appendArray(this.axisListX,a.bodies),d.appendArray(this.axisListY,a.bodies),a.off("addBody",this._addBodyHandler).off("removeBody",this._removeBodyHandler),a.on("addBody",this._addBodyHandler).on("removeBody",this._removeBodyHandler),this.world=a},c.sortAxisListX=function(a){for(var b=1,c=a.length;c>b;b++){for(var d=a[b],e=b-1;e>=0&&!(a[e].aabb.lowerBound[0]<=d.aabb.lowerBound[0]);e--)a[e+1]=a[e];a[e+1]=d}return a},c.sortAxisListY=function(a){for(var b=1,c=a.length;c>b;b++){for(var d=a[b],e=b-1;e>=0&&!(a[e].aabb.lowerBound[1]<=d.aabb.lowerBound[1]);e--)a[e+1]=a[e];a[e+1]=d}return a};var f={keys:[]};c.prototype.getCollisionPairs=function(){{var a,b,d=this.axisListX,g=this.axisListY,h=this.result;this.axisIndex}for(h.length=0,a=0;a!==d.length;a++){var i=d[a];i.aabbNeedsUpdate&&i.updateAABB()}for(c.sortAxisListX(d),c.sortAxisListY(g),a=0,N=d.length;a!==N;a++){var j=d[a];for(b=a+1;N>b;b++){var k=d[b];if(!c.checkBounds(j,k,0))break;if(e.canCollide(j,k)){var l=j.idb;b++){var k=g[b];if(!c.checkBounds(j,k,1))break;if(e.canCollide(j,k)){var l=j.idc)g.scale(e.ni,i,-1),g.sub(e.ri,j,h.position),g.sub(e.rj,k,o.position),g.scale(n,i,c),g.add(e.ri,e.ri,n),-1==a.indexOf(e)&&a.push(e);else{var u=a.indexOf(e);-1!=u&&a.splice(u,1)}if(this.lowerLimitEnabled&&d>s)g.scale(f.ni,i,1),g.sub(f.ri,j,h.position),g.sub(f.rj,k,o.position),g.scale(n,i,d),g.sub(f.rj,f.rj,n),-1==a.indexOf(f)&&a.push(f);else{var u=a.indexOf(f);-1!=u&&a.splice(u,1)}},c.prototype.enableMotor=function(){this.motorEnabled||(this.equations.push(this.motorEquation),this.motorEnabled=!0)},c.prototype.disableMotor=function(){if(this.motorEnabled){var a=this.equations.indexOf(this.motorEquation);this.equations.splice(a,1),this.motorEnabled=!1}}},{"../equations/ContactEquation":23,"../equations/Equation":24,"../equations/RotationalLockEquation":26,"../math/vec2":33,"./Constraint":16}],21:[function(a,b){function c(a,b,c,n,o){d.call(this,a,c,d.REVOLUTE),o=this.maxForce="undefined"!=typeof o?o:Number.MAX_VALUE,this.pivotA=b,this.pivotB=n;var p=this.equations=[new e(a,c,-o,o),new e(a,c,-o,o)],q=p[0],r=p[1];q.computeGq=function(){return h.rotate(i,b,a.angle),h.rotate(j,n,c.angle),h.add(m,c.position,j),h.sub(m,m,a.position),h.sub(m,m,i),h.dot(m,k)},r.computeGq=function(){return h.rotate(i,b,a.angle),h.rotate(j,n,c.angle),h.add(m,c.position,j),h.sub(m,m,a.position),h.sub(m,m,i),h.dot(m,l)},r.minForce=q.minForce=-o,r.maxForce=q.maxForce=o,this.motorEquation=new f(a,c),this.motorEnabled=!1,this.angle=0,this.lowerLimitEnabled=!1,this.upperLimitEnabled=!1,this.lowerLimit=0,this.upperLimit=0,this.upperLimitEquation=new g(a,c),this.lowerLimitEquation=new g(a,c),this.upperLimitEquation.minForce=0,this.lowerLimitEquation.maxForce=0}var d=a("./Constraint"),e=a("../equations/Equation"),f=a("../equations/RotationalVelocityEquation"),g=a("../equations/RotationalLockEquation"),h=a("../math/vec2");b.exports=c;var i=h.create(),j=h.create(),k=h.fromValues(1,0),l=h.fromValues(0,1),m=h.create();c.prototype=new d,c.prototype.update=function(){var a=this.bodyA,b=this.bodyB,c=this.pivotA,d=this.pivotB,e=this.equations,f=(e[0],e[1],e[0]),g=e[1],m=this.upperLimit,n=this.lowerLimit,o=this.upperLimitEquation,p=this.lowerLimitEquation,q=this.angle=b.angle-a.angle;if(this.upperLimitEnabled&&q>m)o.angle=m,-1==e.indexOf(o)&&e.push(o);else{var r=e.indexOf(o);-1!=r&&e.splice(r,1)}if(this.lowerLimitEnabled&&n>q)p.angle=n,-1==e.indexOf(p)&&e.push(p);else{var r=e.indexOf(p);-1!=r&&e.splice(r,1)}h.rotate(i,c,a.angle),h.rotate(j,d,b.angle),f.G[0]=-1,f.G[1]=0,f.G[2]=-h.crossLength(i,k),f.G[3]=1,f.G[4]=0,f.G[5]=h.crossLength(j,k),g.G[0]=0,g.G[1]=-1,g.G[2]=-h.crossLength(i,l),g.G[3]=0,g.G[4]=1,g.G[5]=h.crossLength(j,l)},c.prototype.enableMotor=function(){this.motorEnabled||(this.equations.push(this.motorEquation),this.motorEnabled=!0)},c.prototype.disableMotor=function(){if(this.motorEnabled){var a=this.equations.indexOf(this.motorEquation);this.equations.splice(a,1),this.motorEnabled=!1}},c.prototype.motorIsEnabled=function(){return!!this.motorEnabled},c.prototype.setMotorSpeed=function(a){if(this.motorEnabled){var b=this.equations.indexOf(this.motorEquation);this.equations[b].relativeVelocity=a}},c.prototype.getMotorSpeed=function(){return this.motorEnabled?this.motorEquation.relativeVelocity:!1}},{"../equations/Equation":24,"../equations/RotationalLockEquation":26,"../equations/RotationalVelocityEquation":27,"../math/vec2":33,"./Constraint":16}],22:[function(a,b){function c(a,b,c){c=c||{},d.call(this,a,b,-Number.MAX_VALUE,Number.MAX_VALUE),this.angle=c.angle||0,this.ratio="number"==typeof c.ratio?c.ratio:1,this.setRatio(this.ratio)}{var d=a("./Equation");a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.constructor=c,c.prototype.computeGq=function(){return this.ratio*this.bi.angle-this.bj.angle+this.angle},c.prototype.setRatio=function(a){var b=this.G;b[2]=a,b[5]=-1,this.ratio=a}},{"../math/vec2":33,"./Equation":24}],23:[function(a,b){function c(a,b){d.call(this,a,b,0,Number.MAX_VALUE),this.ri=e.create(),this.penetrationVec=e.create(),this.rj=e.create(),this.ni=e.create(),this.restitution=0,this.firstImpact=!1,this.shapeA=null,this.shapeB=null}{var d=a("./Equation"),e=a("../math/vec2");a("../math/mat2")}b.exports=c,c.prototype=new d,c.prototype.constructor=c,c.prototype.computeB=function(a,b,c){var d=this.bi,f=this.bj,g=this.ri,h=this.rj,i=d.position,j=f.position,k=this.penetrationVec,l=this.ni,m=this.G,n=e.crossLength(g,l),o=e.crossLength(h,l);m[0]=-l[0],m[1]=-l[1],m[2]=-n,m[3]=l[0],m[4]=l[1],m[5]=o,e.add(k,j,h),e.sub(k,k,i),e.sub(k,k,g);var p,q;this.firstImpact&&0!==this.restitution?(q=0,p=1/b*(1+this.restitution)*this.computeGW()):(q=e.dot(l,k),p=this.computeGW());var r=this.computeGiMf(),s=-q*a-p*b-c*r;return s}},{"../math/mat2":31,"../math/vec2":33,"./Equation":24}],24:[function(a,b){function c(a,b,c,d){this.minForce="undefined"==typeof c?-1e6:c,this.maxForce="undefined"==typeof d?1e6:d,this.bi=a,this.bj=b,this.stiffness=1e6,this.relaxation=4,this.G=new g.ARRAY_TYPE(6);for(var e=0;6>e;e++)this.G[e]=0;this.offset=0,this.a=0,this.b=0,this.eps=0,this.h=0,this.updateSpookParams(1/60),this.multiplier=0,this.relativeVelocity=0,this.enabled=!0}function d(a,b,c,d,e){return a[0]*b[0]+a[1]*b[1]+a[2]*c+a[3]*d[0]+a[4]*d[1]+a[5]*e}b.exports=c;var e=a("../math/vec2"),f=a("../math/mat2"),g=a("../utils/Utils");c.prototype.constructor=c,c.prototype.updateSpookParams=function(a){var b=this.stiffness,c=this.relaxation,d=a;this.a=4/(d*(1+4*c)),this.b=4*c/(1+4*c),this.eps=4/(d*d*b*(1+4*c)),this.h=a},c.prototype.computeB=function(a,b,c){var d=this.computeGW(),e=this.computeGq(),f=this.computeGiMf();return-e*a-d*b-f*c};var h=e.create(),i=e.create();c.prototype.computeGq=function(){var a=this.G,b=this.bi,c=this.bj,e=(b.position,c.position,b.angle),f=c.angle;return d(a,h,e,i,f)+this.offset};e.create(),e.create();c.prototype.transformedGmult=function(a,b,c,e,f){return d(a,b,c,e,f)},c.prototype.computeGW=function(){var a=this.G,b=this.bi,c=this.bj,d=b.velocity,e=c.velocity,f=b.angularVelocity,g=c.angularVelocity;return this.transformedGmult(a,d,f,e,g)+this.relativeVelocity},c.prototype.computeGWlambda=function(){var a=this.G,b=this.bi,c=this.bj,e=b.vlambda,f=c.vlambda,g=b.wlambda,h=c.wlambda;return d(a,e,g,f,h)};var j=e.create(),k=e.create();c.prototype.computeGiMf=function(){var a=this.bi,b=this.bj,c=a.force,d=a.angularForce,f=b.force,g=b.angularForce,h=a.invMass,i=b.invMass,l=a.invInertia,m=b.invInertia,n=this.G;return e.scale(j,c,h),e.scale(k,f,i),this.transformedGmult(n,j,d*l,k,g*m)},c.prototype.computeGiMGt=function(){var a=this.bi,b=this.bj,c=a.invMass,d=b.invMass,e=a.invInertia,f=b.invInertia,g=this.G;return g[0]*g[0]*c+g[1]*g[1]*c+g[2]*g[2]*e+g[3]*g[3]*d+g[4]*g[4]*d+g[5]*g[5]*f};{var l=e.create(),m=e.create(),n=e.create();e.create(),e.create(),e.create(),f.create(),f.create()}c.prototype.addToWlambda=function(a){var b=this.bi,c=this.bj,d=l,f=m,g=n,h=this.G;f[0]=h[0],f[1]=h[1],g[0]=h[3],g[1]=h[4],e.scale(d,f,b.invMass*a),e.add(b.vlambda,b.vlambda,d),e.scale(d,g,c.invMass*a),e.add(c.vlambda,c.vlambda,d),b.wlambda+=b.invInertia*h[2]*a,c.wlambda+=c.invInertia*h[5]*a},c.prototype.computeInvC=function(a){return 1/(this.computeGiMGt()+a)}},{"../math/mat2":31,"../math/vec2":33,"../utils/Utils":50}],25:[function(a,b){function c(a,b,c){e.call(this,a,b,-c,c),this.ri=d.create(),this.rj=d.create(),this.t=d.create(),this.contactEquation=null,this.shapeA=null,this.shapeB=null,this.frictionCoefficient=.3}{var d=(a("../math/mat2"),a("../math/vec2")),e=a("./Equation");a("../utils/Utils")}b.exports=c,c.prototype=new e,c.prototype.constructor=c,c.prototype.setSlipForce=function(a){this.maxForce=a,this.minForce=-a},c.prototype.computeB=function(a,b,c){var e=(this.bi,this.bj,this.ri),f=this.rj,g=this.t,h=this.G;h[0]=-g[0],h[1]=-g[1],h[2]=-d.crossLength(e,g),h[3]=g[0],h[4]=g[1],h[5]=d.crossLength(f,g);var i=this.computeGW(),j=this.computeGiMf(),k=-i*b-c*j;return k}},{"../math/mat2":31,"../math/vec2":33,"../utils/Utils":50,"./Equation":24}],26:[function(a,b){function c(a,b,c){c=c||{},d.call(this,a,b,-Number.MAX_VALUE,Number.MAX_VALUE),this.angle=c.angle||0;var e=this.G;e[2]=1,e[5]=-1}var d=a("./Equation"),e=a("../math/vec2");b.exports=c,c.prototype=new d,c.prototype.constructor=c;var f=e.create(),g=e.create(),h=e.fromValues(1,0),i=e.fromValues(0,1);c.prototype.computeGq=function(){return e.rotate(f,h,this.bi.angle+this.angle),e.rotate(g,i,this.bj.angle),e.dot(f,g)}},{"../math/vec2":33,"./Equation":24}],27:[function(a,b){function c(a,b){d.call(this,a,b,-Number.MAX_VALUE,Number.MAX_VALUE),this.relativeVelocity=1,this.ratio=1}{var d=a("./Equation");a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.constructor=c,c.prototype.computeB=function(a,b,c){var d=this.G;d[2]=-1,d[5]=this.ratio;var e=this.computeGiMf(),f=this.computeGW(),g=-f*b-c*e;return g}},{"../math/vec2":33,"./Equation":24}],28:[function(a,b){var c=function(){};b.exports=c,c.prototype={constructor:c,on:function(a,b,c){b.context=c||this,void 0===this._listeners&&(this._listeners={});var d=this._listeners;return void 0===d[a]&&(d[a]=[]),-1===d[a].indexOf(b)&&d[a].push(b),this},has:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},off:function(a,b){if(void 0===this._listeners)return this;var c=this._listeners,d=c[a].indexOf(b);return-1!==d&&c[a].splice(d,1),this},emit:function(a){if(void 0===this._listeners)return this;var b=this._listeners,c=b[a.type];if(void 0!==c){a.target=this;for(var d=0,e=c.length;e>d;d++){var f=c[d];f.call(f.context,a)}}return this}}},{}],29:[function(a,b){function c(a,b,e){if(e=e||{},!(a instanceof d&&b instanceof d))throw new Error("First two arguments must be Material instances.");this.id=c.idCounter++,this.materialA=a,this.materialB=b,this.friction="undefined"!=typeof e.friction?Number(e.friction):.3,this.restitution="undefined"!=typeof e.restitution?Number(e.restitution):0,this.stiffness="undefined"!=typeof e.stiffness?Number(e.stiffness):1e7,this.relaxation="undefined"!=typeof e.relaxation?Number(e.relaxation):3,this.frictionStiffness="undefined"!=typeof e.frictionStiffness?Number(e.frictionStiffness):1e7,this.frictionRelaxation="undefined"!=typeof e.frictionRelaxation?Number(e.frictionRelaxation):3,this.surfaceVelocity="undefined"!=typeof e.surfaceVelocity?Number(e.surfaceVelocity):0}var d=a("./Material");b.exports=c,c.idCounter=0},{"./Material":30}],30:[function(a,b){function c(){this.id=c.idCounter++}b.exports=c,c.idCounter=0},{}],31:[function(a,b){var c=a("../../node_modules/gl-matrix/src/gl-matrix/mat2").mat2;b.exports=c},{"../../node_modules/gl-matrix/src/gl-matrix/mat2":1}],32:[function(a,b){var c={};c.GetArea=function(a){if(a.length<6)return 0;for(var b=a.length-2,c=0,d=0;b>d;d+=2)c+=(a[d+2]-a[d])*(a[d+1]+a[d+3]);return c+=(a[0]-a[b])*(a[b+1]+a[1]),.5*-c},c.Triangulate=function(a){var b=a.length>>1;if(3>b)return[];for(var d=[],e=[],f=0;b>f;f++)e.push(f);for(var f=0,g=b;g>3;){var h=e[(f+0)%g],i=e[(f+1)%g],j=e[(f+2)%g],k=a[2*h],l=a[2*h+1],m=a[2*i],n=a[2*i+1],o=a[2*j],p=a[2*j+1],q=!1;if(c._convex(k,l,m,n,o,p)){q=!0;for(var r=0;g>r;r++){var s=e[r];if(s!=h&&s!=i&&s!=j&&c._PointInTriangle(a[2*s],a[2*s+1],k,l,m,n,o,p)){q=!1;break}}}if(q)d.push(h,i,j),e.splice((f+1)%g,1),g--,f=0;else if(f++>3*g)break}return d.push(e[0],e[1],e[2]),d},c._PointInTriangle=function(a,b,c,d,e,f,g,h){var i=g-c,j=h-d,k=e-c,l=f-d,m=a-c,n=b-d,o=i*i+j*j,p=i*k+j*l,q=i*m+j*n,r=k*k+l*l,s=k*m+l*n,t=1/(o*r-p*p),u=(r*q-p*s)*t,v=(o*s-p*q)*t;return u>=0&&v>=0&&1>u+v},c._convex=function(a,b,c,d,e,f){return(b-d)*(e-c)+(c-a)*(f-d)>=0},b.exports=c},{}],33:[function(a,b){var c=a("../../node_modules/gl-matrix/src/gl-matrix/vec2").vec2;c.getX=function(a){return a[0]},c.getY=function(a){return a[1]},c.crossLength=function(a,b){return a[0]*b[1]-a[1]*b[0]},c.crossVZ=function(a,b,d){return c.rotate(a,b,-Math.PI/2),c.scale(a,a,d),a},c.crossZV=function(a,b,d){return c.rotate(a,d,Math.PI/2),c.scale(a,a,b),a},c.rotate=function(a,b,c){var d=Math.cos(c),e=Math.sin(c),f=b[0],g=b[1];a[0]=d*f-e*g,a[1]=e*f+d*g},c.toLocalFrame=function(a,b,d,e){c.copy(a,b),c.sub(a,a,d),c.rotate(a,a,-e)},c.toGlobalFrame=function(a,b,d,e){c.copy(a,b),c.rotate(a,a,e),c.add(a,a,d)},c.centroid=function(a,b,d,e){return c.add(a,b,d),c.add(a,a,e),c.scale(a,a,1/3),a},b.exports=c},{"../../node_modules/gl-matrix/src/gl-matrix/vec2":2}],34:[function(a,b){function c(a){a=a||{},h.call(this),this.id=++c._idCounter,this.world=null,this.shapes=[],this.shapeOffsets=[],this.shapeAngles=[],this.mass=a.mass||0,this.invMass=0,this.inertia=0,this.invInertia=0,this.fixedRotation=!!a.fixedRotation||!1,this.position=d.fromValues(0,0),a.position&&d.copy(this.position,a.position),this.interpolatedPosition=d.fromValues(0,0),this.velocity=d.fromValues(0,0),a.velocity&&d.copy(this.velocity,a.velocity),this.vlambda=d.fromValues(0,0),this.wlambda=0,this.angle=a.angle||0,this.angularVelocity=a.angularVelocity||0,this.force=d.create(),a.force&&d.copy(this.force,a.force),this.angularForce=a.angularForce||0,this.damping="number"==typeof a.damping?a.damping:.1,this.angularDamping="number"==typeof a.angularDamping?a.angularDamping:.1,this.motionState=0==this.mass?c.STATIC:c.DYNAMIC,this.boundingRadius=0,this.aabb=new g,this.aabbNeedsUpdate=!0,this.allowSleep=!1,this.sleepState=c.AWAKE,this.sleepSpeedLimit=.1,this.sleepTimeLimit=1,this.gravityScale=1,this.timeLastSleepy=0,this.concavePath=null,this.lastDampingScale=1,this.lastAngularDampingScale=1,this.lastDampingTimeStep=-1,this.updateMassProperties()}var d=a("../math/vec2"),e=a("poly-decomp"),f=a("../shapes/Convex"),g=a("../collision/AABB"),h=a("../events/EventEmitter");b.exports=c,c.prototype=new h,c._idCounter=0,c.prototype.setDensity=function(a){var b=this.getArea();this.mass=b*a,this.updateMassProperties()},c.prototype.getArea=function(){for(var a=0,b=0;be&&(e=h+i)}this.boundingRadius=e},c.prototype.addShape=function(a,b,c){c=c||0,b=b?d.fromValues(b[0],b[1]):d.fromValues(0,0),this.shapes.push(a),this.shapeOffsets.push(b),this.shapeAngles.push(c),this.updateMassProperties(),this.updateBoundingRadius(),this.aabbNeedsUpdate=!0},c.prototype.removeShape=function(a){var b=this.shapes.indexOf(a);return-1!=b?(this.shapes.splice(b,1),this.shapeOffsets.splice(b,1),this.shapeAngles.splice(b,1),this.aabbNeedsUpdate=!0,!0):!1},c.prototype.updateMassProperties=function(){if(this.motionState==c.STATIC||this.motionState==c.KINEMATIC)this.mass=Number.MAX_VALUE,this.invMass=0,this.inertia=Number.MAX_VALUE,this.invInertia=0;else{var a=this.shapes,b=a.length,e=this.mass/b,f=0;if(this.fixedRotation)this.inertia=Number.MAX_VALUE,this.invInertia=0;else{for(var g=0;b>g;g++){var h=a[g],i=d.squaredLength(this.shapeOffsets[g]),j=h.computeMomentOfInertia(e);f+=j+e*i}this.inertia=f,this.invInertia=f>0?1/f:0}this.invMass=1/this.mass}};var k=d.create();c.prototype.applyForce=function(a,b){var c=k;d.sub(c,b,this.position),d.add(this.force,this.force,a);var e=d.crossLength(c,a);this.angularForce+=e},c.prototype.toLocalFrame=function(a,b){d.toLocalFrame(a,b,this.position,this.angle)},c.prototype.toWorldFrame=function(a,b){d.toGlobalFrame(a,b,this.position,this.angle)},c.prototype.fromPolygon=function(a,b){b=b||{};for(var c=this.shapes.length;c>=0;--c)this.removeShape(this.shapes[c]);var g=new e.Polygon;if(g.vertices=a,g.makeCCW(),"number"==typeof b.removeCollinearPoints&&g.removeCollinearPoints(b.removeCollinearPoints),"undefined"==typeof b.skipSimpleCheck&&!g.isSimple())return!1;this.concavePath=g.vertices.slice(0);for(var c=0;ce?(this.sleepState=c.SLEEPY,this.timeLastSleepy=a,this.emit(c.sleepyEvent)):b===c.SLEEPY&&e>f?this.wakeUp():b===c.SLEEPY&&a-this.timeLastSleepy>this.sleepTimeLimit&&this.sleep()}},c.sleepyEvent={type:"sleepy"},c.sleepEvent={type:"sleep"},c.wakeUpEvent={type:"wakeup"},c.DYNAMIC=1,c.STATIC=2,c.KINEMATIC=4,c.AWAKE=0,c.SLEEPY=1,c.SLEEPING=2},{"../collision/AABB":9,"../events/EventEmitter":28,"../math/vec2":33,"../shapes/Convex":39,"poly-decomp":7}],35:[function(a,b){function c(a,b,c){c=c||{},this.restLength="number"==typeof c.restLength?c.restLength:1,this.stiffness=c.stiffness||100,this.damping=c.damping||1,this.bodyA=a,this.bodyB=b,this.localAnchorA=d.fromValues(0,0),this.localAnchorB=d.fromValues(0,0),c.localAnchorA&&d.copy(this.localAnchorA,c.localAnchorA),c.localAnchorB&&d.copy(this.localAnchorB,c.localAnchorB),c.worldAnchorA&&this.setWorldAnchorA(c.worldAnchorA),c.worldAnchorB&&this.setWorldAnchorB(c.worldAnchorB)}var d=a("../math/vec2");b.exports=c,c.prototype.setWorldAnchorA=function(a){this.bodyA.toLocalFrame(this.localAnchorA,a)},c.prototype.setWorldAnchorB=function(a){this.bodyB.toLocalFrame(this.localAnchorB,a)},c.prototype.getWorldAnchorA=function(a){this.bodyA.toWorldFrame(a,this.localAnchorA) +},c.prototype.getWorldAnchorB=function(a){this.bodyB.toWorldFrame(a,this.localAnchorB)};var e=d.create(),f=d.create(),g=d.create(),h=d.create(),i=d.create(),j=d.create(),k=d.create(),l=d.create(),m=d.create();c.prototype.applyForce=function(){var a=this.stiffness,b=this.damping,c=this.restLength,n=this.bodyA,o=this.bodyB,p=e,q=f,r=g,s=h,t=m,u=i,v=j,w=k,x=l;this.getWorldAnchorA(u),this.getWorldAnchorB(v),d.sub(w,u,n.position),d.sub(x,v,o.position),d.sub(p,v,u);var y=d.len(p);d.normalize(q,p),d.sub(r,o.velocity,n.velocity),d.crossZV(t,o.angularVelocity,x),d.add(r,r,t),d.crossZV(t,n.angularVelocity,w),d.sub(r,r,t),d.scale(s,q,-a*(y-c)-b*d.dot(r,q)),d.sub(n.force,n.force,s),d.add(o.force,o.force,s);var z=d.crossLength(w,s),A=d.crossLength(x,s);n.angularForce-=z,o.angularForce+=A}},{"../math/vec2":33}],36:[function(a,b){b.exports={AABB:a("./collision/AABB"),AngleLockEquation:a("./equations/AngleLockEquation"),Body:a("./objects/Body"),Broadphase:a("./collision/Broadphase"),Capsule:a("./shapes/Capsule"),Circle:a("./shapes/Circle"),Constraint:a("./constraints/Constraint"),ContactEquation:a("./equations/ContactEquation"),ContactMaterial:a("./material/ContactMaterial"),Convex:a("./shapes/Convex"),DistanceConstraint:a("./constraints/DistanceConstraint"),Equation:a("./equations/Equation"),EventEmitter:a("./events/EventEmitter"),FrictionEquation:a("./equations/FrictionEquation"),GearConstraint:a("./constraints/GearConstraint"),GridBroadphase:a("./collision/GridBroadphase"),GSSolver:a("./solver/GSSolver"),Heightfield:a("./shapes/Heightfield"),Island:a("./solver/IslandSolver"),IslandSolver:a("./solver/IslandSolver"),Line:a("./shapes/Line"),LockConstraint:a("./constraints/LockConstraint"),Material:a("./material/Material"),Narrowphase:a("./collision/Narrowphase"),NaiveBroadphase:a("./collision/NaiveBroadphase"),Particle:a("./shapes/Particle"),Plane:a("./shapes/Plane"),RevoluteConstraint:a("./constraints/RevoluteConstraint"),PrismaticConstraint:a("./constraints/PrismaticConstraint"),Rectangle:a("./shapes/Rectangle"),RotationalVelocityEquation:a("./equations/RotationalVelocityEquation"),SAPBroadphase:a("./collision/SAPBroadphase"),Shape:a("./shapes/Shape"),Solver:a("./solver/Solver"),Spring:a("./objects/Spring"),Utils:a("./utils/Utils"),World:a("./world/World"),QuadTree:a("./collision/QuadTree").QuadTree,vec2:a("./math/vec2"),version:a("../package.json").version}},{"../package.json":8,"./collision/AABB":9,"./collision/Broadphase":10,"./collision/GridBroadphase":11,"./collision/NaiveBroadphase":12,"./collision/Narrowphase":13,"./collision/QuadTree":14,"./collision/SAPBroadphase":15,"./constraints/Constraint":16,"./constraints/DistanceConstraint":17,"./constraints/GearConstraint":18,"./constraints/LockConstraint":19,"./constraints/PrismaticConstraint":20,"./constraints/RevoluteConstraint":21,"./equations/AngleLockEquation":22,"./equations/ContactEquation":23,"./equations/Equation":24,"./equations/FrictionEquation":25,"./equations/RotationalVelocityEquation":27,"./events/EventEmitter":28,"./material/ContactMaterial":29,"./material/Material":30,"./math/vec2":33,"./objects/Body":34,"./objects/Spring":35,"./shapes/Capsule":37,"./shapes/Circle":38,"./shapes/Convex":39,"./shapes/Heightfield":40,"./shapes/Line":41,"./shapes/Particle":42,"./shapes/Plane":43,"./shapes/Rectangle":44,"./shapes/Shape":45,"./solver/GSSolver":46,"./solver/IslandSolver":48,"./solver/Solver":49,"./utils/Utils":50,"./world/World":51}],37:[function(a,b){function c(a,b){this.length=a||1,this.radius=b||1,d.call(this,d.CAPSULE)}var d=a("./Shape"),e=a("../math/vec2");b.exports=c,c.prototype=new d,c.prototype.computeMomentOfInertia=function(a){var b=this.radius,c=this.length+b,d=2*b;return a*(d*d+c*c)/12},c.prototype.updateBoundingRadius=function(){this.boundingRadius=this.radius+this.length/2},c.prototype.updateArea=function(){this.area=Math.PI*this.radius*this.radius+2*this.radius*this.length};var f=e.create();c.prototype.computeAABB=function(a,b,c){var d=this.radius;e.set(f,this.length,0),e.rotate(f,f,c),e.set(a.upperBound,Math.max(f[0]+d,-f[0]+d),Math.max(f[1]+d,-f[1]+d)),e.set(a.lowerBound,Math.min(f[0]-d,-f[0]-d),Math.min(f[1]-d,-f[1]-d)),e.add(a.lowerBound,a.lowerBound,b),e.add(a.upperBound,a.upperBound,b)}},{"../math/vec2":33,"./Shape":45}],38:[function(a,b){function c(a){this.radius=a||1,d.call(this,d.CIRCLE)}var d=a("./Shape"),e=a("../math/vec2");b.exports=c,c.prototype=new d,c.prototype.computeMomentOfInertia=function(a){var b=this.radius;return a*b*b/2},c.prototype.updateBoundingRadius=function(){this.boundingRadius=this.radius},c.prototype.updateArea=function(){this.area=Math.PI*this.radius*this.radius},c.prototype.computeAABB=function(a,b){var c=this.radius;e.set(a.upperBound,c,c),e.set(a.lowerBound,-c,-c),b&&(e.add(a.lowerBound,a.lowerBound,b),e.add(a.upperBound,a.upperBound,b))}},{"../math/vec2":33,"./Shape":45}],39:[function(a,b){function c(a){this.vertices=[];for(var b=0;bg;f=g,g++){var h=this.vertices[f],i=this.vertices[g],j=Math.abs(e.crossLength(h,i)),k=e.dot(i,i)+e.dot(i,h)+e.dot(h,h);b+=j*k,c+=j}return a/6*(b/c)},c.prototype.updateBoundingRadius=function(){for(var a=this.vertices,b=0,c=0;c!==a.length;c++){var d=e.squaredLength(a[c]);d>b&&(b=d)}this.boundingRadius=Math.sqrt(b)},c.triangleArea=function(a,b,c){return.5*((b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1]))},c.prototype.updateArea=function(){this.updateTriangles(),this.area=0;for(var a=this.triangles,b=this.vertices,d=0;d!==a.length;d++){var e=a[d],f=b[e[0]],g=b[e[1]],h=b[e[2]],i=c.triangleArea(f,g,h);this.area+=i}},c.prototype.computeAABB=function(a,b,c){a.setFromPoints(this.vertices,b,c)}},{"../math/polyk":32,"../math/vec2":33,"./Shape":45,"poly-decomp":7}],40:[function(a,b){function c(a,b,c){this.data=a,this.maxValue=b,this.elementWidth=c,d.call(this,d.HEIGHTFIELD)}{var d=a("./Shape");a("../math/vec2")}b.exports=c,c.prototype=new d,c.prototype.computeMomentOfInertia=function(){return Number.MAX_VALUE},c.prototype.updateBoundingRadius=function(){this.boundingRadius=Number.MAX_VALUE},c.prototype.updateArea=function(){for(var a=this.data,b=0,c=0;cf)){var D=u?r:z.eps,E=c.iterateEquation(C,z,D,y,x,w,v,a,f,j,this.useNormalForceForFriction);B+=Math.abs(E)}if(k>=B*B)break}for(A=0;A!==o;A++)n[A].addConstraintVelocity()}},c.iterateEquation=function(a,b,c,d,e,f,g,i,j,k,l){var m=d[a],n=e[a],o=f[a],p=b.computeGWlambda();l&&b instanceof h&&j==k&&(b.maxForce=b.contactEquation.multiplier*b.frictionCoefficient*i,b.minForce=-b.contactEquation.multiplier*b.frictionCoefficient*i);var q=b.maxForce,r=b.minForce;g&&(m=0);var s=n*(m-p-c*o),t=o+s;return r*i>t?s=r*i-o:t>q*i&&(s=q*i-o),f[a]+=s,b.multiplier=f[a]/i,b.addToWlambda(s),s}},{"../equations/FrictionEquation":25,"../math/vec2":33,"../utils/Utils":50,"./Solver":49}],47:[function(a,b){function c(){this.equations=[],this.bodies=[]}b.exports=c,c.prototype.reset=function(){this.equations.length=this.bodies.length=0},c.prototype.getBodies=function(){for(var a=[],b=[],c=this.equations,d=0;d!==c.length;d++){var e=c[d];-1===b.indexOf(e.bi.id)&&(a.push(e.bi),b.push(e.bi.id)),-1===b.indexOf(e.bj.id)&&(a.push(e.bj),b.push(e.bj.id))}return a},c.prototype.solve=function(a,b){var c=[];b.removeAllEquations();for(var d=this.equations.length,e=0;e!==d;e++)b.addEquation(this.equations[e]);for(var f=this.getBodies(),g=f.length,e=0;e!==g;e++)c.push(f[e]);b.solve(a,{bodies:c})}},{}],48:[function(a,b){function c(a,b){g.call(this,b,g.ISLAND);this.subsolver=a,this.numIslands=0,this._nodePool=[],this._islandPool=[],this.beforeSolveIslandEvent={type:"beforeSolveIsland",island:null}}function d(a){for(var b=a.length,c=0;c!==b;c++){var d=a[c];if(!d.visited&&d.body.motionState!=j)return d}return!1}function e(a,b,c){b.push(a.body);for(var d=a.eqs.length,e=0;e!==d;e++){var f=a.eqs[e];-1===c.indexOf(f)&&c.push(f)}}function f(a,b,c,e){for(k.length=0,k.push(a),a.visited=!0,b(a,c,e);k.length;)for(var f,g=k.pop();f=d(g.children);)f.visited=!0,b(f,c,e),k.push(f)}var g=a("./Solver"),h=(a("../math/vec2"),a("../solver/Island")),i=a("../objects/Body"),j=i.STATIC;b.exports=c,c.prototype=new g;var k=[],l=[],m=[],n=[],o=[];c.prototype.solve=function(a,b){var c=l,g=b.bodies,i=this.equations,j=i.length,k=g.length,p=(this.subsolver,this._workers,this._workerData,this._workerIslandGroups,this._islandPool);l.length=0;for(var q=0;q!==k;q++)c.push(this._nodePool.length?this._nodePool.pop():{body:g[q],children:[],eqs:[],visited:!1});for(var q=0;q!==k;q++){var r=c[q];r.body=g[q],r.children.length=0,r.eqs.length=0,r.visited=!1}for(var s=0;s!==j;s++){var t=i[s],q=g.indexOf(t.bi),u=g.indexOf(t.bj),v=c[q],w=c[u];v.children.push(w),v.eqs.push(t),w.children.push(v),w.eqs.push(t)}var x,y=0,z=m,A=n;z.length=0,A.length=0;var B=o;for(B.length=0;x=d(c);){var C=p.length?p.pop():new h;z.length=0,A.length=0,f(x,e,A,z);for(var D=z.length,q=0;q!==D;q++){var t=z[q];C.equations.push(t)}y++,B.push(C)}this.numIslands=y;for(var E=this.beforeSolveIslandEvent,q=0;qd;d++)a[d]=a[d+c];a.length=e},c.ARRAY_TYPE=Float32Array||Array},{}],51:[function(a,b){function c(a){n.apply(this),a=a||{},this.springs=[],this.bodies=[],this.solver=a.solver||new d,this.narrowphase=new x(this),this.gravity=a.gravity||f.fromValues(0,-9.78),this.doProfiling=a.doProfiling||!1,this.lastStepTime=0,this.broadphase=a.broadphase||new e,this.broadphase.setWorld(this),this.constraints=[],this.defaultFriction=.3,this.defaultRestitution=0,this.defaultMaterial=new q,this.defaultContactMaterial=new r(this.defaultMaterial,this.defaultMaterial),this.lastTimeStep=1/60,this.applySpringForces=!0,this.applyDamping=!0,this.applyGravity=!0,this.solveConstraints=!0,this.contactMaterials=[],this.time=0,this.fixedStepTime=0,this.emitImpactEvent=!0,this._constraintIdCounter=0,this._bodyIdCounter=0,this.postStepEvent={type:"postStep"},this.addBodyEvent={type:"addBody",body:null},this.removeBodyEvent={type:"removeBody",body:null},this.addSpringEvent={type:"addSpring",spring:null},this.impactEvent={type:"impact",bodyA:null,bodyB:null,shapeA:null,shapeB:null,contactEquation:null},this.postBroadphaseEvent={type:"postBroadphase",pairs:null},this.enableBodySleeping=!1,this.beginContactEvent={type:"beginContact",shapeA:null,shapeB:null,bodyA:null,bodyB:null,contactEquations:[]},this.endContactEvent={type:"endContact",shapeA:null,shapeB:null,bodyA:null,bodyB:null},this.preSolveEvent={type:"preSolve",contactEquations:null,frictionEquations:null},this.overlappingShapesLastState={keys:[]},this.overlappingShapesCurrentState={keys:[]},this.overlappingShapeLookup={keys:[]}}var d=a("../solver/GSSolver"),e=a("../collision/NaiveBroadphase"),f=a("../math/vec2"),g=a("../shapes/Circle"),h=a("../shapes/Rectangle"),i=a("../shapes/Convex"),j=a("../shapes/Line"),k=a("../shapes/Plane"),l=a("../shapes/Capsule"),m=a("../shapes/Particle"),n=a("../events/EventEmitter"),o=a("../objects/Body"),p=a("../objects/Spring"),q=a("../material/Material"),r=a("../material/ContactMaterial"),s=a("../constraints/DistanceConstraint"),t=a("../constraints/LockConstraint"),u=a("../constraints/RevoluteConstraint"),v=a("../constraints/PrismaticConstraint"),w=a("../../package.json"),x=(a("../collision/Broadphase"),a("../collision/Narrowphase")),y=a("../utils/Utils");b.exports=c;var z=w.version.split(".").slice(0,2).join(".");if("undefined"==typeof performance&&(performance={}),!performance.now){var A=Date.now();performance.timing&&performance.timing.navigationStart&&(A=performance.timing.navigationStart),performance.now=function(){return Date.now()-A}}c.prototype=new Object(n.prototype),c.prototype.addConstraint=function(a){this.constraints.push(a)},c.prototype.addContactMaterial=function(a){this.contactMaterials.push(a)},c.prototype.removeContactMaterial=function(a){var b=this.contactMaterials.indexOf(a);-1!==b&&y.splice(this.contactMaterials,b,1)},c.prototype.getContactMaterial=function(a,b){for(var c=this.contactMaterials,d=0,e=c.length;d!==e;d++){var f=c[d];if(f.materialA===a&&f.materialB===b||f.materialA===b&&f.materialB===a)return f}return!1},c.prototype.removeConstraint=function(a){var b=this.constraints.indexOf(a);-1!==b&&y.splice(this.constraints,b,1)};{var B=(f.create(),f.create(),f.create(),f.create(),f.create(),f.create(),f.create()),C=f.fromValues(0,0),D=f.fromValues(0,0);f.fromValues(0,0)}c.prototype.step=function(a,b,c){if(c=c||10,b=b||0,0==b)this.internalStep(a),this.time+=a;else{var d=Math.floor((this.time+b)/a)-Math.floor(this.time/a);d=Math.min(d,c);for(var e=0;d>e;e++)this.internalStep(a);this.time+=b,this.fixedStepTime+=d*a;for(var f=this.time-this.fixedStepTime-a,g=0;g!==this.bodies.length;g++){var h=this.bodies[g];h.interpolatedPosition[0]=h.position[0]+h.velocity[0]*f,h.interpolatedPosition[1]=h.position[1]+h.velocity[1]*f}}},c.prototype.internalStep=function(a){{var b,d,e=this,g=this.doProfiling,h=this.springs.length,i=this.springs,j=this.bodies,k=this.gravity,l=this.solver,m=this.bodies.length,n=this.broadphase,p=this.narrowphase,q=this.constraints,r=B,s=(f.scale,f.add);f.rotate}this.lastTimeStep=a,g&&(b=performance.now());var t=f.length(this.gravity);if(this.applyGravity)for(var u=0;u!==m;u++){var v=j[u],w=v.force;v.motionState==o.DYNAMIC&&(f.scale(r,k,v.mass*v.gravityScale),s(w,w,r))}if(this.applySpringForces)for(var u=0;u!==h;u++){var x=i[u];x.applyForce()}if(this.applyDamping)for(var u=0;u!==m;u++){var v=j[u];v.motionState==o.DYNAMIC&&v.applyDamping(a)}var y=n.getCollisionPairs(this);this.postBroadphaseEvent.pairs=y,this.emit(this.postBroadphaseEvent),p.reset(this);for(var u=0,z=y.length;u!==z;u+=2)for(var A=y[u],C=y[u+1],D=0,E=A.shapes.length;D!==E;D++)for(var F=A.shapes[D],G=A.shapeOffsets[D],H=A.shapeAngles[D],I=0,J=C.shapes.length;I!==J;I++){var K=C.shapes[I],L=C.shapeOffsets[I],M=C.shapeAngles[I],N=this.defaultContactMaterial;if(F.material&&K.material){var O=this.getContactMaterial(F.material,K.material);O&&(N=O)}this.runNarrowphase(p,A,F,G,H,C,K,L,M,N,t)}for(var P=this.overlappingShapesLastState,u=0;u!==P.keys.length;u++){var Q=P.keys[u];if(P[Q]===!0&&!this.overlappingShapesCurrentState[Q]){var R=this.endContactEvent;R.shapeA=P[Q+"_shapeA"],R.shapeB=P[Q+"_shapeB"],R.bodyA=P[Q+"_bodyA"],R.bodyB=P[Q+"_bodyB"],this.emit(R)}}for(var u=0;u!==P.keys.length;u++)delete P[P.keys[u]];P.keys.length=0;for(var S=this.overlappingShapesCurrentState,u=0;u!==S.keys.length;u++)P[S.keys[u]]=S[S.keys[u]],P.keys.push(S.keys[u]);for(var u=0;u!==S.keys.length;u++)delete S[S.keys[u]];S.keys.length=0;var T=this.preSolveEvent;T.contactEquations=p.contactEquations,T.frictionEquations=p.frictionEquations,this.emit(T),l.addEquations(p.contactEquations),l.addEquations(p.frictionEquations);var U=q.length;for(u=0;u!==U;u++){var V=q[u];V.update(),l.addEquations(V.equations)}this.solveConstraints&&l.solve(a,this),l.removeAllEquations();for(var u=0;u!==m;u++){var W=j[u];W.sleepState!==o.SLEEPING&&W.motionState!=o.STATIC&&c.integrateBody(W,a)}for(var u=0;u!==m;u++)j[u].setZeroForce();if(g&&(d=performance.now(),e.lastStepTime=d-b),this.emitImpactEvent)for(var X=this.impactEvent,u=0;u!==p.contactEquations.length;u++){var Y=p.contactEquations[u];Y.firstImpact&&(X.bodyA=Y.bi,X.bodyB=Y.bj,X.shapeA=Y.shapeA,X.shapeB=Y.shapeB,X.contactEquation=Y,this.emit(X))}if(this.enableBodySleeping)for(u=0;u!==m;u++)j[u].sleepTick(this.time);this.emit(this.postStepEvent)};var E=f.create(),F=f.create();c.integrateBody=function(a,b){var c=a.invMass,d=a.force,e=a.position,g=a.velocity;a.fixedRotation||(a.angularVelocity+=a.angularForce*a.invInertia*b,a.angle+=a.angularVelocity*b),f.scale(E,d,b*c),f.add(g,E,g),f.scale(F,g,b),f.add(e,e,F),a.aabbNeedsUpdate=!0},c.prototype.runNarrowphase=function(a,b,c,d,e,g,h,i,j,k,l){if(0!==(c.collisionGroup&h.collisionMask)&&0!==(h.collisionGroup&c.collisionMask)){f.rotate(C,d,b.angle),f.rotate(D,i,g.angle),f.add(C,C,b.position),f.add(D,D,g.position);var m=e+b.angle,n=j+g.angle;a.enableFriction=k.friction>0,a.frictionCoefficient=k.friction;var p;p=b.motionState==o.STATIC||b.motionState==o.KINEMATIC?g.mass:g.motionState==o.STATIC||g.motionState==o.KINEMATIC?b.mass:b.mass*g.mass/(b.mass+g.mass),a.slipForce=k.friction*l*p,a.restitution=k.restitution,a.surfaceVelocity=k.surfaceVelocity,a.frictionStiffness=k.frictionStiffness,a.frictionRelaxation=k.frictionRelaxation,a.stiffness=k.stiffness,a.relaxation=k.relaxation;var q=a[c.type|h.type],r=0;if(q){var s=c.sensor||h.sensor;if(r=c.type=0;b--)this.removeConstraint(a[b]);for(var c=this.bodies,b=c.length-1;b>=0;b--)this.removeBody(c[b]);for(var d=this.springs,b=d.length-1;b>=0;b--)this.removeSpring(d[b]);for(var e=this.contactMaterials,b=e.length-1;b>=0;b--)this.removeContactMaterial(e[b])},c.prototype.clone=function(){var a=new c;return a.fromJSON(this.toJSON()),a};var G=f.create(),H=f.fromValues(0,0),I=f.fromValues(0,0);c.prototype.hitTest=function(a,b,c){c=c||0;var d=new o({position:a}),e=new m,h=a,j=0,n=G,p=H,q=I;d.addShape(e);for(var r=this.narrowphase,s=[],t=0,u=b.length;t!==u;t++)for(var v=b[t],w=0,x=v.shapes.length;w!==x;w++){var y=v.shapes[w],z=v.shapeOffsets[w]||p,A=v.shapeAngles[w]||0;f.rotate(n,z,v.angle),f.add(n,n,v.position);var B=A+v.angle;(y instanceof g&&r.circleParticle(v,y,n,B,d,e,h,j,!0)||y instanceof i&&r.particleConvex(d,e,h,j,v,y,n,B,!0)||y instanceof k&&r.particlePlane(d,e,h,j,v,y,n,B,!0)||y instanceof l&&r.particleCapsule(d,e,h,j,v,y,n,B,!0)||y instanceof m&&f.squaredLength(f.sub(q,n,a))1&&a.bodyB.id>1},endContactHandler:function(a){a.bodyA.id>1&&a.bodyB.id>1},setBoundsToWorld:function(a,b,c,d,e){this.setBounds(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,a,b,c,d,e)},setWorldMaterial:function(a,b,c,d,e){"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=!0),b&&this._wallShapes[0]&&(this._wallShapes[0].material=a),c&&this._wallShapes[1]&&(this._wallShapes[1].material=a),d&&this._wallShapes[2]&&(this._wallShapes[2].material=a),e&&this._wallShapes[3]&&(this._wallShapes[3].material=a)},setBounds:function(a,b,c,d,e,f,g,h,i){"undefined"==typeof e&&(e=!0),"undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=!0),"undefined"==typeof h&&(h=!0),"undefined"==typeof i&&(i=!0);var j=c/2,k=d/2,l=j+a,m=k+b;if(null!==this.bounds){this.bounds.world&&this.world.removeBody(this.bounds);for(var n=this.bounds.shapes.length;n--;){var o=this.bounds.shapes[n];this.bounds.removeShape(o)}this.bounds.position[0]=this.game.math.px2pi(l),this.bounds.position[1]=this.game.math.px2pi(m)}else this.bounds=new p2.Body({mass:0,position:[this.game.math.px2pi(l),this.game.math.px2pi(m)]});e&&(this._wallShapes[0]=new p2.Plane,i&&(this._wallShapes[0].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[0],[this.game.math.px2pi(-j),0],1.5707963267948966)),f&&(this._wallShapes[1]=new p2.Plane,i&&(this._wallShapes[1].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[1],[this.game.math.px2pi(j),0],-1.5707963267948966)),g&&(this._wallShapes[2]=new p2.Plane,i&&(this._wallShapes[2].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[2],[0,this.game.math.px2pi(-k)],-3.141592653589793)),h&&(this._wallShapes[3]=new p2.Plane,i&&(this._wallShapes[3].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[3],[0,this.game.math.px2pi(k)])),this.world.addBody(this.bounds)},update:function(){this.world.step(1/60)},clear:function(){this.world.clear()},destroy:function(){this.world.clear(),this.game=null},addBody:function(a){return a.data.world?!1:(this.world.addBody(a.data),this.onBodyAdded.dispatch(a),!0)},removeBody:function(a){return this.world.removeBody(a.data),this.onBodyRemoved.dispatch(a),a},addSpring:function(a){return this.world.addSpring(a),this.onSpringAdded.dispatch(a),a},removeSpring:function(a){return this.world.removeSpring(a),this.onSpringRemoved.dispatch(a),a},addConstraint:function(a){return this.world.addConstraint(a),this.onConstraintAdded.dispatch(a),a},removeConstraint:function(a){return this.world.removeConstraint(a),this.onConstraintRemoved.dispatch(a),a},addContactMaterial:function(a){return this.world.addContactMaterial(a),this.onContactMaterialAdded.dispatch(a),a},removeContactMaterial:function(a){return this.world.removeContactMaterial(a),this.onContactMaterialRemoved.dispatch(a),a},getContactMaterial:function(a,b){return this.world.getContactMaterial(a,b)},setMaterial:function(a,b){for(var c=b.length;c--;)b.setMaterial(a)},createMaterial:function(a,b){a=a||"";var c=new Phaser.Physics.P2.Material(a);return this.materials.push(c),"undefined"!=typeof b&&b.setMaterial(c),c},createContactMaterial:function(a,b,c){"undefined"==typeof a&&(a=this.createMaterial()),"undefined"==typeof b&&(b=this.createMaterial());var d=new Phaser.Physics.P2.ContactMaterial(a,b,c);return this.addContactMaterial(d)},getBodies:function(){for(var a=[],b=this.world.bodies.length;b--;)a.push(this.world.bodies[b].parent);return a},getSprings:function(){for(var a=[],b=this.world.springs.length;b--;)a.push(this.world.springs[b]);return a},getConstraints:function(){for(var a=[],b=this.world.constraints.length;b--;)a.push(this.world.springs[b]);return a},hitTest:function(){},toJSON:function(){this.world.toJSON()},createCollisionGroup:function(){var a=Math.pow(2,this._collisionGroupID);this._wallShapes[0]&&(this._wallShapes[0].collisionMask=this._wallShapes[0].collisionMask|a),this._wallShapes[1]&&(this._wallShapes[1].collisionMask=this._wallShapes[1].collisionMask|a),this._wallShapes[2]&&(this._wallShapes[2].collisionMask=this._wallShapes[2].collisionMask|a),this._wallShapes[3]&&(this._wallShapes[3].collisionMask=this._wallShapes[3].collisionMask|a),this._collisionGroupID++;var b=new Phaser.Physics.P2.CollisionGroup(a);return this.collisionGroups.push(b),b},createBody:function(a,b,c,d,e,f){"undefined"==typeof d&&(d=!1);var g=new Phaser.Physics.P2.Body(this.game,null,a,b,c);if(f){var h=g.addPolygon(e,f);if(!h)return!1}return d&&this.world.addBody(g.data),g},createParticle:function(a,b,c,d,e,f){"undefined"==typeof d&&(d=!1);var g=new Phaser.Physics.P2.Body(this.game,null,a,b,c);if(f){var h=g.addPolygon(e,f);if(!h)return!1}return d&&this.world.addBody(g.data),g}},Object.defineProperty(Phaser.Physics.P2.prototype,"friction",{get:function(){return this.world.defaultFriction},set:function(a){this.world.defaultFriction=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"restituion",{get:function(){return this.world.defaultRestitution},set:function(a){this.world.defaultRestitution=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"applySpringForces",{get:function(){return this.world.applySpringForces},set:function(a){this.world.applySpringForces=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"applyDamping",{get:function(){return this.world.applyDamping},set:function(a){this.world.applyDamping=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"applyGravity",{get:function(){return this.world.applyGravity},set:function(a){this.world.applyGravity=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"solveConstraints",{get:function(){return this.world.solveConstraints},set:function(a){this.world.solveConstraints=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"time",{get:function(){return this.world.time}}),Object.defineProperty(Phaser.Physics.P2.prototype,"emitImpactEvent",{get:function(){return this.world.emitImpactEvent},set:function(a){this.world.emitImpactEvent=a}}),Object.defineProperty(Phaser.Physics.P2.prototype,"enableBodySleeping",{get:function(){return this.world.enableBodySleeping},set:function(a){this.world.enableBodySleeping=a}}),Phaser.Physics.P2.PointProxy=function(a,b){this.game=a,this.destination=b},Phaser.Physics.P2.PointProxy.prototype.constructor=Phaser.Physics.P2.PointProxy,Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype,"x",{get:function(){return this.destination[0]},set:function(a){this.destination[0]=this.game.math.px2p(a)}}),Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype,"y",{get:function(){return this.destination[1]},set:function(a){this.destination[1]=this.game.math.px2p(a)}}),Phaser.Physics.P2.InversePointProxy=function(a,b){this.game=a,this.destination=b},Phaser.Physics.P2.InversePointProxy.prototype.constructor=Phaser.Physics.P2.InversePointProxy,Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype,"x",{get:function(){return this.destination[0]},set:function(a){this.destination[0]=this.game.math.px2p(-a)}}),Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype,"y",{get:function(){return this.destination[1]},set:function(a){this.destination[1]=this.game.math.px2p(-a)}}),Phaser.Physics.Body=function(a,b,c,d,e){b=b||null,c=c||0,d=d||0,"undefined"==typeof e&&(e=1),this.game=a,this.sprite=b,this.type=Phaser.Physics.P2,this.offset=new Phaser.Point,this.data=new p2.Body({position:[this.px2pi(c),this.px2pi(d)],mass:e}),this.data.parent=this,this.velocity=new Phaser.Physics.InversePointProxy(this.game,this.data.velocity),this.force=new Phaser.Physics.InversePointProxy(this.game,this.data.force),this.gravity=new Phaser.Point,this.collideWorldBounds=!0,this.onImpact=new Phaser.Signal,this.collidesWith=[],this._bodyCallbacks=[],this._bodyCallbackContext=[],this._groupCallbacks=[],this._groupCallbackContext=[],b&&(this.setRectangleFromSprite(b),this.game.physics.addBody(this))},Phaser.Physics.Body.prototype={createBodyCallback:function(a,b,c){this._bodyCallbacks[a.data.id]=b,this._bodyCallbackContext[a.data.id]=c},createGroupCallback:function(a,b,c){this._groupCallbacks[a.mask]=b,this._groupCallbackContext[a.mask]=c},getCollisionMask:function(){var a=0;this.collideWorldBounds&&(a=this.game.physics.boundsCollisionGroup.mask);for(var b=0;b=0;d--)this.data.shapes[d].collisionGroup=a.mask,this.data.shapes[d].collisionMask=c;else b.collisionGroup=a.mask,shapes.collisionMask=c},clearCollision:function(a,b,c){if("undefined"==typeof c)for(var d=this.data.shapes.length-1;d>=0;d--)a&&(this.data.shapes[d].collisionGroup=null),b&&(this.data.shapes[d].collisionMask=null);else a&&(shapes.collisionGroup=null),b&&(shapes.collisionMask=null);a&&(this.collidesWith.length=0)},collides:function(a,b,c,d){if(Array.isArray(a))for(var e=0;e=0;e--)this.data.shapes[e].collisionMask=f;else d.collisionMask=f},adjustCenterOfMass:function(){this.data.adjustCenterOfMass()},applyDamping:function(a){this.data.applyDamping(a)},applyForce:function(a,b,c){this.data.applyForce(a,[this.px2p(b),this.px2p(c)])},setZeroForce:function(){this.data.setZeroForce()},setZeroRotation:function(){this.data.angularVelocity=0},setZeroVelocity:function(){this.data.velocity[0]=0,this.data.velocity[1]=0},setZeroDamping:function(){this.data.damping=0,this.data.angularDamping=0},toLocalFrame:function(a,b){return this.data.toLocalFrame(a,b)},toWorldFrame:function(a,b){return this.data.toWorldFrame(a,b)},rotateLeft:function(a){this.data.angularVelocity=this.px2p(-a)},rotateRight:function(a){this.data.angularVelocity=this.px2p(a)},moveForward:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.velocity[0]=b*Math.cos(c),this.data.velocity[1]=b*Math.sin(c)},moveBackward:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.velocity[0]=-(b*Math.cos(c)),this.data.velocity[1]=-(b*Math.sin(c))},thrust:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.force[0]+=b*Math.cos(c),this.data.force[1]+=b*Math.sin(c)},reverse:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.force[0]-=b*Math.cos(c),this.data.force[1]-=b*Math.sin(c)},moveLeft:function(a){this.data.velocity[0]=this.px2pi(-a)},moveRight:function(a){this.data.velocity[0]=this.px2pi(a)},moveUp:function(a){this.data.velocity[1]=this.px2pi(-a)},moveDown:function(a){this.data.velocity[1]=this.px2pi(a)},preUpdate:function(){},postUpdate:function(){this.sprite.x=this.p2pxi(this.data.position[0]),this.sprite.y=this.p2pxi(this.data.position[1]),this.fixedRotation||(this.sprite.rotation=this.data.angle)},reset:function(a,b,c,d){"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),this.setZeroForce(),this.setZeroVelocity(),this.setZeroRotation(),c&&this.setZeroDamping(),d&&(this.mass=1),this.x=a,this.y=b},addToWorld:function(){this.data.world!==this.game.physics.world&&this.game.physics.addBody(this)},removeFromWorld:function(){this.data.world===this.game.physics.world&&this.game.physics.removeBody(this)},destroy:function(){this.removeFromWorld(),this.clearShapes(),this.sprite=null},clearShapes:function(){for(var a=this.data.shapes.length-1;a>=0;a--){var b=this.data.shapes[a];this.data.removeShape(b)}},addShape:function(a,b,c,d){return"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),"undefined"==typeof d&&(d=0),this.data.addShape(a,[this.px2pi(b),this.px2pi(c)],d),a},addCircle:function(a,b,c,d){var e=new p2.Circle(this.px2p(a));return this.addShape(e,b,c,d)},addRectangle:function(a,b,c,d,e){var f=new p2.Rectangle(this.px2p(a),this.px2p(b));return this.addShape(f,c,d,e)},addPlane:function(a,b,c){var d=new p2.Plane;return this.addShape(d,a,b,c)},addParticle:function(a,b,c){var d=new p2.Particle;return this.addShape(d,a,b,c)},addLine:function(a,b,c,d){var e=new p2.Line(this.px2p(a));return this.addShape(e,b,c,d)},addCapsule:function(a,b,c,d,e){var f=new p2.Capsule(this.px2p(a),b);return this.addShape(f,c,d,e)},addPolygon:function(a,b){a=a||{},b=Array.prototype.slice.call(arguments,1);var c=[];if(1===b.length&&Array.isArray(b[0]))c=b[0].slice(0);else if(Array.isArray(b[0]))c=b[0].slice(0);else if("number"==typeof b[0])for(var d=0,e=b.length;e>d;d+=2)c.push([b[d],b[d+1]]);var f=c.length-1;c[f][0]===c[0][0]&&c[f][1]===c[0][1]&&c.pop();for(var g=0;g=0;c--)this.data.shapes[c].material=a;else b.material=a},loadPolygon:function(a,b,c){var d=this.game.cache.getPhysicsData(a,b);if(1===d.length){var e=[];d=d.pop();for(var f=0,g=d.shape.length;g>f;f+=2)e.push([d.shape[f],d.shape[f+1]]);return this.addPolygon(c,e)}for(var h=p2.vec2.create(),f=0;f -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ + * @author Richard Davey + * @copyright 2014 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/ - */ - +* 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 * @@ -24652,99 +24661,170 @@ Phaser.RandomDataGenerator.prototype.constructor = Phaser.RandomDataGenerator; */ /** - * QuadTree Constructor - * - * @class Phaser.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.QuadTree = function (physicsManager, x, y, width, height, maxObjects, maxLevels, level) { - - this.physicsManager = physicsManager; - this.ID = physicsManager.quadTreeID; - physicsManager.quadTreeID++; +* QuadTree Constructor +* +* @class Phaser.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 {number} x - The top left coordinate of the quadtree. +* @param {number} y - The top left coordinate of the quadtree. +* @param {number} width - The width of the quadtree in pixels. +* @param {number} height - The height of the quadtree in pixels. +* @param {number} [maxObjects=10] - The maximum number of objects per node. +* @param {number} [maxLevels=4] - The maximum number of levels to iterate to. +* @param {number} [level=0] - Which level is this? +*/ +Phaser.QuadTree = function(x, y, width, height, maxObjects, maxLevels, level) { - this.maxObjects = maxObjects || 10; - this.maxLevels = maxLevels || 4; - this.level = level || 0; + /** + * @property {number} maxObjects - The maximum number of objects per node. + * @default + */ + this.maxObjects = 10; - 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 = []; + /** + * @property {number} maxLevels - The maximum number of levels to break down to. + * @default + */ + this.maxLevels = 4; + + /** + * @property {number} level - The current level. + */ + this.level = 0; + + /** + * @property {object} bounds - Object that contains the quadtree bounds. + */ + this.bounds; + + /** + * @property {array} objects - Array of quadtree children. + */ + this.objects; + + /** + * @property {array} nodes - Array of associated child nodes. + */ + this.nodes; + + this.reset(x, y, width, height, maxObjects, maxLevels, level); }; Phaser.QuadTree.prototype = { - /* - * Split the node into 4 subnodes - * - * @method Phaser.QuadTree#split + /** + * Resets the QuadTree. + * + * @method Phaser.QuadTree#reset + * @param {number} x - The top left coordinate of the quadtree. + * @param {number} y - The top left coordinate of the quadtree. + * @param {number} width - The width of the quadtree in pixels. + * @param {number} height - The height of the quadtree in pixels. + * @param {number} [maxObjects=10] - The maximum number of objects per node. + * @param {number} [maxLevels=4] - The maximum number of levels to iterate to. + * @param {number} [level=0] - Which level is this? */ - split: function() { + reset: function (x, y, width, height, maxObjects, maxLevels, level) { - this.level++; - - // top right node - this.nodes[0] = new Phaser.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.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.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.QuadTree(this.physicsManager, this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + 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 = []; }, - /* - * Insert the object into the node. If the node - * exceeds the capacity, it will split and add all - * objects to their corresponding subnodes. - * + /** + * Populates this quadtree with the children of the given Group. In order to be added the child must exist and have a body property. + * + * @method Phaser.QuadTree#populate + * @param {Phaser.Group} group - The Group to add to the quadtree. + */ + populate: function (group) { + + group.forEach(this.populateHandler, this, true); + + }, + + /** + * Handler for the populate method. + * + * @method Phaser.QuadTree#populateHandler + * @param {Phaser.Sprite|object} sprite - The Sprite to check. + */ + populateHandler: function (sprite) { + + if (sprite.body && sprite.exists) + { + this.insert(sprite.body); + } + + }, + + /** + * Split the node into 4 subnodes + * + * @method Phaser.QuadTree#split + */ + split: function () { + + this.level++; + + // top right node + this.nodes[0] = new Phaser.QuadTree(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.QuadTree(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.QuadTree(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.QuadTree(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.QuadTree#insert - * @param {object} body - Description. + * @param {Phaser.Physics.Arcade.Body|object} body - The Body object to insert into the quadtree. Can be any object so long as it exposes x, y, right and bottom properties. */ 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 @@ -24752,12 +24832,12 @@ Phaser.QuadTree.prototype = { { 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 @@ -24771,27 +24851,27 @@ Phaser.QuadTree.prototype = { } }, - - /* + + /** * Determine which node the object belongs to. - * + * * @method Phaser.QuadTree#getIndex - * @param {object} rect - Description. + * @param {Phaser.Rectangle|object} rect - The bounds in which to check. * @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)) + 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)) + else if (rect.y > this.bounds.bottom) { // rect fits within the bottom-left quadrant of this quadtree index = 2; @@ -24800,80 +24880,80 @@ Phaser.QuadTree.prototype = { 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)) + 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)) + 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. - * + /** + * Return all objects that could collide with the given Sprite. + * * @method Phaser.QuadTree#retrieve - * @param {object} rect - Description. - * @Return {array} - Array with all detected objects. + * @param {Phaser.Sprite} sprite - The sprite to check against. + * @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); + // sprite.body.quadTreeIndex = this.getIndex(sprite.body); + var index = this.getIndex(sprite.body); if (this.nodes[0]) { - // if rect fits into a subnode .. - if (sprite.body.quadTreeIndex !== -1) + // If rect fits into a subnode .. + if (index !== -1) { - returnObjects = returnObjects.concat(this.nodes[sprite.body.quadTreeIndex].retrieve(sprite)); + returnObjects = returnObjects.concat(this.nodes[index].retrieve(sprite)); } else { - // if rect does not fit into a subnode, check it against all subnodes (unrolled for speed) + // 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.QuadTree#clear */ clear: function () { - - this.objects = []; - - for (var i = 0, len = this.nodes.length; i < len; i++) + + this.objects.length = 0; + + var i = this.nodes.length; + + while (i--) { - // if (typeof this.nodes[i] !== 'undefined') - if (this.nodes[i]) - { - this.nodes[i].clear(); - delete this.nodes[i]; - } + this.nodes[i].clear(); + this.nodes.splice(i, 1); } + + this.nodes.length = 0; } }; +Phaser.QuadTree.prototype.constructor = Phaser.QuadTree; + /** * @author Richard Davey * @copyright 2014 Photon Storm Ltd. @@ -34922,12 +35002,7 @@ Phaser.Physics.Arcade = function (game) { /** * @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; + this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); // Avoid gc spikes by caching these values for re-use @@ -35375,7 +35450,7 @@ Phaser.Physics.Arcade.prototype = { // What is the sprite colliding with in the quadtree? this.quadTree.clear(); - this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); + this.quadTree.reset(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); this.quadTree.populate(group); @@ -37336,8311 +37411,6 @@ Phaser.Physics.Arcade.Body.prototype.constructor = Phaser.Physics.Arcade.Body; * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ -/** -* Ninja Physics constructor. -* -* The Ninja Physics system was created in Flash by Metanet Software and ported to JavaScript by Richard Davey. -* -* @class Phaser.Physics.Ninja -* @classdesc Ninja Physics Constructor -* @constructor -* @param {Phaser.Game} game reference to the current game instance. -*/ -Phaser.Physics.Ninja = function (game) { - - /** - * @property {Phaser.Game} game - Local reference to game. - */ - this.game = game; - - this.time = this.game.time; - - /** - * @property {number} gravity - The World gravity setting. - */ - this.gravity = 0.2; - - /** - * @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 {Phaser.QuadTree} quadTree - The world QuadTree. - */ - // this.quadTree = new Phaser.Physics.Ninja.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 {Array} _mapData - Internal cache var. - * @private - */ - this._mapData = []; - -}; - -Phaser.Physics.Ninja.prototype.constructor = Phaser.Physics.Ninja; - -Phaser.Physics.Ninja.prototype = { - - /** - * This will create a Ninja Physics AABB body on the given game object. Its dimensions will match the width and height of the object at the point it is created. - * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. - * - * @method Phaser.Physics.Ninja#enableAABB - * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. - */ - enableAABB: function (object) { - - this.enable(object, 1); - - }, - - /** - * This will create a Ninja Physics Circle body on the given game object. - * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. - * - * @method Phaser.Physics.Ninja#enableCircle - * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. - * @param {number} radius - The radius of the Circle. - */ - enableCircle: function (object, radius) { - - this.enable(object, 2, 0, radius); - - }, - - /** - * This will create a Ninja Physics Tile body on the given game object. There are 34 different types of tile you can create, including 45 degree slopes, - * convex and concave circles and more. The id parameter controls which Tile type is created, but you can also change it at run-time. - * Note that for all degree based tile types they need to have an equal width and height. If the given object doesn't have equal width and height it will use the width. - * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. - * - * @method Phaser.Physics.Ninja#enableTile - * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. - * @param {number} [id=1] - The type of Tile this will use, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. - */ - enableTile: function (object, id) { - - this.enable(object, 3, id); - - }, - - /** - * This will create a Ninja Physics Tile body on the given game object. There are 34 different types of tile you can create, including 45 degree slopes, - * convex and concave circles and more. The id parameter controls which Tile type is created, but you can also change it at run-time. - * Note that for all degree based tile types they need to have an equal width and height. If the given object doesn't have equal width and height it will use the width. - * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed. - * - * @method Phaser.Physics.Ninja#enable - * @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array. - * @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile. - * @param {number} [id=1] - If this body is using a Tile shape, you can set the Tile id here, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. - * @param {number} [radius=0] - If this body is using a Circle shape this controls the radius. - */ - enable: function (object, type, id, radius) { - - if (typeof type === 'undefined') { type = 1; } - if (typeof id === 'undefined') { id = 1; } - - var i = 1; - - if (Array.isArray(object)) - { - // Add to Group - i = object.length; - } - else - { - object = [object]; - } - - while (i--) - { - if (object[i].body === null) - { - object[i].body = new Phaser.Physics.Ninja.Body(this, object[i], type, id, radius); - object[i].anchor.set(0.5); - } - } - - }, - - /** - * Updates the size of this physics world. - * - * @method Phaser.Physics.Ninja#setBounds - * @param {number} x - Top left most corner of the world. - * @param {number} y - Top left most corner of the world. - * @param {number} width - New width of the world. Can never be smaller than the Game.width. - * @param {number} height - New height of the world. Can never be smaller than the Game.height. - */ - setBounds: function (x, y, width, height) { - - this.bounds.setTo(x, y, width, height); - - }, - - /** - * Updates the size of this physics world to match the size of the game world. - * - * @method Phaser.Physics.Ninja#setBoundsToWorld - */ - setBoundsToWorld: function () { - - this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height); - - }, - - /** - * Called automatically by a Physics body, it updates all motion related values on the Body. - * - * @method Phaser.Physics.Ninja#updateMotion - * @param {Phaser.Physics.Ninja.Body} The Body object to be updated. - update: function () { - }, - */ - - /** - * 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. - * The second parameter can be an array of objects, of differing types. - * - * @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|array} object2 - The second object or array of objects to check. Can be 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; - - if (Array.isArray(object2)) - { - for (var i = 0, len = object2.length; i < len; i++) - { - this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true); - } - } - else - { - this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true); - } - - return (this._total > 0); - - }, - - /** - * Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions. - * The second parameter can be an array of objects, of differing types. - * The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead. - * An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place, - * giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped. - * The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called. - * - * @method Phaser.Physics.Ninja#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|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. - * @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. 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 collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. - * @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; - - if (Array.isArray(object2)) - { - for (var i = 0, len = object2.length; i < len; i++) - { - this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false); - } - } - else - { - this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false); - } - - return (this._total > 0); - - }, - - /** - * Internal collision handler. - * - * @method Phaser.Physics.Arcade#collideHandler - * @private - * @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. Can also be an array of objects to check. - * @param {function} collideCallback - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them. - * @param {function} processCallback - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. - * @param {object} callbackContext - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Just run an overlap or a full collision. - */ - collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) { - - // Only collide valid objects - if (typeof object2 === 'undefined' && (object1.type === Phaser.GROUP || object1.type === Phaser.EMITTER)) - { - this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, overlapOnly); - return; - } - - 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, overlapOnly); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - 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, overlapOnly); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - 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, overlapOnly); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.type == Phaser.TILEMAPLAYER) - { - this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); - } - } - } - - }, - - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideSpriteVsSprite - * @private - */ - collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) { - - if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, sprite1, sprite2); - } - - this._total++; - } - - }, - - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideSpriteVsGroup - * @private - */ - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) { - - if (group.length === 0) - { - return; - } - - // What is the sprite colliding with in the quadtree? - // this.quadTree.clear(); - - // this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); - - // this.quadTree.populate(group); - - // this._potentials = this.quadTree.retrieve(sprite); - - for (var i = 0, len = group.children.length; i < len; i++) - { - // We have our potential suspects, are they in this group? - if (group.children[i].exists && group.children[i].body && this.separate(sprite.body, group.children[i].body, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, group.children[i]); - } - - this._total++; - } - } - - }, - - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideGroupVsSelf - * @private - */ - collideGroupVsSelf: function (group, collideCallback, processCallback, callbackContext, overlapOnly) { - - if (group.length === 0) - { - return; - } - - var len = group.children.length; - - for (var i = 0; i < len; i++) - { - for (var j = i + 1; j <= len; j++) - { - if (group.children[i] && group.children[j] && group.children[i].exists && group.children[j].exists) - { - this.collideSpriteVsSprite(group.children[i], group.children[j], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - - }, - - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideGroupVsGroup - * @private - */ - collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) { - - if (group1.length === 0 || group2.length === 0) - { - return; - } - - for (var i = 0, len = group1.children.length; i < len; i++) - { - if (group1.children[i].exists) - { - this.collideSpriteVsGroup(group1.children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - - }, - - /** - * 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. - * @param {function} [processCallback=null] - UN-USED: A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true. - * @param {object} [callbackContext] - UN-USED: The context in which to run the process callback. - * @returns {boolean} Returns true if the bodies collided, otherwise false. - */ - separate: function (body1, body2, processCallback, callbackContext, overlapOnly) { - - if (body1.type !== Phaser.Physics.NINJA || body2.type !== Phaser.Physics.NINJA) - { - return false; - } - - if (body1.aabb && body2.aabb) - { - return body1.aabb.collideAABBVsAABB(body2.aabb); - } - - if (body1.aabb && body2.tile) - { - return body1.aabb.collideAABBVsTile(body2.tile); - } - - if (body1.tile && body2.aabb) - { - return body2.aabb.collideAABBVsTile(body1.tile); - } - - if (body1.circle && body2.tile) - { - return body1.circle.collideCircleVsTile(body2.tile); - } - - if (body1.tile && body2.circle) - { - return body2.circle.collideCircleVsTile(body1.tile); - } - - } - -}; - -/** -* @author Richard Davey -* @copyright 2014 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, bounce values etc all on the Body. -* -* @class Phaser.Physics.Ninja.Body -* @classdesc Ninja Physics Body Constructor -* @constructor -* @param {Phaser.Physics.Ninja} system - The physics system this Body belongs to. -* @param {Phaser.Sprite} sprite - The Sprite object this physics body belongs to. -* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile. -* @param {number} [id=1] - If this body is using a Tile shape, you can set the Tile id here, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. -* @param {number} [radius=16] - If this body is using a Circle shape this controls the radius. -*/ -Phaser.Physics.Ninja.Body = function (system, sprite, type, id, radius) { - - if (typeof type === 'undefined') { type = 1; } - if (typeof id === 'undefined') { id = 1; } - if (typeof radius === 'undefined') { radius = 16; } - - /** - * @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 {number} type - The type of physics system this body belongs to. - */ - this.type = Phaser.Physics.NINJA; - - /** - * @property {Phaser.Physics.Ninja} system - The parent physics system. - */ - this.system = system; - - /** - * @property {Phaser.Physics.Ninja.AABB} aabb - The AABB object this body is using for collision. - */ - this.aabb = null; - - /** - * @property {Phaser.Physics.Ninja.Tile} tile - The Tile object this body is using for collision. - */ - this.tile = null; - - /** - * @property {Phaser.Physics.Ninja.Circle} circle - The Circle object this body is using for collision. - */ - this.circle = null; - - /** - * @property {object} shape - A local reference to the body shape. - */ - this.shape = null; - - // Setting drag to 0 and friction to 0 means you get a normalised speed (px psec) - - /** - * @property {number} drag - The drag applied to this object as it moves. - * @default - */ - this.drag = 1; - - /** - * @property {number} friction - The friction applied to this object as it moves. - * @default - */ - this.friction = 0.05; - - /** - * @property {number} gravityScale - How much of the world gravity should be applied to this object? 1 = all of it, 0.5 = 50%, etc. - * @default - */ - this.gravityScale = 1; - - /** - * @property {number} bounce - The bounciness of this object when it collides. A value between 0 and 1. We recommend setting it to 0.999 to avoid jittering. - * @default - */ - this.bounce = 0.3; - - /** - * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body. - */ - this.velocity = new Phaser.Point(); - - /** - * @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; - - /** - * @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; - - /** - * 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 = 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.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.wasTouching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * @property {number} maxSpeed - The maximum speed this body can travel at (taking drag and friction into account) - * @default - */ - this.maxSpeed = 8; - - var sx = sprite.x; - var sy = sprite.y; - - if (sprite.anchor.x === 0) - { - sx += (sprite.width * 0.5); - } - - if (sprite.anchor.y === 0) - { - sy += (sprite.height * 0.5); - } - - if (type === 1) - { - this.aabb = new Phaser.Physics.Ninja.AABB(this, sx, sy, sprite.width, sprite.height); - this.shape = this.aabb; - } - else if (type === 2) - { - this.circle = new Phaser.Physics.Ninja.Circle(this, sx, sy, radius); - this.shape = this.circle; - } - else if (type === 3) - { - this.tile = new Phaser.Physics.Ninja.Tile(this, sx, sy, sprite.width, sprite.height, id); - this.shape = this.tile; - } - -}; - -Phaser.Physics.Ninja.Body.prototype = { - - /** - * Internal method. - * - * @method Phaser.Physics.Ninja.Body#updateBounds - * @protected - */ - updateBounds: function (centerX, centerY, scaleX, scaleY) { - }, - - /** - * Internal method. - * - * @method Phaser.Physics.Ninja.Body#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.shape.integrate(); - - if (this.collideWorldBounds) - { - this.shape.collideWorldBounds(); - } - - this.speed = Math.sqrt(this.shape.velocity.x * this.shape.velocity.x + this.shape.velocity.y * this.shape.velocity.y); - this.angle = Math.atan2(this.shape.velocity.y, this.shape.velocity.x); - - }, - - /** - * Internal method. - * - * @method Phaser.Physics.Ninja.Body#postUpdate - * @protected - */ - postUpdate: function () { - - if (this.sprite.type === Phaser.TILESPRITE) - { - // TileSprites don't use their anchor property, so we need to adjust the coordinates - this.sprite.x = this.shape.pos.x - this.shape.xw; - this.sprite.y = this.shape.pos.y - this.shape.yw; - } - else - { - this.sprite.x = this.shape.pos.x; - this.sprite.y = this.shape.pos.y; - } - - }, - - /** - * Stops all movement of this body. - * - * @method Phaser.Physics.Ninja.Body#setZeroVelocity - */ - setZeroVelocity: function () { - - this.shape.oldpos.x = this.shape.pos.x; - this.shape.oldpos.y = this.shape.pos.y; - - }, - - /** - * Moves the Body forwards based on its current angle and the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveTo - * @param {number} speed - The speed at which it should move forwards. - * @param {number} angle - The angle in which it should move, given in degrees. - */ - moveTo: function (speed, angle) { - - var magnitude = speed * this.game.time.physicsElapsed; - var angle = this.game.math.degToRad(angle); - - this.shape.pos.x = this.shape.oldpos.x + (magnitude * Math.cos(angle)); - this.shape.pos.y = this.shape.oldpos.y + (magnitude * Math.sin(angle)); - - }, - - /** - * Moves the Body backwards based on its current angle and the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveBackward - * @param {number} speed - The speed at which it should move backwards. - * @param {number} angle - The angle in which it should move, given in degrees. - */ - moveFrom: function (speed, angle) { - - var magnitude = -speed * this.game.time.physicsElapsed; - var angle = this.game.math.degToRad(angle); - - this.shape.pos.x = this.shape.oldpos.x + (magnitude * Math.cos(angle)); - this.shape.pos.y = this.shape.oldpos.y + (magnitude * Math.sin(angle)); - - }, - - /** - * If this Body is dynamic then this will move it to the left by setting its x velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveLeft - * @param {number} speed - The speed at which it should move to the left, in pixels per second. - */ - moveLeft: function (speed) { - - var fx = -speed * this.game.time.physicsElapsed; - - this.shape.pos.x = this.shape.oldpos.x + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.x - this.shape.oldpos.x + fx)); - - }, - - /** - * If this Body is dynamic then this will move it to the right by setting its x velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveRight - * @param {number} speed - The speed at which it should move to the right, in pixels per second. - */ - moveRight: function (speed) { - - var fx = speed * this.game.time.physicsElapsed; - - this.shape.pos.x = this.shape.oldpos.x + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.x - this.shape.oldpos.x + fx)); - - }, - - /** - * If this Body is dynamic then this will move it up by setting its y velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveUp - * @param {number} speed - The speed at which it should move up, in pixels per second. - */ - moveUp: function (speed) { - - var fx = -speed * this.game.time.physicsElapsed; - - this.shape.pos.y = this.shape.oldpos.y + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.y - this.shape.oldpos.y + fx)); - - }, - - /** - * If this Body is dynamic then this will move it down by setting its y velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveDown - * @param {number} speed - The speed at which it should move down, in pixels per second. - */ - moveDown: function (speed) { - - var fx = speed * this.game.time.physicsElapsed; - - this.shape.pos.y = this.shape.oldpos.y + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.y - this.shape.oldpos.y + fx)); - - }, - - /** - * Resets all Body values (velocity, acceleration, rotation, etc) - * - * @method Phaser.Physics.Ninja.Body#reset - */ - reset: function () { - }, - -}; - -/** -* @name Phaser.Physics.Ninja.Body#x -* @property {number} x - The x position. -*/ -Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "x", { - - /** - * The x position. - * @method x - * @return {number} - */ - get: function () { - return this.shape.pos.x; - }, - - /** - * The x position. - * @method x - * @param {number} value - */ - set: function (value) { - this.shape.pos.x = value; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Body#y -* @property {number} y - The y position. -*/ -Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "y", { - - /** - * The y position. - * @method y - * @return {number} - */ - get: function () { - return this.shape.pos.y; - }, - - /** - * The y position. - * @method y - * @param {number} value - */ - set: function (value) { - this.shape.pos.y = value; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Body#width -* @property {number} width - The width of this Body -* @readonly -*/ -Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "width", { - - /** - * The width of this Body - * @method width - * @return {number} - * @readonly - */ - get: function () { - return this.shape.width; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Body#height -* @property {number} height - The height of this Body -* @readonly -*/ -Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "height", { - - /** - * The height of this Body - * @method height - * @return {number} - * @readonly - */ - get: function () { - return this.shape.height; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Body#bottom -* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height) -* @readonly -*/ -Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "bottom", { - - /** - * The sum of the y and height properties. - * @method bottom - * @return {number} - * @readonly - */ - get: function () { - return this.shape.pos.y + this.shape.height; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Body#right -* @property {number} right - The right value of this Body (same as Body.x + Body.width) -* @readonly -*/ -Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "right", { - - /** - * The sum of the x and width properties. - * @method right - * @return {number} - * @readonly - */ - get: function () { - return this.shape.pos.x + this.shape.width; - } - -}); - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Ninja Physics AABB constructor. -* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. -* -* @class Phaser.Physics.Ninja.AABB -* @classdesc Arcade Physics Constructor -* @constructor -* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. -* @param {number} x - The x coordinate to create this shape at. -* @param {number} y - The y coordinate to create this shape at. -* @param {number} width - The width of this AABB. -* @param {number} height - The height of this AABB. -*/ -Phaser.Physics.Ninja.AABB = function (body, x, y, width, height) { - - /** - * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. - */ - this.body = body; - - /** - * @property {Phaser.Physics.Ninja} system - A reference to the physics system. - */ - this.system = body.system; - - /** - * @property {Phaser.Point} pos - The position of this object. - */ - this.pos = new Phaser.Point(x, y); - - /** - * @property {Phaser.Point} oldpos - The position of this object in the previous update. - */ - this.oldpos = new Phaser.Point(x, y); - - /** - * @property {number} xw - Half the width. - * @readonly - */ - this.xw = Math.abs(width / 2); - - /** - * @property {number} xw - Half the height. - * @readonly - */ - this.yw = Math.abs(height / 2); - - /** - * @property {number} width - The width. - * @readonly - */ - this.width = width; - - /** - * @property {number} height - The height. - * @readonly - */ - this.height = height; - - /** - * @property {number} oH - Internal var. - * @private - */ - this.oH = 0; - - /** - * @property {number} oV - Internal var. - * @private - */ - this.oV = 0; - - /** - * @property {Phaser.Point} velocity - The velocity of this object. - */ - this.velocity = new Phaser.Point(); - - /** - * @property {object} aabbTileProjections - All of the collision response handlers. - */ - this.aabbTileProjections = {}; - - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL] = this.projAABB_Full; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG] = this.projAABB_45Deg; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE] = this.projAABB_Concave; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX] = this.projAABB_Convex; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs] = this.projAABB_22DegS; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb] = this.projAABB_22DegB; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs] = this.projAABB_67DegS; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb] = this.projAABB_67DegB; - this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF] = this.projAABB_Half; - -}; - -Phaser.Physics.Ninja.AABB.prototype.constructor = Phaser.Physics.Ninja.AABB; - -Phaser.Physics.Ninja.AABB.COL_NONE = 0; -Phaser.Physics.Ninja.AABB.COL_AXIS = 1; -Phaser.Physics.Ninja.AABB.COL_OTHER = 2; - -Phaser.Physics.Ninja.AABB.prototype = { - - /** - * Updates this AABBs position. - * - * @method Phaser.Physics.Ninja.AABB#integrate - */ - integrate: function () { - - var px = this.pos.x; - var py = this.pos.y; - - // integrate - this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); - this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); - - // store - this.velocity.set(this.pos.x - px, this.pos.y - py); - this.oldpos.set(px, py); - - }, - - /** - * Process a world collision and apply the resulting forces. - * - * @method Phaser.Physics.Ninja.AABB#reportCollisionVsWorld - * @param {number} px - The tangent velocity - * @param {number} py - The tangent velocity - * @param {number} dx - Collision normal - * @param {number} dy - Collision normal - * @param {number} obj - Object this AABB collided with - */ - reportCollisionVsWorld: function (px, py, dx, dy, obj) { - - var p = this.pos; - var o = this.oldpos; - - // Calc velocity - var vx = p.x - o.x; - var vy = p.y - o.y; - - // Find component of velocity parallel to collision normal - var dp = (vx * dx + vy * dy); - var nx = dp * dx; //project velocity onto collision normal - - var ny = dp * dy; //nx,ny is normal velocity - - var tx = vx - nx; //px,py is tangent velocity - var ty = vy - ny; - - // We only want to apply collision response forces if the object is travelling into, and not out of, the collision - var b, bx, by, fx, fy; - - if (dp < 0) - { - fx = tx * this.body.friction; - fy = ty * this.body.friction; - - b = 1 + this.body.bounce; - - bx = (nx * b); - by = (ny * b); - - if (dx === 1) - { - this.body.touching.left = true; - } - else if (dx === -1) - { - this.body.touching.right = true; - } - - if (dy === 1) - { - this.body.touching.up = true; - } - else if (dy === -1) - { - this.body.touching.down = true; - } - } - else - { - // Moving out of collision, do not apply forces - bx = by = fx = fy = 0; - } - - // Project object out of collision - p.x += px; - p.y += py; - - // Apply bounce+friction impulses which alter velocity - o.x += px + bx + fx; - o.y += py + by + fy; - - }, - - /** - * Process a body collision and apply the resulting forces. - * - * @method Phaser.Physics.Ninja.AABB#reportCollisionVsBody - * @param {number} px - The tangent velocity - * @param {number} py - The tangent velocity - * @param {number} dx - Collision normal - * @param {number} dy - Collision normal - * @param {number} obj - Object this AABB collided with - */ - reportCollisionVsBody: function (px, py, dx, dy, obj) { - - // Here - we check if obj is immovable, etc and then we canswap the p/o values below depending on which is heavy - // But then still need to work out how to split force - - var p = this.pos; - var o = this.oldpos; - - // Calc velocity - var vx = p.x - o.x; - var vy = p.y - o.y; - - // Find component of velocity parallel to collision normal - var dp = (vx * dx + vy * dy); - var nx = dp * dx; //project velocity onto collision normal - - var ny = dp * dy; //nx,ny is normal velocity - - var tx = vx - nx; //px,py is tangent velocity - var ty = vy - ny; - - // We only want to apply collision response forces if the object is travelling into, and not out of, the collision - var b, bx, by, fx, fy; - - if (dp < 0) - { - fx = tx * this.body.friction; - fy = ty * this.body.friction; - - b = 1 + this.body.bounce; - - bx = (nx * b); - by = (ny * b); - } - else - { - // Moving out of collision, do not apply forces - bx = by = fx = fy = 0; - } - - // working version - // p.x += px; - // p.y += py; - // o.x += px + bx + fx; - // o.y += py + by + fy; - - // Project object out of collision (applied to the position value) - p.x += px; - p.y += py; - - // obj.pos.x += px; - // obj.pos.y += py; - - - // Apply bounce+friction impulses which alter velocity (applied to old position, thus setting a sort of velocity up) - var rx = px + bx + fx; - var ry = py + by + fy; - - // let's pretend obj is immovable - // rx *= -1; - // ry *= -1; - - - // Now let's share the load - o.x += rx; - o.y += ry; - - // work out objs velocity - - - // rx *= -1; - // ry *= -1; - - // obj.oldpos.x += rx; - // obj.oldpos.y += ry; - - - // console.log(this.body.sprite.name, 'o.x', rx, ry, obj); - - }, - - /** - * Collides this AABB against the world bounds. - * - * @method Phaser.Physics.Ninja.AABB#collideWorldBounds - */ - collideWorldBounds: function () { - - var dx = this.system.bounds.x - (this.pos.x - this.xw); - - if (0 < dx) - { - this.reportCollisionVsWorld(dx, 0, 1, 0, null); - } - else - { - dx = (this.pos.x + this.xw) - this.system.bounds.width; - - if (0 < dx) - { - this.reportCollisionVsWorld(-dx, 0, -1, 0, null); - } - } - - var dy = this.system.bounds.y - (this.pos.y - this.yw); - - if (0 < dy) - { - this.reportCollisionVsWorld(0, dy, 0, 1, null); - } - else - { - dy = (this.pos.y + this.yw) - this.system.bounds.height; - - if (0 < dy) - { - this.reportCollisionVsWorld(0, -dy, 0, -1, null); - } - } - - }, - - /** - * Collides this AABB against a AABB. - * - * @method Phaser.Physics.Ninja.AABB#collideAABBVsAABB - * @param {Phaser.Physics.Ninja.AABB} aabb - The AABB to collide against. - */ - collideAABBVsAABB: function (aabb) { - - var pos = this.pos; - var c = aabb; - - var tx = c.pos.x; - var ty = c.pos.y; - var txw = c.xw; - var tyw = c.yw; - - var dx = pos.x - tx;//tile->obj delta - var px = (txw + this.xw) - Math.abs(dx);//penetration depth in x - - if (0 < px) - { - var dy = pos.y - ty;//tile->obj delta - var py = (tyw + this.yw) - Math.abs(dy);//pen depth in y - - if (0 < py) - { - //object may be colliding with tile; call tile-specific collision function - - //calculate projection vectors - if (px < py) - { - //project in x - if (dx < 0) - { - //project to the left - px *= -1; - py = 0; - } - else - { - //proj to right - py = 0; - } - } - else - { - //project in y - if (dy < 0) - { - //project up - px = 0; - py *= -1; - } - else - { - //project down - px = 0; - } - } - - // return this.aabbTileProjections[1](px, py, this, c); - - var l = Math.sqrt(px * px + py * py); - // this.reportCollisionVsWorld(px, py, px / l, py / l, c); - this.reportCollisionVsBody(px, py, px / l, py / l, c); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - - } - } - - return false; - - }, - - /** - * Collides this AABB against a Tile. - * - * @method Phaser.Physics.Ninja.AABB#collideAABBVsTile - * @param {Phaser.Physics.Ninja.Tile} tile - The Tile to collide against. - */ - collideAABBVsTile: function (tile) { - - var pos = this.pos; - var c = tile; - - var tx = c.pos.x; - var ty = c.pos.y; - var txw = c.xw; - var tyw = c.yw; - - var dx = pos.x - tx;//tile->obj delta - var px = (txw + this.xw) - Math.abs(dx);//penetration depth in x - - if (0 < px) - { - var dy = pos.y - ty;//tile->obj delta - var py = (tyw + this.yw) - Math.abs(dy);//pen depth in y - - if (0 < py) - { - //object may be colliding with tile; call tile-specific collision function - - //calculate projection vectors - if (px < py) - { - //project in x - if (dx < 0) - { - //project to the left - px *= -1; - py = 0; - } - else - { - //proj to right - py = 0; - } - } - else - { - //project in y - if (dy < 0) - { - //project up - px = 0; - py *= -1; - } - else - { - //project down - px = 0; - } - } - - return this.resolveTile(px, py, this, c); - } - } - - return false; - - }, - - /** - * Resolves tile collision. - * - * @method Phaser.Physics.Ninja.AABB#resolveTile - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} body - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} tile - The Tile involved in the collision. - * @return {boolean} True if the collision was processed, otherwise false. - */ - resolveTile: function (x, y, body, tile) { - - if (0 < tile.id) - { - return this.aabbTileProjections[tile.type](x, y, body, tile); - } - else - { - // console.warn("Ninja.AABB.resolveTile was called with an empty (or unknown) tile!: id=" + tile.id + ")"); - return false; - } - - }, - - /** - * Resolves Full tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_Full - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_Full: function (x, y, obj, t) { - - var l = Math.sqrt(x * x + y * y); - obj.reportCollisionVsWorld(x, y, x / l, y / l, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - - }, - - /** - * Resolves Half tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_Half - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_Half: function (x, y, obj, t) { - - //signx or signy must be 0; the other must be -1 or 1 - //calculate the projection vector for the half-edge, and then - //(if collision is occuring) pick the minimum - - var sx = t.signx; - var sy = t.signy; - - var ox = (obj.pos.x - (sx*obj.xw)) - t.pos.x;//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (sy*obj.yw)) - t.pos.y;//point on the AABB, relative to the tile center - - //we perform operations analogous to the 45deg tile, except we're using - //an axis-aligned slope instead of an angled one.. - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - if (lenP < lenN) - { - //project along axis; note that we're assuming that this tile is horizontal OR vertical - //relative to the AABB's current tile, and not diagonal OR the current tile. - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - else - { - //note that we could use -= instead of -dp - obj.reportCollisionVsWorld(sx,sy,t.signx, t.signy, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - } - - return Phaser.Physics.Ninja.AABB.COL_NONE; - - }, - - /** - * Resolves 45 Degree tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_45Deg - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_45Deg: function (x, y, obj, t) { - - var signx = t.signx; - var signy = t.signy; - - var ox = (obj.pos.x - (signx*obj.xw)) - t.pos.x;//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (signy*obj.yw)) - t.pos.y;//point on the AABB, relative to the tile center - - var sx = t.sx; - var sy = t.sy; - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - if (lenP < lenN) - { - //project along axis - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - else - { - //project along slope - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - } - - return Phaser.Physics.Ninja.AABB.COL_NONE; - }, - - /** - * Resolves 22 Degree tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_22DegS - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_22DegS: function (x, y, obj, t) { - - var signx = t.signx; - var signy = t.signy; - - //first we need to check to make sure we're colliding with the slope at all - var py = obj.pos.y - (signy*obj.yw); - var penY = t.pos.y - py;//this is the vector from the innermost point on the box to the highest point on - //the tile; if it is positive, this means the box is above the tile and - //no collision is occuring - if (0 < (penY*signy)) - { - var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope - - var sx = t.sx;//get slope unit normal - var sy = t.sy; - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - var aY = Math.abs(penY); - - if (lenP < lenN) - { - if (aY < lenP) - { - obj.reportCollisionVsWorld(0, penY, 0, penY/aY, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - else - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - } - else - { - if (aY < lenN) - { - obj.reportCollisionVsWorld(0, penY, 0, penY/aY, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - } - } - } - - //if we've reached this point, no collision has occured - return Phaser.Physics.Ninja.AABB.COL_NONE; - }, - - /** - * Resolves 22 Degree tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_22DegB - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_22DegB: function (x, y, obj, t) { - - var signx = t.signx; - var signy = t.signy; - - var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope - - var sx = t.sx;//get slope unit normal - var sy = t.sy; - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - if (lenP < lenN) - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - - } - - return Phaser.Physics.Ninja.AABB.COL_NONE; - - }, - - /** - * Resolves 67 Degree tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_67DegS - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_67DegS: function (x, y, obj, t) { - - var signx = t.signx; - var signy = t.signy; - - var px = obj.pos.x - (signx*obj.xw); - var penX = t.pos.x - px; - - if (0 < (penX*signx)) - { - var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope - - var sx = t.sx;//get slope unit normal - var sy = t.sy; - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need to project it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - var aX = Math.abs(penX); - - if (lenP < lenN) - { - if (aX < lenP) - { - obj.reportCollisionVsWorld(penX, 0, penX/aX, 0, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - else - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - } - else - { - if (aX < lenN) - { - obj.reportCollisionVsWorld(penX, 0, penX/aX, 0, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - } - } - } - - //if we've reached this point, no collision has occured - return Phaser.Physics.Ninja.AABB.COL_NONE; - - }, - - /** - * Resolves 67 Degree tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_67DegB - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_67DegB: function (x, y, obj, t) { - - var signx = t.signx; - var signy = t.signy; - - var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope - - var sx = t.sx;//get slope unit normal - var sy = t.sy; - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - if (lenP < lenN) - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - } - - return Phaser.Physics.Ninja.AABB.COL_NONE; - }, - - /** - * Resolves Convex tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_Convex - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_Convex: function (x, y, obj, t) { - - //if distance from "innermost" corner of AABB is less than than tile radius, - //collision is occuring and we need to project - - var signx = t.signx; - var signy = t.signy; - - var ox = (obj.pos.x - (signx * obj.xw)) - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the circle center to - var oy = (obj.pos.y - (signy * obj.yw)) - (t.pos.y - (signy * t.yw));//the AABB - var len = Math.sqrt(ox * ox + oy * oy); - - var twid = t.xw * 2; - var rad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var pen = rad - len; - - if (((signx * ox) < 0) || ((signy * oy) < 0)) - { - //the test corner is "outside" the 1/4 of the circle we're interested in - var lenP = Math.sqrt(x * x + y * y); - obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS;//we need to report - } - else if (0 < pen) - { - //project along corner->circle vector - ox /= len; - oy /= len; - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - - return Phaser.Physics.Ninja.AABB.COL_NONE; - - }, - - /** - * Resolves Concave tile collision. - * - * @method Phaser.Physics.Ninja.AABB#projAABB_Concave - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projAABB_Concave: function (x, y, obj, t) { - - //if distance from "innermost" corner of AABB is further than tile radius, - //collision is occuring and we need to project - - var signx = t.signx; - var signy = t.signy; - - var ox = (t.pos.x + (signx * t.xw)) - (obj.pos.x - (signx * obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the - var oy = (t.pos.y + (signy * t.yw)) - (obj.pos.y - (signy * obj.yw));//circle's center - - var twid = t.xw * 2; - var rad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var len = Math.sqrt(ox * ox + oy * oy); - var pen = len - rad; - - if (0 < pen) - { - //collision; we need to either project along the axes, or project along corner->circlecenter vector - - var lenP = Math.sqrt(x * x + y * y); - - if (lenP < pen) - { - //it's shorter to move along axis directions - obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); - - return Phaser.Physics.Ninja.AABB.COL_AXIS; - } - else - { - //project along corner->circle vector - ox /= len;//len should never be 0, since if it IS 0, rad should be > than len - oy /= len;//and we should never reach here - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.AABB.COL_OTHER; - } - - } - - return Phaser.Physics.Ninja.AABB.COL_NONE; - - } - -} - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Ninja Physics Tile constructor. -* A Tile is defined by its width, height and type. It's type can include slope data, such as 45 degree slopes, or convex slopes. -* Understand that for any type including a slope (types 2 to 29) the Tile must be SQUARE, i.e. have an equal width and height. -* Also note that as Tiles are primarily used for levels they have gravity disabled and world bounds collision disabled by default. -* -* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. -* -* @class Phaser.Physics.Ninja.Tile -* @classdesc The Ninja Physics Tile class. Based on code by Metanet Software. -* @constructor -* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. -* @param {number} x - The x coordinate to create this shape at. -* @param {number} y - The y coordinate to create this shape at. -* @param {number} width - The width of this AABB. -* @param {number} height - The height of this AABB. -* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile. -*/ -Phaser.Physics.Ninja.Tile = function (body, x, y, width, height, type) { - - if (typeof type === 'undefined') { type = Phaser.Physics.Ninja.Tile.EMPTY; } - - /** - * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. - */ - this.body = body; - - /** - * @property {Phaser.Physics.Ninja} system - A reference to the physics system. - */ - this.system = body.system; - - /** - * @property {number} id - The ID of this Tile. - * @readonly - */ - this.id = type; - - /** - * @property {number} type - The type of this Tile. - * @readonly - */ - this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY; - - /** - * @property {Phaser.Point} pos - The position of this object. - */ - this.pos = new Phaser.Point(x, y); - - /** - * @property {Phaser.Point} oldpos - The position of this object in the previous update. - */ - this.oldpos = new Phaser.Point(x, y); - - if (this.id > 1 && this.id < 30) - { - // Tile Types 2 to 29 require square tile dimensions, so use the width as the base - height = width; - } - - /** - * @property {number} xw - Half the width. - * @readonly - */ - this.xw = Math.abs(width / 2); - - /** - * @property {number} xw - Half the height. - * @readonly - */ - this.yw = Math.abs(height / 2); - - /** - * @property {number} width - The width. - * @readonly - */ - this.width = width; - - /** - * @property {number} height - The height. - * @readonly - */ - this.height = height; - - /** - * @property {Phaser.Point} velocity - The velocity of this object. - */ - this.velocity = new Phaser.Point(); - - /** - * @property {number} signx - Internal var. - * @private - */ - this.signx = 0; - - /** - * @property {number} signy - Internal var. - * @private - */ - this.signy = 0; - - /** - * @property {number} sx - Internal var. - * @private - */ - this.sx = 0; - - /** - * @property {number} sy - Internal var. - * @private - */ - this.sy = 0; - - // By default Tiles disable gravity and world bounds collision - this.body.gravityScale = 0; - this.body.collideWorldBounds = false; - - if (this.id > 0) - { - this.setType(this.id); - } - -}; - -Phaser.Physics.Ninja.Tile.prototype.constructor = Phaser.Physics.Ninja.Tile; - -Phaser.Physics.Ninja.Tile.prototype = { - - /** - * Updates this objects position. - * - * @method Phaser.Physics.Ninja.Tile#integrate - */ - integrate: function () { - - var px = this.pos.x; - var py = this.pos.y; - - this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); - this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); - - this.velocity.set(this.pos.x - px, this.pos.y - py); - this.oldpos.set(px, py); - - }, - - /** - * Tiles cannot collide with the world bounds, it's up to you to keep them where you want them. But we need this API stub to satisfy the Body. - * - * @method Phaser.Physics.Ninja.Tile#collideWorldBounds - */ - collideWorldBounds: function () { - - var dx = this.system.bounds.x - (this.pos.x - this.xw); - - if (0 < dx) - { - this.reportCollisionVsWorld(dx, 0, 1, 0, null); - } - else - { - dx = (this.pos.x + this.xw) - this.system.bounds.width; - - if (0 < dx) - { - this.reportCollisionVsWorld(-dx, 0, -1, 0, null); - } - } - - var dy = this.system.bounds.y - (this.pos.y - this.yw); - - if (0 < dy) - { - this.reportCollisionVsWorld(0, dy, 0, 1, null); - } - else - { - dy = (this.pos.y + this.yw) - this.system.bounds.height; - - if (0 < dy) - { - this.reportCollisionVsWorld(0, -dy, 0, -1, null); - } - } - - }, - - /** - * Process a world collision and apply the resulting forces. - * - * @method Phaser.Physics.Ninja.Tile#reportCollisionVsWorld - * @param {number} px - The tangent velocity - * @param {number} py - The tangent velocity - * @param {number} dx - Collision normal - * @param {number} dy - Collision normal - * @param {number} obj - Object this Tile collided with - */ - reportCollisionVsWorld: function (px, py, dx, dy, obj) { - - var p = this.pos; - var o = this.oldpos; - - // Calc velocity - var vx = p.x - o.x; - var vy = p.y - o.y; - - // Find component of velocity parallel to collision normal - var dp = (vx * dx + vy * dy); - var nx = dp * dx; //project velocity onto collision normal - - var ny = dp * dy; //nx,ny is normal velocity - - var tx = vx - nx; //px,py is tangent velocity - var ty = vy - ny; - - // We only want to apply collision response forces if the object is travelling into, and not out of, the collision - var b, bx, by, fx, fy; - - if (dp < 0) - { - fx = tx * this.body.friction; - fy = ty * this.body.friction; - - b = 1 + this.body.bounce; - - bx = (nx * b); - by = (ny * b); - - if (dx === 1) - { - this.body.touching.left = true; - } - else if (dx === -1) - { - this.body.touching.right = true; - } - - if (dy === 1) - { - this.body.touching.up = true; - } - else if (dy === -1) - { - this.body.touching.down = true; - } - } - else - { - // Moving out of collision, do not apply forces - bx = by = fx = fy = 0; - } - - // Project object out of collision - p.x += px; - p.y += py; - - // Apply bounce+friction impulses which alter velocity - o.x += px + bx + fx; - o.y += py + by + fy; - - }, - - /** - * Tiles cannot collide with the world bounds, it's up to you to keep them where you want them. But we need this API stub to satisfy the Body. - * - * @method Phaser.Physics.Ninja.Tile#setType - * @param {number} id - The type of Tile this will use, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc. - */ - setType: function (id) { - - if (id === Phaser.Physics.Ninja.Tile.EMPTY) - { - this.clear(); - } - else - { - this.id = id; - this.updateType(); - } - - return this; - - }, - - /** - * Sets this tile to be empty. - * - * @method Phaser.Physics.Ninja.Tile#clear - */ - clear: function () { - - this.id = Phaser.Physics.Ninja.Tile.EMPTY; - this.updateType(); - - }, - - /** - * This converts a tile from implicitly-defined (via id), to explicit (via properties). - * Don't call directly, instead of setType. - * - * @method Phaser.Physics.Ninja.Tile#updateType - * @private - */ - updateType: function () { - - if (this.id === 0) - { - //EMPTY - this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY; - this.signx = 0; - this.signy = 0; - this.sx = 0; - this.sy = 0; - - return true; - } - - //tile is non-empty; collide - if (this.id < Phaser.Physics.Ninja.Tile.TYPE_45DEG) - { - //FULL - this.type = Phaser.Physics.Ninja.Tile.TYPE_FULL; - this.signx = 0; - this.signy = 0; - this.sx = 0; - this.sy = 0; - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONCAVE) - { - // 45deg - this.type = Phaser.Physics.Ninja.Tile.TYPE_45DEG; - - if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn) - { - this.signx = 1; - this.signy = -1; - this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal - this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn) - { - this.signx = -1; - this.signy = -1; - this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal - this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp) - { - this.signx = -1; - this.signy = 1; - this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal - this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp) - { - this.signx = 1; - this.signy = 1; - this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal - this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2) - } - else - { - return false; - } - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONVEX) - { - // Concave - this.type = Phaser.Physics.Ninja.Tile.TYPE_CONCAVE; - - if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpn) - { - this.signx = 1; - this.signy = -1; - this.sx = 0; - this.sy = 0; - } - else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnn) - { - this.signx = -1; - this.signy = -1; - this.sx = 0; - this.sy = 0; - } - else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnp) - { - this.signx = -1; - this.signy = 1; - this.sx = 0; - this.sy = 0; - } - else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpp) - { - this.signx = 1; - this.signy = 1; - this.sx = 0; - this.sy = 0; - } - else - { - return false; - } - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGs) - { - // Convex - this.type = Phaser.Physics.Ninja.Tile.TYPE_CONVEX; - - if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpn) - { - this.signx = 1; - this.signy = -1; - this.sx = 0; - this.sy = 0; - } - else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnn) - { - this.signx = -1; - this.signy = -1; - this.sx = 0; - this.sy = 0; - } - else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnp) - { - this.signx = -1; - this.signy = 1; - this.sx = 0; - this.sy = 0; - } - else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpp) - { - this.signx = 1; - this.signy = 1; - this.sx = 0; - this.sy = 0; - } - else - { - return false; - } - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGb) - { - // 22deg small - this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGs; - - if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS) - { - this.signx = 1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS) - { - this.signx = -1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS) - { - this.signx = -1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS) - { - this.signx = 1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else - { - return false; - } - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGs) - { - // 22deg big - this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGb; - - if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB) - { - this.signx = 1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB) - { - this.signx = -1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB) - { - this.signx = -1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB) - { - this.signx = 1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 1) / slen; - this.sy = (this.signy * 2) / slen; - } - else - { - return false; - } - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGb) - { - // 67deg small - this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGs; - - if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS) - { - this.signx = 1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS) - { - this.signx = -1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS) - { - this.signx = -1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS) - { - this.signx = 1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else - { - return false; - } - } - else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_HALF) - { - // 67deg big - this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGb; - - if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB) - { - this.signx = 1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB) - { - this.signx = -1; - this.signy = -1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB) - { - this.signx = -1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB) - { - this.signx = 1; - this.signy = 1; - var slen = Math.sqrt(2 * 2 + 1 * 1); - this.sx = (this.signx * 2) / slen; - this.sy = (this.signy * 1) / slen; - } - else - { - return false; - } - } - else - { - // Half-full tile - this.type = Phaser.Physics.Ninja.Tile.TYPE_HALF; - - if (this.id == Phaser.Physics.Ninja.Tile.HALFd) - { - this.signx = 0; - this.signy = -1; - this.sx = this.signx; - this.sy = this.signy; - } - else if (this.id == Phaser.Physics.Ninja.Tile.HALFu) - { - this.signx = 0; - this.signy = 1; - this.sx = this.signx; - this.sy = this.signy; - } - else if (this.id == Phaser.Physics.Ninja.Tile.HALFl) - { - this.signx = 1; - this.signy = 0; - this.sx = this.signx; - this.sy = this.signy; - } - else if (this.id == Phaser.Physics.Ninja.Tile.HALFr) - { - this.signx = -1; - this.signy = 0; - this.sx = this.signx; - this.sy = this.signy; - } - else - { - return false; - } - } - } - -} - -/** -* @name Phaser.Physics.Ninja.Tile#x -* @property {number} x - The x position. -*/ -Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "x", { - - /** - * The x position. - * @method x - * @return {number} - */ - get: function () { - return this.pos.x - this.xw; - }, - - /** - * The x position. - * @method x - * @param {number} value - */ - set: function (value) { - this.pos.x = value; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Tile#y -* @property {number} y - The y position. -*/ -Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "y", { - - /** - * The y position. - * @method y - * @return {number} - */ - get: function () { - return this.pos.y - this.yw; - }, - - /** - * The y position. - * @method y - * @param {number} value - */ - set: function (value) { - this.pos.y = value; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Tile#bottom -* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height) -* @readonly -*/ -Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "bottom", { - - /** - * The sum of the y and height properties. - * @method bottom - * @return {number} - * @readonly - */ - get: function () { - return this.pos.y + this.yw; - } - -}); - -/** -* @name Phaser.Physics.Ninja.Tile#right -* @property {number} right - The right value of this Body (same as Body.x + Body.width) -* @readonly -*/ -Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "right", { - - /** - * The sum of the x and width properties. - * @method right - * @return {number} - * @readonly - */ - get: function () { - return this.pos.x + this.xw; - } - -}); - -Phaser.Physics.Ninja.Tile.EMPTY = 0; -Phaser.Physics.Ninja.Tile.FULL = 1;//fullAABB tile -Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn = 2;//45-degree triangle, whose normal is (+ve,-ve) -Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn = 3;//(+ve,+ve) -Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp = 4;//(-ve,+ve) -Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp = 5;//(-ve,-ve) -Phaser.Physics.Ninja.Tile.CONCAVEpn = 6;//1/4-circle cutout -Phaser.Physics.Ninja.Tile.CONCAVEnn = 7; -Phaser.Physics.Ninja.Tile.CONCAVEnp = 8; -Phaser.Physics.Ninja.Tile.CONCAVEpp = 9; -Phaser.Physics.Ninja.Tile.CONVEXpn = 10;//1/4/circle -Phaser.Physics.Ninja.Tile.CONVEXnn = 11; -Phaser.Physics.Ninja.Tile.CONVEXnp = 12; -Phaser.Physics.Ninja.Tile.CONVEXpp = 13; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS = 14;//22.5 degree slope -Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS = 15; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS = 16; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS = 17; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB = 18; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB = 19; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB = 20; -Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB = 21; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS = 22;//67.5 degree slope -Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS = 23; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS = 24; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS = 25; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB = 26; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB = 27; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB = 28; -Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB = 29; -Phaser.Physics.Ninja.Tile.HALFd = 30;//half-full tiles -Phaser.Physics.Ninja.Tile.HALFr = 31; -Phaser.Physics.Ninja.Tile.HALFu = 32; -Phaser.Physics.Ninja.Tile.HALFl = 33; - -Phaser.Physics.Ninja.Tile.TYPE_EMPTY = 0; -Phaser.Physics.Ninja.Tile.TYPE_FULL = 1; -Phaser.Physics.Ninja.Tile.TYPE_45DEG = 2; -Phaser.Physics.Ninja.Tile.TYPE_CONCAVE = 6; -Phaser.Physics.Ninja.Tile.TYPE_CONVEX = 10; -Phaser.Physics.Ninja.Tile.TYPE_22DEGs = 14; -Phaser.Physics.Ninja.Tile.TYPE_22DEGb = 18; -Phaser.Physics.Ninja.Tile.TYPE_67DEGs = 22; -Phaser.Physics.Ninja.Tile.TYPE_67DEGb = 26; -Phaser.Physics.Ninja.Tile.TYPE_HALF = 30; - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Ninja Physics Circle constructor. -* Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. -* -* @class Phaser.Physics.Ninja.Circle -* @classdesc Arcade Physics Constructor -* @constructor -* @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. -* @param {number} x - The x coordinate to create this shape at. -* @param {number} y - The y coordinate to create this shape at. -* @param {number} radius - The radius of this Circle. -*/ -Phaser.Physics.Ninja.Circle = function (body, x, y, radius) { - - /** - * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. - */ - this.body = body; - - /** - * @property {Phaser.Physics.Ninja} system - A reference to the physics system. - */ - this.system = body.system; - - /** - * @property {Phaser.Point} pos - The position of this object. - */ - this.pos = new Phaser.Point(x, y); - - /** - * @property {Phaser.Point} oldpos - The position of this object in the previous update. - */ - this.oldpos = new Phaser.Point(x, y); - - /** - * @property {number} radius - The radius of this circle shape. - */ - this.radius = radius; - - /** - * @property {number} width - The width. - * @readonly - */ - this.width = radius * 2; - - /** - * @property {number} height - The height. - * @readonly - */ - this.height = radius * 2; - - /** - * @property {number} oH - Internal var. - * @private - */ - this.oH = 0; - - /** - * @property {number} oV - Internal var. - * @private - */ - this.oV = 0; - - /** - * @property {Phaser.Point} velocity - The velocity of this object. - */ - this.velocity = new Phaser.Point(); - - /** - * @property {object} circleTileProjections - All of the collision response handlers. - */ - this.circleTileProjections = {}; - - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL] = this.projCircle_Full; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG] = this.projCircle_45Deg; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE] = this.projCircle_Concave; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX] = this.projCircle_Convex; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs] = this.projCircle_22DegS; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb] = this.projCircle_22DegB; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs] = this.projCircle_67DegS; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb] = this.projCircle_67DegB; - this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF] = this.projCircle_Half; - -} - -Phaser.Physics.Ninja.Circle.prototype.constructor = Phaser.Physics.Ninja.Circle; - -Phaser.Physics.Ninja.Circle.COL_NONE = 0; -Phaser.Physics.Ninja.Circle.COL_AXIS = 1; -Phaser.Physics.Ninja.Circle.COL_OTHER = 2; - -Phaser.Physics.Ninja.Circle.prototype = { - - /** - * Updates this Circles position. - * - * @method Phaser.Physics.Ninja.Circle#integrate - */ - integrate: function () { - - var px = this.pos.x; - var py = this.pos.y; - - // integrate - this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); - this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); - - // store - this.velocity.set(this.pos.x - px, this.pos.y - py); - this.oldpos.set(px, py); - - }, - - /** - * Process a world collision and apply the resulting forces. - * - * @method Phaser.Physics.Ninja.Circle#reportCollisionVsWorld - * @param {number} px - The tangent velocity - * @param {number} py - The tangent velocity - * @param {number} dx - Collision normal - * @param {number} dy - Collision normal - * @param {number} obj - Object this Circle collided with - */ - reportCollisionVsWorld: function (px, py, dx, dy, obj) { - - var p = this.pos; - var o = this.oldpos; - - // Calc velocity - var vx = p.x - o.x; - var vy = p.y - o.y; - - // Find component of velocity parallel to collision normal - var dp = (vx * dx + vy * dy); - var nx = dp * dx; //project velocity onto collision normal - - var ny = dp * dy; //nx,ny is normal velocity - - var tx = vx - nx; //px,py is tangent velocity - var ty = vy - ny; - - // We only want to apply collision response forces if the object is travelling into, and not out of, the collision - var b, bx, by, fx, fy; - - if (dp < 0) - { - fx = tx * this.body.friction; - fy = ty * this.body.friction; - - b = 1 + this.body.bounce; - - bx = (nx * b); - by = (ny * b); - - if (dx === 1) - { - this.body.touching.left = true; - } - else if (dx === -1) - { - this.body.touching.right = true; - } - - if (dy === 1) - { - this.body.touching.up = true; - } - else if (dy === -1) - { - this.body.touching.down = true; - } - } - else - { - // Moving out of collision, do not apply forces - bx = by = fx = fy = 0; - } - - // Project object out of collision - p.x += px; - p.y += py; - - // Apply bounce+friction impulses which alter velocity - o.x += px + bx + fx; - o.y += py + by + fy; - - }, - - /** - * Collides this Circle against the world bounds. - * - * @method Phaser.Physics.Ninja.Circle#collideWorldBounds - */ - collideWorldBounds: function () { - - var dx = this.system.bounds.x - (this.pos.x - this.xw); - - if (0 < dx) - { - this.reportCollisionVsWorld(dx, 0, 1, 0, null); - } - else - { - dx = (this.pos.x + this.xw) - this.system.bounds.width; - - if (0 < dx) - { - this.reportCollisionVsWorld(-dx, 0, -1, 0, null); - } - } - - var dy = this.system.bounds.y - (this.pos.y - this.yw); - - if (0 < dy) - { - this.reportCollisionVsWorld(0, dy, 0, 1, null); - } - else - { - dy = (this.pos.y + this.yw) - this.system.bounds.height; - - if (0 < dy) - { - this.reportCollisionVsWorld(0, -dy, 0, -1, null); - } - } - - }, - - /** - * Collides this Circle with a Tile. - * - * @method Phaser.Physics.Ninja.Circle#collideCircleVsTile - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {boolean} True if they collide, otherwise false. - */ - collideCircleVsTile: function (tile) { - - var pos = this.pos; - var r = this.radius; - var c = tile; - - var tx = c.pos.x; - var ty = c.pos.y; - var txw = c.xw; - var tyw = c.yw; - - var dx = pos.x - tx; // tile->obj delta - var px = (txw + r) - Math.abs(dx); // penetration depth in x - - if (0 < px) - { - var dy = pos.y - ty; // tile->obj delta - var py = (tyw + r) - Math.abs(dy); // pen depth in y - - if (0 < py) - { - // object may be colliding with tile - - // determine grid/voronoi region of circle center - this.oH = 0; - this.oV = 0; - - if (dx < -txw) - { - // circle is on left side of tile - this.oH = -1; - } - else if (txw < dx) - { - // circle is on right side of tile - this.oH = 1; - } - - if (dy < -tyw) - { - // circle is on top side of tile - this.oV = -1; - } - else if (tyw < dy) - { - // circle is on bottom side of tile - this.oV = 1; - } - - return this.resolveCircleTile(px, py, this.oH, this.oV, this, c); - - } - } - }, - - /** - * Resolves tile collision. - * - * @method Phaser.Physics.Ninja.Circle#resolveCircleTile - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - resolveCircleTile: function (x, y, oH, oV, obj, t) { - - if (0 < t.id) - { - return this.circleTileProjections[t.type](x, y, oH, oV, obj, t); - } - else - { - // console.log("ResolveCircleTile() was called with an empty (or unknown) tile!: ID=" + t.id + ")"); - return false; - } - - }, - - /** - * Resolves Full tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_Full - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_Full: function (x, y, oH, oV, obj, t) { - - //if we're colliding vs. the current cell, we need to project along the - //smallest penetration vector. - //if we're colliding vs. horiz. or vert. neighb, we simply project horiz/vert - //if we're colliding diagonally, we need to collide vs. tile corner - - if (oH == 0) - { - if (oV == 0) - { - //collision with current cell - if (x < y) - { - //penetration in x is smaller; project in x - var dx = obj.pos.x - t.pos.x;//get sign for projection along x-axis - - //NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?) - if (dx < 0) - { - obj.reportCollisionVsWorld(-x, 0, -1, 0, t); - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(x, 0, 1, 0, t); - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - } - else - { - //penetration in y is smaller; project in y - var dy = obj.pos.y - t.pos.y;//get sign for projection along y-axis - - //NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?) - if (dy < 0) - { - obj.reportCollisionVsWorld(0, -y, 0, -1, t); - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(0, y, 0, 1, t); - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - } - } - else - { - //collision with vertical neighbor - obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - } - else if (oV == 0) - { - //collision with horizontal neighbor - obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //diagonal collision - - //get diag vertex position - var vx = t.pos.x + (oH * t.xw); - var vy = t.pos.y + (oV * t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx * dx + dy * dy); - var pen = obj.radius - len; - - if (0 < pen) - { - //vertex is in the circle; project outward - if (len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - - }, - - /** - * Resolves 45 Degree tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_45Deg - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_45Deg: function (x, y, oH, oV, obj, t) { - - //if we're colliding diagonally: - // -if obj is in the diagonal pointed to by the slope normal: we can't collide, do nothing - // -else, collide vs. the appropriate vertex - //if obj is in this tile: perform collision as for aabb-ve-45deg - //if obj is horiz OR very neighb in direction of slope: collide only vs. slope - //if obj is horiz or vert neigh against direction of slope: collide vs. face - - var signx = t.signx; - var signy = t.signy; - var lenP; - - if (oH == 0) - { - if (oV == 0) - { - //colliding with current tile - - var sx = t.sx; - var sy = t.sy; - - var ox = (obj.pos.x - (sx * obj.radius)) - t.pos.x;//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (sy * obj.radius)) - t.pos.y;//point on the circle, relative to the tile center - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the innermost point is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox * sx) + (oy * sy); - - if (dp < 0) - { - //collision; project delta onto slope and use this as the slope penetration vector - sx *= -dp;//(sx,sy) is now the penetration vector - sy *= -dp; - - //find the smallest axial projection vector - if (x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - - //get sign for projection along x-axis - if ((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - - //get sign for projection along y-axis - if ((obj.pos.y - t.pos.y) < 0) - { - y *= -1; - } - } - - var lenN = Math.sqrt(sx * sx + sy * sy); - - if (lenP < lenN) - { - obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - - } - else - { - //colliding vertically - if ((signy * oV) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y + (oV * t.yw));//point on the circle, relative to the closest tile vert - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the vertex, otherwise by the normal. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronoi region, or that of the vertex. - var perp = (ox * -sy) + (oy * sx); - if (0 < (perp * signx * signy)) - { - //collide vs. vertex - var len = Math.sqrt(ox * ox + oy * oy); - var pen = obj.radius - len; - if (0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox * sx) + (oy * sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - if (0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - } - else if (oV == 0) - { - //colliding horizontally - if ((signx * oH) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var ox = obj.pos.x - (t.pos.x + (oH * t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//point on the circle, relative to the closest tile vert - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the normal, otherwise by the vertex. - //(NOTE: this is the opposite logic of the vertical case; - // for vertical, if the perp prod and the slope's slope agree, it's outside. - // for horizontal, if the perp prod and the slope's slope agree, circle is inside. - // ..but this is only a property of flahs' coord system (i.e the rules might swap - // in righthanded systems)) - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox * -sy) + (oy * sx); - if ((perp * signx * signy) < 0) - { - //collide vs. vertex - var len = Math.sqrt(ox * ox + oy * oy); - var pen = obj.radius - len; - if (0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox * sx) + (oy * sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - if (0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - else - { - //colliding diagonally - if (0 < ((signx * oH) + (signy * oV))) - { - //the dotprod of slope normal and cell offset is strictly positive, - //therefore obj is in the diagonal neighb pointed at by the normal, and - //it cannot possibly reach/touch/penetrate the slope - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else - { - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x + (oH * t.xw); - var vy = t.pos.y + (oV * t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx * dx + dy * dy); - var pen = obj.radius - len; - if (0 < pen) - { - //vertex is in the circle; project outward - if (len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - }, - - /** - * Resolves Concave tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_Concave - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_Concave: function (x, y, oH, oV, obj, t) { - - //if we're colliding diagonally: - // -if obj is in the diagonal pointed to by the slope normal: we can't collide, do nothing - // -else, collide vs. the appropriate vertex - //if obj is in this tile: perform collision as for aabb - //if obj is horiz OR very neighb in direction of slope: collide vs vert - //if obj is horiz or vert neigh against direction of slope: collide vs. face - - var signx = t.signx; - var signy = t.signy; - var lenP; - - if (oH == 0) - { - if (oV == 0) - { - //colliding with current tile - - var ox = (t.pos.x + (signx * t.xw)) - obj.pos.x;//(ox,oy) is the vector from the circle to - var oy = (t.pos.y + (signy * t.yw)) - obj.pos.y;//tile-circle's center - - var twid = t.xw * 2; - var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var len = Math.sqrt(ox * ox + oy * oy); - var pen = (len + obj.radius) - trad; - - if (0 < pen) - { - //find the smallest axial projection vector - if (x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - - //get sign for projection along x-axis - if ((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - - //get sign for projection along y-axis - if ((obj.pos.y - t.pos.y) < 0) - { - y *= -1; - } - } - - - if (lenP < pen) - { - obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we can assume that len >0, because if we're here then - //(len + obj.radius) > trad, and since obj.radius <= trad - //len MUST be > 0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - - } - else - { - //colliding vertically - if ((signy * oV) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we could only be colliding vs the vertical tip - - //get diag vertex position - var vx = t.pos.x - (signx * t.xw); - var vy = t.pos.y + (oV * t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx * dx + dy * dy); - var pen = obj.radius - len; - if (0 < pen) - { - //vertex is in the circle; project outward - if (len == 0) - { - //project out vertically - dx = 0; - dy = oV; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - else if (oV == 0) - { - //colliding horizontally - if ((signx * oH) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we could only be colliding vs the horizontal tip - - //get diag vertex position - var vx = t.pos.x + (oH * t.xw); - var vy = t.pos.y - (signy * t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx * dx + dy * dy); - var pen = obj.radius - len; - if (0 < pen) - { - //vertex is in the circle; project outward - if (len == 0) - { - //project out horizontally - dx = oH; - dy = 0; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - else - { - //colliding diagonally - if (0 < ((signx * oH) + (signy * oV))) - { - //the dotprod of slope normal and cell offset is strictly positive, - //therefore obj is in the diagonal neighb pointed at by the normal, and - //it cannot possibly reach/touch/penetrate the slope - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else - { - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x + (oH * t.xw); - var vy = t.pos.y + (oV * t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx * dx + dy * dy); - var pen = obj.radius - len; - if (0 < pen) - { - //vertex is in the circle; project outward - if (len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - - }, - - /** - * Resolves Convex tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_Convex - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_Convex: function (x, y, oH, oV, obj, t) { - - //if the object is horiz AND/OR vertical neighbor in the normal (signx,signy) - //direction, collide vs. tile-circle only. - //if we're colliding diagonally: - // -else, collide vs. the appropriate vertex - //if obj is in this tile: perform collision as for aabb - //if obj is horiz or vert neigh against direction of slope: collide vs. face - - var signx = t.signx; - var signy = t.signy; - var lenP; - - if (oH == 0) - { - if (oV == 0) - { - //colliding with current tile - - - var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to - var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center - - var twid = t.xw * 2; - var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var len = Math.sqrt(ox * ox + oy * oy); - var pen = (trad + obj.radius) - len; - - if (0 < pen) - { - //find the smallest axial projection vector - if (x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - - //get sign for projection along x-axis - if ((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - - //get sign for projection along y-axis - if ((obj.pos.y - t.pos.y) < 0) - { - y *= -1; - } - } - - - if (lenP < pen) - { - obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //note: len should NEVER be == 0, because if it is, - //projeciton by an axis shoudl always be shorter, and we should - //never arrive here - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - - } - } - } - else - { - //colliding vertically - if ((signy * oV) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //obj in neighboring cell pointed at by tile normal; - //we could only be colliding vs the tile-circle surface - - var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to - var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center - - var twid = t.xw * 2; - var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var len = Math.sqrt(ox * ox + oy * oy); - var pen = (trad + obj.radius) - len; - - if (0 < pen) - { - - //note: len should NEVER be == 0, because if it is, - //obj is not in a neighboring cell! - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - else if (oV == 0) - { - //colliding horizontally - if ((signx * oH) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //obj in neighboring cell pointed at by tile normal; - //we could only be colliding vs the tile-circle surface - - var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to - var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center - - var twid = t.xw * 2; - var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var len = Math.sqrt(ox * ox + oy * oy); - var pen = (trad + obj.radius) - len; - - if (0 < pen) - { - - //note: len should NEVER be == 0, because if it is, - //obj is not in a neighboring cell! - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - else - { - //colliding diagonally - if (0 < ((signx * oH) + (signy * oV))) - { - //obj in diag neighb cell pointed at by tile normal; - //we could only be colliding vs the tile-circle surface - - var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to - var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center - - var twid = t.xw * 2; - var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; - //note that this should be precomputed at compile-time since it's constant - - var len = Math.sqrt(ox * ox + oy * oy); - var pen = (trad + obj.radius) - len; - - if (0 < pen) - { - - //note: len should NEVER be == 0, because if it is, - //obj is not in a neighboring cell! - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x + (oH * t.xw); - var vy = t.pos.y + (oV * t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx * dx + dy * dy); - var pen = obj.radius - len; - if (0 < pen) - { - //vertex is in the circle; project outward - if (len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - - }, - - /** - * Resolves Half tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_Half - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_Half: function (x,y,oH,oV,obj,t) { - - //if obj is in a neighbor pointed at by the halfedge normal, - //we'll never collide (i.e if the normal is (0,1) and the obj is in the DL.D, or R neighbors) - // - //if obj is in a neigbor perpendicular to the halfedge normal, it might - //collide with the halfedge-vertex, or with the halfedge side. - // - //if obj is in a neigb pointing opposite the halfedge normal, obj collides with edge - // - //if obj is in a diagonal (pointing away from the normal), obj collides vs vertex - // - //if obj is in the halfedge cell, it collides as with aabb - - var signx = t.signx; - var signy = t.signy; - - var celldp = (oH*signx + oV*signy);//this tells us about the configuration of cell-offset relative to tile normal - if(0 < celldp) - { - //obj is in "far" (pointed-at-by-normal) neighbor of halffull tile, and will never hit - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else if(oH == 0) - { - if(oV == 0) - { - //colliding with current tile - var r = obj.radius; - var ox = (obj.pos.x - (signx*r)) - t.pos.x;//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (signy*r)) - t.pos.y;//point on the circle, relative to the tile center - - - //we perform operations analogous to the 45deg tile, except we're using - //an axis-aligned slope instead of an angled one.. - var sx = signx; - var sy = signy; - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - - var lenN = Math.sqrt(sx*sx + sy*sy); - var lenP = Math.sqrt(x*x + y*y); - - if(lenP < lenN) - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP,t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.signx,t.signy); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - return true; - } - - } - else - { - //colliding vertically - - if(celldp == 0) - { - - var r = obj.radius; - var dx = obj.pos.x - t.pos.x; - - //we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex - //or halfedge side - if((dx*signx) < 0) - { - //collision with halfedge side - obj.reportCollisionVsWorld(0,y*oV,0,oV,t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //collision with halfedge vertex - var dy = obj.pos.y - (t.pos.y + oV*t.yw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = signx / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - } - else - { - //due to the first conditional (celldp >0), we know we're in the cell "opposite" the normal, and so - //we can only collide with the cell edge - //collision with vertical neighbor - obj.reportCollisionVsWorld(0,y*oV,0,oV,t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - - } - } - else if(oV == 0) - { - //colliding horizontally - if(celldp == 0) - { - - var r = obj.radius; - var dy = obj.pos.y - t.pos.y; - - //we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex - //or halfedge side - if((dy*signy) < 0) - { - //collision with halfedge side - obj.reportCollisionVsWorld(x*oH,0,oH,0,t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //collision with halfedge vertex - var dx = obj.pos.x - (t.pos.x + oH*t.xw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = signx / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - } - else - { - //due to the first conditional (celldp >0), we know w're in the cell "opposite" the normal, and so - //we can only collide with the cell edge - obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - } - else - { - //colliding diagonally; we know, due to the initial (celldp >0) test which has failed - //if we've reached this point, that we're in a diagonal neighbor on the non-normal side, so - //we could only be colliding with the cell vertex, if at all. - - //get diag vertex position - var vx = t.pos.x + (oH*t.xw); - var vy = t.pos.y + (oV*t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - - }, - - /** - * Resolves 22 Degree tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_22DegS - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_22DegS: function (x,y,oH,oV,obj,t) { - - //if the object is in a cell pointed at by signy, no collision will ever occur - //otherwise, - // - //if we're colliding diagonally: - // -collide vs. the appropriate vertex - //if obj is in this tile: collide vs slope or vertex - //if obj is horiz neighb in direction of slope: collide vs. slope or vertex - //if obj is horiz neighb against the slope: - // if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face) - // else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert) - //if obj is vert neighb against direction of slope: collide vs. face - - var signx = t.signx; - var signy = t.signy; - - if(0 < (signy*oV)) - { - //object will never collide vs tile, it can't reach that far - - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else if(oH == 0) - { - if(oV == 0) - { - //colliding with current tile - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var r = obj.radius; - var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the tile corner - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the vertex, otherwise by the normal or axially. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - - var perp = (ox*-sy) + (oy*sx); - if(0 < (perp*signx*signy)) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = r - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope or vs axis - ox -= r*sx;//this gives us the vector from - oy -= r*sy;//a point on the slope to the innermost point on the circle - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - - //find the smallest axial projection vector - if(x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - //get sign for projection along x-axis - if((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - //get sign for projection along y-axis - if((obj.pos.y - t.pos.y)< 0) - { - y *= -1; - } - } - - if(lenP < lenN) - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - } - - } - else - { - //colliding vertically; we can assume that (signy*oV) < 0 - //due to the first conditional far above - - obj.reportCollisionVsWorld(0,y*oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - } - else if(oV == 0) - { - //colliding horizontally - if((signx*oH) < 0) - { - //colliding with face/edge OR with corner of wedge, depending on our position vertically - - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x - (signx*t.xw); - var vy = t.pos.y; - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - if((dy*signy) < 0) - { - //colliding vs face - obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding vs. vertex - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - else - { - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var ox = obj.pos.x - (t.pos.x + (oH*t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the closest tile vert - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the normal, otherwise by the vertex. - //(NOTE: this is the opposite logic of the vertical case; - // for vertical, if the perp prod and the slope's slope agree, it's outside. - // for horizontal, if the perp prod and the slope's slope agree, circle is inside. - // ..but this is only a property of flahs' coord system (i.e the rules might swap - // in righthanded systems)) - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox*-sy) + (oy*sx); - if((perp*signx*signy) < 0) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = obj.radius - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox*sx) + (oy*sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - - if(0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx*pen, sy*pen, sx, sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - else - { - - //colliding diagonally; due to the first conditional above, - //obj is vertically offset against slope, and offset in either direction horizontally - - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x + (oH*t.xw); - var vy = t.pos.y + (oV*t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - - }, - - /** - * Resolves 22 Degree tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_22DegB - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_22DegB: function (x,y,oH, oV, obj,t) { - - //if we're colliding diagonally: - // -if we're in the cell pointed at by the normal, collide vs slope, else - // collide vs. the appropriate corner/vertex - // - //if obj is in this tile: collide as with aabb - // - //if obj is horiz or vertical neighbor AGAINST the slope: collide with edge - // - //if obj is horiz neighb in direction of slope: collide vs. slope or vertex or edge - // - //if obj is vert neighb in direction of slope: collide vs. slope or vertex - - var signx = t.signx; - var signy = t.signy; - - if(oH == 0) - { - if(oV == 0) - { - //colliding with current cell - - var sx = t.sx; - var sy = t.sy; - - var r = obj.radius; - var ox = (obj.pos.x - (sx*r)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (sy*r)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - - //find the smallest axial projection vector - if(x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - //get sign for projection along x-axis - if((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - //get sign for projection along y-axis - if((obj.pos.y - t.pos.y)< 0) - { - y *= -1; - } - } - - if(lenP < lenN) - { - obj.reportCollisionVsWorld(x, y, x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - else - { - //colliding vertically - - if((signy*oV) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y + (signy*t.yw));//point on the circle, relative to the closest tile vert - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the vertex, otherwise by the normal. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox*-sy) + (oy*sx); - if(0 < (perp*signx*signy)) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = obj.radius - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox*sx) + (oy*sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - if(0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx*pen, sy*pen,sx, sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - } - else if(oV == 0) - { - //colliding horizontally - - if((signx*oH) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding with edge, slope, or vertex - - var ox = obj.pos.x - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the closest tile vert - - if((oy*signy) < 0) - { - //we're colliding with the halfface - obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding with the vertex or slope - - var sx = t.sx; - var sy = t.sy; - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the slope, otherwise by the vertex. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox*-sy) + (oy*sx); - if((perp*signx*signy) < 0) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = obj.radius - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox*sx) + (oy*sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - if(0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - } - else - { - //colliding diagonally - if( 0 < ((signx*oH) + (signy*oV)) ) - { - //the dotprod of slope normal and cell offset is strictly positive, - //therefore obj is in the diagonal neighb pointed at by the normal. - - //collide vs slope - - //we should really precalc this at compile time, but for now, fuck it - var slen = Math.sqrt(2*2 + 1*1);//the raw slope is (-2,-1) - var sx = (signx*1) / slen;//get slope _unit_ normal; - var sy = (signy*2) / slen;//raw RH normal is (1,-2) - - var r = obj.radius; - var ox = (obj.pos.x - (sx*r)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (sy*r)) - (t.pos.y + (signy*t.yw));//point on the circle, relative to a point on the slope - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - //(sx,sy)*-dp is the projection vector - obj.reportCollisionVsWorld(-sx*dp, -sy*dp, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else - { - //collide vs the appropriate vertex - var vx = t.pos.x + (oH*t.xw); - var vy = t.pos.y + (oV*t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - }, - - /** - * Resolves 67 Degree tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_67DegS - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_67DegS: function (x,y,oH,oV,obj,t) { - - //if the object is in a cell pointed at by signx, no collision will ever occur - //otherwise, - // - //if we're colliding diagonally: - // -collide vs. the appropriate vertex - //if obj is in this tile: collide vs slope or vertex or axis - //if obj is vert neighb in direction of slope: collide vs. slope or vertex - //if obj is vert neighb against the slope: - // if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face) - // else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert) - //if obj is horiz neighb against direction of slope: collide vs. face - - var signx = t.signx; - var signy = t.signy; - - if(0 < (signx*oH)) - { - //object will never collide vs tile, it can't reach that far - - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else if(oH == 0) - { - if(oV == 0) - { - //colliding with current tile - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var r = obj.radius; - var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the tile corner - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the normal or axis, otherwise by the corner/vertex - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronoi region, or that of the vertex. - - var perp = (ox*-sy) + (oy*sx); - if((perp*signx*signy) < 0) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = r - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope or vs axis - ox -= r*sx;//this gives us the vector from - oy -= r*sy;//a point on the slope to the innermost point on the circle - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - - //find the smallest axial projection vector - if(x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - //get sign for projection along x-axis - if((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - //get sign for projection along y-axis - if((obj.pos.y - t.pos.y)< 0) - { - y *= -1; - } - } - - if(lenP < lenN) - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS - } - else - { - obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - - } - else - { - //colliding vertically - - if((signy*oV) < 0) - { - //colliding with face/edge OR with corner of wedge, depending on our position vertically - - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x; - var vy = t.pos.y - (signy*t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - if((dx*signx) < 0) - { - //colliding vs face - obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding vs. vertex - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - else - { - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var sx = t.sx; - var sy = t.sy; - - var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y + (oV*t.yw));//point on the circle, relative to the closest tile vert - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the vertex, otherwise by the normal. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox*-sy) + (oy*sx); - if(0 < (perp*signx*signy)) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = obj.radius - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox*sx) + (oy*sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - - if(0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - } - else if(oV == 0) - { - //colliding horizontally; we can assume that (signy*oV) < 0 - //due to the first conditional far above - - obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding diagonally; due to the first conditional above, - //obj is vertically offset against slope, and offset in either direction horizontally - - //collide vs. vertex - //get diag vertex position - var vx = t.pos.x + (oH*t.xw); - var vy = t.pos.y + (oV*t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - - }, - - /** - * Resolves 67 Degree tile collision. - * - * @method Phaser.Physics.Ninja.Circle#projCircle_67DegB - * @param {number} x - Penetration depth on the x axis. - * @param {number} y - Penetration depth on the y axis. - * @param {number} oH - Grid / voronoi region. - * @param {number} oV - Grid / voronoi region. - * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. - * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. - * @return {number} The result of the collision. - */ - projCircle_67DegB: function (x,y,oH, oV, obj,t) { - - //if we're colliding diagonally: - // -if we're in the cell pointed at by the normal, collide vs slope, else - // collide vs. the appropriate corner/vertex - // - //if obj is in this tile: collide as with aabb - // - //if obj is horiz or vertical neighbor AGAINST the slope: collide with edge - // - //if obj is vert neighb in direction of slope: collide vs. slope or vertex or halfedge - // - //if obj is horiz neighb in direction of slope: collide vs. slope or vertex - - var signx = t.signx; - var signy = t.signy; - - if(oH == 0) - { - if(oV == 0) - { - //colliding with current cell - - var sx = t.sx; - var sy = t.sy; - - var r = obj.radius; - var ox = (obj.pos.x - (sx*r)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (sy*r)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - sx *= -dp;//(sx,sy) is now the projection vector - sy *= -dp; - - var lenN = Math.sqrt(sx*sx + sy*sy); - - //find the smallest axial projection vector - if(x < y) - { - //penetration in x is smaller - lenP = x; - y = 0; - //get sign for projection along x-axis - if((obj.pos.x - t.pos.x) < 0) - { - x *= -1; - } - } - else - { - //penetration in y is smaller - lenP = y; - x = 0; - //get sign for projection along y-axis - if((obj.pos.y - t.pos.y)< 0) - { - y *= -1; - } - } - - if(lenP < lenN) - { - obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - } - else - { - //colliding vertically - - if((signy*oV) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding with edge, slope, or vertex - - var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y + (signy*t.yw));//point on the circle, relative to the closest tile vert - - if((ox*signx) < 0) - { - //we're colliding with the halfface - obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //colliding with the vertex or slope - - var sx = t.sx; - var sy = t.sy; - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the vertex, otherwise by the slope. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox*-sy) + (oy*sx); - if(0 < (perp*signx*signy)) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = obj.radius - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox*sx) + (oy*sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - if(0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx*pen, sy*pen, sx, sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - } - } - else if(oV == 0) - { - //colliding horizontally - - if((signx*oH) < 0) - { - //colliding with face/edge - obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); - - return Phaser.Physics.Ninja.Circle.COL_AXIS; - } - else - { - //we could only be colliding vs the slope OR a vertex - //look at the vector form the closest vert to the circle to decide - - var slen = Math.sqrt(2*2 + 1*1);//the raw slope is (-2,-1) - var sx = (signx*2) / slen;//get slope _unit_ normal; - var sy = (signy*1) / slen;//raw RH normal is (1,-2) - - var ox = obj.pos.x - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost - var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the closest tile vert - - //if the component of (ox,oy) parallel to the normal's righthand normal - //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) - //then we project by the slope, otherwise by the vertex. - //note that this is simply a VERY tricky/weird method of determining - //if the circle is in side the slope/face's voronio region, or that of the vertex. - var perp = (ox*-sy) + (oy*sx); - if((perp*signx*signy) < 0) - { - //collide vs. vertex - var len = Math.sqrt(ox*ox + oy*oy); - var pen = obj.radius - len; - if(0 < pen) - { - //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 - ox /= len; - oy /= len; - - obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - else - { - //collide vs. slope - - //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're - //penetrating the slope. note that this method of penetration calculation doesn't hold - //in general (i.e it won't work if the circle is in the slope), but works in this case - //because we know the circle is in a neighboring cell - var dp = (ox*sx) + (oy*sy); - var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. - if(0 < pen) - { - //collision; circle out along normal by penetration amount - obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - } - } - } - else - { - //colliding diagonally - if( 0 < ((signx*oH) + (signy*oV)) ) - { - //the dotprod of slope normal and cell offset is strictly positive, - //therefore obj is in the diagonal neighb pointed at by the normal. - - //collide vs slope - - var sx = t.sx; - var sy = t.sy; - - var r = obj.radius; - var ox = (obj.pos.x - (sx*r)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost - var oy = (obj.pos.y - (sy*r)) - (t.pos.y - (signy*t.yw));//point on the circle, relative to a point on the slope - - //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope - //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) - var dp = (ox*sx) + (oy*sy); - - if(dp < 0) - { - //collision; project delta onto slope and use this to displace the object - //(sx,sy)*-dp is the projection vector - - obj.reportCollisionVsWorld(-sx*dp, -sy*dp, t.sx, t.sy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - else - { - - //collide vs the appropriate vertex - var vx = t.pos.x + (oH*t.xw); - var vy = t.pos.y + (oV*t.yw); - - var dx = obj.pos.x - vx;//calc vert->circle vector - var dy = obj.pos.y - vy; - - var len = Math.sqrt(dx*dx + dy*dy); - var pen = obj.radius - len; - if(0 < pen) - { - //vertex is in the circle; project outward - if(len == 0) - { - //project out by 45deg - dx = oH / Math.SQRT2; - dy = oV / Math.SQRT2; - } - else - { - dx /= len; - dy /= len; - } - - obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); - - return Phaser.Physics.Ninja.Circle.COL_OTHER; - } - - } - } - - return Phaser.Physics.Ninja.Circle.COL_NONE; - } - -} - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* @const -* @type {number} -*/ -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.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.P2 = function (game, config) { - - /** - * @property {Phaser.Game} game - Local reference to game. - */ - this.game = game; - - if (typeof config === 'undefined') - { - config = { gravity: [0, 0], broadphase: new p2.SAPBroadphase() }; - } - - /** - * @property {p2.World} game - The p2 World in which the simulation is run. - * @protected - */ - this.world = new p2.World(config); - - /** - * @property {array} materials - A local array of all created Materials. - * @protected - */ - this.materials = []; - - /** - * @property {Phaser.InversePointProxy} gravity - The gravity applied to all bodies each step. - */ - 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. - */ - this.bounds = null; - - /** - * @property {array} _wallShapes - The wall bounds shapes. - * @private - */ - this._wallShapes = [ null, null, null, null ]; - - /** - * @property {Phaser.Signal} onBodyAdded - Dispatched when a new Body is added to the World. - */ - this.onBodyAdded = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onBodyRemoved - Dispatched when a Body is removed from the World. - */ - this.onBodyRemoved = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onSpringAdded - Dispatched when a new Spring is added to the World. - */ - this.onSpringAdded = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onSpringRemoved - Dispatched when a Spring is removed from the World. - */ - this.onSpringRemoved = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onConstraintAdded - Dispatched when a new Constraint is added to the World. - */ - this.onConstraintAdded = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onConstraintRemoved - Dispatched when a Constraint is removed from the World. - */ - this.onConstraintRemoved = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onContactMaterialAdded - Dispatched when a new ContactMaterial is added to the World. - */ - this.onContactMaterialAdded = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onContactMaterialRemoved - Dispatched when a ContactMaterial is removed from the World. - */ - this.onContactMaterialRemoved = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onPostStep - Dispatched after the World.step() - */ - this.onPostStep = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onPostBroadphase - Dispatched after the Broadphase has collected collision pairs in the world. - */ - this.onPostBroadphase = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onImpact - Dispatched when a first contact is created between two bodies. This event is fired after the step has been done. - */ - this.onImpact = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onBeginContact - Dispatched when a first contact is created between two bodies. This event is fired before the step has been done. - */ - this.onBeginContact = new Phaser.Signal(); - - /** - * @property {Phaser.Signal} onEndContact - Dispatched when final contact occurs between two bodies. This event is fired before the step has been done. - */ - this.onEndContact = new Phaser.Signal(); - - // Hook into the World events - this.world.on("postStep", this.postStepHandler, this); - this.world.on("postBroadphase", this.postBroadphaseHandler, this); - this.world.on("impact", this.impactHandler, this); - this.world.on("beginContact", this.beginContactHandler, this); - this.world.on("endContact", this.endContactHandler, this); - - /** - * @property {array} collisionGroups - Internal var. - */ - this.collisionGroups = []; - - /** - * @property {number} _collisionGroupID - Internal var. - * @private - */ - this._collisionGroupID = 2; - - 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 = []; - - // Group vs. Group callbacks - - // By default we want everything colliding with everything - this.setBoundsToWorld(true, true, true, true, false); - -}; - -Phaser.Physics.P2.prototype = { - - /** - * Handles a p2 postStep event. - * - * @method Phaser.Physics.P2#postStepHandler - * @private - * @param {object} event - The event data. - */ - postStepHandler: function (event) { - - }, - - /** - * 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.P2#postBroadphaseHandler - * @private - * @param {object} event - The event data. - */ - postBroadphaseHandler: function (event) { - - // Body.id 1 is always the World bounds object - - for (var i = 0; i < event.pairs.length; i += 2) - { - var a = event.pairs[i]; - var b = event.pairs[i+1]; - - if (a.id !== 1 && b.id !== 1) - { - // console.log('postBroadphaseHandler', a, b); - } - } - - }, - - /** - * Handles a p2 impact event. - * - * @method Phaser.Physics.P2#impactHandler - * @private - * @param {object} event - The event data. - */ - impactHandler: function (event) { - - if (event.bodyA.parent && event.bodyB.parent) - { - // Body vs. Body callbacks - var a = event.bodyA.parent; - var b = event.bodyB.parent; - - if (a._bodyCallbacks[event.bodyB.id]) - { - a._bodyCallbacks[event.bodyB.id].call(a._bodyCallbackContext[event.bodyB.id], a, b, event.shapeA, event.shapeB); - } - - if (b._bodyCallbacks[event.bodyA.id]) - { - b._bodyCallbacks[event.bodyA.id].call(b._bodyCallbackContext[event.bodyA.id], b, a, event.shapeB, event.shapeA); - } - - // Body vs. Group callbacks - if (a._groupCallbacks[event.shapeB.collisionGroup]) - { - a._groupCallbacks[event.shapeB.collisionGroup].call(a._groupCallbackContext[event.shapeB.collisionGroup], a, b, event.shapeA, event.shapeB); - } - - if (b._groupCallbacks[event.shapeA.collisionGroup]) - { - b._groupCallbacks[event.shapeA.collisionGroup].call(b._groupCallbackContext[event.shapeA.collisionGroup], b, a, event.shapeB, event.shapeA); - } - } - - }, - - /** - * Handles a p2 begin contact event. - * - * @method Phaser.Physics.P2#beginContactHandler - * @private - * @param {object} event - The event data. - */ - beginContactHandler: function (event) { - - // console.log('beginContactHandler'); - // console.log(event); - - if (event.bodyA.id > 1 && event.bodyB.id > 1) - { - // console.log('beginContactHandler'); - // console.log(event.bodyA.parent.sprite.key); - // console.log(event.bodyB.parent.sprite.key); - } - - }, - - /** - * Handles a p2 end contact event. - * - * @method Phaser.Physics.P2#endContactHandler - * @private - * @param {object} event - The event data. - */ - endContactHandler: function (event) { - - // console.log('endContactHandler'); - // console.log(event); - - - if (event.bodyA.id > 1 && event.bodyB.id > 1) - { - // console.log('endContactHandler'); - // console.log(event); - } - - }, - - /** - * Sets the bounds of the Physics world to match the Game.World dimensions. - * You can optionally set which 'walls' to create: left, right, top or bottom. - * - * @method Phaser.Physics#setBoundsToWorld - * @param {boolean} [left=true] - If true will create the left bounds wall. - * @param {boolean} [right=true] - If true will create the right bounds wall. - * @param {boolean} [top=true] - If true will create the top bounds wall. - * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. - * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group. - */ - setBoundsToWorld: function (left, right, top, bottom, setCollisionGroup) { - - this.setBounds(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, left, right, top, bottom, setCollisionGroup); - - }, - - /** - * Sets the given material against the 4 bounds of this World. - * - * @method Phaser.Physics#setWorldMaterial - * @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. - * @param {boolean} [bottom=true] - If true will set the material on the bottom bounds wall. - */ - setWorldMaterial: function (material, left, right, top, bottom) { - - if (typeof left === 'undefined') { left = true; } - if (typeof right === 'undefined') { right = true; } - if (typeof top === 'undefined') { top = true; } - if (typeof bottom === 'undefined') { bottom = true; } - - if (left && this._wallShapes[0]) - { - this._wallShapes[0].material = material; - } - - if (right && this._wallShapes[1]) - { - this._wallShapes[1].material = material; - } - - if (top && this._wallShapes[2]) - { - this._wallShapes[2].material = material; - } - - if (bottom && this._wallShapes[3]) - { - this._wallShapes[3].material = material; - } - - }, - - /** - * 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.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. - * @param {number} height - The height of the bounds. - * @param {boolean} [left=true] - If true will create the left bounds wall. - * @param {boolean} [right=true] - If true will create the right bounds wall. - * @param {boolean} [top=true] - If true will create the top bounds wall. - * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. - * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group. - */ - setBounds: function (x, y, width, height, left, right, top, bottom, setCollisionGroup) { - - if (typeof left === 'undefined') { left = true; } - if (typeof right === 'undefined') { right = true; } - if (typeof top === 'undefined') { top = true; } - if (typeof bottom === 'undefined') { bottom = true; } - if (typeof setCollisionGroup === 'undefined') { setCollisionGroup = true; } - - var hw = (width / 2); - var hh = (height / 2); - var cx = hw + x; - var cy = hh + y; - - if (this.bounds !== null) - { - if (this.bounds.world) - { - this.world.removeBody(this.bounds); - } - - var i = this.bounds.shapes.length; - - while (i--) - { - var shape = this.bounds.shapes[i]; - this.bounds.removeShape(shape); - } - - this.bounds.position[0] = this.game.math.px2pi(cx); - this.bounds.position[1] = this.game.math.px2pi(cy); - } - else - { - this.bounds = new p2.Body({ mass: 0, position:[this.game.math.px2pi(cx), this.game.math.px2pi(cy)] }); - } - - if (left) - { - this._wallShapes[0] = new p2.Plane(); - - if (setCollisionGroup) - { - this._wallShapes[0].collisionGroup = this.boundsCollisionGroup.mask; - // this._wallShapes[0].collisionGroup = this.everythingCollisionGroup.mask; - // this._wallShapes[0].collisionMask = this.everythingCollisionGroup.mask; - } - - this.bounds.addShape(this._wallShapes[0], [this.game.math.px2pi(-hw), 0], 1.5707963267948966 ); - } - - if (right) - { - this._wallShapes[1] = new p2.Plane(); - - if (setCollisionGroup) - { - this._wallShapes[1].collisionGroup = this.boundsCollisionGroup.mask; - // this._wallShapes[1].collisionGroup = this.everythingCollisionGroup.mask; - // this._wallShapes[1].collisionMask = this.everythingCollisionGroup.mask; - } - - this.bounds.addShape(this._wallShapes[1], [this.game.math.px2pi(hw), 0], -1.5707963267948966 ); - } - - if (top) - { - this._wallShapes[2] = new p2.Plane(); - - if (setCollisionGroup) - { - this._wallShapes[2].collisionGroup = this.boundsCollisionGroup.mask; - // this._wallShapes[2].collisionGroup = this.everythingCollisionGroup.mask; - // this._wallShapes[2].collisionMask = this.everythingCollisionGroup.mask; - } - - this.bounds.addShape(this._wallShapes[2], [0, this.game.math.px2pi(-hh)], -3.141592653589793 ); - } - - if (bottom) - { - this._wallShapes[3] = new p2.Plane(); - - if (setCollisionGroup) - { - this._wallShapes[3].collisionGroup = this.boundsCollisionGroup.mask; - // this._wallShapes[3].collisionGroup = this.everythingCollisionGroup.mask; - // this._wallShapes[3].collisionMask = this.everythingCollisionGroup.mask; - } - - this.bounds.addShape(this._wallShapes[3], [0, this.game.math.px2pi(hh)] ); - } - - this.world.addBody(this.bounds); - - }, - - /** - * @method Phaser.Physics.P2#update - */ - update: function () { - - this.world.step(1 / 60); - - }, - - /** - * Clears all bodies from the simulation. - * - * @method Phaser.Physics.P2#clear - */ - clear: function () { - - this.world.clear(); - - }, - - /** - * 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.P2#destroy - */ - destroy: function () { - - this.world.clear(); - - this.game = null; - - }, - - /** - * Add a body 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) { - - if (body.data.world) - { - return false; - } - else - { - this.world.addBody(body.data); - - this.onBodyAdded.dispatch(body); - - return true; - } - - }, - - /** - * Removes a body from the world. - * - * @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) { - - this.world.removeBody(body.data); - - this.onBodyRemoved.dispatch(body); - - return body; - - }, - - /** - * Adds a Spring to the world. - * - * @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) { - - this.world.addSpring(spring); - - this.onSpringAdded.dispatch(spring); - - return spring; - - }, - - /** - * Removes a Spring from the world. - * - * @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) { - - this.world.removeSpring(spring); - - this.onSpringRemoved.dispatch(spring); - - return spring; - - }, - - /** - * Adds a Constraint to the world. - * - * @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) { - - this.world.addConstraint(constraint); - - this.onConstraintAdded.dispatch(constraint); - - return constraint; - - }, - - /** - * Removes a Constraint from the world. - * - * @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) { - - this.world.removeConstraint(constraint); - - this.onConstraintRemoved.dispatch(constraint); - - return constraint; - - }, - - /** - * Adds a Contact Material to the world. - * - * @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) { - - this.world.addContactMaterial(material); - - this.onContactMaterialAdded.dispatch(material); - - return material; - - }, - - /** - * Removes a Contact Material from the world. - * - * @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) { - - this.world.removeContactMaterial(material); - - this.onContactMaterialRemoved.dispatch(material); - - return material; - - }, - - /** - * Gets a Contact Material based on the two given Materials. - * - * @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) { - - return this.world.getContactMaterial(materialA, materialB); - - }, - - /** - * Sets the given Material against all Shapes owned by all the Bodies in the given array. - * - * @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) { - - var i = bodies.length; - - while (i--) - { - bodies.setMaterial(material); - } - - }, - - /** - * Creates a Material. Materials are applied to Shapes owned by a Body and can be set with Body.setMaterial(). - * 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.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.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.P2.Material(name); - - this.materials.push(material); - - if (typeof body !== 'undefined') - { - body.setMaterial(material); - } - - return material; - - }, - - /** - * Creates a Contact Material from the two given Materials. You can then edit the properties of the Contact Material directly. - * - * @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.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.P2.ContactMaterial(materialA, materialB, options); - - return this.addContactMaterial(contact); - - }, - - /** - * Populates and returns an array of all current Bodies in the world. - * - * @method Phaser.Physics.P2#getBodies - * @return {array} An array containing all current Bodies in the world. - */ - getBodies: function () { - - var output = []; - var i = this.world.bodies.length; - - while (i--) - { - output.push(this.world.bodies[i].parent); - } - - return output; - - }, - - /** - * Populates and returns an array of all current Springs in the world. - * - * @method Phaser.Physics.P2#getSprings - * @return {array} An array containing all current Springs in the world. - */ - getSprings: function () { - - var output = []; - var i = this.world.springs.length; - - while (i--) - { - output.push(this.world.springs[i]); - } - - return output; - - }, - - /** - * Populates and returns an array of all current Constraints in the world. - * - * @method Phaser.Physics.P2#getConstraints - * @return {array} An array containing all current Constraints in the world. - */ - getConstraints: function () { - - var output = []; - var i = this.world.constraints.length; - - while (i--) - { - output.push(this.world.springs[i]); - } - - return output; - - }, - - /** - * Test if a world point overlaps bodies. - * - * @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. - * @return {Array} Array of bodies that overlap the point. - */ - hitTest: function (worldPoint, bodies, precision) { - - }, - - /** - * Converts the current world into a JSON object. - * - * @method Phaser.Physics.P2#toJSON - * @return {object} A JSON representation of the world. - */ - toJSON: function () { - - this.world.toJSON(); - - }, - - createCollisionGroup: function () { - - var bitmask = Math.pow(2, this._collisionGroupID); - - if (this._wallShapes[0]) - { - this._wallShapes[0].collisionMask = this._wallShapes[0].collisionMask | bitmask; - } - - if (this._wallShapes[1]) - { - this._wallShapes[1].collisionMask = this._wallShapes[1].collisionMask | bitmask; - } - - if (this._wallShapes[2]) - { - this._wallShapes[2].collisionMask = this._wallShapes[2].collisionMask | bitmask; - } - - if (this._wallShapes[3]) - { - this._wallShapes[3].collisionMask = this._wallShapes[3].collisionMask | bitmask; - } - - this._collisionGroupID++; - - var group = new Phaser.Physics.P2.CollisionGroup(bitmask); - - this.collisionGroups.push(group); - - return group; - - }, - - /** - * @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. - * @param {boolean} [addToWorld=false] - Automatically add this Body to the world? (usually false as it won't have any shapes on construction). - * @param {object} options - An object containing the build options: - * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. - * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. - * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. - * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon. - * Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...], - * or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers. - */ - createBody: function (x, y, mass, addToWorld, options, data) { - - if (typeof addToWorld === 'undefined') { addToWorld = false; } - - var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass); - - if (data) - { - var result = body.addPolygon(options, data); - - if (!result) - { - return false; - } - } - - if (addToWorld) - { - this.world.addBody(body.data); - } - - return body; - - }, - - /** - * @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. - * @param {boolean} [addToWorld=false] - Automatically add this Body to the world? (usually false as it won't have any shapes on construction). - * @param {object} options - An object containing the build options: - * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. - * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. - * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. - * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon. - * Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...], - * or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers. - */ - createParticle: function (x, y, mass, addToWorld, options, data) { - - if (typeof addToWorld === 'undefined') { addToWorld = false; } - - var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass); - - if (data) - { - var result = body.addPolygon(options, data); - - if (!result) - { - return false; - } - } - - if (addToWorld) - { - this.world.addBody(body.data); - } - - return body; - - }, - - - -}; - -/** -* @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.P2.prototype, "friction", { - - get: function () { - - return this.world.defaultFriction; - - }, - - set: function (value) { - - this.world.defaultFriction = value; - - } - -}); - -/** -* @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.P2.prototype, "restituion", { - - get: function () { - - return this.world.defaultRestitution; - - }, - - set: function (value) { - - this.world.defaultRestitution = value; - - } - -}); - -/** -* @name Phaser.Physics.P2#applySpringForces -* @property {boolean} applySpringForces - Enable to automatically apply spring forces each step. -*/ -Object.defineProperty(Phaser.Physics.P2.prototype, "applySpringForces", { - - get: function () { - - return this.world.applySpringForces; - - }, - - set: function (value) { - - this.world.applySpringForces = value; - - } - -}); - -/** -* @name Phaser.Physics.P2#applyDamping -* @property {boolean} applyDamping - Enable to automatically apply body damping each step. -*/ -Object.defineProperty(Phaser.Physics.P2.prototype, "applyDamping", { - - get: function () { - - return this.world.applyDamping; - - }, - - set: function (value) { - - this.world.applyDamping = value; - - } - -}); - -/** -* @name Phaser.Physics.P2#applyGravity -* @property {boolean} applyGravity - Enable to automatically apply gravity each step. -*/ -Object.defineProperty(Phaser.Physics.P2.prototype, "applyGravity", { - - get: function () { - - return this.world.applyGravity; - - }, - - set: function (value) { - - this.world.applyGravity = value; - - } - -}); - -/** -* @name Phaser.Physics.P2#solveConstraints -* @property {boolean} solveConstraints - Enable/disable constraint solving in each step. -*/ -Object.defineProperty(Phaser.Physics.P2.prototype, "solveConstraints", { - - get: function () { - - return this.world.solveConstraints; - - }, - - set: function (value) { - - this.world.solveConstraints = value; - - } - -}); - -/** -* @name Phaser.Physics.P2#time -* @property {boolean} time - The World time. -* @readonly -*/ -Object.defineProperty(Phaser.Physics.P2.prototype, "time", { - - get: function () { - - return this.world.time; - - } - -}); - -/** -* @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.P2.prototype, "emitImpactEvent", { - - get: function () { - - return this.world.emitImpactEvent; - - }, - - set: function (value) { - - this.world.emitImpactEvent = value; - - } - -}); - -/** -* @name Phaser.Physics.P2#enableBodySleeping -* @property {boolean} enableBodySleeping - Enable / disable automatic body sleeping. -*/ -Object.defineProperty(Phaser.Physics.P2.prototype, "enableBodySleeping", { - - get: function () { - - return this.world.enableBodySleeping; - - }, - - set: function (value) { - - this.world.enableBodySleeping = value; - - } - -}); - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* A PointProxy is an internal class that allows for direct getter/setter style property access to Arrays and TypedArrays. -* -* @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.P2.PointProxy = function (game, destination) { - - this.game = game; - this.destination = destination; - -}; - -Phaser.Physics.P2.PointProxy.prototype.constructor = Phaser.Physics.P2.PointProxy; - -/** -* @name Phaser.Physics.P2.PointProxy#x -* @property {number} x - The x property of this PointProxy. -*/ -Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "x", { - - get: function () { - - return this.destination[0]; - - }, - - set: function (value) { - - this.destination[0] = this.game.math.px2p(value); - - } - -}); - -/** -* @name Phaser.Physics.P2.PointProxy#y -* @property {number} y - The y property of this PointProxy. -*/ -Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "y", { - - get: function () { - - return this.destination[1]; - - }, - - set: function (value) { - - this.destination[1] = this.game.math.px2p(value); - - } - -}); - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* 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.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.P2.InversePointProxy = function (game, destination) { - - this.game = game; - this.destination = destination; - -}; - -Phaser.Physics.P2.InversePointProxy.prototype.constructor = Phaser.Physics.P2.InversePointProxy; - -/** -* @name Phaser.Physics.P2.InversePointProxy#x -* @property {number} x - The x property of this InversePointProxy. -*/ -Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "x", { - - get: function () { - - return this.destination[0]; - - }, - - set: function (value) { - - this.destination[0] = this.game.math.px2p(-value); - - } - -}); - -/** -* @name Phaser.Physics.P2.InversePointProxy#y -* @property {number} y - The y property of this InversePointProxy. -*/ -Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "y", { - - get: function () { - - return this.destination[1]; - - }, - - set: function (value) { - - this.destination[1] = this.game.math.px2p(-value); - - } - -}); - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* The Physics Body is typically linked to a single Sprite and defines properties that determine how the physics body is simulated. -* These properties affect how the body reacts to forces, what forces it generates on itself (to simulate friction), and how it reacts to collisions in the scene. -* In most cases, the properties are used to simulate physical effects. Each body also has its own property values that determine exactly how it reacts to forces and collisions in the scene. -* By default a single Rectangle shape is added to the Body that matches the dimensions of the parent Sprite. See addShape, removeShape, clearShapes to add extra shapes around the Body. -* Note: When bound to a Sprite to avoid single-pixel jitters on mobile devices we strongly recommend using Sprite sizes that are even on both axis, i.e. 128x128 not 127x127. -* -* @class Phaser.Physics.Body -* @classdesc Physics Body Constructor -* @constructor -* @param {Phaser.Game} game - Game reference to the currently running game. -* @param {Phaser.Sprite} [sprite] - The Sprite object this physics body belongs to. -* @param {number} [x=0] - The x coordinate of this Body. -* @param {number} [y=0] - The y coordinate of this Body. -* @param {number} [mass=1] - The default mass of this Body (0 = static). -*/ -Phaser.Physics.Body = function (game, sprite, x, y, mass) { - - sprite = sprite || null; - x = x || 0; - y = y || 0; - if (typeof mass === 'undefined') { mass = 1; } - - /** - * @property {Phaser.Game} game - Local reference to game. - */ - this.game = game; - - /** - * @property {Phaser.Sprite} sprite - Reference to the parent Sprite. - */ - this.sprite = sprite; - - /** - * @property {number} type - The type of physics system this body belongs to. - */ - this.type = Phaser.Physics.P2; - - /** - * @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position. - */ - this.offset = new Phaser.Point(); - - /** - * @property {p2.Body} data - The p2 Body data. - * @protected - */ - this.data = new p2.Body({ position:[this.px2pi(x), this.px2pi(y)], mass: mass }); - this.data.parent = this; - - /** - * @property {Phaser.InversePointProxy} velocity - The velocity of the body. Set velocity.x to a negative value to move to the left, position to the right. velocity.y negative values move up, positive move down. - */ - this.velocity = new Phaser.Physics.InversePointProxy(this.game, this.data.velocity); - - /** - * @property {Phaser.InversePointProxy} force - The force applied to the body. - */ - this.force = new Phaser.Physics.InversePointProxy(this.game, this.data.force); - - /** - * @property {Phaser.Point} gravity - A locally applied gravity force to the Body. Applied directly before the world step. NOTE: Not currently implemented. - */ - this.gravity = new Phaser.Point(); - - /** - * A Body can be set to collide against the World bounds automatically if this is set to true. Otherwise it will leave the World. - * Note that this only applies if your World has bounds! The response to the collision should be managed via CollisionMaterials. - * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds? - */ - this.collideWorldBounds = true; - - /** - * @property {Phaser.Signal} onImpact - Dispatched when the shape/s of this Body impact with another. The event will be sent 2 parameters, this Body and the impact Body. - */ - this.onImpact = new Phaser.Signal(); - - /** - * @property {array} collidesWith - Array of CollisionGroups that this Bodies shapes collide with. - * @private - */ - this.collidesWith = []; - - /** - * @property {array} _bodyCallbacks - Array of Body callbacks. - * @private - */ - this._bodyCallbacks = []; - - /** - * @property {array} _bodyCallbackContext - Array of Body callback contexts. - * @private - */ - this._bodyCallbackContext = []; - - /** - * @property {array} _groupCallbacks - Array of Group callbacks. - * @private - */ - this._groupCallbacks = []; - - /** - * @property {array} _bodyCallbackContext - Array of Grouo callback contexts. - * @private - */ - this._groupCallbackContext = []; - - // Set-up the default shape - if (sprite) - { - this.setRectangleFromSprite(sprite); - - this.game.physics.addBody(this); - } - -}; - -Phaser.Physics.Body.prototype = { - - /** - * Sets a callback to be fired any time this Body impacts with the given Body. The impact test is performed against body.id values. - * The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body. - * - * @method Phaser.Physics.Body#createBodyCallback - * @param {Phaser.Physics.Body} body - The Body to send impact events for. - * @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback. - * @param {object} callbackContext - The context under which the callback will fire. - */ - createBodyCallback: function (body, callback, callbackContext) { - - this._bodyCallbacks[body.data.id] = callback; - this._bodyCallbackContext[body.data.id] = callbackContext; - - }, - - /** - * Sets a callback to be fired any time this Body impacts with the given Group. The impact test is performed against shape.collisionGroup values. - * The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body. - * This callback will only fire if this Body has been assigned a collision group. - * - * @method Phaser.Physics.Body#createGroupCallback - * @param {Phaser.Physics.CollisionGroup} group - The Group to send impact events for. - * @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback. - * @param {object} callbackContext - The context under which the callback will fire. - */ - createGroupCallback: function (group, callback, callbackContext) { - - this._groupCallbacks[group.mask] = callback; - this._groupCallbackContext[group.mask] = callbackContext; - - }, - - /** - * Gets the collision bitmask from the groups this body collides with. - * - * @method Phaser.Physics.Body#getCollisionMask - * @return {number} The bitmask. - */ - getCollisionMask: function () { - - var mask = 0; - - if (this.collideWorldBounds) - { - mask = this.game.physics.boundsCollisionGroup.mask; - } - - for (var i = 0; i < this.collidesWith.length; i++) - { - mask = mask | this.collidesWith[i].mask; - } - - return mask; - - }, - - /** - * Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified. - * This also resets the collisionMask. - * - * @method Phaser.Physics.Body#setCollisionGroup - * @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group that this Bodies shapes will use. - * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision group will be added to all Shapes in this Body. - */ - setCollisionGroup: function (group, shape) { - - var mask = this.getCollisionMask(); - - if (typeof shape === 'undefined') - { - for (var i = this.data.shapes.length - 1; i >= 0; i--) - { - this.data.shapes[i].collisionGroup = group.mask; - this.data.shapes[i].collisionMask = mask; - } - } - else - { - shape.collisionGroup = group.mask; - shapes.collisionMask = mask; - } - - }, - - /** - * Clears the collision data from the shapes in this Body. Optionally clears Group and/or Mask. - * - * @method Phaser.Physics.Body#clearCollision - * @param {boolean} [clearGroup=true] - Clear the collisionGroup value from the shape/s? - * @param {boolean} [clearMask=true] - Clear the collisionMask value from the shape/s? - * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision data will be cleared from all Shapes in this Body. - */ - clearCollision: function (clearGroup, clearMask, shape) { - - if (typeof shape === 'undefined') - { - for (var i = this.data.shapes.length - 1; i >= 0; i--) - { - if (clearGroup) - { - this.data.shapes[i].collisionGroup = null; - } - - if (clearMask) - { - this.data.shapes[i].collisionMask = null; - } - } - } - else - { - if (clearGroup) - { - shapes.collisionGroup = null; - } - - if (clearMask) - { - shapes.collisionMask = null; - } - } - - if (clearGroup) - { - this.collidesWith.length = 0; - } - - }, - - /** - * Adds the given CollisionGroup, or array of CollisionGroups, to the list of groups that this body will collide with and updates the collision masks. - * - * @method Phaser.Physics.Body#collides - * @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group or Array of Collision Groups that this Bodies shapes will collide with. - * @param {function} [callback] - Optional callback that will be triggered when this Body impacts with the given Group. - * @param {object} [callbackContext] - The context under which the callback will be called. - * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision mask will be added to all Shapes in this Body. - */ - collides: function (group, callback, callbackContext, shape) { - - if (Array.isArray(group)) - { - for (var i = 0; i < group.length; i++) - { - if (this.collidesWith.indexOf(group[i]) === -1) - { - this.collidesWith.push(group[i]); - - if (callback) - { - this.createGroupCallback(group[i], callback, callbackContext); - } - } - } - } - else - { - if (this.collidesWith.indexOf(group) === -1) - { - this.collidesWith.push(group); - - if (callback) - { - this.createGroupCallback(group, callback, callbackContext); - } - } - } - - var mask = this.getCollisionMask(); - - if (typeof shape === 'undefined') - { - for (var i = this.data.shapes.length - 1; i >= 0; i--) - { - this.data.shapes[i].collisionMask = mask; - } - } - else - { - shape.collisionMask = mask; - } - - }, - - /** - * Moves the shape offsets so their center of mass becomes the body center of mass. - * - * @method Phaser.Physics.Body#adjustCenterOfMass - */ - adjustCenterOfMass: function () { - - this.data.adjustCenterOfMass(); - - }, - - /** - * Apply damping, see http://code.google.com/p/bullet/issues/detail?id=74 for details. - * - * @method Phaser.Physics.Body#applyDamping - * @param {number} dt - Current time step. - */ - applyDamping: function (dt) { - - this.data.applyDamping(dt); - - }, - - /** - * Apply force to a world point. This could for example be a point on the RigidBody surface. Applying force this way will add to Body.force and Body.angularForce. - * - * @method Phaser.Physics.Body#applyForce - * @param {number} force - The force to add. - * @param {number} worldX - The world x point to apply the force on. - * @param {number} worldY - The world y point to apply the force on. - */ - applyForce: function (force, worldX, worldY) { - - this.data.applyForce(force, [this.px2p(worldX), this.px2p(worldY)]); - - }, - - /** - * Sets the force on the body to zero. - * - * @method Phaser.Physics.Body#setZeroForce - */ - setZeroForce: function () { - - this.data.setZeroForce(); - - }, - - /** - * If this Body is dynamic then this will zero its angular velocity. - * - * @method Phaser.Physics.Body#setZeroRotation - */ - setZeroRotation: function () { - - this.data.angularVelocity = 0; - - }, - - /** - * If this Body is dynamic then this will zero its velocity on both axis. - * - * @method Phaser.Physics.Body#setZeroVelocity - */ - setZeroVelocity: function () { - - this.data.velocity[0] = 0; - this.data.velocity[1] = 0; - - }, - - /** - * Sets the Body damping and angularDamping to zero. - * - * @method Phaser.Physics.Body#setZeroDamping - */ - setZeroDamping: function () { - - this.data.damping = 0; - this.data.angularDamping = 0; - - }, - - /** - * Transform a world point to local body frame. - * - * @method Phaser.Physics.Body#toLocalFrame - * @param {Float32Array|Array} out - The vector to store the result in. - * @param {Float32Array|Array} worldPoint - The input world vector. - */ - toLocalFrame: function (out, worldPoint) { - - return this.data.toLocalFrame(out, worldPoint); - - }, - - /** - * Transform a local point to world frame. - * - * @method Phaser.Physics.Body#toWorldFrame - * @param {Array} out - The vector to store the result in. - * @param {Array} localPoint - The input local vector. - */ - toWorldFrame: function (out, localPoint) { - - return this.data.toWorldFrame(out, localPoint); - - }, - - /** - * This will rotate the Body by the given speed to the left (counter-clockwise). - * - * @method Phaser.Physics.Body#rotateLeft - * @param {number} speed - The speed at which it should rotate. - */ - rotateLeft: function (speed) { - - this.data.angularVelocity = this.px2p(-speed); - - }, - - /** - * This will rotate the Body by the given speed to the left (clockwise). - * - * @method Phaser.Physics.Body#rotateRight - * @param {number} speed - The speed at which it should rotate. - */ - rotateRight: function (speed) { - - this.data.angularVelocity = this.px2p(speed); - - }, - - /** - * Moves the Body forwards based on its current angle and the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveForward - * @param {number} speed - The speed at which it should move forwards. - */ - moveForward: function (speed) { - - var magnitude = this.px2pi(-speed); - var angle = this.data.angle + Math.PI / 2; - - this.data.velocity[0] = magnitude * Math.cos(angle); - this.data.velocity[1] = magnitude * Math.sin(angle); - - }, - - /** - * Moves the Body backwards based on its current angle and the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveBackward - * @param {number} speed - The speed at which it should move backwards. - */ - moveBackward: function (speed) { - - var magnitude = this.px2pi(-speed); - var angle = this.data.angle + Math.PI / 2; - - this.data.velocity[0] = -(magnitude * Math.cos(angle)); - this.data.velocity[1] = -(magnitude * Math.sin(angle)); - - }, - - /** - * Applies a force to the Body that causes it to 'thrust' forwards, based on its current angle and the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#thrust - * @param {number} speed - The speed at which it should thrust. - */ - thrust: function (speed) { - - var magnitude = this.px2pi(-speed); - var angle = this.data.angle + Math.PI / 2; - - this.data.force[0] += magnitude * Math.cos(angle); - this.data.force[1] += magnitude * Math.sin(angle); - - }, - - /** - * Applies a force to the Body that causes it to 'thrust' backwards (in reverse), based on its current angle and the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#rever - * @param {number} speed - The speed at which it should reverse. - */ - reverse: function (speed) { - - var magnitude = this.px2pi(-speed); - var angle = this.data.angle + Math.PI / 2; - - this.data.force[0] -= magnitude * Math.cos(angle); - this.data.force[1] -= magnitude * Math.sin(angle); - - }, - - /** - * If this Body is dynamic then this will move it to the left by setting its x velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveLeft - * @param {number} speed - The speed at which it should move to the left, in pixels per second. - */ - moveLeft: function (speed) { - - this.data.velocity[0] = this.px2pi(-speed); - - }, - - /** - * If this Body is dynamic then this will move it to the right by setting its x velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveRight - * @param {number} speed - The speed at which it should move to the right, in pixels per second. - */ - moveRight: function (speed) { - - this.data.velocity[0] = this.px2pi(speed); - - }, - - /** - * If this Body is dynamic then this will move it up by setting its y velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveUp - * @param {number} speed - The speed at which it should move up, in pixels per second. - */ - moveUp: function (speed) { - - this.data.velocity[1] = this.px2pi(-speed); - - }, - - /** - * If this Body is dynamic then this will move it down by setting its y velocity to the given speed. - * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms). - * - * @method Phaser.Physics.Body#moveDown - * @param {number} speed - The speed at which it should move down, in pixels per second. - */ - moveDown: function (speed) { - - this.data.velocity[1] = this.px2pi(speed); - - }, - - /** - * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished. - * - * @method Phaser.Physics.Body#preUpdate - * @protected - */ - preUpdate: function () { - }, - - /** - * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished. - * - * @method Phaser.Physics.Body#postUpdate - * @protected - */ - postUpdate: function () { - - this.sprite.x = this.p2pxi(this.data.position[0]); - this.sprite.y = this.p2pxi(this.data.position[1]); - - if (!this.fixedRotation) - { - this.sprite.rotation = this.data.angle; - } - - }, - - /** - * Resets the Body force, velocity (linear and angular) and rotation. Optionally resets damping and mass. - * - * @method Phaser.Physics.Body#reset - * @param {number} x - The new x position of the Body. - * @param {number} y - The new x position of the Body. - * @param {boolean} [resetDamping=false] - Resets the linear and angular damping. - * @param {boolean} [resetMass=false] - Sets the Body mass back to 1. - */ - reset: function (x, y, resetDamping, resetMass) { - - if (typeof resetDamping === 'undefined') { resetDamping = false; } - if (typeof resetMass === 'undefined') { resetMass = false; } - - this.setZeroForce(); - this.setZeroVelocity(); - this.setZeroRotation(); - - if (resetDamping) - { - this.setZeroDamping(); - } - - if (resetMass) - { - this.mass = 1; - } - - this.x = x; - this.y = y; - - }, - - /** - * Adds this physics body to the world. - * - * @method Phaser.Physics.Body#addToWorld - */ - addToWorld: function () { - - if (this.data.world !== this.game.physics.world) - { - this.game.physics.addBody(this); - } - - }, - - /** - * Removes this physics body from the world. - * - * @method Phaser.Physics.Body#removeFromWorld - */ - removeFromWorld: function () { - - if (this.data.world === this.game.physics.world) - { - this.game.physics.removeBody(this); - } - - }, - - /** - * Destroys this Body and all references it holds to other objects. - * - * @method Phaser.Physics.Body#destroy - */ - destroy: function () { - - this.removeFromWorld(); - - this.clearShapes(); - - this.sprite = null; - - /* - this.collideCallback = null; - this.collideCallbackContext = null; - */ - - }, - - /** - * Removes all Shapes from this Body. - * - * @method Phaser.Physics.Body#clearShapes - */ - clearShapes: function () { - - for (var i = this.data.shapes.length - 1; i >= 0; i--) - { - var shape = this.data.shapes[i]; - this.data.removeShape(shape); - } - - }, - - /** - * Add a shape to the body. You can pass a local transform when adding a shape, so that the shape gets an offset and an angle relative to the body center of mass. - * Will automatically update the mass properties and bounding radius. - * - * @method Phaser.Physics.Body#addShape - * @param {*} shape - The shape to add to the body. - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Circle|p2.Rectangle|p2.Plane|p2.Line|p2.Particle} The shape that was added to the body. - */ - addShape: function (shape, offsetX, offsetY, rotation) { - - if (typeof offsetX === 'undefined') { offsetX = 0; } - if (typeof offsetY === 'undefined') { offsetY = 0; } - if (typeof rotation === 'undefined') { rotation = 0; } - - this.data.addShape(shape, [this.px2pi(offsetX), this.px2pi(offsetY)], rotation); - - return shape; - - }, - - /** - * Adds a Circle shape to this Body. You can control the offset from the center of the body and the rotation. - * - * @method Phaser.Physics.Body#addCircle - * @param {number} radius - The radius of this circle (in pixels) - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Circle} The Circle shape that was added to the Body. - */ - addCircle: function (radius, offsetX, offsetY, rotation) { - - var shape = new p2.Circle(this.px2p(radius)); - - return this.addShape(shape, offsetX, offsetY, rotation); - - }, - - /** - * Adds a Rectangle shape to this Body. You can control the offset from the center of the body and the rotation. - * - * @method Phaser.Physics.Body#addRectangle - * @param {number} width - The width of the rectangle in pixels. - * @param {number} height - The height of the rectangle in pixels. - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Rectangle} The Rectangle shape that was added to the Body. - */ - addRectangle: function (width, height, offsetX, offsetY, rotation) { - - var shape = new p2.Rectangle(this.px2p(width), this.px2p(height)); - - return this.addShape(shape, offsetX, offsetY, rotation); - - }, - - /** - * Adds a Plane shape to this Body. The plane is facing in the Y direction. You can control the offset from the center of the body and the rotation. - * - * @method Phaser.Physics.Body#addPlane - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Plane} The Plane shape that was added to the Body. - */ - addPlane: function (offsetX, offsetY, rotation) { - - var shape = new p2.Plane(); - - return this.addShape(shape, offsetX, offsetY, rotation); - - }, - - /** - * Adds a Particle shape to this Body. You can control the offset from the center of the body and the rotation. - * - * @method Phaser.Physics.Body#addParticle - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Particle} The Particle shape that was added to the Body. - */ - addParticle: function (offsetX, offsetY, rotation) { - - var shape = new p2.Particle(); - - return this.addShape(shape, offsetX, offsetY, rotation); - - }, - - /** - * Adds a Line shape to this Body. - * The line shape is along the x direction, and stretches from [-length/2, 0] to [length/2,0]. - * You can control the offset from the center of the body and the rotation. - * - * @method Phaser.Physics.Body#addLine - * @param {number} length - The length of this line (in pixels) - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Line} The Line shape that was added to the Body. - */ - addLine: function (length, offsetX, offsetY, rotation) { - - var shape = new p2.Line(this.px2p(length)); - - return this.addShape(shape, offsetX, offsetY, rotation); - - }, - - /** - * Adds a Capsule shape to this Body. - * You can control the offset from the center of the body and the rotation. - * - * @method Phaser.Physics.Body#addCapsule - * @param {number} length - The distance between the end points in pixels. - * @param {number} radius - Radius of the capsule in radians. - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Capsule} The Capsule shape that was added to the Body. - */ - addCapsule: function (length, radius, offsetX, offsetY, rotation) { - - var shape = new p2.Capsule(this.px2p(length), radius); - - return this.addShape(shape, offsetX, offsetY, rotation); - - }, - - /** - * Reads a polygon shape path, and assembles convex shapes from that and puts them at proper offset points. The shape must be simple and without holes. - * This function expects the x.y values to be given in pixels. If you want to provide them at p2 world scales then call Body.data.fromPolygon directly. - * - * @method Phaser.Physics.Body#addPolygon - * @param {object} options - An object containing the build options: - * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. - * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. - * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. - * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon. - * Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...], - * or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers. - * @return {boolean} True on success, else false. - */ - addPolygon: function (options, points) { - - options = options || {}; - - points = Array.prototype.slice.call(arguments, 1); - - var path = []; - - // Did they pass in a single array of points? - if (points.length === 1 && Array.isArray(points[0])) - { - path = points[0].slice(0); - } - else if (Array.isArray(points[0])) - { - path = points[0].slice(0); - // for (var i = 0, len = points[0].length; i < len; i += 2) - // { - // path.push([points[0][i], points[0][i + 1]]); - // } - } - else if (typeof points[0] === 'number') - { - // console.log('addPolygon --- We\'ve a list of numbers'); - // We've a list of numbers - for (var i = 0, len = points.length; i < len; i += 2) - { - path.push([points[i], points[i + 1]]); - } - } - - // console.log('addPolygon PATH pre'); - // console.log(path[1]); - // console.table(path); - - // top and tail - var idx = path.length - 1; - - if ( path[idx][0] === path[0][0] && path[idx][1] === path[0][1] ) - { - path.pop(); - } - - // Now process them into p2 values - for (var p = 0; p < path.length; p++) - { - path[p][0] = this.px2pi(path[p][0]); - path[p][1] = this.px2pi(path[p][1]); - } - - // console.log('addPolygon PATH POST'); - // console.log(path[1]); - // console.table(path); - - return this.data.fromPolygon(path, options); - - }, - - /** - * Remove a shape from the body. Will automatically update the mass properties and bounding radius. - * - * @method Phaser.Physics.Body#removeShape - * @param {p2.Circle|p2.Rectangle|p2.Plane|p2.Line|p2.Particle} shape - The shape to remove from the body. - * @return {boolean} True if the shape was found and removed, else false. - */ - removeShape: function (shape) { - - return this.data.removeShape(shape); - - }, - - /** - * Clears any previously set shapes. Then creates a new Circle shape and adds it to this Body. - * - * @method Phaser.Physics.Body#setCircle - * @param {number} radius - The radius of this circle (in pixels) - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - */ - setCircle: function (radius, offsetX, offsetY, rotation) { - - this.clearShapes(); - - this.addCircle(radius, offsetX, offsetY, rotation); - - }, - - /** - * Clears any previously set shapes. The creates a new Rectangle shape at the given size and offset, and adds it to this Body. - * If you wish to create a Rectangle to match the size of a Sprite or Image see Body.setRectangleFromSprite. - * - * @method Phaser.Physics.Body#setRectangle - * @param {number} [width=16] - The width of the rectangle in pixels. - * @param {number} [height=16] - The height of the rectangle in pixels. - * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass. - * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass. - * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians. - * @return {p2.Rectangle} The Rectangle shape that was added to the Body. - */ - setRectangle: function (width, height, offsetX, offsetY, rotation) { - - if (typeof width === 'undefined') { width = 16; } - if (typeof height === 'undefined') { height = 16; } - - this.clearShapes(); - - return this.addRectangle(width, height, offsetX, offsetY, rotation); - - }, - - /** - * Clears any previously set shapes. - * Then creates a Rectangle shape sized to match the dimensions and orientation of the Sprite given. - * If no Sprite is given it defaults to using the parent of this Body. - * - * @method Phaser.Physics.Body#setRectangleFromSprite - * @param {Phaser.Sprite|Phaser.Image} [sprite] - The Sprite on which the Rectangle will get its dimensions. - * @return {p2.Rectangle} The Rectangle shape that was added to the Body. - */ - setRectangleFromSprite: function (sprite) { - - if (typeof sprite === 'undefined') { sprite = this.sprite; } - - this.clearShapes(); - - return this.addRectangle(sprite.width, sprite.height, 0, 0, sprite.rotation); - - }, - - /** - * Adds the given Material to all Shapes that belong to this Body. - * If you only wish to apply it to a specific Shape in this Body then provide that as the 2nd parameter. - * - * @method Phaser.Physics.Body#setMaterial - * @param {Phaser.Physics.Material} material - The Material that will be applied. - * @param {p2.Shape} [shape] - An optional Shape. If not provided the Material will be added to all Shapes in this Body. - */ - setMaterial: function (material, shape) { - - if (typeof shape === 'undefined') - { - for (var i = this.data.shapes.length - 1; i >= 0; i--) - { - this.data.shapes[i].material = material; - } - } - else - { - shape.material = material; - } - - }, - - /** - * Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body. - * - * @method Phaser.Physics.Body#loadPolygon - * @param {string} key - The key of the Physics Data file as stored in Game.Cache. - * @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from. - * @param {object} options - An object containing the build options. Note that this isn't used if the data file contains multiple shapes. - * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. - * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. - * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. - * @return {boolean} True on success, else false. - */ - loadPolygon: function (key, object, options) { - - var data = this.game.cache.getPhysicsData(key, object); - - if (data.length === 1) - { - var temp = []; - - data = data.pop() - // We've a list of numbers - for (var i = 0, len = data.shape.length; i < len; i += 2) - { - temp.push([data.shape[i], data.shape[i + 1]]); - } - - return this.addPolygon(options, temp); - } - else - { - // We've multiple Convex shapes, they should be CCW automatically - var cm = p2.vec2.create(); - - for (var i = 0; i < data.length; i++) - { - var vertices = []; - - for (var s = 0; s < data[i].shape.length; s += 2) - { - vertices.push([ this.px2pi(data[i].shape[s]), this.px2pi(data[i].shape[s + 1]) ]); - } - - var c = new p2.Convex(vertices); - - // Move all vertices so its center of mass is in the local center of the convex - for (var j = 0; j !== c.vertices.length; j++) - { - var v = c.vertices[j]; - p2.vec2.sub(v, v, c.centerOfMass); - } - - p2.vec2.scale(cm, c.centerOfMass, 1); - - cm[0] -= this.px2pi(this.sprite.width / 2); - cm[1] -= this.px2pi(this.sprite.height / 2); - - c.updateTriangles(); - c.updateCenterOfMass(); - c.updateBoundingRadius(); - - this.data.addShape(c, cm); - } - - // this.data.adjustCenterOfMass(); - this.data.aabbNeedsUpdate = true; - - return true; - } - - return false; - - }, - - /** - * Reads the physics data from a physics data file stored in the Game.Cache. - * It will add the shape data to this Body, as well as set the density (mass), friction and bounce (restitution) values. - * - * @method Phaser.Physics.Body#loadPolygon - * @param {string} key - The key of the Physics Data file as stored in Game.Cache. - * @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from. - * @param {object} options - An object containing the build options: - * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices. - * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself. - * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points. - * @return {boolean} True on success, else false. - */ - loadData: function (key, object, options) { - - var data = game.cache.getPhysicsData(key, object); - - if (data && data.shape) - { - this.mass = data.density; - // set friction + bounce here - this.loadPolygon(key, object); - } - - }, - - /** - * Convert p2 physics value (meters) to pixel scale. - * - * @method Phaser.Physics.Body#p2px - * @param {number} v - The value to convert. - * @return {number} The scaled value. - */ - p2px: function (v) { - - return v *= 20; - - }, - - /** - * Convert pixel value to p2 physics scale (meters). - * - * @method Phaser.Physics.Body#px2p - * @param {number} v - The value to convert. - * @return {number} The scaled value. - */ - px2p: function (v) { - - return v * 0.05; - - }, - - /** - * Convert p2 physics value (meters) to pixel scale and inverses it. - * - * @method Phaser.Physics.Body#p2pxi - * @param {number} v - The value to convert. - * @return {number} The scaled value. - */ - p2pxi: function (v) { - - return v *= -20; - - }, - - /** - * Convert pixel value to p2 physics scale (meters) and inverses it. - * - * @method Phaser.Physics.Body#px2pi - * @param {number} v - The value to convert. - * @return {number} The scaled value. - */ - px2pi: function (v) { - - return v * -0.05; - - } - -}; - -Phaser.Physics.Body.prototype.constructor = Phaser.Physics.Body; - -/** -* @name Phaser.Physics.Body#static -* @property {boolean} static - Returns true if the Body is static. Setting Body.static to 'false' will make it dynamic. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "static", { - - get: function () { - - return (this.data.motionState === Phaser.STATIC); - - }, - - set: function (value) { - - if (value && this.data.motionState !== Phaser.STATIC) - { - this.data.motionState = Phaser.STATIC; - this.mass = 0; - } - else if (!value && this.data.motionState === Phaser.STATIC) - { - this.data.motionState = Phaser.DYNAMIC; - - if (this.mass === 0) - { - this.mass = 1; - } - } - - } - -}); - -/** -* @name Phaser.Physics.Body#dynamic -* @property {boolean} dynamic - Returns true if the Body is dynamic. Setting Body.dynamic to 'false' will make it static. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "dynamic", { - - get: function () { - - return (this.data.motionState === Phaser.DYNAMIC); - - }, - - set: function (value) { - - if (value && this.data.motionState !== Phaser.DYNAMIC) - { - this.data.motionState = Phaser.DYNAMIC; - - if (this.mass === 0) - { - this.mass = 1; - } - } - else if (!value && this.data.motionState === Phaser.DYNAMIC) - { - this.data.motionState = Phaser.STATIC; - this.mass = 0; - } - - } - -}); - -/** -* @name Phaser.Physics.Body#kinematic -* @property {boolean} kinematic - Returns true if the Body is kinematic. Setting Body.kinematic to 'false' will make it static. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "kinematic", { - - get: function () { - - return (this.data.motionState === Phaser.KINEMATIC); - - }, - - set: function (value) { - - if (value && this.data.motionState !== Phaser.KINEMATIC) - { - this.data.motionState = Phaser.KINEMATIC; - this.mass = 4; - } - else if (!value && this.data.motionState === Phaser.KINEMATIC) - { - this.data.motionState = Phaser.STATIC; - this.mass = 0; - } - - } - -}); - -/** -* @name Phaser.Physics.Body#allowSleep -* @property {boolean} allowSleep - -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "allowSleep", { - - get: function () { - - return this.data.allowSleep; - - }, - - set: function (value) { - - if (value !== this.data.allowSleep) - { - this.data.allowSleep = value; - } - - } - -}); - -/** -* The angle of the Body 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 Body.angle = 450 is the same as Body.angle = 90. -* If you wish to work in radians instead of degrees use the property Body.rotation instead. Working in radians is faster as it doesn't have to convert values. -* -* @name Phaser.Physics.Body#angle -* @property {number} angle - The angle of this Body in degrees. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "angle", { - - get: function() { - - return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.data.angle)); - - }, - - set: function(value) { - - this.data.angle = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); - - } - -}); - -/** -* Damping is specified as a value between 0 and 1, which is the proportion of velocity lost per second. -* @name Phaser.Physics.Body#angularDamping -* @property {number} angularDamping - The angular damping acting acting on the body. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "angularDamping", { - - get: function () { - - return this.data.angularDamping; - - }, - - set: function (value) { - - this.data.angularDamping = value; - - } - -}); - -/** -* @name Phaser.Physics.Body#angularForce -* @property {number} angularForce - The angular force acting on the body. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "angularForce", { - - get: function () { - - return this.data.angularForce; - - }, - - set: function (value) { - - this.data.angularForce = value; - - } - -}); - -/** -* @name Phaser.Physics.Body#angularVelocity -* @property {number} angularVelocity - The angular velocity of the body. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "angularVelocity", { - - get: function () { - - return this.data.angularVelocity; - - }, - - set: function (value) { - - this.data.angularVelocity = value; - - } - -}); - -/** -* Damping is specified as a value between 0 and 1, which is the proportion of velocity lost per second. -* @name Phaser.Physics.Body#damping -* @property {number} damping - The linear damping acting on the body in the velocity direction. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "damping", { - - get: function () { - - return this.data.damping; - - }, - - set: function (value) { - - this.data.damping = value; - - } - -}); - -/** -* @name Phaser.Physics.Body#fixedRotation -* @property {boolean} fixedRotation - -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "fixedRotation", { - - get: function () { - - return this.data.fixedRotation; - - }, - - set: function (value) { - - if (value !== this.data.fixedRotation) - { - this.data.fixedRotation = value; - // update anything? - } - - } - -}); - -/** -* @name Phaser.Physics.Body#inertia -* @property {number} inertia - The inertia of the body around the Z axis.. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "inertia", { - - get: function () { - - return this.data.inertia; - - }, - - set: function (value) { - - this.data.inertia = value; - - } - -}); - -/** -* @name Phaser.Physics.Body#mass -* @property {number} mass - -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "mass", { - - get: function () { - - return this.data.mass; - - }, - - set: function (value) { - - if (value !== this.data.mass) - { - this.data.mass = value; - this.data.updateMassProperties(); - - if (value === 0) - { - // this.static = true; - } - } - - } - -}); - -/** -* @name Phaser.Physics.Body#motionState -* @property {number} motionState - The type of motion this body has. Should be one of: Body.STATIC (the body does not move), Body.DYNAMIC (body can move and respond to collisions) and Body.KINEMATIC (only moves according to its .velocity). -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "motionState", { - - get: function () { - - return this.data.motionState; - - }, - - set: function (value) { - - if (value !== this.data.motionState) - { - this.data.motionState = value; - // update? - } - - } - -}); - -/** -* The angle of the Body in radians. -* If you wish to work in degrees instead of radians use the Body.angle property instead. Working in radians is faster as it doesn't have to convert values. -* -* @name Phaser.Physics.Body#rotation -* @property {number} rotation - The angle of this Body in radians. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "rotation", { - - get: function() { - - return this.data.angle; - - }, - - set: function(value) { - - this.data.angle = value; - - } - -}); - -/** -* @name Phaser.Physics.Body#sleepSpeedLimit -* @property {number} sleepSpeedLimit - . -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "sleepSpeedLimit", { - - get: function () { - - return this.data.sleepSpeedLimit; - - }, - - set: function (value) { - - this.data.sleepSpeedLimit = value; - - } - -}); - -/** -* @name Phaser.Physics.Body#x -* @property {number} x - The x coordinate of this Body. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "x", { - - get: function () { - - return this.p2pxi(this.data.position[0]); - - }, - - set: function (value) { - - this.data.position[0] = this.px2pi(value); - - } - -}); - -/** -* @name Phaser.Physics.Body#y -* @property {number} y - The y coordinate of this Body. -*/ -Object.defineProperty(Phaser.Physics.Body.prototype, "y", { - - get: function () { - - return this.p2pxi(this.data.position[1]); - - }, - - set: function (value) { - - this.data.position[1] = this.px2pi(value); - - } - -}); - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Creates a spring, connecting two bodies. -* -* @class Phaser.Physics.P2.Spring -* @classdesc Physics Spring Constructor -* @constructor -* @param {Phaser.Game} game - A reference to the current game. -* @param {p2.Body} bodyA - First connected body. -* @param {p2.Body} bodyB - Second connected body. -* @param {number} [restLength=1] - Rest length of the spring. A number > 0. -* @param {number} [stiffness=100] - Stiffness of the spring. A number >= 0. -* @param {number} [damping=1] - Damping of the spring. A number >= 0. -* @param {Array} [worldA] - Where to hook the spring to body A, in world coordinates, i.e. [32, 32]. -* @param {Array} [worldB] - Where to hook the spring to body B, in world coordinates, i.e. [32, 32]. -* @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.P2.Spring = function (game, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB) { - - /** - * @property {Phaser.Game} game - Local reference to game. - */ - this.game = game; - - if (typeof restLength === 'undefined') { restLength = 1; } - if (typeof stiffness === 'undefined') { stiffness = 100; } - if (typeof damping === 'undefined') { damping = 1; } - - var options = { - restLength: restLength, - stiffness: stiffness, - damping: damping - }; - - if (typeof worldA !== 'undefined' && worldA !== null) - { - options.worldAnchorA = [ game.math.px2p(worldA[0]), game.math.px2p(worldA[1]) ]; - } - - if (typeof worldB !== 'undefined' && worldB !== null) - { - options.worldAnchorB = [ game.math.px2p(worldB[0]), game.math.px2p(worldB[1]) ]; - } - - if (typeof localA !== 'undefined' && localA !== null) - { - options.localAnchorA = [ game.math.px2p(localA[0]), game.math.px2p(localA[1]) ]; - } - - if (typeof localB !== 'undefined' && localB !== null) - { - options.localAnchorB = [ game.math.px2p(localB[0]), game.math.px2p(localB[1]) ]; - } - - p2.Spring.call(this, bodyA, bodyB, options); - -} - -Phaser.Physics.P2.Spring.prototype = Object.create(p2.Spring.prototype); -Phaser.Physics.P2.Spring.prototype.constructor = Phaser.Physics.P2.Spring; - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* \o/ ~ "Because I'm a Material girl" -* -* @class Phaser.Physics.P2.Material -* @classdesc Physics Material Constructor -* @constructor -*/ -Phaser.Physics.P2.Material = function (name) { - - /** - * @property {string} name - The user defined name given to this Material. - * @default - */ - this.name = name; - - p2.Material.call(this); - -} - -Phaser.Physics.P2.Material.prototype = Object.create(p2.Material.prototype); -Phaser.Physics.P2.Material.prototype.constructor = Phaser.Physics.P2.Material; - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Defines a physics material -* -* @class Phaser.Physics.P2.ContactMaterial -* @classdesc Physics ContactMaterial Constructor -* @constructor -* @param {Phaser.Physics.P2.Material} materialA -* @param {Phaser.Physics.P2.Material} materialB -* @param {object} [options] -*/ -Phaser.Physics.P2.ContactMaterial = function (materialA, materialB, options) { - - /** - * @property {number} id - The contact material identifier. - */ - - /** - * @property {Phaser.Physics.P2.Material} materialA - First material participating in the contact material. - */ - - /** - * @property {Phaser.Physics.P2.Material} materialB - First second participating in the contact material. - */ - - /** - * @property {number} [friction=0.3] - Friction to use in the contact of these two materials. - */ - - /** - * @property {number} [restitution=0.0] - Restitution to use in the contact of these two materials. - */ - - /** - * @property {number} [stiffness=1e7] - Stiffness of the resulting ContactEquation that this ContactMaterial generate. - */ - - /** - * @property {number} [relaxation=3] - Relaxation of the resulting ContactEquation that this ContactMaterial generate. - */ - - /** - * @property {number} [frictionStiffness=1e7] - Stiffness of the resulting FrictionEquation that this ContactMaterial generate. - */ - - /** - * @property {number} [frictionRelaxation=3] - Relaxation of the resulting FrictionEquation that this ContactMaterial generate. - */ - - /** - * @property {number} [surfaceVelocity=0] - Will add surface velocity to this material. If bodyA rests on top if bodyB, and the surface velocity is positive, bodyA will slide to the right. - */ - - p2.ContactMaterial.call(this, materialA, materialB, options); - -} - -Phaser.Physics.P2.ContactMaterial.prototype = Object.create(p2.ContactMaterial.prototype); -Phaser.Physics.P2.ContactMaterial.prototype.constructor = Phaser.Physics.P2.ContactMaterial; - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Collision Group -* -* @class Phaser.Physics.P2.CollisionGroup -* @classdesc Physics Collision Group Constructor -* @constructor -*/ -Phaser.Physics.P2.CollisionGroup = function (bitmask) { - - /** - * @property {number} mask - The CollisionGroup bitmask. - */ - this.mask = bitmask; - -} - -/** -* @author Richard Davey -* @copyright 2014 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - /** * Phaser.Particles is the Particle Manager for the game. It is called during the game update loop and in turn updates any Emitters attached to it. * @@ -49432,7 +41202,7 @@ Phaser.TilemapParser = { { return this.parseCSV(key, map.data, tileWidth, tileHeight); } - else if (map.format === Phaser.Tilemap.TILED_JSON) + else if (!map.format || map.format === Phaser.Tilemap.TILED_JSON) { return this.parseTiledJSON(map.data); } @@ -50025,7 +41795,7 @@ Phaser.Tileset.prototype.constructor = Phaser.Tileset; } exports.Phaser = Phaser; } else if (typeof define !== 'undefined' && define.amd) { - define(Phaser); + define('phaser', Phaser); } else { root.Phaser = Phaser; } diff --git a/build/custom/phaser-no-libs.min.js b/build/custom/phaser-no-libs.min.js index 22e6ff674..d6740bdbf 100644 --- a/build/custom/phaser-no-libs.min.js +++ b/build/custom/phaser-no-libs.min.js @@ -1,13 +1,11 @@ /* Phaser (no libs) v2.0.0 - http://phaser.io - @photonstorm - (c) 2014 Photon Storm Ltd. */ (function(){var a=this,b=b||{VERSION:"<%= version %>",DEV_VERSION:"2.0",GAMES:[],AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,SPRITE:0,BUTTON:1,IMAGE:2,GRAPHICS:3,TEXT:4,TILESPRITE:5,BITMAPTEXT:6,GROUP:7,RENDERTEXTURE:8,TILEMAP:9,TILEMAPLAYER:10,EMITTER:11,POLYGON:12,BITMAPDATA:13,CANVAS_FILTER:14,WEBGL_FILTER:15,ELLIPSE:16,SPRITEBATCH:17,BITMAPFONT:18,NONE:0,LEFT:1,RIGHT:2,UP:3,DOWN:4,DYNAMIC:1,STATIC:2,KINEMATIC:4,blendModes:{NORMAL:0,ADD:1,MULTIPLY:2,SCREEN:3,OVERLAY:4,DARKEN:5,LIGHTEN:6,COLOR_DODGE:7,COLOR_BURN:8,HARD_LIGHT:9,SOFT_LIGHT:10,DIFFERENCE:11,EXCLUSION:12,HUE:13,SATURATION:14,COLOR:15,LUMINOSITY:16},scaleModes:{DEFAULT:0,LINEAR:0,NEAREST:1}};PIXI.InteractionManager=function(){},b.Utils={parseDimension:function(a,b){var c=0,d=0;return"string"==typeof a?"%"===a.substr(-1)?(c=parseInt(a,10)/100,d=0===b?window.innerWidth*c:window.innerHeight*c):d=parseInt(a,10):d=a,d},shuffle:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},pad:function(a,b,c,d){if("undefined"==typeof b)var b=0;if("undefined"==typeof c)var c=" ";if("undefined"==typeof d)var d=3;var e=0;if(b+1>=a.length)switch(d){case 1:a=Array(b+1-a.length).join(c)+a;break;case 3:var f=Math.ceil((e=b-a.length)/2),g=e-f;a=Array(g+1).join(c)+a+Array(f+1).join(c);break;default:a+=Array(b+1-a.length).join(c)}return a},isPlainObject:function(a){if("object"!=typeof a||a.nodeType||a===a.window)return!1;try{if(a.constructor&&!hasOwn.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},extend:function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[1]||{},i=2),j===i&&(h=this,--i);j>i;i++)if(null!=(a=arguments[i]))for(c in a)d=h[c],e=a[c],h!==e&&(k&&e&&(b.Utils.isPlainObject(e)||(f=Array.isArray(e)))?(f?(f=!1,g=d&&Array.isArray(d)?d:[]):g=d&&b.Utils.isPlainObject(d)?d:{},h[c]=b.Utils.extend(k,g,e)):void 0!==e&&(h[c]=e));return h}},"function"!=typeof Function.prototype.bind&&(Function.prototype.bind=function(){var a=Array.prototype.slice;return function(b){function c(){var f=e.concat(a.call(arguments));d.apply(this instanceof c?this:b,f)}var d=this,e=a.call(arguments,1);if("function"!=typeof d)throw new TypeError;return c.prototype=function f(a){return a&&(f.prototype=a),this instanceof f?void 0:new f}(d.prototype),c}}()),Array.isArray||(Array.isArray=function(a){return"[object Array]"==Object.prototype.toString.call(a)}),b.Circle=function(a,b,c){a=a||0,b=b||0,c=c||0,this.x=a,this.y=b,this._diameter=c,this._radius=c>0?.5*c:0},b.Circle.prototype={circumference:function(){return 2*Math.PI*this._radius},setTo:function(a,b,c){return this.x=a,this.y=b,this._diameter=c,this._radius=.5*c,this},copyFrom:function(a){return this.setTo(a.x,a.y,a.diameter)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.diameter=this._diameter,a},distance:function(a,c){return"undefined"==typeof c&&(c=!1),c?b.Math.distanceRound(this.x,this.y,a.x,a.y):b.Math.distance(this.x,this.y,a.x,a.y)},clone:function(a){return"undefined"==typeof a?a=new b.Circle(this.x,this.y,this.diameter):a.setTo(this.x,this.y,this.diameter),a},contains:function(a,c){return b.Circle.contains(this,a,c)},circumferencePoint:function(a,c,d){return b.Circle.circumferencePoint(this,a,c,d)},offset:function(a,b){return this.x+=a,this.y+=b,this},offsetPoint:function(a){return this.offset(a.x,a.y)},toString:function(){return"[{Phaser.Circle (x="+this.x+" y="+this.y+" diameter="+this.diameter+" radius="+this.radius+")}]"}},b.Circle.prototype.constructor=b.Circle,Object.defineProperty(b.Circle.prototype,"diameter",{get:function(){return this._diameter},set:function(a){a>0&&(this._diameter=a,this._radius=.5*a)}}),Object.defineProperty(b.Circle.prototype,"radius",{get:function(){return this._radius},set:function(a){a>0&&(this._radius=a,this._diameter=2*a)}}),Object.defineProperty(b.Circle.prototype,"left",{get:function(){return this.x-this._radius},set:function(a){a>this.x?(this._radius=0,this._diameter=0):this.radius=this.x-a}}),Object.defineProperty(b.Circle.prototype,"right",{get:function(){return this.x+this._radius},set:function(a){athis.y?(this._radius=0,this._diameter=0):this.radius=this.y-a}}),Object.defineProperty(b.Circle.prototype,"bottom",{get:function(){return this.y+this._radius},set:function(a){a0?Math.PI*this._radius*this._radius:0}}),Object.defineProperty(b.Circle.prototype,"empty",{get:function(){return 0===this._diameter},set:function(a){a===!0&&this.setTo(0,0,0)}}),b.Circle.contains=function(a,b,c){if(a.radius>0&&b>=a.left&&b<=a.right&&c>=a.top&&c<=a.bottom){var d=(a.x-b)*(a.x-b),e=(a.y-c)*(a.y-c);return d+e<=a.radius*a.radius}return!1},b.Circle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.diameter==b.diameter},b.Circle.intersects=function(a,c){return b.Math.distance(a.x,a.y,c.x,c.y)<=a.radius+c.radius},b.Circle.circumferencePoint=function(a,c,d,e){return"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=new b.Point),d===!0&&(c=b.Math.degToRad(c)),e.x=a.x+a.radius*Math.cos(c),e.y=a.y+a.radius*Math.sin(c),e},b.Circle.intersectsRectangle=function(a,b){var c=Math.abs(a.x-b.x-b.halfWidth),d=b.halfWidth+a.radius;if(c>d)return!1;var e=Math.abs(a.y-b.y-b.halfHeight),f=b.halfHeight+a.radius;if(e>f)return!1;if(c<=b.halfWidth||e<=b.halfHeight)return!0;var g=c-b.halfWidth,h=e-b.halfHeight,i=g*g,j=h*h,k=a.radius*a.radius;return k>=i+j},PIXI.Circle=b.Circle,b.Point=function(a,b){a=a||0,b=b||0,this.x=a,this.y=b},b.Point.prototype={copyFrom:function(a){return this.setTo(a.x,a.y)},invert:function(){return this.setTo(this.y,this.x)},setTo:function(a,b){return this.x=a||0,this.y=b||(0!==b?this.x:0),this},set:function(a,b){return this.x=a||0,this.y=b||(0!==b?this.x:0),this},add:function(a,b){return this.x+=a,this.y+=b,this},subtract:function(a,b){return this.x-=a,this.y-=b,this},multiply:function(a,b){return this.x*=a,this.y*=b,this},divide:function(a,b){return this.x/=a,this.y/=b,this},clampX:function(a,c){return this.x=b.Math.clamp(this.x,a,c),this},clampY:function(a,c){return this.y=b.Math.clamp(this.y,a,c),this},clamp:function(a,c){return this.x=b.Math.clamp(this.x,a,c),this.y=b.Math.clamp(this.y,a,c),this},clone:function(a){return"undefined"==typeof a?a=new b.Point(this.x,this.y):a.setTo(this.x,this.y),a},copyTo:function(a){return a.x=this.x,a.y=this.y,a},distance:function(a,c){return b.Point.distance(this,a,c)},equals:function(a){return a.x==this.x&&a.y==this.y},rotate:function(a,c,d,e,f){return b.Point.rotate(this,a,c,d,e,f)},getMagnitude:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},setMagnitude:function(a){return this.normalize().multiply(a,a)},normalize:function(){if(!this.isZero()){var a=this.getMagnitude();this.x/=a,this.y/=a}return this},isZero:function(){return 0===this.x&&0===this.y},toString:function(){return"[{Point (x="+this.x+" y="+this.y+")}]"}},b.Point.prototype.constructor=b.Point,b.Point.add=function(a,c,d){return"undefined"==typeof d&&(d=new b.Point),d.x=a.x+c.x,d.y=a.y+c.y,d},b.Point.subtract=function(a,c,d){return"undefined"==typeof d&&(d=new b.Point),d.x=a.x-c.x,d.y=a.y-c.y,d},b.Point.multiply=function(a,c,d){return"undefined"==typeof d&&(d=new b.Point),d.x=a.x*c.x,d.y=a.y*c.y,d},b.Point.divide=function(a,c,d){return"undefined"==typeof d&&(d=new b.Point),d.x=a.x/c.x,d.y=a.y/c.y,d},b.Point.equals=function(a,b){return a.x==b.x&&a.y==b.y},b.Point.distance=function(a,c,d){return"undefined"==typeof d&&(d=!1),d?b.Math.distanceRound(a.x,a.y,c.x,c.y):b.Math.distance(a.x,a.y,c.x,c.y)},b.Point.rotate=function(a,c,d,e,f,g){return f=f||!1,g=g||null,f&&(e=b.Math.degToRad(e)),null===g&&(g=Math.sqrt((c-a.x)*(c-a.x)+(d-a.y)*(d-a.y))),a.setTo(c+g*Math.cos(e),d+g*Math.sin(e))},PIXI.Point=b.Point,b.Rectangle=function(a,b,c,d){a=a||0,b=b||0,c=c||0,d=d||0,this.x=a,this.y=b,this.width=c,this.height=d},b.Rectangle.prototype={offset:function(a,b){return this.x+=a,this.y+=b,this},offsetPoint:function(a){return this.offset(a.x,a.y)},setTo:function(a,b,c,d){return this.x=a,this.y=b,this.width=c,this.height=d,this},floor:function(){this.x=Math.floor(this.x),this.y=Math.floor(this.y)},floorAll:function(){this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.width=Math.floor(this.width),this.height=Math.floor(this.height)},copyFrom:function(a){return this.setTo(a.x,a.y,a.width,a.height)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.width=this.width,a.height=this.height,a},inflate:function(a,c){return b.Rectangle.inflate(this,a,c)},size:function(a){return b.Rectangle.size(this,a)},clone:function(a){return b.Rectangle.clone(this,a)},contains:function(a,c){return b.Rectangle.contains(this,a,c)},containsRect:function(a){return b.Rectangle.containsRect(this,a)},equals:function(a){return b.Rectangle.equals(this,a)},intersection:function(a,c){return b.Rectangle.intersection(this,a,c)},intersects:function(a,c){return b.Rectangle.intersects(this,a,c)},intersectsRaw:function(a,c,d,e,f){return b.Rectangle.intersectsRaw(this,a,c,d,e,f)},union:function(a,c){return b.Rectangle.union(this,a,c)},toString:function(){return"[{Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+" empty="+this.empty+")}]"},get halfWidth(){return Math.round(this.width/2)},get halfHeight(){return Math.round(this.height/2)},get bottom(){return this.y+this.height},set bottom(a){this.height=a<=this.y?0:this.y-a},get bottomRight(){return new b.Point(this.right,this.bottom)},set bottomRight(a){this.right=a.x,this.bottom=a.y},get left(){return this.x},set left(a){this.width=a>=this.right?0:this.right-a,this.x=a},get right(){return this.x+this.width},set right(a){this.width=a<=this.x?0:this.x+a},get volume(){return this.width*this.height},get perimeter(){return 2*this.width+2*this.height},get centerX(){return this.x+this.halfWidth},set centerX(a){this.x=a-this.halfWidth},get centerY(){return this.y+this.halfHeight},set centerY(a){this.y=a-this.halfHeight},get top(){return this.y},set top(a){a>=this.bottom?(this.height=0,this.y=a):this.height=this.bottom-a},get topLeft(){return new b.Point(this.x,this.y)},set topLeft(a){this.x=a.x,this.y=a.y},get empty(){return!this.width||!this.height},set empty(a){a===!0&&this.setTo(0,0,0,0)}},b.Rectangle.prototype.constructor=b.Rectangle,b.Rectangle.inflate=function(a,b,c){return a.x-=b,a.width+=2*b,a.y-=c,a.height+=2*c,a},b.Rectangle.inflatePoint=function(a,c){return b.Rectangle.inflate(a,c.x,c.y)},b.Rectangle.size=function(a,c){return"undefined"==typeof c?c=new b.Point(a.width,a.height):c.setTo(a.width,a.height),c},b.Rectangle.clone=function(a,c){return"undefined"==typeof c?c=new b.Rectangle(a.x,a.y,a.width,a.height):c.setTo(a.x,a.y,a.width,a.height),c},b.Rectangle.contains=function(a,b,c){return a.width<=0||a.height<=0?!1:b>=a.x&&b<=a.right&&c>=a.y&&c<=a.bottom},b.Rectangle.containsRaw=function(a,b,c,d,e,f){return e>=a&&a+c>=e&&f>=b&&b+d>=f},b.Rectangle.containsPoint=function(a,c){return b.Rectangle.contains(a,c.x,c.y)},b.Rectangle.containsRect=function(a,b){return a.volume>b.volume?!1:a.x>=b.x&&a.y>=b.y&&a.right<=b.right&&a.bottom<=b.bottom},b.Rectangle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.width==b.width&&a.height==b.height},b.Rectangle.intersection=function(a,c,d){return"undefined"==typeof d&&(d=new b.Rectangle),b.Rectangle.intersects(a,c)&&(d.x=Math.max(a.x,c.x),d.y=Math.max(a.y,c.y),d.width=Math.min(a.right,c.right)-d.x,d.height=Math.min(a.bottom,c.bottom)-d.y),d},b.Rectangle.intersects=function(a,b){return a.width<=0||a.height<=0||b.width<=0||b.height<=0?!1:!(a.rightb.right||a.y>b.bottom)},b.Rectangle.intersectsRaw=function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=0),!(b>a.right+f||ca.bottom+f||e=c&&d>=a&&b>=e&&f>=b}},Object.defineProperty(b.Line.prototype,"length",{get:function(){return Math.sqrt((this.end.x-this.start.x)*(this.end.x-this.start.x)+(this.end.y-this.start.y)*(this.end.y-this.start.y))}}),Object.defineProperty(b.Line.prototype,"angle",{get:function(){return Math.atan2(this.end.x-this.start.x,this.end.y-this.start.y)}}),Object.defineProperty(b.Line.prototype,"slope",{get:function(){return(this.end.y-this.start.y)/(this.end.x-this.start.x)}}),Object.defineProperty(b.Line.prototype,"perpSlope",{get:function(){return-((this.end.x-this.start.x)/(this.end.y-this.start.y))}}),b.Line.intersectsPoints=function(a,c,d,e,f,g){"undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=new b.Point);var h=c.y-a.y,i=e.y-d.y,j=a.x-c.x,k=d.x-e.x,l=c.x*a.y-a.x*c.y,m=e.x*d.y-d.x*e.y,n=h*k-i*j;if(0===n)return null;if(g.x=(j*m-k*l)/n,g.y=(i*l-h*m)/n,f){if(Math.pow(g.x-c.x+(g.y-c.y),2)>Math.pow(a.x-c.x+(a.y-c.y),2))return null;if(Math.pow(g.x-a.x+(g.y-a.y),2)>Math.pow(a.x-c.x+(a.y-c.y),2))return null;if(Math.pow(g.x-e.x+(g.y-e.y),2)>Math.pow(d.x-e.x+(d.y-e.y),2))return null;if(Math.pow(g.x-d.x+(g.y-d.y),2)>Math.pow(d.x-e.x+(d.y-e.y),2))return null}return g},b.Line.intersects=function(a,c,d,e){return b.Line.intersectsPoints(a.start,a.end,c.start,c.end,d,e)},b.Ellipse=function(a,c,d,e){this.type=b.ELLIPSE,a=a||0,c=c||0,d=d||0,e=e||0,this.x=a,this.y=c,this.width=d,this.height=e},b.Ellipse.prototype={setTo:function(a,b,c,d){return this.x=a,this.y=b,this.width=c,this.height=d,this},copyFrom:function(a){return this.setTo(a.x,a.y,a.width,a.height)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.width=this.width,a.height=this.height,a},clone:function(a){return"undefined"==typeof a?a=new b.Ellipse(this.x,this.y,this.width,this.height):a.setTo(this.x,this.y,this.width,this.height),a},contains:function(a,c){return b.Ellipse.contains(this,a,c)},toString:function(){return"[{Phaser.Ellipse (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+")}]"}},b.Ellipse.prototype.constructor=b.Ellipse,Object.defineProperty(b.Ellipse.prototype,"left",{get:function(){return this.x},set:function(a){this.x=a}}),Object.defineProperty(b.Ellipse.prototype,"right",{get:function(){return this.x+this.width},set:function(a){this.width=ad+e},b.Ellipse.prototype.getBounds=function(){return new b.Rectangle(this.x,this.y,this.width,this.height)},PIXI.Ellipse=b.Ellipse,b.Polygon=function(a){if(this.type=b.POLYGON,a instanceof Array||(a=Array.prototype.slice.call(arguments)),"number"==typeof a[0]){for(var c=[],d=0,e=a.length;e>d;d+=2)c.push(new b.Point(a[d],a[d+1]));a=c}this.points=a},b.Polygon.prototype={clone:function(){for(var a=[],c=0;cb!=i>b&&(h-f)*(b-g)/(i-g)+f>a;j&&(c=!0)}return c}},b.Polygon.prototype.constructor=b.Polygon,PIXI.Polygon=b.Polygon,b.Camera=function(a,c,d,e,f,g){this.game=a,this.world=a.world,this.id=0,this.view=new b.Rectangle(d,e,f,g),this.screenView=new b.Rectangle(d,e,f,g),this.bounds=new b.Rectangle(d,e,f,g),this.deadzone=null,this.visible=!0,this.atLimit={x:!1,y:!1},this.target=null,this._edge=0,this.displayObject=null,this.scale=null},b.Camera.FOLLOW_LOCKON=0,b.Camera.FOLLOW_PLATFORMER=1,b.Camera.FOLLOW_TOPDOWN=2,b.Camera.FOLLOW_TOPDOWN_TIGHT=3,b.Camera.prototype={follow:function(a,c){"undefined"==typeof c&&(c=b.Camera.FOLLOW_LOCKON),this.target=a;var d;switch(c){case b.Camera.FOLLOW_PLATFORMER:var e=this.width/8,f=this.height/3;this.deadzone=new b.Rectangle((this.width-e)/2,(this.height-f)/2-.25*f,e,f);break;case b.Camera.FOLLOW_TOPDOWN:d=Math.max(this.width,this.height)/4,this.deadzone=new b.Rectangle((this.width-d)/2,(this.height-d)/2,d,d);break;case b.Camera.FOLLOW_TOPDOWN_TIGHT:d=Math.max(this.width,this.height)/8,this.deadzone=new b.Rectangle((this.width-d)/2,(this.height-d)/2,d,d);break;case b.Camera.FOLLOW_LOCKON:this.deadzone=null;break;default:this.deadzone=null}},focusOn:function(a){this.setPosition(Math.round(a.x-this.view.halfWidth),Math.round(a.y-this.view.halfHeight))},focusOnXY:function(a,b){this.setPosition(Math.round(a-this.view.halfWidth),Math.round(b-this.view.halfHeight))},update:function(){this.target&&this.updateTarget(),this.bounds&&this.checkBounds(),this.displayObject.position.x=-this.view.x,this.displayObject.position.y=-this.view.y},updateTarget:function(){this.deadzone?(this._edge=this.target.x-this.deadzone.x,this.view.x>this._edge&&(this.view.x=this._edge),this._edge=this.target.x+this.target.width-this.deadzone.x-this.deadzone.width,this.view.xthis._edge&&(this.view.y=this._edge),this._edge=this.target.y+this.target.height-this.deadzone.y-this.deadzone.height,this.view.ythis.bounds.right&&(this.atLimit.x=!0,this.view.x=this.bounds.right-this.width),this.view.ythis.bounds.bottom&&(this.atLimit.y=!0,this.view.y=this.bounds.bottom-this.height),this.view.floor()},setPosition:function(a,b){this.view.x=a,this.view.y=b,this.bounds&&this.checkBounds()},setSize:function(a,b){this.view.width=a,this.view.height=b},reset:function(){this.target=null,this.view.x=0,this.view.y=0}},b.Camera.prototype.constructor=b.Camera,Object.defineProperty(b.Camera.prototype,"x",{get:function(){return this.view.x},set:function(a){this.view.x=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(b.Camera.prototype,"y",{get:function(){return this.view.y},set:function(a){this.view.y=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(b.Camera.prototype,"width",{get:function(){return this.view.width},set:function(a){this.view.width=a}}),Object.defineProperty(b.Camera.prototype,"height",{get:function(){return this.view.height},set:function(a){this.view.height=a}}),b.State=function(){this.game=null,this.add=null,this.make=null,this.camera=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.sound=null,this.scale=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.particles=null,this.physics=null,this.rnd=null},b.State.prototype={preload:function(){},loadUpdate:function(){},loadRender:function(){},create:function(){},update:function(){},render:function(){},paused:function(){},destroy:function(){}},b.State.prototype.constructor=b.State,b.StateManager=function(a,b){this.game=a,this.states={},this._pendingState=null,"undefined"!=typeof b&&null!==b&&(this._pendingState=b),this._clearWorld=!1,this._clearCache=!1,this._created=!1,this._args=[],this.current="",this.onInitCallback=null,this.onPreloadCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPreRenderCallback=null,this.onLoadUpdateCallback=null,this.onLoadRenderCallback=null,this.onPausedCallback=null,this.onResumedCallback=null,this.onShutDownCallback=null},b.StateManager.prototype={boot:function(){this.game.onPause.add(this.pause,this),this.game.onResume.add(this.resume,this),this.game.load.onLoadComplete.add(this.loadComplete,this),null!==this._pendingState&&("string"==typeof this._pendingState||this.add("default",this._pendingState,!0))},add:function(a,c,d){"undefined"==typeof d&&(d=!1);var e;return c instanceof b.State?e=c:"object"==typeof c?(e=c,e.game=this.game):"function"==typeof c&&(e=new c(this.game)),this.states[a]=e,d&&(this.game.isBooted?this.start(a):this._pendingState=a),e},remove:function(a){this.current==a&&(this.callbackContext=null,this.onInitCallback=null,this.onShutDownCallback=null,this.onPreloadCallback=null,this.onLoadRenderCallback=null,this.onLoadUpdateCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPausedCallback=null,this.onResumedCallback=null,this.onDestroyCallback=null),delete this.states[a]},start:function(a,b,c){"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!1),this.checkState(a)&&(this._pendingState=a,this._clearWorld=b,this._clearCache=c,arguments.length>3&&(this._args=Array.prototype.splice.call(arguments,3)))},dummy:function(){},preUpdate:function(){this._pendingState&&this.game.isBooted&&(this.current&&this.onShutDownCallback.call(this.callbackContext,this.game),this._clearWorld&&(this.game.tweens.removeAll(),this.game.world.destroy(),this.game.physics.clear(),this._clearCache===!0&&this.game.cache.destroy()),this.setCurrentState(this._pendingState),this.onPreloadCallback?(this.game.load.reset(),this.onPreloadCallback.call(this.callbackContext,this.game),0===this.game.load.totalQueuedFiles()?this.loadComplete():this.game.load.start()):this.loadComplete(),this.current===this._pendingState&&(this._pendingState=null))},checkState:function(a){if(this.states[a]){var b=!1;return this.states[a].preload&&(b=!0),this.states[a].create&&(b=!0),this.states[a].update&&(b=!0),this.states[a].render&&(b=!0),b===!1?(console.warn("Invalid Phaser State object given. Must contain at least a one of the required functions: preload, create, update or render"),!1):!0}return console.warn("Phaser.StateManager - No state found with the key: "+a),!1},link:function(a){this.states[a].game=this.game,this.states[a].add=this.game.add,this.states[a].make=this.game.make,this.states[a].camera=this.game.camera,this.states[a].cache=this.game.cache,this.states[a].input=this.game.input,this.states[a].load=this.game.load,this.states[a].math=this.game.math,this.states[a].sound=this.game.sound,this.states[a].scale=this.game.scale,this.states[a].state=this,this.states[a].stage=this.game.stage,this.states[a].time=this.game.time,this.states[a].tweens=this.game.tweens,this.states[a].world=this.game.world,this.states[a].particles=this.game.particles,this.states[a].rnd=this.game.rnd,this.states[a].physics=this.game.physics},setCurrentState:function(a){this.callbackContext=this.states[a],this.link(a),this.onInitCallback=this.states[a].init||this.dummy,this.onPreloadCallback=this.states[a].preload||null,this.onLoadRenderCallback=this.states[a].loadRender||null,this.onLoadUpdateCallback=this.states[a].loadUpdate||null,this.onCreateCallback=this.states[a].create||null,this.onUpdateCallback=this.states[a].update||null,this.onPreRenderCallback=this.states[a].preRender||null,this.onRenderCallback=this.states[a].render||null,this.onPausedCallback=this.states[a].paused||null,this.onResumedCallback=this.states[a].resumed||null,this.onShutDownCallback=this.states[a].shutdown||this.dummy,this.current=a,this._created=!1,this.onInitCallback.apply(this.callbackContext,this._args),this._args=[]},getCurrentState:function(){return this.states[this.current]},loadComplete:function(){this._created===!1&&this.onCreateCallback?(this._created=!0,this.onCreateCallback.call(this.callbackContext,this.game)):this._created=!0},pause:function(){this._created&&this.onPausedCallback&&this.onPausedCallback.call(this.callbackContext,this.game)},resume:function(){this._created&&this.onResumedCallback&&this.onResumedCallback.call(this.callbackContext,this.game)},update:function(){this._created&&this.onUpdateCallback?this.onUpdateCallback.call(this.callbackContext,this.game):this.onLoadUpdateCallback&&this.onLoadUpdateCallback.call(this.callbackContext,this.game)},preRender:function(){this.onPreRenderCallback&&this.onPreRenderCallback.call(this.callbackContext,this.game)},render:function(){this._created&&this.onRenderCallback?(this.game.renderType===b.CANVAS&&(this.game.context.save(),this.game.context.setTransform(1,0,0,1,0,0)),this.onRenderCallback.call(this.callbackContext,this.game),this.game.renderType===b.CANVAS&&this.game.context.restore()):this.onLoadRenderCallback&&this.onLoadRenderCallback.call(this.callbackContext,this.game)},destroy:function(){this.callbackContext=null,this.onInitCallback=null,this.onShutDownCallback=null,this.onPreloadCallback=null,this.onLoadRenderCallback=null,this.onLoadUpdateCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPausedCallback=null,this.onResumedCallback=null,this.onDestroyCallback=null,this.game=null,this.states={},this._pendingState=null}},b.StateManager.prototype.constructor=b.StateManager,b.LinkedList=function(){this.next=null,this.prev=null,this.first=null,this.last=null,this.total=0},b.LinkedList.prototype={add:function(a){return 0===this.total&&null==this.first&&null==this.last?(this.first=a,this.last=a,this.next=a,a.prev=this,this.total++,a):(this.last.next=a,a.prev=this.last,this.last=a,this.total++,a)},remove:function(a){a==this.first?this.first=this.first.next:a==this.last&&(this.last=this.last.prev),a.prev&&(a.prev.next=a.next),a.next&&(a.next.prev=a.prev),a.next=a.prev=null,null==this.first&&(this.last=null),this.total--},callAll:function(a){if(this.first&&this.last){var b=this.first;do b&&b[a]&&b[a].call(b),b=b.next;while(b!=this.last.next)}}},b.LinkedList.prototype.constructor=b.LinkedList,b.Signal=function(){this._bindings=[],this._prevParams=null;var a=this;this.dispatch=function(){b.Signal.prototype.dispatch.apply(a,arguments)}},b.Signal.prototype={memorize:!1,_shouldPropagate:!0,active:!0,validateListener:function(a,b){if("function"!=typeof a)throw new Error("listener is a required param of {fn}() and should be a Function.".replace("{fn}",b))},_registerListener:function(a,c,d,e){var f,g=this._indexOfListener(a,d);if(-1!==g){if(f=this._bindings[g],f.isOnce()!==c)throw new Error("You cannot add"+(c?"":"Once")+"() then add"+(c?"Once":"")+"() the same listener without removing the relationship first.")}else f=new b.SignalBinding(this,a,c,d,e),this._addBinding(f);return this.memorize&&this._prevParams&&f.execute(this._prevParams),f},_addBinding:function(a){var b=this._bindings.length;do--b;while(this._bindings[b]&&a._priority<=this._bindings[b]._priority);this._bindings.splice(b+1,0,a)},_indexOfListener:function(a,b){for(var c,d=this._bindings.length;d--;)if(c=this._bindings[d],c._listener===a&&c.context===b)return d;return-1},has:function(a,b){return-1!==this._indexOfListener(a,b)},add:function(a,b,c){return this.validateListener(a,"add"),this._registerListener(a,!1,b,c)},addOnce:function(a,b,c){return this.validateListener(a,"addOnce"),this._registerListener(a,!0,b,c)},remove:function(a,b){this.validateListener(a,"remove");var c=this._indexOfListener(a,b);return-1!==c&&(this._bindings[c]._destroy(),this._bindings.splice(c,1)),a},removeAll:function(){for(var a=this._bindings.length;a--;)this._bindings[a]._destroy();this._bindings.length=0},getNumListeners:function(){return this._bindings.length},halt:function(){this._shouldPropagate=!1},dispatch:function(){if(this.active){var a,b=Array.prototype.slice.call(arguments),c=this._bindings.length;if(this.memorize&&(this._prevParams=b),c){a=this._bindings.slice(),this._shouldPropagate=!0;do c--;while(a[c]&&this._shouldPropagate&&a[c].execute(b)!==!1)}}},forget:function(){this._prevParams=null},dispose:function(){this.removeAll(),delete this._bindings,delete this._prevParams},toString:function(){return"[Phaser.Signal active:"+this.active+" numListeners:"+this.getNumListeners()+"]"}},b.Signal.prototype.constructor=b.Signal,b.SignalBinding=function(a,b,c,d,e){this._listener=b,this._isOnce=c,this.context=d,this._signal=a,this._priority=e||0},b.SignalBinding.prototype={active:!0,params:null,execute:function(a){var b,c;return this.active&&this._listener&&(c=this.params?this.params.concat(a):a,b=this._listener.apply(this.context,c),this._isOnce&&this.detach()),b},detach:function(){return this.isBound()?this._signal.remove(this._listener,this.context):null},isBound:function(){return!!this._signal&&!!this._listener},isOnce:function(){return this._isOnce},getListener:function(){return this._listener},getSignal:function(){return this._signal},_destroy:function(){delete this._signal,delete this._listener,delete this.context},toString:function(){return"[Phaser.SignalBinding isOnce:"+this._isOnce+", isBound:"+this.isBound()+", active:"+this.active+"]"}},b.SignalBinding.prototype.constructor=b.SignalBinding,b.Filter=function(a,c,d){this.game=a,this.type=b.WEBGL_FILTER,this.passes=[this],this.shaders=[],this.dirty=!0,this.padding=0,this.uniforms={time:{type:"1f",value:0},resolution:{type:"2f",value:{x:256,y:256}},mouse:{type:"2f",value:{x:0,y:0}}},this.fragmentSrc=d||[]},b.Filter.prototype={init:function(){},setResolution:function(a,b){this.uniforms.resolution.value.x=a,this.uniforms.resolution.value.y=b},update:function(a){"undefined"!=typeof a&&(a.x>0&&(this.uniforms.mouse.x=a.x.toFixed(2)),a.y>0&&(this.uniforms.mouse.y=a.y.toFixed(2))),this.uniforms.time.value=this.game.time.totalElapsedSeconds()},destroy:function(){this.game=null}},b.Filter.prototype.constructor=b.Filter,Object.defineProperty(b.Filter.prototype,"width",{get:function(){return this.uniforms.resolution.value.x},set:function(a){this.uniforms.resolution.value.x=a}}),Object.defineProperty(b.Filter.prototype,"height",{get:function(){return this.uniforms.resolution.value.y},set:function(a){this.uniforms.resolution.value.y=a}}),b.Plugin=function(a,b){"undefined"==typeof b&&(b=null),this.game=a,this.parent=b,this.active=!1,this.visible=!1,this.hasPreUpdate=!1,this.hasUpdate=!1,this.hasPostUpdate=!1,this.hasRender=!1,this.hasPostRender=!1},b.Plugin.prototype={preUpdate:function(){},update:function(){},render:function(){},postRender:function(){},destroy:function(){this.game=null,this.parent=null,this.active=!1,this.visible=!1}},b.Plugin.prototype.constructor=b.Plugin,b.PluginManager=function(a,b){this.game=a,this._parent=b,this.plugins=[],this._pluginsLength=0},b.PluginManager.prototype={add:function(a){var b=!1;return"function"==typeof a?a=new a(this.game,this._parent):(a.game=this.game,a.parent=this._parent),"function"==typeof a.preUpdate&&(a.hasPreUpdate=!0,b=!0),"function"==typeof a.update&&(a.hasUpdate=!0,b=!0),"function"==typeof a.postUpdate&&(a.hasPostUpdate=!0,b=!0),"function"==typeof a.render&&(a.hasRender=!0,b=!0),"function"==typeof a.postRender&&(a.hasPostRender=!0,b=!0),b?((a.hasPreUpdate||a.hasUpdate||a.hasPostUpdate)&&(a.active=!0),(a.hasRender||a.hasPostRender)&&(a.visible=!0),this._pluginsLength=this.plugins.push(a),"function"==typeof a.init&&a.init(),a):null -},remove:function(a){if(0!==this._pluginsLength)for(this._p=0;this._pb;b++)this.children[b].preUpdate()},b.Stage.prototype.update=function(){for(var a=this.children.length;a--;)this.children[a].update()},b.Stage.prototype.postUpdate=function(){if(this.game.world.camera.target){this.game.world.camera.target.postUpdate(),this.game.world.camera.update();for(var a=this.children.length;a--;)this.children[a]!==this.game.world.camera.target&&this.children[a].postUpdate()}else{this.game.world.camera.update();for(var a=this.children.length;a--;)this.children[a].postUpdate()}this.checkOffsetInterval!==!1&&this.game.time.now>this._nextOffsetCheck&&(b.Canvas.getOffset(this.game.canvas,this.offset),this._nextOffsetCheck=this.game.time.now+this.checkOffsetInterval)},b.Stage.prototype.parseConfig=function(a){this.game.canvas=a.canvasID?b.Canvas.create(this.game.width,this.game.height,a.canvasID):b.Canvas.create(this.game.width,this.game.height),a.canvasStyle?this.game.canvas.stlye=a.canvasStyle:this.game.canvas.style["-webkit-full-screen"]="width: 100%; height: 100%",a.checkOffsetInterval&&(this.checkOffsetInterval=a.checkOffsetInterval),a.disableVisibilityChange&&(this.disableVisibilityChange=a.disableVisibilityChange),a.fullScreenScaleMode&&(this.fullScreenScaleMode=a.fullScreenScaleMode),a.scaleMode&&(this.scaleMode=a.scaleMode),a.backgroundColor&&(this.backgroundColor=a.backgroundColor)},b.Stage.prototype.boot=function(){b.Canvas.getOffset(this.game.canvas,this.offset),this.bounds=new b.Rectangle(this.offset.x,this.offset.y,this.game.width,this.game.height);var a=this;this._onChange=function(b){return a.visibilityChange(b)},b.Canvas.setUserSelect(this.game.canvas,"none"),b.Canvas.setTouchAction(this.game.canvas,"none"),this.checkVisibility()},b.Stage.prototype.checkVisibility=function(){this._hiddenVar=void 0!=document.webkitHidden?"webkitvisibilitychange":void 0!=document.mozHidden?"mozvisibilitychange":void 0!=document.msHidden?"msvisibilitychange":void 0!=document.hidden?"visibilitychange":null,this._hiddenVar&&document.addEventListener(this._hiddenVar,this._onChange,!1),window.onpagehide&&(window.onpagehide=this._onChange,window.onpageshow=this._onChange),window.onblur=this._onChange,window.onfocus=this._onChange},b.Stage.prototype.visibilityChange=function(a){return this.disableVisibilityChange?void 0:"pagehide"===a.type||"blur"===a.type||"pageshow"===a.type||"focus"===a.type?void("pagehide"===a.type||"blur"===a.type?this.game.gamePaused(a.timeStamp):("pageshow"===a.type||"focus"===a.type)&&this.game.gameResumed(a.timeStamp)):void(document.hidden||document.mozHidden||document.msHidden||document.webkitHidden?this.game.gamePaused(a.timeStamp):this.game.gameResumed(a.timeStamp))},b.Stage.prototype.setBackgroundColor=function(a){this._backgroundColor=a||0,this.backgroundColorSplit=PIXI.hex2rgb(this.backgroundColor);var b=this._backgroundColor.toString(16);b="000000".substr(0,6-b.length)+b,this.backgroundColorString="#"+b},Object.defineProperty(b.Stage.prototype,"backgroundColor",{get:function(){return this._backgroundColor},set:function(a){this._backgroundColor=a,this.game.transparent===!1&&("string"==typeof a&&(a=b.Color.hexToRGB(a)),this.setBackgroundColor(a))}}),Object.defineProperty(b.Stage.prototype,"smoothed",{get:function(){return!PIXI.scaleModes.LINEAR},set:function(a){PIXI.scaleModes.LINEAR=a?0:1}}),b.Group=function(a,c,d,e){"undefined"==typeof e&&(e=!1),this.game=a,"undefined"==typeof c&&(c=a.world),this.name=d||"group",PIXI.DisplayObjectContainer.call(this),e?this.game.stage.addChild(this):c&&c.addChild(this),this.type=b.GROUP,this.alive=!0,this.exists=!0,this.scale=new b.Point(1,1),this.cursor=null,this._cursorIndex=0,this.cameraOffset=new b.Point,this._cache=new Int16Array([0,0,0,0,1,0,1,0])},b.Group.prototype=Object.create(PIXI.DisplayObjectContainer.prototype),b.Group.prototype.constructor=b.Group,b.Group.RETURN_NONE=0,b.Group.RETURN_TOTAL=1,b.Group.RETURN_CHILD=2,b.Group.SORT_ASCENDING=-1,b.Group.SORT_DESCENDING=1,b.Group.prototype.add=function(a){return a.parent!==this&&(this.addChild(a),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a),a},b.Group.prototype.addAt=function(a,b){return a.parent!==this&&(this.addChildAt(a,b),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a),a},b.Group.prototype.getAt=function(a){return 0>a||a>this.children.length?-1:this.getChildAt(a)},b.Group.prototype.create=function(a,c,d,e,f){"undefined"==typeof f&&(f=!0);var g=new b.Sprite(this.game,a,c,d,e);return g.exists=f,g.visible=f,g.alive=f,this.addChild(g),g.events&&g.events.onAddedToGroup.dispatch(g,this),null===this.cursor&&(this.cursor=g),g},b.Group.prototype.createMultiple=function(a,b,c,d){"undefined"==typeof d&&(d=!1);for(var e=0;a>e;e++)this.create(0,0,b,c,d)},b.Group.prototype.next=function(){this.cursor&&(this._cursorIndex===this.children.length?this._cursorIndex=0:this._cursorIndex++,this.cursor=this.children[this._cursorIndex])},b.Group.prototype.previous=function(){this.cursor&&(0===this._cursorIndex?this._cursorIndex=this.children.length-1:this._cursorIndex--,this.cursor=this.children[this._cursorIndex])},b.Group.prototype.swap=function(a,b){return this.swapChildren(a,b)},b.Group.prototype.bringToTop=function(a){return a.parent===this&&this.getIndex(a)0&&(this.remove(a),this.addAt(a,0)),a},b.Group.prototype.moveUp=function(a){if(a.parent===this&&this.getIndex(a)0){var b=this.getIndex(a),c=this.getAt(b-1);c&&this.swap(b,c)}return a},b.Group.prototype.xy=function(a,b,c){return 0>a||a>this.children.length?-1:(this.getChildAt(a).x=b,void(this.getChildAt(a).y=c))},b.Group.prototype.reverse=function(){this.children.reverse()},b.Group.prototype.getIndex=function(a){return this.children.indexOf(a)},b.Group.prototype.replace=function(a,b){var c=this.getIndex(a);-1!==c&&(void 0!==b.parent&&(b.events.onRemovedFromGroup.dispatch(b,this),b.parent.removeChild(b)),this.removeChild(a),this.addChildAt(b,c),b.events.onAddedToGroup.dispatch(b,this),this.cursor===a&&(this.cursor=b))},b.Group.prototype.setProperty=function(a,b,c,d){d=d||0;var e=b.length;1==e?0===d?a[b[0]]=c:1==d?a[b[0]]+=c:2==d?a[b[0]]-=c:3==d?a[b[0]]*=c:4==d&&(a[b[0]]/=c):2==e?0===d?a[b[0]][b[1]]=c:1==d?a[b[0]][b[1]]+=c:2==d?a[b[0]][b[1]]-=c:3==d?a[b[0]][b[1]]*=c:4==d&&(a[b[0]][b[1]]/=c):3==e?0===d?a[b[0]][b[1]][b[2]]=c:1==d?a[b[0]][b[1]][b[2]]+=c:2==d?a[b[0]][b[1]][b[2]]-=c:3==d?a[b[0]][b[1]][b[2]]*=c:4==d&&(a[b[0]][b[1]][b[2]]/=c):4==e&&(0===d?a[b[0]][b[1]][b[2]][b[3]]=c:1==d?a[b[0]][b[1]][b[2]][b[3]]+=c:2==d?a[b[0]][b[1]][b[2]][b[3]]-=c:3==d?a[b[0]][b[1]][b[2]][b[3]]*=c:4==d&&(a[b[0]][b[1]][b[2]][b[3]]/=c))},b.Group.prototype.set=function(a,b,c,d,e,f){b=b.split("."),"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=!1),(d===!1||d&&a.alive)&&(e===!1||e&&a.visible)&&this.setProperty(a,b,c,f)},b.Group.prototype.setAll=function(a,b,c,d,e){a=a.split("."),"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),e=e||0;for(var f=0,g=this.children.length;g>f;f++)(!c||c&&this.children[f].alive)&&(!d||d&&this.children[f].visible)&&this.setProperty(this.children[f],a,b,e)},b.Group.prototype.addAll=function(a,b,c,d){this.setAll(a,b,c,d,1)},b.Group.prototype.subAll=function(a,b,c,d){this.setAll(a,b,c,d,2)},b.Group.prototype.multiplyAll=function(a,b,c,d){this.setAll(a,b,c,d,3)},b.Group.prototype.divideAll=function(a,b,c,d){this.setAll(a,b,c,d,4)},b.Group.prototype.callAllExists=function(a,b){for(var c=Array.prototype.splice.call(arguments,2),d=0,e=this.children.length;e>d;d++)this.children[d].exists===b&&this.children[d][a]&&this.children[d][a].apply(this.children[d],c)},b.Group.prototype.callbackFromArray=function(a,b,c){if(1==c){if(a[b[0]])return a[b[0]]}else if(2==c){if(a[b[0]][b[1]])return a[b[0]][b[1]]}else if(3==c){if(a[b[0]][b[1]][b[2]])return a[b[0]][b[1]][b[2]]}else if(4==c){if(a[b[0]][b[1]][b[2]][b[3]])return a[b[0]][b[1]][b[2]][b[3]]}else if(a[b])return a[b];return!1},b.Group.prototype.callAll=function(a,b){if("undefined"!=typeof a){a=a.split(".");var c=a.length;if("undefined"==typeof b||null===b||""===b)b=null;else if("string"==typeof b){b=b.split(".");var d=b.length}for(var e=Array.prototype.splice.call(arguments,2),f=null,g=null,h=0,i=this.children.length;i>h;h++)f=this.callbackFromArray(this.children[h],a,c),b&&f?(g=this.callbackFromArray(this.children[h],b,d),f&&f.apply(g,e)):f&&f.apply(this.children[h],e)}},b.Group.prototype.preUpdate=function(){if(!this.exists||!this.parent.exists)return this.renderOrderID=-1,!1;for(var a=this.children.length;a--;)this.children[a].preUpdate();return!0},b.Group.prototype.update=function(){for(var a=this.children.length;a--;)this.children[a].update()},b.Group.prototype.postUpdate=function(){1===this._cache[7]&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y);for(var a=this.children.length;a--;)this.children[a].postUpdate()},b.Group.prototype.forEach=function(a,b,c){"undefined"==typeof c&&(c=!1);var d=Array.prototype.splice.call(arguments,3);d.unshift(null);for(var e=0,f=this.children.length;f>e;e++)(!c||c&&this.children[e].exists)&&(d[0]=this.children[e],a.apply(b,d))},b.Group.prototype.forEachExists=function(a,c){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("exists",!0,b.Group.RETURN_TOTAL,a,c,d)},b.Group.prototype.forEachAlive=function(a,c){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!0,b.Group.RETURN_TOTAL,a,c,d)},b.Group.prototype.forEachDead=function(a,c){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!1,b.Group.RETURN_TOTAL,a,c,d)},b.Group.prototype.sort=function(a,c){"undefined"==typeof a&&(a="y"),"undefined"==typeof c&&(c=b.Group.SORT_ASCENDING)},b.Group.prototype.sortHandler=function(){},b.Group.prototype.iterate=function(a,c,d,e,f,g){if(d===b.Group.RETURN_TOTAL&&0===this.children.length)return 0;"undefined"==typeof e&&(e=!1);for(var h=0,i=0,j=this.children.length;j>i;i++)if(this.children[i][a]===c&&(h++,e&&(g[0]=this.children[i],e.apply(f,g)),d===b.Group.RETURN_CHILD))return this.children[i];return d===b.Group.RETURN_TOTAL?h:d===b.Group.RETURN_CHILD?null:void 0},b.Group.prototype.getFirstExists=function(a){return"boolean"!=typeof a&&(a=!0),this.iterate("exists",a,b.Group.RETURN_CHILD)},b.Group.prototype.getFirstAlive=function(){return this.iterate("alive",!0,b.Group.RETURN_CHILD)},b.Group.prototype.getFirstDead=function(){return this.iterate("alive",!1,b.Group.RETURN_CHILD)},b.Group.prototype.countLiving=function(){return this.iterate("alive",!0,b.Group.RETURN_TOTAL)},b.Group.prototype.countDead=function(){return this.iterate("alive",!1,b.Group.RETURN_TOTAL)},b.Group.prototype.getRandom=function(a,b){return 0===this.children.length?null:(a=a||0,b=b||this.children.length,this.game.math.getRandom(this.children,a,b))},b.Group.prototype.remove=function(a){return 0!==this.children.length?(a.events&&a.events.onRemovedFromGroup.dispatch(a,this),this.removeChild(a),this.cursor===a&&this.next(),!0):void 0},b.Group.prototype.removeAll=function(){if(0!==this.children.length){do this.children[0].events&&this.children[0].events.onRemovedFromGroup.dispatch(this.children[0],this),this.removeChild(this.children[0]);while(this.children.length>0);this.cursor=null}},b.Group.prototype.removeBetween=function(a,b){if(0!==this.children.length){if(a>b||0>a||b>this.children.length)return!1;for(var c=a;b>c;c++)this.children[c].events&&this.children[c].events.onRemovedFromGroup.dispatch(this.children[c],this),this.removeChild(this.children[c]),this.cursor===child&&(this.cursor=null)}},b.Group.prototype.destroy=function(a){if(null!==this.game){if("undefined"==typeof a&&(a=!0),a){if(this.children.length>0)do this.children[0].parent&&this.children[0].destroy(a);while(this.children.length>0)}else this.removeAll();this.parent.removeChild(this),this.game=null,this.exists=!1,this.cursor=null}},Object.defineProperty(b.Group.prototype,"total",{get:function(){return this.iterate("exists",!0,b.Group.RETURN_TOTAL)}}),Object.defineProperty(b.Group.prototype,"length",{get:function(){return this.children.length}}),Object.defineProperty(b.Group.prototype,"angle",{get:function(){return b.Math.radToDeg(this.rotation)},set:function(a){this.rotation=b.Math.degToRad(a)}}),Object.defineProperty(b.Group.prototype,"fixedToCamera",{get:function(){return!!this._cache[7]},set:function(a){a?(this._cache[7]=1,this.cameraOffset.set(this.x,this.y)):this._cache[7]=0}}),b.World=function(a){b.Group.call(this,a,null,"__world",!1),this.bounds=new b.Rectangle(0,0,a.width,a.height),this.camera=null},b.World.prototype=Object.create(b.Group.prototype),b.World.prototype.constructor=b.World,b.World.prototype.boot=function(){this.camera=new b.Camera(this.game,0,0,0,this.game.width,this.game.height),this.camera.displayObject=this,this.camera.scale=this.scale,this.game.camera=this.camera,this.game.stage.addChild(this)},b.World.prototype.setBounds=function(a,b,c,d){cwindow.outerHeight&&(this.orientation=90),this.scaleFactor=new b.Point(1,1),this.scaleFactorInversed=new b.Point(1,1),this.margin=new b.Point(0,0),this.aspectRatio=0,this.sourceAspectRatio=c/d,this.event=null,this.scaleMode=b.ScaleManager.NO_SCALE,this.fullScreenScaleMode=b.ScaleManager.NO_SCALE,this._startHeight=0,this._width=0,this._height=0;var e=this;window.addEventListener("orientationchange",function(a){return e.checkOrientation(a)},!1),window.addEventListener("resize",function(a){return e.checkResize(a)},!1),document.addEventListener("webkitfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("mozfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("fullscreenchange",function(a){return e.fullScreenChange(a)},!1)},b.ScaleManager.EXACT_FIT=0,b.ScaleManager.NO_SCALE=1,b.ScaleManager.SHOW_ALL=2,b.ScaleManager.prototype={startFullScreen:function(a){!this.isFullScreen&&this.game.device.fullscreen&&("undefined"!=typeof a&&this.game.renderType===b.CANVAS&&(this.game.stage.smoothed=a),this._width=this.width,this._height=this.height,this.game.device.fullscreenKeyboard?this.game.canvas[this.game.device.requestFullscreen](Element.ALLOW_KEYBOARD_INPUT):this.game.canvas[this.game.device.requestFullscreen]())},stopFullScreen:function(){this.game.canvas[this.game.device.cancelFullscreen]()},fullScreenChange:function(a){this.event=a,this.isFullScreen?(this.fullScreenScaleMode===b.ScaleManager.EXACT_FIT?(this.game.canvas.style.width="100%",this.game.canvas.style.height="100%",this.width=window.outerWidth,this.height=window.outerHeight,this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height,this.checkResize()):this.fullScreenScaleMode===b.ScaleManager.SHOW_ALL&&(this.setShowAll(),this.refresh()),this.enterFullScreen.dispatch(this.width,this.height)):(this.game.canvas.style.width=this.game.width+"px",this.game.canvas.style.height=this.game.height+"px",this.width=this._width,this.height=this._height,this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height,this.leaveFullScreen.dispatch(this.width,this.height))},forceOrientation:function(a,b,c){"undefined"==typeof b&&(b=!1),this.forceLandscape=a,this.forcePortrait=b,"undefined"!=typeof c&&((null==c||this.game.cache.checkImageKey(c)===!1)&&(c="__default"),this.orientationSprite=new PIXI.Sprite(PIXI.TextureCache[c]),this.orientationSprite.anchor.x=.5,this.orientationSprite.anchor.y=.5,this.orientationSprite.position.x=this.game.width/2,this.orientationSprite.position.y=this.game.height/2,this.checkOrientationState(),this.incorrectOrientation?(this.orientationSprite.visible=!0,this.game.world.visible=!1):(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.game.stage.addChild(this.orientationSprite))},checkOrientationState:function(){this.incorrectOrientation?(this.forceLandscape&&window.innerWidth>window.innerHeight||this.forcePortrait&&window.innerHeight>window.innerWidth)&&(this.incorrectOrientation=!1,this.leaveIncorrectOrientation.dispatch(),this.orientationSprite&&(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.scaleMode!==b.ScaleManager.NO_SCALE&&this.refresh()):(this.forceLandscape&&window.innerWidthwindow.outerHeight?90:0,this.isLandscape?this.enterLandscape.dispatch(this.orientation,!0,!1):this.enterPortrait.dispatch(this.orientation,!1,!0),this.scaleMode!==b.ScaleManager.NO_SCALE&&this.refresh(),this.checkOrientationState()},refresh:function(){if(this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),null==this._check&&this.maxIterations>0){this._iterations=this.maxIterations;var a=this;this._check=window.setInterval(function(){return a.setScreenSize()},10),this.setScreenSize()}},setScreenSize:function(a){"undefined"==typeof a&&(a=!1),this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),this._iterations--,(a||window.innerHeight>this._startHeight||this._iterations<0)&&(document.documentElement.style.minHeight=window.innerHeight+"px",this.incorrectOrientation===!0?this.setMaximum():this.isFullScreen?this.fullScreenScaleMode==b.ScaleManager.EXACT_FIT?this.setExactFit():this.fullScreenScaleMode==b.ScaleManager.SHOW_ALL&&this.setShowAll():this.scaleMode==b.ScaleManager.EXACT_FIT?this.setExactFit():this.scaleMode==b.ScaleManager.SHOW_ALL&&this.setShowAll(),this.setSize(),clearInterval(this._check),this._check=null)},setSize:function(){this.incorrectOrientation===!1&&(this.maxWidth&&this.width>this.maxWidth&&(this.width=this.maxWidth),this.maxHeight&&this.height>this.maxHeight&&(this.height=this.maxHeight),this.minWidth&&this.widththis.maxWidth?this.maxWidth:a,this.height=this.maxHeight&&b>this.maxHeight?this.maxHeight:b}},b.ScaleManager.prototype.constructor=b.ScaleManager,Object.defineProperty(b.ScaleManager.prototype,"isFullScreen",{get:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement}}),Object.defineProperty(b.ScaleManager.prototype,"isPortrait",{get:function(){return 0===this.orientation||180==this.orientation}}),Object.defineProperty(b.ScaleManager.prototype,"isLandscape",{get:function(){return 90===this.orientation||-90===this.orientation}}),b.Game=function(a,c,d,e,f,g,h,i){this.id=b.GAMES.push(this)-1,this.config=null,this.physicsConfig=i,this.parent="",this.width=800,this.height=600,this.transparent=!1,this.antialias=!0,this.renderer=b.AUTO,this.renderType=b.AUTO,this.state=null,this.isBooted=!1,this.isRunning=!1,this.raf=null,this.add=null,this.make=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.net=null,this.scale=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.physics=null,this.rnd=null,this.device=null,this.camera=null,this.canvas=null,this.context=null,this.debug=null,this.particles=null,this.stepping=!1,this.pendingStep=!1,this.stepCount=0,this._paused=!1,this._codePaused=!1,1===arguments.length&&"object"==typeof arguments[0]?this.parseConfig(arguments[0]):("undefined"!=typeof a&&(this.width=a),"undefined"!=typeof c&&(this.height=c),"undefined"!=typeof d&&(this.renderer=d,this.renderType=d),"undefined"!=typeof e&&(this.parent=e),"undefined"!=typeof g&&(this.transparent=g),"undefined"!=typeof h&&(this.antialias=h),this.state=new b.StateManager(this,f));var j=this;return this._onBoot=function(){return j.boot()},"complete"===document.readyState||"interactive"===document.readyState?window.setTimeout(this._onBoot,0):(document.addEventListener("DOMContentLoaded",this._onBoot,!1),window.addEventListener("load",this._onBoot,!1)),this},b.Game.prototype={parseConfig:function(a){this.config=a,a.width&&(this.width=b.Utils.parseDimension(a.width,0)),a.height&&(this.height=b.Utils.parseDimension(a.height,1)),a.renderer&&(this.renderer=a.renderer,this.renderType=a.renderer),a.parent&&(this.parent=a.parent),a.transparent&&(this.transparent=a.transparent),a.antialias&&(this.antialias=a.antialias),a.physicsConfig&&(this.physicsConfig=a.physicsConfig);var c=null;a.state&&(c=a.state),this.state=new b.StateManager(this,c)},boot:function(){this.isBooted||(document.body?(document.removeEventListener("DOMContentLoaded",this._onBoot),window.removeEventListener("load",this._onBoot),this.onPause=new b.Signal,this.onResume=new b.Signal,this.isBooted=!0,this.device=new b.Device(this),this.math=b.Math,this.rnd=new b.RandomDataGenerator([(Date.now()*Math.random()).toString()]),this.stage=new b.Stage(this,this.width,this.height),this.scale=new b.ScaleManager(this,this.width,this.height),this.setUpRenderer(),this.device.checkFullScreenSupport(),this.world=new b.World(this),this.add=new b.GameObjectFactory(this),this.make=new b.GameObjectCreator(this),this.cache=new b.Cache(this),this.load=new b.Loader(this),this.time=new b.Time(this),this.tweens=new b.TweenManager(this),this.input=new b.Input(this),this.sound=new b.SoundManager(this),this.physics=new b.Physics(this,this.physicsConfig),this.particles=new b.Particles(this),this.plugins=new b.PluginManager(this,this),this.net=new b.Net(this),this.debug=new b.Utils.Debug(this),this.time.boot(),this.stage.boot(),this.world.boot(),this.input.boot(),this.sound.boot(),this.state.boot(),this.debug.boot(),this.showDebugHeader(),this.isRunning=!0,this.raf=this.config&&this.config.forceSetTimeOut?new b.RequestAnimationFrame(this,this.config.forceSetTimeOut):new b.RequestAnimationFrame(this,!1),this.raf.start()):window.setTimeout(this._onBoot,20))},showDebugHeader:function(){var a=b.DEV_VERSION,c="Canvas",d="HTML Audio";if(this.renderType==b.WEBGL?c="WebGL":this.renderType==b.HEADLESS&&(c="Headless"),this.device.webAudio&&(d="WebAudio"),this.device.chrome){var e=["%c %c %c Phaser v"+a+" - Renderer: "+c+" - Audio: "+d+" %c %c ","background: #00bff3","background: #0072bc","color: #ffffff; background: #003471","background: #0072bc","background: #00bff3"];console.log.apply(console,e)}else console.log("Phaser v"+a+" - Renderer: "+c+" - Audio: "+d)},setUpRenderer:function(){if(this.device.trident&&(this.renderType=b.CANVAS),this.renderType===b.HEADLESS||this.renderType===b.CANVAS||this.renderType===b.AUTO&&this.device.webGL===!1){if(!this.device.canvas)throw new Error("Phaser.Game - cannot create Canvas or WebGL context, aborting.");this.renderType===b.AUTO&&(this.renderType=b.CANVAS),this.renderer=new PIXI.CanvasRenderer(this.width,this.height,this.canvas,this.transparent),this.context=this.renderer.context}else this.renderType=b.WEBGL,this.renderer=new PIXI.WebGLRenderer(this.width,this.height,this.canvas,this.transparent,this.antialias),this.context=null;this.stage.smoothed=this.antialias,b.Canvas.addToDOM(this.canvas,this.parent,!0),b.Canvas.setTouchAction(this.canvas)},update:function(a){this.time.update(a),this._paused?(this.input.update(),this.renderType!==b.HEADLESS&&(this.renderer.render(this.stage),this.plugins.render(),this.state.render(),this.plugins.postRender())):(this.pendingStep||(this.stepping&&(this.pendingStep=!0),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.physics.update(),this.particles.update(),this.plugins.update(),this.stage.postUpdate(),this.plugins.postUpdate()),this.renderType!==b.HEADLESS&&(this.renderer.render(this.stage),this.plugins.render(),this.state.render(),this.plugins.postRender()))},enableStep:function(){this.stepping=!0,this.pendingStep=!1,this.stepCount=0},disableStep:function(){this.stepping=!1,this.pendingStep=!1},step:function(){this.pendingStep=!1,this.stepCount++},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=!1},gamePaused:function(a){this._paused||(this._paused=!0,this.time.gamePaused(a),this.sound.setMute(),this.onPause.dispatch(this))},gameResumed:function(a){this._paused&&!this._codePaused&&(this._paused=!1,this.time.gameResumed(a),this.input.reset(),this.sound.unsetMute(),this.onResume.dispatch(this))}},b.Game.prototype.constructor=b.Game,Object.defineProperty(b.Game.prototype,"paused",{get:function(){return this._paused},set:function(a){a===!0?this._paused===!1&&(this._paused=!0,this._codePaused=!0,this.sound.mute=!0,this.time.gamePaused(),this.onPause.dispatch(this)):this._paused&&(this._paused=!1,this._codePaused=!1,this.input.reset(),this.sound.mute=!1,this.time.gameResumed(),this.onResume.dispatch(this))}}),b.Input=function(a){this.game=a,this.hitCanvas=null,this.hitContext=null,this.moveCallback=null,this.moveCallbackContext=this,this.pollRate=0,this.disabled=!1,this.multiInputOverride=b.Input.MOUSE_TOUCH_COMBINE,this.position=null,this.speed=null,this.circle=null,this.scale=null,this.maxPointers=10,this.currentPointers=0,this.tapRate=200,this.doubleTapRate=300,this.holdRate=2e3,this.justPressedRate=200,this.justReleasedRate=200,this.recordPointerHistory=!1,this.recordRate=100,this.recordLimit=100,this.pointer1=null,this.pointer2=null,this.pointer3=null,this.pointer4=null,this.pointer5=null,this.pointer6=null,this.pointer7=null,this.pointer8=null,this.pointer9=null,this.pointer10=null,this.activePointer=null,this.mousePointer=null,this.mouse=null,this.keyboard=null,this.touch=null,this.mspointer=null,this.gamepad=null,this.gestures=null,this.onDown=null,this.onUp=null,this.onTap=null,this.onHold=null,this.interactiveItems=new b.LinkedList,this._localPoint=new b.Point,this._pollCounter=0,this._oldPosition=null,this._x=0,this._y=0 +},remove:function(a){if(0!==this._pluginsLength)for(this._p=0;this._pb;b++)this.children[b].preUpdate()},b.Stage.prototype.update=function(){for(var a=this.children.length;a--;)this.children[a].update()},b.Stage.prototype.postUpdate=function(){if(this.game.world.camera.target){this.game.world.camera.target.postUpdate(),this.game.world.camera.update();for(var a=this.children.length;a--;)this.children[a]!==this.game.world.camera.target&&this.children[a].postUpdate()}else{this.game.world.camera.update();for(var a=this.children.length;a--;)this.children[a].postUpdate()}this.checkOffsetInterval!==!1&&this.game.time.now>this._nextOffsetCheck&&(b.Canvas.getOffset(this.game.canvas,this.offset),this._nextOffsetCheck=this.game.time.now+this.checkOffsetInterval)},b.Stage.prototype.parseConfig=function(a){this.game.canvas=a.canvasID?b.Canvas.create(this.game.width,this.game.height,a.canvasID):b.Canvas.create(this.game.width,this.game.height),a.canvasStyle?this.game.canvas.stlye=a.canvasStyle:this.game.canvas.style["-webkit-full-screen"]="width: 100%; height: 100%",a.checkOffsetInterval&&(this.checkOffsetInterval=a.checkOffsetInterval),a.disableVisibilityChange&&(this.disableVisibilityChange=a.disableVisibilityChange),a.fullScreenScaleMode&&(this.fullScreenScaleMode=a.fullScreenScaleMode),a.scaleMode&&(this.scaleMode=a.scaleMode),a.backgroundColor&&(this.backgroundColor=a.backgroundColor)},b.Stage.prototype.boot=function(){b.Canvas.getOffset(this.game.canvas,this.offset),this.bounds=new b.Rectangle(this.offset.x,this.offset.y,this.game.width,this.game.height);var a=this;this._onChange=function(b){return a.visibilityChange(b)},b.Canvas.setUserSelect(this.game.canvas,"none"),b.Canvas.setTouchAction(this.game.canvas,"none"),this.checkVisibility()},b.Stage.prototype.checkVisibility=function(){this._hiddenVar=void 0!=document.webkitHidden?"webkitvisibilitychange":void 0!=document.mozHidden?"mozvisibilitychange":void 0!=document.msHidden?"msvisibilitychange":void 0!=document.hidden?"visibilitychange":null,this._hiddenVar&&document.addEventListener(this._hiddenVar,this._onChange,!1),window.onpagehide&&(window.onpagehide=this._onChange,window.onpageshow=this._onChange),window.onblur=this._onChange,window.onfocus=this._onChange},b.Stage.prototype.visibilityChange=function(a){return this.disableVisibilityChange?void 0:"pagehide"===a.type||"blur"===a.type||"pageshow"===a.type||"focus"===a.type?void("pagehide"===a.type||"blur"===a.type?this.game.gamePaused(a.timeStamp):("pageshow"===a.type||"focus"===a.type)&&this.game.gameResumed(a.timeStamp)):void(document.hidden||document.mozHidden||document.msHidden||document.webkitHidden?this.game.gamePaused(a.timeStamp):this.game.gameResumed(a.timeStamp))},b.Stage.prototype.setBackgroundColor=function(a){this._backgroundColor=a||0,this.backgroundColorSplit=PIXI.hex2rgb(this.backgroundColor);var b=this._backgroundColor.toString(16);b="000000".substr(0,6-b.length)+b,this.backgroundColorString="#"+b},Object.defineProperty(b.Stage.prototype,"backgroundColor",{get:function(){return this._backgroundColor},set:function(a){this._backgroundColor=a,this.game.transparent===!1&&("string"==typeof a&&(a=b.Color.hexToRGB(a)),this.setBackgroundColor(a))}}),Object.defineProperty(b.Stage.prototype,"smoothed",{get:function(){return!PIXI.scaleModes.LINEAR},set:function(a){PIXI.scaleModes.LINEAR=a?0:1}}),b.Group=function(a,c,d,e){"undefined"==typeof e&&(e=!1),this.game=a,"undefined"==typeof c&&(c=a.world),this.name=d||"group",PIXI.DisplayObjectContainer.call(this),e?this.game.stage.addChild(this):c&&c.addChild(this),this.type=b.GROUP,this.alive=!0,this.exists=!0,this.scale=new b.Point(1,1),this.cursor=null,this._cursorIndex=0,this.cameraOffset=new b.Point,this._cache=new Int16Array([0,0,0,0,1,0,1,0])},b.Group.prototype=Object.create(PIXI.DisplayObjectContainer.prototype),b.Group.prototype.constructor=b.Group,b.Group.RETURN_NONE=0,b.Group.RETURN_TOTAL=1,b.Group.RETURN_CHILD=2,b.Group.SORT_ASCENDING=-1,b.Group.SORT_DESCENDING=1,b.Group.prototype.add=function(a){return a.parent!==this&&(this.addChild(a),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a),a},b.Group.prototype.addAt=function(a,b){return a.parent!==this&&(this.addChildAt(a,b),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a),a},b.Group.prototype.getAt=function(a){return 0>a||a>this.children.length?-1:this.getChildAt(a)},b.Group.prototype.create=function(a,c,d,e,f){"undefined"==typeof f&&(f=!0);var g=new b.Sprite(this.game,a,c,d,e);return g.exists=f,g.visible=f,g.alive=f,this.addChild(g),g.events&&g.events.onAddedToGroup.dispatch(g,this),null===this.cursor&&(this.cursor=g),g},b.Group.prototype.createMultiple=function(a,b,c,d){"undefined"==typeof d&&(d=!1);for(var e=0;a>e;e++)this.create(0,0,b,c,d)},b.Group.prototype.next=function(){this.cursor&&(this._cursorIndex===this.children.length?this._cursorIndex=0:this._cursorIndex++,this.cursor=this.children[this._cursorIndex])},b.Group.prototype.previous=function(){this.cursor&&(0===this._cursorIndex?this._cursorIndex=this.children.length-1:this._cursorIndex--,this.cursor=this.children[this._cursorIndex])},b.Group.prototype.swap=function(a,b){return this.swapChildren(a,b)},b.Group.prototype.bringToTop=function(a){return a.parent===this&&this.getIndex(a)0&&(this.remove(a),this.addAt(a,0)),a},b.Group.prototype.moveUp=function(a){if(a.parent===this&&this.getIndex(a)0){var b=this.getIndex(a),c=this.getAt(b-1);c&&this.swap(b,c)}return a},b.Group.prototype.xy=function(a,b,c){return 0>a||a>this.children.length?-1:(this.getChildAt(a).x=b,void(this.getChildAt(a).y=c))},b.Group.prototype.reverse=function(){this.children.reverse()},b.Group.prototype.getIndex=function(a){return this.children.indexOf(a)},b.Group.prototype.replace=function(a,b){var c=this.getIndex(a);-1!==c&&(void 0!==b.parent&&(b.events.onRemovedFromGroup.dispatch(b,this),b.parent.removeChild(b)),this.removeChild(a),this.addChildAt(b,c),b.events.onAddedToGroup.dispatch(b,this),this.cursor===a&&(this.cursor=b))},b.Group.prototype.setProperty=function(a,b,c,d){d=d||0;var e=b.length;1==e?0===d?a[b[0]]=c:1==d?a[b[0]]+=c:2==d?a[b[0]]-=c:3==d?a[b[0]]*=c:4==d&&(a[b[0]]/=c):2==e?0===d?a[b[0]][b[1]]=c:1==d?a[b[0]][b[1]]+=c:2==d?a[b[0]][b[1]]-=c:3==d?a[b[0]][b[1]]*=c:4==d&&(a[b[0]][b[1]]/=c):3==e?0===d?a[b[0]][b[1]][b[2]]=c:1==d?a[b[0]][b[1]][b[2]]+=c:2==d?a[b[0]][b[1]][b[2]]-=c:3==d?a[b[0]][b[1]][b[2]]*=c:4==d&&(a[b[0]][b[1]][b[2]]/=c):4==e&&(0===d?a[b[0]][b[1]][b[2]][b[3]]=c:1==d?a[b[0]][b[1]][b[2]][b[3]]+=c:2==d?a[b[0]][b[1]][b[2]][b[3]]-=c:3==d?a[b[0]][b[1]][b[2]][b[3]]*=c:4==d&&(a[b[0]][b[1]][b[2]][b[3]]/=c))},b.Group.prototype.set=function(a,b,c,d,e,f){b=b.split("."),"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=!1),(d===!1||d&&a.alive)&&(e===!1||e&&a.visible)&&this.setProperty(a,b,c,f)},b.Group.prototype.setAll=function(a,b,c,d,e){a=a.split("."),"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),e=e||0;for(var f=0,g=this.children.length;g>f;f++)(!c||c&&this.children[f].alive)&&(!d||d&&this.children[f].visible)&&this.setProperty(this.children[f],a,b,e)},b.Group.prototype.addAll=function(a,b,c,d){this.setAll(a,b,c,d,1)},b.Group.prototype.subAll=function(a,b,c,d){this.setAll(a,b,c,d,2)},b.Group.prototype.multiplyAll=function(a,b,c,d){this.setAll(a,b,c,d,3)},b.Group.prototype.divideAll=function(a,b,c,d){this.setAll(a,b,c,d,4)},b.Group.prototype.callAllExists=function(a,b){for(var c=Array.prototype.splice.call(arguments,2),d=0,e=this.children.length;e>d;d++)this.children[d].exists===b&&this.children[d][a]&&this.children[d][a].apply(this.children[d],c)},b.Group.prototype.callbackFromArray=function(a,b,c){if(1==c){if(a[b[0]])return a[b[0]]}else if(2==c){if(a[b[0]][b[1]])return a[b[0]][b[1]]}else if(3==c){if(a[b[0]][b[1]][b[2]])return a[b[0]][b[1]][b[2]]}else if(4==c){if(a[b[0]][b[1]][b[2]][b[3]])return a[b[0]][b[1]][b[2]][b[3]]}else if(a[b])return a[b];return!1},b.Group.prototype.callAll=function(a,b){if("undefined"!=typeof a){a=a.split(".");var c=a.length;if("undefined"==typeof b||null===b||""===b)b=null;else if("string"==typeof b){b=b.split(".");var d=b.length}for(var e=Array.prototype.splice.call(arguments,2),f=null,g=null,h=0,i=this.children.length;i>h;h++)f=this.callbackFromArray(this.children[h],a,c),b&&f?(g=this.callbackFromArray(this.children[h],b,d),f&&f.apply(g,e)):f&&f.apply(this.children[h],e)}},b.Group.prototype.preUpdate=function(){if(!this.exists||!this.parent.exists)return this.renderOrderID=-1,!1;for(var a=this.children.length;a--;)this.children[a].preUpdate();return!0},b.Group.prototype.update=function(){for(var a=this.children.length;a--;)this.children[a].update()},b.Group.prototype.postUpdate=function(){1===this._cache[7]&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y);for(var a=this.children.length;a--;)this.children[a].postUpdate()},b.Group.prototype.forEach=function(a,b,c){"undefined"==typeof c&&(c=!1);var d=Array.prototype.splice.call(arguments,3);d.unshift(null);for(var e=0,f=this.children.length;f>e;e++)(!c||c&&this.children[e].exists)&&(d[0]=this.children[e],a.apply(b,d))},b.Group.prototype.forEachExists=function(a,c){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("exists",!0,b.Group.RETURN_TOTAL,a,c,d)},b.Group.prototype.forEachAlive=function(a,c){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!0,b.Group.RETURN_TOTAL,a,c,d)},b.Group.prototype.forEachDead=function(a,c){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!1,b.Group.RETURN_TOTAL,a,c,d)},b.Group.prototype.sort=function(a,c){"undefined"==typeof a&&(a="y"),"undefined"==typeof c&&(c=b.Group.SORT_ASCENDING)},b.Group.prototype.sortHandler=function(){},b.Group.prototype.iterate=function(a,c,d,e,f,g){if(d===b.Group.RETURN_TOTAL&&0===this.children.length)return 0;"undefined"==typeof e&&(e=!1);for(var h=0,i=0,j=this.children.length;j>i;i++)if(this.children[i][a]===c&&(h++,e&&(g[0]=this.children[i],e.apply(f,g)),d===b.Group.RETURN_CHILD))return this.children[i];return d===b.Group.RETURN_TOTAL?h:d===b.Group.RETURN_CHILD?null:void 0},b.Group.prototype.getFirstExists=function(a){return"boolean"!=typeof a&&(a=!0),this.iterate("exists",a,b.Group.RETURN_CHILD)},b.Group.prototype.getFirstAlive=function(){return this.iterate("alive",!0,b.Group.RETURN_CHILD)},b.Group.prototype.getFirstDead=function(){return this.iterate("alive",!1,b.Group.RETURN_CHILD)},b.Group.prototype.countLiving=function(){return this.iterate("alive",!0,b.Group.RETURN_TOTAL)},b.Group.prototype.countDead=function(){return this.iterate("alive",!1,b.Group.RETURN_TOTAL)},b.Group.prototype.getRandom=function(a,b){return 0===this.children.length?null:(a=a||0,b=b||this.children.length,this.game.math.getRandom(this.children,a,b))},b.Group.prototype.remove=function(a){return 0!==this.children.length?(a.events&&a.events.onRemovedFromGroup.dispatch(a,this),this.removeChild(a),this.cursor===a&&this.next(),!0):void 0},b.Group.prototype.removeAll=function(){if(0!==this.children.length){do this.children[0].events&&this.children[0].events.onRemovedFromGroup.dispatch(this.children[0],this),this.removeChild(this.children[0]);while(this.children.length>0);this.cursor=null}},b.Group.prototype.removeBetween=function(a,b){if(0!==this.children.length){if(a>b||0>a||b>this.children.length)return!1;for(var c=a;b>c;c++)this.children[c].events&&this.children[c].events.onRemovedFromGroup.dispatch(this.children[c],this),this.removeChild(this.children[c]),this.cursor===child&&(this.cursor=null)}},b.Group.prototype.destroy=function(a){if(null!==this.game){if("undefined"==typeof a&&(a=!0),a){if(this.children.length>0)do this.children[0].parent&&this.children[0].destroy(a);while(this.children.length>0)}else this.removeAll();this.parent.removeChild(this),this.game=null,this.exists=!1,this.cursor=null}},Object.defineProperty(b.Group.prototype,"total",{get:function(){return this.iterate("exists",!0,b.Group.RETURN_TOTAL)}}),Object.defineProperty(b.Group.prototype,"length",{get:function(){return this.children.length}}),Object.defineProperty(b.Group.prototype,"angle",{get:function(){return b.Math.radToDeg(this.rotation)},set:function(a){this.rotation=b.Math.degToRad(a)}}),Object.defineProperty(b.Group.prototype,"fixedToCamera",{get:function(){return!!this._cache[7]},set:function(a){a?(this._cache[7]=1,this.cameraOffset.set(this.x,this.y)):this._cache[7]=0}}),b.World=function(a){b.Group.call(this,a,null,"__world",!1),this.bounds=new b.Rectangle(0,0,a.width,a.height),this.camera=null},b.World.prototype=Object.create(b.Group.prototype),b.World.prototype.constructor=b.World,b.World.prototype.boot=function(){this.camera=new b.Camera(this.game,0,0,0,this.game.width,this.game.height),this.camera.displayObject=this,this.camera.scale=this.scale,this.game.camera=this.camera,this.game.stage.addChild(this)},b.World.prototype.setBounds=function(a,b,c,d){cwindow.outerHeight&&(this.orientation=90),this.scaleFactor=new b.Point(1,1),this.scaleFactorInversed=new b.Point(1,1),this.margin=new b.Point(0,0),this.aspectRatio=0,this.sourceAspectRatio=c/d,this.event=null,this.scaleMode=b.ScaleManager.NO_SCALE,this.fullScreenScaleMode=b.ScaleManager.NO_SCALE,this._startHeight=0,this._width=0,this._height=0;var e=this;window.addEventListener("orientationchange",function(a){return e.checkOrientation(a)},!1),window.addEventListener("resize",function(a){return e.checkResize(a)},!1),document.addEventListener("webkitfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("mozfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("fullscreenchange",function(a){return e.fullScreenChange(a)},!1)},b.ScaleManager.EXACT_FIT=0,b.ScaleManager.NO_SCALE=1,b.ScaleManager.SHOW_ALL=2,b.ScaleManager.prototype={startFullScreen:function(a){!this.isFullScreen&&this.game.device.fullscreen&&("undefined"!=typeof a&&this.game.renderType===b.CANVAS&&(this.game.stage.smoothed=a),this._width=this.width,this._height=this.height,this.game.device.fullscreenKeyboard?this.fullScreenTarget[this.game.device.requestFullscreen](Element.ALLOW_KEYBOARD_INPUT):this.fullScreenTarget[this.game.device.requestFullscreen]())},stopFullScreen:function(){this.fullScreenTarget[this.game.device.cancelFullscreen]()},fullScreenChange:function(a){this.event=a,this.isFullScreen?(this.fullScreenScaleMode===b.ScaleManager.EXACT_FIT?(this.fullScreenTarget.style.width="100%",this.fullScreenTarget.style.height="100%",this.width=window.outerWidth,this.height=window.outerHeight,this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height,this.checkResize()):this.fullScreenScaleMode===b.ScaleManager.SHOW_ALL&&(this.setShowAll(),this.refresh()),this.enterFullScreen.dispatch(this.width,this.height)):(this.fullScreenTarget.style.width=this.game.width+"px",this.fullScreenTarget.style.height=this.game.height+"px",this.width=this._width,this.height=this._height,this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height,this.leaveFullScreen.dispatch(this.width,this.height))},forceOrientation:function(a,b,c){"undefined"==typeof b&&(b=!1),this.forceLandscape=a,this.forcePortrait=b,"undefined"!=typeof c&&((null==c||this.game.cache.checkImageKey(c)===!1)&&(c="__default"),this.orientationSprite=new PIXI.Sprite(PIXI.TextureCache[c]),this.orientationSprite.anchor.x=.5,this.orientationSprite.anchor.y=.5,this.orientationSprite.position.x=this.game.width/2,this.orientationSprite.position.y=this.game.height/2,this.checkOrientationState(),this.incorrectOrientation?(this.orientationSprite.visible=!0,this.game.world.visible=!1):(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.game.stage.addChild(this.orientationSprite))},checkOrientationState:function(){this.incorrectOrientation?(this.forceLandscape&&window.innerWidth>window.innerHeight||this.forcePortrait&&window.innerHeight>window.innerWidth)&&(this.incorrectOrientation=!1,this.leaveIncorrectOrientation.dispatch(),this.orientationSprite&&(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.scaleMode!==b.ScaleManager.NO_SCALE&&this.refresh()):(this.forceLandscape&&window.innerWidthwindow.outerHeight?90:0,this.isLandscape?this.enterLandscape.dispatch(this.orientation,!0,!1):this.enterPortrait.dispatch(this.orientation,!1,!0),this.scaleMode!==b.ScaleManager.NO_SCALE&&this.refresh(),this.checkOrientationState()},refresh:function(){if(this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),null==this._check&&this.maxIterations>0){this._iterations=this.maxIterations;var a=this;this._check=window.setInterval(function(){return a.setScreenSize()},10),this.setScreenSize()}},setScreenSize:function(a){"undefined"==typeof a&&(a=!1),this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),this._iterations--,(a||window.innerHeight>this._startHeight||this._iterations<0)&&(document.documentElement.style.minHeight=window.innerHeight+"px",this.incorrectOrientation===!0?this.setMaximum():this.isFullScreen?this.fullScreenScaleMode==b.ScaleManager.EXACT_FIT?this.setExactFit():this.fullScreenScaleMode==b.ScaleManager.SHOW_ALL&&this.setShowAll():this.scaleMode==b.ScaleManager.EXACT_FIT?this.setExactFit():this.scaleMode==b.ScaleManager.SHOW_ALL&&this.setShowAll(),this.setSize(),clearInterval(this._check),this._check=null)},setSize:function(){this.incorrectOrientation===!1&&(this.maxWidth&&this.width>this.maxWidth&&(this.width=this.maxWidth),this.maxHeight&&this.height>this.maxHeight&&(this.height=this.maxHeight),this.minWidth&&this.widththis.maxWidth?this.maxWidth:a,this.height=this.maxHeight&&b>this.maxHeight?this.maxHeight:b}},b.ScaleManager.prototype.constructor=b.ScaleManager,Object.defineProperty(b.ScaleManager.prototype,"isFullScreen",{get:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement}}),Object.defineProperty(b.ScaleManager.prototype,"isPortrait",{get:function(){return 0===this.orientation||180==this.orientation}}),Object.defineProperty(b.ScaleManager.prototype,"isLandscape",{get:function(){return 90===this.orientation||-90===this.orientation}}),b.Game=function(a,c,d,e,f,g,h,i){this.id=b.GAMES.push(this)-1,this.config=null,this.physicsConfig=i,this.parent="",this.width=800,this.height=600,this.transparent=!1,this.antialias=!0,this.renderer=b.AUTO,this.renderType=b.AUTO,this.state=null,this.isBooted=!1,this.isRunning=!1,this.raf=null,this.add=null,this.make=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.net=null,this.scale=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.physics=null,this.rnd=null,this.device=null,this.camera=null,this.canvas=null,this.context=null,this.debug=null,this.particles=null,this.stepping=!1,this.pendingStep=!1,this.stepCount=0,this._paused=!1,this._codePaused=!1,1===arguments.length&&"object"==typeof arguments[0]?this.parseConfig(arguments[0]):("undefined"!=typeof a&&(this.width=a),"undefined"!=typeof c&&(this.height=c),"undefined"!=typeof d&&(this.renderer=d,this.renderType=d),"undefined"!=typeof e&&(this.parent=e),"undefined"!=typeof g&&(this.transparent=g),"undefined"!=typeof h&&(this.antialias=h),this.state=new b.StateManager(this,f));var j=this;return this._onBoot=function(){return j.boot()},"complete"===document.readyState||"interactive"===document.readyState?window.setTimeout(this._onBoot,0):(document.addEventListener("DOMContentLoaded",this._onBoot,!1),window.addEventListener("load",this._onBoot,!1)),this},b.Game.prototype={parseConfig:function(a){this.config=a,a.width&&(this.width=b.Utils.parseDimension(a.width,0)),a.height&&(this.height=b.Utils.parseDimension(a.height,1)),a.renderer&&(this.renderer=a.renderer,this.renderType=a.renderer),a.parent&&(this.parent=a.parent),a.transparent&&(this.transparent=a.transparent),a.antialias&&(this.antialias=a.antialias),a.physicsConfig&&(this.physicsConfig=a.physicsConfig);var c=null;a.state&&(c=a.state),this.state=new b.StateManager(this,c)},boot:function(){this.isBooted||(document.body?(document.removeEventListener("DOMContentLoaded",this._onBoot),window.removeEventListener("load",this._onBoot),this.onPause=new b.Signal,this.onResume=new b.Signal,this.isBooted=!0,this.device=new b.Device(this),this.math=b.Math,this.rnd=new b.RandomDataGenerator([(Date.now()*Math.random()).toString()]),this.stage=new b.Stage(this,this.width,this.height),this.scale=new b.ScaleManager(this,this.width,this.height),this.setUpRenderer(),this.device.checkFullScreenSupport(),this.world=new b.World(this),this.add=new b.GameObjectFactory(this),this.make=new b.GameObjectCreator(this),this.cache=new b.Cache(this),this.load=new b.Loader(this),this.time=new b.Time(this),this.tweens=new b.TweenManager(this),this.input=new b.Input(this),this.sound=new b.SoundManager(this),this.physics=new b.Physics(this,this.physicsConfig),this.particles=new b.Particles(this),this.plugins=new b.PluginManager(this,this),this.net=new b.Net(this),this.debug=new b.Utils.Debug(this),this.time.boot(),this.stage.boot(),this.world.boot(),this.input.boot(),this.sound.boot(),this.state.boot(),this.debug.boot(),this.showDebugHeader(),this.isRunning=!0,this.raf=this.config&&this.config.forceSetTimeOut?new b.RequestAnimationFrame(this,this.config.forceSetTimeOut):new b.RequestAnimationFrame(this,!1),this.raf.start()):window.setTimeout(this._onBoot,20))},showDebugHeader:function(){var a=b.DEV_VERSION,c="Canvas",d="HTML Audio";if(this.renderType==b.WEBGL?c="WebGL":this.renderType==b.HEADLESS&&(c="Headless"),this.device.webAudio&&(d="WebAudio"),this.device.chrome){var e=["%c %c %c Phaser v"+a+" - Renderer: "+c+" - Audio: "+d+" %c %c ","background: #00bff3","background: #0072bc","color: #ffffff; background: #003471","background: #0072bc","background: #00bff3"];console.log.apply(console,e)}else console.log("Phaser v"+a+" - Renderer: "+c+" - Audio: "+d)},setUpRenderer:function(){if(this.device.trident&&(this.renderType=b.CANVAS),this.renderType===b.HEADLESS||this.renderType===b.CANVAS||this.renderType===b.AUTO&&this.device.webGL===!1){if(!this.device.canvas)throw new Error("Phaser.Game - cannot create Canvas or WebGL context, aborting.");this.renderType===b.AUTO&&(this.renderType=b.CANVAS),this.renderer=new PIXI.CanvasRenderer(this.width,this.height,this.canvas,this.transparent),this.context=this.renderer.context}else this.renderType=b.WEBGL,this.renderer=new PIXI.WebGLRenderer(this.width,this.height,this.canvas,this.transparent,this.antialias),this.context=null;this.stage.smoothed=this.antialias,b.Canvas.addToDOM(this.canvas,this.parent,!0),b.Canvas.setTouchAction(this.canvas)},update:function(a){this.time.update(a),this._paused?(this.input.update(),this.renderType!==b.HEADLESS&&(this.renderer.render(this.stage),this.plugins.render(),this.state.render(),this.plugins.postRender())):(this.pendingStep||(this.stepping&&(this.pendingStep=!0),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.physics.update(),this.particles.update(),this.plugins.update(),this.stage.postUpdate(),this.plugins.postUpdate()),this.renderType!==b.HEADLESS&&(this.renderer.render(this.stage),this.plugins.render(),this.state.render(),this.plugins.postRender()))},enableStep:function(){this.stepping=!0,this.pendingStep=!1,this.stepCount=0},disableStep:function(){this.stepping=!1,this.pendingStep=!1},step:function(){this.pendingStep=!1,this.stepCount++},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=!1},gamePaused:function(a){this._paused||(this._paused=!0,this.time.gamePaused(a),this.sound.setMute(),this.onPause.dispatch(this))},gameResumed:function(a){this._paused&&!this._codePaused&&(this._paused=!1,this.time.gameResumed(a),this.input.reset(),this.sound.unsetMute(),this.onResume.dispatch(this))}},b.Game.prototype.constructor=b.Game,Object.defineProperty(b.Game.prototype,"paused",{get:function(){return this._paused},set:function(a){a===!0?this._paused===!1&&(this._paused=!0,this._codePaused=!0,this.sound.mute=!0,this.time.gamePaused(),this.onPause.dispatch(this)):this._paused&&(this._paused=!1,this._codePaused=!1,this.input.reset(),this.sound.mute=!1,this.time.gameResumed(),this.onResume.dispatch(this))}}),b.Input=function(a){this.game=a,this.hitCanvas=null,this.hitContext=null,this.moveCallback=null,this.moveCallbackContext=this,this.pollRate=0,this.disabled=!1,this.multiInputOverride=b.Input.MOUSE_TOUCH_COMBINE,this.position=null,this.speed=null,this.circle=null,this.scale=null,this.maxPointers=10,this.currentPointers=0,this.tapRate=200,this.doubleTapRate=300,this.holdRate=2e3,this.justPressedRate=200,this.justReleasedRate=200,this.recordPointerHistory=!1,this.recordRate=100,this.recordLimit=100,this.pointer1=null,this.pointer2=null,this.pointer3=null,this.pointer4=null,this.pointer5=null,this.pointer6=null,this.pointer7=null,this.pointer8=null,this.pointer9=null,this.pointer10=null,this.activePointer=null,this.mousePointer=null,this.mouse=null,this.keyboard=null,this.touch=null,this.mspointer=null,this.gamepad=null,this.gestures=null,this.onDown=null,this.onUp=null,this.onTap=null,this.onHold=null,this.interactiveItems=new b.LinkedList,this._localPoint=new b.Point,this._pollCounter=0,this._oldPosition=null,this._x=0,this._y=0 },b.Input.MOUSE_OVERRIDES_TOUCH=0,b.Input.TOUCH_OVERRIDES_MOUSE=1,b.Input.MOUSE_TOUCH_COMBINE=2,b.Input.prototype={boot:function(){this.mousePointer=new b.Pointer(this.game,0),this.pointer1=new b.Pointer(this.game,1),this.pointer2=new b.Pointer(this.game,2),this.mouse=new b.Mouse(this.game),this.keyboard=new b.Keyboard(this.game),this.touch=new b.Touch(this.game),this.mspointer=new b.MSPointer(this.game),this.gamepad=new b.Gamepad(this.game),this.gestures=new b.Gestures(this.game),this.onDown=new b.Signal,this.onUp=new b.Signal,this.onTap=new b.Signal,this.onHold=new b.Signal,this.scale=new b.Point(1,1),this.speed=new b.Point,this.position=new b.Point,this._oldPosition=new b.Point,this.circle=new b.Circle(0,0,44),this.activePointer=this.mousePointer,this.currentPointers=0,this.hitCanvas=document.createElement("canvas"),this.hitCanvas.width=1,this.hitCanvas.height=1,this.hitContext=this.hitCanvas.getContext("2d"),this.mouse.start(),this.keyboard.start(),this.touch.start(),this.mspointer.start(),this.mousePointer.active=!0},destroy:function(){this.mouse.stop(),this.keyboard.stop(),this.touch.stop(),this.mspointer.stop(),this.gamepad.stop(),this.gestures.stop(),this.moveCallback=null},setMoveCallback:function(a,b){this.moveCallback=a,this.moveCallbackContext=b},addPointer:function(){for(var a=0,c=10;c>0;c--)null===this["pointer"+c]&&(a=c);return 0===a?(console.warn("You can only have 10 Pointer objects"),null):(this["pointer"+a]=new b.Pointer(this.game,a),this["pointer"+a])},update:function(){return this.keyboard.update(),this.pollRate>0&&this._pollCounter=c;c++)this["pointer"+c]&&this["pointer"+c].reset();this.currentPointers=0,"none"!==this.game.canvas.style.cursor&&(this.game.canvas.style.cursor="inherit"),a===!0&&(this.onDown.dispose(),this.onUp.dispose(),this.onTap.dispose(),this.onHold.dispose(),this.onDown=new b.Signal,this.onUp=new b.Signal,this.onTap=new b.Signal,this.onHold=new b.Signal,this.interactiveItems.callAll("reset")),this._pollCounter=0}},resetSpeed:function(a,b){this._oldPosition.setTo(a,b),this.speed.setTo(0,0)},startPointer:function(a){if(this.maxPointers<10&&this.totalActivePointers==this.maxPointers)return null;if(this.pointer1.active===!1)return this.pointer1.start(a);if(this.pointer2.active===!1)return this.pointer2.start(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active===!1)return this["pointer"+b].start(a);return null},updatePointer:function(a){if(this.pointer1.active&&this.pointer1.identifier==a.identifier)return this.pointer1.move(a);if(this.pointer2.active&&this.pointer2.identifier==a.identifier)return this.pointer2.move(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active&&this["pointer"+b].identifier==a.identifier)return this["pointer"+b].move(a);return null},stopPointer:function(a){if(this.pointer1.active&&this.pointer1.identifier==a.identifier)return this.pointer1.stop(a);if(this.pointer2.active&&this.pointer2.identifier==a.identifier)return this.pointer2.stop(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active&&this["pointer"+b].identifier==a.identifier)return this["pointer"+b].stop(a);return null},getPointer:function(a){if(a=a||!1,this.pointer1.active==a)return this.pointer1;if(this.pointer2.active==a)return this.pointer2;for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active==a)return this["pointer"+b];return null},getPointerFromIdentifier:function(a){if(this.pointer1.identifier==a)return this.pointer1;if(this.pointer2.identifier==a)return this.pointer2;for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].identifier==a)return this["pointer"+b];return null},getLocalPosition:function(a,c,d){"undefined"==typeof d&&(d=new b.Point);var e=a.worldTransform,f=1/(e.a*e.d+e.b*-e.c);return d.setTo(e.d*f*c.x+-e.b*f*c.y+(e.ty*e.b-e.tx*e.d)*f,e.a*f*c.y+-e.c*f*c.x+(-e.ty*e.a+e.tx*e.c)*f)},hitTest:function(a,c,d){if(!a.worldVisible)return!1;if(this.getLocalPosition(a,c,this._localPoint),d.copyFrom(this._localPoint),a.hitArea&&a.hitArea.contains)return a.hitArea.contains(this._localPoint.x,this._localPoint.y)?!0:!1;if(a instanceof b.TileSprite){var e=a.width,f=a.height,g=-e*a.anchor.x;if(this._localPoint.x>g&&this._localPoint.xh&&this._localPoint.yg&&this._localPoint.xh&&this._localPoint.yi;i++)if(this.hitTest(a.children[i],c,d))return!0;return!1}},b.Input.prototype.constructor=b.Input,Object.defineProperty(b.Input.prototype,"x",{get:function(){return this._x},set:function(a){this._x=Math.floor(a)}}),Object.defineProperty(b.Input.prototype,"y",{get:function(){return this._y},set:function(a){this._y=Math.floor(a)}}),Object.defineProperty(b.Input.prototype,"pollLocked",{get:function(){return this.pollRate>0&&this._pollCounter=a;a++)this["pointer"+a]&&this["pointer"+a].active&&this.currentPointers++;return this.currentPointers}}),Object.defineProperty(b.Input.prototype,"worldX",{get:function(){return this.game.camera.view.x+this.x}}),Object.defineProperty(b.Input.prototype,"worldY",{get:function(){return this.game.camera.view.y+this.y}}),b.Key=function(a,c){this.game=a,this.isDown=!1,this.isUp=!0,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.timeDown=0,this.duration=0,this.timeUp=-2500,this.repeats=0,this.keyCode=c,this.onDown=new b.Signal,this.onHoldCallback=null,this.onHoldContext=null,this.onUp=new b.Signal},b.Key.prototype={update:function(){this.isDown&&(this.duration=this.game.time.now-this.timeDown,this.repeats++,this.onHoldCallback&&this.onHoldCallback.call(this.onHoldContext,this))},processKeyDown:function(a){this.isDown||(this.altKey=a.altKey,this.ctrlKey=a.ctrlKey,this.shiftKey=a.shiftKey,this.isDown=!0,this.isUp=!1,this.timeDown=this.game.time.now,this.duration=0,this.repeats=0,this.onDown.dispatch(this))},processKeyUp:function(){this.isUp||(this.isDown=!1,this.isUp=!0,this.timeUp=this.game.time.now,this.duration=this.game.time.now-this.timeDown,this.onUp.dispatch(this))},reset:function(){this.isDown=!1,this.isUp=!0,this.timeUp=this.game.time.now,this.duration=this.game.time.now-this.timeDown},justPressed:function(a){return"undefined"==typeof a&&(a=2500),this.isDown&&this.duration=this.game.input.holdRate&&((this.game.input.multiInputOverride==b.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==b.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==b.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&this.game.input.onHold.dispatch(this),this._holdSent=!0),this.game.input.recordPointerHistory&&this.game.time.now>=this._nextDrop&&(this._nextDrop=this.game.time.now+this.game.input.recordRate,this._history.push({x:this.position.x,y:this.position.y}),this._history.length>this.game.input.recordLimit&&this._history.shift()))},move:function(a,c){if(!this.game.input.pollLocked){if("undefined"==typeof c&&(c=!1),"undefined"!=typeof a.button&&(this.button=a.button),this.clientX=a.clientX,this.clientY=a.clientY,this.pageX=a.pageX,this.pageY=a.pageY,this.screenX=a.screenX,this.screenY=a.screenY,this.x=(this.pageX-this.game.stage.offset.x)*this.game.input.scale.x,this.y=(this.pageY-this.game.stage.offset.y)*this.game.input.scale.y,this.position.setTo(this.x,this.y),this.circle.x=this.x,this.circle.y=this.y,(this.game.input.multiInputOverride==b.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==b.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==b.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.activePointer=this,this.game.input.x=this.x,this.game.input.y=this.y,this.game.input.position.setTo(this.game.input.x,this.game.input.y),this.game.input.circle.x=this.game.input.x,this.game.input.circle.y=this.game.input.y),this.game.paused)return this;if(this.game.input.moveCallback&&this.game.input.moveCallback.call(this.game.input.moveCallbackContext,this,this.x,this.y),null!==this.targetObject&&this.targetObject.isDragged===!0)return this.targetObject.update(this)===!1&&(this.targetObject=null),this;if(this._highestRenderOrderID=Number.MAX_SAFE_INTEGER,this._highestRenderObject=null,this._highestInputPriorityID=-1,this.game.input.interactiveItems.total>0){var d=this.game.input.interactiveItems.next;do(d.pixelPerfectClick||d.pixelPerfectOver||d.priorityID>this._highestInputPriorityID||d.priorityID===this._highestInputPriorityID&&d.sprite._cache[3]=0&&this.duration<=this.game.input.tapRate&&(this.timeUp-this.previousTapTime0&&(this.active=!1),this.withinGame=!1,this.isDown=!1,this.isUp=!0,this.isMouse===!1&&this.game.input.currentPointers--,this.game.input.interactiveItems.total>0){var c=this.game.input.interactiveItems.next;do c&&c._releasedHandler(this),c=c.next;while(null!=c)}return this.targetObject&&this.targetObject._releasedHandler(this),this.targetObject=null,this},justPressed:function(a){return a=a||this.game.input.justPressedRate,this.isDown===!0&&this.timeDown+a>this.game.time.now},justReleased:function(a){return a=a||this.game.input.justReleasedRate,this.isUp===!0&&this.timeUp+a>this.game.time.now},reset:function(){this.isMouse===!1&&(this.active=!1),this.identifier=null,this.isDown=!1,this.isUp=!0,this.totalTouches=0,this._holdSent=!1,this._history.length=0,this._stateReset=!0,this.targetObject&&this.targetObject._releasedHandler(this),this.targetObject=null}},b.Pointer.prototype.constructor=b.Pointer,Object.defineProperty(b.Pointer.prototype,"duration",{get:function(){return this.isUp?-1:this.game.time.now-this.timeDown}}),Object.defineProperty(b.Pointer.prototype,"worldX",{get:function(){return this.game.world.camera.x+this.x}}),Object.defineProperty(b.Pointer.prototype,"worldY",{get:function(){return this.game.world.camera.y+this.y}}),b.Touch=function(a){this.game=a,this.disabled=!1,this.callbackContext=this.game,this.touchStartCallback=null,this.touchMoveCallback=null,this.touchEndCallback=null,this.touchEnterCallback=null,this.touchLeaveCallback=null,this.touchCancelCallback=null,this.preventDefault=!0,this.event=null,this._onTouchStart=null,this._onTouchMove=null,this._onTouchEnd=null,this._onTouchEnter=null,this._onTouchLeave=null,this._onTouchCancel=null,this._onTouchMove=null},b.Touch.prototype={start:function(){var a=this;this.game.device.touch&&(this._onTouchStart=function(b){return a.onTouchStart(b)},this._onTouchMove=function(b){return a.onTouchMove(b)},this._onTouchEnd=function(b){return a.onTouchEnd(b)},this._onTouchEnter=function(b){return a.onTouchEnter(b)},this._onTouchLeave=function(b){return a.onTouchLeave(b)},this._onTouchCancel=function(b){return a.onTouchCancel(b)},this.game.canvas.addEventListener("touchstart",this._onTouchStart,!1),this.game.canvas.addEventListener("touchmove",this._onTouchMove,!1),this.game.canvas.addEventListener("touchend",this._onTouchEnd,!1),this.game.canvas.addEventListener("touchenter",this._onTouchEnter,!1),this.game.canvas.addEventListener("touchleave",this._onTouchLeave,!1),this.game.canvas.addEventListener("touchcancel",this._onTouchCancel,!1))},consumeDocumentTouches:function(){this._documentTouchMove=function(a){a.preventDefault()},document.addEventListener("touchmove",this._documentTouchMove,!1)},onTouchStart:function(a){if(this.event=a,this.touchStartCallback&&this.touchStartCallback.call(this.callbackContext,a),!this.game.input.disabled&&!this.disabled){this.preventDefault&&a.preventDefault();for(var b=0;b0&&e>this.deadZone||0>e&&e<-this.deadZone?{axis:d,value:e}:{axis:d,value:0})}this._prevTimestamp=this._rawPad.timestamp}},connect:function(a){var b=!this._connected;this._index=a.index,this._connected=!0,this._rawPad=a,this._rawButtons=a.buttons,this._axes=a.axes,b&&this._padParent.onConnectCallback&&this._padParent.onConnectCallback.call(this._padParent.callbackContext,this._index),b&&this.onConnectCallback&&this.onConnectCallback.call(this.callbackContext)},disconnect:function(){var a=this._connected;this._connected=!1,this._rawPad=void 0,this._rawButtons=[],this._buttons=[];var b=this._index;this._index=null,a&&this._padParent.onDisconnectCallback&&this._padParent.onDisconnectCallback.call(this._padParent.callbackContext,b),a&&this.onDisconnectCallback&&this.onDisconnectCallback.call(this.callbackContext)},processAxisChange:function(a){this.game.input.disabled||this.game.input.gamepad.disabled||this._axes[a.axis]!==a.value&&(this._axes[a.axis]=a.value,this._padParent.onAxisCallback&&this._padParent.onAxisCallback.call(this._padParent.callbackContext,a,this._index),this.onAxisCallback&&this.onAxisCallback.call(this.callbackContext,a))},processButtonDown:function(a,b){this.game.input.disabled||this.game.input.gamepad.disabled||(this._padParent.onDownCallback&&this._padParent.onDownCallback.call(this._padParent.callbackContext,a,b,this._index),this.onDownCallback&&this.onDownCallback.call(this.callbackContext,a,b),this._buttons[a]&&this._buttons[a].isDown?this._buttons[a].duration=this.game.time.now-this._buttons[a].timeDown:this._buttons[a]?(this._buttons[a].isDown=!0,this._buttons[a].timeDown=this.game.time.now,this._buttons[a].duration=0,this._buttons[a].value=b):this._buttons[a]={isDown:!0,timeDown:this.game.time.now,timeUp:0,duration:0,value:b},this._hotkeys[a]&&this._hotkeys[a].processButtonDown(b))},processButtonUp:function(a,b){this.game.input.disabled||this.game.input.gamepad.disabled||(this._padParent.onUpCallback&&this._padParent.onUpCallback.call(this._padParent.callbackContext,a,b,this._index),this.onUpCallback&&this.onUpCallback.call(this.callbackContext,a,b),this._hotkeys[a]&&this._hotkeys[a].processButtonUp(b),this._buttons[a]?(this._buttons[a].isDown=!1,this._buttons[a].timeUp=this.game.time.now,this._buttons[a].value=b):this._buttons[a]={isDown:!1,timeDown:this.game.time.now,timeUp:this.game.time.now,duration:0,value:b})},processButtonFloat:function(a,b){this.game.input.disabled||this.game.input.gamepad.disabled||(this._padParent.onFloatCallback&&this._padParent.onFloatCallback.call(this._padParent.callbackContext,a,b,this._index),this.onFloatCallback&&this.onFloatCallback.call(this.callbackContext,a,b),this._buttons[a]?this._buttons[a].value=b:this._buttons[a]={value:b},this._hotkeys[a]&&this._hotkeys[a].processButtonFloat(b))},axis:function(a){return this._axes[a]?this._axes[a]:!1},isDown:function(a){return this._buttons[a]?this._buttons[a].isDown:!1},justReleased:function(a,b){return"undefined"==typeof b&&(b=250),this._buttons[a]&&this._buttons[a].isDown===!1&&this.game.time.now-this._buttons[a].timeUpd;d++)this._pointerData[d]={id:d,x:0,y:0,isDown:!1,isUp:!1,isOver:!1,isOut:!1,timeOver:0,timeOut:0,timeDown:0,timeUp:0,downDuration:0,isDragged:!1};this.snapOffset=new b.Point,this.enabled=!0,this.sprite.events&&null===this.sprite.events.onInputOver&&(this.sprite.events.onInputOver=new b.Signal,this.sprite.events.onInputOut=new b.Signal,this.sprite.events.onInputDown=new b.Signal,this.sprite.events.onInputUp=new b.Signal,this.sprite.events.onDragStart=new b.Signal,this.sprite.events.onDragStop=new b.Signal)}return this.sprite},reset:function(){this.enabled=!1;for(var a=0;10>a;a++)this._pointerData[a]={id:a,x:0,y:0,isDown:!1,isUp:!1,isOver:!1,isOut:!1,timeOver:0,timeOut:0,timeDown:0,timeUp:0,downDuration:0,isDragged:!1}},stop:function(){this.enabled!==!1&&(this.enabled=!1,this.game.input.interactiveItems.remove(this))},destroy:function(){this.enabled&&(this.enabled=!1,this.game.input.interactiveItems.remove(this),this._pointerData.length=0,this.boundsRect=null,this.boundsSprite=null,this.sprite=null)},pointerX:function(a){return a=a||0,this._pointerData[a].x},pointerY:function(a){return a=a||0,this._pointerData[a].y},pointerDown:function(a){return a=a||0,this._pointerData[a].isDown},pointerUp:function(a){return a=a||0,this._pointerData[a].isUp},pointerTimeDown:function(a){return a=a||0,this._pointerData[a].timeDown},pointerTimeUp:function(a){return a=a||0,this._pointerData[a].timeUp},pointerOver:function(a){if(this.enabled){if("undefined"!=typeof a)return this._pointerData[a].isOver;for(var b=0;10>b;b++)if(this._pointerData[b].isOver)return!0}return!1},pointerOut:function(a){if(this.enabled){if("undefined"!=typeof a)return this._pointerData[a].isOut;for(var b=0;10>b;b++)if(this._pointerData[b].isOut)return!0}return!1},pointerTimeOver:function(a){return a=a||0,this._pointerData[a].timeOver},pointerTimeOut:function(a){return a=a||0,this._pointerData[a].timeOut},pointerDragged:function(a){return a=a||0,this._pointerData[a].isDragged},checkPointerDown:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.parent.visible===!1?!1:this.game.input.hitTest(this.sprite,a,this._tempPoint)?this.pixelPerfectClick?this.checkPixel(this._tempPoint.x,this._tempPoint.y):!0:!1},checkPointerOver:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.parent.visible===!1?!1:this.game.input.hitTest(this.sprite,a,this._tempPoint)?this.pixelPerfectOver?this.checkPixel(this._tempPoint.x,this._tempPoint.y):!0:!1},checkPixel:function(a,b,c){if(this.sprite.texture.baseTexture.source){if(this.game.input.hitContext.clearRect(0,0,1,1),null===a&&null===b){this.game.input.getLocalPosition(this.sprite,c,this._tempPoint);var a=this._tempPoint.x,b=this._tempPoint.y}0!==this.sprite.anchor.x&&(a-=-this.sprite.texture.frame.width*this.sprite.anchor.x),0!==this.sprite.anchor.y&&(b-=-this.sprite.texture.frame.height*this.sprite.anchor.y),a+=this.sprite.texture.frame.x,b+=this.sprite.texture.frame.y,this.game.input.hitContext.drawImage(this.sprite.texture.baseTexture.source,a,b,1,1,0,0,1,1);var d=this.game.input.hitContext.getImageData(0,0,1,1);if(d.data[3]>=this.pixelPerfectAlpha)return!0}return!1},update:function(a){return null!==this.sprite?this.enabled&&this.sprite.visible&&this.sprite.parent.visible?this.draggable&&this._draggedPointerID==a.id?this.updateDrag(a):this._pointerData[a.id].isOver===!0?this.checkPointerOver(a)?(this._pointerData[a.id].x=a.x-this.sprite.x,this._pointerData[a.id].y=a.y-this.sprite.y,!0):(this._pointerOutHandler(a),!1):void 0:(this._pointerOutHandler(a),!1):void 0},_pointerOverHandler:function(a){null!==this.sprite&&this._pointerData[a.id].isOver===!1&&(this._pointerData[a.id].isOver=!0,this._pointerData[a.id].isOut=!1,this._pointerData[a.id].timeOver=this.game.time.now,this._pointerData[a.id].x=a.x-this.sprite.x,this._pointerData[a.id].y=a.y-this.sprite.y,this.useHandCursor&&this._pointerData[a.id].isDragged===!1&&(this.game.canvas.style.cursor="pointer"),this.sprite.events.onInputOver.dispatch(this.sprite,a))},_pointerOutHandler:function(a){null!==this.sprite&&(this._pointerData[a.id].isOver=!1,this._pointerData[a.id].isOut=!0,this._pointerData[a.id].timeOut=this.game.time.now,this.useHandCursor&&this._pointerData[a.id].isDragged===!1&&(this.game.canvas.style.cursor="default"),this.sprite&&this.sprite.events&&this.sprite.events.onInputOut.dispatch(this.sprite,a))},_touchedHandler:function(a){if(null!==this.sprite){if(this._pointerData[a.id].isDown===!1&&this._pointerData[a.id].isOver===!0){if(this.pixelPerfectClick&&!this.checkPixel(null,null,a))return;this._pointerData[a.id].isDown=!0,this._pointerData[a.id].isUp=!1,this._pointerData[a.id].timeDown=this.game.time.now,this.sprite.events.onInputDown.dispatch(this.sprite,a),this.draggable&&this.isDragged===!1&&this.startDrag(a),this.bringToTop&&this.sprite.bringToTop()}return this.consumePointerEvent}},_releasedHandler:function(a){null!==this.sprite&&this._pointerData[a.id].isDown&&a.isUp&&(this._pointerData[a.id].isDown=!1,this._pointerData[a.id].isUp=!0,this._pointerData[a.id].timeUp=this.game.time.now,this._pointerData[a.id].downDuration=this._pointerData[a.id].timeUp-this._pointerData[a.id].timeDown,this.checkPointerOver(a)?this.sprite.events.onInputUp.dispatch(this.sprite,a,!0):(this.sprite.events.onInputUp.dispatch(this.sprite,a,!1),this.useHandCursor&&(this.game.canvas.style.cursor="default")),this.draggable&&this.isDragged&&this._draggedPointerID==a.id&&this.stopDrag(a))},updateDrag:function(a){return a.isUp?(this.stopDrag(a),!1):(this.sprite.fixedToCamera?(this.allowHorizontalDrag&&(this.sprite.cameraOffset.x=a.x+this._dragPoint.x+this.dragOffset.x),this.allowVerticalDrag&&(this.sprite.cameraOffset.y=a.y+this._dragPoint.y+this.dragOffset.y),this.boundsRect&&this.checkBoundsRect(),this.boundsSprite&&this.checkBoundsSprite(),this.snapOnDrag&&(this.sprite.cameraOffset.x=Math.round((this.sprite.cameraOffset.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.cameraOffset.y=Math.round((this.sprite.cameraOffset.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY)):(this.allowHorizontalDrag&&(this.sprite.x=a.x+this._dragPoint.x+this.dragOffset.x),this.allowVerticalDrag&&(this.sprite.y=a.y+this._dragPoint.y+this.dragOffset.y),this.boundsRect&&this.checkBoundsRect(),this.boundsSprite&&this.checkBoundsSprite(),this.snapOnDrag&&(this.sprite.x=Math.round((this.sprite.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.y=Math.round((this.sprite.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY)),!0)},justOver:function(a,b){return a=a||0,b=b||500,this._pointerData[a].isOver&&this.overDuration(a)a;a++)this._pointerData[a].isDragged=!1;this.draggable=!1,this.isDragged=!1,this._draggedPointerID=-1},startDrag:function(a){this.isDragged=!0,this._draggedPointerID=a.id,this._pointerData[a.id].isDragged=!0,this.sprite.fixedToCamera?this.dragFromCenter?(this.sprite.centerOn(a.x,a.y),this._dragPoint.setTo(this.sprite.cameraOffset.x-a.x,this.sprite.cameraOffset.y-a.y)):this._dragPoint.setTo(this.sprite.cameraOffset.x-a.x,this.sprite.cameraOffset.y-a.y):this.dragFromCenter?(this.sprite.centerOn(a.x,a.y),this._dragPoint.setTo(this.sprite.x-a.x,this.sprite.y-a.y)):this._dragPoint.setTo(this.sprite.x-a.x,this.sprite.y-a.y),this.updateDrag(a),this.bringToTop&&this.sprite.bringToTop(),this.sprite.events.onDragStart.dispatch(this.sprite,a)},stopDrag:function(a){this.isDragged=!1,this._draggedPointerID=-1,this._pointerData[a.id].isDragged=!1,this.snapOnRelease&&(this.sprite.fixedToCamera?(this.sprite.cameraOffset.x=Math.round((this.sprite.cameraOffset.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.cameraOffset.y=Math.round((this.sprite.cameraOffset.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY):(this.sprite.x=Math.round((this.sprite.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.y=Math.round((this.sprite.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY)),this.sprite.events.onDragStop.dispatch(this.sprite,a),this.checkPointerOver(a)===!1&&this._pointerOutHandler(a)},setDragLock:function(a,b){"undefined"==typeof a&&(a=!0),"undefined"==typeof b&&(b=!0),this.allowHorizontalDrag=a,this.allowVerticalDrag=b},enableSnap:function(a,b,c,d,e,f){"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=0),"undefined"==typeof f&&(f=0),this.snapX=a,this.snapY=b,this.snapOffsetX=e,this.snapOffsetY=f,this.snapOnDrag=c,this.snapOnRelease=d},disableSnap:function(){this.snapOnDrag=!1,this.snapOnRelease=!1},checkBoundsRect:function(){this.sprite.fixedToCamera?(this.sprite.cameraOffset.xthis.boundsRect.right&&(this.sprite.cameraOffset.x=this.boundsRect.right-this.sprite.width),this.sprite.cameraOffset.ythis.boundsRect.bottom&&(this.sprite.cameraOffset.y=this.boundsRect.bottom-this.sprite.height)):(this.sprite.xthis.boundsRect.right&&(this.sprite.x=this.boundsRect.right-this.sprite.width),this.sprite.ythis.boundsRect.bottom&&(this.sprite.y=this.boundsRect.bottom-this.sprite.height))},checkBoundsSprite:function(){this.sprite.fixedToCamera&&this.boundsSprite.fixedToCamera?(this.sprite.cameraOffset.xthis.boundsSprite.camerOffset.x+this.boundsSprite.width&&(this.sprite.cameraOffset.x=this.boundsSprite.camerOffset.x+this.boundsSprite.width-this.sprite.width),this.sprite.cameraOffset.ythis.boundsSprite.camerOffset.y+this.boundsSprite.height&&(this.sprite.cameraOffset.y=this.boundsSprite.camerOffset.y+this.boundsSprite.height-this.sprite.height)):(this.sprite.xthis.boundsSprite.x+this.boundsSprite.width&&(this.sprite.x=this.boundsSprite.x+this.boundsSprite.width-this.sprite.width),this.sprite.ythis.boundsSprite.y+this.boundsSprite.height&&(this.sprite.y=this.boundsSprite.y+this.boundsSprite.height-this.sprite.height))}},b.InputHandler.prototype.constructor=b.InputHandler,b.Gestures=function(a){this.game=a,this.active=!1,this._gestures=[],this._pointers=[],this.game.input.setMoveCallback(function(a){this.active&&this._updatePointerState(a)},this)},b.Gestures.prototype={add:function(a,b){this.add(a,b,null,null)},add:function(a,b,c,d){var e={gesture:new a,hasStarted:!1,onGestureStarted:c,onGestureUpdated:b,onGestureStopped:d};this._gestures.push(e)},remove:function(a){for(var b=this._gestures.length-1;b>=0;--b)this._gestures[b].gesture.name==(new a).name&&delete this._gestures[b];this._gestures=this._gestures.filter(function(a){return"undefined"!=typeof a})},update:function(){if(this.active&&this._pointers.length>0){for(var a=this._pointers.filter(function(a){return a.isDown}).length>0,b=this._gestures.length-1;b>=0;--b)if(this._gestures[b].hasStarted){var c=this._gestures[b].gesture.update(this._pointers);if(c){var d=this._gestures[b].gesture.getData();null!=this._gestures[b].onGestureUpdated&&this._gestures[b].onGestureUpdated(d)}a||(this._gestures[b].gesture.stop(this._pointers),this._gestures[b].hasStarted=!1,null!=this._gestures[b].onGestureStopped&&this._gestures[b].onGestureStopped())}else this._gestures[b].hasStarted=!0,this._gestures[b].gesture.start(this._pointers),null!=this._gestures[b].onGestureStarted&&this._gestures[b].onGestureStarted();this._pointers=this._pointers.filter(function(a){return a.isDown})}},_updatePointerState:function(a){for(var b=null,c=this._pointers.length-1;c>=0;--c)if(this._pointers[c].pointer==a){b=this._pointers[c];break}null==b&&a.isDown?(b={pointer:a,justPressed:!0,isUp:!1,isDown:!0},this._pointers.push(b)):null!=b&&(b.justPressed=!1,b.isDown=a.isDown,b.isUp=a.isUp)}},b.Gestures.prototype.constructor=b.Gestures,b.Gestures.Helpers={createOrFindPointerData:function(a,b){for(var c=null,d=a.length-1;d>=0;--d)if(a[d].pointer==b){c=a[d];break}return null==c&&(c={pointer:b,isNew:!0},a.push(c)),c}},b.Gesture={},b.Gesture.SwipeLeft=function(a){this.game=a,this.name="SwipeLeft",this._pointerData=[]},b.Gesture.SwipeLeft.prototype={_createOrFindPointerData:function(a){var c=b.Gestures.Helpers.createOrFindPointerData(this._pointerData,a);return c.isNew&&(c.isNew=!1,c.lastX=a.pointer.x,c.lastY=a.pointer.y,c.hasTriggered=!1),c},start:function(a){for(var b=a.length-1;b>=0;--b)this._createOrFindPointerData(a[b])},update:function(a){for(var b=a.length-1;b>=0;--b){var c=this._createOrFindPointerData(a[b]);if(c.pointer.isDown&&!c.hasTriggered){var d=a[b].pointer.x,e=c.lastX-d;if(c.lastX=d,e>100)return c.hasTriggered=!0,!0}}return!1},stop:function(){this._pointerData=[]},getData:function(){return{didSwipe:!0}}},b.Gesture.SwipeLeft.prototype.constructor=b.Gesture.SwipeLeft,b.Gesture.SwipeRight=function(a){this.game=a,this.name="SwipeRight",this._pointerData=[]},b.Gesture.SwipeRight.prototype={_createOrFindPointerData:function(a){var c=b.Gestures.Helpers.createOrFindPointerData(this._pointerData,a);return c.isNew&&(c.isNew=!1,c.lastX=a.pointer.x,c.lastY=a.pointer.y,c.hasTriggered=!1),c},start:function(a){for(var b=a.length-1;b>=0;--b)this._createOrFindPointerData(a[b])},update:function(a){for(var b=a.length-1;b>=0;--b){var c=this._createOrFindPointerData(a[b]);if(c.pointer.isDown&&!c.hasTriggered){var d=a[b].pointer.x,e=c.lastX-d;if(c.lastX=d,-100>e)return c.hasTriggered=!0,!0}}return!1},stop:function(){this._pointerData=[]},getData:function(){return{didSwipe:!0}}},b.Gesture.SwipeRight.prototype.constructor=b.Gesture.SwipeRight,b.Gesture.SwipeDown=function(a){this.game=a,this.name="SwipeDown",this._pointerData=[]},b.Gesture.SwipeDown.prototype={_createOrFindPointerData:function(a){var c=b.Gestures.Helpers.createOrFindPointerData(this._pointerData,a);return c.isNew&&(c.isNew=!1,c.lastX=a.pointer.x,c.lastY=a.pointer.y,c.hasTriggered=!1),c},start:function(a){for(var b=a.length-1;b>=0;--b)this._createOrFindPointerData(a[b])},update:function(a){for(var b=a.length-1;b>=0;--b){var c=this._createOrFindPointerData(a[b]);if(c.pointer.isDown&&!c.hasTriggered){var d=a[b].pointer.y,e=c.lastY-d;if(c.lastY=d,-100>e)return c.hasTriggered=!0,!0}}return!1},stop:function(){this._pointerData=[]},getData:function(){return{didSwipe:!0}}},b.Gesture.SwipeDown.prototype.constructor=b.Gesture.SwipeDown,b.Gesture.SwipeUp=function(a){this.game=a,this.name="SwipeUp",this._pointerData=[]},b.Gesture.SwipeUp.prototype={_createOrFindPointerData:function(a){var c=b.Gestures.Helpers.createOrFindPointerData(this._pointerData,a);return c.isNew&&(c.isNew=!1,c.lastX=a.pointer.x,c.lastY=a.pointer.y,c.hasTriggered=!1),c},start:function(a){for(var b=a.length-1;b>=0;--b)this._createOrFindPointerData(a[b])},update:function(a){for(var b=a.length-1;b>=0;--b){var c=this._createOrFindPointerData(a[b]);if(c.pointer.isDown&&!c.hasTriggered){var d=a[b].pointer.y,e=c.lastY-d;if(c.lastY=d,e>100)return c.hasTriggered=!0,!0}}return!1},stop:function(){this._pointerData=[]},getData:function(){return{didSwipe:!0}}},b.Gesture.SwipeUp.prototype.constructor=b.Gesture.SwipeUp,b.Events=function(a){this.parent=a,this.onAddedToGroup=new b.Signal,this.onRemovedFromGroup=new b.Signal,this.onKilled=new b.Signal,this.onRevived=new b.Signal,this.onOutOfBounds=new b.Signal,this.onInputOver=null,this.onInputOut=null,this.onInputDown=null,this.onInputUp=null,this.onDragStart=null,this.onDragStop=null,this.onAnimationStart=null,this.onAnimationComplete=null,this.onAnimationLoop=null},b.Events.prototype={destroy:function(){this.parent=null,this.onAddedToGroup.dispose(),this.onRemovedFromGroup.dispose(),this.onKilled.dispose(),this.onRevived.dispose(),this.onOutOfBounds.dispose(),this.onInputOver&&(this.onInputOver.dispose(),this.onInputOut.dispose(),this.onInputDown.dispose(),this.onInputUp.dispose(),this.onDragStart.dispose(),this.onDragStop.dispose()),this.onAnimationStart&&(this.onAnimationStart.dispose(),this.onAnimationComplete.dispose(),this.onAnimationLoop.dispose())}},b.Events.prototype.constructor=b.Events,b.GameObjectFactory=function(a){this.game=a,this.world=this.game.world},b.GameObjectFactory.prototype={existing:function(a){return this.world.add(a)},image:function(a,c,d,e,f){return"undefined"==typeof f&&(f=this.world),f.add(new b.Image(this.game,a,c,d,e))},sprite:function(a,b,c,d,e){return"undefined"==typeof e&&(e=this.world),e.create(a,b,c,d)},tween:function(a){return this.game.tweens.create(a)},group:function(a,c,d){return"undefined"==typeof c&&(c="group"),"undefined"==typeof d&&(d=!1),new b.Group(this.game,a,c,d)},spriteBatch:function(a,c,d){return"undefined"==typeof c&&(c="group"),"undefined"==typeof d&&(d=!1),new b.SpriteBatch(this.game,a,c,d)},audio:function(a,b,c,d){return this.game.sound.add(a,b,c,d)},sound:function(a,b,c,d){return this.game.sound.add(a,b,c,d)},tileSprite:function(a,c,d,e,f,g,h){return"undefined"==typeof h&&(h=this.world),h.add(new b.TileSprite(this.game,a,c,d,e,f,g))},text:function(a,c,d,e,f){return"undefined"==typeof f&&(f=this.world),f.add(new b.Text(this.game,a,c,d,e))},button:function(a,c,d,e,f,g,h,i,j,k){return"undefined"==typeof k&&(k=this.world),k.add(new b.Button(this.game,a,c,d,e,f,g,h,i,j))},graphics:function(a,c,d){return"undefined"==typeof d&&(d=this.world),d.add(new b.Graphics(this.game,a,c))},emitter:function(a,c,d){return this.game.particles.add(new b.Particles.Arcade.Emitter(this.game,a,c,d))},retroFont:function(a,c,d,e,f,g,h,i,j){return new b.RetroFont(this.game,a,c,d,e,f,g,h,i,j)},bitmapText:function(a,c,d,e,f,g){return"undefined"==typeof g&&(g=this.world),g.add(new b.BitmapText(this.game,a,c,d,e,f))},tilemap:function(a,c,d,e,f){return new b.Tilemap(this.game,a,c,d,e,f)},renderTexture:function(a,c,d,e){("undefined"==typeof d||""===d)&&(d=this.game.rnd.uuid()),"undefined"==typeof e&&(e=!1);var f=new b.RenderTexture(this.game,a,c,d);return e&&this.game.cache.addRenderTexture(d,f),f},bitmapData:function(a,c,d){"undefined"==typeof d&&(d=!1),("undefined"==typeof key||""===key)&&(key=this.game.rnd.uuid());var e=new b.BitmapData(this.game,key,a,c);return d&&this.game.cache.addBitmapData(key,e),e},filter:function(a){var c=Array.prototype.splice.call(arguments,1),a=new b.Filter[a](this.game);return a.init.apply(a,c),a}},b.GameObjectFactory.prototype.constructor=b.GameObjectFactory,b.GameObjectCreator=function(a){this.game=a,this.world=this.game.world},b.GameObjectCreator.prototype={image:function(a,c,d,e){return new b.Image(this.game,a,c,d,e)},sprite:function(a,c,d,e){return new b.Sprite(this.game,a,c,d,e)},tween:function(a){return new b.Tween(a,this.game)},group:function(a,c,d){return"undefined"==typeof c&&(c="group"),"undefined"==typeof d&&(d=!1),new b.Group(this.game,a,c,d)},spriteBatch:function(a,c,d){return"undefined"==typeof c&&(c="group"),"undefined"==typeof d&&(d=!1),new b.SpriteBatch(this.game,a,c,d)},audio:function(a,b,c,d){return this.game.sound.add(a,b,c,d)},sound:function(a,b,c,d){return this.game.sound.add(a,b,c,d)},tileSprite:function(a,c,d,e,f,g){return new b.TileSprite(this.game,a,c,d,e,f,g)},text:function(a,c,d,e){return new b.Text(this.game,a,c,d,e)},button:function(a,c,d,e,f,g,h,i,j){return new b.Button(this.game,a,c,d,e,f,g,h,i,j)},graphics:function(a,c){return new b.Graphics(this.game,a,c)},emitter:function(a,c,d){return new b.Particles.Arcade.Emitter(this.game,a,c,d)},retroFont:function(a,c,d,e,f,g,h,i,j){return new b.RetroFont(this.game,a,c,d,e,f,g,h,i,j)},bitmapText:function(a,c,d,e,f){return new b.BitmapText(this.game,a,c,d,e,f)},tilemap:function(a,c,d,e,f){return new b.Tilemap(this.game,a,c,d,e,f)},renderTexture:function(a,c,d,e){("undefined"==typeof d||""===d)&&(d=this.game.rnd.uuid()),"undefined"==typeof e&&(e=!1);var f=new b.RenderTexture(this.game,a,c,d);return e&&this.game.cache.addRenderTexture(d,f),f},bitmapData:function(a,c,d){"undefined"==typeof d&&(d=!1),("undefined"==typeof key||""===key)&&(key=this.game.rnd.uuid());var e=new b.BitmapData(this.game,key,a,c);return d&&this.game.cache.addBitmapData(key,e),e},filter:function(a){var c=Array.prototype.splice.call(arguments,1),a=new b.Filter[a](this.game);return a.init.apply(a,c),a}},b.GameObjectCreator.prototype.constructor=b.GameObjectCreator,b.BitmapData=function(a,c,d,e){"undefined"==typeof d&&(d=100),"undefined"==typeof e&&(e=100),this.game=a,this.key=c,this.width=d,this.height=e,this.canvas=b.Canvas.create(d,e,"",!0),this.context=this.canvas.getContext("2d"),this.ctx=this.context,this.imageData=this.context.getImageData(0,0,d,e),this.pixels=this.imageData.data.buffer?this.imageData.data.buffer:this.imageData.data,this.baseTexture=new PIXI.BaseTexture(this.canvas),this.texture=new PIXI.Texture(this.baseTexture),this.textureFrame=new b.Frame(0,0,0,d,e,"bitmapData",a.rnd.uuid()),this.type=b.BITMAPDATA,this._dirty=!1},b.BitmapData.prototype={add:function(a){if(Array.isArray(a))for(var b=0;b=0&&a<=this.width&&b>=0&&b<=this.height&&(this.pixels[b*this.width+a]=f<<24|e<<16|d<<8|c,this.context.putImageData(this.imageData,0,0),this._dirty=!0)},setPixel:function(a,b,c,d,e){this.setPixel32(a,b,c,d,e,255)},getPixel:function(a,b){return a>=0&&a<=this.width&&b>=0&&b<=this.height?this.data32[b*this.width+a]:void 0},getPixel32:function(a,b){return a>=0&&a<=this.width&&b>=0&&b<=this.height?this.data32[b*this.width+a]:void 0},getPixels:function(a){return this.context.getImageData(a.x,a.y,a.width,a.height)},copyPixels:function(a,b,c,d){"string"==typeof a&&(a=this.game.cache.getImage(a)),a&&this.context.drawImage(a,b.x,b.y,b.width,b.height,c,d,b.width,b.height)},draw:function(a,b,c){"string"==typeof a&&(a=this.game.cache.getImage(a)),a&&this.context.drawImage(a,0,0,a.width,a.height,b,c,a.width,a.height)},alphaMask:function(a,b){var c=this.context.globalCompositeOperation;"string"==typeof b&&(b=this.game.cache.getImage(b)),b&&this.context.drawImage(b,0,0),this.context.globalCompositeOperation="source-atop","string"==typeof a&&(a=this.game.cache.getImage(a)),a&&this.context.drawImage(a,0,0),this.context.globalCompositeOperation=c},render:function(){this._dirty&&(this.game.renderType===b.WEBGL&&PIXI.updateWebGLTexture(this.baseTexture,this.game.renderer.gl),this._dirty=!1)}},b.BitmapData.prototype.constructor=b.BitmapData,b.Sprite=function(a,c,d,e,f){c=c||0,d=d||0,e=e||null,f=f||null,this.game=a,this.name="",this.type=b.SPRITE,this.events=new b.Events(this),this.animations=new b.AnimationManager(this),this.key=e,this._frame=0,this._frameName="",PIXI.Sprite.call(this,PIXI.TextureCache.__default),this.loadTexture(e,f),this.position.set(c,d),this.world=new b.Point(c,d),this.autoCull=!1,this.input=null,this.body=null,this.health=1,this.lifespan=0,this.checkWorldBounds=!1,this.outOfBoundsKill=!1,this.debug=!1,this.cameraOffset=new b.Point,this._cache=new Int16Array([0,0,0,0,1,0,1,0]),this._bounds=new b.Rectangle},b.Sprite.prototype=Object.create(PIXI.Sprite.prototype),b.Sprite.prototype.constructor=b.Sprite,b.Sprite.prototype.preUpdate=function(){if(1===this._cache[4])return this.world.setTo(this.parent.position.x+this.position.x,this.parent.position.y+this.position.y),this.worldTransform.tx=this.world.x,this.worldTransform.ty=this.world.y,this._cache[0]=this.world.x,this._cache[1]=this.world.y,this._cache[2]=this.rotation,this._cache[4]=0,!1; -if(this._cache[0]=this.world.x,this._cache[1]=this.world.y,this._cache[2]=this.rotation,!this.exists||!this.parent.exists)return this._cache[3]=-1,!1;if(this.lifespan>0&&(this.lifespan-=this.game.time.elapsed,this.lifespan<=0))return this.kill(),!1;if((this.autoCull||this.checkWorldBounds)&&this._bounds.copyFrom(this.getBounds()),this.autoCull&&(this.renderable=this.game.world.camera.screenView.intersects(this._bounds)),this.checkWorldBounds)if(1===this._cache[5]&&this.game.world.bounds.intersects(this._bounds))this._cache[5]=0;else if(0===this._cache[5]&&!this.game.world.bounds.intersects(this._bounds)&&(this._cache[5]=1,this.events.onOutOfBounds.dispatch(this),this.outOfBoundsKill))return this.kill(),!1;this.world.setTo(this.game.camera.x+this.worldTransform.tx,this.game.camera.y+this.worldTransform.ty),this.visible&&(this._cache[3]=this.game.stage.currentRenderOrderID++),this.animations.update(),this.exists&&this.body&&this.body.preUpdate();for(var a=0,b=this.children.length;b>a;a++)this.children[a].preUpdate();return!0},b.Sprite.prototype.update=function(){},b.Sprite.prototype.postUpdate=function(){this.key instanceof b.BitmapData&&this.key._dirty&&this.key.render(),this.exists&&this.body&&this.body.postUpdate(),1===this._cache[7]&&(this.position.x=(this.game.camera.view.x+this.cameraOffset.x)/this.game.camera.scale.x,this.position.y=(this.game.camera.view.y+this.cameraOffset.y)/this.game.camera.scale.y);for(var a=0,c=this.children.length;c>a;a++)this.children[a].postUpdate()},b.Sprite.prototype.loadTexture=function(a,c){return c=c||0,a instanceof b.RenderTexture?(this.key=a.key,void this.setTexture(a)):a instanceof b.BitmapData?(this.key=a.key,void this.setTexture(a.texture)):a instanceof PIXI.Texture?(this.key=a,void this.setTexture(a)):null===a||"undefined"==typeof a?(this.key="__default",void this.setTexture(PIXI.TextureCache[this.key])):"string"!=typeof a||this.game.cache.checkImageKey(a)?this.game.cache.isSpriteSheet(a)?(this.key=a,this.animations.loadFrameData(this.game.cache.getFrameData(a)),"string"==typeof c?this.frameName=c:this.frame=c,void 0):(this.key=a,void this.setTexture(PIXI.TextureCache[a])):(this.key="__missing",void this.setTexture(PIXI.TextureCache[this.key]))},b.Sprite.prototype.crop=function(a){if("undefined"==typeof a||null===a)this.texture.hasOwnProperty("sourceWidth")&&this.texture.setFrame(new b.Rectangle(0,0,this.texture.sourceWidth,this.texture.sourceHeight));else if(this.texture instanceof PIXI.Texture){var c={};b.Utils.extend(!0,c,this.texture),c.sourceWidth=c.width,c.sourceHeight=c.height,c.frame=a,c.width=a.width,c.height=a.height,this.texture=c,this.texture.updateFrame=!0,PIXI.Texture.frameUpdates.push(this.texture)}else this.texture.setFrame(a)},b.Sprite.prototype.revive=function(a){return"undefined"==typeof a&&(a=1),this.alive=!0,this.exists=!0,this.visible=!0,this.health=a,this.events&&this.events.onRevived.dispatch(this),this},b.Sprite.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},b.Sprite.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.input&&this.input.destroy(),this.animations&&this.animations.destroy(),this.body&&this.body.destroy(),this.events&&this.events.destroy();var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.alive=!1,this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.Sprite.prototype.damage=function(a){return this.alive&&(this.health-=a,this.health<0&&this.kill()),this},b.Sprite.prototype.reset=function(a,b,c){return"undefined"==typeof c&&(c=1),this.world.setTo(a,b),this.position.x=a,this.position.y=b,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this._outOfBoundsFired=!1,this.health=c,this.body&&this.body.reset(a,b,!1,!1),this},b.Sprite.prototype.bringToTop=function(){return this.parent&&this.parent.bringToTop(this),this},b.Sprite.prototype.play=function(a,b,c,d){return this.animations?this.animations.play(a,b,c,d):void 0},Object.defineProperty(b.Sprite.prototype,"angle",{get:function(){return b.Math.wrapAngle(b.Math.radToDeg(this.rotation))},set:function(a){this.rotation=b.Math.degToRad(b.Math.wrapAngle(a))}}),Object.defineProperty(b.Sprite.prototype,"deltaX",{get:function(){return this.world.x-this._cache[0]}}),Object.defineProperty(b.Sprite.prototype,"deltaY",{get:function(){return this.world.y-this._cache[1]}}),Object.defineProperty(b.Sprite.prototype,"deltaZ",{get:function(){return this.rotation-this._cache[2]}}),Object.defineProperty(b.Sprite.prototype,"inWorld",{get:function(){return this.game.world.bounds.intersects(this.getBounds())}}),Object.defineProperty(b.Sprite.prototype,"inCamera",{get:function(){return this.game.world.camera.screenView.intersects(this.getBounds())}}),Object.defineProperty(b.Sprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(b.Sprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(b.Sprite.prototype,"renderOrderID",{get:function(){return this._cache[3]}}),Object.defineProperty(b.Sprite.prototype,"inputEnabled",{get:function(){return this.input&&this.input.enabled},set:function(a){a?null===this.input&&(this.input=new b.InputHandler(this),this.input.start()):this.input&&this.input.enabled&&this.input.stop()}}),Object.defineProperty(b.Sprite.prototype,"exists",{get:function(){return!!this._cache[6]},set:function(a){a?(this._cache[6]=1,this.body&&this.body.type===b.Physics.P2&&this.body.addToWorld(),this.visible=!0):(this._cache[6]=0,this.body&&this.body.type===b.Physics.P2&&this.body.removeFromWorld(),this.visible=!1)}}),Object.defineProperty(b.Sprite.prototype,"fixedToCamera",{get:function(){return!!this._cache[7]},set:function(a){a?(this._cache[7]=1,this.cameraOffset.set(this.x,this.y)):this._cache[7]=0}}),Object.defineProperty(b.Sprite.prototype,"smoothed",{get:function(){return!this.texture.baseTexture.scaleMode},set:function(a){a?this.texture&&(this.texture.baseTexture.scaleMode=0):this.texture&&(this.texture.baseTexture.scaleMode=1)}}),b.Image=function(a,c,d,e,f){c=c||0,d=d||0,e=e||null,f=f||null,this.game=a,this.exists=!0,this.name="",this.type=b.IMAGE,this.events=new b.Events(this),this.key=e,this._frame=0,this._frameName="",PIXI.Sprite.call(this,PIXI.TextureCache.__default),this.loadTexture(e,f),this.position.set(c,d),this.world=new b.Point(c,d),this.autoCull=!1,this.input=null,this.cameraOffset=new b.Point,this._cache=new Int16Array([0,0,0,0,1,0,1,0])},b.Image.prototype=Object.create(PIXI.Sprite.prototype),b.Image.prototype.constructor=b.Image,b.Image.prototype.preUpdate=function(){if(this._cache[0]=this.world.x,this._cache[1]=this.world.y,this._cache[2]=this.rotation,!this.exists||!this.parent.exists)return this._cache[3]=-1,!1;this.autoCull&&(this.renderable=this.game.world.camera.screenView.intersects(this.getBounds())),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),this.visible&&(this._cache[3]=this.game.stage.currentRenderOrderID++);for(var a=0,b=this.children.length;b>a;a++)this.children[a].preUpdate();return!0},b.Image.prototype.update=function(){},b.Image.prototype.postUpdate=function(){this.key instanceof b.BitmapData&&this.key._dirty&&this.key.render(),1===this._cache[7]&&(this.position.x=(this.game.camera.view.x+this.cameraOffset.x)/this.game.camera.scale.x,this.position.y=(this.game.camera.view.y+this.cameraOffset.y)/this.game.camera.scale.y);for(var a=0,c=this.children.length;c>a;a++)this.children[a].postUpdate()},b.Image.prototype.loadTexture=function(a,c){if(c=c||0,a instanceof b.RenderTexture)return this.key=a.key,void this.setTexture(a);if(a instanceof b.BitmapData)return this.key=a.key,void this.setTexture(a.texture);if(a instanceof PIXI.Texture)return this.key=a,void this.setTexture(a);if(null===a||"undefined"==typeof a)return this.key="__default",void this.setTexture(PIXI.TextureCache[this.key]);if("string"==typeof a&&!this.game.cache.checkImageKey(a))return this.key="__missing",void this.setTexture(PIXI.TextureCache[this.key]);if(this.game.cache.isSpriteSheet(a)){this.key=a;var d=this.game.cache.getFrameData(a);return"string"==typeof c?(this._frame=0,this._frameName=c,void this.setTexture(PIXI.TextureCache[d.getFrameByName(c).uuid])):(this._frame=c,this._frameName="",void this.setTexture(PIXI.TextureCache[d.getFrame(c).uuid]))}return this.key=a,void this.setTexture(PIXI.TextureCache[a])},b.Image.prototype.crop=function(a){if("undefined"==typeof a||null===a)this.texture.hasOwnProperty("sourceWidth")&&this.texture.setFrame(new b.Rectangle(0,0,this.texture.sourceWidth,this.texture.sourceHeight));else if(this.texture instanceof PIXI.Texture){var c={};b.Utils.extend(!0,c,this.texture),c.sourceWidth=c.width,c.sourceHeight=c.height,c.frame=a,c.width=a.width,c.height=a.height,this.texture=c,this.texture.updateFrame=!0,PIXI.Texture.frameUpdates.push(this.texture)}else this.texture.setFrame(a)},b.Image.prototype.revive=function(){return this.alive=!0,this.exists=!0,this.visible=!0,this.events&&this.events.onRevived.dispatch(this),this},b.Image.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},b.Image.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.events&&this.events.destroy(),this.input&&this.input.destroy();var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.alive=!1,this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.Image.prototype.reset=function(a,b){return this.world.setTo(a,b),this.position.x=a,this.position.y=b,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this},b.Image.prototype.bringToTop=function(){return this.parent&&this.parent.bringToTop(this),this},Object.defineProperty(b.Image.prototype,"angle",{get:function(){return b.Math.wrapAngle(b.Math.radToDeg(this.rotation))},set:function(a){this.rotation=b.Math.degToRad(b.Math.wrapAngle(a))}}),Object.defineProperty(b.Image.prototype,"deltaX",{get:function(){return this.world.x-this._cache[0]}}),Object.defineProperty(b.Image.prototype,"deltaY",{get:function(){return this.world.y-this._cache[1]}}),Object.defineProperty(b.Image.prototype,"deltaZ",{get:function(){return this.rotation-this._cache[2]}}),Object.defineProperty(b.Image.prototype,"inWorld",{get:function(){return this.game.world.bounds.intersects(this.getBounds())}}),Object.defineProperty(b.Image.prototype,"inCamera",{get:function(){return this.game.world.camera.screenView.intersects(this.getBounds())}}),Object.defineProperty(b.Image.prototype,"frame",{get:function(){return this._frame},set:function(a){if(a!==this.frame&&this.game.cache.isSpriteSheet(this.key)){var b=this.game.cache.getFrameData(this.key);b&&aa;a++)this.children[a].preUpdate();return!0},b.TileSprite.prototype.update=function(){},b.TileSprite.prototype.postUpdate=function(){this.exists&&this.body&&this.body.postUpdate(),1===this._cache[7]&&(this.position.x=this.game.camera.view.x+this.cameraOffset.x,this.position.y=this.game.camera.view.y+this.cameraOffset.y);for(var a=0,b=this.children.length;b>a;a++)this.children[a].postUpdate()},b.TileSprite.prototype.autoScroll=function(a,b){this._scroll.set(a,b)},b.TileSprite.prototype.stopScroll=function(){this._scroll.set(0,0)},b.TileSprite.prototype.loadTexture=function(a,c){return c=c||0,a instanceof b.RenderTexture?(this.key=a.key,void this.setTexture(a)):a instanceof b.BitmapData?(this.key=a.key,void this.setTexture(a.texture)):a instanceof PIXI.Texture?(this.key=a,void this.setTexture(a)):null===a||"undefined"==typeof a?(this.key="__default",void this.setTexture(PIXI.TextureCache[this.key])):"string"!=typeof a||this.game.cache.checkImageKey(a)?this.game.cache.isSpriteSheet(a)?(this.key=a,this.animations.loadFrameData(this.game.cache.getFrameData(a)),"string"==typeof c?this.frameName=c:this.frame=c,void 0):(this.key=a,void this.setTexture(PIXI.TextureCache[a])):(this.key="__missing",void this.setTexture(PIXI.TextureCache[this.key]))},b.TileSprite.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.filters&&(this.filters=null),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.animations.destroy(),this.events.destroy();var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.TileSprite.prototype.play=function(a,b,c,d){return this.animations.play(a,b,c,d)},Object.defineProperty(b.TileSprite.prototype,"angle",{get:function(){return b.Math.wrapAngle(b.Math.radToDeg(this.rotation))},set:function(a){this.rotation=b.Math.degToRad(b.Math.wrapAngle(a))}}),Object.defineProperty(b.TileSprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){a!==this.animations.frame&&(this.animations.frame=a)}}),Object.defineProperty(b.TileSprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){a!==this.animations.frameName&&(this.animations.frameName=a)}}),Object.defineProperty(b.TileSprite.prototype,"fixedToCamera",{get:function(){return!!this._cache[7]},set:function(a){a?(this._cache[7]=1,this.cameraOffset.set(this.x,this.y)):this._cache[7]=0}}),Object.defineProperty(b.TileSprite.prototype,"exists",{get:function(){return!!this._cache[6]},set:function(a){a?(this._cache[6]=1,this.body&&this.body.type===b.Physics.P2&&this.body.addToWorld(),this.visible=!0):(this._cache[6]=0,this.body&&this.body.type===b.Physics.P2&&this.body.removeFromWorld(),this.visible=!1)}}),Object.defineProperty(b.TileSprite.prototype,"inputEnabled",{get:function(){return this.input&&this.input.enabled},set:function(a){a?null===this.input&&(this.input=new b.InputHandler(this),this.input.start()):this.input&&this.input.enabled&&this.input.stop()}}),b.Text=function(a,c,d,e,f){c=c||0,d=d||0,e=e||"",f=f||"",this.game=a,this.exists=!0,this.name="",this.type=b.TEXT,this.world=new b.Point(c,d),this._text=e,this._font="",this._fontSize=32,this._fontWeight="normal",this._lineSpacing=0,this.events=new b.Events(this),this.input=null,this.cameraOffset=new b.Point,PIXI.Text.call(this,e,f),this.position.set(c,d),this._cache=new Int16Array([0,0,0,0,1,0,1,0])},b.Text.prototype=Object.create(PIXI.Text.prototype),b.Text.prototype.constructor=b.Text,b.Text.prototype.preUpdate=function(){if(this._cache[0]=this.world.x,this._cache[1]=this.world.y,this._cache[2]=this.rotation,!this.exists||!this.parent.exists)return this.renderOrderID=-1,!1;this.autoCull&&(this.renderable=this.game.world.camera.screenView.intersects(this.getBounds())),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),this.visible&&(this._cache[3]=this.game.stage.currentRenderOrderID++);for(var a=0,b=this.children.length;b>a;a++)this.children[a].preUpdate();return!0},b.Text.prototype.update=function(){},b.Text.prototype.postUpdate=function(){1===this._cache[7]&&(this.position.x=(this.game.camera.view.x+this.cameraOffset.x)/this.game.camera.scale.x,this.position.y=(this.game.camera.view.y+this.cameraOffset.y)/this.game.camera.scale.y);for(var a=0,b=this.children.length;b>a;a++)this.children[a].postUpdate()},b.Text.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.texture.destroy(),this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null);var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.Text.prototype.setShadow=function(a,b,c,d){this.style.shadowOffsetX=a||0,this.style.shadowOffsetY=b||0,this.style.shadowColor=c||"rgba(0,0,0,0)",this.style.shadowBlur=d||0,this.dirty=!0},b.Text.prototype.setStyle=function(a){a=a||{},a.font=a.font||"bold 20pt Arial",a.fill=a.fill||"black",a.align=a.align||"left",a.stroke=a.stroke||"black",a.strokeThickness=a.strokeThickness||0,a.wordWrap=a.wordWrap||!1,a.wordWrapWidth=a.wordWrapWidth||100,a.shadowOffsetX=a.shadowOffsetX||0,a.shadowOffsetY=a.shadowOffsetY||0,a.shadowColor=a.shadowColor||"rgba(0,0,0,0)",a.shadowBlur=a.shadowBlur||0,this.style=a,this.dirty=!0},b.Text.prototype.updateText=function(){this.context.font=this.style.font;var a=this.text;this.style.wordWrap&&(a=this.runWordWrap(this.text));for(var b=a.split(/(?:\r\n|\r|\n)/),c=[],d=0,e=0;ee?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}d?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",b.RetroFont.TEXT_SET2=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",b.RetroFont.TEXT_SET3="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",b.RetroFont.TEXT_SET4="ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",b.RetroFont.TEXT_SET5="ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",b.RetroFont.TEXT_SET6="ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",b.RetroFont.TEXT_SET7="AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",b.RetroFont.TEXT_SET8="0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",b.RetroFont.TEXT_SET9="ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",b.RetroFont.TEXT_SET10="ABCDEFGHIJKLMNOPQRSTUVWXYZ",b.RetroFont.TEXT_SET11="ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789",b.RetroFont.prototype.setFixedWidth=function(a,b){"undefined"==typeof b&&(b="left"),this.fixedWidth=a,this.align=b},b.RetroFont.prototype.setText=function(a,b,c,d,e,f){this.multiLine=b||!1,this.customSpacingX=c||0,this.customSpacingY=d||0,this.align=e||"left",this.autoUpperCase=f?!1:!0,a.length>0&&(this.text=a)},b.RetroFont.prototype.resize=function(a,b){if(this.width=a,this.height=b,this.frame.width=this.width,this.frame.height=this.height,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.renderer.type===PIXI.WEBGL_RENDERER){this.projection.x=this.width/2,this.projection.y=-this.height/2;var c=this.renderer.gl;c.bindTexture(c.TEXTURE_2D,this.baseTexture._glTextures[c.id]),c.texImage2D(c.TEXTURE_2D,0,c.RGBA,this.width,this.height,0,c.RGBA,c.UNSIGNED_BYTE,null)}else this.textureBuffer.resize(this.width,this.height);PIXI.Texture.frameUpdates.push(this)},b.RetroFont.prototype.buildRetroFontText=function(){var a=0,c=0;if(this.multiLine){var d=this._text.split("\n");this.fixedWidth>0?this.resize(fixedWidth,d.length*(this.characterHeight+this.customSpacingY)-this.customSpacingY):this.resize(this.getLongestLine()*(this.characterWidth+this.customSpacingX),d.length*(this.characterHeight+this.customSpacingY)-this.customSpacingY),this.textureBuffer.clear();for(var e=0;ea&&(a=0),this.pasteLine(d[e],a,c,this.customSpacingX),c+=this.characterHeight+this.customSpacingY}}else{switch(this.fixedWidth>0?this.resize(fixedWidth,this.characterHeight):this.resize(this._text.length*(this.characterWidth+this.customSpacingX),this.characterHeight),this.textureBuffer.clear(),this.align){case b.RetroFont.ALIGN_LEFT:a=0;break;case b.RetroFont.ALIGN_RIGHT:a=this.width-this._text.length*(this.characterWidth+this.customSpacingX);break;case b.RetroFont.ALIGN_CENTER:a=this.width/2-this._text.length*(this.characterWidth+this.customSpacingX)/2,a+=this.customSpacingX/2}this.pasteLine(this._text,a,0,this.customSpacingX)}},b.RetroFont.prototype.pasteLine=function(a,c,d){for(var e=new b.Point,f=0;f=0&&(this.stamp.frame=this.grabData[a.charCodeAt(f)],e.set(c,d),this.render(this.stamp,e,!1),c+=this.characterWidth+this.customSpacingX,c>this.width))break},b.RetroFont.prototype.getLongestLine=function(){var a=0;if(this._text.length>0)for(var b=this._text.split("\n"),c=0;ca&&(a=b[c].length);return a},b.RetroFont.prototype.removeUnsupportedCharacters=function(a){for(var b="",c=0;c=0||!a&&"\n"===d)&&(b=b.concat(d))}return b},Object.defineProperty(b.RetroFont.prototype,"text",{get:function(){return this._text},set:function(a){var b;b=this.autoUpperCase?a.toUpperCase():a,b!==this._text&&(this._text=b,this.removeUnsupportedCharacters(this.multiLine),this.buildRetroFontText())}}),b.Canvas={create:function(a,b,c,d){if("undefined"==typeof d&&(d=!1),a=a||256,b=b||256,d)var e=document.createElement("canvas");else var e=document.createElement(navigator.isCocoonJS?"screencanvas":"canvas");return"string"==typeof c&&""!==c&&(e.id=c),e.width=a,e.height=b,e.style.display="block",e},getOffset:function(a,c){c=c||new b.Point;var d=a.getBoundingClientRect(),e=a.clientTop||document.body.clientTop||0,f=a.clientLeft||document.body.clientLeft||0,g=0,h=0;return"CSS1Compat"===document.compatMode?(g=window.pageYOffset||document.documentElement.scrollTop||a.scrollTop||0,h=window.pageXOffset||document.documentElement.scrollLeft||a.scrollLeft||0):(g=window.pageYOffset||document.body.scrollTop||a.scrollTop||0,h=window.pageXOffset||document.body.scrollLeft||a.scrollLeft||0),c.x=d.left+h-f,c.y=d.top+g-e,c},getAspectRatio:function(a){return a.width/a.height},setBackgroundColor:function(a,b){return b=b||"rgb(0,0,0)",a.style.backgroundColor=b,a},setTouchAction:function(a,b){return b=b||"none",a.style.msTouchAction=b,a.style["ms-touch-action"]=b,a.style["touch-action"]=b,a},setUserSelect:function(a,b){return b=b||"none",a.style["-webkit-touch-callout"]=b,a.style["-webkit-user-select"]=b,a.style["-khtml-user-select"]=b,a.style["-moz-user-select"]=b,a.style["-ms-user-select"]=b,a.style["user-select"]=b,a.style["-webkit-tap-highlight-color"]="rgba(0, 0, 0, 0)",a},addToDOM:function(a,b,c){var d;return"undefined"==typeof c&&(c=!0),b&&("string"==typeof b?d=document.getElementById(b):"object"==typeof b&&1===b.nodeType&&(d=b)),d||(d=document.body),c&&d.style&&(d.style.overflow="hidden"),d.appendChild(a),a},setTransform:function(a,b,c,d,e,f,g){return a.setTransform(d,f,g,e,b,c),a},setSmoothingEnabled:function(a,b){return a.imageSmoothingEnabled=b,a.mozImageSmoothingEnabled=b,a.oImageSmoothingEnabled=b,a.webkitImageSmoothingEnabled=b,a.msImageSmoothingEnabled=b,a},setImageRenderingCrisp:function(a){return a.style["image-rendering"]="optimizeSpeed",a.style["image-rendering"]="crisp-edges",a.style["image-rendering"]="-moz-crisp-edges",a.style["image-rendering"]="-webkit-optimize-contrast",a.style["image-rendering"]="optimize-contrast",a.style.msInterpolationMode="nearest-neighbor",a},setImageRenderingBicubic:function(a){return a.style["image-rendering"]="auto",a.style.msInterpolationMode="bicubic",a}},b.Device=function(a){this.game=a,this.patchAndroidClearRectBug=!1,this.desktop=!1,this.iOS=!1,this.cocoonJS=!1,this.ejecta=!1,this.android=!1,this.chromeOS=!1,this.linux=!1,this.macOS=!1,this.windows=!1,this.windowsPhone=!1,this.canvas=!1,this.file=!1,this.fileSystem=!1,this.localStorage=!1,this.webGL=!1,this.worker=!1,this.touch=!1,this.mspointer=!1,this.css3D=!1,this.pointerLock=!1,this.typedArray=!1,this.vibration=!1,this.quirksMode=!1,this.arora=!1,this.chrome=!1,this.epiphany=!1,this.firefox=!1,this.ie=!1,this.ieVersion=0,this.trident=!1,this.tridentVersion=0,this.mobileSafari=!1,this.midori=!1,this.opera=!1,this.safari=!1,this.webApp=!1,this.silk=!1,this.audioData=!1,this.webAudio=!1,this.ogg=!1,this.opus=!1,this.mp3=!1,this.wav=!1,this.m4a=!1,this.webm=!1,this.iPhone=!1,this.iPhone4=!1,this.iPad=!1,this.pixelRatio=0,this.littleEndian=!1,this.fullscreen=!1,this.requestFullscreen="",this.cancelFullscreen="",this.fullscreenKeyboard=!1,this._checkAudio(),this._checkBrowser(),this._checkCSS3D(),this._checkDevice(),this._checkFeatures(),this._checkOS()},b.Device.prototype={_checkOS:function(){var a=navigator.userAgent;/Android/.test(a)?this.android=!0:/CrOS/.test(a)?this.chromeOS=!0:/iP[ao]d|iPhone/i.test(a)?this.iOS=!0:/Linux/.test(a)?this.linux=!0:/Mac OS/.test(a)?this.macOS=!0:/Windows/.test(a)&&(this.windows=!0,/Windows Phone/i.test(a)&&(this.windowsPhone=!0)),(this.windows||this.macOS||this.linux&&this.silk===!1)&&(this.desktop=!0),(this.windowsPhone||/Windows NT/i.test(a)&&/Touch/i.test(a))&&(this.desktop=!1)},_checkFeatures:function(){this.canvas=!!window.CanvasRenderingContext2D||this.cocoonJS;try{this.localStorage=!!localStorage.getItem}catch(a){this.localStorage=!1}this.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),this.fileSystem=!!window.requestFileSystem,this.webGL=function(){try{var a=document.createElement("canvas");return!!window.WebGLRenderingContext&&(a.getContext("webgl")||a.getContext("experimental-webgl"))}catch(b){return!1}}(),this.webGL=null===this.webGL||this.webGL===!1?!1:!0,this.worker=!!window.Worker,("ontouchstart"in document.documentElement||window.navigator.maxTouchPoints&&window.navigator.maxTouchPoints>1)&&(this.touch=!0),(window.navigator.msPointerEnabled||window.navigator.pointerEnabled)&&(this.mspointer=!0),this.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.quirksMode="CSS1Compat"===document.compatMode?!1:!0},checkFullScreenSupport:function(){for(var a=["requestFullscreen","requestFullScreen","webkitRequestFullscreen","webkitRequestFullScreen","msRequestFullscreen","msRequestFullScreen","mozRequestFullScreen","mozRequestFullscreen"],b=0;b0,this.typedArray=!0):(this.littleEndian=!1,this.typedArray=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(this.vibration=!0)},_checkCSS3D:function(){var a,b=document.createElement("p"),c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(b,null);for(var d in c)void 0!==b.style[d]&&(b.style[d]="translate3d(1px,1px,1px)",a=window.getComputedStyle(b).getPropertyValue(c[d]));document.body.removeChild(b),this.css3D=void 0!==a&&a.length>0&&"none"!==a},canPlayAudio:function(a){return"mp3"==a&&this.mp3?!0:"ogg"==a&&(this.ogg||this.opus)?!0:"m4a"==a&&this.m4a?!0:"wav"==a&&this.wav?!0:"webm"==a&&this.webm?!0:!1},isConsoleOpen:function(){return window.console&&window.console.firebug?!0:window.console?(console.profile(),console.profileEnd(),console.clear&&console.clear(),console.profiles.length>0):!1}},b.Device.prototype.constructor=b.Device,b.RequestAnimationFrame=function(a,b){"undefined"==typeof b&&(b=!1),this.game=a,this.isRunning=!1,this.forceSetTimeOut=b;for(var c=["ms","moz","webkit","o"],d=0;da},fuzzyGreaterThan:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),a>b-c},fuzzyCeil:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.ceil(a-b)},fuzzyFloor:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.floor(a+b)},average:function(){for(var a=[],b=0;b0?Math.floor(a):Math.ceil(a)},shear:function(a){return a%1},snapTo:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.round(a/b),c+a)},snapToFloor:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.floor(a/b),c+a)},snapToCeil:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.ceil(a/b),c+a)},snapToInArray:function(a,b,c){if("undefined"==typeof c&&(c=!0),c&&b.sort(),a=f-a?f:e},roundTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.round(a*d)/d},floorTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.floor(a*d)/d},ceilTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.ceil(a*d)/d},interpolateFloat:function(a,b,c){return(b-a)*c+a},angleBetween:function(a,b,c,d){return Math.atan2(c-a,d-b)},angleBetweenPoints:function(a,b){return Math.atan2(b.x-a.x,b.y-a.y)},reverseAngle:function(a){return this.normalizeAngle(a+Math.PI,!0)},normalizeAngle:function(a){return a%=2*Math.PI,a>=0?a:a+2*Math.PI},normalizeLatitude:function(a){return Math.max(-90,Math.min(90,a))},normalizeLongitude:function(a){return a%360==180?180:(a%=360,-180>a?a+360:a>180?a-360:a)},nearestAngleBetween:function(a,b,c){"undefined"==typeof c&&(c=!0);var d=c?Math.PI:180;return a=this.normalizeAngle(a,c),b=this.normalizeAngle(b,c),-d/2>a&&b>d/2&&(a+=2*d),-d/2>b&&a>d/2&&(b+=2*d),b-a},interpolateAngles:function(a,b,c,d,e){return"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=null),a=this.normalizeAngle(a,d),b=this.normalizeAngleToAnother(b,a,d),"function"==typeof e?e(c,a,b-a,1):this.interpolateFloat(a,b,c)},chanceRoll:function(a){return"undefined"==typeof a&&(a=50),0>=a?!1:a>=100?!0:100*Math.random()>=a?!1:!0},numberArray:function(a,b){for(var c=[],d=a;b>=d;d++)c.push(d);return c},maxAdd:function(a,b,c){return a+=b,a>c&&(a=c),a},minSub:function(a,b,c){return a-=b,c>a&&(a=c),a},wrap:function(a,b,c){var d=c-b;if(0>=d)return 0;var e=(a-b)%d;return 0>e&&(e+=d),e+b},wrapValue:function(a,b,c){var d;return a=Math.abs(a),b=Math.abs(b),c=Math.abs(c),d=(a+b)%c},randomSign:function(){return Math.random()>.5?1:-1},isOdd:function(a){return 1&a},isEven:function(a){return 1&a?!1:!0},max:function(){for(var a=1,b=0,c=arguments.length;c>a;a++)arguments[b]b;b++)a[b]b;b++)a[b]>a[c]&&(c=b);return a[c]},minProperty:function(a){if(2===arguments.length&&"object"==typeof arguments[1])var b=arguments[1];else var b=arguments.slice(1);for(var c=1,d=0,e=b.length;e>c;c++)b[c][a]c;c++)b[c][a]>b[d][a]&&(d=c);return b[d][a]},wrapAngle:function(a){return this.wrap(a,-180,180)},angleLimit:function(a,b,c){var d=a;return a>c?d=c:b>a&&(d=b),d},linearInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return 0>b?this.linear(a[0],a[1],d):b>1?this.linear(a[c],a[c-1],c-d):this.linear(a[e],a[e+1>c?c:e+1],d-e)},bezierInterpolation:function(a,b){for(var c=0,d=a.length-1,e=0;d>=e;e++)c+=Math.pow(1-b,d-e)*Math.pow(b,e)*a[e]*this.bernstein(d,e);return c},catmullRomInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return a[0]===a[c]?(0>b&&(e=Math.floor(d=c*(1+b))),this.catmullRom(a[(e-1+c)%c],a[e],a[(e+1)%c],a[(e+2)%c],d-e)):0>b?a[0]-(this.catmullRom(a[0],a[0],a[1],a[1],-d)-a[0]):b>1?a[c]-(this.catmullRom(a[c],a[c],a[c-1],a[c-1],d-c)-a[c]):this.catmullRom(a[e?e-1:0],a[e],a[e+1>c?c:e+1],a[e+2>c?c:e+2],d-e)},linear:function(a,b,c){return(b-a)*c+a},bernstein:function(a,b){return this.factorial(a)/this.factorial(b)/this.factorial(a-b)},catmullRom:function(a,b,c,d,e){var f=.5*(c-a),g=.5*(d-b),h=e*e,i=e*h;return(2*b-2*c+f+g)*i+(-3*b+3*c-2*f-g)*h+f*e+b},difference:function(a,b){return Math.abs(a-b)},getRandom:function(a,b,c){if("undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),null!=a){var d=c;if((0===d||d>a.length-b)&&(d=a.length-b),d>0)return a[b+Math.floor(Math.random()*d)]}return null},floor:function(a){var b=0|a;return a>0?b:b!=a?b-1:b},ceil:function(a){var b=0|a;return a>0?b!=a?b+1:b:b},sinCosGenerator:function(a,b,c,d){"undefined"==typeof b&&(b=1),"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1);for(var e=b,f=c,g=d*Math.PI/a,h=[],i=[],j=0;a>j;j++)f-=e*g,e+=f*g,h[j]=f,i[j]=e;return{sin:i,cos:h,length:a}},shift:function(a){var b=a.shift();return a.push(b),b},shuffleArray:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},distance:function(a,b,c,d){var e=a-c,f=b-d;return Math.sqrt(e*e+f*f)},distancePow:function(a,b,c,d,e){return"undefined"==typeof e&&(e=2),Math.sqrt(Math.pow(c-a,e)+Math.pow(d-b,e))},distanceRounded:function(a,c,d,e){return Math.round(b.Math.distance(a,c,d,e))},clamp:function(a,b,c){return b>a?b:a>c?c:a},clampBottom:function(a,b){return b>a?b:a},within:function(a,b,c){return Math.abs(a-b)<=c},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*(3-2*a))},smootherstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*a*(a*(6*a-15)+10))},sign:function(a){return 0>a?-1:a>0?1:0},p2px:function(a){return a*=20},px2p:function(a){return.05*a},p2pxi:function(a){return a*=-20},px2pi:function(a){return a*-.05},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}()},b.RandomDataGenerator=function(a){"undefined"==typeof a&&(a=[]),this.c=1,this.s0=0,this.s1=0,this.s2=0,this.sow(a)},b.RandomDataGenerator.prototype={rnd:function(){var a=2091639*this.s0+2.3283064365386963e-10*this.c;return this.c=0|a,this.s0=this.s1,this.s1=this.s2,this.s2=a-this.c,this.s2},sow:function(a){"undefined"==typeof a&&(a=[]),this.s0=this.hash(" "),this.s1=this.hash(this.s0),this.s2=this.hash(this.s1),this.c=1;for(var b,c=0;b=a[c++];)this.s0-=this.hash(b),this.s0+=~~(this.s0<0),this.s1-=this.hash(b),this.s1+=~~(this.s1<0),this.s2-=this.hash(b),this.s2+=~~(this.s2<0)},hash:function(a){var b,c,d;for(d=4022871197,a=a.toString(),c=0;c>>0,b-=d,b*=d,d=b>>>0,b-=d,d+=4294967296*b;return 2.3283064365386963e-10*(d>>>0)},integer:function(){return 4294967296*this.rnd.apply(this)},frac:function(){return this.rnd.apply(this)+1.1102230246251565e-16*(2097152*this.rnd.apply(this)|0)},real:function(){return this.integer()+this.frac()},integerInRange:function(a,b){return Math.round(this.realInRange(a,b))},realInRange:function(a,b){return this.frac()*(b-a)+a},normal:function(){return 1-2*this.frac()},uuid:function(){var a="",b="";for(b=a="";a++<36;b+=~a%5|3*a&4?(15^a?8^this.frac()*(20^a?16:4):4).toString(16):"-");return b},pick:function(a){return a[this.integerInRange(0,a.length)]},weightedPick:function(a){return a[~~(Math.pow(this.frac(),2)*a.length)]},timestamp:function(a,b){return this.realInRange(a||9466848e5,b||1577862e6)},angle:function(){return this.integerInRange(-180,180)}},b.RandomDataGenerator.prototype.constructor=b.RandomDataGenerator,b.QuadTree=function(a,b,c,d,e,f,g,h){this.physicsManager=a,this.ID=a.quadTreeID,a.quadTreeID++,this.maxObjects=f||10,this.maxLevels=g||4,this.level=h||0,this.bounds={x:Math.round(b),y:Math.round(c),width:d,height:e,subWidth:Math.floor(d/2),subHeight:Math.floor(e/2),right:Math.round(b)+Math.floor(d/2),bottom:Math.round(c)+Math.floor(e/2)},this.objects=[],this.nodes=[]},b.QuadTree.prototype={split:function(){this.level++,this.nodes[0]=new b.QuadTree(this.physicsManager,this.bounds.right,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[1]=new b.QuadTree(this.physicsManager,this.bounds.x,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[2]=new b.QuadTree(this.physicsManager,this.bounds.x,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[3]=new b.QuadTree(this.physicsManager,this.bounds.right,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level)},insert:function(a){var b,c=0;if(null!=this.nodes[0]&&(b=this.getIndex(a),-1!==b))return void this.nodes[b].insert(a);if(this.objects.push(a),this.objects.length>this.maxObjects&&this.levelthis.bounds.bottom&&(b=2):a.x>this.bounds.right&&(a.ythis.bounds.bottom&&(b=3)),b},retrieve:function(a){var b=this.objects;return a.body.quadTreeIndex=this.getIndex(a.body),a.body.quadTreeIDs.push(this.ID),this.nodes[0]&&(-1!==a.body.quadTreeIndex?b=b.concat(this.nodes[a.body.quadTreeIndex].retrieve(a)):(b=b.concat(this.nodes[0].retrieve(a)),b=b.concat(this.nodes[1].retrieve(a)),b=b.concat(this.nodes[2].retrieve(a)),b=b.concat(this.nodes[3].retrieve(a)))),b},clear:function(){this.objects=[];for(var a=0,b=this.nodes.length;b>a;a++)this.nodes[a]&&(this.nodes[a].clear(),delete this.nodes[a])}},b.Net=function(a){this.game=a},b.Net.prototype={getHostName:function(){return window.location&&window.location.hostname?window.location.hostname:null},checkDomainName:function(a){return-1!==window.location.hostname.indexOf(a)},updateQueryString:function(a,b,c,d){"undefined"==typeof c&&(c=!1),("undefined"==typeof d||""===d)&&(d=window.location.href);var e="",f=new RegExp("([?|&])"+a+"=.*?(&|#|$)(.*)","gi");if(f.test(d))e="undefined"!=typeof b&&null!==b?d.replace(f,"$1"+a+"="+b+"$2$3"):d.replace(f,"$1$3").replace(/(&|\?)$/,"");else if("undefined"!=typeof b&&null!==b){var g=-1!==d.indexOf("?")?"&":"?",h=d.split("#");d=h[0]+g+a+"="+b,h[1]&&(d+="#"+h[1]),e=d}else e=d;return c?void(window.location.href=e):e},getQueryString:function(a){"undefined"==typeof a&&(a="");var b={},c=location.search.substring(1).split("&");for(var d in c){var e=c[d].split("=");if(e.length>1){if(a&&a==this.decodeURI(e[0]))return this.decodeURI(e[1]);b[this.decodeURI(e[0])]=this.decodeURI(e[1])}}return b},decodeURI:function(a){return decodeURIComponent(a.replace(/\+/g," "))}},b.Net.prototype.constructor=b.Net,b.TweenManager=function(a){this.game=a,this._tweens=[],this._add=[],this.game.onPause.add(this._pauseAll,this),this.game.onResume.add(this._resumeAll,this)},b.TweenManager.prototype={getAll:function(){return this._tweens},removeAll:function(){for(var a=0;aa;)this._tweens[a].update(this.game.time.now)?a++:(this._tweens.splice(a,1),b--);return this._add.length>0&&(this._tweens=this._tweens.concat(this._add),this._add.length=0),!0},isTweening:function(a){return this._tweens.some(function(b){return b._object===a})},_pauseAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a]._pause()},_resumeAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a]._resume()},pauseAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].pause()},resumeAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].resume(!0)}},b.TweenManager.prototype.constructor=b.TweenManager,b.Tween=function(a,c,d){this._object=a,this.game=c,this._manager=d,this._valuesStart={},this._valuesEnd={},this._valuesStartRepeat={},this._duration=1e3,this._repeat=0,this._yoyo=!1,this._reversed=!1,this._delayTime=0,this._startTime=null,this._easingFunction=b.Easing.Linear.None,this._interpolationFunction=b.Math.linearInterpolation,this._chainedTweens=[],this._onStartCallbackFired=!1,this._onUpdateCallback=null,this._onUpdateCallbackContext=null,this._paused=!1,this._pausedTime=0,this._codePaused=!1,this.pendingDelete=!1,this.onStart=new b.Signal,this.onLoop=new b.Signal,this.onComplete=new b.Signal,this.isRunning=!1},b.Tween.prototype={to:function(a,b,c,d,e,f,g){b=b||1e3,c=c||null,d=d||!1,e=e||0,f=f||0,g=g||!1;var h;return this._parent?(h=this._manager.create(this._object),this._lastChild.chain(h),this._lastChild=h):(h=this,this._parent=this,this._lastChild=this),h._repeat=f,h._duration=b,h._valuesEnd=a,null!==c&&(h._easingFunction=c),e>0&&(h._delayTime=e),h._yoyo=g,d?this.start():this},start:function(){if(null!==this.game&&null!==this._object){this._manager.add(this),this.isRunning=!0,this._onStartCallbackFired=!1,this._startTime=this.game.time.now+this._delayTime;for(var a in this._valuesEnd){if(Array.isArray(this._valuesEnd[a])){if(0===this._valuesEnd[a].length)continue;this._valuesEnd[a]=[this._object[a]].concat(this._valuesEnd[a])}this._valuesStart[a]=this._object[a],Array.isArray(this._valuesStart[a])||(this._valuesStart[a]*=1),this._valuesStartRepeat[a]=this._valuesStart[a]||0}return this}},generateData:function(a,b){if(null===this.game||null===this._object)return null;this._startTime=0; -for(var c in this._valuesEnd){if(Array.isArray(this._valuesEnd[c])){if(0===this._valuesEnd[c].length)continue;this._valuesEnd[c]=[this._object[c]].concat(this._valuesEnd[c])}this._valuesStart[c]=this._object[c],Array.isArray(this._valuesStart[c])||(this._valuesStart[c]*=1),this._valuesStartRepeat[c]=this._valuesStart[c]||0}for(var d=0,e=a*(this._duration/1e3),f=this._duration/e,g=[];e--;){var c,h=(d-this._startTime)/this._duration;h=h>1?1:h;var i=this._easingFunction(h),j={};for(c in this._valuesEnd){var k=this._valuesStart[c]||0,l=this._valuesEnd[c];l instanceof Array?j[c]=this._interpolationFunction(l,i):("string"==typeof l&&(l=k+parseFloat(l,10)),"number"==typeof l&&(j[c]=k+(l-k)*i))}g.push(j),d+=f}if(this._yoyo){var m=g.slice();m.reverse(),g=g.concat(m)}return"undefined"!=typeof b?b=b.concat(g):g},stop:function(){return this.isRunning=!1,this._onUpdateCallback=null,this._manager.remove(this),this},delay:function(a){return this._delayTime=a,this},repeat:function(a){return this._repeat=a,this},yoyo:function(a){return this._yoyo=a,this},easing:function(a){return this._easingFunction=a,this},interpolation:function(a){return this._interpolationFunction=a,this},chain:function(){return this._chainedTweens=arguments,this},loop:function(){return this._lastChild.chain(this),this},onUpdateCallback:function(a,b){return this._onUpdateCallback=a,this._onUpdateCallbackContext=b,this},pause:function(){this._codePaused=!0,this._paused=!0,this._pausedTime=this.game.time.now},_pause:function(){this._codePaused||(this._paused=!0,this._pausedTime=this.game.time.now)},resume:function(){this._paused&&(this._paused=!1,this._codePaused=!1,this._startTime+=this.game.time.now-this._pausedTime)},_resume:function(){this._codePaused||(this._startTime+=this.game.time.pauseDuration,this._paused=!1)},update:function(a){if(this.pendingDelete)return!1;if(this._paused||a1?1:c;var d=this._easingFunction(c);for(b in this._valuesEnd){var e=this._valuesStart[b]||0,f=this._valuesEnd[b];f instanceof Array?this._object[b]=this._interpolationFunction(f,d):("string"==typeof f&&(f=e+parseFloat(f,10)),"number"==typeof f&&(this._object[b]=e+(f-e)*d))}if(null!==this._onUpdateCallback&&this._onUpdateCallback.call(this._onUpdateCallbackContext,this,d),1==c){if(this._repeat>0){isFinite(this._repeat)&&this._repeat--;for(b in this._valuesStartRepeat){if("string"==typeof this._valuesEnd[b]&&(this._valuesStartRepeat[b]=this._valuesStartRepeat[b]+parseFloat(this._valuesEnd[b],10)),this._yoyo){var g=this._valuesStartRepeat[b];this._valuesStartRepeat[b]=this._valuesEnd[b],this._valuesEnd[b]=g,this._reversed=!this._reversed}this._valuesStart[b]=this._valuesStartRepeat[b]}return this._startTime=a+this._delayTime,this.onLoop.dispatch(this._object),!0}this.isRunning=!1,this.onComplete.dispatch(this._object);for(var h=0,i=this._chainedTweens.length;i>h;h++)this._chainedTweens[h].start(a);return!1}return!0}},b.Tween.prototype.constructor=b.Tween,b.Easing={Linear:{None:function(a){return a}},Quadratic:{In:function(a){return a*a},Out:function(a){return a*(2-a)},InOut:function(a){return(a*=2)<1?.5*a*a:-.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a:.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return(a*=2)<1?.5*a*a*a*a:-.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a*a*a},Out:function(a){return--a*a*a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a*a*a:.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:(a*=2)<1?.5*Math.pow(1024,a-1):.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1-Math.sqrt(1-a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return(a*=2)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),-(c*Math.pow(2,10*(a-=1))*Math.sin(2*(a-b)*Math.PI/d)))},Out:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),c*Math.pow(2,-10*a)*Math.sin(2*(a-b)*Math.PI/d)+1)},InOut:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),(a*=2)<1?-.5*c*Math.pow(2,10*(a-=1))*Math.sin(2*(a-b)*Math.PI/d):c*Math.pow(2,-10*(a-=1))*Math.sin(2*(a-b)*Math.PI/d)*.5+1)}},Back:{In:function(a){var b=1.70158;return a*a*((b+1)*a-b)},Out:function(a){var b=1.70158;return--a*a*((b+1)*a+b)+1},InOut:function(a){var b=2.5949095;return(a*=2)<1?.5*a*a*((b+1)*a-b):.5*((a-=2)*a*((b+1)*a+b)+2)}},Bounce:{In:function(a){return 1-b.Easing.Bounce.Out(1-a)},Out:function(a){return 1/2.75>a?7.5625*a*a:2/2.75>a?7.5625*(a-=1.5/2.75)*a+.75:2.5/2.75>a?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},InOut:function(a){return.5>a?.5*b.Easing.Bounce.In(2*a):.5*b.Easing.Bounce.Out(2*a-1)+.5}}},b.Time=function(a){this.game=a,this.time=0,this.now=0,this.elapsed=0,this.pausedTime=0,this.advancedTiming=!1,this.fps=0,this.fpsMin=1e3,this.fpsMax=0,this.msMin=1e3,this.msMax=0,this.physicsElapsed=0,this.frames=0,this.pauseDuration=0,this.timeToCall=0,this.lastTime=0,this.events=new b.Timer(this.game,!1),this._started=0,this._timeLastSecond=0,this._pauseStarted=0,this._justResumed=!1,this._timers=[],this._len=0,this._i=0},b.Time.prototype={boot:function(){this._started=Date.now(),this.events.start()},create:function(a){"undefined"==typeof a&&(a=!0);var c=new b.Timer(this.game,a);return this._timers.push(c),c},removeAll:function(){for(var a=0;athis._timeLastSecond+1e3&&(this.fps=Math.round(1e3*this.frames/(this.now-this._timeLastSecond)),this.fpsMin=this.game.math.min(this.fpsMin,this.fps),this.fpsMax=this.game.math.max(this.fpsMax,this.fps),this._timeLastSecond=this.now,this.frames=0)),this.time=this.now,this.lastTime=a+this.timeToCall,!this.game.paused)for(this.events.update(this.now),this._i=0,this._len=this._timers.length;this._i0&&(this.events.sort(this.sortHandler),this.nextTick=this.events[0].tick)},sortHandler:function(a,b){return a.tickb.tick?1:0},update:function(a){if(this.paused)return!0;for(this._now=a,this._len=this.events.length,this._i=0;this._i=this.nextTick&&this._len>0){for(this._i=0;this._i=this.events[this._i].tick;){var b=this._now-this.events[this._i].tick,c=this._now+this.events[this._i].delay-b;0>c&&(c=this._now+this.events[this._i].delay),this.events[this._i].loop===!0?(this.events[this._i].tick=c,this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args)):this.events[this._i].repeatCount>0?(this.events[this._i].repeatCount--,this.events[this._i].tick=c,this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args)):(this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args),this.events.splice(this._i,1),this._len--),this._i++}this.events.length>0?this.order():(this.expired=!0,this.onComplete.dispatch(this))}return this.expired&&this.autoDestroy?!1:!0},pause:function(){this.running&&!this.expired&&(this._pauseStarted=this.game.time.now,this.paused=!0,this._codePaused=!0)},_pause:function(){this.running&&!this.expired&&(this._pauseStarted=this.game.time.now,this.paused=!0)},resume:function(){if(this.running&&!this.expired){for(var a=this.game.time.now-this._pauseStarted,b=0;bthis._now?this.nextTick-this._now:0}}),Object.defineProperty(b.Timer.prototype,"length",{get:function(){return this.events.length}}),Object.defineProperty(b.Timer.prototype,"ms",{get:function(){return this._now-this._started}}),Object.defineProperty(b.Timer.prototype,"seconds",{get:function(){return.001*this.ms}}),b.Timer.prototype.constructor=b.Timer,b.TimerEvent=function(a,b,c,d,e,f,g,h){this.timer=a,this.delay=b,this.tick=c,this.repeatCount=d-1,this.loop=e,this.callback=f,this.callbackContext=g,this.args=h,this.pendingDelete=!1},b.TimerEvent.prototype.constructor=b.TimerEvent,b.AnimationManager=function(a){this.sprite=a,this.game=a.game,this.currentFrame=null,this.updateIfVisible=!0,this.isLoaded=!1,this._frameData=null,this._anims={},this._outputFrames=[]},b.AnimationManager.prototype={loadFrameData:function(a){this._frameData=a,this.frame=0,this.isLoaded=!0},add:function(a,c,d,e,f){return null==this._frameData?void console.warn("No FrameData available for Phaser.Animation "+a):(c=c||[],d=d||60,"undefined"==typeof e&&(e=!1),"undefined"==typeof f&&(f=c&&"number"==typeof c[0]?!0:!1),null==this.sprite.events.onAnimationStart&&(this.sprite.events.onAnimationStart=new b.Signal,this.sprite.events.onAnimationComplete=new b.Signal,this.sprite.events.onAnimationLoop=new b.Signal),this._outputFrames.length=0,this._frameData.getFrameIndexes(c,f,this._outputFrames),this._anims[a]=new b.Animation(this.game,this.sprite,a,this._frameData,this._outputFrames,d,e),this.currentAnim=this._anims[a],this.currentFrame=this.currentAnim.currentFrame,this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1),this._anims[a])},validateFrames:function(a,b){"undefined"==typeof b&&(b=!0);for(var c=0;cthis._frameData.total)return!1}else if(this._frameData.checkFrameName(a[c])===!1)return!1;return!0},play:function(a,b,c,d){if(this._anims[a]){if(this.currentAnim!=this._anims[a])return this.currentAnim=this._anims[a],this.currentAnim.paused=!1,this.currentAnim.play(b,c,d);if(this.currentAnim.isPlaying===!1)return this.currentAnim.paused=!1,this.currentAnim.play(b,c,d)}},stop:function(a,b){"undefined"==typeof b&&(b=!1),"string"==typeof a?this._anims[a]&&(this.currentAnim=this._anims[a],this.currentAnim.stop(b)):this.currentAnim&&this.currentAnim.stop(b)},update:function(){return this.updateIfVisible&&!this.sprite.visible?!1:this.currentAnim&&this.currentAnim.update()===!0?(this.currentFrame=this.currentAnim.currentFrame,!0):!1},getAnimation:function(a){return"string"==typeof a&&this._anims[a]?this._anims[a]:null},refreshFrame:function(){this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1)},destroy:function(){this._anims={},this._frameData=null,this._frameIndex=0,this.currentAnim=null,this.currentFrame=null}},b.AnimationManager.prototype.constructor=b.AnimationManager,Object.defineProperty(b.AnimationManager.prototype,"frameData",{get:function(){return this._frameData}}),Object.defineProperty(b.AnimationManager.prototype,"frameTotal",{get:function(){return this._frameData?this._frameData.total:-1}}),Object.defineProperty(b.AnimationManager.prototype,"paused",{get:function(){return this.currentAnim.isPaused},set:function(a){this.currentAnim.paused=a}}),Object.defineProperty(b.AnimationManager.prototype,"frame",{get:function(){return this.currentFrame?this._frameIndex:void 0},set:function(a){"number"==typeof a&&this._frameData&&null!==this._frameData.getFrame(a)&&(this.currentFrame=this._frameData.getFrame(a),this._frameIndex=a,this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1))}}),Object.defineProperty(b.AnimationManager.prototype,"frameName",{get:function(){return this.currentFrame?this.currentFrame.name:void 0},set:function(a){"string"==typeof a&&this._frameData&&null!==this._frameData.getFrameByName(a)?(this.currentFrame=this._frameData.getFrameByName(a),this._frameIndex=this.currentFrame.index,this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1)):console.warn("Cannot set frameName: "+a)}}),b.Animation=function(a,c,d,e,f,g,h){this.game=a,this._parent=c,this._frameData=e,this.name=d,this._frames=[],this._frames=this._frames.concat(f),this.delay=1e3/g,this.loop=h,this.loopCount=0,this.killOnComplete=!1,this.isFinished=!1,this.isPlaying=!1,this.isPaused=!1,this._pauseStartTime=0,this._frameIndex=0,this._frameDiff=0,this._frameSkip=1,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.onStart=new b.Signal,this.onComplete=new b.Signal,this.onLoop=new b.Signal,this.game.onPause.add(this.onPause,this),this.game.onResume.add(this.onResume,this)},b.Animation.prototype={play:function(a,b,c){return"number"==typeof a&&(this.delay=1e3/a),"boolean"==typeof b&&(this.loop=b),"undefined"!=typeof c&&(this.killOnComplete=c),this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this.loopCount=0,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this._parent.__tilePattern&&(this._parent.__tilePattern=!1,this._parent.tilingTexture=!1),this._parent.events.onAnimationStart.dispatch(this._parent,this),this.onStart.dispatch(this._parent,this),this},restart:function(){this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this.loopCount=0,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.onStart.dispatch(this._parent,this)},stop:function(a,b){"undefined"==typeof a&&(a=!1),"undefined"==typeof b&&(b=!1),this.isPlaying=!1,this.isFinished=!0,this.paused=!1,a&&(this.currentFrame=this._frameData.getFrame(this._frames[0])),b&&(this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.onComplete.dispatch(this._parent,this))},onPause:function(){this.isPlaying&&(this._frameDiff=this._timeNextFrame-this.game.time.now)},onResume:function(){this.isPlaying&&(this._timeNextFrame=this.game.time.now+this._frameDiff)},update:function(){return this.isPaused?!1:this.isPlaying===!0&&this.game.time.now>=this._timeNextFrame?(this._frameSkip=1,this._frameDiff=this.game.time.now-this._timeNextFrame,this._timeLastFrame=this.game.time.now,this._frameDiff>this.delay&&(this._frameSkip=Math.floor(this._frameDiff/this.delay),this._frameDiff-=this._frameSkip*this.delay),this._timeNextFrame=this.game.time.now+(this.delay-this._frameDiff),this._frameIndex+=this._frameSkip,this._frameIndex>=this._frames.length?this.loop?(this._frameIndex%=this._frames.length,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&(this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this._parent.__tilePattern&&(this._parent.__tilePattern=!1,this._parent.tilingTexture=!1)),this.loopCount++,this._parent.events.onAnimationLoop.dispatch(this._parent,this),this.onLoop.dispatch(this._parent,this)):this.complete():(this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&(this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this._parent.__tilePattern&&(this._parent.__tilePattern=!1,this._parent.tilingTexture=!1))),!0):!1},destroy:function(){this.game=null,this._parent=null,this._frames=null,this._frameData=null,this.currentFrame=null,this.isPlaying=!1,this.onStart.destroy(),this.onLoop.destroy(),this.onComplete.destroy(),this.game.onPause.remove(this.onPause,this),this.game.onResume.remove(this.onResume,this)},complete:function(){this.isPlaying=!1,this.isFinished=!0,this.paused=!1,this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.onComplete.dispatch(this._parent,this),this.killOnComplete&&this._parent.kill()}},b.Animation.prototype.constructor=b.Animation,Object.defineProperty(b.Animation.prototype,"paused",{get:function(){return this.isPaused},set:function(a){this.isPaused=a,a?this._pauseStartTime=this.game.time.now:this.isPlaying&&(this._timeNextFrame=this.game.time.now+this.delay)}}),Object.defineProperty(b.Animation.prototype,"frameTotal",{get:function(){return this._frames.length}}),Object.defineProperty(b.Animation.prototype,"frame",{get:function(){return null!==this.currentFrame?this.currentFrame.index:this._frameIndex},set:function(a){this.currentFrame=this._frameData.getFrame(this._frames[a]),null!==this.currentFrame&&(this._frameIndex=a,this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]))}}),Object.defineProperty(b.Animation.prototype,"speed",{get:function(){return Math.round(1e3/this.delay)},set:function(a){a>=1&&(this.delay=1e3/a)}}),b.Animation.generateFrameNames=function(a,c,d,e,f){"undefined"==typeof e&&(e="");var g=[],h="";if(d>c)for(var i=c;d>=i;i++)h="number"==typeof f?b.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);else for(var i=c;i>=d;i--)h="number"==typeof f?b.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);return g},b.Frame=function(a,c,d,e,f,g,h){this.index=a,this.x=c,this.y=d,this.width=e,this.height=f,this.name=g,this.uuid=h,this.centerX=Math.floor(e/2),this.centerY=Math.floor(f/2),this.distance=b.Math.distance(0,0,e,f),this.rotated=!1,this.rotationDirection="cw",this.trimmed=!1,this.sourceSizeW=e,this.sourceSizeH=f,this.spriteSourceSizeX=0,this.spriteSourceSizeY=0,this.spriteSourceSizeW=0,this.spriteSourceSizeH=0},b.Frame.prototype={setTrim:function(a,b,c,d,e,f,g){this.trimmed=a,a&&(this.width=b,this.height=c,this.sourceSizeW=b,this.sourceSizeH=c,this.centerX=Math.floor(b/2),this.centerY=Math.floor(c/2),this.spriteSourceSizeX=d,this.spriteSourceSizeY=e,this.spriteSourceSizeW=f,this.spriteSourceSizeH=g)},getRect:function(a){return"undefined"==typeof a?a=new b.Rectangle(this.x,this.y,this.width,this.height):a.setTo(this.x,this.y,this.width,this.height),a}},b.Frame.prototype.constructor=b.Frame,b.FrameData=function(){this._frames=[],this._frameNames=[]},b.FrameData.prototype={addFrame:function(a){return a.index=this._frames.length,this._frames.push(a),""!==a.name&&(this._frameNames[a.name]=a.index),a},getFrame:function(a){return a>this._frames.length&&(a=0),this._frames[a]},getFrameByName:function(a){return"number"==typeof this._frameNames[a]?this._frames[this._frameNames[a]]:null},checkFrameName:function(a){return null==this._frameNames[a]?!1:!0},getFrameRange:function(a,b,c){"undefined"==typeof c&&(c=[]);for(var d=a;b>=d;d++)c.push(this._frames[d]);return c},getFrames:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0;dd;d++)c.push(b?this.getFrame(a[d]):this.getFrameByName(a[d]));return c},getFrameIndexes:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0,e=this._frames.length;e>d;d++)c.push(this._frames[d].index);else for(var d=0,e=a.length;e>d;d++)b?c.push(a[d]):this.getFrameByName(a[d])&&c.push(this.getFrameByName(a[d]).index);return c}},b.FrameData.prototype.constructor=b.FrameData,Object.defineProperty(b.FrameData.prototype,"total",{get:function(){return this._frames.length}}),b.AnimationParser={spriteSheet:function(a,c,d,e,f,g,h){var i=a.cache.getImage(c);if(null==i)return null;var j=i.width,k=i.height;0>=d&&(d=Math.floor(-j/Math.min(-1,d))),0>=e&&(e=Math.floor(-k/Math.min(-1,e)));var l=Math.floor((j-g)/(d+h)),m=Math.floor((k-g)/(e+h)),n=l*m;if(-1!==f&&(n=f),0===j||0===k||d>j||e>k||0===n)return console.warn("Phaser.AnimationParser.spriteSheet: width/height zero or width/height < given frameWidth/frameHeight"),null;for(var o=new b.FrameData,p=g,q=g,r=0;n>r;r++){var s=a.rnd.uuid();o.addFrame(new b.Frame(r,p,q,d,e,"",s)),PIXI.TextureCache[s]=new PIXI.Texture(PIXI.BaseTextureCache[c],{x:p,y:q,width:d,height:e}),p+=d+h,p+d>j&&(p=g,q+=e+h)}return o},JSONData:function(a,c,d){if(!c.frames)return console.warn("Phaser.AnimationParser.JSONData: Invalid Texture Atlas JSON given, missing 'frames' array"),void console.log(c);for(var e,f=new b.FrameData,g=c.frames,h=0;h tag");for(var e,f,g,h,i,j,k,l,m,n,o,p,q=new b.FrameData,r=c.getElementsByTagName("SubTexture"),s=0;s0&&(this.lifespan-=this.game.time.elapsed,this.lifespan<=0))return this.kill(),!1;if((this.autoCull||this.checkWorldBounds)&&this._bounds.copyFrom(this.getBounds()),this.autoCull&&(this.renderable=this.game.world.camera.screenView.intersects(this._bounds)),this.checkWorldBounds)if(1===this._cache[5]&&this.game.world.bounds.intersects(this._bounds))this._cache[5]=0;else if(0===this._cache[5]&&!this.game.world.bounds.intersects(this._bounds)&&(this._cache[5]=1,this.events.onOutOfBounds.dispatch(this),this.outOfBoundsKill))return this.kill(),!1;this.world.setTo(this.game.camera.x+this.worldTransform.tx,this.game.camera.y+this.worldTransform.ty),this.visible&&(this._cache[3]=this.game.stage.currentRenderOrderID++),this.animations.update(),this.exists&&this.body&&this.body.preUpdate();for(var a=0,b=this.children.length;b>a;a++)this.children[a].preUpdate();return!0},b.Sprite.prototype.update=function(){},b.Sprite.prototype.postUpdate=function(){this.key instanceof b.BitmapData&&this.key._dirty&&this.key.render(),this.exists&&this.body&&this.body.postUpdate(),1===this._cache[7]&&(this.position.x=(this.game.camera.view.x+this.cameraOffset.x)/this.game.camera.scale.x,this.position.y=(this.game.camera.view.y+this.cameraOffset.y)/this.game.camera.scale.y);for(var a=0,c=this.children.length;c>a;a++)this.children[a].postUpdate()},b.Sprite.prototype.loadTexture=function(a,c){return c=c||0,a instanceof b.RenderTexture?(this.key=a.key,void this.setTexture(a)):a instanceof b.BitmapData?(this.key=a.key,void this.setTexture(a.texture)):a instanceof PIXI.Texture?(this.key=a,void this.setTexture(a)):null===a||"undefined"==typeof a?(this.key="__default",void this.setTexture(PIXI.TextureCache[this.key])):"string"!=typeof a||this.game.cache.checkImageKey(a)?this.game.cache.isSpriteSheet(a)?(this.key=a,this.animations.loadFrameData(this.game.cache.getFrameData(a)),"string"==typeof c?this.frameName=c:this.frame=c,void 0):(this.key=a,void this.setTexture(PIXI.TextureCache[a])):(this.key="__missing",void this.setTexture(PIXI.TextureCache[this.key]))},b.Sprite.prototype.crop=function(a){if("undefined"==typeof a||null===a)this.texture.hasOwnProperty("sourceWidth")&&this.texture.setFrame(new b.Rectangle(0,0,this.texture.sourceWidth,this.texture.sourceHeight));else if(this.texture instanceof PIXI.Texture){var c={};b.Utils.extend(!0,c,this.texture),c.sourceWidth=c.width,c.sourceHeight=c.height,c.frame=a,c.width=a.width,c.height=a.height,this.texture=c,this.texture.updateFrame=!0,PIXI.Texture.frameUpdates.push(this.texture)}else this.texture.setFrame(a)},b.Sprite.prototype.revive=function(a){return"undefined"==typeof a&&(a=1),this.alive=!0,this.exists=!0,this.visible=!0,this.health=a,this.events&&this.events.onRevived.dispatch(this),this},b.Sprite.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},b.Sprite.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.input&&this.input.destroy(),this.animations&&this.animations.destroy(),this.body&&this.body.destroy(),this.events&&this.events.destroy();var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.alive=!1,this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.Sprite.prototype.damage=function(a){return this.alive&&(this.health-=a,this.health<=0&&this.kill()),this},b.Sprite.prototype.reset=function(a,b,c){return"undefined"==typeof c&&(c=1),this.world.setTo(a,b),this.position.x=a,this.position.y=b,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this._outOfBoundsFired=!1,this.health=c,this.body&&this.body.reset(a,b,!1,!1),this},b.Sprite.prototype.bringToTop=function(){return this.parent&&this.parent.bringToTop(this),this},b.Sprite.prototype.play=function(a,b,c,d){return this.animations?this.animations.play(a,b,c,d):void 0},Object.defineProperty(b.Sprite.prototype,"angle",{get:function(){return b.Math.wrapAngle(b.Math.radToDeg(this.rotation))},set:function(a){this.rotation=b.Math.degToRad(b.Math.wrapAngle(a))}}),Object.defineProperty(b.Sprite.prototype,"deltaX",{get:function(){return this.world.x-this._cache[0]}}),Object.defineProperty(b.Sprite.prototype,"deltaY",{get:function(){return this.world.y-this._cache[1]}}),Object.defineProperty(b.Sprite.prototype,"deltaZ",{get:function(){return this.rotation-this._cache[2]}}),Object.defineProperty(b.Sprite.prototype,"inWorld",{get:function(){return this.game.world.bounds.intersects(this.getBounds())}}),Object.defineProperty(b.Sprite.prototype,"inCamera",{get:function(){return this.game.world.camera.screenView.intersects(this.getBounds())}}),Object.defineProperty(b.Sprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(b.Sprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(b.Sprite.prototype,"renderOrderID",{get:function(){return this._cache[3]}}),Object.defineProperty(b.Sprite.prototype,"inputEnabled",{get:function(){return this.input&&this.input.enabled},set:function(a){a?null===this.input&&(this.input=new b.InputHandler(this),this.input.start()):this.input&&this.input.enabled&&this.input.stop()}}),Object.defineProperty(b.Sprite.prototype,"exists",{get:function(){return!!this._cache[6]},set:function(a){a?(this._cache[6]=1,this.body&&this.body.type===b.Physics.P2&&this.body.addToWorld(),this.visible=!0):(this._cache[6]=0,this.body&&this.body.type===b.Physics.P2&&this.body.removeFromWorld(),this.visible=!1)}}),Object.defineProperty(b.Sprite.prototype,"fixedToCamera",{get:function(){return!!this._cache[7]},set:function(a){a?(this._cache[7]=1,this.cameraOffset.set(this.x,this.y)):this._cache[7]=0}}),Object.defineProperty(b.Sprite.prototype,"smoothed",{get:function(){return!this.texture.baseTexture.scaleMode},set:function(a){a?this.texture&&(this.texture.baseTexture.scaleMode=0):this.texture&&(this.texture.baseTexture.scaleMode=1)}}),b.Image=function(a,c,d,e,f){c=c||0,d=d||0,e=e||null,f=f||null,this.game=a,this.exists=!0,this.name="",this.type=b.IMAGE,this.events=new b.Events(this),this.key=e,this._frame=0,this._frameName="",PIXI.Sprite.call(this,PIXI.TextureCache.__default),this.loadTexture(e,f),this.position.set(c,d),this.world=new b.Point(c,d),this.autoCull=!1,this.input=null,this.cameraOffset=new b.Point,this._cache=new Int16Array([0,0,0,0,1,0,1,0])},b.Image.prototype=Object.create(PIXI.Sprite.prototype),b.Image.prototype.constructor=b.Image,b.Image.prototype.preUpdate=function(){if(this._cache[0]=this.world.x,this._cache[1]=this.world.y,this._cache[2]=this.rotation,!this.exists||!this.parent.exists)return this._cache[3]=-1,!1;this.autoCull&&(this.renderable=this.game.world.camera.screenView.intersects(this.getBounds())),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),this.visible&&(this._cache[3]=this.game.stage.currentRenderOrderID++);for(var a=0,b=this.children.length;b>a;a++)this.children[a].preUpdate();return!0},b.Image.prototype.update=function(){},b.Image.prototype.postUpdate=function(){this.key instanceof b.BitmapData&&this.key._dirty&&this.key.render(),1===this._cache[7]&&(this.position.x=(this.game.camera.view.x+this.cameraOffset.x)/this.game.camera.scale.x,this.position.y=(this.game.camera.view.y+this.cameraOffset.y)/this.game.camera.scale.y);for(var a=0,c=this.children.length;c>a;a++)this.children[a].postUpdate()},b.Image.prototype.loadTexture=function(a,c){if(c=c||0,a instanceof b.RenderTexture)return this.key=a.key,void this.setTexture(a);if(a instanceof b.BitmapData)return this.key=a.key,void this.setTexture(a.texture);if(a instanceof PIXI.Texture)return this.key=a,void this.setTexture(a);if(null===a||"undefined"==typeof a)return this.key="__default",void this.setTexture(PIXI.TextureCache[this.key]);if("string"==typeof a&&!this.game.cache.checkImageKey(a))return this.key="__missing",void this.setTexture(PIXI.TextureCache[this.key]);if(this.game.cache.isSpriteSheet(a)){this.key=a;var d=this.game.cache.getFrameData(a);return"string"==typeof c?(this._frame=0,this._frameName=c,void this.setTexture(PIXI.TextureCache[d.getFrameByName(c).uuid])):(this._frame=c,this._frameName="",void this.setTexture(PIXI.TextureCache[d.getFrame(c).uuid]))}return this.key=a,void this.setTexture(PIXI.TextureCache[a])},b.Image.prototype.crop=function(a){if("undefined"==typeof a||null===a)this.texture.hasOwnProperty("sourceWidth")&&this.texture.setFrame(new b.Rectangle(0,0,this.texture.sourceWidth,this.texture.sourceHeight));else if(this.texture instanceof PIXI.Texture){var c={};b.Utils.extend(!0,c,this.texture),c.sourceWidth=c.width,c.sourceHeight=c.height,c.frame=a,c.width=a.width,c.height=a.height,this.texture=c,this.texture.updateFrame=!0,PIXI.Texture.frameUpdates.push(this.texture)}else this.texture.setFrame(a)},b.Image.prototype.revive=function(){return this.alive=!0,this.exists=!0,this.visible=!0,this.events&&this.events.onRevived.dispatch(this),this},b.Image.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},b.Image.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.events&&this.events.destroy(),this.input&&this.input.destroy();var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.alive=!1,this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.Image.prototype.reset=function(a,b){return this.world.setTo(a,b),this.position.x=a,this.position.y=b,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this},b.Image.prototype.bringToTop=function(){return this.parent&&this.parent.bringToTop(this),this},Object.defineProperty(b.Image.prototype,"angle",{get:function(){return b.Math.wrapAngle(b.Math.radToDeg(this.rotation))},set:function(a){this.rotation=b.Math.degToRad(b.Math.wrapAngle(a))}}),Object.defineProperty(b.Image.prototype,"deltaX",{get:function(){return this.world.x-this._cache[0]}}),Object.defineProperty(b.Image.prototype,"deltaY",{get:function(){return this.world.y-this._cache[1]}}),Object.defineProperty(b.Image.prototype,"deltaZ",{get:function(){return this.rotation-this._cache[2]}}),Object.defineProperty(b.Image.prototype,"inWorld",{get:function(){return this.game.world.bounds.intersects(this.getBounds())}}),Object.defineProperty(b.Image.prototype,"inCamera",{get:function(){return this.game.world.camera.screenView.intersects(this.getBounds())}}),Object.defineProperty(b.Image.prototype,"frame",{get:function(){return this._frame},set:function(a){if(a!==this.frame&&this.game.cache.isSpriteSheet(this.key)){var b=this.game.cache.getFrameData(this.key);b&&aa;a++)this.children[a].preUpdate();return!0},b.TileSprite.prototype.update=function(){},b.TileSprite.prototype.postUpdate=function(){this.exists&&this.body&&this.body.postUpdate(),1===this._cache[7]&&(this.position.x=this.game.camera.view.x+this.cameraOffset.x,this.position.y=this.game.camera.view.y+this.cameraOffset.y);for(var a=0,b=this.children.length;b>a;a++)this.children[a].postUpdate()},b.TileSprite.prototype.autoScroll=function(a,b){this._scroll.set(a,b)},b.TileSprite.prototype.stopScroll=function(){this._scroll.set(0,0)},b.TileSprite.prototype.loadTexture=function(a,c){return c=c||0,a instanceof b.RenderTexture?(this.key=a.key,void this.setTexture(a)):a instanceof b.BitmapData?(this.key=a.key,void this.setTexture(a.texture)):a instanceof PIXI.Texture?(this.key=a,void this.setTexture(a)):null===a||"undefined"==typeof a?(this.key="__default",void this.setTexture(PIXI.TextureCache[this.key])):"string"!=typeof a||this.game.cache.checkImageKey(a)?this.game.cache.isSpriteSheet(a)?(this.key=a,this.animations.loadFrameData(this.game.cache.getFrameData(a)),"string"==typeof c?this.frameName=c:this.frame=c,void 0):(this.key=a,void this.setTexture(PIXI.TextureCache[a])):(this.key="__missing",void this.setTexture(PIXI.TextureCache[this.key]))},b.TileSprite.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.filters&&(this.filters=null),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.animations.destroy(),this.events.destroy();var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.TileSprite.prototype.play=function(a,b,c,d){return this.animations.play(a,b,c,d)},Object.defineProperty(b.TileSprite.prototype,"angle",{get:function(){return b.Math.wrapAngle(b.Math.radToDeg(this.rotation))},set:function(a){this.rotation=b.Math.degToRad(b.Math.wrapAngle(a))}}),Object.defineProperty(b.TileSprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){a!==this.animations.frame&&(this.animations.frame=a)}}),Object.defineProperty(b.TileSprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){a!==this.animations.frameName&&(this.animations.frameName=a)}}),Object.defineProperty(b.TileSprite.prototype,"fixedToCamera",{get:function(){return!!this._cache[7]},set:function(a){a?(this._cache[7]=1,this.cameraOffset.set(this.x,this.y)):this._cache[7]=0}}),Object.defineProperty(b.TileSprite.prototype,"exists",{get:function(){return!!this._cache[6]},set:function(a){a?(this._cache[6]=1,this.body&&this.body.type===b.Physics.P2&&this.body.addToWorld(),this.visible=!0):(this._cache[6]=0,this.body&&this.body.type===b.Physics.P2&&this.body.removeFromWorld(),this.visible=!1)}}),Object.defineProperty(b.TileSprite.prototype,"inputEnabled",{get:function(){return this.input&&this.input.enabled},set:function(a){a?null===this.input&&(this.input=new b.InputHandler(this),this.input.start()):this.input&&this.input.enabled&&this.input.stop()}}),b.Text=function(a,c,d,e,f){c=c||0,d=d||0,e=e||"",f=f||"",this.game=a,this.exists=!0,this.name="",this.type=b.TEXT,this.world=new b.Point(c,d),this._text=e,this._font="",this._fontSize=32,this._fontWeight="normal",this._lineSpacing=0,this.events=new b.Events(this),this.input=null,this.cameraOffset=new b.Point,PIXI.Text.call(this,e,f),this.position.set(c,d),this._cache=new Int16Array([0,0,0,0,1,0,1,0])},b.Text.prototype=Object.create(PIXI.Text.prototype),b.Text.prototype.constructor=b.Text,b.Text.prototype.preUpdate=function(){if(this._cache[0]=this.world.x,this._cache[1]=this.world.y,this._cache[2]=this.rotation,!this.exists||!this.parent.exists)return this.renderOrderID=-1,!1;this.autoCull&&(this.renderable=this.game.world.camera.screenView.intersects(this.getBounds())),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),this.visible&&(this._cache[3]=this.game.stage.currentRenderOrderID++);for(var a=0,b=this.children.length;b>a;a++)this.children[a].preUpdate();return!0},b.Text.prototype.update=function(){},b.Text.prototype.postUpdate=function(){1===this._cache[7]&&(this.position.x=(this.game.camera.view.x+this.cameraOffset.x)/this.game.camera.scale.x,this.position.y=(this.game.camera.view.y+this.cameraOffset.y)/this.game.camera.scale.y);for(var a=0,b=this.children.length;b>a;a++)this.children[a].postUpdate()},b.Text.prototype.destroy=function(a){if(null!==this.game){"undefined"==typeof a&&(a=!0),this.parent&&(this.parent instanceof b.Group?this.parent.remove(this):this.parent.removeChild(this)),this.texture.destroy(),this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null);var c=this.children.length;if(a)for(;c--;)this.children[c].destroy(a);else for(;c--;)this.removeChild(this.children[c]);this.exists=!1,this.visible=!1,this.filters=null,this.mask=null,this.game=null}},b.Text.prototype.setShadow=function(a,b,c,d){this.style.shadowOffsetX=a||0,this.style.shadowOffsetY=b||0,this.style.shadowColor=c||"rgba(0,0,0,0)",this.style.shadowBlur=d||0,this.dirty=!0},b.Text.prototype.setStyle=function(a){a=a||{},a.font=a.font||"bold 20pt Arial",a.fill=a.fill||"black",a.align=a.align||"left",a.stroke=a.stroke||"black",a.strokeThickness=a.strokeThickness||0,a.wordWrap=a.wordWrap||!1,a.wordWrapWidth=a.wordWrapWidth||100,a.shadowOffsetX=a.shadowOffsetX||0,a.shadowOffsetY=a.shadowOffsetY||0,a.shadowColor=a.shadowColor||"rgba(0,0,0,0)",a.shadowBlur=a.shadowBlur||0,this.style=a,this.dirty=!0},b.Text.prototype.updateText=function(){this.context.font=this.style.font;var a=this.text;this.style.wordWrap&&(a=this.runWordWrap(this.text));for(var b=a.split(/(?:\r\n|\r|\n)/),c=[],d=0,e=0;ee?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}d?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",b.RetroFont.TEXT_SET2=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",b.RetroFont.TEXT_SET3="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",b.RetroFont.TEXT_SET4="ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",b.RetroFont.TEXT_SET5="ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",b.RetroFont.TEXT_SET6="ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",b.RetroFont.TEXT_SET7="AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",b.RetroFont.TEXT_SET8="0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",b.RetroFont.TEXT_SET9="ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",b.RetroFont.TEXT_SET10="ABCDEFGHIJKLMNOPQRSTUVWXYZ",b.RetroFont.TEXT_SET11="ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789",b.RetroFont.prototype.setFixedWidth=function(a,b){"undefined"==typeof b&&(b="left"),this.fixedWidth=a,this.align=b},b.RetroFont.prototype.setText=function(a,b,c,d,e,f){this.multiLine=b||!1,this.customSpacingX=c||0,this.customSpacingY=d||0,this.align=e||"left",this.autoUpperCase=f?!1:!0,a.length>0&&(this.text=a)},b.RetroFont.prototype.resize=function(a,b){if(this.width=a,this.height=b,this.frame.width=this.width,this.frame.height=this.height,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.renderer.type===PIXI.WEBGL_RENDERER){this.projection.x=this.width/2,this.projection.y=-this.height/2;var c=this.renderer.gl;c.bindTexture(c.TEXTURE_2D,this.baseTexture._glTextures[c.id]),c.texImage2D(c.TEXTURE_2D,0,c.RGBA,this.width,this.height,0,c.RGBA,c.UNSIGNED_BYTE,null)}else this.textureBuffer.resize(this.width,this.height);PIXI.Texture.frameUpdates.push(this)},b.RetroFont.prototype.buildRetroFontText=function(){var a=0,c=0;if(this.multiLine){var d=this._text.split("\n");this.fixedWidth>0?this.resize(fixedWidth,d.length*(this.characterHeight+this.customSpacingY)-this.customSpacingY):this.resize(this.getLongestLine()*(this.characterWidth+this.customSpacingX),d.length*(this.characterHeight+this.customSpacingY)-this.customSpacingY),this.textureBuffer.clear();for(var e=0;ea&&(a=0),this.pasteLine(d[e],a,c,this.customSpacingX),c+=this.characterHeight+this.customSpacingY}}else{switch(this.fixedWidth>0?this.resize(fixedWidth,this.characterHeight):this.resize(this._text.length*(this.characterWidth+this.customSpacingX),this.characterHeight),this.textureBuffer.clear(),this.align){case b.RetroFont.ALIGN_LEFT:a=0;break;case b.RetroFont.ALIGN_RIGHT:a=this.width-this._text.length*(this.characterWidth+this.customSpacingX);break;case b.RetroFont.ALIGN_CENTER:a=this.width/2-this._text.length*(this.characterWidth+this.customSpacingX)/2,a+=this.customSpacingX/2}this.pasteLine(this._text,a,0,this.customSpacingX)}},b.RetroFont.prototype.pasteLine=function(a,c,d){for(var e=new b.Point,f=0;f=0&&(this.stamp.frame=this.grabData[a.charCodeAt(f)],e.set(c,d),this.render(this.stamp,e,!1),c+=this.characterWidth+this.customSpacingX,c>this.width))break},b.RetroFont.prototype.getLongestLine=function(){var a=0;if(this._text.length>0)for(var b=this._text.split("\n"),c=0;ca&&(a=b[c].length);return a},b.RetroFont.prototype.removeUnsupportedCharacters=function(a){for(var b="",c=0;c=0||!a&&"\n"===d)&&(b=b.concat(d))}return b},Object.defineProperty(b.RetroFont.prototype,"text",{get:function(){return this._text},set:function(a){var b;b=this.autoUpperCase?a.toUpperCase():a,b!==this._text&&(this._text=b,this.removeUnsupportedCharacters(this.multiLine),this.buildRetroFontText())}}),b.Canvas={create:function(a,b,c,d){if("undefined"==typeof d&&(d=!1),a=a||256,b=b||256,d)var e=document.createElement("canvas");else var e=document.createElement(navigator.isCocoonJS?"screencanvas":"canvas");return"string"==typeof c&&""!==c&&(e.id=c),e.width=a,e.height=b,e.style.display="block",e},getOffset:function(a,c){c=c||new b.Point;var d=a.getBoundingClientRect(),e=a.clientTop||document.body.clientTop||0,f=a.clientLeft||document.body.clientLeft||0,g=0,h=0;return"CSS1Compat"===document.compatMode?(g=window.pageYOffset||document.documentElement.scrollTop||a.scrollTop||0,h=window.pageXOffset||document.documentElement.scrollLeft||a.scrollLeft||0):(g=window.pageYOffset||document.body.scrollTop||a.scrollTop||0,h=window.pageXOffset||document.body.scrollLeft||a.scrollLeft||0),c.x=d.left+h-f,c.y=d.top+g-e,c},getAspectRatio:function(a){return a.width/a.height},setBackgroundColor:function(a,b){return b=b||"rgb(0,0,0)",a.style.backgroundColor=b,a},setTouchAction:function(a,b){return b=b||"none",a.style.msTouchAction=b,a.style["ms-touch-action"]=b,a.style["touch-action"]=b,a},setUserSelect:function(a,b){return b=b||"none",a.style["-webkit-touch-callout"]=b,a.style["-webkit-user-select"]=b,a.style["-khtml-user-select"]=b,a.style["-moz-user-select"]=b,a.style["-ms-user-select"]=b,a.style["user-select"]=b,a.style["-webkit-tap-highlight-color"]="rgba(0, 0, 0, 0)",a},addToDOM:function(a,b,c){var d;return"undefined"==typeof c&&(c=!0),b&&("string"==typeof b?d=document.getElementById(b):"object"==typeof b&&1===b.nodeType&&(d=b)),d||(d=document.body),c&&d.style&&(d.style.overflow="hidden"),d.appendChild(a),a},setTransform:function(a,b,c,d,e,f,g){return a.setTransform(d,f,g,e,b,c),a},setSmoothingEnabled:function(a,b){return a.imageSmoothingEnabled=b,a.mozImageSmoothingEnabled=b,a.oImageSmoothingEnabled=b,a.webkitImageSmoothingEnabled=b,a.msImageSmoothingEnabled=b,a},setImageRenderingCrisp:function(a){return a.style["image-rendering"]="optimizeSpeed",a.style["image-rendering"]="crisp-edges",a.style["image-rendering"]="-moz-crisp-edges",a.style["image-rendering"]="-webkit-optimize-contrast",a.style["image-rendering"]="optimize-contrast",a.style.msInterpolationMode="nearest-neighbor",a},setImageRenderingBicubic:function(a){return a.style["image-rendering"]="auto",a.style.msInterpolationMode="bicubic",a}},b.Device=function(a){this.game=a,this.patchAndroidClearRectBug=!1,this.desktop=!1,this.iOS=!1,this.cocoonJS=!1,this.ejecta=!1,this.android=!1,this.chromeOS=!1,this.linux=!1,this.macOS=!1,this.windows=!1,this.windowsPhone=!1,this.canvas=!1,this.file=!1,this.fileSystem=!1,this.localStorage=!1,this.webGL=!1,this.worker=!1,this.touch=!1,this.mspointer=!1,this.css3D=!1,this.pointerLock=!1,this.typedArray=!1,this.vibration=!1,this.quirksMode=!1,this.arora=!1,this.chrome=!1,this.epiphany=!1,this.firefox=!1,this.ie=!1,this.ieVersion=0,this.trident=!1,this.tridentVersion=0,this.mobileSafari=!1,this.midori=!1,this.opera=!1,this.safari=!1,this.webApp=!1,this.silk=!1,this.audioData=!1,this.webAudio=!1,this.ogg=!1,this.opus=!1,this.mp3=!1,this.wav=!1,this.m4a=!1,this.webm=!1,this.iPhone=!1,this.iPhone4=!1,this.iPad=!1,this.pixelRatio=0,this.littleEndian=!1,this.fullscreen=!1,this.requestFullscreen="",this.cancelFullscreen="",this.fullscreenKeyboard=!1,this._checkAudio(),this._checkBrowser(),this._checkCSS3D(),this._checkDevice(),this._checkFeatures(),this._checkOS()},b.Device.prototype={_checkOS:function(){var a=navigator.userAgent;/Android/.test(a)?this.android=!0:/CrOS/.test(a)?this.chromeOS=!0:/iP[ao]d|iPhone/i.test(a)?this.iOS=!0:/Linux/.test(a)?this.linux=!0:/Mac OS/.test(a)?this.macOS=!0:/Windows/.test(a)&&(this.windows=!0,/Windows Phone/i.test(a)&&(this.windowsPhone=!0)),(this.windows||this.macOS||this.linux&&this.silk===!1)&&(this.desktop=!0),(this.windowsPhone||/Windows NT/i.test(a)&&/Touch/i.test(a))&&(this.desktop=!1)},_checkFeatures:function(){this.canvas=!!window.CanvasRenderingContext2D||this.cocoonJS;try{this.localStorage=!!localStorage.getItem}catch(a){this.localStorage=!1}this.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),this.fileSystem=!!window.requestFileSystem,this.webGL=function(){try{var a=document.createElement("canvas");return!!window.WebGLRenderingContext&&(a.getContext("webgl")||a.getContext("experimental-webgl"))}catch(b){return!1}}(),this.webGL=null===this.webGL||this.webGL===!1?!1:!0,this.worker=!!window.Worker,("ontouchstart"in document.documentElement||window.navigator.maxTouchPoints&&window.navigator.maxTouchPoints>1)&&(this.touch=!0),(window.navigator.msPointerEnabled||window.navigator.pointerEnabled)&&(this.mspointer=!0),this.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.quirksMode="CSS1Compat"===document.compatMode?!1:!0},checkFullScreenSupport:function(){for(var a=["requestFullscreen","requestFullScreen","webkitRequestFullscreen","webkitRequestFullScreen","msRequestFullscreen","msRequestFullScreen","mozRequestFullScreen","mozRequestFullscreen"],b=0;b0,this.typedArray=!0):(this.littleEndian=!1,this.typedArray=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(this.vibration=!0)},_checkCSS3D:function(){var a,b=document.createElement("p"),c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(b,null);for(var d in c)void 0!==b.style[d]&&(b.style[d]="translate3d(1px,1px,1px)",a=window.getComputedStyle(b).getPropertyValue(c[d]));document.body.removeChild(b),this.css3D=void 0!==a&&a.length>0&&"none"!==a},canPlayAudio:function(a){return"mp3"==a&&this.mp3?!0:"ogg"==a&&(this.ogg||this.opus)?!0:"m4a"==a&&this.m4a?!0:"wav"==a&&this.wav?!0:"webm"==a&&this.webm?!0:!1},isConsoleOpen:function(){return window.console&&window.console.firebug?!0:window.console?(console.profile(),console.profileEnd(),console.clear&&console.clear(),console.profiles.length>0):!1}},b.Device.prototype.constructor=b.Device,b.RequestAnimationFrame=function(a,b){"undefined"==typeof b&&(b=!1),this.game=a,this.isRunning=!1,this.forceSetTimeOut=b;for(var c=["ms","moz","webkit","o"],d=0;da},fuzzyGreaterThan:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),a>b-c},fuzzyCeil:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.ceil(a-b)},fuzzyFloor:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.floor(a+b)},average:function(){for(var a=[],b=0;b0?Math.floor(a):Math.ceil(a)},shear:function(a){return a%1},snapTo:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.round(a/b),c+a)},snapToFloor:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.floor(a/b),c+a)},snapToCeil:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.ceil(a/b),c+a)},snapToInArray:function(a,b,c){if("undefined"==typeof c&&(c=!0),c&&b.sort(),a=f-a?f:e},roundTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.round(a*d)/d},floorTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.floor(a*d)/d},ceilTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.ceil(a*d)/d},interpolateFloat:function(a,b,c){return(b-a)*c+a},angleBetween:function(a,b,c,d){return Math.atan2(c-a,d-b)},angleBetweenPoints:function(a,b){return Math.atan2(b.x-a.x,b.y-a.y)},reverseAngle:function(a){return this.normalizeAngle(a+Math.PI,!0)},normalizeAngle:function(a){return a%=2*Math.PI,a>=0?a:a+2*Math.PI},normalizeLatitude:function(a){return Math.max(-90,Math.min(90,a))},normalizeLongitude:function(a){return a%360==180?180:(a%=360,-180>a?a+360:a>180?a-360:a)},nearestAngleBetween:function(a,b,c){"undefined"==typeof c&&(c=!0);var d=c?Math.PI:180;return a=this.normalizeAngle(a,c),b=this.normalizeAngle(b,c),-d/2>a&&b>d/2&&(a+=2*d),-d/2>b&&a>d/2&&(b+=2*d),b-a},interpolateAngles:function(a,b,c,d,e){return"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=null),a=this.normalizeAngle(a,d),b=this.normalizeAngleToAnother(b,a,d),"function"==typeof e?e(c,a,b-a,1):this.interpolateFloat(a,b,c)},chanceRoll:function(a){return"undefined"==typeof a&&(a=50),0>=a?!1:a>=100?!0:100*Math.random()>=a?!1:!0},numberArray:function(a,b){for(var c=[],d=a;b>=d;d++)c.push(d);return c},maxAdd:function(a,b,c){return a+=b,a>c&&(a=c),a},minSub:function(a,b,c){return a-=b,c>a&&(a=c),a},wrap:function(a,b,c){var d=c-b;if(0>=d)return 0;var e=(a-b)%d;return 0>e&&(e+=d),e+b},wrapValue:function(a,b,c){var d;return a=Math.abs(a),b=Math.abs(b),c=Math.abs(c),d=(a+b)%c},randomSign:function(){return Math.random()>.5?1:-1},isOdd:function(a){return 1&a},isEven:function(a){return 1&a?!1:!0},max:function(){for(var a=1,b=0,c=arguments.length;c>a;a++)arguments[b]b;b++)a[b]b;b++)a[b]>a[c]&&(c=b);return a[c]},minProperty:function(a){if(2===arguments.length&&"object"==typeof arguments[1])var b=arguments[1];else var b=arguments.slice(1);for(var c=1,d=0,e=b.length;e>c;c++)b[c][a]c;c++)b[c][a]>b[d][a]&&(d=c);return b[d][a]},wrapAngle:function(a){return this.wrap(a,-180,180)},angleLimit:function(a,b,c){var d=a;return a>c?d=c:b>a&&(d=b),d},linearInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return 0>b?this.linear(a[0],a[1],d):b>1?this.linear(a[c],a[c-1],c-d):this.linear(a[e],a[e+1>c?c:e+1],d-e)},bezierInterpolation:function(a,b){for(var c=0,d=a.length-1,e=0;d>=e;e++)c+=Math.pow(1-b,d-e)*Math.pow(b,e)*a[e]*this.bernstein(d,e);return c},catmullRomInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return a[0]===a[c]?(0>b&&(e=Math.floor(d=c*(1+b))),this.catmullRom(a[(e-1+c)%c],a[e],a[(e+1)%c],a[(e+2)%c],d-e)):0>b?a[0]-(this.catmullRom(a[0],a[0],a[1],a[1],-d)-a[0]):b>1?a[c]-(this.catmullRom(a[c],a[c],a[c-1],a[c-1],d-c)-a[c]):this.catmullRom(a[e?e-1:0],a[e],a[e+1>c?c:e+1],a[e+2>c?c:e+2],d-e)},linear:function(a,b,c){return(b-a)*c+a},bernstein:function(a,b){return this.factorial(a)/this.factorial(b)/this.factorial(a-b)},catmullRom:function(a,b,c,d,e){var f=.5*(c-a),g=.5*(d-b),h=e*e,i=e*h;return(2*b-2*c+f+g)*i+(-3*b+3*c-2*f-g)*h+f*e+b},difference:function(a,b){return Math.abs(a-b)},getRandom:function(a,b,c){if("undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),null!=a){var d=c;if((0===d||d>a.length-b)&&(d=a.length-b),d>0)return a[b+Math.floor(Math.random()*d)]}return null},floor:function(a){var b=0|a;return a>0?b:b!=a?b-1:b},ceil:function(a){var b=0|a;return a>0?b!=a?b+1:b:b},sinCosGenerator:function(a,b,c,d){"undefined"==typeof b&&(b=1),"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1);for(var e=b,f=c,g=d*Math.PI/a,h=[],i=[],j=0;a>j;j++)f-=e*g,e+=f*g,h[j]=f,i[j]=e;return{sin:i,cos:h,length:a}},shift:function(a){var b=a.shift();return a.push(b),b},shuffleArray:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},distance:function(a,b,c,d){var e=a-c,f=b-d;return Math.sqrt(e*e+f*f)},distancePow:function(a,b,c,d,e){return"undefined"==typeof e&&(e=2),Math.sqrt(Math.pow(c-a,e)+Math.pow(d-b,e))},distanceRounded:function(a,c,d,e){return Math.round(b.Math.distance(a,c,d,e))},clamp:function(a,b,c){return b>a?b:a>c?c:a},clampBottom:function(a,b){return b>a?b:a},within:function(a,b,c){return Math.abs(a-b)<=c},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*(3-2*a))},smootherstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*a*(a*(6*a-15)+10))},sign:function(a){return 0>a?-1:a>0?1:0},p2px:function(a){return a*=20},px2p:function(a){return.05*a},p2pxi:function(a){return a*=-20},px2pi:function(a){return a*-.05},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}()},b.RandomDataGenerator=function(a){"undefined"==typeof a&&(a=[]),this.c=1,this.s0=0,this.s1=0,this.s2=0,this.sow(a)},b.RandomDataGenerator.prototype={rnd:function(){var a=2091639*this.s0+2.3283064365386963e-10*this.c;return this.c=0|a,this.s0=this.s1,this.s1=this.s2,this.s2=a-this.c,this.s2},sow:function(a){"undefined"==typeof a&&(a=[]),this.s0=this.hash(" "),this.s1=this.hash(this.s0),this.s2=this.hash(this.s1),this.c=1;for(var b,c=0;b=a[c++];)this.s0-=this.hash(b),this.s0+=~~(this.s0<0),this.s1-=this.hash(b),this.s1+=~~(this.s1<0),this.s2-=this.hash(b),this.s2+=~~(this.s2<0)},hash:function(a){var b,c,d;for(d=4022871197,a=a.toString(),c=0;c>>0,b-=d,b*=d,d=b>>>0,b-=d,d+=4294967296*b;return 2.3283064365386963e-10*(d>>>0)},integer:function(){return 4294967296*this.rnd.apply(this)},frac:function(){return this.rnd.apply(this)+1.1102230246251565e-16*(2097152*this.rnd.apply(this)|0)},real:function(){return this.integer()+this.frac()},integerInRange:function(a,b){return Math.round(this.realInRange(a,b))},realInRange:function(a,b){return this.frac()*(b-a)+a},normal:function(){return 1-2*this.frac()},uuid:function(){var a="",b="";for(b=a="";a++<36;b+=~a%5|3*a&4?(15^a?8^this.frac()*(20^a?16:4):4).toString(16):"-");return b},pick:function(a){return a[this.integerInRange(0,a.length)]},weightedPick:function(a){return a[~~(Math.pow(this.frac(),2)*a.length)]},timestamp:function(a,b){return this.realInRange(a||9466848e5,b||1577862e6)},angle:function(){return this.integerInRange(-180,180)}},b.RandomDataGenerator.prototype.constructor=b.RandomDataGenerator,b.QuadTree=function(a,b,c,d,e,f,g){this.maxObjects=10,this.maxLevels=4,this.level=0,this.bounds,this.objects,this.nodes,this.reset(a,b,c,d,e,f,g)},b.QuadTree.prototype={reset:function(a,b,c,d,e,f,g){this.maxObjects=e||10,this.maxLevels=f||4,this.level=g||0,this.bounds={x:Math.round(a),y:Math.round(b),width:c,height:d,subWidth:Math.floor(c/2),subHeight:Math.floor(d/2),right:Math.round(a)+Math.floor(c/2),bottom:Math.round(b)+Math.floor(d/2)},this.objects=[],this.nodes=[]},populate:function(a){a.forEach(this.populateHandler,this,!0)},populateHandler:function(a){a.body&&a.exists&&this.insert(a.body)},split:function(){this.level++,this.nodes[0]=new b.QuadTree(this.bounds.right,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[1]=new b.QuadTree(this.bounds.x,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[2]=new b.QuadTree(this.bounds.x,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[3]=new b.QuadTree(this.bounds.right,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level)},insert:function(a){var b,c=0;if(null!=this.nodes[0]&&(b=this.getIndex(a),-1!==b))return void this.nodes[b].insert(a);if(this.objects.push(a),this.objects.length>this.maxObjects&&this.levelthis.bounds.bottom&&(b=2):a.x>this.bounds.right&&(a.ythis.bounds.bottom&&(b=3)),b},retrieve:function(a){var b=this.objects,c=this.getIndex(a.body);return this.nodes[0]&&(-1!==c?b=b.concat(this.nodes[c].retrieve(a)):(b=b.concat(this.nodes[0].retrieve(a)),b=b.concat(this.nodes[1].retrieve(a)),b=b.concat(this.nodes[2].retrieve(a)),b=b.concat(this.nodes[3].retrieve(a)))),b},clear:function(){this.objects.length=0;for(var a=this.nodes.length;a--;)this.nodes[a].clear(),this.nodes.splice(a,1);this.nodes.length=0}},b.QuadTree.prototype.constructor=b.QuadTree,b.Net=function(a){this.game=a},b.Net.prototype={getHostName:function(){return window.location&&window.location.hostname?window.location.hostname:null},checkDomainName:function(a){return-1!==window.location.hostname.indexOf(a)},updateQueryString:function(a,b,c,d){"undefined"==typeof c&&(c=!1),("undefined"==typeof d||""===d)&&(d=window.location.href);var e="",f=new RegExp("([?|&])"+a+"=.*?(&|#|$)(.*)","gi");if(f.test(d))e="undefined"!=typeof b&&null!==b?d.replace(f,"$1"+a+"="+b+"$2$3"):d.replace(f,"$1$3").replace(/(&|\?)$/,"");else if("undefined"!=typeof b&&null!==b){var g=-1!==d.indexOf("?")?"&":"?",h=d.split("#");d=h[0]+g+a+"="+b,h[1]&&(d+="#"+h[1]),e=d}else e=d;return c?void(window.location.href=e):e},getQueryString:function(a){"undefined"==typeof a&&(a="");var b={},c=location.search.substring(1).split("&");for(var d in c){var e=c[d].split("=");if(e.length>1){if(a&&a==this.decodeURI(e[0]))return this.decodeURI(e[1]);b[this.decodeURI(e[0])]=this.decodeURI(e[1])}}return b},decodeURI:function(a){return decodeURIComponent(a.replace(/\+/g," "))}},b.Net.prototype.constructor=b.Net,b.TweenManager=function(a){this.game=a,this._tweens=[],this._add=[],this.game.onPause.add(this._pauseAll,this),this.game.onResume.add(this._resumeAll,this)},b.TweenManager.prototype={getAll:function(){return this._tweens},removeAll:function(){for(var a=0;aa;)this._tweens[a].update(this.game.time.now)?a++:(this._tweens.splice(a,1),b--);return this._add.length>0&&(this._tweens=this._tweens.concat(this._add),this._add.length=0),!0},isTweening:function(a){return this._tweens.some(function(b){return b._object===a})},_pauseAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a]._pause()},_resumeAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a]._resume()},pauseAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].pause()},resumeAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].resume(!0)}},b.TweenManager.prototype.constructor=b.TweenManager,b.Tween=function(a,c,d){this._object=a,this.game=c,this._manager=d,this._valuesStart={},this._valuesEnd={},this._valuesStartRepeat={},this._duration=1e3,this._repeat=0,this._yoyo=!1,this._reversed=!1,this._delayTime=0,this._startTime=null,this._easingFunction=b.Easing.Linear.None,this._interpolationFunction=b.Math.linearInterpolation,this._chainedTweens=[],this._onStartCallbackFired=!1,this._onUpdateCallback=null,this._onUpdateCallbackContext=null,this._paused=!1,this._pausedTime=0,this._codePaused=!1,this.pendingDelete=!1,this.onStart=new b.Signal,this.onLoop=new b.Signal,this.onComplete=new b.Signal,this.isRunning=!1},b.Tween.prototype={to:function(a,b,c,d,e,f,g){b=b||1e3,c=c||null,d=d||!1,e=e||0,f=f||0,g=g||!1;var h;return this._parent?(h=this._manager.create(this._object),this._lastChild.chain(h),this._lastChild=h):(h=this,this._parent=this,this._lastChild=this),h._repeat=f,h._duration=b,h._valuesEnd=a,null!==c&&(h._easingFunction=c),e>0&&(h._delayTime=e),h._yoyo=g,d?this.start():this},start:function(){if(null!==this.game&&null!==this._object){this._manager.add(this),this.isRunning=!0,this._onStartCallbackFired=!1,this._startTime=this.game.time.now+this._delayTime;for(var a in this._valuesEnd){if(Array.isArray(this._valuesEnd[a])){if(0===this._valuesEnd[a].length)continue;this._valuesEnd[a]=[this._object[a]].concat(this._valuesEnd[a])}this._valuesStart[a]=this._object[a],Array.isArray(this._valuesStart[a])||(this._valuesStart[a]*=1),this._valuesStartRepeat[a]=this._valuesStart[a]||0}return this}},generateData:function(a,b){if(null===this.game||null===this._object)return null; +this._startTime=0;for(var c in this._valuesEnd){if(Array.isArray(this._valuesEnd[c])){if(0===this._valuesEnd[c].length)continue;this._valuesEnd[c]=[this._object[c]].concat(this._valuesEnd[c])}this._valuesStart[c]=this._object[c],Array.isArray(this._valuesStart[c])||(this._valuesStart[c]*=1),this._valuesStartRepeat[c]=this._valuesStart[c]||0}for(var d=0,e=a*(this._duration/1e3),f=this._duration/e,g=[];e--;){var c,h=(d-this._startTime)/this._duration;h=h>1?1:h;var i=this._easingFunction(h),j={};for(c in this._valuesEnd){var k=this._valuesStart[c]||0,l=this._valuesEnd[c];l instanceof Array?j[c]=this._interpolationFunction(l,i):("string"==typeof l&&(l=k+parseFloat(l,10)),"number"==typeof l&&(j[c]=k+(l-k)*i))}g.push(j),d+=f}if(this._yoyo){var m=g.slice();m.reverse(),g=g.concat(m)}return"undefined"!=typeof b?b=b.concat(g):g},stop:function(){return this.isRunning=!1,this._onUpdateCallback=null,this._manager.remove(this),this},delay:function(a){return this._delayTime=a,this},repeat:function(a){return this._repeat=a,this},yoyo:function(a){return this._yoyo=a,this},easing:function(a){return this._easingFunction=a,this},interpolation:function(a){return this._interpolationFunction=a,this},chain:function(){return this._chainedTweens=arguments,this},loop:function(){return this._lastChild.chain(this),this},onUpdateCallback:function(a,b){return this._onUpdateCallback=a,this._onUpdateCallbackContext=b,this},pause:function(){this._codePaused=!0,this._paused=!0,this._pausedTime=this.game.time.now},_pause:function(){this._codePaused||(this._paused=!0,this._pausedTime=this.game.time.now)},resume:function(){this._paused&&(this._paused=!1,this._codePaused=!1,this._startTime+=this.game.time.now-this._pausedTime)},_resume:function(){this._codePaused||(this._startTime+=this.game.time.pauseDuration,this._paused=!1)},update:function(a){if(this.pendingDelete)return!1;if(this._paused||a1?1:c;var d=this._easingFunction(c);for(b in this._valuesEnd){var e=this._valuesStart[b]||0,f=this._valuesEnd[b];f instanceof Array?this._object[b]=this._interpolationFunction(f,d):("string"==typeof f&&(f=e+parseFloat(f,10)),"number"==typeof f&&(this._object[b]=e+(f-e)*d))}if(null!==this._onUpdateCallback&&this._onUpdateCallback.call(this._onUpdateCallbackContext,this,d),1==c){if(this._repeat>0){isFinite(this._repeat)&&this._repeat--;for(b in this._valuesStartRepeat){if("string"==typeof this._valuesEnd[b]&&(this._valuesStartRepeat[b]=this._valuesStartRepeat[b]+parseFloat(this._valuesEnd[b],10)),this._yoyo){var g=this._valuesStartRepeat[b];this._valuesStartRepeat[b]=this._valuesEnd[b],this._valuesEnd[b]=g,this._reversed=!this._reversed}this._valuesStart[b]=this._valuesStartRepeat[b]}return this._startTime=a+this._delayTime,this.onLoop.dispatch(this._object),!0}this.isRunning=!1,this.onComplete.dispatch(this._object);for(var h=0,i=this._chainedTweens.length;i>h;h++)this._chainedTweens[h].start(a);return!1}return!0}},b.Tween.prototype.constructor=b.Tween,b.Easing={Linear:{None:function(a){return a}},Quadratic:{In:function(a){return a*a},Out:function(a){return a*(2-a)},InOut:function(a){return(a*=2)<1?.5*a*a:-.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a:.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return(a*=2)<1?.5*a*a*a*a:-.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a*a*a},Out:function(a){return--a*a*a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a*a*a:.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:(a*=2)<1?.5*Math.pow(1024,a-1):.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1-Math.sqrt(1-a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return(a*=2)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),-(c*Math.pow(2,10*(a-=1))*Math.sin(2*(a-b)*Math.PI/d)))},Out:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),c*Math.pow(2,-10*a)*Math.sin(2*(a-b)*Math.PI/d)+1)},InOut:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),(a*=2)<1?-.5*c*Math.pow(2,10*(a-=1))*Math.sin(2*(a-b)*Math.PI/d):c*Math.pow(2,-10*(a-=1))*Math.sin(2*(a-b)*Math.PI/d)*.5+1)}},Back:{In:function(a){var b=1.70158;return a*a*((b+1)*a-b)},Out:function(a){var b=1.70158;return--a*a*((b+1)*a+b)+1},InOut:function(a){var b=2.5949095;return(a*=2)<1?.5*a*a*((b+1)*a-b):.5*((a-=2)*a*((b+1)*a+b)+2)}},Bounce:{In:function(a){return 1-b.Easing.Bounce.Out(1-a)},Out:function(a){return 1/2.75>a?7.5625*a*a:2/2.75>a?7.5625*(a-=1.5/2.75)*a+.75:2.5/2.75>a?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},InOut:function(a){return.5>a?.5*b.Easing.Bounce.In(2*a):.5*b.Easing.Bounce.Out(2*a-1)+.5}}},b.Time=function(a){this.game=a,this.time=0,this.now=0,this.elapsed=0,this.pausedTime=0,this.advancedTiming=!1,this.fps=0,this.fpsMin=1e3,this.fpsMax=0,this.msMin=1e3,this.msMax=0,this.physicsElapsed=0,this.frames=0,this.pauseDuration=0,this.timeToCall=0,this.lastTime=0,this.events=new b.Timer(this.game,!1),this._started=0,this._timeLastSecond=0,this._pauseStarted=0,this._justResumed=!1,this._timers=[],this._len=0,this._i=0},b.Time.prototype={boot:function(){this._started=Date.now(),this.events.start()},create:function(a){"undefined"==typeof a&&(a=!0);var c=new b.Timer(this.game,a);return this._timers.push(c),c},removeAll:function(){for(var a=0;athis._timeLastSecond+1e3&&(this.fps=Math.round(1e3*this.frames/(this.now-this._timeLastSecond)),this.fpsMin=this.game.math.min(this.fpsMin,this.fps),this.fpsMax=this.game.math.max(this.fpsMax,this.fps),this._timeLastSecond=this.now,this.frames=0)),this.time=this.now,this.lastTime=a+this.timeToCall,!this.game.paused)for(this.events.update(this.now),this._i=0,this._len=this._timers.length;this._i0&&(this.events.sort(this.sortHandler),this.nextTick=this.events[0].tick)},sortHandler:function(a,b){return a.tickb.tick?1:0},update:function(a){if(this.paused)return!0;for(this._now=a,this._len=this.events.length,this._i=0;this._i=this.nextTick&&this._len>0){for(this._i=0;this._i=this.events[this._i].tick;){var b=this._now-this.events[this._i].tick,c=this._now+this.events[this._i].delay-b;0>c&&(c=this._now+this.events[this._i].delay),this.events[this._i].loop===!0?(this.events[this._i].tick=c,this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args)):this.events[this._i].repeatCount>0?(this.events[this._i].repeatCount--,this.events[this._i].tick=c,this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args)):(this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args),this.events.splice(this._i,1),this._len--),this._i++}this.events.length>0?this.order():(this.expired=!0,this.onComplete.dispatch(this))}return this.expired&&this.autoDestroy?!1:!0},pause:function(){this.running&&!this.expired&&(this._pauseStarted=this.game.time.now,this.paused=!0,this._codePaused=!0)},_pause:function(){this.running&&!this.expired&&(this._pauseStarted=this.game.time.now,this.paused=!0)},resume:function(){if(this.running&&!this.expired){for(var a=this.game.time.now-this._pauseStarted,b=0;bthis._now?this.nextTick-this._now:0}}),Object.defineProperty(b.Timer.prototype,"length",{get:function(){return this.events.length}}),Object.defineProperty(b.Timer.prototype,"ms",{get:function(){return this._now-this._started}}),Object.defineProperty(b.Timer.prototype,"seconds",{get:function(){return.001*this.ms}}),b.Timer.prototype.constructor=b.Timer,b.TimerEvent=function(a,b,c,d,e,f,g,h){this.timer=a,this.delay=b,this.tick=c,this.repeatCount=d-1,this.loop=e,this.callback=f,this.callbackContext=g,this.args=h,this.pendingDelete=!1},b.TimerEvent.prototype.constructor=b.TimerEvent,b.AnimationManager=function(a){this.sprite=a,this.game=a.game,this.currentFrame=null,this.updateIfVisible=!0,this.isLoaded=!1,this._frameData=null,this._anims={},this._outputFrames=[]},b.AnimationManager.prototype={loadFrameData:function(a){this._frameData=a,this.frame=0,this.isLoaded=!0},add:function(a,c,d,e,f){return null==this._frameData?void console.warn("No FrameData available for Phaser.Animation "+a):(c=c||[],d=d||60,"undefined"==typeof e&&(e=!1),"undefined"==typeof f&&(f=c&&"number"==typeof c[0]?!0:!1),null==this.sprite.events.onAnimationStart&&(this.sprite.events.onAnimationStart=new b.Signal,this.sprite.events.onAnimationComplete=new b.Signal,this.sprite.events.onAnimationLoop=new b.Signal),this._outputFrames.length=0,this._frameData.getFrameIndexes(c,f,this._outputFrames),this._anims[a]=new b.Animation(this.game,this.sprite,a,this._frameData,this._outputFrames,d,e),this.currentAnim=this._anims[a],this.currentFrame=this.currentAnim.currentFrame,this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1),this._anims[a])},validateFrames:function(a,b){"undefined"==typeof b&&(b=!0);for(var c=0;cthis._frameData.total)return!1}else if(this._frameData.checkFrameName(a[c])===!1)return!1;return!0},play:function(a,b,c,d){if(this._anims[a]){if(this.currentAnim!=this._anims[a])return this.currentAnim=this._anims[a],this.currentAnim.paused=!1,this.currentAnim.play(b,c,d);if(this.currentAnim.isPlaying===!1)return this.currentAnim.paused=!1,this.currentAnim.play(b,c,d)}},stop:function(a,b){"undefined"==typeof b&&(b=!1),"string"==typeof a?this._anims[a]&&(this.currentAnim=this._anims[a],this.currentAnim.stop(b)):this.currentAnim&&this.currentAnim.stop(b)},update:function(){return this.updateIfVisible&&!this.sprite.visible?!1:this.currentAnim&&this.currentAnim.update()===!0?(this.currentFrame=this.currentAnim.currentFrame,!0):!1},getAnimation:function(a){return"string"==typeof a&&this._anims[a]?this._anims[a]:null},refreshFrame:function(){this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1)},destroy:function(){this._anims={},this._frameData=null,this._frameIndex=0,this.currentAnim=null,this.currentFrame=null}},b.AnimationManager.prototype.constructor=b.AnimationManager,Object.defineProperty(b.AnimationManager.prototype,"frameData",{get:function(){return this._frameData}}),Object.defineProperty(b.AnimationManager.prototype,"frameTotal",{get:function(){return this._frameData?this._frameData.total:-1}}),Object.defineProperty(b.AnimationManager.prototype,"paused",{get:function(){return this.currentAnim.isPaused},set:function(a){this.currentAnim.paused=a}}),Object.defineProperty(b.AnimationManager.prototype,"frame",{get:function(){return this.currentFrame?this._frameIndex:void 0},set:function(a){"number"==typeof a&&this._frameData&&null!==this._frameData.getFrame(a)&&(this.currentFrame=this._frameData.getFrame(a),this._frameIndex=a,this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1))}}),Object.defineProperty(b.AnimationManager.prototype,"frameName",{get:function(){return this.currentFrame?this.currentFrame.name:void 0},set:function(a){"string"==typeof a&&this._frameData&&null!==this._frameData.getFrameByName(a)?(this.currentFrame=this._frameData.getFrameByName(a),this._frameIndex=this.currentFrame.index,this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this.sprite.__tilePattern&&(this.__tilePattern=!1,this.tilingTexture=!1)):console.warn("Cannot set frameName: "+a)}}),b.Animation=function(a,c,d,e,f,g,h){this.game=a,this._parent=c,this._frameData=e,this.name=d,this._frames=[],this._frames=this._frames.concat(f),this.delay=1e3/g,this.loop=h,this.loopCount=0,this.killOnComplete=!1,this.isFinished=!1,this.isPlaying=!1,this.isPaused=!1,this._pauseStartTime=0,this._frameIndex=0,this._frameDiff=0,this._frameSkip=1,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.onStart=new b.Signal,this.onComplete=new b.Signal,this.onLoop=new b.Signal,this.game.onPause.add(this.onPause,this),this.game.onResume.add(this.onResume,this)},b.Animation.prototype={play:function(a,b,c){return"number"==typeof a&&(this.delay=1e3/a),"boolean"==typeof b&&(this.loop=b),"undefined"!=typeof c&&(this.killOnComplete=c),this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this.loopCount=0,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this._parent.__tilePattern&&(this._parent.__tilePattern=!1,this._parent.tilingTexture=!1),this._parent.events.onAnimationStart.dispatch(this._parent,this),this.onStart.dispatch(this._parent,this),this},restart:function(){this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this.loopCount=0,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.onStart.dispatch(this._parent,this)},stop:function(a,b){"undefined"==typeof a&&(a=!1),"undefined"==typeof b&&(b=!1),this.isPlaying=!1,this.isFinished=!0,this.paused=!1,a&&(this.currentFrame=this._frameData.getFrame(this._frames[0])),b&&(this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.onComplete.dispatch(this._parent,this))},onPause:function(){this.isPlaying&&(this._frameDiff=this._timeNextFrame-this.game.time.now)},onResume:function(){this.isPlaying&&(this._timeNextFrame=this.game.time.now+this._frameDiff)},update:function(){return this.isPaused?!1:this.isPlaying===!0&&this.game.time.now>=this._timeNextFrame?(this._frameSkip=1,this._frameDiff=this.game.time.now-this._timeNextFrame,this._timeLastFrame=this.game.time.now,this._frameDiff>this.delay&&(this._frameSkip=Math.floor(this._frameDiff/this.delay),this._frameDiff-=this._frameSkip*this.delay),this._timeNextFrame=this.game.time.now+(this.delay-this._frameDiff),this._frameIndex+=this._frameSkip,this._frameIndex>=this._frames.length?this.loop?(this._frameIndex%=this._frames.length,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&(this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this._parent.__tilePattern&&(this._parent.__tilePattern=!1,this._parent.tilingTexture=!1)),this.loopCount++,this._parent.events.onAnimationLoop.dispatch(this._parent,this),this.onLoop.dispatch(this._parent,this)):this.complete():(this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&(this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]),this._parent.__tilePattern&&(this._parent.__tilePattern=!1,this._parent.tilingTexture=!1))),!0):!1},destroy:function(){this.game=null,this._parent=null,this._frames=null,this._frameData=null,this.currentFrame=null,this.isPlaying=!1,this.onStart.destroy(),this.onLoop.destroy(),this.onComplete.destroy(),this.game.onPause.remove(this.onPause,this),this.game.onResume.remove(this.onResume,this)},complete:function(){this.isPlaying=!1,this.isFinished=!0,this.paused=!1,this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.onComplete.dispatch(this._parent,this),this.killOnComplete&&this._parent.kill()}},b.Animation.prototype.constructor=b.Animation,Object.defineProperty(b.Animation.prototype,"paused",{get:function(){return this.isPaused},set:function(a){this.isPaused=a,a?this._pauseStartTime=this.game.time.now:this.isPlaying&&(this._timeNextFrame=this.game.time.now+this.delay)}}),Object.defineProperty(b.Animation.prototype,"frameTotal",{get:function(){return this._frames.length}}),Object.defineProperty(b.Animation.prototype,"frame",{get:function(){return null!==this.currentFrame?this.currentFrame.index:this._frameIndex},set:function(a){this.currentFrame=this._frameData.getFrame(this._frames[a]),null!==this.currentFrame&&(this._frameIndex=a,this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]))}}),Object.defineProperty(b.Animation.prototype,"speed",{get:function(){return Math.round(1e3/this.delay)},set:function(a){a>=1&&(this.delay=1e3/a)}}),b.Animation.generateFrameNames=function(a,c,d,e,f){"undefined"==typeof e&&(e="");var g=[],h="";if(d>c)for(var i=c;d>=i;i++)h="number"==typeof f?b.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);else for(var i=c;i>=d;i--)h="number"==typeof f?b.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);return g},b.Frame=function(a,c,d,e,f,g,h){this.index=a,this.x=c,this.y=d,this.width=e,this.height=f,this.name=g,this.uuid=h,this.centerX=Math.floor(e/2),this.centerY=Math.floor(f/2),this.distance=b.Math.distance(0,0,e,f),this.rotated=!1,this.rotationDirection="cw",this.trimmed=!1,this.sourceSizeW=e,this.sourceSizeH=f,this.spriteSourceSizeX=0,this.spriteSourceSizeY=0,this.spriteSourceSizeW=0,this.spriteSourceSizeH=0},b.Frame.prototype={setTrim:function(a,b,c,d,e,f,g){this.trimmed=a,a&&(this.width=b,this.height=c,this.sourceSizeW=b,this.sourceSizeH=c,this.centerX=Math.floor(b/2),this.centerY=Math.floor(c/2),this.spriteSourceSizeX=d,this.spriteSourceSizeY=e,this.spriteSourceSizeW=f,this.spriteSourceSizeH=g)},getRect:function(a){return"undefined"==typeof a?a=new b.Rectangle(this.x,this.y,this.width,this.height):a.setTo(this.x,this.y,this.width,this.height),a}},b.Frame.prototype.constructor=b.Frame,b.FrameData=function(){this._frames=[],this._frameNames=[]},b.FrameData.prototype={addFrame:function(a){return a.index=this._frames.length,this._frames.push(a),""!==a.name&&(this._frameNames[a.name]=a.index),a},getFrame:function(a){return a>this._frames.length&&(a=0),this._frames[a]},getFrameByName:function(a){return"number"==typeof this._frameNames[a]?this._frames[this._frameNames[a]]:null},checkFrameName:function(a){return null==this._frameNames[a]?!1:!0},getFrameRange:function(a,b,c){"undefined"==typeof c&&(c=[]);for(var d=a;b>=d;d++)c.push(this._frames[d]);return c},getFrames:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0;dd;d++)c.push(b?this.getFrame(a[d]):this.getFrameByName(a[d]));return c},getFrameIndexes:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0,e=this._frames.length;e>d;d++)c.push(this._frames[d].index);else for(var d=0,e=a.length;e>d;d++)b?c.push(a[d]):this.getFrameByName(a[d])&&c.push(this.getFrameByName(a[d]).index);return c}},b.FrameData.prototype.constructor=b.FrameData,Object.defineProperty(b.FrameData.prototype,"total",{get:function(){return this._frames.length}}),b.AnimationParser={spriteSheet:function(a,c,d,e,f,g,h){var i=a.cache.getImage(c);if(null==i)return null;var j=i.width,k=i.height;0>=d&&(d=Math.floor(-j/Math.min(-1,d))),0>=e&&(e=Math.floor(-k/Math.min(-1,e)));var l=Math.floor((j-g)/(d+h)),m=Math.floor((k-g)/(e+h)),n=l*m;if(-1!==f&&(n=f),0===j||0===k||d>j||e>k||0===n)return console.warn("Phaser.AnimationParser.spriteSheet: width/height zero or width/height < given frameWidth/frameHeight"),null;for(var o=new b.FrameData,p=g,q=g,r=0;n>r;r++){var s=a.rnd.uuid();o.addFrame(new b.Frame(r,p,q,d,e,"",s)),PIXI.TextureCache[s]=new PIXI.Texture(PIXI.BaseTextureCache[c],{x:p,y:q,width:d,height:e}),p+=d+h,p+d>j&&(p=g,q+=e+h)}return o},JSONData:function(a,c,d){if(!c.frames)return console.warn("Phaser.AnimationParser.JSONData: Invalid Texture Atlas JSON given, missing 'frames' array"),void console.log(c);for(var e,f=new b.FrameData,g=c.frames,h=0;h tag");for(var e,f,g,h,i,j,k,l,m,n,o,p,q=new b.FrameData,r=c.getElementsByTagName("SubTexture"),s=0;s0)for(var c=0;c0)for(var c=0;c0)for(var c=0;c0?(this._fileIndex=0,this._progressChunk=100/this._fileList.length,this.loadFile()):(this.progress=100,this.progressFloat=100,this.hasLoaded=!0,this.onLoadComplete.dispatch()))},loadFile:function(){if(!this._fileList[this._fileIndex])return void console.warn("Phaser.Loader loadFile invalid index "+this._fileIndex);var a=this._fileList[this._fileIndex],c=this;switch(a.type){case"image":case"spritesheet":case"textureatlas":case"bitmapfont":a.data=new Image,a.data.name=a.key,a.data.onload=function(){return c.fileComplete(c._fileIndex)},a.data.onerror=function(){return c.fileError(c._fileIndex)},this.crossOrigin&&(a.data.crossOrigin=this.crossOrigin),a.data.src=this.baseURL+a.url;break;case"audio":a.url=this.getAudioURL(a.url),null!==a.url?this.game.sound.usingWebAudio?(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="arraybuffer",this._xhr.onload=function(){return c.fileComplete(c._fileIndex)},this._xhr.onerror=function(){return c.fileError(c._fileIndex)},this._xhr.send()):this.game.sound.usingAudioTag&&(this.game.sound.touchLocked?(a.data=new Audio,a.data.name=a.key,a.data.preload="auto",a.data.src=this.baseURL+a.url,this.fileComplete(this._fileIndex)):(a.data=new Audio,a.data.name=a.key,a.data.onerror=function(){return c.fileError(c._fileIndex)},a.data.preload="auto",a.data.src=this.baseURL+a.url,a.data.addEventListener("canplaythrough",b.GAMES[this.game.id].load.fileComplete(this._fileIndex),!1),a.data.load())):this.fileError(this._fileIndex);break;case"json":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return c.jsonLoadComplete(c._fileIndex)},this._xhr.send();break;case"tilemap":if(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",a.format===b.Tilemap.TILED_JSON)this._xhr.onload=function(){return c.jsonLoadComplete(c._fileIndex)};else{if(a.format!==b.Tilemap.CSV)throw new Error("Phaser.Loader. Invalid Tilemap format: "+a.format);this._xhr.onload=function(){return c.csvLoadComplete(c._fileIndex)}}this._xhr.onerror=function(){return c.dataLoadError(c._fileIndex)},this._xhr.send();break;case"text":case"script":case"physics":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return c.fileComplete(c._fileIndex)},this._xhr.onerror=function(){return c.fileError(c._fileIndex)},this._xhr.send();break;case"binary":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="arraybuffer",this._xhr.onload=function(){return c.fileComplete(c._fileIndex)},this._xhr.onerror=function(){return c.fileError(c._fileIndex)},this._xhr.send()}},getAudioURL:function(a){var b;"string"==typeof a&&(a=[a]);for(var c=0;c100&&(this.progress=100),null!==this.preloadSprite&&(0===this.preloadSprite.direction?this.preloadSprite.crop.width=Math.floor(this.preloadSprite.width/100*this.progress):this.preloadSprite.crop.height=Math.floor(this.preloadSprite.height/100*this.progress)),this.onFileComplete.dispatch(this.progress,this._fileList[a].key,b,this.totalLoadedFiles(),this._fileList.length),this.totalQueuedFiles()>0?(this._fileIndex++,this.loadFile()):(this.hasLoaded=!0,this.isLoading=!1,this.removeAll(),this.onLoadComplete.dispatch())},totalLoadedFiles:function(){for(var a=0,b=0;b=this.durationMS&&(this.usingWebAudio?this.loop?(this.onLoop.dispatch(this),""===this.currentMarker?(this.currentTime=0,this.startTime=this.game.time.now):(this.onMarkerComplete.dispatch(this.currentMarker,this),this.play(this.currentMarker,0,this.volume,!0,!0))):this.stop():this.loop?(this.onLoop.dispatch(this),this.play(this.currentMarker,0,this.volume,!0,!0)):this.stop()))},play:function(a,b,c,d,e){if(a=a||"",b=b||0,"undefined"==typeof c&&(c=this._volume),"undefined"==typeof d&&(d=this.loop),"undefined"==typeof e&&(e=!0),this.isPlaying!==!0||e!==!1||this.override!==!1){if(this.isPlaying&&this.override&&(this.usingWebAudio?"undefined"==typeof this._sound.stop?this._sound.noteOff(0):this._sound.stop(0):this.usingAudioTag&&(this._sound.pause(),this._sound.currentTime=0)),this.currentMarker=a,""!==a){if(!this.markers[a])return void console.warn("Phaser.Sound.play: audio marker "+a+" doesn't exist");this.position=this.markers[a].start,this.volume=this.markers[a].volume,this.loop=this.markers[a].loop,this.duration=this.markers[a].duration,this.durationMS=this.markers[a].durationMS,this._tempMarker=a,this._tempPosition=this.position,this._tempVolume=this.volume,this._tempLoop=this.loop}else this.position=b,this.volume=c,this.loop=d,this.duration=0,this.durationMS=0,this._tempMarker=a,this._tempPosition=b,this._tempVolume=c,this._tempLoop=d;this.usingWebAudio?this.game.cache.isSoundDecoded(this.key)?(null==this._buffer&&(this._buffer=this.game.cache.getSoundData(this.key)),this._sound=this.context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.connect(this.externalNode?this.externalNode.input:this.gainNode),this.totalDuration=this._sound.buffer.duration,0===this.duration&&(this.duration=this.totalDuration,this.durationMS=1e3*this.totalDuration),this.loop&&""===a&&(this._sound.loop=!0),"undefined"==typeof this._sound.start?this._sound.noteGrainOn(0,this.position,this.duration):this._sound.start(0,this.position,this.duration),this.isPlaying=!0,this.startTime=this.game.time.now,this.currentTime=0,this.stopTime=this.startTime+this.durationMS,this.onPlay.dispatch(this)):(this.pendingPlayback=!0,this.game.cache.getSound(this.key)&&this.game.cache.getSound(this.key).isDecoding===!1&&this.game.sound.decode(this.key,this)):this.game.cache.getSound(this.key)&&this.game.cache.getSound(this.key).locked?(this.game.cache.reloadSound(this.key),this.pendingPlayback=!0):this._sound&&(this.game.device.cocoonJS||4===this._sound.readyState)?(this._sound.play(),this.totalDuration=this._sound.duration,0===this.duration&&(this.duration=this.totalDuration,this.durationMS=1e3*this.totalDuration),this._sound.currentTime=this.position,this._sound.muted=this._muted,this._sound.volume=this._muted?0:this._volume,this.isPlaying=!0,this.startTime=this.game.time.now,this.currentTime=0,this.stopTime=this.startTime+this.durationMS,this.onPlay.dispatch(this)):this.pendingPlayback=!0}},restart:function(a,b,c,d){a=a||"",b=b||0,c=c||1,"undefined"==typeof d&&(d=!1),this.play(a,b,c,d,!0)},pause:function(){this.isPlaying&&this._sound&&(this.stop(),this.isPlaying=!1,this.paused=!0,this.pausedPosition=this.currentTime,this.pausedTime=this.game.time.now,this.onPause.dispatch(this))},resume:function(){if(this.paused&&this._sound){if(this.usingWebAudio){var a=this.position+this.pausedPosition/1e3;this._sound=this.context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.connect(this.externalNode?this.externalNode.input:this.gainNode),this.loop&&(this._sound.loop=!0),"undefined"==typeof this._sound.start?this._sound.noteGrainOn(0,a,this.duration):this._sound.start(0,a,this.duration)}else this._sound.play();this.isPlaying=!0,this.paused=!1,this.startTime+=this.game.time.now-this.pausedTime,this.onResume.dispatch(this)}},stop:function(){this.isPlaying&&this._sound&&(this.usingWebAudio?"undefined"==typeof this._sound.stop?this._sound.noteOff(0):this._sound.stop(0):this.usingAudioTag&&(this._sound.pause(),this._sound.currentTime=0)),this.isPlaying=!1;var a=this.currentMarker;""!==this.currentMarker&&this.onMarkerComplete.dispatch(this.currentMarker,this),this.currentMarker="",this.onStop.dispatch(this,a)}},b.Sound.prototype.constructor=b.Sound,Object.defineProperty(b.Sound.prototype,"isDecoding",{get:function(){return this.game.cache.getSound(this.key).isDecoding}}),Object.defineProperty(b.Sound.prototype,"isDecoded",{get:function(){return this.game.cache.isSoundDecoded(this.key)}}),Object.defineProperty(b.Sound.prototype,"mute",{get:function(){return this._muted},set:function(a){a=a||null,a?(this._muted=!0,this.usingWebAudio?(this._muteVolume=this.gainNode.gain.value,this.gainNode.gain.value=0):this.usingAudioTag&&this._sound&&(this._muteVolume=this._sound.volume,this._sound.volume=0)):(this._muted=!1,this.usingWebAudio?this.gainNode.gain.value=this._muteVolume:this.usingAudioTag&&this._sound&&(this._sound.volume=this._muteVolume)),this.onMute.dispatch(this)}}),Object.defineProperty(b.Sound.prototype,"volume",{get:function(){return this._volume},set:function(a){this.usingWebAudio?(this._volume=a,this.gainNode.gain.value=a):this.usingAudioTag&&this._sound&&a>=0&&1>=a&&(this._volume=a,this._sound.volume=a)}}),b.SoundManager=function(a){this.game=a,this.onSoundDecode=new b.Signal,this._codeMuted=!1,this._muted=!1,this._unlockSource=null,this._volume=1,this._sounds=[],this.context=null,this.usingWebAudio=!0,this.usingAudioTag=!1,this.noAudio=!1,this.connectToMaster=!0,this.touchLocked=!1,this.channels=32},b.SoundManager.prototype={boot:function(){if(this.game.device.iOS&&this.game.device.webAudio===!1&&(this.channels=1),this.game.device.iOS||window.PhaserGlobal&&window.PhaserGlobal.fakeiOSTouchLock?(this.game.input.touch.callbackContext=this,this.game.input.touch.touchStartCallback=this.unlock,this.game.input.mouse.callbackContext=this,this.game.input.mouse.mouseDownCallback=this.unlock,this.touchLocked=!0):this.touchLocked=!1,window.PhaserGlobal){if(window.PhaserGlobal.disableAudio===!0)return this.usingWebAudio=!1,void(this.noAudio=!0);if(window.PhaserGlobal.disableWebAudio===!0)return this.usingWebAudio=!1,this.usingAudioTag=!0,void(this.noAudio=!1)}window.AudioContext?this.context=new window.AudioContext:window.webkitAudioContext?this.context=new window.webkitAudioContext:window.Audio?(this.usingWebAudio=!1,this.usingAudioTag=!0):(this.usingWebAudio=!1,this.noAudio=!0),null!==this.context&&(this.masterGain="undefined"==typeof this.context.createGain?this.context.createGainNode():this.context.createGain(),this.masterGain.gain.value=1,this.masterGain.connect(this.context.destination))},unlock:function(){if(this.touchLocked!==!1)if(this.game.device.webAudio===!1||window.PhaserGlobal&&window.PhaserGlobal.disableWebAudio===!0)this.touchLocked=!1,this._unlockSource=null,this.game.input.touch.callbackContext=null,this.game.input.touch.touchStartCallback=null,this.game.input.mouse.callbackContext=null,this.game.input.mouse.mouseDownCallback=null;else{var a=this.context.createBuffer(1,1,22050);this._unlockSource=this.context.createBufferSource(),this._unlockSource.buffer=a,this._unlockSource.connect(this.context.destination),this._unlockSource.noteOn(0)}},stopAll:function(){for(var a=0;a255)return b.Color.getColor(255,255,255);if(a>c)return b.Color.getColor(255,255,255);var e=a+Math.round(Math.random()*(c-a)),f=a+Math.round(Math.random()*(c-a)),g=a+Math.round(Math.random()*(c-a));return b.Color.getColor32(d,e,f,g)},getRGB:function(a){return{alpha:a>>>24,red:a>>16&255,green:a>>8&255,blue:255&a}},getWebRGB:function(a){var b=(a>>>24)/255,c=a>>16&255,d=a>>8&255,e=255&a;return"rgba("+c.toString()+","+d.toString()+","+e.toString()+","+b.toString()+")"},getAlpha:function(a){return a>>>24},getAlphaFloat:function(a){return(a>>>24)/255},getRed:function(a){return a>>16&255},getGreen:function(a){return a>>8&255},getBlue:function(a){return 255&a}},b.Physics=function(a,c){this.game=a,this.config=c,this.arcade=new b.Physics.Arcade(a),this.p2=null,this.ninja=null,this.box2d=null,this.chipmunk=null},b.Physics.ARCADE=0,b.Physics.P2=1,b.Physics.NINJA=2,b.Physics.BOX2D=3,b.Physics.CHIPMUNK=5,b.Physics.prototype={startSystem:function(a){a===b.Physics.ARCADE&&null===this.arcade?this.arcade=new b.Physics.Arcade(this.game):a===b.Physics.P2&&null===this.p2&&(this.p2=new b.Physics.P2(this.game,this.config)),a===b.Physics.NINJA&&null===this.ninja?this.ninja=new b.Physics.Ninja(this.game):a===b.Physics.BOX2D&&null===this.box2d||a===b.Physics.CHIPMUNK&&null===this.chipmunk},enable:function(a,c){"undefined"==typeof c&&(c=b.Physics.ARCADE);var d=1;if(a instanceof b.Group);else for(Array.isArray(a)?d=a.length:a=[a];d--;)null===a[d].body&&(c===b.Physics.ARCADE?a[d].body=new b.Physics.Arcade.Body(a[d]):c===b.Physics.P2?(a[d].body=new b.Physics.P2.Body(this.game,a[d],a[d].x,a[d].y,1),a[d].anchor.set(.5)):c===b.Physics.NINJA&&(a[d].body=new b.Physics.Ninja.Body(this.ninja,a[d]),a[d].anchor.set(.5)))},update:function(){this.p2&&this.p2.update()},setBoundsToWorld:function(){this.ninja&&this.ninja.setBoundsToWorld()},clear:function(){this.p2&&this.p2.clear()}},b.Physics.prototype.constructor=b.Physics,b.Physics.Arcade=function(a){this.game=a,this.gravity=new b.Point,this.bounds=new b.Rectangle(0,0,a.world.width,a.world.height),this.maxObjects=10,this.maxLevels=4,this.OVERLAP_BIAS=4,this.quadTree=new b.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),this.quadTreeID=0,this._bounds1=new b.Rectangle,this._bounds2=new b.Rectangle,this._overlap=0,this._maxOverlap=0,this._velocity1=0,this._velocity2=0,this._newVelocity1=0,this._newVelocity2=0,this._average=0,this._mapData=[],this._mapTiles=0,this._result=!1,this._total=0,this._angle=0,this._dx=0,this._dy=0,this._intersection=new b.Rectangle},b.Physics.Arcade.prototype.constructor=b.Physics.Arcade,b.Physics.Arcade.prototype={enable:function(a,c){"undefined"==typeof c&&(c=!0);var d=1;for(Array.isArray(a)?d=a.length:a=[a];d--;)a[d]instanceof b.Group?a[d].forEach(this.enableBody,this,!1,c):this.enableBody(a[d])},enableBody:function(a,c){return a instanceof b.Group?void this.enable(a,!0,c):(a.hasOwnProperty("body")&&null===a.body&&(a.body=new b.Physics.Arcade.Body(a)),void(c&&a.hasOwnProperty("children")&&a.children.forEach(this.enable,this)))},updateMotion:function(a){this._velocityDelta=.5*(this.computeVelocity(a.angularVelocity,a.angularAcceleration,a.angularDrag,a.maxAngular,0)-a.angularVelocity),a.angularVelocity+=this._velocityDelta,a.rotation+=a.angularVelocity*this.game.time.physicsElapsed,a.angularVelocity+=this._velocityDelta,a.velocity.x+=this.gravity.x*this.game.time.physicsElapsed*a.gravityScale.x,a.velocity.y+=this.gravity.y*this.game.time.physicsElapsed*a.gravityScale.y,a.velocity.x=this.computeVelocity(a.velocity.x,a.acceleration.x,a.drag.x,a.maxVelocity.x),a.velocity.y=this.computeVelocity(a.velocity.y,a.acceleration.y,a.drag.y,a.maxVelocity.y)},computeVelocity:function(a,b,c,d){return d=d||1e4,b?a+b*this.game.time.physicsElapsed:c&&(this._drag=c*this.game.time.physicsElapsed,a-this._drag>0?a-=this._drag:a+this._drag<0?a+=this._drag:a=0),a>d?a=d:-d>a&&(a=-d),a},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!1);else this.collideHandler(a,b,c,d,e,!1);return this._total>0},collideHandler:function(a,c,d,e,f,g){return"undefined"!=typeof c||a.type!==b.GROUP&&a.type!==b.EMITTER?void(a&&c&&a.exists&&c.exists&&(a.type==b.SPRITE||a.type==b.TILESPRITE?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsSprite(a,c,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideSpriteVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,c,d,e,f):a.type==b.GROUP?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsGroup(c,a,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideGroupVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,c,d,e,f):a.type==b.TILEMAPLAYER?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsTilemapLayer(c,a,d,e,f):(c.type==b.GROUP||c.type==b.EMITTER)&&this.collideGroupVsTilemapLayer(c,a,d,e,f):a.type==b.EMITTER&&(c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsGroup(c,a,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideGroupVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,c,d,e,f)))):void this.collideGroupVsSelf(a,d,e,f,g)},collideSpriteVsSprite:function(a,b,c,d,e,f){this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++)},collideSpriteVsGroup:function(a,c,d,e,f,g){if(0!==c.length){this.quadTree.clear(),this.quadTree=new b.QuadTree(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this.quadTree.populate(c),this._potentials=this.quadTree.retrieve(a);for(var h=0,i=this._potentials.length;i>h;h++)this.separate(a.body,this._potentials[h],e,f,g)&&(d&&d.call(f,a,this._potentials[h].sprite),this._total++)}},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a.children[g]&&a.children[h]&&a.children[g].exists&&a.children[h].exists&&this.collideSpriteVsSprite(a.children[g],a.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length)for(var g=0,h=a.children.length;h>g;g++)a.children[g].exists&&this.collideSpriteVsGroup(a.children[g],b,c,d,e,f)},collideSpriteVsTilemapLayer:function(a,b){this._mapData=b.getIntersectingTiles(a.body.position.x,a.body.position.y,a.body.width,a.body.height,!0),0!==this._mapData.length&&this.separateTiles(a.body,this._mapData)},collideGroupVsTilemapLayer:function(a,b,c,d,e){if(0!==a.length)for(var f=0,g=a.children.length;g>f;f++)a.children[f].exists&&this.collideSpriteVsTilemapLayer(a.children[f],b,c,d,e)},separate:function(a,c,d,e,f){return b.Rectangle.intersects(a,c)?d&&d.call(e,a.sprite,c.sprite)===!1?!1:this.separateX(a,c,f)||this.separateY(a,c,f)?(this._result=!0,!0):!1:!1},separateX:function(a,c,d){return a.immovable&&c.immovable?!1:(this._overlap=0,b.Rectangle.intersects(a,c)&&(this._maxOverlap=a.deltaAbsX()+c.deltaAbsX()+this.OVERLAP_BIAS,0===a.deltaX()&&0===c.deltaX()?(a.embedded=!0,c.embedded=!0):a.deltaX()>c.deltaX()?(this._overlap=a.x+a.width-c.x,this._overlap>this._maxOverlap||a.checkCollision.right===!1||c.checkCollision.left===!1?this._overlap=0:(a.touching.right=!0,c.touching.left=!0)):a.deltaX()this._maxOverlap||a.checkCollision.left===!1||c.checkCollision.right===!1?this._overlap=0:(a.touching.left=!0,c.touching.right=!0)),0!==this._overlap)?(a.overlapX=this._overlap,c.overlapX=this._overlap,d||a.customSeparateX||c.customSeparateX?!0:(this._velocity1=a.velocity.x,this._velocity2=c.velocity.x,a.immovable||c.immovable?a.immovable?c.immovable||(c.x+=this._overlap,c.velocity.x=this._velocity1-this._velocity2*c.bounce.x):(a.x=a.x-this._overlap,a.velocity.x=this._velocity2-this._velocity1*a.bounce.x):(this._overlap*=.5,a.x=a.x-this._overlap,c.x+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*c.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/c.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.x=this._average+this._newVelocity1*a.bounce.x,c.velocity.x=this._average+this._newVelocity2*c.bounce.x),!0)):!1)},separateY:function(a,c,d){return a.immovable&&c.immovable?!1:(this._overlap=0,b.Rectangle.intersects(a,c)&&(this._maxOverlap=a.deltaAbsY()+c.deltaAbsY()+this.OVERLAP_BIAS,0===a.deltaY()&&0===c.deltaY()?(a.embedded=!0,c.embedded=!0):a.deltaY()>c.deltaY()?(this._overlap=a.y+a.height-c.y,this._overlap>this._maxOverlap||a.checkCollision.down===!1||c.checkCollision.up===!1?this._overlap=0:(a.touching.down=!0,c.touching.up=!0)):a.deltaY()this._maxOverlap||a.checkCollision.up===!1||c.checkCollision.down===!1?this._overlap=0:(a.touching.up=!0,c.touching.down=!0)),0!==this._overlap)?(a.overlapY=this._overlap,c.overlapY=this._overlap,d||a.customSeparateY||c.customSeparateY?!0:(this._velocity1=a.velocity.y,this._velocity2=c.velocity.y,a.immovable||c.immovable?a.immovable?c.immovable||(c.y+=this._overlap,c.velocity.y=this._velocity1-this._velocity2*c.bounce.y,a.moves&&(c.x+=a.x-a.preX)):(a.y=a.y-this._overlap,a.velocity.y=this._velocity2-this._velocity1*a.bounce.y,c.moves&&(a.x+=c.x-c.preX)):(this._overlap*=.5,a.y=a.y-this._overlap,c.y+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*c.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/c.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.y=this._average+this._newVelocity1*a.bounce.y,c.velocity.y=this._average+this._newVelocity2*c.bounce.y),!0)):!1)},separateTiles:function(a,b){a.resetResult();for(var c=!1,d=0;d0&&!c.intersects(b.position.x,b.position.y,b.right,b.bottom))return console.log("no collision so bail out (separted in a previous step"),!1;if(b.newVelocity.x&&(c.faceLeft||c.faceRight)){var d=0,e=0;b.newVelocity.x>0&&c.faceLeft?d=b.width:b.newVelocity.x<0&&c.faceRight&&(e=c.width),b.position.x=c.worldX-d+e,b.velocity.x=0}if(b.newVelocity.y&&(c.faceTop||c.faceBottom)){var f=0,g=0;b.newVelocity.y>0&&c.faceBottom?f=b.height:b.newVelocity.y<0&&c.faceTop&&(g=c.height),b.position.y=c.worldY-f+g,b.velocity.y=0}},XXXseparateTile:function(a,c){if(c.tile.callback||c.layer.callbacks[c.tile.index]){if(c.tile.callback&&c.tile.callback.call(c.tile.callbackContext,a.sprite,c)===!1)return!1;if(c.layer.callbacks[c.tile.index]&&c.layer.callbacks[c.tile.index].callback.call(c.layer.callbacks[c.tile.index].callbackContext,a.sprite,c)===!1)return!1}a.overlapX=0,a.deltaX()<0&&a.checkCollision.left&&c.tile.faceRight&&a.x0&&(a.deltaX()<0&&a.checkCollision.left&&c.tile.faceRight&&(a.x=c.right),a.deltaX()>0&&a.checkCollision.right&&c.tile.faceLeft&&(a.right=c.x)),b.Rectangle.intersection(a,c,this._intersection),0===this._intersection.width&&0===this._intersection.height)return!1;a.overlapY=0;var d=!1;this._intersection.height>0&&(a.deltaY()<0&&a.checkCollision.up&&c.tile.faceBottom,a.deltaY()>0&&a.checkCollision.down&&c.tile.faceTop&&(d=!0,a.overlapY=this._intersection.height)),0!==a.overlapY&&(a.overlapY<0?a.blocked.up=!0:a.overlapY>0&&(a.blocked.down=!0),a.y-=a.overlapY,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.velocity.y=0===a.bounce.y?0:-a.velocity.y*a.bounce.y)},processTileSeparation:function(a){return 0!==a.overlapX&&(a.overlapX<0?a.blocked.left=!0:a.overlapX>0&&(a.blocked.right=!0),a.x-=a.overlapX,a.preX-=a.overlapX,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.velocity.x=0===a.bounce.x?0:-a.velocity.x*a.bounce.x),0!==a.overlapY&&(a.overlapY<0?a.blocked.up=!0:a.overlapY>0&&(a.blocked.down=!0),a.y-=a.overlapY,a.preY-=a.overlapY,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.velocity.y=0===a.bounce.y?0:-a.velocity.y*a.bounce.y),!0},moveToObject:function(a,b,c,d){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=0),this._angle=Math.atan2(b.y-a.y,b.x-a.x),d>0&&(c=this.distanceBetween(a,b)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*c,a.body.velocity.y=Math.sin(this._angle)*c,this._angle},moveToObject:function(a,b,c,d){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=0),this._angle=Math.atan2(b.y-a.y,b.x-a.x),d>0&&(c=this.distanceBetween(a,b)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*c,a.body.velocity.y=Math.sin(this._angle)*c,this._angle},moveToPointer:function(a,b,c,d){return"undefined"==typeof b&&(b=60),c=c||this.game.input.activePointer,"undefined"==typeof d&&(d=0),this._angle=this.angleToPointer(a,c),d>0&&(b=this.distanceToPointer(a,c)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*b,a.body.velocity.y=Math.sin(this._angle)*b,this._angle},moveToXY:function(a,b,c,d,e){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=0),this._angle=Math.atan2(c-a.y,b-a.x),e>0&&(d=this.distanceToXY(a,b,c)/(e/1e3)),a.body.velocity.x=Math.cos(this._angle)*d,a.body.velocity.y=Math.sin(this._angle)*d,this._angle},velocityFromAngle:function(a,c,d){return"undefined"==typeof c&&(c=60),d=d||new b.Point,d.setTo(Math.cos(this.game.math.degToRad(a))*c,Math.sin(this.game.math.degToRad(a))*c)},velocityFromRotation:function(a,c,d){return"undefined"==typeof c&&(c=60),d=d||new b.Point,d.setTo(Math.cos(a)*c,Math.sin(a)*c)},accelerationFromRotation:function(a,c,d){return"undefined"==typeof c&&(c=60),d=d||new b.Point,d.setTo(Math.cos(a)*c,Math.sin(a)*c)},accelerateToObject:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleBetween(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToPointer:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof b&&(b=this.game.input.activePointer),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleToPointer(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToXY:function(a,b,c,d,e,f){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=1e3),"undefined"==typeof f&&(f=1e3),this._angle=this.angleToXY(a,b,c),a.body.acceleration.setTo(Math.cos(this._angle)*d,Math.sin(this._angle)*d),a.body.maxVelocity.setTo(e,f),this._angle},distanceBetween:function(a,b){return this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToXY:function(a,b,c){return this._dx=a.x-b,this._dy=a.y-c,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},angleBetween:function(a,b){return this._dx=b.x-a.x,this._dy=b.y-a.y,Math.atan2(this._dy,this._dx)},angleToXY:function(a,b,c){return this._dx=b-a.x,this._dy=c-a.y,Math.atan2(this._dy,this._dx)},angleToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=b.worldX-a.x,this._dy=b.worldY-a.y,Math.atan2(this._dy,this._dx)}},b.Physics.Arcade.Body=function(a){this.sprite=a,this.game=a.game,this.type=b.Physics.ARCADE,this.offset=new b.Point(-(a.anchor.x*a.width),-(a.anchor.y*a.height)),this.position=new b.Point(a.x+this.offset.x,a.y+this.offset.y),this.prev=new b.Point(this.position.x,this.position.y),this.preRotation=a.angle,this.sourceWidth=a.texture.frame.width,this.sourceHeight=a.texture.frame.height,this.width=a.width,this.height=a.height,this.halfWidth=Math.abs(a.width/2),this.halfHeight=Math.abs(a.height/2),this.center=new b.Point(a.x+this.halfWidth,a.y+this.halfHeight),this._sx=a.scale.x,this._sy=a.scale.y,this.velocity=new b.Point,this.newVelocity=new b.Point(0,0),this.acceleration=new b.Point,this.drag=new b.Point,this.gravityScale=new b.Point(1,1),this.bounce=new b.Point,this.maxVelocity=new b.Point(1e4,1e4),this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.skipQuadTree=!1,this.facing=b.NONE,this.immovable=!1,this.moves=!0,this.rotation=0,this.allowRotation=!0,this.customSeparateX=!1,this.customSeparateY=!1,this.overlapX=0,this.overlapY=0,this.embedded=!1,this.collideWorldBounds=!1,this.checkCollision={none:!1,any:!0,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.blocked={x:0,y:0,up:!1,down:!1,left:!1,right:!1},this.result={x:0,y:0,px:0,py:0,tx:0,ty:0,slope:!1}},b.Physics.Arcade.Body.prototype={resetResult:function(){this.result.x=!1,this.result.y=!1,this.result.slope=!1,this.result.px=this.position.x,this.result.py=this.position.y,this.result.tx=0,this.result.ty=0},updateBounds:function(a,b,c,d){(c!=this._sx||d!=this._sy)&&(this.width=this.sourceWidth*c,this.height=this.sourceHeight*d,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this._sx=c,this._sy=d,this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight))},preUpdate:function(){this.resetResult(),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=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.embedded=!1,this.prev.set(this.position.x,this.position.y),this.moves&&(this.game.physics.arcade.updateMotion(this),this.newVelocity.set(this.velocity.x*this.game.time.physicsElapsed,this.velocity.y*this.game.time.physicsElapsed),this.position.x+=this.newVelocity.x,this.position.y+=this.newVelocity.y,this.collideWorldBounds&&this.checkWorldBounds())},postUpdate:function(){this.sprite.x=this.position.x-this.offset.x,this.sprite.y=this.position.y-this.offset.y,this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight),this.allowRotation&&(this.sprite.angle+=this.deltaZ())},checkWorldBounds:function(){this.xthis.game.world.bounds.right&&(this.x=this.game.world.bounds.right-this.width,this.velocity.x*=-this.bounce.x),this.ythis.game.world.bounds.bottom&&(this.y=this.game.world.bounds.bottom-this.height,this.velocity.y*=-this.bounce.y)},setSize:function(a,b,c,d){c=c||this.offset.x,d=d||this.offset.y,this.sourceWidth=a,this.sourceHeight=b,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(c,d),this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight)},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)},deltaAbsX:function(){return this.deltaX()>0?this.deltaX():-this.deltaX()},deltaAbsY:function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},deltaX:function(){return this.position.x-this.prev.x},deltaY:function(){return this.position.y-this.prev.y},deltaZ:function(){return this.rotation-this.preRotation}},Object.defineProperty(b.Physics.Arcade.Body.prototype,"bottom",{get:function(){return this.position.y+this.height}}),Object.defineProperty(b.Physics.Arcade.Body.prototype,"right",{get:function(){return this.position.x+this.width}}),Object.defineProperty(b.Physics.Arcade.Body.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(b.Physics.Arcade.Body.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),b.Physics.Arcade.Body.prototype.constructor=b.Physics.Arcade.Body,b.Physics.Ninja=function(a){this.game=a,this.time=this.game.time,this.gravity=.2,this.bounds=new b.Rectangle(0,0,a.world.width,a.world.height),this._mapData=[]},b.Physics.Ninja.prototype.constructor=b.Physics.Ninja,b.Physics.Ninja.prototype={enableAABB:function(a){this.enable(a,1)},enableCircle:function(a,b){this.enable(a,2,0,b)},enableTile:function(a,b){this.enable(a,3,b)},enable:function(a,c,d,e){"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1);var f=1;for(Array.isArray(a)?f=a.length:a=[a];f--;)null===a[f].body&&(a[f].body=new b.Physics.Ninja.Body(this,a[f],c,d,e),a[f].anchor.set(.5))},setBounds:function(a,b,c,d){this.bounds.setTo(a,b,c,d)},setBoundsToWorld:function(){this.bounds.setTo(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height)},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!1);else this.collideHandler(a,b,c,d,e,!1);return this._total>0},collideHandler:function(a,c,d,e,f,g){return"undefined"!=typeof c||a.type!==b.GROUP&&a.type!==b.EMITTER?void(a&&c&&a.exists&&c.exists&&(a.type==b.SPRITE||a.type==b.TILESPRITE?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsSprite(a,c,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideSpriteVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,c,d,e,f):a.type==b.GROUP?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsGroup(c,a,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideGroupVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,c,d,e,f):a.type==b.TILEMAPLAYER?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsTilemapLayer(c,a,d,e,f):(c.type==b.GROUP||c.type==b.EMITTER)&&this.collideGroupVsTilemapLayer(c,a,d,e,f):a.type==b.EMITTER&&(c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsGroup(c,a,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideGroupVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,c,d,e,f)))):void this.collideGroupVsSelf(a,d,e,f,g)},collideSpriteVsSprite:function(a,b,c,d,e,f){this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++)},collideSpriteVsGroup:function(a,b,c,d,e,f){if(0!==b.length)for(var g=0,h=b.children.length;h>g;g++)b.children[g].exists&&b.children[g].body&&this.separate(a.body,b.children[g].body,d,e,f)&&(c&&c.call(e,a,b.children[g]),this._total++)},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a.children[g]&&a.children[h]&&a.children[g].exists&&a.children[h].exists&&this.collideSpriteVsSprite(a.children[g],a.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length)for(var g=0,h=a.children.length;h>g;g++)a.children[g].exists&&this.collideSpriteVsGroup(a.children[g],b,c,d,e,f)},separate:function(a,c){return a.type!==b.Physics.NINJA||c.type!==b.Physics.NINJA?!1:a.aabb&&c.aabb?a.aabb.collideAABBVsAABB(c.aabb):a.aabb&&c.tile?a.aabb.collideAABBVsTile(c.tile):a.tile&&c.aabb?c.aabb.collideAABBVsTile(a.tile):a.circle&&c.tile?a.circle.collideCircleVsTile(c.tile):a.tile&&c.circle?c.circle.collideCircleVsTile(a.tile):void 0}},b.Physics.Ninja.Body=function(a,c,d,e,f){"undefined"==typeof d&&(d=1),"undefined"==typeof e&&(e=1),"undefined"==typeof f&&(f=16),this.sprite=c,this.game=c.game,this.type=b.Physics.NINJA,this.system=a,this.aabb=null,this.tile=null,this.circle=null,this.shape=null,this.drag=1,this.friction=.05,this.gravityScale=1,this.bounce=.3,this.velocity=new b.Point,this.skipQuadTree=!1,this.facing=b.NONE,this.immovable=!1,this.collideWorldBounds=!0,this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.maxSpeed=8; -var g=c.x,h=c.y;0===c.anchor.x&&(g+=.5*c.width),0===c.anchor.y&&(h+=.5*c.height),1===d?(this.aabb=new b.Physics.Ninja.AABB(this,g,h,c.width,c.height),this.shape=this.aabb):2===d?(this.circle=new b.Physics.Ninja.Circle(this,g,h,f),this.shape=this.circle):3===d&&(this.tile=new b.Physics.Ninja.Tile(this,g,h,c.width,c.height,e),this.shape=this.tile)},b.Physics.Ninja.Body.prototype={updateBounds:function(){},preUpdate:function(){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=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.shape.integrate(),this.collideWorldBounds&&this.shape.collideWorldBounds(),this.speed=Math.sqrt(this.shape.velocity.x*this.shape.velocity.x+this.shape.velocity.y*this.shape.velocity.y),this.angle=Math.atan2(this.shape.velocity.y,this.shape.velocity.x)},postUpdate:function(){this.sprite.type===b.TILESPRITE?(this.sprite.x=this.shape.pos.x-this.shape.xw,this.sprite.y=this.shape.pos.y-this.shape.yw):(this.sprite.x=this.shape.pos.x,this.sprite.y=this.shape.pos.y)},setZeroVelocity:function(){this.shape.oldpos.x=this.shape.pos.x,this.shape.oldpos.y=this.shape.pos.y},moveTo:function(a,b){var c=a*this.game.time.physicsElapsed,b=this.game.math.degToRad(b);this.shape.pos.x=this.shape.oldpos.x+c*Math.cos(b),this.shape.pos.y=this.shape.oldpos.y+c*Math.sin(b)},moveFrom:function(a,b){var c=-a*this.game.time.physicsElapsed,b=this.game.math.degToRad(b);this.shape.pos.x=this.shape.oldpos.x+c*Math.cos(b),this.shape.pos.y=this.shape.oldpos.y+c*Math.sin(b)},moveLeft:function(a){var b=-a*this.game.time.physicsElapsed;this.shape.pos.x=this.shape.oldpos.x+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.x-this.shape.oldpos.x+b))},moveRight:function(a){var b=a*this.game.time.physicsElapsed;this.shape.pos.x=this.shape.oldpos.x+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.x-this.shape.oldpos.x+b))},moveUp:function(a){var b=-a*this.game.time.physicsElapsed;this.shape.pos.y=this.shape.oldpos.y+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.y-this.shape.oldpos.y+b))},moveDown:function(a){var b=a*this.game.time.physicsElapsed;this.shape.pos.y=this.shape.oldpos.y+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.y-this.shape.oldpos.y+b))},reset:function(){}},Object.defineProperty(b.Physics.Ninja.Body.prototype,"x",{get:function(){return this.shape.pos.x},set:function(a){this.shape.pos.x=a}}),Object.defineProperty(b.Physics.Ninja.Body.prototype,"y",{get:function(){return this.shape.pos.y},set:function(a){this.shape.pos.y=a}}),Object.defineProperty(b.Physics.Ninja.Body.prototype,"width",{get:function(){return this.shape.width}}),Object.defineProperty(b.Physics.Ninja.Body.prototype,"height",{get:function(){return this.shape.height}}),Object.defineProperty(b.Physics.Ninja.Body.prototype,"bottom",{get:function(){return this.shape.pos.y+this.shape.height}}),Object.defineProperty(b.Physics.Ninja.Body.prototype,"right",{get:function(){return this.shape.pos.x+this.shape.width}}),b.Physics.Ninja.AABB=function(a,c,d,e,f){this.body=a,this.system=a.system,this.pos=new b.Point(c,d),this.oldpos=new b.Point(c,d),this.xw=Math.abs(e/2),this.yw=Math.abs(f/2),this.width=e,this.height=f,this.oH=0,this.oV=0,this.velocity=new b.Point,this.aabbTileProjections={},this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_FULL]=this.projAABB_Full,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_45DEG]=this.projAABB_45Deg,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_CONCAVE]=this.projAABB_Concave,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_CONVEX]=this.projAABB_Convex,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_22DEGs]=this.projAABB_22DegS,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_22DEGb]=this.projAABB_22DegB,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_67DEGs]=this.projAABB_67DegS,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_67DEGb]=this.projAABB_67DegB,this.aabbTileProjections[b.Physics.Ninja.Tile.TYPE_HALF]=this.projAABB_Half},b.Physics.Ninja.AABB.prototype.constructor=b.Physics.Ninja.AABB,b.Physics.Ninja.AABB.COL_NONE=0,b.Physics.Ninja.AABB.COL_AXIS=1,b.Physics.Ninja.AABB.COL_OTHER=2,b.Physics.Ninja.AABB.prototype={integrate:function(){var a=this.pos.x,b=this.pos.y;this.pos.x+=this.body.drag*this.pos.x-this.body.drag*this.oldpos.x,this.pos.y+=this.body.drag*this.pos.y-this.body.drag*this.oldpos.y+this.system.gravity*this.body.gravityScale,this.velocity.set(this.pos.x-a,this.pos.y-b),this.oldpos.set(a,b)},reportCollisionVsWorld:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},reportCollisionVsBody:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e):f=g=h=i=0,j.x+=a,j.y+=b;var s=a+f+h,t=b+g+i;k.x+=s,k.y+=t},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.width,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.height,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},collideAABBVsAABB:function(a){var c=this.pos,d=a,e=d.pos.x,f=d.pos.y,g=d.xw,h=d.yw,i=c.x-e,j=g+this.xw-Math.abs(i);if(j>0){var k=c.y-f,l=h+this.yw-Math.abs(k);if(l>0){l>j?0>i?(j*=-1,l=0):l=0:0>k?(j=0,l*=-1):j=0;var m=Math.sqrt(j*j+l*l);return this.reportCollisionVsBody(j,l,j/m,l/m,d),b.Physics.Ninja.AABB.COL_AXIS}}return!1},collideAABBVsTile:function(a){var b=this.pos,c=a,d=c.pos.x,e=c.pos.y,f=c.xw,g=c.yw,h=b.x-d,i=f+this.xw-Math.abs(h);if(i>0){var j=b.y-e,k=g+this.yw-Math.abs(j);if(k>0)return k>i?0>h?(i*=-1,k=0):k=0:0>j?(i=0,k*=-1):i=0,this.resolveTile(i,k,this,c)}return!1},resolveTile:function(a,b,c,d){return 0j){f*=-j,g*=-j;var k=Math.sqrt(f*f+g*g),l=Math.sqrt(a*a+c*c);return k>l?(d.reportCollisionVsWorld(a,c,a/l,c/l,e),b.Physics.Ninja.AABB.COL_AXIS):(d.reportCollisionVsWorld(f,g,e.signx,e.signy,e),b.Physics.Ninja.AABB.COL_OTHER)}return b.Physics.Ninja.AABB.COL_NONE},projAABB_45Deg:function(a,c,d,e){var f=e.signx,g=e.signy,h=d.pos.x-f*d.xw-e.pos.x,i=d.pos.y-g*d.yw-e.pos.y,j=e.sx,k=e.sy,l=h*j+i*k;if(0>l){j*=-l,k*=-l;var m=Math.sqrt(j*j+k*k),n=Math.sqrt(a*a+c*c);return m>n?(d.reportCollisionVsWorld(a,c,a/n,c/n,e),b.Physics.Ninja.AABB.COL_AXIS):(d.reportCollisionVsWorld(j,k,e.sx,e.sy),b.Physics.Ninja.AABB.COL_OTHER)}return b.Physics.Ninja.AABB.COL_NONE},projAABB_22DegS:function(a,c,d,e){var f=e.signx,g=e.signy,h=d.pos.y-g*d.yw,i=e.pos.y-h;if(i*g>0){var j=d.pos.x-f*d.xw-(e.pos.x+f*e.xw),k=d.pos.y-g*d.yw-(e.pos.y-g*e.yw),l=e.sx,m=e.sy,n=j*l+k*m;if(0>n){l*=-n,m*=-n;var o=Math.sqrt(l*l+m*m),p=Math.sqrt(a*a+c*c),q=Math.abs(i);return o>p?p>q?(d.reportCollisionVsWorld(0,i,0,i/q,e),b.Physics.Ninja.AABB.COL_OTHER):(d.reportCollisionVsWorld(a,c,a/p,c/p,e),b.Physics.Ninja.AABB.COL_AXIS):o>q?(d.reportCollisionVsWorld(0,i,0,i/q,e),b.Physics.Ninja.AABB.COL_OTHER):(d.reportCollisionVsWorld(l,m,e.sx,e.sy,e),b.Physics.Ninja.AABB.COL_OTHER)}}return b.Physics.Ninja.AABB.COL_NONE},projAABB_22DegB:function(a,c,d,e){var f=e.signx,g=e.signy,h=d.pos.x-f*d.xw-(e.pos.x-f*e.xw),i=d.pos.y-g*d.yw-(e.pos.y+g*e.yw),j=e.sx,k=e.sy,l=h*j+i*k;if(0>l){j*=-l,k*=-l;var m=Math.sqrt(j*j+k*k),n=Math.sqrt(a*a+c*c);return m>n?(d.reportCollisionVsWorld(a,c,a/n,c/n,e),b.Physics.Ninja.AABB.COL_AXIS):(d.reportCollisionVsWorld(j,k,e.sx,e.sy,e),b.Physics.Ninja.AABB.COL_OTHER)}return b.Physics.Ninja.AABB.COL_NONE},projAABB_67DegS:function(a,c,d,e){var f=e.signx,g=e.signy,h=d.pos.x-f*d.xw,i=e.pos.x-h;if(i*f>0){var j=d.pos.x-f*d.xw-(e.pos.x-f*e.xw),k=d.pos.y-g*d.yw-(e.pos.y+g*e.yw),l=e.sx,m=e.sy,n=j*l+k*m;if(0>n){l*=-n,m*=-n;var o=Math.sqrt(l*l+m*m),p=Math.sqrt(a*a+c*c),q=Math.abs(i);return o>p?p>q?(d.reportCollisionVsWorld(i,0,i/q,0,e),b.Physics.Ninja.AABB.COL_OTHER):(d.reportCollisionVsWorld(a,c,a/p,c/p,e),b.Physics.Ninja.AABB.COL_AXIS):o>q?(d.reportCollisionVsWorld(i,0,i/q,0,e),b.Physics.Ninja.AABB.COL_OTHER):(d.reportCollisionVsWorld(l,m,e.sx,e.sy,e),b.Physics.Ninja.AABB.COL_OTHER)}}return b.Physics.Ninja.AABB.COL_NONE},projAABB_67DegB:function(a,c,d,e){var f=e.signx,g=e.signy,h=d.pos.x-f*d.xw-(e.pos.x+f*e.xw),i=d.pos.y-g*d.yw-(e.pos.y-g*e.yw),j=e.sx,k=e.sy,l=h*j+i*k;if(0>l){j*=-l,k*=-l;var m=Math.sqrt(j*j+k*k),n=Math.sqrt(a*a+c*c);return m>n?(d.reportCollisionVsWorld(a,c,a/n,c/n,e),b.Physics.Ninja.AABB.COL_AXIS):(d.reportCollisionVsWorld(j,k,e.sx,e.sy,e),b.Physics.Ninja.AABB.COL_OTHER)}return b.Physics.Ninja.AABB.COL_NONE},projAABB_Convex:function(a,c,d,e){var f=e.signx,g=e.signy,h=d.pos.x-f*d.xw-(e.pos.x-f*e.xw),i=d.pos.y-g*d.yw-(e.pos.y-g*e.yw),j=Math.sqrt(h*h+i*i),k=2*e.xw,l=Math.sqrt(k*k+0),m=l-j;if(0>f*h||0>g*i){var n=Math.sqrt(a*a+c*c);return d.reportCollisionVsWorld(a,c,a/n,c/n,e),b.Physics.Ninja.AABB.COL_AXIS}return m>0?(h/=j,i/=j,d.reportCollisionVsWorld(h*m,i*m,h,i,e),b.Physics.Ninja.AABB.COL_OTHER):b.Physics.Ninja.AABB.COL_NONE},projAABB_Concave:function(a,c,d,e){var f=e.signx,g=e.signy,h=e.pos.x+f*e.xw-(d.pos.x-f*d.xw),i=e.pos.y+g*e.yw-(d.pos.y-g*d.yw),j=2*e.xw,k=Math.sqrt(j*j+0),l=Math.sqrt(h*h+i*i),m=l-k;if(m>0){var n=Math.sqrt(a*a+c*c);return m>n?(d.reportCollisionVsWorld(a,c,a/n,c/n,e),b.Physics.Ninja.AABB.COL_AXIS):(h/=l,i/=l,d.reportCollisionVsWorld(h*m,i*m,h,i,e),b.Physics.Ninja.AABB.COL_OTHER)}return b.Physics.Ninja.AABB.COL_NONE}},b.Physics.Ninja.Tile=function(a,c,d,e,f,g){"undefined"==typeof g&&(g=b.Physics.Ninja.Tile.EMPTY),this.body=a,this.system=a.system,this.id=g,this.type=b.Physics.Ninja.Tile.TYPE_EMPTY,this.pos=new b.Point(c,d),this.oldpos=new b.Point(c,d),this.id>1&&this.id<30&&(f=e),this.xw=Math.abs(e/2),this.yw=Math.abs(f/2),this.width=e,this.height=f,this.velocity=new b.Point,this.signx=0,this.signy=0,this.sx=0,this.sy=0,this.body.gravityScale=0,this.body.collideWorldBounds=!1,this.id>0&&this.setType(this.id)},b.Physics.Ninja.Tile.prototype.constructor=b.Physics.Ninja.Tile,b.Physics.Ninja.Tile.prototype={integrate:function(){var a=this.pos.x,b=this.pos.y;this.pos.x+=this.body.drag*this.pos.x-this.body.drag*this.oldpos.x,this.pos.y+=this.body.drag*this.pos.y-this.body.drag*this.oldpos.y+this.system.gravity*this.body.gravityScale,this.velocity.set(this.pos.x-a,this.pos.y-b),this.oldpos.set(a,b)},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.width,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.height,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},reportCollisionVsWorld:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},setType:function(a){return a===b.Physics.Ninja.Tile.EMPTY?this.clear():(this.id=a,this.updateType()),this},clear:function(){this.id=b.Physics.Ninja.Tile.EMPTY,this.updateType()},updateType:function(){if(0===this.id)return this.type=b.Physics.Ninja.Tile.TYPE_EMPTY,this.signx=0,this.signy=0,this.sx=0,this.sy=0,!0;if(this.idn?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.width,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.height,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},collideCircleVsTile:function(a){var b=this.pos,c=this.radius,d=a,e=d.pos.x,f=d.pos.y,g=d.xw,h=d.yw,i=b.x-e,j=g+c-Math.abs(i);if(j>0){var k=b.y-f,l=h+c-Math.abs(k);if(l>0)return this.oH=0,this.oV=0,-g>i?this.oH=-1:i>g&&(this.oH=1),-h>k?this.oV=-1:k>h&&(this.oV=1),this.resolveCircleTile(j,l,this.oH,this.oV,this,d)}},resolveCircleTile:function(a,b,c,d,e,f){return 0a){var h=f.pos.x-g.pos.x;return 0>h?(f.reportCollisionVsWorld(-a,0,-1,0,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(a,0,1,0,g),b.Physics.Ninja.Circle.COL_AXIS)}var i=f.pos.y-g.pos.y;return 0>i?(f.reportCollisionVsWorld(0,-c,0,-1,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(0,c,0,1,g),b.Physics.Ninja.Circle.COL_AXIS)}return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS}if(0==e)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var j=g.pos.x+d*g.xw,k=g.pos.y+e*g.yw,h=f.pos.x-j,i=f.pos.y-k,l=Math.sqrt(h*h+i*i),m=f.radius-l;return m>0?(0==l?(h=d/Math.SQRT2,i=e/Math.SQRT2):(h/=l,i/=l),f.reportCollisionVsWorld(h*m,i*m,h,i,g),b.Physics.Ninja.Circle.COL_OTHER):b.Physics.Ninja.Circle.COL_NONE},projCircle_45Deg:function(a,c,d,e,f,g){var h,i=g.signx,j=g.signy;if(0==d)if(0==e){var k=g.sx,l=g.sy,m=f.pos.x-k*f.radius-g.pos.x,n=f.pos.y-l*f.radius-g.pos.y,o=m*k+n*l;if(0>o){k*=-o,l*=-o,c>a?(h=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(h=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1));var p=Math.sqrt(k*k+l*l);return p>h?(f.reportCollisionVsWorld(a,c,a/h,c/h,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(k,l,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>j*e)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var k=g.sx,l=g.sy,m=f.pos.x-(g.pos.x-i*g.xw),n=f.pos.y-(g.pos.y+e*g.yw),q=m*-l+n*k;if(q*i*j>0){var r=Math.sqrt(m*m+n*n),s=f.radius-r;if(s>0)return m/=r,n/=r,f.reportCollisionVsWorld(m*s,n*s,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var o=m*k+n*l,s=f.radius-Math.abs(o);if(s>0)return f.reportCollisionVsWorld(k*s,l*s,k,l,g),b.Physics.Ninja.Circle.COL_OTHER}}else if(0==e){if(0>i*d)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var k=g.sx,l=g.sy,m=f.pos.x-(g.pos.x+d*g.xw),n=f.pos.y-(g.pos.y-j*g.yw),q=m*-l+n*k;if(0>q*i*j){var r=Math.sqrt(m*m+n*n),s=f.radius-r;if(s>0)return m/=r,n/=r,f.reportCollisionVsWorld(m*s,n*s,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var o=m*k+n*l,s=f.radius-Math.abs(o);if(s>0)return f.reportCollisionVsWorld(k*s,l*s,k,l,g),b.Physics.Ninja.Circle.COL_OTHER}}else{if(i*d+j*e>0)return b.Physics.Ninja.Circle.COL_NONE;var t=g.pos.x+d*g.xw,u=g.pos.y+e*g.yw,v=f.pos.x-t,w=f.pos.y-u,r=Math.sqrt(v*v+w*w),s=f.radius-r;if(s>0)return 0==r?(v=d/Math.SQRT2,w=e/Math.SQRT2):(v/=r,w/=r),f.reportCollisionVsWorld(v*s,w*s,v,w,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_Concave:function(a,c,d,e,f,g){var h,i=g.signx,j=g.signy;if(0==d){if(0==e){var k=g.pos.x+i*g.xw-f.pos.x,l=g.pos.y+j*g.yw-f.pos.y,m=2*g.xw,n=Math.sqrt(m*m+0),o=Math.sqrt(k*k+l*l),p=o+f.radius-n;return p>0?(c>a?(h=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(h=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1)),p>h?(f.reportCollisionVsWorld(a,c,a/h,c/h,g),b.Physics.Ninja.Circle.COL_AXIS):(k/=o,l/=o,f.reportCollisionVsWorld(k*p,l*p,k,l,g),b.Physics.Ninja.Circle.COL_OTHER)):b.Physics.Ninja.Circle.COL_NONE}if(0>j*e)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var q=g.pos.x-i*g.xw,r=g.pos.y+e*g.yw,s=f.pos.x-q,t=f.pos.y-r,o=Math.sqrt(s*s+t*t),p=f.radius-o;if(p>0)return 0==o?(s=0,t=e):(s/=o,t/=o),f.reportCollisionVsWorld(s*p,t*p,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}else if(0==e){if(0>i*d)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var q=g.pos.x+d*g.xw,r=g.pos.y-j*g.yw,s=f.pos.x-q,t=f.pos.y-r,o=Math.sqrt(s*s+t*t),p=f.radius-o;if(p>0)return 0==o?(s=d,t=0):(s/=o,t/=o),f.reportCollisionVsWorld(s*p,t*p,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}else{if(i*d+j*e>0)return b.Physics.Ninja.Circle.COL_NONE;var q=g.pos.x+d*g.xw,r=g.pos.y+e*g.yw,s=f.pos.x-q,t=f.pos.y-r,o=Math.sqrt(s*s+t*t),p=f.radius-o;if(p>0)return 0==o?(s=d/Math.SQRT2,t=e/Math.SQRT2):(s/=o,t/=o),f.reportCollisionVsWorld(s*p,t*p,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_Convex:function(a,c,d,e,f,g){var h,i=g.signx,j=g.signy;if(0==d)if(0==e){var k=f.pos.x-(g.pos.x-i*g.xw),l=f.pos.y-(g.pos.y-j*g.yw),m=2*g.xw,n=Math.sqrt(m*m+0),o=Math.sqrt(k*k+l*l),p=n+f.radius-o;if(p>0)return c>a?(h=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(h=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1)),p>h?(f.reportCollisionVsWorld(a,c,a/h,c/h,g),b.Physics.Ninja.Circle.COL_AXIS):(k/=o,l/=o,f.reportCollisionVsWorld(k*p,l*p,k,l,g),b.Physics.Ninja.Circle.COL_OTHER)}else{if(0>j*e)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var k=f.pos.x-(g.pos.x-i*g.xw),l=f.pos.y-(g.pos.y-j*g.yw),m=2*g.xw,n=Math.sqrt(m*m+0),o=Math.sqrt(k*k+l*l),p=n+f.radius-o;if(p>0)return k/=o,l/=o,f.reportCollisionVsWorld(k*p,l*p,k,l,g),b.Physics.Ninja.Circle.COL_OTHER}else if(0==e){if(0>i*d)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var k=f.pos.x-(g.pos.x-i*g.xw),l=f.pos.y-(g.pos.y-j*g.yw),m=2*g.xw,n=Math.sqrt(m*m+0),o=Math.sqrt(k*k+l*l),p=n+f.radius-o;if(p>0)return k/=o,l/=o,f.reportCollisionVsWorld(k*p,l*p,k,l,g),b.Physics.Ninja.Circle.COL_OTHER}else if(i*d+j*e>0){var k=f.pos.x-(g.pos.x-i*g.xw),l=f.pos.y-(g.pos.y-j*g.yw),m=2*g.xw,n=Math.sqrt(m*m+0),o=Math.sqrt(k*k+l*l),p=n+f.radius-o;if(p>0)return k/=o,l/=o,f.reportCollisionVsWorld(k*p,l*p,k,l,g),b.Physics.Ninja.Circle.COL_OTHER}else{var q=g.pos.x+d*g.xw,r=g.pos.y+e*g.yw,s=f.pos.x-q,t=f.pos.y-r,o=Math.sqrt(s*s+t*t),p=f.radius-o;if(p>0)return 0==o?(s=d/Math.SQRT2,t=e/Math.SQRT2):(s/=o,t/=o),f.reportCollisionVsWorld(s*p,t*p,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_Half:function(a,c,d,e,f,g){var h=g.signx,i=g.signy,j=d*h+e*i;if(j>0)return b.Physics.Ninja.Circle.COL_NONE;if(0==d)if(0==e){var k=f.radius,l=f.pos.x-h*k-g.pos.x,m=f.pos.y-i*k-g.pos.y,n=h,o=i,p=l*n+m*o;if(0>p){n*=-p,o*=-p;var q=Math.sqrt(n*n+o*o),r=Math.sqrt(a*a+c*c);return q>r?(f.reportCollisionVsWorld(a,c,a/r,c/r,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(n,o,g.signx,g.signy),b.Physics.Ninja.Circle.COL_OTHER)}}else{if(0!=j)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var k=f.radius,s=f.pos.x-g.pos.x;if(0>s*h)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var t=f.pos.y-(g.pos.y+e*g.yw),u=Math.sqrt(s*s+t*t),v=f.radius-u;if(v>0)return 0==u?(s=h/Math.SQRT2,t=e/Math.SQRT2):(s/=u,t/=u),f.reportCollisionVsWorld(s*v,t*v,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}else if(0==e){if(0!=j)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var k=f.radius,t=f.pos.y-g.pos.y;if(0>t*i)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var s=f.pos.x-(g.pos.x+d*g.xw),u=Math.sqrt(s*s+t*t),v=f.radius-u;if(v>0)return 0==u?(s=h/Math.SQRT2,t=e/Math.SQRT2):(s/=u,t/=u),f.reportCollisionVsWorld(s*v,t*v,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}else{var w=g.pos.x+d*g.xw,x=g.pos.y+e*g.yw,s=f.pos.x-w,t=f.pos.y-x,u=Math.sqrt(s*s+t*t),v=f.radius-u;if(v>0)return 0==u?(s=d/Math.SQRT2,t=e/Math.SQRT2):(s/=u,t/=u),f.reportCollisionVsWorld(s*v,t*v,s,t,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_22DegS:function(a,c,d,e,f,g){var h=g.signx,i=g.signy;if(i*e>0)return b.Physics.Ninja.Circle.COL_NONE;if(0==d){if(0!=e)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var j=g.sx,k=g.sy,l=f.radius,m=f.pos.x-(g.pos.x-h*g.xw),n=f.pos.y-g.pos.y,o=m*-k+n*j;if(o*h*i>0){var p=Math.sqrt(m*m+n*n),q=l-p;if(q>0)return m/=p,n/=p,f.reportCollisionVsWorld(m*q,n*q,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{m-=l*j,n-=l*k;var r=m*j+n*k;if(0>r){j*=-r,k*=-r;var s=Math.sqrt(j*j+k*k);return c>a?(lenP=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(lenP=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1)),s>lenP?(f.reportCollisionVsWorld(a,c,a/lenP,c/lenP,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(j,k,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER)}}}else if(0==e)if(0>h*d){var t=g.pos.x-h*g.xw,u=g.pos.y,v=f.pos.x-t,w=f.pos.y-u;if(0>w*i)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var p=Math.sqrt(v*v+w*w),q=f.radius-p;if(q>0)return 0==p?(v=d/Math.SQRT2,w=e/Math.SQRT2):(v/=p,w/=p),f.reportCollisionVsWorld(v*q,w*q,v,w,g),b.Physics.Ninja.Circle.COL_OTHER}else{var j=g.sx,k=g.sy,m=f.pos.x-(g.pos.x+d*g.xw),n=f.pos.y-(g.pos.y-i*g.yw),o=m*-k+n*j;if(0>o*h*i){var p=Math.sqrt(m*m+n*n),q=f.radius-p;if(q>0)return m/=p,n/=p,f.reportCollisionVsWorld(m*q,n*q,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var r=m*j+n*k,q=f.radius-Math.abs(r);if(q>0)return f.reportCollisionVsWorld(j*q,k*q,j,k,g),b.Physics.Ninja.Circle.COL_OTHER}}else{var t=g.pos.x+d*g.xw,u=g.pos.y+e*g.yw,v=f.pos.x-t,w=f.pos.y-u,p=Math.sqrt(v*v+w*w),q=f.radius-p;if(q>0)return 0==p?(v=d/Math.SQRT2,w=e/Math.SQRT2):(v/=p,w/=p),f.reportCollisionVsWorld(v*q,w*q,v,w,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_22DegB:function(a,c,d,e,f,g){var h=g.signx,i=g.signy;if(0==d)if(0==e){var j=g.sx,k=g.sy,l=f.radius,m=f.pos.x-j*l-(g.pos.x-h*g.xw),n=f.pos.y-k*l-(g.pos.y+i*g.yw),o=m*j+n*k;if(0>o){j*=-o,k*=-o;var p=Math.sqrt(j*j+k*k);return c>a?(lenP=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(lenP=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1)),p>lenP?(f.reportCollisionVsWorld(a,c,a/lenP,c/lenP,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(j,k,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>i*e)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var j=g.sx,k=g.sy,m=f.pos.x-(g.pos.x-h*g.xw),n=f.pos.y-(g.pos.y+i*g.yw),q=m*-k+n*j;if(q*h*i>0){var r=Math.sqrt(m*m+n*n),s=f.radius-r;if(s>0)return m/=r,n/=r,f.reportCollisionVsWorld(m*s,n*s,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=f.radius-Math.abs(o);if(s>0)return f.reportCollisionVsWorld(j*s,k*s,j,k,g),b.Physics.Ninja.Circle.COL_OTHER}}else if(0==e){if(0>h*d)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var m=f.pos.x-(g.pos.x+h*g.xw),n=f.pos.y-g.pos.y;if(0>n*i)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS; -var j=g.sx,k=g.sy,q=m*-k+n*j;if(0>q*h*i){var r=Math.sqrt(m*m+n*n),s=f.radius-r;if(s>0)return m/=r,n/=r,f.reportCollisionVsWorld(m*s,n*s,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=f.radius-Math.abs(o);if(s>0)return f.reportCollisionVsWorld(j*s,k*s,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER}}else{if(h*d+i*e>0){var t=Math.sqrt(5),j=1*h/t,k=2*i/t,l=f.radius,m=f.pos.x-j*l-(g.pos.x-h*g.xw),n=f.pos.y-k*l-(g.pos.y+i*g.yw),o=m*j+n*k;return 0>o?(f.reportCollisionVsWorld(-j*o,-k*o,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER):b.Physics.Ninja.Circle.COL_NONE}var u=g.pos.x+d*g.xw,v=g.pos.y+e*g.yw,w=f.pos.x-u,x=f.pos.y-v,r=Math.sqrt(w*w+x*x),s=f.radius-r;if(s>0)return 0==r?(w=d/Math.SQRT2,x=e/Math.SQRT2):(w/=r,x/=r),f.reportCollisionVsWorld(w*s,x*s,w,x,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_67DegS:function(a,c,d,e,f,g){var h=g.signx,i=g.signy;if(h*d>0)return b.Physics.Ninja.Circle.COL_NONE;if(0==d)if(0==e){var j=g.sx,k=g.sy,l=f.radius,m=f.pos.x-g.pos.x,n=f.pos.y-(g.pos.y-i*g.yw),o=m*-k+n*j;if(0>o*h*i){var p=Math.sqrt(m*m+n*n),q=l-p;if(q>0)return m/=p,n/=p,f.reportCollisionVsWorld(m*q,n*q,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{m-=l*j,n-=l*k;var r=m*j+n*k;if(0>r){j*=-r,k*=-r;var s=Math.sqrt(j*j+k*k);return c>a?(lenP=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(lenP=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1)),s>lenP?(f.reportCollisionVsWorld(a,c,a/lenP,c/lenP,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(j,k,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER)}}}else if(0>i*e){var t=g.pos.x,u=g.pos.y-i*g.yw,v=f.pos.x-t,w=f.pos.y-u;if(0>v*h)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var p=Math.sqrt(v*v+w*w),q=f.radius-p;if(q>0)return 0==p?(v=d/Math.SQRT2,w=e/Math.SQRT2):(v/=p,w/=p),f.reportCollisionVsWorld(v*q,w*q,v,w,g),b.Physics.Ninja.Circle.COL_OTHER}else{var j=g.sx,k=g.sy,m=f.pos.x-(g.pos.x-h*g.xw),n=f.pos.y-(g.pos.y+e*g.yw),o=m*-k+n*j;if(o*h*i>0){var p=Math.sqrt(m*m+n*n),q=f.radius-p;if(q>0)return m/=p,n/=p,f.reportCollisionVsWorld(m*q,n*q,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var r=m*j+n*k,q=f.radius-Math.abs(r);if(q>0)return f.reportCollisionVsWorld(j*q,k*q,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER}}else{if(0==e)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var t=g.pos.x+d*g.xw,u=g.pos.y+e*g.yw,v=f.pos.x-t,w=f.pos.y-u,p=Math.sqrt(v*v+w*w),q=f.radius-p;if(q>0)return 0==p?(v=d/Math.SQRT2,w=e/Math.SQRT2):(v/=p,w/=p),f.reportCollisionVsWorld(v*q,w*q,v,w,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE},projCircle_67DegB:function(a,c,d,e,f,g){var h=g.signx,i=g.signy;if(0==d)if(0==e){var j=g.sx,k=g.sy,l=f.radius,m=f.pos.x-j*l-(g.pos.x+h*g.xw),n=f.pos.y-k*l-(g.pos.y-i*g.yw),o=m*j+n*k;if(0>o){j*=-o,k*=-o;var p=Math.sqrt(j*j+k*k);return c>a?(lenP=a,c=0,f.pos.x-g.pos.x<0&&(a*=-1)):(lenP=c,a=0,f.pos.y-g.pos.y<0&&(c*=-1)),p>lenP?(f.reportCollisionVsWorld(a,c,a/lenP,c/lenP,g),b.Physics.Ninja.Circle.COL_AXIS):(f.reportCollisionVsWorld(j,k,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>i*e)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var m=f.pos.x-g.pos.x,n=f.pos.y-(g.pos.y+i*g.yw);if(0>m*h)return f.reportCollisionVsWorld(0,c*e,0,e,g),b.Physics.Ninja.Circle.COL_AXIS;var j=g.sx,k=g.sy,q=m*-k+n*j;if(q*h*i>0){var r=Math.sqrt(m*m+n*n),s=f.radius-r;if(s>0)return m/=r,n/=r,f.reportCollisionVsWorld(m*s,n*s,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=f.radius-Math.abs(o);if(s>0)return f.reportCollisionVsWorld(j*s,k*s,j,k,g),b.Physics.Ninja.Circle.COL_OTHER}}else if(0==e){if(0>h*d)return f.reportCollisionVsWorld(a*d,0,d,0,g),b.Physics.Ninja.Circle.COL_AXIS;var t=Math.sqrt(5),j=2*h/t,k=1*i/t,m=f.pos.x-(g.pos.x+h*g.xw),n=f.pos.y-(g.pos.y-i*g.yw),q=m*-k+n*j;if(0>q*h*i){var r=Math.sqrt(m*m+n*n),s=f.radius-r;if(s>0)return m/=r,n/=r,f.reportCollisionVsWorld(m*s,n*s,m,n,g),b.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=f.radius-Math.abs(o);if(s>0)return f.reportCollisionVsWorld(j*s,k*s,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER}}else{if(h*d+i*e>0){var j=g.sx,k=g.sy,l=f.radius,m=f.pos.x-j*l-(g.pos.x+h*g.xw),n=f.pos.y-k*l-(g.pos.y-i*g.yw),o=m*j+n*k;return 0>o?(f.reportCollisionVsWorld(-j*o,-k*o,g.sx,g.sy,g),b.Physics.Ninja.Circle.COL_OTHER):b.Physics.Ninja.Circle.COL_NONE}var u=g.pos.x+d*g.xw,v=g.pos.y+e*g.yw,w=f.pos.x-u,x=f.pos.y-v,r=Math.sqrt(w*w+x*x),s=f.radius-r;if(s>0)return 0==r?(w=d/Math.SQRT2,x=e/Math.SQRT2):(w/=r,x/=r),f.reportCollisionVsWorld(w*s,x*s,w,x,g),b.Physics.Ninja.Circle.COL_OTHER}return b.Physics.Ninja.Circle.COL_NONE}},b.Physics.P2.LIME_CORONA_JSON=0,p2.Body.prototype.parent=null,p2.Spring.prototype.parent=null,b.Physics.P2=function(a,c){this.game=a,"undefined"==typeof c&&(c={gravity:[0,0],broadphase:new p2.SAPBroadphase}),this.world=new p2.World(c),this.materials=[],this.gravity=new b.Physics.P2.InversePointProxy(a,this.world.gravity),this.bounds=null,this._wallShapes=[null,null,null,null],this.onBodyAdded=new b.Signal,this.onBodyRemoved=new b.Signal,this.onSpringAdded=new b.Signal,this.onSpringRemoved=new b.Signal,this.onConstraintAdded=new b.Signal,this.onConstraintRemoved=new b.Signal,this.onContactMaterialAdded=new b.Signal,this.onContactMaterialRemoved=new b.Signal,this.onPostStep=new b.Signal,this.onPostBroadphase=new b.Signal,this.onImpact=new b.Signal,this.onBeginContact=new b.Signal,this.onEndContact=new b.Signal,this.world.on("postStep",this.postStepHandler,this),this.world.on("postBroadphase",this.postBroadphaseHandler,this),this.world.on("impact",this.impactHandler,this),this.world.on("beginContact",this.beginContactHandler,this),this.world.on("endContact",this.endContactHandler,this),this.collisionGroups=[],this._collisionGroupID=2,this.nothingCollisionGroup=new b.Physics.P2.CollisionGroup(1),this.boundsCollisionGroup=new b.Physics.P2.CollisionGroup(2),this.everythingCollisionGroup=new b.Physics.P2.CollisionGroup(2147483648),this.boundsCollidesWith=[],this.setBoundsToWorld(!0,!0,!0,!0,!1)},b.Physics.P2.prototype={postStepHandler:function(){},postBroadphaseHandler:function(a){for(var b=0;b1&&a.bodyB.id>1},endContactHandler:function(a){a.bodyA.id>1&&a.bodyB.id>1},setBoundsToWorld:function(a,b,c,d,e){this.setBounds(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,a,b,c,d,e)},setWorldMaterial:function(a,b,c,d,e){"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=!0),b&&this._wallShapes[0]&&(this._wallShapes[0].material=a),c&&this._wallShapes[1]&&(this._wallShapes[1].material=a),d&&this._wallShapes[2]&&(this._wallShapes[2].material=a),e&&this._wallShapes[3]&&(this._wallShapes[3].material=a)},setBounds:function(a,b,c,d,e,f,g,h,i){"undefined"==typeof e&&(e=!0),"undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=!0),"undefined"==typeof h&&(h=!0),"undefined"==typeof i&&(i=!0);var j=c/2,k=d/2,l=j+a,m=k+b;if(null!==this.bounds){this.bounds.world&&this.world.removeBody(this.bounds);for(var n=this.bounds.shapes.length;n--;){var o=this.bounds.shapes[n];this.bounds.removeShape(o)}this.bounds.position[0]=this.game.math.px2pi(l),this.bounds.position[1]=this.game.math.px2pi(m)}else this.bounds=new p2.Body({mass:0,position:[this.game.math.px2pi(l),this.game.math.px2pi(m)]});e&&(this._wallShapes[0]=new p2.Plane,i&&(this._wallShapes[0].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[0],[this.game.math.px2pi(-j),0],1.5707963267948966)),f&&(this._wallShapes[1]=new p2.Plane,i&&(this._wallShapes[1].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[1],[this.game.math.px2pi(j),0],-1.5707963267948966)),g&&(this._wallShapes[2]=new p2.Plane,i&&(this._wallShapes[2].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[2],[0,this.game.math.px2pi(-k)],-3.141592653589793)),h&&(this._wallShapes[3]=new p2.Plane,i&&(this._wallShapes[3].collisionGroup=this.boundsCollisionGroup.mask),this.bounds.addShape(this._wallShapes[3],[0,this.game.math.px2pi(k)])),this.world.addBody(this.bounds)},update:function(){this.world.step(1/60)},clear:function(){this.world.clear()},destroy:function(){this.world.clear(),this.game=null},addBody:function(a){return a.data.world?!1:(this.world.addBody(a.data),this.onBodyAdded.dispatch(a),!0)},removeBody:function(a){return this.world.removeBody(a.data),this.onBodyRemoved.dispatch(a),a},addSpring:function(a){return this.world.addSpring(a),this.onSpringAdded.dispatch(a),a},removeSpring:function(a){return this.world.removeSpring(a),this.onSpringRemoved.dispatch(a),a},addConstraint:function(a){return this.world.addConstraint(a),this.onConstraintAdded.dispatch(a),a},removeConstraint:function(a){return this.world.removeConstraint(a),this.onConstraintRemoved.dispatch(a),a},addContactMaterial:function(a){return this.world.addContactMaterial(a),this.onContactMaterialAdded.dispatch(a),a},removeContactMaterial:function(a){return this.world.removeContactMaterial(a),this.onContactMaterialRemoved.dispatch(a),a},getContactMaterial:function(a,b){return this.world.getContactMaterial(a,b)},setMaterial:function(a,b){for(var c=b.length;c--;)b.setMaterial(a)},createMaterial:function(a,c){a=a||"";var d=new b.Physics.P2.Material(a);return this.materials.push(d),"undefined"!=typeof c&&c.setMaterial(d),d},createContactMaterial:function(a,c,d){"undefined"==typeof a&&(a=this.createMaterial()),"undefined"==typeof c&&(c=this.createMaterial());var e=new b.Physics.P2.ContactMaterial(a,c,d);return this.addContactMaterial(e)},getBodies:function(){for(var a=[],b=this.world.bodies.length;b--;)a.push(this.world.bodies[b].parent);return a},getSprings:function(){for(var a=[],b=this.world.springs.length;b--;)a.push(this.world.springs[b]);return a},getConstraints:function(){for(var a=[],b=this.world.constraints.length;b--;)a.push(this.world.springs[b]);return a},hitTest:function(){},toJSON:function(){this.world.toJSON()},createCollisionGroup:function(){var a=Math.pow(2,this._collisionGroupID);this._wallShapes[0]&&(this._wallShapes[0].collisionMask=this._wallShapes[0].collisionMask|a),this._wallShapes[1]&&(this._wallShapes[1].collisionMask=this._wallShapes[1].collisionMask|a),this._wallShapes[2]&&(this._wallShapes[2].collisionMask=this._wallShapes[2].collisionMask|a),this._wallShapes[3]&&(this._wallShapes[3].collisionMask=this._wallShapes[3].collisionMask|a),this._collisionGroupID++;var c=new b.Physics.P2.CollisionGroup(a);return this.collisionGroups.push(c),c},createBody:function(a,c,d,e,f,g){"undefined"==typeof e&&(e=!1);var h=new b.Physics.P2.Body(this.game,null,a,c,d);if(g){var i=h.addPolygon(f,g);if(!i)return!1}return e&&this.world.addBody(h.data),h},createParticle:function(a,c,d,e,f,g){"undefined"==typeof e&&(e=!1);var h=new b.Physics.P2.Body(this.game,null,a,c,d);if(g){var i=h.addPolygon(f,g);if(!i)return!1}return e&&this.world.addBody(h.data),h}},Object.defineProperty(b.Physics.P2.prototype,"friction",{get:function(){return this.world.defaultFriction},set:function(a){this.world.defaultFriction=a}}),Object.defineProperty(b.Physics.P2.prototype,"restituion",{get:function(){return this.world.defaultRestitution},set:function(a){this.world.defaultRestitution=a}}),Object.defineProperty(b.Physics.P2.prototype,"applySpringForces",{get:function(){return this.world.applySpringForces},set:function(a){this.world.applySpringForces=a}}),Object.defineProperty(b.Physics.P2.prototype,"applyDamping",{get:function(){return this.world.applyDamping},set:function(a){this.world.applyDamping=a}}),Object.defineProperty(b.Physics.P2.prototype,"applyGravity",{get:function(){return this.world.applyGravity},set:function(a){this.world.applyGravity=a}}),Object.defineProperty(b.Physics.P2.prototype,"solveConstraints",{get:function(){return this.world.solveConstraints},set:function(a){this.world.solveConstraints=a}}),Object.defineProperty(b.Physics.P2.prototype,"time",{get:function(){return this.world.time}}),Object.defineProperty(b.Physics.P2.prototype,"emitImpactEvent",{get:function(){return this.world.emitImpactEvent},set:function(a){this.world.emitImpactEvent=a}}),Object.defineProperty(b.Physics.P2.prototype,"enableBodySleeping",{get:function(){return this.world.enableBodySleeping},set:function(a){this.world.enableBodySleeping=a}}),b.Physics.P2.PointProxy=function(a,b){this.game=a,this.destination=b},b.Physics.P2.PointProxy.prototype.constructor=b.Physics.P2.PointProxy,Object.defineProperty(b.Physics.P2.PointProxy.prototype,"x",{get:function(){return this.destination[0]},set:function(a){this.destination[0]=this.game.math.px2p(a)}}),Object.defineProperty(b.Physics.P2.PointProxy.prototype,"y",{get:function(){return this.destination[1]},set:function(a){this.destination[1]=this.game.math.px2p(a)}}),b.Physics.P2.InversePointProxy=function(a,b){this.game=a,this.destination=b},b.Physics.P2.InversePointProxy.prototype.constructor=b.Physics.P2.InversePointProxy,Object.defineProperty(b.Physics.P2.InversePointProxy.prototype,"x",{get:function(){return this.destination[0]},set:function(a){this.destination[0]=this.game.math.px2p(-a)}}),Object.defineProperty(b.Physics.P2.InversePointProxy.prototype,"y",{get:function(){return this.destination[1]},set:function(a){this.destination[1]=this.game.math.px2p(-a)}}),b.Physics.Body=function(a,c,d,e,f){c=c||null,d=d||0,e=e||0,"undefined"==typeof f&&(f=1),this.game=a,this.sprite=c,this.type=b.Physics.P2,this.offset=new b.Point,this.data=new p2.Body({position:[this.px2pi(d),this.px2pi(e)],mass:f}),this.data.parent=this,this.velocity=new b.Physics.InversePointProxy(this.game,this.data.velocity),this.force=new b.Physics.InversePointProxy(this.game,this.data.force),this.gravity=new b.Point,this.collideWorldBounds=!0,this.onImpact=new b.Signal,this.collidesWith=[],this._bodyCallbacks=[],this._bodyCallbackContext=[],this._groupCallbacks=[],this._groupCallbackContext=[],c&&(this.setRectangleFromSprite(c),this.game.physics.addBody(this))},b.Physics.Body.prototype={createBodyCallback:function(a,b,c){this._bodyCallbacks[a.data.id]=b,this._bodyCallbackContext[a.data.id]=c},createGroupCallback:function(a,b,c){this._groupCallbacks[a.mask]=b,this._groupCallbackContext[a.mask]=c},getCollisionMask:function(){var a=0;this.collideWorldBounds&&(a=this.game.physics.boundsCollisionGroup.mask);for(var b=0;b=0;d--)this.data.shapes[d].collisionGroup=a.mask,this.data.shapes[d].collisionMask=c;else b.collisionGroup=a.mask,shapes.collisionMask=c},clearCollision:function(a,b,c){if("undefined"==typeof c)for(var d=this.data.shapes.length-1;d>=0;d--)a&&(this.data.shapes[d].collisionGroup=null),b&&(this.data.shapes[d].collisionMask=null);else a&&(shapes.collisionGroup=null),b&&(shapes.collisionMask=null);a&&(this.collidesWith.length=0)},collides:function(a,b,c,d){if(Array.isArray(a))for(var e=0;e=0;e--)this.data.shapes[e].collisionMask=f;else d.collisionMask=f},adjustCenterOfMass:function(){this.data.adjustCenterOfMass()},applyDamping:function(a){this.data.applyDamping(a)},applyForce:function(a,b,c){this.data.applyForce(a,[this.px2p(b),this.px2p(c)])},setZeroForce:function(){this.data.setZeroForce()},setZeroRotation:function(){this.data.angularVelocity=0},setZeroVelocity:function(){this.data.velocity[0]=0,this.data.velocity[1]=0},setZeroDamping:function(){this.data.damping=0,this.data.angularDamping=0},toLocalFrame:function(a,b){return this.data.toLocalFrame(a,b)},toWorldFrame:function(a,b){return this.data.toWorldFrame(a,b)},rotateLeft:function(a){this.data.angularVelocity=this.px2p(-a)},rotateRight:function(a){this.data.angularVelocity=this.px2p(a)},moveForward:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.velocity[0]=b*Math.cos(c),this.data.velocity[1]=b*Math.sin(c)},moveBackward:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.velocity[0]=-(b*Math.cos(c)),this.data.velocity[1]=-(b*Math.sin(c))},thrust:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.force[0]+=b*Math.cos(c),this.data.force[1]+=b*Math.sin(c)},reverse:function(a){var b=this.px2pi(-a),c=this.data.angle+Math.PI/2;this.data.force[0]-=b*Math.cos(c),this.data.force[1]-=b*Math.sin(c)},moveLeft:function(a){this.data.velocity[0]=this.px2pi(-a)},moveRight:function(a){this.data.velocity[0]=this.px2pi(a)},moveUp:function(a){this.data.velocity[1]=this.px2pi(-a)},moveDown:function(a){this.data.velocity[1]=this.px2pi(a)},preUpdate:function(){},postUpdate:function(){this.sprite.x=this.p2pxi(this.data.position[0]),this.sprite.y=this.p2pxi(this.data.position[1]),this.fixedRotation||(this.sprite.rotation=this.data.angle)},reset:function(a,b,c,d){"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),this.setZeroForce(),this.setZeroVelocity(),this.setZeroRotation(),c&&this.setZeroDamping(),d&&(this.mass=1),this.x=a,this.y=b},addToWorld:function(){this.data.world!==this.game.physics.world&&this.game.physics.addBody(this)},removeFromWorld:function(){this.data.world===this.game.physics.world&&this.game.physics.removeBody(this)},destroy:function(){this.removeFromWorld(),this.clearShapes(),this.sprite=null},clearShapes:function(){for(var a=this.data.shapes.length-1;a>=0;a--){var b=this.data.shapes[a];this.data.removeShape(b)}},addShape:function(a,b,c,d){return"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),"undefined"==typeof d&&(d=0),this.data.addShape(a,[this.px2pi(b),this.px2pi(c)],d),a},addCircle:function(a,b,c,d){var e=new p2.Circle(this.px2p(a));return this.addShape(e,b,c,d)},addRectangle:function(a,b,c,d,e){var f=new p2.Rectangle(this.px2p(a),this.px2p(b));return this.addShape(f,c,d,e)},addPlane:function(a,b,c){var d=new p2.Plane;return this.addShape(d,a,b,c)},addParticle:function(a,b,c){var d=new p2.Particle;return this.addShape(d,a,b,c)},addLine:function(a,b,c,d){var e=new p2.Line(this.px2p(a));return this.addShape(e,b,c,d)},addCapsule:function(a,b,c,d,e){var f=new p2.Capsule(this.px2p(a),b);return this.addShape(f,c,d,e)},addPolygon:function(a,b){a=a||{},b=Array.prototype.slice.call(arguments,1);var c=[];if(1===b.length&&Array.isArray(b[0]))c=b[0].slice(0);else if(Array.isArray(b[0]))c=b[0].slice(0);else if("number"==typeof b[0])for(var d=0,e=b.length;e>d;d+=2)c.push([b[d],b[d+1]]);var f=c.length-1;c[f][0]===c[0][0]&&c[f][1]===c[0][1]&&c.pop();for(var g=0;g=0;c--)this.data.shapes[c].material=a;else b.material=a},loadPolygon:function(a,b,c){var d=this.game.cache.getPhysicsData(a,b);if(1===d.length){var e=[];d=d.pop();for(var f=0,g=d.shape.length;g>f;f+=2)e.push([d.shape[f],d.shape[f+1]]);return this.addPolygon(c,e)}for(var h=p2.vec2.create(),f=0;f=this._timer&&(this.emitParticle(),this._counter++,this._quantity>0&&this._counter>=this._quantity&&(this.on=!1),this._timer=this.game.time.now+this.frequency)},b.Particles.Arcade.Emitter.prototype.makeParticles=function(a,c,d,e,f){"undefined"==typeof c&&(c=0),"undefined"==typeof d&&(d=this.maxParticles),"undefined"==typeof e&&(e=!1),"undefined"==typeof f&&(f=!1);for(var g,h=0,i=a,j=c;d>h;)null===this.particleClass&&("object"==typeof a&&(i=this.game.rnd.pick(a)),"object"==typeof c&&(j=this.game.rnd.pick(c)),g=new b.Sprite(this.game,0,0,i,j)),e?(g.body.checkCollision.any=!0,g.body.checkCollision.none=!1):g.body.checkCollision.none=!0,g.body.collideWorldBounds=f,g.exists=!1,g.visible=!1,g.anchor.setTo(.5,.5),this.add(g),h++;return this},b.Particles.Arcade.Emitter.prototype.kill=function(){this.on=!1,this.alive=!1,this.exists=!1},b.Particles.Arcade.Emitter.prototype.revive=function(){this.alive=!0,this.exists=!0},b.Particles.Arcade.Emitter.prototype.start=function(a,b,c,d){"undefined"==typeof a&&(a=!0),"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=250),"undefined"==typeof d&&(d=0),this.revive(),this.visible=!0,this.on=!0,this._explode=a,this.lifespan=b,this.frequency=c,a?this._quantity=d:this._quantity+=d,this._counter=0,this._timer=this.game.time.now+c},b.Particles.Arcade.Emitter.prototype.emitParticle=function(){var a=this.getFirstExists(!1);if(null!=a){if(this.width>1||this.height>1?a.reset(this.game.rnd.integerInRange(this.left,this.right),this.game.rnd.integerInRange(this.top,this.bottom)):a.reset(this.emitX,this.emitY),a.lifespan=this.lifespan,a.body.bounce.setTo(this.bounce.x,this.bounce.y),a.body.velocity.x=this.minParticleSpeed.x!=this.maxParticleSpeed.x?this.game.rnd.integerInRange(this.minParticleSpeed.x,this.maxParticleSpeed.x):this.minParticleSpeed.x,a.body.velocity.y=this.minParticleSpeed.y!=this.maxParticleSpeed.y?this.game.rnd.integerInRange(this.minParticleSpeed.y,this.maxParticleSpeed.y):this.minParticleSpeed.y,a.body.gravity.y=this.gravity,a.body.angularVelocity=this.minRotation!=this.maxRotation?this.game.rnd.integerInRange(this.minRotation,this.maxRotation):this.minRotation,1!==this.minParticleScale||1!==this.maxParticleScale){var b=this.game.rnd.realInRange(this.minParticleScale,this.maxParticleScale);a.scale.setTo(b,b)}a.body.friction=this.particleFriction,a.body.angularDrag=this.angularDrag}},b.Particles.Arcade.Emitter.prototype.setSize=function(a,b){this.width=a,this.height=b},b.Particles.Arcade.Emitter.prototype.setXSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.x=a,this.maxParticleSpeed.x=b},b.Particles.Arcade.Emitter.prototype.setYSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.y=a,this.maxParticleSpeed.y=b},b.Particles.Arcade.Emitter.prototype.setRotation=function(a,b){a=a||0,b=b||0,this.minRotation=a,this.maxRotation=b},b.Particles.Arcade.Emitter.prototype.at=function(a){a.center&&(this.emitX=a.center.x,this.emitY=a.center.y)},Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"x",{get:function(){return this.emitX},set:function(a){this.emitX=a}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"y",{get:function(){return this.emitY},set:function(a){this.emitY=a}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"left",{get:function(){return Math.floor(this.x-this.width/2)}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"right",{get:function(){return Math.floor(this.x+this.width/2)}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"top",{get:function(){return Math.floor(this.y-this.height/2)}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"bottom",{get:function(){return Math.floor(this.y+this.height/2)}}),b.Tile=function(a,b,c,d,e,f){this.layer=a,this.index=b,this.x=c,this.y=d,this.worldX=c*e,this.worldY=d*f,this.width=e,this.height=f,this.centerX=Math.abs(e/2),this.centerY=Math.abs(f/2),this.alpha=1,this.properties={},this.scanned=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this.collides=!1,this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.collisionCallback=null,this.collisionCallbackContext=this},b.Tile.prototype={intersects:function(a,b,c,d){return c<=this.worldX?!1:d<=this.worldY?!1:a>=this.worldX+this.width?!1:b>=this.worldY+this.height?!1:!0},setCollisionCallback:function(a,b){this.collisionCallback=a,this.collisionCallbackContext=b},destroy:function(){this.collisionCallback=null,this.collisionCallbackContext=null,this.properties=null},setCollision:function(a,b,c,d){this.collideLeft=a,this.collideRight=b,this.collideUp=c,this.collideDown=d,a||b||c||d?(this.collides=!0,this.collideNone=!1):(this.collides=!1,this.collideNone=!0)},resetCollision:function(){this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.collides=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1 -},copy:function(a){this.index=a.index,this.alpha=a.alpha,this.properties=a.properties,this.collides=a.collides,this.collideNone=a.collideNone,this.collideUp=a.collideUp,this.collideDown=a.collideDown,this.collideLeft=a.collideLeft,this.collideRight=a.collideRight,this.collisionCallback=a.collisionCallback,this.collisionCallbackContext=a.collisionCallbackContext}},b.Tile.prototype.constructor=b.Tile,Object.defineProperty(b.Tile.prototype,"canCollide",{get:function(){return this.collides||this.collisionCallback||this.layer.callbacks[this.index]}}),Object.defineProperty(b.Tile.prototype,"left",{get:function(){return this.x}}),Object.defineProperty(b.Tile.prototype,"right",{get:function(){return this.x+this.width}}),Object.defineProperty(b.Tile.prototype,"top",{get:function(){return this.y}}),Object.defineProperty(b.Tile.prototype,"bottom",{get:function(){return this.y+this.height}}),b.Tilemap=function(a,c,d,e,f,g){this.game=a,this.key=c;var h=b.TilemapParser.parse(this.game,c,d,e,f,g);null!==h&&(this.width=h.width,this.height=h.height,this.tileWidth=h.tileWidth,this.tileHeight=h.tileHeight,this.orientation=h.orientation,this.version=h.version,this.properties=h.properties,this.widthInPixels=h.widthInPixels,this.heightInPixels=h.heightInPixels,this.layers=h.layers,this.tilesets=h.tilesets,this.tiles=h.tiles,this.objects=h.objects,this.collideIndexes=[],this.collision=h.collision,this.images=h.images,this.currentLayer=0,this.debugMap=[],this._results=[],this._tempA=0,this._tempB=0)},b.Tilemap.CSV=0,b.Tilemap.TILED_JSON=1,b.Tilemap.prototype={create:function(a,b,c,d,e){this.width=b,this.height=c,this.setTileSize(d,e);for(var f,g=[],h=0;c>h;h++){f=[];for(var i=0;b>i;i++)f.push(null);g.push(f)}this.layers.push({name:a,x:0,y:0,width:b,height:c,widthInPixels:this.widthInPixels,heightInPixels:this.heightInPixels,alpha:1,visible:!0,properties:{},indexes:[],callbacks:[],bodies:[],data:g}),this.currentLayer=this.layers.length-1},setTileSize:function(a,b){this.tileWidth=a,this.tileHeight=b,this.widthInPixels=this.width*a,this.heightInPixels=this.height*b},addTilesetImage:function(a,c,d,e,f,g){if("undefined"==typeof d&&(d=this.tileWidth),"undefined"==typeof e&&(e=this.tileHeight),"undefined"==typeof f&&(f=0),"undefined"==typeof g&&(g=0),"undefined"==typeof c){if("string"!=typeof a)return!1;c=a}if("string"==typeof a&&(a=this.getTilesetIndex(a)),this.tilesets[a])return this.tilesets[a].setImage(this.game.cache.getImage(c)),!0;var h=new b.Tileset(c,0,d,e,f,g,{});return h.setImage(this.game.cache.getImage(c)),this.tilesets.push(h),!1},createFromObjects:function(a,c,d,e,f,g,h,i){if("undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=!1),"undefined"==typeof h&&(h=this.game.world),"undefined"==typeof i&&(i=b.Sprite),!this.objects[a])return void console.warn("Tilemap.createFromObjects: Invalid objectgroup name given: "+a);for(var j,k=0,l=this.objects[a].length;l>k;k++)if(this.objects[a][k].gid===c){j=new i(this.game,this.objects[a][k].x,this.objects[a][k].y,d,e),j.anchor.setTo(0,1),j.name=this.objects[a][k].name,j.visible=this.objects[a][k].visible,j.autoCull=g,j.exists=f,h.add(j);for(property in this.objects[a][k].properties)h.set(j,property,this.objects[a][k].properties[property],!1,!1,0)}},clearPhysicsBodies:function(a){a=this.getLayer(a);for(var b=this.layers[a].bodies.length;b--;)this.layers[a].bodies[b].destroy()},generateCollisionData:function(a,b){a=this.getLayer(a),"undefined"==typeof b&&(b=!0),this.layers[a].bodies.length>0&&this.clearPhysicsBodies(a),this.layers[a].bodies.length=[];for(var c=0,d=0,e=0,f=0,g=this.layers[a].height;g>f;f++){c=0;for(var h=0,i=this.layers[a].width;i>h;h++){var j=this.layers[a].data[f][h];if(j)if(right=this.getTileRight(a,h,f),0===c&&(d=j.x*j.width,e=j.y*j.height,c=j.width),right&&right.collides)c+=j.width;else{var k=this.game.physics.createBody(d,e,0,!1);k.addRectangle(c,j.height,c/2,j.height/2,0),b&&this.game.physics.addBody(k),this.layers[a].bodies.push(k),c=0}}}return this.layers[a].bodies},createCollisionObjects:function(a,b){"undefined"==typeof b&&(b=!0);for(var c=[],d=0,e=this.collision[a].length;e>d;d++){var f=this.collision[a][d],g=this.game.physics.createBody(f.x,f.y,0,b,{},f.polyline);g&&c.push(g)}return c},createLayer:function(a,c,d,e){"undefined"==typeof c&&(c=this.game.width),"undefined"==typeof d&&(d=this.game.height),"undefined"==typeof e&&(e=this.game.world);var f=a;return"string"==typeof a&&(f=this.getLayerIndex(a)),null===f||f>this.layers.length?void console.warn("Tilemap.createLayer: Invalid layer ID given: "+f):e.add(new b.TilemapLayer(this.game,this,f,c,d))},getIndex:function(a,b){for(var c=0;ce;e++)this.layers[d].callbacks[a[e]]={callback:b,callbackContext:c}},setTileLocationCallback:function(a,b,c,d,e,f,g){if(g=this.getLayer(g),this.copy(a,b,c,d,g),!(this._results.length<2))for(var h=1;hd;d++)this.setCollisionByIndex(a[d],b,c,!1);this.calculateFaces(c)},setCollisionBetween:function(a,b,c,d){if("undefined"==typeof c&&(c=!0),d=this.getLayer(d),!(a>b)){for(var e=a;b>=e;e++)this.setCollisionByIndex(e,c,d,!1);this.calculateFaces(d)}},setCollisionByExclusion:function(a,b,c){"undefined"==typeof b&&(b=!0),c=this.getLayer(c);for(var d=0,e=this.tiles.length;e>d;d++)-1===a.indexOf(d)&&this.setCollisionByIndex(d,b,c,!1);this.calculateFaces(c)},setCollisionByIndex:function(a,b,c,d){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=this.currentLayer),"undefined"==typeof d&&(d=!0),b)this.collideIndexes.push(a);else{var e=this.collideIndexes.indexOf(a);e>-1&&this.collideIndexes.splice(e,1)}for(var f=0;ff;f++)for(var h=0,i=this.layers[a].width;i>h;h++){var j=this.layers[a].data[f][h];j&&(b=this.getTileAbove(a,h,f),c=this.getTileBelow(a,h,f),d=this.getTileLeft(a,h,f),e=this.getTileRight(a,h,f),j.collides&&(j.faceTop=!0,j.faceBottom=!0,j.faceLeft=!0,j.faceRight=!0),b&&b.collides&&(j.faceTop=!1),c&&c.collides&&(j.faceBottom=!1),d&&d.collides&&(j.faceLeft=!1),e&&e.collides&&(j.faceRight=!1))}},getTileAbove:function(a,b,c){return c>0?this.layers[a].data[c-1][b]:null},getTileBelow:function(a,b,c){return c0?this.layers[a].data[c][b-1]:null},getTileRight:function(a,b,c){return b=0&&c=0&&d-1?this.layers[e].data[d][c].setCollision(!0,!0,!0,!0):this.layers[e].data[d][c].resetCollision(),this.layers[e].dirty=!0,this.calculateFaces(e)}},putTileWorldXY:function(a,b,c,d,e,f){f=this.getLayer(f),b=this.game.math.snapToFloor(b,d)/d,c=this.game.math.snapToFloor(c,e)/e,this.putTile(a,b,c,f)},getTile:function(a,b,c){return c=this.getLayer(c),a>=0&&a=0&&ba&&(a=0),0>b&&(b=0),c>this.layers[e].width&&(c=this.layers[e].width),d>this.layers[e].height&&(d=this.layers[e].height),this._results.length=0,this._results.push({x:a,y:b,width:c,height:d,layer:e});for(var f=b;b+d>f;f++)for(var g=a;a+c>g;g++)this._results.push(this.layers[e].data[f][g]);return this._results},paste:function(a,b,c,d){if("undefined"==typeof a&&(a=0),"undefined"==typeof b&&(b=0),d=this.getLayer(d),c&&!(c.length<2)){for(var e=c[1].x-a,f=c[1].y-b,g=1;g1?this.debugMap[this.layers[this.currentLayer].data[c][d]]?"background: "+this.debugMap[this.layers[this.currentLayer].data[c][d]]:"background: #ffffff":"background: rgb(0, 0, 0)");a+="\n"}b[0]=a,console.log.apply(console,b)},destroy:function(){this.removeAllLayers(),this.data=[],this.game=null}},b.Tilemap.prototype.constructor=b.Tilemap,b.TilemapLayer=function(a,c,d,e,f){this.game=a,this.map=c,this.index=d,this.layer=c.layers[d],this.canvas=b.Canvas.create(e,f,"",!0),this.context=this.canvas.getContext("2d"),this.baseTexture=new PIXI.BaseTexture(this.canvas),this.texture=new PIXI.Texture(this.baseTexture),this.textureFrame=new b.Frame(0,0,0,e,f,"tilemapLayer",a.rnd.uuid()),b.Image.call(this,this.game,0,0,this.texture,this.textureFrame),this.name="",this.type=b.TILEMAPLAYER,this.fixedToCamera=!0,this.cameraOffset=new b.Point(0,0),this.tileColor="rgb(255, 255, 255)",this.debug=!1,this.debugAlpha=.5,this.debugColor="rgba(0, 255, 0, 1)",this.debugFill=!1,this.debugFillColor="rgba(0, 255, 0, 0.2)",this.debugCallbackColor="rgba(255, 0, 0, 1)",this.scrollFactorX=1,this.scrollFactorY=1,this.dirty=!0,this._cw=c.tileWidth,this._ch=c.tileHeight,this._ga=1,this._dx=0,this._dy=0,this._dw=0,this._dh=0,this._tx=0,this._ty=0,this._tw=0,this._th=0,this._tl=0,this._maxX=0,this._maxY=0,this._startX=0,this._startY=0,this._results=[],this._x=0,this._y=0,this._prevX=0,this._prevY=0,this.updateMax()},b.TilemapLayer.prototype=Object.create(b.Image.prototype),b.TilemapLayer.prototype.constructor=b.TilemapLayer,b.TilemapLayer.prototype.postUpdate=function(){b.Image.prototype.postUpdate.call(this),this.scrollX=this.game.camera.x*this.scrollFactorX,this.scrollY=this.game.camera.y*this.scrollFactorY,this.render()},b.TilemapLayer.prototype.resizeWorld=function(){this.game.world.setBounds(0,0,this.layer.widthInPixels,this.layer.heightInPixels)},b.TilemapLayer.prototype._fixX=function(a){return 0>a&&(a=0),1===this.scrollFactorX?a:this._x+(a-this._x/this.scrollFactorX)},b.TilemapLayer.prototype._unfixX=function(a){return 1===this.scrollFactorX?a:this._x/this.scrollFactorX+(a-this._x)},b.TilemapLayer.prototype._fixY=function(a){return 0>a&&(a=0),1===this.scrollFactorY?a:this._y+(a-this._y/this.scrollFactorY)},b.TilemapLayer.prototype._unfixY=function(a){return 1===this.scrollFactorY?a:this._y/this.scrollFactorY+(a-this._y)},b.TilemapLayer.prototype.getTileX=function(a){return this.game.math.snapToFloor(this._fixX(a),this.map.tileWidth)/this.map.tileWidth},b.TilemapLayer.prototype.getTileY=function(a){return this.game.math.snapToFloor(this._fixY(a),this.map.tileHeight)/this.map.tileHeight},b.TilemapLayer.prototype.getTileXY=function(a,b,c){return c.x=this.getTileX(a),c.y=this.getTileY(b),c},b.TilemapLayer.prototype.getIntersectingTiles=function(a,b,c,d){for(var e=this.getTiles(a,b,c,d,!1),f=a+c,g=b+d,h=e.length;h--;)e[h].intersects(a,b,f,g);return e},b.TilemapLayer.prototype.getTiles=function(a,b,c,d,e){"undefined"==typeof e&&(e=!1),a=this._fixX(a),b=this._fixY(b),c>this.layer.widthInPixels&&(c=this.layer.widthInPixels),d>this.layer.heightInPixels&&(d=this.layer.heightInPixels),this._tx=this.game.math.snapToFloor(a,this._cw)/this._cw,this._ty=this.game.math.snapToFloor(b,this._ch)/this._ch,this._tw=(this.game.math.snapToCeil(c,this._cw)+this._cw)/this._cw,this._th=(this.game.math.snapToCeil(d,this._ch)+this._ch)/this._ch,this._results=[];for(var f=this._ty;fthis.layer.width&&(this._maxX=this.layer.width),this._maxY>this.layer.height&&(this._maxY=this.layer.height)),this.dirty=!0},b.TilemapLayer.prototype.render=function(){if(this.layer.dirty&&(this.dirty=!0),this.dirty&&this.visible){this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.map.tileWidth),this._dy=-(this._y-this._startY*this.map.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.fillStyle=this.tileColor;var a,c;this.debug&&(this.context.globalAlpha=this.debugAlpha);for(var d=this._startY,e=this._startY+this._maxY;e>d;d++){this._column=this.layer.data[d];for(var f=this._startX,g=this._startX+this._maxX;g>f;f++)this._column[f]&&(a=this._column[f],c=this.map.tilesets[0],this.debug===!1&&a.alpha!==this.context.globalAlpha&&(this.context.globalAlpha=a.alpha),c.draw(this.context,Math.floor(this._tx),Math.floor(this._ty),a.index),a.debug&&(this.context.fillStyle="rgba(0, 255, 0, 0.4)",this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight))),this._tx+=this.map.tileWidth;this._tx=this._dx,this._ty+=this.map.tileHeight}return this.debug&&(this.context.globalAlpha=1,this.renderDebug()),this.game.renderType===b.WEBGL&&PIXI.updateWebGLTexture(this.baseTexture,this.game.renderer.gl),this.dirty=!1,this.layer.dirty=!1,!0}},b.TilemapLayer.prototype.OLDrender=function(){this.layer.dirty&&(this.dirty=!0),!this.dirty||!this.visible,this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.map.tileWidth),this._dy=-(this._y-this._startY*this.map.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.fillStyle=this.tileColor;var a,c;this.debug&&(this.context.globalAlpha=this.debugAlpha);for(var d=this._startY,e=this._startY+this._maxY;e>d;d++){this._column=this.layer.data[d];for(var f=this._startX,g=this._startX+this._maxX;g>f;f++)this._column[f]&&(a=this._column[f],this.map.tiles[a.index]&&(c=this.map.tilesets[this.map.tiles[a.index][2]],c.image?(this.debug===!1&&a.alpha!==this.context.globalAlpha&&(this.context.globalAlpha=a.alpha),c.tileWidth!==this.map.tileWidth||c.tileHeight!==this.map.tileHeight?this.context.drawImage(this.map.tilesets[this.map.tiles[a.index][2]].image,this.map.tiles[a.index][0],this.map.tiles[a.index][1],c.tileWidth,c.tileHeight,Math.floor(this._tx),Math.floor(this._ty)-(c.tileHeight-this.map.tileHeight),c.tileWidth,c.tileHeight):this.context.drawImage(this.map.tilesets[this.map.tiles[a.index][2]].image,this.map.tiles[a.index][0],this.map.tiles[a.index][1],this.map.tileWidth,this.map.tileHeight,Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight),this.context.fillStyle="rgba(0, 255, 0, 0.4)",this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight)):this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight))),this._tx+=this.map.tileWidth;this._tx=this._dx,this._ty+=this.map.tileHeight}return this.debug&&(this.context.globalAlpha=1,this.renderDebug()),this.game.renderType===b.WEBGL&&PIXI.updateWebGLTexture(this.baseTexture,this.game.renderer.gl),this.dirty=!1,this.layer.dirty=!1,!0},b.TilemapLayer.prototype.renderDebug=function(){this._tx=this._dx,this._ty=this._dy,this.context.strokeStyle=this.debugColor,this.context.fillStyle=this.debugFillColor;for(var a=this._startY,b=this._startY+this._maxY;b>a;a++){this._column=this.layer.data[a];for(var c=this._startX,d=this._startX+this._maxX;d>c;c++){var e=this._column[c];e&&(e.faceTop||e.faceBottom||e.faceLeft||e.faceRight)&&(this._tx=Math.floor(this._tx),this.debugFill&&this.context.fillRect(this._tx,this._ty,this._cw,this._ch),this.context.beginPath(),e.faceTop&&(this.context.moveTo(this._tx,this._ty),this.context.lineTo(this._tx+this._cw,this._ty)),e.faceBottom&&(this.context.moveTo(this._tx,this._ty+this._ch),this.context.lineTo(this._tx+this._cw,this._ty+this._ch)),e.faceLeft&&(this.context.moveTo(this._tx,this._ty),this.context.lineTo(this._tx,this._ty+this._ch)),e.faceRight&&(this.context.moveTo(this._tx+this._cw,this._ty),this.context.lineTo(this._tx+this._cw,this._ty+this._ch)),this.context.stroke()),this._tx+=this.map.tileWidth}this._tx=this._dx,this._ty+=this.map.tileHeight}},Object.defineProperty(b.TilemapLayer.prototype,"scrollX",{get:function(){return this._x},set:function(a){a!==this._x&&a>=0&&this.layer.widthInPixels>this.width&&(this._x=a,this._x>this.layer.widthInPixels-this.width&&(this._x=this.layer.widthInPixels-this.width),this._startX=this.game.math.floor(this._x/this.map.tileWidth),this._startX<0&&(this._startX=0),this._startX+this._maxX>this.layer.width&&(this._startX=this.layer.width-this._maxX),this.dirty=!0)}}),Object.defineProperty(b.TilemapLayer.prototype,"scrollY",{get:function(){return this._y},set:function(a){a!==this._y&&a>=0&&this.layer.heightInPixels>this.height&&(this._y=a,this._y>this.layer.heightInPixels-this.height&&(this._y=this.layer.heightInPixels-this.height),this._startY=this.game.math.floor(this._y/this.map.tileHeight),this._startY<0&&(this._startY=0),this._startY+this._maxY>this.layer.height&&(this._startY=this.layer.height-this._maxY),this.dirty=!0)}}),Object.defineProperty(b.TilemapLayer.prototype,"collisionWidth",{get:function(){return this._cw},set:function(a){this._cw=a,this.dirty=!0}}),Object.defineProperty(b.TilemapLayer.prototype,"collisionHeight",{get:function(){return this._ch},set:function(a){this._ch=a,this.dirty=!0}}),b.TilemapParser={tileset:function(a,c,d,e,f,g,h,i,j){var k=a.cache.getTilesetImage(c);if(null===k)return console.warn("Phaser.TilemapParser.tileSet: Invalid image key given"),null;var l=k.width,m=k.height;return-1===h&&(h=Math.round(l/d)),-1===i&&(i=Math.round(m/e)),-1===j&&(j=h*i),0===l||0===m||d>l||e>m||0===j?(console.warn("Phaser.TilemapParser.tileSet: width/height zero or width/height < given tileWidth/tileHeight"),null):new b.Tileset(k,c,d,e,f,g,h,i,j)},parse:function(a,c,d,e,f,g){if("undefined"==typeof d&&(d=32),"undefined"==typeof e&&(e=32),"undefined"==typeof f&&(f=10),"undefined"==typeof g&&(g=10),"undefined"==typeof c)return this.getEmptyData();if(null===c)return this.getEmptyData(d,e,f,g);var h=a.cache.getTilemapData(c);if(h){if(h.format===b.Tilemap.CSV)return this.parseCSV(c,h.data,d,e);if(h.format===b.Tilemap.TILED_JSON)return this.parseTiledJSON(h.data)}else console.warn("Phaser.TilemapParser.parse - No map data found for key "+c)},parseCSV:function(a,c,d,e){var f=this.getEmptyData();c=c.trim();for(var g=[],h=c.split("\n"),i=h.length,j=0,k=0;kj;j++)h.push(a.layers[e].data[j]>0?new b.Tile(f,a.layers[e].data[j],g,i.length,a.tilewidth,a.tileheight):null),g++,g===a.layers[e].width&&(i.push(h),g=0,h=[]);f.data=i,d.push(f)}c.layers=d;for(var l=[],e=0;ep;p++)if(a.layers[e].objects[p].gid){var q={gid:a.layers[e].objects[p].gid,name:a.layers[e].objects[p].name,x:a.layers[e].objects[p].x,y:a.layers[e].objects[p].y,visible:a.layers[e].objects[p].visible,properties:a.layers[e].objects[p].properties};n[a.layers[e].name].push(q)}else if(a.layers[e].objects[p].polyline){var q={name:a.layers[e].objects[p].name,x:a.layers[e].objects[p].x,y:a.layers[e].objects[p].y,width:a.layers[e].objects[p].width,height:a.layers[e].objects[p].height,visible:a.layers[e].objects[p].visible,properties:a.layers[e].objects[p].properties};q.polyline=[];for(var r=0;r255)return b.Color.getColor(255,255,255);if(a>c)return b.Color.getColor(255,255,255);var e=a+Math.round(Math.random()*(c-a)),f=a+Math.round(Math.random()*(c-a)),g=a+Math.round(Math.random()*(c-a));return b.Color.getColor32(d,e,f,g)},getRGB:function(a){return{alpha:a>>>24,red:a>>16&255,green:a>>8&255,blue:255&a}},getWebRGB:function(a){var b=(a>>>24)/255,c=a>>16&255,d=a>>8&255,e=255&a;return"rgba("+c.toString()+","+d.toString()+","+e.toString()+","+b.toString()+")"},getAlpha:function(a){return a>>>24},getAlphaFloat:function(a){return(a>>>24)/255},getRed:function(a){return a>>16&255},getGreen:function(a){return a>>8&255},getBlue:function(a){return 255&a}},b.Physics=function(a,c){this.game=a,this.config=c,this.arcade=new b.Physics.Arcade(a),this.p2=null,this.ninja=null,this.box2d=null,this.chipmunk=null},b.Physics.ARCADE=0,b.Physics.P2=1,b.Physics.NINJA=2,b.Physics.BOX2D=3,b.Physics.CHIPMUNK=5,b.Physics.prototype={startSystem:function(a){a===b.Physics.ARCADE&&null===this.arcade?this.arcade=new b.Physics.Arcade(this.game):a===b.Physics.P2&&null===this.p2&&(this.p2=new b.Physics.P2(this.game,this.config)),a===b.Physics.NINJA&&null===this.ninja?this.ninja=new b.Physics.Ninja(this.game):a===b.Physics.BOX2D&&null===this.box2d||a===b.Physics.CHIPMUNK&&null===this.chipmunk},enable:function(a,c){"undefined"==typeof c&&(c=b.Physics.ARCADE);var d=1;if(a instanceof b.Group);else for(Array.isArray(a)?d=a.length:a=[a];d--;)null===a[d].body&&(c===b.Physics.ARCADE?a[d].body=new b.Physics.Arcade.Body(a[d]):c===b.Physics.P2?(a[d].body=new b.Physics.P2.Body(this.game,a[d],a[d].x,a[d].y,1),a[d].anchor.set(.5)):c===b.Physics.NINJA&&(a[d].body=new b.Physics.Ninja.Body(this.ninja,a[d]),a[d].anchor.set(.5)))},update:function(){this.p2&&this.p2.update()},setBoundsToWorld:function(){this.ninja&&this.ninja.setBoundsToWorld()},clear:function(){this.p2&&this.p2.clear()}},b.Physics.prototype.constructor=b.Physics,b.Physics.Arcade=function(a){this.game=a,this.gravity=new b.Point,this.bounds=new b.Rectangle(0,0,a.world.width,a.world.height),this.maxObjects=10,this.maxLevels=4,this.OVERLAP_BIAS=4,this.quadTree=new b.QuadTree(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this._bounds1=new b.Rectangle,this._bounds2=new b.Rectangle,this._overlap=0,this._maxOverlap=0,this._velocity1=0,this._velocity2=0,this._newVelocity1=0,this._newVelocity2=0,this._average=0,this._mapData=[],this._mapTiles=0,this._result=!1,this._total=0,this._angle=0,this._dx=0,this._dy=0,this._intersection=new b.Rectangle},b.Physics.Arcade.prototype.constructor=b.Physics.Arcade,b.Physics.Arcade.prototype={enable:function(a,c){"undefined"==typeof c&&(c=!0);var d=1;for(Array.isArray(a)?d=a.length:a=[a];d--;)a[d]instanceof b.Group?a[d].forEach(this.enableBody,this,!1,c):this.enableBody(a[d])},enableBody:function(a,c){return a instanceof b.Group?void this.enable(a,!0,c):(a.hasOwnProperty("body")&&null===a.body&&(a.body=new b.Physics.Arcade.Body(a)),void(c&&a.hasOwnProperty("children")&&a.children.forEach(this.enable,this)))},updateMotion:function(a){this._velocityDelta=.5*(this.computeVelocity(a.angularVelocity,a.angularAcceleration,a.angularDrag,a.maxAngular,0)-a.angularVelocity),a.angularVelocity+=this._velocityDelta,a.rotation+=a.angularVelocity*this.game.time.physicsElapsed,a.angularVelocity+=this._velocityDelta,a.velocity.x+=this.gravity.x*this.game.time.physicsElapsed*a.gravityScale.x,a.velocity.y+=this.gravity.y*this.game.time.physicsElapsed*a.gravityScale.y,a.velocity.x=this.computeVelocity(a.velocity.x,a.acceleration.x,a.drag.x,a.maxVelocity.x),a.velocity.y=this.computeVelocity(a.velocity.y,a.acceleration.y,a.drag.y,a.maxVelocity.y)},computeVelocity:function(a,b,c,d){return d=d||1e4,b?a+b*this.game.time.physicsElapsed:c&&(this._drag=c*this.game.time.physicsElapsed,a-this._drag>0?a-=this._drag:a+this._drag<0?a+=this._drag:a=0),a>d?a=d:-d>a&&(a=-d),a},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!1);else this.collideHandler(a,b,c,d,e,!1);return this._total>0},collideHandler:function(a,c,d,e,f,g){return"undefined"!=typeof c||a.type!==b.GROUP&&a.type!==b.EMITTER?void(a&&c&&a.exists&&c.exists&&(a.type==b.SPRITE||a.type==b.TILESPRITE?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsSprite(a,c,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideSpriteVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,c,d,e,f):a.type==b.GROUP?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsGroup(c,a,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideGroupVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,c,d,e,f):a.type==b.TILEMAPLAYER?c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsTilemapLayer(c,a,d,e,f):(c.type==b.GROUP||c.type==b.EMITTER)&&this.collideGroupVsTilemapLayer(c,a,d,e,f):a.type==b.EMITTER&&(c.type==b.SPRITE||c.type==b.TILESPRITE?this.collideSpriteVsGroup(c,a,d,e,f,g):c.type==b.GROUP||c.type==b.EMITTER?this.collideGroupVsGroup(a,c,d,e,f,g):c.type==b.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,c,d,e,f)))):void this.collideGroupVsSelf(a,d,e,f,g)},collideSpriteVsSprite:function(a,b,c,d,e,f){this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++)},collideSpriteVsGroup:function(a,b,c,d,e,f){if(0!==b.length){this.quadTree.clear(),this.quadTree.reset(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this.quadTree.populate(b),this._potentials=this.quadTree.retrieve(a);for(var g=0,h=this._potentials.length;h>g;g++)this.separate(a.body,this._potentials[g],d,e,f)&&(c&&c.call(e,a,this._potentials[g].sprite),this._total++)}},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a.children[g]&&a.children[h]&&a.children[g].exists&&a.children[h].exists&&this.collideSpriteVsSprite(a.children[g],a.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length)for(var g=0,h=a.children.length;h>g;g++)a.children[g].exists&&this.collideSpriteVsGroup(a.children[g],b,c,d,e,f)},collideSpriteVsTilemapLayer:function(a,b){this._mapData=b.getIntersectingTiles(a.body.position.x,a.body.position.y,a.body.width,a.body.height,!0),0!==this._mapData.length&&this.separateTiles(a.body,this._mapData)},collideGroupVsTilemapLayer:function(a,b,c,d,e){if(0!==a.length)for(var f=0,g=a.children.length;g>f;f++)a.children[f].exists&&this.collideSpriteVsTilemapLayer(a.children[f],b,c,d,e)},separate:function(a,c,d,e,f){return b.Rectangle.intersects(a,c)?d&&d.call(e,a.sprite,c.sprite)===!1?!1:this.separateX(a,c,f)||this.separateY(a,c,f)?(this._result=!0,!0):!1:!1},separateX:function(a,c,d){return a.immovable&&c.immovable?!1:(this._overlap=0,b.Rectangle.intersects(a,c)&&(this._maxOverlap=a.deltaAbsX()+c.deltaAbsX()+this.OVERLAP_BIAS,0===a.deltaX()&&0===c.deltaX()?(a.embedded=!0,c.embedded=!0):a.deltaX()>c.deltaX()?(this._overlap=a.x+a.width-c.x,this._overlap>this._maxOverlap||a.checkCollision.right===!1||c.checkCollision.left===!1?this._overlap=0:(a.touching.right=!0,c.touching.left=!0)):a.deltaX()this._maxOverlap||a.checkCollision.left===!1||c.checkCollision.right===!1?this._overlap=0:(a.touching.left=!0,c.touching.right=!0)),0!==this._overlap)?(a.overlapX=this._overlap,c.overlapX=this._overlap,d||a.customSeparateX||c.customSeparateX?!0:(this._velocity1=a.velocity.x,this._velocity2=c.velocity.x,a.immovable||c.immovable?a.immovable?c.immovable||(c.x+=this._overlap,c.velocity.x=this._velocity1-this._velocity2*c.bounce.x):(a.x=a.x-this._overlap,a.velocity.x=this._velocity2-this._velocity1*a.bounce.x):(this._overlap*=.5,a.x=a.x-this._overlap,c.x+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*c.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/c.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.x=this._average+this._newVelocity1*a.bounce.x,c.velocity.x=this._average+this._newVelocity2*c.bounce.x),!0)):!1)},separateY:function(a,c,d){return a.immovable&&c.immovable?!1:(this._overlap=0,b.Rectangle.intersects(a,c)&&(this._maxOverlap=a.deltaAbsY()+c.deltaAbsY()+this.OVERLAP_BIAS,0===a.deltaY()&&0===c.deltaY()?(a.embedded=!0,c.embedded=!0):a.deltaY()>c.deltaY()?(this._overlap=a.y+a.height-c.y,this._overlap>this._maxOverlap||a.checkCollision.down===!1||c.checkCollision.up===!1?this._overlap=0:(a.touching.down=!0,c.touching.up=!0)):a.deltaY()this._maxOverlap||a.checkCollision.up===!1||c.checkCollision.down===!1?this._overlap=0:(a.touching.up=!0,c.touching.down=!0)),0!==this._overlap)?(a.overlapY=this._overlap,c.overlapY=this._overlap,d||a.customSeparateY||c.customSeparateY?!0:(this._velocity1=a.velocity.y,this._velocity2=c.velocity.y,a.immovable||c.immovable?a.immovable?c.immovable||(c.y+=this._overlap,c.velocity.y=this._velocity1-this._velocity2*c.bounce.y,a.moves&&(c.x+=a.x-a.preX)):(a.y=a.y-this._overlap,a.velocity.y=this._velocity2-this._velocity1*a.bounce.y,c.moves&&(a.x+=c.x-c.preX)):(this._overlap*=.5,a.y=a.y-this._overlap,c.y+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*c.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/c.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.y=this._average+this._newVelocity1*a.bounce.y,c.velocity.y=this._average+this._newVelocity2*c.bounce.y),!0)):!1)},separateTiles:function(a,b){a.resetResult();for(var c=!1,d=0;d0&&!c.intersects(b.position.x,b.position.y,b.right,b.bottom))return console.log("no collision so bail out (separted in a previous step"),!1;if(b.newVelocity.x&&(c.faceLeft||c.faceRight)){var d=0,e=0;b.newVelocity.x>0&&c.faceLeft?d=b.width:b.newVelocity.x<0&&c.faceRight&&(e=c.width),b.position.x=c.worldX-d+e,b.velocity.x=0}if(b.newVelocity.y&&(c.faceTop||c.faceBottom)){var f=0,g=0;b.newVelocity.y>0&&c.faceBottom?f=b.height:b.newVelocity.y<0&&c.faceTop&&(g=c.height),b.position.y=c.worldY-f+g,b.velocity.y=0}},XXXseparateTile:function(a,c){if(c.tile.callback||c.layer.callbacks[c.tile.index]){if(c.tile.callback&&c.tile.callback.call(c.tile.callbackContext,a.sprite,c)===!1)return!1;if(c.layer.callbacks[c.tile.index]&&c.layer.callbacks[c.tile.index].callback.call(c.layer.callbacks[c.tile.index].callbackContext,a.sprite,c)===!1)return!1}a.overlapX=0,a.deltaX()<0&&a.checkCollision.left&&c.tile.faceRight&&a.x0&&(a.deltaX()<0&&a.checkCollision.left&&c.tile.faceRight&&(a.x=c.right),a.deltaX()>0&&a.checkCollision.right&&c.tile.faceLeft&&(a.right=c.x)),b.Rectangle.intersection(a,c,this._intersection),0===this._intersection.width&&0===this._intersection.height)return!1;a.overlapY=0;var d=!1;this._intersection.height>0&&(a.deltaY()<0&&a.checkCollision.up&&c.tile.faceBottom,a.deltaY()>0&&a.checkCollision.down&&c.tile.faceTop&&(d=!0,a.overlapY=this._intersection.height)),0!==a.overlapY&&(a.overlapY<0?a.blocked.up=!0:a.overlapY>0&&(a.blocked.down=!0),a.y-=a.overlapY,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.velocity.y=0===a.bounce.y?0:-a.velocity.y*a.bounce.y)},processTileSeparation:function(a){return 0!==a.overlapX&&(a.overlapX<0?a.blocked.left=!0:a.overlapX>0&&(a.blocked.right=!0),a.x-=a.overlapX,a.preX-=a.overlapX,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.velocity.x=0===a.bounce.x?0:-a.velocity.x*a.bounce.x),0!==a.overlapY&&(a.overlapY<0?a.blocked.up=!0:a.overlapY>0&&(a.blocked.down=!0),a.y-=a.overlapY,a.preY-=a.overlapY,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.velocity.y=0===a.bounce.y?0:-a.velocity.y*a.bounce.y),!0},moveToObject:function(a,b,c,d){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=0),this._angle=Math.atan2(b.y-a.y,b.x-a.x),d>0&&(c=this.distanceBetween(a,b)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*c,a.body.velocity.y=Math.sin(this._angle)*c,this._angle},moveToObject:function(a,b,c,d){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=0),this._angle=Math.atan2(b.y-a.y,b.x-a.x),d>0&&(c=this.distanceBetween(a,b)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*c,a.body.velocity.y=Math.sin(this._angle)*c,this._angle},moveToPointer:function(a,b,c,d){return"undefined"==typeof b&&(b=60),c=c||this.game.input.activePointer,"undefined"==typeof d&&(d=0),this._angle=this.angleToPointer(a,c),d>0&&(b=this.distanceToPointer(a,c)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*b,a.body.velocity.y=Math.sin(this._angle)*b,this._angle},moveToXY:function(a,b,c,d,e){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=0),this._angle=Math.atan2(c-a.y,b-a.x),e>0&&(d=this.distanceToXY(a,b,c)/(e/1e3)),a.body.velocity.x=Math.cos(this._angle)*d,a.body.velocity.y=Math.sin(this._angle)*d,this._angle},velocityFromAngle:function(a,c,d){return"undefined"==typeof c&&(c=60),d=d||new b.Point,d.setTo(Math.cos(this.game.math.degToRad(a))*c,Math.sin(this.game.math.degToRad(a))*c)},velocityFromRotation:function(a,c,d){return"undefined"==typeof c&&(c=60),d=d||new b.Point,d.setTo(Math.cos(a)*c,Math.sin(a)*c)},accelerationFromRotation:function(a,c,d){return"undefined"==typeof c&&(c=60),d=d||new b.Point,d.setTo(Math.cos(a)*c,Math.sin(a)*c)},accelerateToObject:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleBetween(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToPointer:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof b&&(b=this.game.input.activePointer),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleToPointer(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToXY:function(a,b,c,d,e,f){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=1e3),"undefined"==typeof f&&(f=1e3),this._angle=this.angleToXY(a,b,c),a.body.acceleration.setTo(Math.cos(this._angle)*d,Math.sin(this._angle)*d),a.body.maxVelocity.setTo(e,f),this._angle},distanceBetween:function(a,b){return this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToXY:function(a,b,c){return this._dx=a.x-b,this._dy=a.y-c,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},angleBetween:function(a,b){return this._dx=b.x-a.x,this._dy=b.y-a.y,Math.atan2(this._dy,this._dx)},angleToXY:function(a,b,c){return this._dx=b-a.x,this._dy=c-a.y,Math.atan2(this._dy,this._dx)},angleToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=b.worldX-a.x,this._dy=b.worldY-a.y,Math.atan2(this._dy,this._dx)}},b.Physics.Arcade.Body=function(a){this.sprite=a,this.game=a.game,this.type=b.Physics.ARCADE,this.offset=new b.Point(-(a.anchor.x*a.width),-(a.anchor.y*a.height)),this.position=new b.Point(a.x+this.offset.x,a.y+this.offset.y),this.prev=new b.Point(this.position.x,this.position.y),this.preRotation=a.angle,this.sourceWidth=a.texture.frame.width,this.sourceHeight=a.texture.frame.height,this.width=a.width,this.height=a.height,this.halfWidth=Math.abs(a.width/2),this.halfHeight=Math.abs(a.height/2),this.center=new b.Point(a.x+this.halfWidth,a.y+this.halfHeight),this._sx=a.scale.x,this._sy=a.scale.y,this.velocity=new b.Point,this.newVelocity=new b.Point(0,0),this.acceleration=new b.Point,this.drag=new b.Point,this.gravityScale=new b.Point(1,1),this.bounce=new b.Point,this.maxVelocity=new b.Point(1e4,1e4),this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.skipQuadTree=!1,this.facing=b.NONE,this.immovable=!1,this.moves=!0,this.rotation=0,this.allowRotation=!0,this.customSeparateX=!1,this.customSeparateY=!1,this.overlapX=0,this.overlapY=0,this.embedded=!1,this.collideWorldBounds=!1,this.checkCollision={none:!1,any:!0,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.blocked={x:0,y:0,up:!1,down:!1,left:!1,right:!1},this.result={x:0,y:0,px:0,py:0,tx:0,ty:0,slope:!1}},b.Physics.Arcade.Body.prototype={resetResult:function(){this.result.x=!1,this.result.y=!1,this.result.slope=!1,this.result.px=this.position.x,this.result.py=this.position.y,this.result.tx=0,this.result.ty=0},updateBounds:function(a,b,c,d){(c!=this._sx||d!=this._sy)&&(this.width=this.sourceWidth*c,this.height=this.sourceHeight*d,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this._sx=c,this._sy=d,this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight))},preUpdate:function(){this.resetResult(),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=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.embedded=!1,this.prev.set(this.position.x,this.position.y),this.moves&&(this.game.physics.arcade.updateMotion(this),this.newVelocity.set(this.velocity.x*this.game.time.physicsElapsed,this.velocity.y*this.game.time.physicsElapsed),this.position.x+=this.newVelocity.x,this.position.y+=this.newVelocity.y,this.collideWorldBounds&&this.checkWorldBounds())},postUpdate:function(){this.sprite.x=this.position.x-this.offset.x,this.sprite.y=this.position.y-this.offset.y,this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight),this.allowRotation&&(this.sprite.angle+=this.deltaZ())},checkWorldBounds:function(){this.xthis.game.world.bounds.right&&(this.x=this.game.world.bounds.right-this.width,this.velocity.x*=-this.bounce.x),this.ythis.game.world.bounds.bottom&&(this.y=this.game.world.bounds.bottom-this.height,this.velocity.y*=-this.bounce.y)},setSize:function(a,b,c,d){c=c||this.offset.x,d=d||this.offset.y,this.sourceWidth=a,this.sourceHeight=b,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(c,d),this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight)},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)},deltaAbsX:function(){return this.deltaX()>0?this.deltaX():-this.deltaX()},deltaAbsY:function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},deltaX:function(){return this.position.x-this.prev.x},deltaY:function(){return this.position.y-this.prev.y},deltaZ:function(){return this.rotation-this.preRotation}},Object.defineProperty(b.Physics.Arcade.Body.prototype,"bottom",{get:function(){return this.position.y+this.height}}),Object.defineProperty(b.Physics.Arcade.Body.prototype,"right",{get:function(){return this.position.x+this.width}}),Object.defineProperty(b.Physics.Arcade.Body.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(b.Physics.Arcade.Body.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),b.Physics.Arcade.Body.prototype.constructor=b.Physics.Arcade.Body,b.Particles=function(a){this.game=a,this.emitters={},this.ID=0},b.Particles.prototype={add:function(a){return this.emitters[a.name]=a,a},remove:function(a){delete this.emitters[a.name]},update:function(){for(var a in this.emitters)this.emitters[a].exists&&this.emitters[a].update()}},b.Particles.prototype.constructor=b.Particles,b.Particles.Arcade={},b.Particles.Arcade.Emitter=function(a,c,d,e){this.maxParticles=e||50,b.Group.call(this,a),this.name="emitter"+this.game.particles.ID++,this.type=b.EMITTER,this.x=0,this.y=0,this.width=1,this.height=1,this.minParticleSpeed=new b.Point(-100,-100),this.maxParticleSpeed=new b.Point(100,100),this.minParticleScale=1,this.maxParticleScale=1,this.minRotation=-360,this.maxRotation=360,this.gravity=100,this.particleClass=null,this.particleFriction=0,this.angularDrag=0,this.frequency=100,this.lifespan=2e3,this.bounce=new b.Point,this._quantity=0,this._timer=0,this._counter=0,this._explode=!0,this.on=!1,this.exists=!0,this.emitX=c,this.emitY=d},b.Particles.Arcade.Emitter.prototype=Object.create(b.Group.prototype),b.Particles.Arcade.Emitter.prototype.constructor=b.Particles.Arcade.Emitter,b.Particles.Arcade.Emitter.prototype.update=function(){if(this.on)if(this._explode){this._counter=0;do this.emitParticle(),this._counter++;while(this._counter=this._timer&&(this.emitParticle(),this._counter++,this._quantity>0&&this._counter>=this._quantity&&(this.on=!1),this._timer=this.game.time.now+this.frequency)},b.Particles.Arcade.Emitter.prototype.makeParticles=function(a,c,d,e,f){"undefined"==typeof c&&(c=0),"undefined"==typeof d&&(d=this.maxParticles),"undefined"==typeof e&&(e=!1),"undefined"==typeof f&&(f=!1);for(var g,h=0,i=a,j=c;d>h;)null===this.particleClass&&("object"==typeof a&&(i=this.game.rnd.pick(a)),"object"==typeof c&&(j=this.game.rnd.pick(c)),g=new b.Sprite(this.game,0,0,i,j)),e?(g.body.checkCollision.any=!0,g.body.checkCollision.none=!1):g.body.checkCollision.none=!0,g.body.collideWorldBounds=f,g.exists=!1,g.visible=!1,g.anchor.setTo(.5,.5),this.add(g),h++;return this},b.Particles.Arcade.Emitter.prototype.kill=function(){this.on=!1,this.alive=!1,this.exists=!1},b.Particles.Arcade.Emitter.prototype.revive=function(){this.alive=!0,this.exists=!0},b.Particles.Arcade.Emitter.prototype.start=function(a,b,c,d){"undefined"==typeof a&&(a=!0),"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=250),"undefined"==typeof d&&(d=0),this.revive(),this.visible=!0,this.on=!0,this._explode=a,this.lifespan=b,this.frequency=c,a?this._quantity=d:this._quantity+=d,this._counter=0,this._timer=this.game.time.now+c},b.Particles.Arcade.Emitter.prototype.emitParticle=function(){var a=this.getFirstExists(!1);if(null!=a){if(this.width>1||this.height>1?a.reset(this.game.rnd.integerInRange(this.left,this.right),this.game.rnd.integerInRange(this.top,this.bottom)):a.reset(this.emitX,this.emitY),a.lifespan=this.lifespan,a.body.bounce.setTo(this.bounce.x,this.bounce.y),a.body.velocity.x=this.minParticleSpeed.x!=this.maxParticleSpeed.x?this.game.rnd.integerInRange(this.minParticleSpeed.x,this.maxParticleSpeed.x):this.minParticleSpeed.x,a.body.velocity.y=this.minParticleSpeed.y!=this.maxParticleSpeed.y?this.game.rnd.integerInRange(this.minParticleSpeed.y,this.maxParticleSpeed.y):this.minParticleSpeed.y,a.body.gravity.y=this.gravity,a.body.angularVelocity=this.minRotation!=this.maxRotation?this.game.rnd.integerInRange(this.minRotation,this.maxRotation):this.minRotation,1!==this.minParticleScale||1!==this.maxParticleScale){var b=this.game.rnd.realInRange(this.minParticleScale,this.maxParticleScale);a.scale.setTo(b,b) +}a.body.friction=this.particleFriction,a.body.angularDrag=this.angularDrag}},b.Particles.Arcade.Emitter.prototype.setSize=function(a,b){this.width=a,this.height=b},b.Particles.Arcade.Emitter.prototype.setXSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.x=a,this.maxParticleSpeed.x=b},b.Particles.Arcade.Emitter.prototype.setYSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.y=a,this.maxParticleSpeed.y=b},b.Particles.Arcade.Emitter.prototype.setRotation=function(a,b){a=a||0,b=b||0,this.minRotation=a,this.maxRotation=b},b.Particles.Arcade.Emitter.prototype.at=function(a){a.center&&(this.emitX=a.center.x,this.emitY=a.center.y)},Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"x",{get:function(){return this.emitX},set:function(a){this.emitX=a}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"y",{get:function(){return this.emitY},set:function(a){this.emitY=a}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"left",{get:function(){return Math.floor(this.x-this.width/2)}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"right",{get:function(){return Math.floor(this.x+this.width/2)}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"top",{get:function(){return Math.floor(this.y-this.height/2)}}),Object.defineProperty(b.Particles.Arcade.Emitter.prototype,"bottom",{get:function(){return Math.floor(this.y+this.height/2)}}),b.Tile=function(a,b,c,d,e,f){this.layer=a,this.index=b,this.x=c,this.y=d,this.worldX=c*e,this.worldY=d*f,this.width=e,this.height=f,this.centerX=Math.abs(e/2),this.centerY=Math.abs(f/2),this.alpha=1,this.properties={},this.scanned=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this.collides=!1,this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.collisionCallback=null,this.collisionCallbackContext=this},b.Tile.prototype={intersects:function(a,b,c,d){return c<=this.worldX?!1:d<=this.worldY?!1:a>=this.worldX+this.width?!1:b>=this.worldY+this.height?!1:!0},setCollisionCallback:function(a,b){this.collisionCallback=a,this.collisionCallbackContext=b},destroy:function(){this.collisionCallback=null,this.collisionCallbackContext=null,this.properties=null},setCollision:function(a,b,c,d){this.collideLeft=a,this.collideRight=b,this.collideUp=c,this.collideDown=d,a||b||c||d?(this.collides=!0,this.collideNone=!1):(this.collides=!1,this.collideNone=!0)},resetCollision:function(){this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.collides=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1},copy:function(a){this.index=a.index,this.alpha=a.alpha,this.properties=a.properties,this.collides=a.collides,this.collideNone=a.collideNone,this.collideUp=a.collideUp,this.collideDown=a.collideDown,this.collideLeft=a.collideLeft,this.collideRight=a.collideRight,this.collisionCallback=a.collisionCallback,this.collisionCallbackContext=a.collisionCallbackContext}},b.Tile.prototype.constructor=b.Tile,Object.defineProperty(b.Tile.prototype,"canCollide",{get:function(){return this.collides||this.collisionCallback||this.layer.callbacks[this.index]}}),Object.defineProperty(b.Tile.prototype,"left",{get:function(){return this.x}}),Object.defineProperty(b.Tile.prototype,"right",{get:function(){return this.x+this.width}}),Object.defineProperty(b.Tile.prototype,"top",{get:function(){return this.y}}),Object.defineProperty(b.Tile.prototype,"bottom",{get:function(){return this.y+this.height}}),b.Tilemap=function(a,c,d,e,f,g){this.game=a,this.key=c;var h=b.TilemapParser.parse(this.game,c,d,e,f,g);null!==h&&(this.width=h.width,this.height=h.height,this.tileWidth=h.tileWidth,this.tileHeight=h.tileHeight,this.orientation=h.orientation,this.version=h.version,this.properties=h.properties,this.widthInPixels=h.widthInPixels,this.heightInPixels=h.heightInPixels,this.layers=h.layers,this.tilesets=h.tilesets,this.tiles=h.tiles,this.objects=h.objects,this.collideIndexes=[],this.collision=h.collision,this.images=h.images,this.currentLayer=0,this.debugMap=[],this._results=[],this._tempA=0,this._tempB=0)},b.Tilemap.CSV=0,b.Tilemap.TILED_JSON=1,b.Tilemap.prototype={create:function(a,b,c,d,e){this.width=b,this.height=c,this.setTileSize(d,e);for(var f,g=[],h=0;c>h;h++){f=[];for(var i=0;b>i;i++)f.push(null);g.push(f)}this.layers.push({name:a,x:0,y:0,width:b,height:c,widthInPixels:this.widthInPixels,heightInPixels:this.heightInPixels,alpha:1,visible:!0,properties:{},indexes:[],callbacks:[],bodies:[],data:g}),this.currentLayer=this.layers.length-1},setTileSize:function(a,b){this.tileWidth=a,this.tileHeight=b,this.widthInPixels=this.width*a,this.heightInPixels=this.height*b},addTilesetImage:function(a,c,d,e,f,g){if("undefined"==typeof d&&(d=this.tileWidth),"undefined"==typeof e&&(e=this.tileHeight),"undefined"==typeof f&&(f=0),"undefined"==typeof g&&(g=0),"undefined"==typeof c){if("string"!=typeof a)return!1;c=a}if("string"==typeof a&&(a=this.getTilesetIndex(a)),this.tilesets[a])return this.tilesets[a].setImage(this.game.cache.getImage(c)),!0;var h=new b.Tileset(c,0,d,e,f,g,{});return h.setImage(this.game.cache.getImage(c)),this.tilesets.push(h),!1},createFromObjects:function(a,c,d,e,f,g,h,i){if("undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=!1),"undefined"==typeof h&&(h=this.game.world),"undefined"==typeof i&&(i=b.Sprite),!this.objects[a])return void console.warn("Tilemap.createFromObjects: Invalid objectgroup name given: "+a);for(var j,k=0,l=this.objects[a].length;l>k;k++)if(this.objects[a][k].gid===c){j=new i(this.game,this.objects[a][k].x,this.objects[a][k].y,d,e),j.anchor.setTo(0,1),j.name=this.objects[a][k].name,j.visible=this.objects[a][k].visible,j.autoCull=g,j.exists=f,h.add(j);for(property in this.objects[a][k].properties)h.set(j,property,this.objects[a][k].properties[property],!1,!1,0)}},clearPhysicsBodies:function(a){a=this.getLayer(a);for(var b=this.layers[a].bodies.length;b--;)this.layers[a].bodies[b].destroy()},generateCollisionData:function(a,b){a=this.getLayer(a),"undefined"==typeof b&&(b=!0),this.layers[a].bodies.length>0&&this.clearPhysicsBodies(a),this.layers[a].bodies.length=[];for(var c=0,d=0,e=0,f=0,g=this.layers[a].height;g>f;f++){c=0;for(var h=0,i=this.layers[a].width;i>h;h++){var j=this.layers[a].data[f][h];if(j)if(right=this.getTileRight(a,h,f),0===c&&(d=j.x*j.width,e=j.y*j.height,c=j.width),right&&right.collides)c+=j.width;else{var k=this.game.physics.createBody(d,e,0,!1);k.addRectangle(c,j.height,c/2,j.height/2,0),b&&this.game.physics.addBody(k),this.layers[a].bodies.push(k),c=0}}}return this.layers[a].bodies},createCollisionObjects:function(a,b){"undefined"==typeof b&&(b=!0);for(var c=[],d=0,e=this.collision[a].length;e>d;d++){var f=this.collision[a][d],g=this.game.physics.createBody(f.x,f.y,0,b,{},f.polyline);g&&c.push(g)}return c},createLayer:function(a,c,d,e){"undefined"==typeof c&&(c=this.game.width),"undefined"==typeof d&&(d=this.game.height),"undefined"==typeof e&&(e=this.game.world);var f=a;return"string"==typeof a&&(f=this.getLayerIndex(a)),null===f||f>this.layers.length?void console.warn("Tilemap.createLayer: Invalid layer ID given: "+f):e.add(new b.TilemapLayer(this.game,this,f,c,d))},getIndex:function(a,b){for(var c=0;ce;e++)this.layers[d].callbacks[a[e]]={callback:b,callbackContext:c}},setTileLocationCallback:function(a,b,c,d,e,f,g){if(g=this.getLayer(g),this.copy(a,b,c,d,g),!(this._results.length<2))for(var h=1;hd;d++)this.setCollisionByIndex(a[d],b,c,!1);this.calculateFaces(c)},setCollisionBetween:function(a,b,c,d){if("undefined"==typeof c&&(c=!0),d=this.getLayer(d),!(a>b)){for(var e=a;b>=e;e++)this.setCollisionByIndex(e,c,d,!1);this.calculateFaces(d)}},setCollisionByExclusion:function(a,b,c){"undefined"==typeof b&&(b=!0),c=this.getLayer(c);for(var d=0,e=this.tiles.length;e>d;d++)-1===a.indexOf(d)&&this.setCollisionByIndex(d,b,c,!1);this.calculateFaces(c)},setCollisionByIndex:function(a,b,c,d){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=this.currentLayer),"undefined"==typeof d&&(d=!0),b)this.collideIndexes.push(a);else{var e=this.collideIndexes.indexOf(a);e>-1&&this.collideIndexes.splice(e,1)}for(var f=0;ff;f++)for(var h=0,i=this.layers[a].width;i>h;h++){var j=this.layers[a].data[f][h];j&&(b=this.getTileAbove(a,h,f),c=this.getTileBelow(a,h,f),d=this.getTileLeft(a,h,f),e=this.getTileRight(a,h,f),j.collides&&(j.faceTop=!0,j.faceBottom=!0,j.faceLeft=!0,j.faceRight=!0),b&&b.collides&&(j.faceTop=!1),c&&c.collides&&(j.faceBottom=!1),d&&d.collides&&(j.faceLeft=!1),e&&e.collides&&(j.faceRight=!1))}},getTileAbove:function(a,b,c){return c>0?this.layers[a].data[c-1][b]:null},getTileBelow:function(a,b,c){return c0?this.layers[a].data[c][b-1]:null},getTileRight:function(a,b,c){return b=0&&c=0&&d-1?this.layers[e].data[d][c].setCollision(!0,!0,!0,!0):this.layers[e].data[d][c].resetCollision(),this.layers[e].dirty=!0,this.calculateFaces(e)}},putTileWorldXY:function(a,b,c,d,e,f){f=this.getLayer(f),b=this.game.math.snapToFloor(b,d)/d,c=this.game.math.snapToFloor(c,e)/e,this.putTile(a,b,c,f)},getTile:function(a,b,c){return c=this.getLayer(c),a>=0&&a=0&&ba&&(a=0),0>b&&(b=0),c>this.layers[e].width&&(c=this.layers[e].width),d>this.layers[e].height&&(d=this.layers[e].height),this._results.length=0,this._results.push({x:a,y:b,width:c,height:d,layer:e});for(var f=b;b+d>f;f++)for(var g=a;a+c>g;g++)this._results.push(this.layers[e].data[f][g]);return this._results},paste:function(a,b,c,d){if("undefined"==typeof a&&(a=0),"undefined"==typeof b&&(b=0),d=this.getLayer(d),c&&!(c.length<2)){for(var e=c[1].x-a,f=c[1].y-b,g=1;g1?this.debugMap[this.layers[this.currentLayer].data[c][d]]?"background: "+this.debugMap[this.layers[this.currentLayer].data[c][d]]:"background: #ffffff":"background: rgb(0, 0, 0)");a+="\n"}b[0]=a,console.log.apply(console,b)},destroy:function(){this.removeAllLayers(),this.data=[],this.game=null}},b.Tilemap.prototype.constructor=b.Tilemap,b.TilemapLayer=function(a,c,d,e,f){this.game=a,this.map=c,this.index=d,this.layer=c.layers[d],this.canvas=b.Canvas.create(e,f,"",!0),this.context=this.canvas.getContext("2d"),this.baseTexture=new PIXI.BaseTexture(this.canvas),this.texture=new PIXI.Texture(this.baseTexture),this.textureFrame=new b.Frame(0,0,0,e,f,"tilemapLayer",a.rnd.uuid()),b.Image.call(this,this.game,0,0,this.texture,this.textureFrame),this.name="",this.type=b.TILEMAPLAYER,this.fixedToCamera=!0,this.cameraOffset=new b.Point(0,0),this.tileColor="rgb(255, 255, 255)",this.debug=!1,this.debugAlpha=.5,this.debugColor="rgba(0, 255, 0, 1)",this.debugFill=!1,this.debugFillColor="rgba(0, 255, 0, 0.2)",this.debugCallbackColor="rgba(255, 0, 0, 1)",this.scrollFactorX=1,this.scrollFactorY=1,this.dirty=!0,this._cw=c.tileWidth,this._ch=c.tileHeight,this._ga=1,this._dx=0,this._dy=0,this._dw=0,this._dh=0,this._tx=0,this._ty=0,this._tw=0,this._th=0,this._tl=0,this._maxX=0,this._maxY=0,this._startX=0,this._startY=0,this._results=[],this._x=0,this._y=0,this._prevX=0,this._prevY=0,this.updateMax()},b.TilemapLayer.prototype=Object.create(b.Image.prototype),b.TilemapLayer.prototype.constructor=b.TilemapLayer,b.TilemapLayer.prototype.postUpdate=function(){b.Image.prototype.postUpdate.call(this),this.scrollX=this.game.camera.x*this.scrollFactorX,this.scrollY=this.game.camera.y*this.scrollFactorY,this.render()},b.TilemapLayer.prototype.resizeWorld=function(){this.game.world.setBounds(0,0,this.layer.widthInPixels,this.layer.heightInPixels)},b.TilemapLayer.prototype._fixX=function(a){return 0>a&&(a=0),1===this.scrollFactorX?a:this._x+(a-this._x/this.scrollFactorX)},b.TilemapLayer.prototype._unfixX=function(a){return 1===this.scrollFactorX?a:this._x/this.scrollFactorX+(a-this._x)},b.TilemapLayer.prototype._fixY=function(a){return 0>a&&(a=0),1===this.scrollFactorY?a:this._y+(a-this._y/this.scrollFactorY)},b.TilemapLayer.prototype._unfixY=function(a){return 1===this.scrollFactorY?a:this._y/this.scrollFactorY+(a-this._y)},b.TilemapLayer.prototype.getTileX=function(a){return this.game.math.snapToFloor(this._fixX(a),this.map.tileWidth)/this.map.tileWidth},b.TilemapLayer.prototype.getTileY=function(a){return this.game.math.snapToFloor(this._fixY(a),this.map.tileHeight)/this.map.tileHeight},b.TilemapLayer.prototype.getTileXY=function(a,b,c){return c.x=this.getTileX(a),c.y=this.getTileY(b),c},b.TilemapLayer.prototype.getIntersectingTiles=function(a,b,c,d){for(var e=this.getTiles(a,b,c,d,!1),f=a+c,g=b+d,h=e.length;h--;)e[h].intersects(a,b,f,g);return e},b.TilemapLayer.prototype.getTiles=function(a,b,c,d,e){"undefined"==typeof e&&(e=!1),a=this._fixX(a),b=this._fixY(b),c>this.layer.widthInPixels&&(c=this.layer.widthInPixels),d>this.layer.heightInPixels&&(d=this.layer.heightInPixels),this._tx=this.game.math.snapToFloor(a,this._cw)/this._cw,this._ty=this.game.math.snapToFloor(b,this._ch)/this._ch,this._tw=(this.game.math.snapToCeil(c,this._cw)+this._cw)/this._cw,this._th=(this.game.math.snapToCeil(d,this._ch)+this._ch)/this._ch,this._results=[];for(var f=this._ty;fthis.layer.width&&(this._maxX=this.layer.width),this._maxY>this.layer.height&&(this._maxY=this.layer.height)),this.dirty=!0},b.TilemapLayer.prototype.render=function(){if(this.layer.dirty&&(this.dirty=!0),this.dirty&&this.visible){this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.map.tileWidth),this._dy=-(this._y-this._startY*this.map.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.fillStyle=this.tileColor;var a,c;this.debug&&(this.context.globalAlpha=this.debugAlpha);for(var d=this._startY,e=this._startY+this._maxY;e>d;d++){this._column=this.layer.data[d];for(var f=this._startX,g=this._startX+this._maxX;g>f;f++)this._column[f]&&(a=this._column[f],c=this.map.tilesets[0],this.debug===!1&&a.alpha!==this.context.globalAlpha&&(this.context.globalAlpha=a.alpha),c.draw(this.context,Math.floor(this._tx),Math.floor(this._ty),a.index),a.debug&&(this.context.fillStyle="rgba(0, 255, 0, 0.4)",this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight))),this._tx+=this.map.tileWidth;this._tx=this._dx,this._ty+=this.map.tileHeight}return this.debug&&(this.context.globalAlpha=1,this.renderDebug()),this.game.renderType===b.WEBGL&&PIXI.updateWebGLTexture(this.baseTexture,this.game.renderer.gl),this.dirty=!1,this.layer.dirty=!1,!0}},b.TilemapLayer.prototype.OLDrender=function(){this.layer.dirty&&(this.dirty=!0),!this.dirty||!this.visible,this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.map.tileWidth),this._dy=-(this._y-this._startY*this.map.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.fillStyle=this.tileColor;var a,c;this.debug&&(this.context.globalAlpha=this.debugAlpha);for(var d=this._startY,e=this._startY+this._maxY;e>d;d++){this._column=this.layer.data[d];for(var f=this._startX,g=this._startX+this._maxX;g>f;f++)this._column[f]&&(a=this._column[f],this.map.tiles[a.index]&&(c=this.map.tilesets[this.map.tiles[a.index][2]],c.image?(this.debug===!1&&a.alpha!==this.context.globalAlpha&&(this.context.globalAlpha=a.alpha),c.tileWidth!==this.map.tileWidth||c.tileHeight!==this.map.tileHeight?this.context.drawImage(this.map.tilesets[this.map.tiles[a.index][2]].image,this.map.tiles[a.index][0],this.map.tiles[a.index][1],c.tileWidth,c.tileHeight,Math.floor(this._tx),Math.floor(this._ty)-(c.tileHeight-this.map.tileHeight),c.tileWidth,c.tileHeight):this.context.drawImage(this.map.tilesets[this.map.tiles[a.index][2]].image,this.map.tiles[a.index][0],this.map.tiles[a.index][1],this.map.tileWidth,this.map.tileHeight,Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight),this.context.fillStyle="rgba(0, 255, 0, 0.4)",this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight)):this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight))),this._tx+=this.map.tileWidth;this._tx=this._dx,this._ty+=this.map.tileHeight}return this.debug&&(this.context.globalAlpha=1,this.renderDebug()),this.game.renderType===b.WEBGL&&PIXI.updateWebGLTexture(this.baseTexture,this.game.renderer.gl),this.dirty=!1,this.layer.dirty=!1,!0},b.TilemapLayer.prototype.renderDebug=function(){this._tx=this._dx,this._ty=this._dy,this.context.strokeStyle=this.debugColor,this.context.fillStyle=this.debugFillColor;for(var a=this._startY,b=this._startY+this._maxY;b>a;a++){this._column=this.layer.data[a];for(var c=this._startX,d=this._startX+this._maxX;d>c;c++){var e=this._column[c];e&&(e.faceTop||e.faceBottom||e.faceLeft||e.faceRight)&&(this._tx=Math.floor(this._tx),this.debugFill&&this.context.fillRect(this._tx,this._ty,this._cw,this._ch),this.context.beginPath(),e.faceTop&&(this.context.moveTo(this._tx,this._ty),this.context.lineTo(this._tx+this._cw,this._ty)),e.faceBottom&&(this.context.moveTo(this._tx,this._ty+this._ch),this.context.lineTo(this._tx+this._cw,this._ty+this._ch)),e.faceLeft&&(this.context.moveTo(this._tx,this._ty),this.context.lineTo(this._tx,this._ty+this._ch)),e.faceRight&&(this.context.moveTo(this._tx+this._cw,this._ty),this.context.lineTo(this._tx+this._cw,this._ty+this._ch)),this.context.stroke()),this._tx+=this.map.tileWidth}this._tx=this._dx,this._ty+=this.map.tileHeight}},Object.defineProperty(b.TilemapLayer.prototype,"scrollX",{get:function(){return this._x},set:function(a){a!==this._x&&a>=0&&this.layer.widthInPixels>this.width&&(this._x=a,this._x>this.layer.widthInPixels-this.width&&(this._x=this.layer.widthInPixels-this.width),this._startX=this.game.math.floor(this._x/this.map.tileWidth),this._startX<0&&(this._startX=0),this._startX+this._maxX>this.layer.width&&(this._startX=this.layer.width-this._maxX),this.dirty=!0)}}),Object.defineProperty(b.TilemapLayer.prototype,"scrollY",{get:function(){return this._y},set:function(a){a!==this._y&&a>=0&&this.layer.heightInPixels>this.height&&(this._y=a,this._y>this.layer.heightInPixels-this.height&&(this._y=this.layer.heightInPixels-this.height),this._startY=this.game.math.floor(this._y/this.map.tileHeight),this._startY<0&&(this._startY=0),this._startY+this._maxY>this.layer.height&&(this._startY=this.layer.height-this._maxY),this.dirty=!0)}}),Object.defineProperty(b.TilemapLayer.prototype,"collisionWidth",{get:function(){return this._cw},set:function(a){this._cw=a,this.dirty=!0}}),Object.defineProperty(b.TilemapLayer.prototype,"collisionHeight",{get:function(){return this._ch},set:function(a){this._ch=a,this.dirty=!0}}),b.TilemapParser={tileset:function(a,c,d,e,f,g,h,i,j){var k=a.cache.getTilesetImage(c);if(null===k)return console.warn("Phaser.TilemapParser.tileSet: Invalid image key given"),null;var l=k.width,m=k.height;return-1===h&&(h=Math.round(l/d)),-1===i&&(i=Math.round(m/e)),-1===j&&(j=h*i),0===l||0===m||d>l||e>m||0===j?(console.warn("Phaser.TilemapParser.tileSet: width/height zero or width/height < given tileWidth/tileHeight"),null):new b.Tileset(k,c,d,e,f,g,h,i,j)},parse:function(a,c,d,e,f,g){if("undefined"==typeof d&&(d=32),"undefined"==typeof e&&(e=32),"undefined"==typeof f&&(f=10),"undefined"==typeof g&&(g=10),"undefined"==typeof c)return this.getEmptyData();if(null===c)return this.getEmptyData(d,e,f,g);var h=a.cache.getTilemapData(c);if(h){if(h.format===b.Tilemap.CSV)return this.parseCSV(c,h.data,d,e);if(!h.format||h.format===b.Tilemap.TILED_JSON)return this.parseTiledJSON(h.data)}else console.warn("Phaser.TilemapParser.parse - No map data found for key "+c)},parseCSV:function(a,c,d,e){var f=this.getEmptyData();c=c.trim();for(var g=[],h=c.split("\n"),i=h.length,j=0,k=0;kj;j++)h.push(a.layers[e].data[j]>0?new b.Tile(f,a.layers[e].data[j],g,i.length,a.tilewidth,a.tileheight):null),g++,g===a.layers[e].width&&(i.push(h),g=0,h=[]);f.data=i,d.push(f)}c.layers=d;for(var l=[],e=0;ep;p++)if(a.layers[e].objects[p].gid){var q={gid:a.layers[e].objects[p].gid,name:a.layers[e].objects[p].name,x:a.layers[e].objects[p].x,y:a.layers[e].objects[p].y,visible:a.layers[e].objects[p].visible,properties:a.layers[e].objects[p].properties};n[a.layers[e].name].push(q)}else if(a.layers[e].objects[p].polyline){var q={name:a.layers[e].objects[p].name,x:a.layers[e].objects[p].x,y:a.layers[e].objects[p].y,width:a.layers[e].objects[p].width,height:a.layers[e].objects[p].height,visible:a.layers[e].objects[p].visible,properties:a.layers[e].objects[p].properties};q.polyline=[];for(var r=0;r=c&&a<=c+this.width){var d=this.y;if(b>=d&&b<=d+this.height)return!0}return!1},b.Rectangle.prototype.constructor=b.Rectangle,b.EmptyRectangle=new b.Rectangle(0,0,0,0),b.Polygon=function(a){if(a instanceof Array||(a=Array.prototype.slice.call(arguments)),"number"==typeof a[0]){for(var c=[],d=0,e=a.length;e>d;d+=2)c.push(new b.Point(a[d],a[d+1]));a=c}this.points=a},b.Polygon.prototype.clone=function(){for(var a=[],c=0;cb!=i>b&&(h-f)*(b-g)/(i-g)+f>a;j&&(c=!c)}return c},b.Polygon.prototype.constructor=b.Polygon,b.Circle=function(a,b,c){this.x=a||0,this.y=b||0,this.radius=c||0},b.Circle.prototype.clone=function(){return new b.Circle(this.x,this.y,this.radius)},b.Circle.prototype.contains=function(a,b){if(this.radius<=0)return!1;var c=this.x-a,d=this.y-b,e=this.radius*this.radius;return c*=c,d*=d,e>=c+d},b.Circle.prototype.constructor=b.Circle,b.Ellipse=function(a,b,c,d){this.x=a||0,this.y=b||0,this.width=c||0,this.height=d||0},b.Ellipse.prototype.clone=function(){return new b.Ellipse(this.x,this.y,this.width,this.height)},b.Ellipse.prototype.contains=function(a,b){if(this.width<=0||this.height<=0)return!1;var c=(a-this.x)/this.width,d=(b-this.y)/this.height;return c*=c,d*=d,1>=c+d},b.Ellipse.prototype.getBounds=function(){return new b.Rectangle(this.x,this.y,this.width,this.height)},b.Ellipse.prototype.constructor=b.Ellipse,b.determineMatrixArrayType=function(){return"undefined"!=typeof Float32Array?Float32Array:Array},b.Matrix2=b.determineMatrixArrayType(),b.Matrix=function(){this.a=1,this.b=0,this.c=0,this.d=1,this.tx=0,this.ty=0},b.Matrix.prototype.fromArray=function(a){this.a=a[0],this.b=a[1],this.c=a[3],this.d=a[4],this.tx=a[2],this.ty=a[5]},b.Matrix.prototype.toArray=function(a){this.array||(this.array=new Float32Array(9));var b=this.array;return a?(this.array[0]=this.a,this.array[1]=this.c,this.array[2]=0,this.array[3]=this.b,this.array[4]=this.d,this.array[5]=0,this.array[6]=this.tx,this.array[7]=this.ty,this.array[8]=1):(this.array[0]=this.a,this.array[1]=this.b,this.array[2]=this.tx,this.array[3]=this.c,this.array[4]=this.d,this.array[5]=this.ty,this.array[6]=0,this.array[7]=0,this.array[8]=1),b},b.identityMatrix=new b.Matrix,b.DisplayObject=function(){this.position=new b.Point,this.scale=new b.Point(1,1),this.pivot=new b.Point(0,0),this.rotation=0,this.alpha=1,this.visible=!0,this.hitArea=null,this.buttonMode=!1,this.renderable=!1,this.parent=null,this.stage=null,this.worldAlpha=1,this._interactive=!1,this.defaultCursor="pointer",this.worldTransform=new b.Matrix,this.color=[],this.dynamic=!0,this._sr=0,this._cr=1,this.filterArea=new b.Rectangle(0,0,1,1),this._bounds=new b.Rectangle(0,0,1,1),this._currentBounds=null,this._mask=null,this._cacheAsBitmap=!1,this._cacheIsDirty=!1},b.DisplayObject.prototype.constructor=b.DisplayObject,b.DisplayObject.prototype.setInteractive=function(a){this.interactive=a},Object.defineProperty(b.DisplayObject.prototype,"interactive",{get:function(){return this._interactive},set:function(a){this._interactive=a,this.stage&&(this.stage.dirty=!0)}}),Object.defineProperty(b.DisplayObject.prototype,"worldVisible",{get:function(){var a=this;do{if(!a.visible)return!1;a=a.parent}while(a);return!0}}),Object.defineProperty(b.DisplayObject.prototype,"mask",{get:function(){return this._mask},set:function(a){this._mask&&(this._mask.isMask=!1),this._mask=a,this._mask&&(this._mask.isMask=!0)}}),Object.defineProperty(b.DisplayObject.prototype,"filters",{get:function(){return this._filters},set:function(a){if(a){for(var b=[],c=0;c=0&&b<=this.children.length))throw new Error(a+" The index "+b+" supplied is out of bounds "+this.children.length);a.parent&&a.parent.removeChild(a),a.parent=this,this.children.splice(b,0,a),this.stage&&a.setStageReference(this.stage)},b.DisplayObjectContainer.prototype.swapChildren=function(a,b){if(a!==b){var c=this.children.indexOf(a),d=this.children.indexOf(b);if(0>c||0>d)throw new Error("swapChildren: Both the supplied DisplayObjects must be a child of the caller.");this.children[c]=b,this.children[d]=a}},b.DisplayObjectContainer.prototype.getChildAt=function(a){if(a>=0&&aa;a++)this.children[a].updateTransform()},b.DisplayObjectContainer.prototype.getBounds=function(a){if(0===this.children.length)return b.EmptyRectangle;if(a){var c=this.worldTransform;this.worldTransform=a,this.updateTransform(),this.worldTransform=c}for(var d,e,f,g=1/0,h=1/0,i=-1/0,j=-1/0,k=!1,l=0,m=this.children.length;m>l;l++){var n=this.children[l];n.visible&&(k=!0,d=this.children[l].getBounds(a),g=ge?i:e,j=j>f?j:f)}if(!k)return b.EmptyRectangle;var o=this._bounds;return o.x=g,o.y=h,o.width=i-g,o.height=j-h,o},b.DisplayObjectContainer.prototype.getLocalBounds=function(){var a=this.worldTransform;this.worldTransform=b.identityMatrix;for(var c=0,d=this.children.length;d>c;c++)this.children[c].updateTransform();var e=this.getBounds();return this.worldTransform=a,e},b.DisplayObjectContainer.prototype.setStageReference=function(a){this.stage=a,this._interactive&&(this.stage.dirty=!0);for(var b=0,c=this.children.length;c>b;b++){var d=this.children[b];d.setStageReference(a)}},b.DisplayObjectContainer.prototype.removeStageReference=function(){for(var a=0,b=this.children.length;b>a;a++){var c=this.children[a];c.removeStageReference()}this._interactive&&(this.stage.dirty=!0),this.stage=null},b.DisplayObjectContainer.prototype._renderWebGL=function(a){if(this.visible&&!(this.alpha<=0)){if(this._cacheAsBitmap)return void this._renderCachedSprite(a);var b,c;if(this._mask||this._filters){for(this._mask&&(a.spriteBatch.stop(),a.maskManager.pushMask(this.mask,a),a.spriteBatch.start()),this._filters&&(a.spriteBatch.flush(),a.filterManager.pushFilter(this._filterBlock)),b=0,c=this.children.length;c>b;b++)this.children[b]._renderWebGL(a);a.spriteBatch.stop(),this._filters&&a.filterManager.popFilter(),this._mask&&a.maskManager.popMask(a),a.spriteBatch.start()}else for(b=0,c=this.children.length;c>b;b++)this.children[b]._renderWebGL(a)}},b.DisplayObjectContainer.prototype._renderCanvas=function(a){if(this.visible!==!1&&0!==this.alpha){if(this._cacheAsBitmap)return void this._renderCachedSprite(a);this._mask&&a.maskManager.pushMask(this._mask,a.context);for(var b=0,c=this.children.length;c>b;b++){var d=this.children[b];d._renderCanvas(a)}this._mask&&a.maskManager.popMask(a.context)}},b.Sprite=function(a){b.DisplayObjectContainer.call(this),this.anchor=new b.Point,this.texture=a,this._width=0,this._height=0,this.tint=16777215,this.blendMode=b.blendModes.NORMAL,a.baseTexture.hasLoaded?this.onTextureUpdate():(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},b.Sprite.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Sprite.prototype.constructor=b.Sprite,Object.defineProperty(b.Sprite.prototype,"width",{get:function(){return this.scale.x*this.texture.frame.width},set:function(a){this.scale.x=a/this.texture.frame.width,this._width=a}}),Object.defineProperty(b.Sprite.prototype,"height",{get:function(){return this.scale.y*this.texture.frame.height},set:function(a){this.scale.y=a/this.texture.frame.height,this._height=a}}),b.Sprite.prototype.setTexture=function(a){this.texture.baseTexture!==a.baseTexture?(this.textureChange=!0,this.texture=a):this.texture=a,this.cachedTint=16777215,this.updateFrame=!0},b.Sprite.prototype.onTextureUpdate=function(){this._width&&(this.scale.x=this._width/this.texture.frame.width),this._height&&(this.scale.y=this._height/this.texture.frame.height),this.updateFrame=!0},b.Sprite.prototype.getBounds=function(a){var b=this.texture.frame.width,c=this.texture.frame.height,d=b*(1-this.anchor.x),e=b*-this.anchor.x,f=c*(1-this.anchor.y),g=c*-this.anchor.y,h=a||this.worldTransform,i=h.a,j=h.c,k=h.b,l=h.d,m=h.tx,n=h.ty,o=i*e+k*g+m,p=l*g+j*e+n,q=i*d+k*g+m,r=l*g+j*d+n,s=i*d+k*f+m,t=l*f+j*d+n,u=i*e+k*f+m,v=l*f+j*e+n,w=-1/0,x=-1/0,y=1/0,z=1/0;y=y>o?o:y,y=y>q?q:y,y=y>s?s:y,y=y>u?u:y,z=z>p?p:z,z=z>r?r:z,z=z>t?t:z,z=z>v?v:z,w=o>w?o:w,w=q>w?q:w,w=s>w?s:w,w=u>w?u:w,x=p>x?p:x,x=r>x?r:x,x=t>x?t:x,x=v>x?v:x;var A=this._bounds;return A.x=y,A.width=w-y,A.y=z,A.height=x-z,this._currentBounds=A,A},b.Sprite.prototype._renderWebGL=function(a){if(this.visible&&!(this.alpha<=0)){var b,c;if(this._mask||this._filters){var d=a.spriteBatch;for(this._mask&&(d.stop(),a.maskManager.pushMask(this.mask,a),d.start()),this._filters&&(d.flush(),a.filterManager.pushFilter(this._filterBlock)),d.render(this),b=0,c=this.children.length;c>b;b++)this.children[b]._renderWebGL(a);d.stop(),this._filters&&a.filterManager.popFilter(),this._mask&&a.maskManager.popMask(a),d.start()}else for(a.spriteBatch.render(this),b=0,c=this.children.length;c>b;b++)this.children[b]._renderWebGL(a)}},b.Sprite.prototype._renderCanvas=function(a){if(this.visible!==!1&&0!==this.alpha){var c=this.texture.frame,d=a.context,e=this.texture;if(this.blendMode!==a.currentBlendMode&&(a.currentBlendMode=this.blendMode,d.globalCompositeOperation=b.blendModesCanvas[a.currentBlendMode]),this._mask&&a.maskManager.pushMask(this._mask,a.context),c&&c.width&&c.height&&e.baseTexture.source){d.globalAlpha=this.worldAlpha;var f=this.worldTransform;if(a.roundPixels?d.setTransform(f.a,f.c,f.b,f.d,0|f.tx,0|f.ty):d.setTransform(f.a,f.c,f.b,f.d,f.tx,f.ty),a.smoothProperty&&a.scaleMode!==this.texture.baseTexture.scaleMode&&(a.scaleMode=this.texture.baseTexture.scaleMode,d[a.smoothProperty]=a.scaleMode===b.scaleModes.LINEAR),16777215!==this.tint){if(this.cachedTint!==this.tint){if(!e.baseTexture.hasLoaded)return;this.cachedTint=this.tint,this.tintedTexture=b.CanvasTinter.getTintedTexture(this,this.tint)}d.drawImage(this.tintedTexture,0,0,c.width,c.height,this.anchor.x*-c.width,this.anchor.y*-c.height,c.width,c.height)}else if(e.trim){var g=e.trim;d.drawImage(this.texture.baseTexture.source,c.x,c.y,c.width,c.height,g.x-this.anchor.x*g.width,g.y-this.anchor.y*g.height,c.width,c.height)}else d.drawImage(this.texture.baseTexture.source,c.x,c.y,c.width,c.height,this.anchor.x*-c.width,this.anchor.y*-c.height,c.width,c.height)}for(var h=0,i=this.children.length;i>h;h++){var j=this.children[h];j._renderCanvas(a)}this._mask&&a.maskManager.popMask(a.context)}},b.Sprite.fromFrame=function(a){var c=b.TextureCache[a];if(!c)throw new Error('The frameId "'+a+'" does not exist in the texture cache'+this);return new b.Sprite(c)},b.Sprite.fromImage=function(a,c,d){var e=b.Texture.fromImage(a,c,d);return new b.Sprite(e)},b.SpriteBatch=function(a){b.DisplayObjectContainer.call(this),this.textureThing=a,this.ready=!1},b.SpriteBatch.prototype=Object.create(b.DisplayObjectContainer.prototype),b.SpriteBatch.constructor=b.SpriteBatch,b.SpriteBatch.prototype.initWebGL=function(a){this.fastSpriteBatch=new b.WebGLFastSpriteBatch(a),this.ready=!0},b.SpriteBatch.prototype.updateTransform=function(){b.DisplayObject.prototype.updateTransform.call(this)},b.SpriteBatch.prototype._renderWebGL=function(a){!this.visible||this.alpha<=0||!this.children.length||(this.ready||this.initWebGL(a.gl),a.spriteBatch.stop(),a.shaderManager.activateShader(a.shaderManager.fastShader),this.fastSpriteBatch.begin(this,a),this.fastSpriteBatch.render(this),a.shaderManager.activateShader(a.shaderManager.defaultShader),a.spriteBatch.start())},b.SpriteBatch.prototype._renderCanvas=function(a){var c=a.context;c.globalAlpha=this.worldAlpha,b.DisplayObject.prototype.updateTransform.call(this);for(var d=this.worldTransform,e=!0,f=0;fe?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}d=2?parseInt(c[c.length-2],10):b.BitmapText.fonts[this.fontName].size,this.dirty=!0,this.tint=a.tint},b.BitmapText.prototype.updateText=function(){for(var a=b.BitmapText.fonts[this.fontName],c=new b.Point,d=null,e=[],f=0,g=[],h=0,i=this.fontSize/a.size,j=0;j=j;j++){var n=0;"right"===this.style.align?n=f-g[j]:"center"===this.style.align&&(n=(f-g[j])/2),m.push(n)}var o=this.children.length,p=e.length,q=this.tint||16777215;for(j=0;p>j;j++){var r=o>j?this.children[j]:this._pool.pop();r?r.setTexture(e[j].texture):r=new b.Sprite(e[j].texture),r.position.x=(e[j].position.x+m[e[j].line])*i,r.position.y=e[j].position.y*i,r.scale.x=r.scale.y=i,r.tint=q,r.parent||this.addChild(r)}for(;this.children.length>p;){var s=this.getChildAt(this.children.length-1);this._pool.push(s),this.removeChild(s)}this.textWidth=f*i,this.textHeight=(c.y+a.lineHeight)*i},b.BitmapText.prototype.updateTransform=function(){this.dirty&&(this.updateText(),this.dirty=!1),b.DisplayObjectContainer.prototype.updateTransform.call(this)},b.BitmapText.fonts={},b.Stage=function(a){b.DisplayObjectContainer.call(this),this.worldTransform=new b.Matrix,this.interactive=!0,this.interactionManager=new b.InteractionManager(this),this.dirty=!0,this.stage=this,this.stage.hitArea=new b.Rectangle(0,0,1e5,1e5),this.setBackgroundColor(a)},b.Stage.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Stage.prototype.constructor=b.Stage,b.Stage.prototype.setInteractionDelegate=function(a){this.interactionManager.setTargetDomElement(a)},b.Stage.prototype.updateTransform=function(){this.worldAlpha=1;for(var a=0,b=this.children.length;b>a;a++)this.children[a].updateTransform();this.dirty&&(this.dirty=!1,this.interactionManager.dirty=!0),this.interactive&&this.interactionManager.update()},b.Stage.prototype.setBackgroundColor=function(a){this.backgroundColor=a||0,this.backgroundColorSplit=b.hex2rgb(this.backgroundColor);var c=this.backgroundColor.toString(16);c="000000".substr(0,6-c.length)+c,this.backgroundColorString="#"+c},b.Stage.prototype.getMousePosition=function(){return this.interactionManager.mouse.global};for(var c=0,d=["ms","moz","webkit","o"],e=0;e>16&255)/255,(a>>8&255)/255,(255&a)/255]},b.rgb2hex=function(a){return(255*a[0]<<16)+(255*a[1]<<8)+255*a[2]},"function"!=typeof Function.prototype.bind&&(Function.prototype.bind=function(){var a=Array.prototype.slice;return function(b){function c(){var f=e.concat(a.call(arguments));d.apply(this instanceof c?this:b,f)}var d=this,e=a.call(arguments,1);if("function"!=typeof d)throw new TypeError;return c.prototype=function f(a){return a&&(f.prototype=a),this instanceof f?void 0:new f}(d.prototype),c}}()),b.AjaxRequest=function(){var a=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Microsoft.XMLHTTP"];if(!window.ActiveXObject)return window.XMLHttpRequest?new window.XMLHttpRequest:!1;for(var b=0;b0&&0===(a&a-1))return a;for(var b=1;a>b;)b<<=1;return b},b.EventTarget=function(){var a={};this.addEventListener=this.on=function(b,c){void 0===a[b]&&(a[b]=[]),-1===a[b].indexOf(c)&&a[b].push(c)},this.dispatchEvent=this.emit=function(b){if(a[b.type]&&a[b.type].length)for(var c=0,d=a[b.type].length;d>c;c++)a[b.type][c](b)},this.removeEventListener=this.off=function(b,c){var d=a[b].indexOf(c);-1!==d&&a[b].splice(d,1)},this.removeAllEventListeners=function(b){var c=a[b];c&&(c.length=0)}},b.PolyK={},b.PolyK.Triangulate=function(a){var c=!0,d=a.length>>1;if(3>d)return[];for(var e=[],f=[],g=0;d>g;g++)f.push(g);g=0;for(var h=d;h>3;){var i=f[(g+0)%h],j=f[(g+1)%h],k=f[(g+2)%h],l=a[2*i],m=a[2*i+1],n=a[2*j],o=a[2*j+1],p=a[2*k],q=a[2*k+1],r=!1;if(b.PolyK._convex(l,m,n,o,p,q,c)){r=!0;for(var s=0;h>s;s++){var t=f[s];if(t!==i&&t!==j&&t!==k&&b.PolyK._PointInTriangle(a[2*t],a[2*t+1],l,m,n,o,p,q)){r=!1;break}}}if(r)e.push(i,j,k),f.splice((g+1)%h,1),h--,g=0;else if(g++>3*h){if(!c)return window.console.log("PIXI Warning: shape too complex to fill"),[];for(e=[],f=[],g=0;d>g;g++)f.push(g);g=0,h=d,c=!1}}return e.push(f[0],f[1],f[2]),e},b.PolyK._PointInTriangle=function(a,b,c,d,e,f,g,h){var i=g-c,j=h-d,k=e-c,l=f-d,m=a-c,n=b-d,o=i*i+j*j,p=i*k+j*l,q=i*m+j*n,r=k*k+l*l,s=k*m+l*n,t=1/(o*r-p*p),u=(r*q-p*s)*t,v=(o*s-p*q)*t;return u>=0&&v>=0&&1>u+v},b.PolyK._convex=function(a,b,c,d,e,f,g){return(b-d)*(e-c)+(c-a)*(f-d)>=0===g},b.initDefaultShaders=function(){},b.CompileVertexShader=function(a,c){return b._CompileShader(a,c,a.VERTEX_SHADER)},b.CompileFragmentShader=function(a,c){return b._CompileShader(a,c,a.FRAGMENT_SHADER)},b._CompileShader=function(a,b,c){var d=b.join("\n"),e=a.createShader(c);return a.shaderSource(e,d),a.compileShader(e),a.getShaderParameter(e,a.COMPILE_STATUS)?e:(window.console.log(a.getShaderInfoLog(e)),null)},b.compileProgram=function(a,c,d){var e=b.CompileFragmentShader(a,d),f=b.CompileVertexShader(a,c),g=a.createProgram();return a.attachShader(g,f),a.attachShader(g,e),a.linkProgram(g),a.getProgramParameter(g,a.LINK_STATUS)||window.console.log("Could not initialise shaders"),g},b.PixiShader=function(a){this.gl=a,this.program=null,this.fragmentSrc=["precision lowp float;","varying vec2 vTextureCoord;","varying vec4 vColor;","uniform sampler2D uSampler;","void main(void) {"," gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;","}"],this.textureCount=0,this.attributes=[],this.init()},b.PixiShader.prototype.init=function(){var a=this.gl,c=b.compileProgram(a,this.vertexSrc||b.PixiShader.defaultVertexSrc,this.fragmentSrc);a.useProgram(c),this.uSampler=a.getUniformLocation(c,"uSampler"),this.projectionVector=a.getUniformLocation(c,"projectionVector"),this.offsetVector=a.getUniformLocation(c,"offsetVector"),this.dimensions=a.getUniformLocation(c,"dimensions"),this.aVertexPosition=a.getAttribLocation(c,"aVertexPosition"),this.aTextureCoord=a.getAttribLocation(c,"aTextureCoord"),this.colorAttribute=a.getAttribLocation(c,"aColor"),-1===this.colorAttribute&&(this.colorAttribute=2),this.attributes=[this.aVertexPosition,this.aTextureCoord,this.colorAttribute];for(var d in this.uniforms)this.uniforms[d].uniformLocation=a.getUniformLocation(c,d);this.initUniforms(),this.program=c},b.PixiShader.prototype.initUniforms=function(){this.textureCount=1;var a,b=this.gl;for(var c in this.uniforms){a=this.uniforms[c];var d=a.type;"sampler2D"===d?(a._init=!1,null!==a.value&&this.initSampler2D(a)):"mat2"===d||"mat3"===d||"mat4"===d?(a.glMatrix=!0,a.glValueLength=1,"mat2"===d?a.glFunc=b.uniformMatrix2fv:"mat3"===d?a.glFunc=b.uniformMatrix3fv:"mat4"===d&&(a.glFunc=b.uniformMatrix4fv)):(a.glFunc=b["uniform"+d],a.glValueLength="2f"===d||"2i"===d?2:"3f"===d||"3i"===d?3:"4f"===d||"4i"===d?4:1)}},b.PixiShader.prototype.initSampler2D=function(a){if(a.value&&a.value.baseTexture&&a.value.baseTexture.hasLoaded){var b=this.gl;if(b.activeTexture(b["TEXTURE"+this.textureCount]),b.bindTexture(b.TEXTURE_2D,a.value.baseTexture._glTextures[b.id]),a.textureData){var c=a.textureData,d=c.magFilter?c.magFilter:b.LINEAR,e=c.minFilter?c.minFilter:b.LINEAR,f=c.wrapS?c.wrapS:b.CLAMP_TO_EDGE,g=c.wrapT?c.wrapT:b.CLAMP_TO_EDGE,h=c.luminance?b.LUMINANCE:b.RGBA;if(c.repeat&&(f=b.REPEAT,g=b.REPEAT),b.pixelStorei(b.UNPACK_FLIP_Y_WEBGL,!!c.flipY),c.width){var i=c.width?c.width:512,j=c.height?c.height:2,k=c.border?c.border:0;b.texImage2D(b.TEXTURE_2D,0,h,i,j,k,h,b.UNSIGNED_BYTE,null)}else b.texImage2D(b.TEXTURE_2D,0,h,b.RGBA,b.UNSIGNED_BYTE,a.value.baseTexture.source);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,d),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,e),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,f),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,g)}b.uniform1i(a.uniformLocation,this.textureCount),a._init=!0,this.textureCount++}},b.PixiShader.prototype.syncUniforms=function(){this.textureCount=1;var a,c=this.gl;for(var d in this.uniforms)a=this.uniforms[d],1===a.glValueLength?a.glMatrix===!0?a.glFunc.call(c,a.uniformLocation,a.transpose,a.value):a.glFunc.call(c,a.uniformLocation,a.value):2===a.glValueLength?a.glFunc.call(c,a.uniformLocation,a.value.x,a.value.y):3===a.glValueLength?a.glFunc.call(c,a.uniformLocation,a.value.x,a.value.y,a.value.z):4===a.glValueLength?a.glFunc.call(c,a.uniformLocation,a.value.x,a.value.y,a.value.z,a.value.w):"sampler2D"===a.type&&(a._init?(c.activeTexture(c["TEXTURE"+this.textureCount]),c.bindTexture(c.TEXTURE_2D,a.value.baseTexture._glTextures[c.id]||b.createWebGLTexture(a.value.baseTexture,c)),c.uniform1i(a.uniformLocation,this.textureCount),this.textureCount++):this.initSampler2D(a))},b.PixiShader.prototype.destroy=function(){this.gl.deleteProgram(this.program),this.uniforms=null,this.gl=null,this.attributes=null},b.PixiShader.defaultVertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute vec2 aColor;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","varying vec4 vColor;","const vec2 center = vec2(-1.0, 1.0);","void main(void) {"," gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);"," vTextureCoord = aTextureCoord;"," vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;"," vColor = vec4(color * aColor.x, aColor.x);","}"],b.PixiFastShader=function(a){this.gl=a,this.program=null,this.fragmentSrc=["precision lowp float;","varying vec2 vTextureCoord;","varying float vColor;","uniform sampler2D uSampler;","void main(void) {"," gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aPositionCoord;","attribute vec2 aScale;","attribute float aRotation;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","uniform mat3 uMatrix;","varying vec2 vTextureCoord;","varying float vColor;","const vec2 center = vec2(-1.0, 1.0);","void main(void) {"," vec2 v;"," vec2 sv = aVertexPosition * aScale;"," v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);"," v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);"," v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;"," gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);"," vTextureCoord = aTextureCoord;"," vColor = aColor;","}"],this.textureCount=0,this.init() },b.PixiFastShader.prototype.init=function(){var a=this.gl,c=b.compileProgram(a,this.vertexSrc,this.fragmentSrc);a.useProgram(c),this.uSampler=a.getUniformLocation(c,"uSampler"),this.projectionVector=a.getUniformLocation(c,"projectionVector"),this.offsetVector=a.getUniformLocation(c,"offsetVector"),this.dimensions=a.getUniformLocation(c,"dimensions"),this.uMatrix=a.getUniformLocation(c,"uMatrix"),this.aVertexPosition=a.getAttribLocation(c,"aVertexPosition"),this.aPositionCoord=a.getAttribLocation(c,"aPositionCoord"),this.aScale=a.getAttribLocation(c,"aScale"),this.aRotation=a.getAttribLocation(c,"aRotation"),this.aTextureCoord=a.getAttribLocation(c,"aTextureCoord"),this.colorAttribute=a.getAttribLocation(c,"aColor"),-1===this.colorAttribute&&(this.colorAttribute=2),this.attributes=[this.aVertexPosition,this.aPositionCoord,this.aScale,this.aRotation,this.aTextureCoord,this.colorAttribute],this.program=c},b.PixiFastShader.prototype.destroy=function(){this.gl.deleteProgram(this.program),this.uniforms=null,this.gl=null,this.attributes=null},b.StripShader=function(){this.program=null,this.fragmentSrc=["precision mediump float;","varying vec2 vTextureCoord;","varying float vColor;","uniform float alpha;","uniform sampler2D uSampler;","void main(void) {"," gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));"," gl_FragColor = gl_FragColor * alpha;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform mat3 translationMatrix;","uniform vec2 projectionVector;","varying vec2 vTextureCoord;","uniform vec2 offsetVector;","varying float vColor;","void main(void) {"," vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);"," v -= offsetVector.xyx;"," gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);"," vTextureCoord = aTextureCoord;"," vColor = aColor;","}"]},b.StripShader.prototype.init=function(){var a=b.gl,c=b.compileProgram(a,this.vertexSrc,this.fragmentSrc);a.useProgram(c),this.uSampler=a.getUniformLocation(c,"uSampler"),this.projectionVector=a.getUniformLocation(c,"projectionVector"),this.offsetVector=a.getUniformLocation(c,"offsetVector"),this.colorAttribute=a.getAttribLocation(c,"aColor"),this.aVertexPosition=a.getAttribLocation(c,"aVertexPosition"),this.aTextureCoord=a.getAttribLocation(c,"aTextureCoord"),this.translationMatrix=a.getUniformLocation(c,"translationMatrix"),this.alpha=a.getUniformLocation(c,"alpha"),this.program=c},b.PrimitiveShader=function(a){this.gl=a,this.program=null,this.fragmentSrc=["precision mediump float;","varying vec4 vColor;","void main(void) {"," gl_FragColor = vColor;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec4 aColor;","uniform mat3 translationMatrix;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","uniform float alpha;","uniform vec3 tint;","varying vec4 vColor;","void main(void) {"," vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);"," v -= offsetVector.xyx;"," gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);"," vColor = aColor * vec4(tint * alpha, alpha);","}"],this.init()},b.PrimitiveShader.prototype.init=function(){var a=this.gl,c=b.compileProgram(a,this.vertexSrc,this.fragmentSrc);a.useProgram(c),this.projectionVector=a.getUniformLocation(c,"projectionVector"),this.offsetVector=a.getUniformLocation(c,"offsetVector"),this.tintColor=a.getUniformLocation(c,"tint"),this.aVertexPosition=a.getAttribLocation(c,"aVertexPosition"),this.colorAttribute=a.getAttribLocation(c,"aColor"),this.attributes=[this.aVertexPosition,this.colorAttribute],this.translationMatrix=a.getUniformLocation(c,"translationMatrix"),this.alpha=a.getUniformLocation(c,"alpha"),this.program=c},b.PrimitiveShader.prototype.destroy=function(){this.gl.deleteProgram(this.program),this.uniforms=null,this.gl=null,this.attribute=null},b.WebGLGraphics=function(){},b.WebGLGraphics.renderGraphics=function(a,c){var d=c.gl,e=c.projection,f=c.offset,g=c.shaderManager.primitiveShader;a._webGL[d.id]||(a._webGL[d.id]={points:[],indices:[],lastIndex:0,buffer:d.createBuffer(),indexBuffer:d.createBuffer()});var h=a._webGL[d.id];a.dirty&&(a.dirty=!1,a.clearDirty&&(a.clearDirty=!1,h.lastIndex=0,h.points=[],h.indices=[]),b.WebGLGraphics.updateGraphics(a,d)),c.shaderManager.activatePrimitiveShader(),d.blendFunc(d.ONE,d.ONE_MINUS_SRC_ALPHA),d.uniformMatrix3fv(g.translationMatrix,!1,a.worldTransform.toArray(!0)),d.uniform2f(g.projectionVector,e.x,-e.y),d.uniform2f(g.offsetVector,-f.x,-f.y),d.uniform3fv(g.tintColor,b.hex2rgb(a.tint)),d.uniform1f(g.alpha,a.worldAlpha),d.bindBuffer(d.ARRAY_BUFFER,h.buffer),d.vertexAttribPointer(g.aVertexPosition,2,d.FLOAT,!1,24,0),d.vertexAttribPointer(g.colorAttribute,4,d.FLOAT,!1,24,8),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,h.indexBuffer),d.drawElements(d.TRIANGLE_STRIP,h.indices.length,d.UNSIGNED_SHORT,0),c.shaderManager.deactivatePrimitiveShader()},b.WebGLGraphics.updateGraphics=function(a,c){for(var d=a._webGL[c.id],e=d.lastIndex;e3&&b.WebGLGraphics.buildPoly(f,d),f.lineWidth>0&&b.WebGLGraphics.buildLine(f,d)):f.type===b.Graphics.RECT?b.WebGLGraphics.buildRectangle(f,d):(f.type===b.Graphics.CIRC||f.type===b.Graphics.ELIP)&&b.WebGLGraphics.buildCircle(f,d)}d.lastIndex=a.graphicsData.length,d.glPoints=new Float32Array(d.points),c.bindBuffer(c.ARRAY_BUFFER,d.buffer),c.bufferData(c.ARRAY_BUFFER,d.glPoints,c.STATIC_DRAW),d.glIndicies=new Uint16Array(d.indices),c.bindBuffer(c.ELEMENT_ARRAY_BUFFER,d.indexBuffer),c.bufferData(c.ELEMENT_ARRAY_BUFFER,d.glIndicies,c.STATIC_DRAW)},b.WebGLGraphics.buildRectangle=function(a,c){var d=a.points,e=d[0],f=d[1],g=d[2],h=d[3];if(a.fill){var i=b.hex2rgb(a.fillColor),j=a.fillAlpha,k=i[0]*j,l=i[1]*j,m=i[2]*j,n=c.points,o=c.indices,p=n.length/6;n.push(e,f),n.push(k,l,m,j),n.push(e+g,f),n.push(k,l,m,j),n.push(e,f+h),n.push(k,l,m,j),n.push(e+g,f+h),n.push(k,l,m,j),o.push(p,p,p+1,p+2,p+3,p+3)}if(a.lineWidth){var q=a.points;a.points=[e,f,e+g,f,e+g,f+h,e,f+h,e,f],b.WebGLGraphics.buildLine(a,c),a.points=q}},b.WebGLGraphics.buildCircle=function(a,c){var d=a.points,e=d[0],f=d[1],g=d[2],h=d[3],i=40,j=2*Math.PI/i,k=0;if(a.fill){var l=b.hex2rgb(a.fillColor),m=a.fillAlpha,n=l[0]*m,o=l[1]*m,p=l[2]*m,q=c.points,r=c.indices,s=q.length/6;for(r.push(s),k=0;i+1>k;k++)q.push(e,f,n,o,p,m),q.push(e+Math.sin(j*k)*g,f+Math.cos(j*k)*h,n,o,p,m),r.push(s++,s++);r.push(s-1)}if(a.lineWidth){var t=a.points;for(a.points=[],k=0;i+1>k;k++)a.points.push(e+Math.sin(j*k)*g,f+Math.cos(j*k)*h);b.WebGLGraphics.buildLine(a,c),a.points=t}},b.WebGLGraphics.buildLine=function(a,c){var d=0,e=a.points;if(0!==e.length){if(a.lineWidth%2)for(d=0;dd;d++)l=e[2*(d-1)],m=e[2*(d-1)+1],n=e[2*d],o=e[2*d+1],p=e[2*(d+1)],q=e[2*(d+1)+1],r=-(m-o),s=l-n,F=Math.sqrt(r*r+s*s),r/=F,s/=F,r*=L,s*=L,t=-(o-q),u=n-p,F=Math.sqrt(t*t+u*u),t/=F,u/=F,t*=L,u*=L,x=-s+m-(-s+o),y=-r+n-(-r+l),z=(-r+l)*(-s+o)-(-r+n)*(-s+m),A=-u+q-(-u+o),B=-t+n-(-t+p),C=(-t+p)*(-u+o)-(-t+n)*(-u+q),D=x*B-A*y,Math.abs(D)<.1?(D+=10.1,G.push(n-r,o-s,O,P,Q,N),G.push(n+r,o+s,O,P,Q,N)):(j=(y*C-B*z)/D,k=(A*z-x*C)/D,E=(j-n)*(j-n)+(k-o)+(k-o),E>19600?(v=r-t,w=s-u,F=Math.sqrt(v*v+w*w),v/=F,w/=F,v*=L,w*=L,G.push(n-v,o-w),G.push(O,P,Q,N),G.push(n+v,o+w),G.push(O,P,Q,N),G.push(n-v,o-w),G.push(O,P,Q,N),J++):(G.push(j,k),G.push(O,P,Q,N),G.push(n-(j-n),o-(k-o)),G.push(O,P,Q,N)));for(l=e[2*(I-2)],m=e[2*(I-2)+1],n=e[2*(I-1)],o=e[2*(I-1)+1],r=-(m-o),s=l-n,F=Math.sqrt(r*r+s*s),r/=F,s/=F,r*=L,s*=L,G.push(n-r,o-s),G.push(O,P,Q,N),G.push(n+r,o+s),G.push(O,P,Q,N),H.push(K),d=0;J>d;d++)H.push(K++);H.push(K-1)}},b.WebGLGraphics.buildPoly=function(a,c){var d=a.points;if(!(d.length<6)){var e=c.points,f=c.indices,g=d.length/2,h=b.hex2rgb(a.fillColor),i=a.fillAlpha,j=h[0]*i,k=h[1]*i,l=h[2]*i,m=b.PolyK.Triangulate(d),n=e.length/6,o=0;for(o=0;oo;o++)e.push(d[2*o],d[2*o+1],j,k,l,i)}},b.glContexts=[],b.WebGLRenderer=function(a,c,d,e,f){b.defaultRenderer||(b.defaultRenderer=this),this.type=b.WEBGL_RENDERER,this.transparent=!!e,this.width=a||800,this.height=c||600,this.view=d||document.createElement("canvas"),this.view.width=this.width,this.view.height=this.height,this.contextLost=this.handleContextLost.bind(this),this.contextRestoredLost=this.handleContextRestored.bind(this),this.view.addEventListener("webglcontextlost",this.contextLost,!1),this.view.addEventListener("webglcontextrestored",this.contextRestoredLost,!1),this.options={alpha:this.transparent,antialias:!!f,premultipliedAlpha:!!e,stencil:!0};try{this.gl=this.view.getContext("experimental-webgl",this.options)}catch(g){try{this.gl=this.view.getContext("webgl",this.options)}catch(h){throw new Error(" This browser does not support webGL. Try using the canvas renderer"+this)}}var i=this.gl;this.glContextId=i.id=b.WebGLRenderer.glContextId++,b.glContexts[this.glContextId]=i,b.blendModesWebGL||(b.blendModesWebGL=[],b.blendModesWebGL[b.blendModes.NORMAL]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.ADD]=[i.SRC_ALPHA,i.DST_ALPHA],b.blendModesWebGL[b.blendModes.MULTIPLY]=[i.DST_COLOR,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.SCREEN]=[i.SRC_ALPHA,i.ONE],b.blendModesWebGL[b.blendModes.OVERLAY]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.DARKEN]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.LIGHTEN]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.COLOR_DODGE]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.COLOR_BURN]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.HARD_LIGHT]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.SOFT_LIGHT]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.DIFFERENCE]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.EXCLUSION]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.HUE]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.SATURATION]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.COLOR]=[i.ONE,i.ONE_MINUS_SRC_ALPHA],b.blendModesWebGL[b.blendModes.LUMINOSITY]=[i.ONE,i.ONE_MINUS_SRC_ALPHA]),this.projection=new b.Point,this.projection.x=this.width/2,this.projection.y=-this.height/2,this.offset=new b.Point(0,0),this.resize(this.width,this.height),this.contextLost=!1,this.shaderManager=new b.WebGLShaderManager(i),this.spriteBatch=new b.WebGLSpriteBatch(i),this.maskManager=new b.WebGLMaskManager(i),this.filterManager=new b.WebGLFilterManager(i,this.transparent),this.renderSession={},this.renderSession.gl=this.gl,this.renderSession.drawCount=0,this.renderSession.shaderManager=this.shaderManager,this.renderSession.maskManager=this.maskManager,this.renderSession.filterManager=this.filterManager,this.renderSession.spriteBatch=this.spriteBatch,this.renderSession.renderer=this,i.useProgram(this.shaderManager.defaultShader.program),i.disable(i.DEPTH_TEST),i.disable(i.CULL_FACE),i.enable(i.BLEND),i.colorMask(!0,!0,!0,this.transparent)},b.WebGLRenderer.prototype.constructor=b.WebGLRenderer,b.WebGLRenderer.prototype.render=function(a){if(!this.contextLost){this.__stage!==a&&(a.interactive&&a.interactionManager.removeEvents(),this.__stage=a),b.WebGLRenderer.updateTextures(),a.updateTransform(),a._interactive&&(a._interactiveEventsAdded||(a._interactiveEventsAdded=!0,a.interactionManager.setTarget(this)));var c=this.gl;c.viewport(0,0,this.width,this.height),c.bindFramebuffer(c.FRAMEBUFFER,null),this.transparent?c.clearColor(0,0,0,0):c.clearColor(a.backgroundColorSplit[0],a.backgroundColorSplit[1],a.backgroundColorSplit[2],1),c.clear(c.COLOR_BUFFER_BIT),this.renderDisplayObject(a,this.projection),a.interactive?a._interactiveEventsAdded||(a._interactiveEventsAdded=!0,a.interactionManager.setTarget(this)):a._interactiveEventsAdded&&(a._interactiveEventsAdded=!1,a.interactionManager.setTarget(this))}},b.WebGLRenderer.prototype.renderDisplayObject=function(a,b,c){this.renderSession.drawCount=0,this.renderSession.currentBlendMode=9999,this.renderSession.projection=b,this.renderSession.offset=this.offset,this.spriteBatch.begin(this.renderSession),this.filterManager.begin(this.renderSession,c),a._renderWebGL(this.renderSession),this.spriteBatch.end()},b.WebGLRenderer.updateTextures=function(){var a=0;for(a=0;a=0;c--){var d=a._glTextures[c],e=b.glContexts[c];e&&d&&e.deleteTexture(d)}a._glTextures.length=0},b.WebGLRenderer.updateTextureFrame=function(a){a.updateFrame=!1,a._updateWebGLuvs()},b.WebGLRenderer.prototype.resize=function(a,b){this.width=a,this.height=b,this.view.width=a,this.view.height=b,this.gl.viewport(0,0,this.width,this.height),this.projection.x=this.width/2,this.projection.y=-this.height/2},b.createWebGLTexture=function(a,c){return a.hasLoaded&&(a._glTextures[c.id]=c.createTexture(),c.bindTexture(c.TEXTURE_2D,a._glTextures[c.id]),c.pixelStorei(c.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,a.source),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,a.scaleMode===b.scaleModes.LINEAR?c.LINEAR:c.NEAREST),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,a.scaleMode===b.scaleModes.LINEAR?c.LINEAR:c.NEAREST),a._powerOf2?(c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,c.REPEAT),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,c.REPEAT)):(c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,c.CLAMP_TO_EDGE),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,c.CLAMP_TO_EDGE)),c.bindTexture(c.TEXTURE_2D,null)),a._glTextures[c.id]},b.updateWebGLTexture=function(a,c){a._glTextures[c.id]&&(c.bindTexture(c.TEXTURE_2D,a._glTextures[c.id]),c.pixelStorei(c.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,a.source),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,a.scaleMode===b.scaleModes.LINEAR?c.LINEAR:c.NEAREST),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,a.scaleMode===b.scaleModes.LINEAR?c.LINEAR:c.NEAREST),a._powerOf2?(c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,c.REPEAT),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,c.REPEAT)):(c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,c.CLAMP_TO_EDGE),c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,c.CLAMP_TO_EDGE)),c.bindTexture(c.TEXTURE_2D,null))},b.WebGLRenderer.prototype.handleContextLost=function(a){a.preventDefault(),this.contextLost=!0},b.WebGLRenderer.prototype.handleContextRestored=function(){try{this.gl=this.view.getContext("experimental-webgl",this.options)}catch(a){try{this.gl=this.view.getContext("webgl",this.options)}catch(c){throw new Error(" This browser does not support webGL. Try using the canvas renderer"+this)}}var d=this.gl;d.id=b.WebGLRenderer.glContextId++,this.shaderManager.setContext(d),this.spriteBatch.setContext(d),this.maskManager.setContext(d),this.filterManager.setContext(d),this.renderSession.gl=this.gl,d.disable(d.DEPTH_TEST),d.disable(d.CULL_FACE),d.enable(d.BLEND),d.colorMask(!0,!0,!0,this.transparent),this.gl.viewport(0,0,this.width,this.height);for(var e in b.TextureCache){var f=b.TextureCache[e].baseTexture;f._glTextures=[]}this.contextLost=!1},b.WebGLRenderer.prototype.destroy=function(){this.view.removeEventListener("webglcontextlost",this.contextLost),this.view.removeEventListener("webglcontextrestored",this.contextRestoredLost),b.glContexts[this.glContextId]=null,this.projection=null,this.offset=null,this.shaderManager.destroy(),this.spriteBatch.destroy(),this.maskManager.destroy(),this.filterManager.destroy(),this.shaderManager=null,this.spriteBatch=null,this.maskManager=null,this.filterManager=null,this.gl=null,this.renderSession=null},b.WebGLRenderer.glContextId=0,b.WebGLMaskManager=function(a){this.maskStack=[],this.maskPosition=0,this.setContext(a)},b.WebGLMaskManager.prototype.setContext=function(a){this.gl=a},b.WebGLMaskManager.prototype.pushMask=function(a,c){var d=this.gl;0===this.maskStack.length&&(d.enable(d.STENCIL_TEST),d.stencilFunc(d.ALWAYS,1,1)),this.maskStack.push(a),d.colorMask(!1,!1,!1,!0),d.stencilOp(d.KEEP,d.KEEP,d.INCR),b.WebGLGraphics.renderGraphics(a,c),d.colorMask(!0,!0,!0,!0),d.stencilFunc(d.NOTEQUAL,0,this.maskStack.length),d.stencilOp(d.KEEP,d.KEEP,d.KEEP)},b.WebGLMaskManager.prototype.popMask=function(a){var c=this.gl,d=this.maskStack.pop();d&&(c.colorMask(!1,!1,!1,!1),c.stencilOp(c.KEEP,c.KEEP,c.DECR),b.WebGLGraphics.renderGraphics(d,a),c.colorMask(!0,!0,!0,!0),c.stencilFunc(c.NOTEQUAL,0,this.maskStack.length),c.stencilOp(c.KEEP,c.KEEP,c.KEEP)),0===this.maskStack.length&&c.disable(c.STENCIL_TEST)},b.WebGLMaskManager.prototype.destroy=function(){this.maskStack=null,this.gl=null},b.WebGLShaderManager=function(a){this.maxAttibs=10,this.attribState=[],this.tempAttribState=[];for(var b=0;bd;d+=6,e+=4)this.indices[d+0]=e+0,this.indices[d+1]=e+1,this.indices[d+2]=e+2,this.indices[d+3]=e+0,this.indices[d+4]=e+2,this.indices[d+5]=e+3;this.drawing=!1,this.currentBatchSize=0,this.currentBaseTexture=null,this.setContext(a)},b.WebGLSpriteBatch.prototype.setContext=function(a){this.gl=a,this.vertexBuffer=a.createBuffer(),this.indexBuffer=a.createBuffer(),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,this.indices,a.STATIC_DRAW),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),a.bufferData(a.ARRAY_BUFFER,this.vertices,a.DYNAMIC_DRAW),this.currentBlendMode=99999},b.WebGLSpriteBatch.prototype.begin=function(a){this.renderSession=a,this.shader=this.renderSession.shaderManager.defaultShader,this.start()},b.WebGLSpriteBatch.prototype.end=function(){this.flush()},b.WebGLSpriteBatch.prototype.render=function(a){var b=a.texture;(b.baseTexture!==this.currentBaseTexture||this.currentBatchSize>=this.size)&&(this.flush(),this.currentBaseTexture=b.baseTexture),a.blendMode!==this.currentBlendMode&&this.setBlendMode(a.blendMode);var c=a._uvs||a.texture._uvs;if(c){var d,e,f,g,h=a.worldAlpha,i=a.tint,j=this.vertices,k=a.anchor.x,l=a.anchor.y;if(a.texture.trim){var m=a.texture.trim;e=m.x-k*m.width,d=e+b.frame.width,g=m.y-l*m.height,f=g+b.frame.height}else d=b.frame.width*(1-k),e=b.frame.width*-k,f=b.frame.height*(1-l),g=b.frame.height*-l;var n=4*this.currentBatchSize*this.vertSize,o=a.worldTransform,p=o.a,q=o.c,r=o.b,s=o.d,t=o.tx,u=o.ty;j[n++]=p*e+r*g+t,j[n++]=s*g+q*e+u,j[n++]=c.x0,j[n++]=c.y0,j[n++]=h,j[n++]=i,j[n++]=p*d+r*g+t,j[n++]=s*g+q*d+u,j[n++]=c.x1,j[n++]=c.y1,j[n++]=h,j[n++]=i,j[n++]=p*d+r*f+t,j[n++]=s*f+q*d+u,j[n++]=c.x2,j[n++]=c.y2,j[n++]=h,j[n++]=i,j[n++]=p*e+r*f+t,j[n++]=s*f+q*e+u,j[n++]=c.x3,j[n++]=c.y3,j[n++]=h,j[n++]=i,this.currentBatchSize++}},b.WebGLSpriteBatch.prototype.renderTilingSprite=function(a){var c=a.tilingTexture;(c.baseTexture!==this.currentBaseTexture||this.currentBatchSize>=this.size)&&(this.flush(),this.currentBaseTexture=c.baseTexture),a.blendMode!==this.currentBlendMode&&this.setBlendMode(a.blendMode),a._uvs||(a._uvs=new b.TextureUvs);var d=a._uvs;a.tilePosition.x%=c.baseTexture.width*a.tileScaleOffset.x,a.tilePosition.y%=c.baseTexture.height*a.tileScaleOffset.y;var e=a.tilePosition.x/(c.baseTexture.width*a.tileScaleOffset.x),f=a.tilePosition.y/(c.baseTexture.height*a.tileScaleOffset.y),g=a.width/c.baseTexture.width/(a.tileScale.x*a.tileScaleOffset.x),h=a.height/c.baseTexture.height/(a.tileScale.y*a.tileScaleOffset.y);d.x0=0-e,d.y0=0-f,d.x1=1*g-e,d.y1=0-f,d.x2=1*g-e,d.y2=1*h-f,d.x3=0-e,d.y3=1*h-f;var i=a.worldAlpha,j=a.tint,k=this.vertices,l=a.width,m=a.height,n=a.anchor.x,o=a.anchor.y,p=l*(1-n),q=l*-n,r=m*(1-o),s=m*-o,t=4*this.currentBatchSize*this.vertSize,u=a.worldTransform,v=u.a,w=u.c,x=u.b,y=u.d,z=u.tx,A=u.ty;k[t++]=v*q+x*s+z,k[t++]=y*s+w*q+A,k[t++]=d.x0,k[t++]=d.y0,k[t++]=i,k[t++]=j,k[t++]=v*p+x*s+z,k[t++]=y*s+w*p+A,k[t++]=d.x1,k[t++]=d.y1,k[t++]=i,k[t++]=j,k[t++]=v*p+x*r+z,k[t++]=y*r+w*p+A,k[t++]=d.x2,k[t++]=d.y2,k[t++]=i,k[t++]=j,k[t++]=v*q+x*r+z,k[t++]=y*r+w*q+A,k[t++]=d.x3,k[t++]=d.y3,k[t++]=i,k[t++]=j,this.currentBatchSize++},b.WebGLSpriteBatch.prototype.flush=function(){if(0!==this.currentBatchSize){var a=this.gl;if(a.bindTexture(a.TEXTURE_2D,this.currentBaseTexture._glTextures[a.id]||b.createWebGLTexture(this.currentBaseTexture,a)),this.currentBatchSize>.5*this.size)a.bufferSubData(a.ARRAY_BUFFER,0,this.vertices);else{var c=this.vertices.subarray(0,4*this.currentBatchSize*this.vertSize);a.bufferSubData(a.ARRAY_BUFFER,0,c)}a.drawElements(a.TRIANGLES,6*this.currentBatchSize,a.UNSIGNED_SHORT,0),this.currentBatchSize=0,this.renderSession.drawCount++}},b.WebGLSpriteBatch.prototype.stop=function(){this.flush()},b.WebGLSpriteBatch.prototype.start=function(){var a=this.gl;a.activeTexture(a.TEXTURE0),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer);var c=this.renderSession.projection;a.uniform2f(this.shader.projectionVector,c.x,c.y);var d=4*this.vertSize;a.vertexAttribPointer(this.shader.aVertexPosition,2,a.FLOAT,!1,d,0),a.vertexAttribPointer(this.shader.aTextureCoord,2,a.FLOAT,!1,d,8),a.vertexAttribPointer(this.shader.colorAttribute,2,a.FLOAT,!1,d,16),this.currentBlendMode!==b.blendModes.NORMAL&&this.setBlendMode(b.blendModes.NORMAL)},b.WebGLSpriteBatch.prototype.setBlendMode=function(a){this.flush(),this.currentBlendMode=a;var c=b.blendModesWebGL[this.currentBlendMode];this.gl.blendFunc(c[0],c[1])},b.WebGLSpriteBatch.prototype.destroy=function(){this.vertices=null,this.indices=null,this.gl.deleteBuffer(this.vertexBuffer),this.gl.deleteBuffer(this.indexBuffer),this.currentBaseTexture=null,this.gl=null},b.WebGLFastSpriteBatch=function(a){this.vertSize=10,this.maxSize=6e3,this.size=this.maxSize;var b=4*this.size*this.vertSize,c=6*this.maxSize;this.vertices=new Float32Array(b),this.indices=new Uint16Array(c),this.vertexBuffer=null,this.indexBuffer=null,this.lastIndexCount=0;for(var d=0,e=0;c>d;d+=6,e+=4)this.indices[d+0]=e+0,this.indices[d+1]=e+1,this.indices[d+2]=e+2,this.indices[d+3]=e+0,this.indices[d+4]=e+2,this.indices[d+5]=e+3;this.drawing=!1,this.currentBatchSize=0,this.currentBaseTexture=null,this.currentBlendMode=0,this.renderSession=null,this.shader=null,this.matrix=null,this.setContext(a)},b.WebGLFastSpriteBatch.prototype.setContext=function(a){this.gl=a,this.vertexBuffer=a.createBuffer(),this.indexBuffer=a.createBuffer(),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,this.indices,a.STATIC_DRAW),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),a.bufferData(a.ARRAY_BUFFER,this.vertices,a.DYNAMIC_DRAW),this.currentBlendMode=99999},b.WebGLFastSpriteBatch.prototype.begin=function(a,b){this.renderSession=b,this.shader=this.renderSession.shaderManager.fastShader,this.matrix=a.worldTransform.toArray(!0),this.start()},b.WebGLFastSpriteBatch.prototype.end=function(){this.flush()},b.WebGLFastSpriteBatch.prototype.render=function(a){var b=a.children,c=b[0];if(c.texture._uvs){this.currentBaseTexture=c.texture.baseTexture,c.blendMode!==this.currentBlendMode&&this.setBlendMode(c.blendMode);for(var d=0,e=b.length;e>d;d++)this.renderSprite(b[d]);this.flush()}},b.WebGLFastSpriteBatch.prototype.renderSprite=function(a){if(a.visible&&(a.texture.baseTexture===this.currentBaseTexture||(this.flush(),this.currentBaseTexture=a.texture.baseTexture,a.texture._uvs))){var b,c,d,e,f,g,h,i,j=this.vertices;if(b=a.texture._uvs,c=a.texture.frame.width,d=a.texture.frame.height,a.texture.trim){var k=a.texture.trim;f=k.x-a.anchor.x*k.width,e=f+a.texture.frame.width,h=k.y-a.anchor.y*k.height,g=h+a.texture.frame.height}else e=a.texture.frame.width*(1-a.anchor.x),f=a.texture.frame.width*-a.anchor.x,g=a.texture.frame.height*(1-a.anchor.y),h=a.texture.frame.height*-a.anchor.y;i=4*this.currentBatchSize*this.vertSize,j[i++]=f,j[i++]=h,j[i++]=a.position.x,j[i++]=a.position.y,j[i++]=a.scale.x,j[i++]=a.scale.y,j[i++]=a.rotation,j[i++]=b.x0,j[i++]=b.y1,j[i++]=a.alpha,j[i++]=e,j[i++]=h,j[i++]=a.position.x,j[i++]=a.position.y,j[i++]=a.scale.x,j[i++]=a.scale.y,j[i++]=a.rotation,j[i++]=b.x1,j[i++]=b.y1,j[i++]=a.alpha,j[i++]=e,j[i++]=g,j[i++]=a.position.x,j[i++]=a.position.y,j[i++]=a.scale.x,j[i++]=a.scale.y,j[i++]=a.rotation,j[i++]=b.x2,j[i++]=b.y2,j[i++]=a.alpha,j[i++]=f,j[i++]=g,j[i++]=a.position.x,j[i++]=a.position.y,j[i++]=a.scale.x,j[i++]=a.scale.y,j[i++]=a.rotation,j[i++]=b.x3,j[i++]=b.y3,j[i++]=a.alpha,this.currentBatchSize++,this.currentBatchSize>=this.size&&this.flush()}},b.WebGLFastSpriteBatch.prototype.flush=function(){if(0!==this.currentBatchSize){var a=this.gl;if(this.currentBaseTexture._glTextures[a.id]||b.createWebGLTexture(this.currentBaseTexture,a),a.bindTexture(a.TEXTURE_2D,this.currentBaseTexture._glTextures[a.id]),this.currentBatchSize>.5*this.size)a.bufferSubData(a.ARRAY_BUFFER,0,this.vertices);else{var c=this.vertices.subarray(0,4*this.currentBatchSize*this.vertSize);a.bufferSubData(a.ARRAY_BUFFER,0,c)}a.drawElements(a.TRIANGLES,6*this.currentBatchSize,a.UNSIGNED_SHORT,0),this.currentBatchSize=0,this.renderSession.drawCount++}},b.WebGLFastSpriteBatch.prototype.stop=function(){this.flush()},b.WebGLFastSpriteBatch.prototype.start=function(){var a=this.gl;a.activeTexture(a.TEXTURE0),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer);var c=this.renderSession.projection;a.uniform2f(this.shader.projectionVector,c.x,c.y),a.uniformMatrix3fv(this.shader.uMatrix,!1,this.matrix);var d=4*this.vertSize;a.vertexAttribPointer(this.shader.aVertexPosition,2,a.FLOAT,!1,d,0),a.vertexAttribPointer(this.shader.aPositionCoord,2,a.FLOAT,!1,d,8),a.vertexAttribPointer(this.shader.aScale,2,a.FLOAT,!1,d,16),a.vertexAttribPointer(this.shader.aRotation,1,a.FLOAT,!1,d,24),a.vertexAttribPointer(this.shader.aTextureCoord,2,a.FLOAT,!1,d,28),a.vertexAttribPointer(this.shader.colorAttribute,1,a.FLOAT,!1,d,36),this.currentBlendMode!==b.blendModes.NORMAL&&this.setBlendMode(b.blendModes.NORMAL)},b.WebGLFastSpriteBatch.prototype.setBlendMode=function(a){this.flush(),this.currentBlendMode=a;var c=b.blendModesWebGL[this.currentBlendMode];this.gl.blendFunc(c[0],c[1])},b.WebGLFilterManager=function(a,b){this.transparent=b,this.filterStack=[],this.offsetX=0,this.offsetY=0,this.setContext(a)},b.WebGLFilterManager.prototype.setContext=function(a){this.gl=a,this.texturePool=[],this.initShaderBuffers()},b.WebGLFilterManager.prototype.begin=function(a,b){this.renderSession=a,this.defaultShader=a.shaderManager.defaultShader;var c=this.renderSession.projection;this.width=2*c.x,this.height=2*-c.y,this.buffer=b},b.WebGLFilterManager.prototype.pushFilter=function(a){var c=this.gl,d=this.renderSession.projection,e=this.renderSession.offset;this.filterStack.push(a);var f=a.filterPasses[0];this.offsetX+=a.target.filterArea.x,this.offsetY+=a.target.filterArea.y;var g=this.texturePool.pop();g?g.resize(this.width,this.height):g=new b.FilterTexture(this.gl,this.width,this.height),c.bindTexture(c.TEXTURE_2D,g.texture),a.target.filterArea=a.target.getBounds();var h=a.target.filterArea,i=f.padding;h.x-=i,h.y-=i,h.width+=2*i,h.height+=2*i,h.x<0&&(h.x=0),h.width>this.width&&(h.width=this.width),h.y<0&&(h.y=0),h.height>this.height&&(h.height=this.height),c.bindFramebuffer(c.FRAMEBUFFER,g.frameBuffer),c.viewport(0,0,h.width,h.height),d.x=h.width/2,d.y=-h.height/2,e.x=-h.x,e.y=-h.y,c.uniform2f(this.defaultShader.projectionVector,h.width/2,-h.height/2),c.uniform2f(this.defaultShader.offsetVector,-h.x,-h.y),c.colorMask(!0,!0,!0,!0),c.clearColor(0,0,0,0),c.clear(c.COLOR_BUFFER_BIT),a._glFilterTexture=g},b.WebGLFilterManager.prototype.popFilter=function(){var a=this.gl,c=this.filterStack.pop(),d=c.target.filterArea,e=c._glFilterTexture,f=this.renderSession.projection,g=this.renderSession.offset;if(c.filterPasses.length>1){a.viewport(0,0,d.width,d.height),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),this.vertexArray[0]=0,this.vertexArray[1]=d.height,this.vertexArray[2]=d.width,this.vertexArray[3]=d.height,this.vertexArray[4]=0,this.vertexArray[5]=0,this.vertexArray[6]=d.width,this.vertexArray[7]=0,a.bufferSubData(a.ARRAY_BUFFER,0,this.vertexArray),a.bindBuffer(a.ARRAY_BUFFER,this.uvBuffer),this.uvArray[2]=d.width/this.width,this.uvArray[5]=d.height/this.height,this.uvArray[6]=d.width/this.width,this.uvArray[7]=d.height/this.height,a.bufferSubData(a.ARRAY_BUFFER,0,this.uvArray);var h=e,i=this.texturePool.pop();i||(i=new b.FilterTexture(this.gl,this.width,this.height)),i.resize(this.width,this.height),a.bindFramebuffer(a.FRAMEBUFFER,i.frameBuffer),a.clear(a.COLOR_BUFFER_BIT),a.disable(a.BLEND);for(var j=0;j0&&(b.Texture.frameUpdates.length=0)},b.CanvasRenderer.prototype.resize=function(a,b){this.width=a,this.height=b,this.view.width=a,this.view.height=b},b.CanvasRenderer.prototype.renderDisplayObject=function(a,b){this.renderSession.context=b||this.context,a._renderCanvas(this.renderSession)},b.CanvasRenderer.prototype.renderStripFlat=function(a){var b=this.context,c=a.verticies,d=c.length/2;this.count++,b.beginPath();for(var e=1;d-2>e;e++){var f=2*e,g=c[f],h=c[f+2],i=c[f+4],j=c[f+1],k=c[f+3],l=c[f+5];b.moveTo(g,j),b.lineTo(h,k),b.lineTo(i,l)}b.fillStyle="#FF0000",b.fill(),b.closePath()},b.CanvasRenderer.prototype.renderStrip=function(a){var b=this.context,c=a.verticies,d=a.uvs,e=c.length/2;this.count++;for(var f=1;e-2>f;f++){var g=2*f,h=c[g],i=c[g+2],j=c[g+4],k=c[g+1],l=c[g+3],m=c[g+5],n=d[g]*a.texture.width,o=d[g+2]*a.texture.width,p=d[g+4]*a.texture.width,q=d[g+1]*a.texture.height,r=d[g+3]*a.texture.height,s=d[g+5]*a.texture.height;b.save(),b.beginPath(),b.moveTo(h,k),b.lineTo(i,l),b.lineTo(j,m),b.closePath(),b.clip();var t=n*r+q*p+o*s-r*p-q*o-n*s,u=h*r+q*j+i*s-r*j-q*i-h*s,v=n*i+h*p+o*j-i*p-h*o-n*j,w=n*r*j+q*i*p+h*o*s-h*r*p-q*o*j-n*i*s,x=k*r+q*m+l*s-r*m-q*l-k*s,y=n*l+k*p+o*m-l*p-k*o-n*m,z=n*r*m+q*l*p+k*o*s-k*r*p-q*o*m-n*l*s;b.transform(u/t,x/t,v/t,y/t,w/t,z/t),b.drawImage(a.texture.baseTexture.source,0,0),b.restore()}},b.CanvasBuffer=function(a,b){this.width=a,this.height=b,this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.canvas.width=a,this.canvas.height=b},b.CanvasBuffer.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)},b.CanvasBuffer.prototype.resize=function(a,b){this.width=this.canvas.width=a,this.height=this.canvas.height=b},b.CanvasGraphics=function(){},b.CanvasGraphics.renderGraphics=function(a,c){for(var d=a.worldAlpha,e="",f=0;f1&&(d=1,window.console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object"));for(var e=0;1>e;e++){var f=a.graphicsData[e],g=f.points;if(f.type===b.Graphics.POLY){c.beginPath(),c.moveTo(g[0],g[1]);for(var h=1;hd;d++)this.children[d]._renderWebGL(a);a.spriteBatch.stop()}this._filters&&a.filterManager.popFilter(),this._mask&&a.maskManager.popMask(a),a.drawCount++,a.spriteBatch.start()}},b.Graphics.prototype._renderCanvas=function(a){if(this.visible!==!1&&0!==this.alpha&&this.isMask!==!0){var c=a.context,d=this.worldTransform;this.blendMode!==a.currentBlendMode&&(a.currentBlendMode=this.blendMode,c.globalCompositeOperation=b.blendModesCanvas[a.currentBlendMode]),c.setTransform(d.a,d.c,d.b,d.d,d.tx,d.ty),b.CanvasGraphics.renderGraphics(this,c);for(var e=0,f=this.children.length;f>e;e++)this.children[e]._renderCanvas(a)}},b.Graphics.prototype.getBounds=function(a){this.bounds||this.updateBounds();var b=this.bounds.x,c=this.bounds.width+this.bounds.x,d=this.bounds.y,e=this.bounds.height+this.bounds.y,f=a||this.worldTransform,g=f.a,h=f.c,i=f.b,j=f.d,k=f.tx,l=f.ty,m=g*c+i*e+k,n=j*e+h*c+l,o=g*b+i*e+k,p=j*e+h*b+l,q=g*b+i*d+k,r=j*d+h*b+l,s=g*c+i*d+k,t=j*d+h*c+l,u=-1/0,v=-1/0,w=1/0,x=1/0;w=w>m?m:w,w=w>o?o:w,w=w>q?q:w,w=w>s?s:w,x=x>n?n:x,x=x>p?p:x,x=x>r?r:x,x=x>t?t:x,u=m>u?m:u,u=o>u?o:u,u=q>u?q:u,u=s>u?s:u,v=n>v?n:v,v=p>v?p:v,v=r>v?r:v,v=t>v?t:v;var y=this._bounds;return y.x=w,y.width=u-w,y.y=x,y.height=v-x,y},b.Graphics.prototype.updateBounds=function(){for(var a,c,d,e,f,g=1/0,h=-1/0,i=1/0,j=-1/0,k=0;kc?c:g,h=c+e>h?c+e:h,i=i>d?c:i,j=d+f>j?d+f:j;else if(m===b.Graphics.CIRC||m===b.Graphics.ELIP)c=a[0],d=a[1],e=a[2]+n/2,f=a[3]+n/2,g=g>c-e?c-e:g,h=c+e>h?c+e:h,i=i>d-f?d-f:i,j=d+f>j?d+f:j;else for(var o=0;oc-n?c-n:g,h=c+n>h?c+n:h,i=i>d-n?d-n:i,j=d+n>j?d+n:j}var p=this.boundsPadding;this.bounds=new b.Rectangle(g-p,i-p,h-g+2*p,j-i+2*p)},b.Graphics.prototype._generateCachedSprite=function(){var a=this.getLocalBounds();if(this._cachedSprite)this._cachedSprite.buffer.resize(a.width,a.height);else{var c=new b.CanvasBuffer(a.width,a.height),d=b.Texture.fromCanvas(c.canvas);this._cachedSprite=new b.Sprite(d),this._cachedSprite.buffer=c,this._cachedSprite.worldTransform=this.worldTransform}this._cachedSprite.anchor.x=-(a.x/a.width),this._cachedSprite.anchor.y=-(a.y/a.height),this._cachedSprite.buffer.context.translate(-a.x,-a.y),b.CanvasGraphics.renderGraphics(this,this._cachedSprite.buffer.context)},b.Graphics.prototype.destroyCachedSprite=function(){this._cachedSprite.texture.destroy(!0),this._cachedSprite=null},b.Graphics.POLY=0,b.Graphics.RECT=1,b.Graphics.CIRC=2,b.Graphics.ELIP=3,b.TilingSprite=function(a,c,d){b.Sprite.call(this,a),this.width=c||100,this.height=d||100,this.tileScale=new b.Point(1,1),this.tileScaleOffset=new b.Point(1,1),this.tilePosition=new b.Point(0,0),this.renderable=!0,this.tint=16777215,this.blendMode=b.blendModes.NORMAL},b.TilingSprite.prototype=Object.create(b.Sprite.prototype),b.TilingSprite.prototype.constructor=b.TilingSprite,Object.defineProperty(b.TilingSprite.prototype,"width",{get:function(){return this._width},set:function(a){this._width=a}}),Object.defineProperty(b.TilingSprite.prototype,"height",{get:function(){return this._height},set:function(a){this._height=a}}),b.TilingSprite.prototype.onTextureUpdate=function(){this.updateFrame=!0},b.TilingSprite.prototype.setTexture=function(a){this.texture!==a&&(this.texture=a,this.refreshTexture=!0,this.cachedTint=16777215)},b.TilingSprite.prototype._renderWebGL=function(a){if(this.visible!==!1&&0!==this.alpha){var c,d;for(this.mask&&(a.spriteBatch.stop(),a.maskManager.pushMask(this.mask,a),a.spriteBatch.start()),this.filters&&(a.spriteBatch.flush(),a.filterManager.pushFilter(this._filterBlock)),!this.tilingTexture||this.refreshTexture?(this.generateTilingTexture(!0),this.tilingTexture&&this.tilingTexture.needsUpdate&&(b.updateWebGLTexture(this.tilingTexture.baseTexture,a.gl),this.tilingTexture.needsUpdate=!1)):a.spriteBatch.renderTilingSprite(this),c=0,d=this.children.length;d>c;c++)this.children[c]._renderWebGL(a);a.spriteBatch.stop(),this.filters&&a.filterManager.popFilter(),this.mask&&a.maskManager.popMask(a),a.spriteBatch.start()}},b.TilingSprite.prototype._renderCanvas=function(a){if(this.visible!==!1&&0!==this.alpha){var c=a.context;this._mask&&a.maskManager.pushMask(this._mask,c),c.globalAlpha=this.worldAlpha;var d=this.worldTransform;c.setTransform(d.a,d.c,d.b,d.d,d.tx,d.ty),(!this.__tilePattern||this.refreshTexture)&&(this.generateTilingTexture(!1),this.tilingTexture&&(this.__tilePattern=c.createPattern(this.tilingTexture.baseTexture.source,"repeat"))),this.blendMode!==a.currentBlendMode&&(a.currentBlendMode=this.blendMode,c.globalCompositeOperation=b.blendModesCanvas[a.currentBlendMode]),c.beginPath();var e=this.tilePosition,f=this.tileScale;e.x%=this.tilingTexture.baseTexture.width,e.y%=this.tilingTexture.baseTexture.height,c.scale(f.x,f.y),c.translate(e.x,e.y),c.fillStyle=this.__tilePattern,c.fillRect(-e.x,-e.y,this.width/f.x,this.height/f.y),c.scale(1/f.x,1/f.y),c.translate(-e.x,-e.y),c.closePath(),this._mask&&a.maskManager.popMask(a.context)}},b.TilingSprite.prototype.getBounds=function(){var a=this._width,b=this._height,c=a*(1-this.anchor.x),d=a*-this.anchor.x,e=b*(1-this.anchor.y),f=b*-this.anchor.y,g=this.worldTransform,h=g.a,i=g.c,j=g.b,k=g.d,l=g.tx,m=g.ty,n=h*d+j*f+l,o=k*f+i*d+m,p=h*c+j*f+l,q=k*f+i*c+m,r=h*c+j*e+l,s=k*e+i*c+m,t=h*d+j*e+l,u=k*e+i*d+m,v=-1/0,w=-1/0,x=1/0,y=1/0;x=x>n?n:x,x=x>p?p:x,x=x>r?r:x,x=x>t?t:x,y=y>o?o:y,y=y>q?q:y,y=y>s?s:y,y=y>u?u:y,v=n>v?n:v,v=p>v?p:v,v=r>v?r:v,v=t>v?t:v,w=o>w?o:w,w=q>w?q:w,w=s>w?s:w,w=u>w?u:w;var z=this._bounds;return z.x=x,z.width=v-x,z.y=y,z.height=w-y,this._currentBounds=z,z},b.TilingSprite.prototype.generateTilingTexture=function(a){var c=this.texture;if(c.baseTexture.hasLoaded){var d,e,f=c.baseTexture,g=c.frame,h=g.width!==f.width||g.height!==f.height,i=!1;if(a?(d=b.getNextPowerOfTwo(g.width),e=b.getNextPowerOfTwo(g.height),g.width!==d&&g.height!==e&&(i=!0)):h&&(d=g.width,e=g.height,i=!0),i){var j;this.tilingTexture&&this.tilingTexture.isTiling?(j=this.tilingTexture.canvasBuffer,j.resize(d,e),this.tilingTexture.baseTexture.width=d,this.tilingTexture.baseTexture.height=e,this.tilingTexture.needsUpdate=!0):(j=new b.CanvasBuffer(d,e),this.tilingTexture=b.Texture.fromCanvas(j.canvas),this.tilingTexture.canvasBuffer=j,this.tilingTexture.isTiling=!0),j.context.drawImage(c.baseTexture.source,g.x,g.y,g.width,g.height,0,0,d,e),this.tileScaleOffset.x=g.width/d,this.tileScaleOffset.y=g.height/e}else this.tilingTexture&&this.tilingTexture.isTiling&&this.tilingTexture.destroy(!0),this.tileScaleOffset.x=1,this.tileScaleOffset.y=1,this.tilingTexture=c;this.refreshTexture=!1,this.tilingTexture.baseTexture._powerOf2=!0}},b.BaseTextureCache={},b.texturesToUpdate=[],b.texturesToDestroy=[],b.BaseTextureCacheIdGenerator=0,b.BaseTexture=function(a,c){if(b.EventTarget.call(this),this.width=100,this.height=100,this.scaleMode=c||b.scaleModes.DEFAULT,this.hasLoaded=!1,this.source=a,this.id=b.BaseTextureCacheIdGenerator++,this._glTextures=[],a){if(this.source.complete||this.source.getContext)this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,b.texturesToUpdate.push(this);else{var d=this;this.source.onload=function(){d.hasLoaded=!0,d.width=d.source.width,d.height=d.source.height,b.texturesToUpdate.push(d),d.dispatchEvent({type:"loaded",content:d})}}this.imageUrl=null,this._powerOf2=!1}},b.BaseTexture.prototype.constructor=b.BaseTexture,b.BaseTexture.prototype.destroy=function(){this.imageUrl&&(delete b.BaseTextureCache[this.imageUrl],this.imageUrl=null,this.source.src=null),this.source=null,b.texturesToDestroy.push(this)},b.BaseTexture.prototype.updateSourceImage=function(a){this.hasLoaded=!1,this.source.src=null,this.source.src=a},b.BaseTexture.fromImage=function(a,c,d){var e=b.BaseTextureCache[a];if(c=!c,!e){var f=new Image;c&&(f.crossOrigin=""),f.src=a,e=new b.BaseTexture(f,d),e.imageUrl=a,b.BaseTextureCache[a]=e}return e},b.BaseTexture.fromCanvas=function(a,c){a._pixiId||(a._pixiId="canvas_"+b.TextureCacheIdGenerator++);var d=b.BaseTextureCache[a._pixiId];return d||(d=new b.BaseTexture(a,c),b.BaseTextureCache[a._pixiId]=d),d},b.TextureCache={},b.FrameCache={},b.TextureCacheIdGenerator=0,b.Texture=function(a,c){if(b.EventTarget.call(this),c||(this.noFrame=!0,c=new b.Rectangle(0,0,1,1)),a instanceof b.Texture&&(a=a.baseTexture),this.baseTexture=a,this.frame=c,this.trim=null,this.scope=this,this._uvs=null,a.hasLoaded)this.noFrame&&(c=new b.Rectangle(0,0,a.width,a.height)),this.setFrame(c);else{var d=this;a.addEventListener("loaded",function(){d.onBaseTextureLoaded()})}},b.Texture.prototype.constructor=b.Texture,b.Texture.prototype.onBaseTextureLoaded=function(){var a=this.baseTexture;a.removeEventListener("loaded",this.onLoaded),this.noFrame&&(this.frame=new b.Rectangle(0,0,a.width,a.height)),this.setFrame(this.frame),this.scope.dispatchEvent({type:"update",content:this})},b.Texture.prototype.destroy=function(a){a&&this.baseTexture.destroy()},b.Texture.prototype.setFrame=function(a){if(this.frame=a,this.width=a.width,this.height=a.height,a.x+a.width>this.baseTexture.width||a.y+a.height>this.baseTexture.height)throw new Error("Texture Error: frame does not fit inside the base Texture dimensions "+this);this.updateFrame=!0,b.Texture.frameUpdates.push(this)},b.Texture.prototype._updateWebGLuvs=function(){this._uvs||(this._uvs=new b.TextureUvs);var a=this.frame,c=this.baseTexture.width,d=this.baseTexture.height;this._uvs.x0=a.x/c,this._uvs.y0=a.y/d,this._uvs.x1=(a.x+a.width)/c,this._uvs.y1=a.y/d,this._uvs.x2=(a.x+a.width)/c,this._uvs.y2=(a.y+a.height)/d,this._uvs.x3=a.x/c,this._uvs.y3=(a.y+a.height)/d},b.Texture.fromImage=function(a,c,d){var e=b.TextureCache[a];return e||(e=new b.Texture(b.BaseTexture.fromImage(a,c,d)),b.TextureCache[a]=e),e},b.Texture.fromFrame=function(a){var c=b.TextureCache[a];if(!c)throw new Error('The frameId "'+a+'" does not exist in the texture cache ');return c},b.Texture.fromCanvas=function(a,c){var d=b.BaseTexture.fromCanvas(a,c);return new b.Texture(d)},b.Texture.addTextureToCache=function(a,c){b.TextureCache[c]=a},b.Texture.removeTextureFromCache=function(a){var c=b.TextureCache[a];return delete b.TextureCache[a],delete b.BaseTextureCache[a],c},b.Texture.frameUpdates=[],b.TextureUvs=function(){this.x0=0,this.y0=0,this.x1=0,this.y1=0,this.x2=0,this.y2=0,this.x3=0,this.y4=0},b.RenderTexture=function(a,c,d){if(b.EventTarget.call(this),this.width=a||100,this.height=c||100,this.frame=new b.Rectangle(0,0,this.width,this.height),this.baseTexture=new b.BaseTexture,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.baseTexture._glTextures=[],this.baseTexture.hasLoaded=!0,this.renderer=d||b.defaultRenderer,this.renderer.type===b.WEBGL_RENDERER){var e=this.renderer.gl;this.textureBuffer=new b.FilterTexture(e,this.width,this.height),this.baseTexture._glTextures[e.id]=this.textureBuffer.texture,this.render=this.renderWebGL,this.projection=new b.Point(this.width/2,-this.height/2)}else this.render=this.renderCanvas,this.textureBuffer=new b.CanvasBuffer(this.width,this.height),this.baseTexture.source=this.textureBuffer.canvas;b.Texture.frameUpdates.push(this)},b.RenderTexture.prototype=Object.create(b.Texture.prototype),b.RenderTexture.prototype.constructor=b.RenderTexture,b.RenderTexture.prototype.resize=function(a,c){if(this.width=a,this.height=c,this.frame.width=this.width,this.frame.height=this.height,this.renderer.type===b.WEBGL_RENDERER){this.projection.x=this.width/2,this.projection.y=-this.height/2;var d=this.renderer.gl;d.bindTexture(d.TEXTURE_2D,this.baseTexture._glTextures[d.id]),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,this.width,this.height,0,d.RGBA,d.UNSIGNED_BYTE,null)}else this.textureBuffer.resize(this.width,this.height);b.Texture.frameUpdates.push(this)},b.RenderTexture.prototype.renderWebGL=function(a,c,d){var e=this.renderer.gl;e.colorMask(!0,!0,!0,!0),e.viewport(0,0,this.width,this.height),e.bindFramebuffer(e.FRAMEBUFFER,this.textureBuffer.frameBuffer),d&&this.textureBuffer.clear();var f=a.children,g=a.worldTransform;a.worldTransform=b.RenderTexture.tempMatrix,a.worldTransform.d=-1,a.worldTransform.ty=-2*this.projection.y,c&&(a.worldTransform.tx=c.x,a.worldTransform.ty-=c.y);for(var h=0,i=f.length;i>h;h++)f[h].updateTransform();b.WebGLRenderer.updateTextures(),this.renderer.renderDisplayObject(a,this.projection,this.textureBuffer.frameBuffer),a.worldTransform=g},b.RenderTexture.prototype.renderCanvas=function(a,c,d){var e=a.children,f=a.worldTransform;a.worldTransform=b.RenderTexture.tempMatrix,c&&(a.worldTransform.tx=c.x,a.worldTransform.ty=c.y);for(var g=0,h=e.length;h>g;g++)e[g].updateTransform();d&&this.textureBuffer.clear();var i=this.textureBuffer.context;this.renderer.renderDisplayObject(a,i),i.setTransform(1,0,0,1,0,0),a.worldTransform=f},b.RenderTexture.tempMatrix=new b.Matrix,"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=b),exports.PIXI=b):"undefined"!=typeof define&&define.amd?define(b):a.PIXI=b}).call(this); \ No newline at end of file +},b.WebGLFilterManager.prototype.applyFilterPass=function(a,c,d,e){var f=this.gl,g=a.shaders[f.id];g||(g=new b.PixiShader(f),g.fragmentSrc=a.fragmentSrc,g.uniforms=a.uniforms,g.init(),a.shaders[f.id]=g),f.useProgram(g.program),f.uniform2f(g.projectionVector,d/2,-e/2),f.uniform2f(g.offsetVector,0,0),a.uniforms.dimensions&&(a.uniforms.dimensions.value[0]=this.width,a.uniforms.dimensions.value[1]=this.height,a.uniforms.dimensions.value[2]=this.vertexArray[0],a.uniforms.dimensions.value[3]=this.vertexArray[5]),g.syncUniforms(),f.bindBuffer(f.ARRAY_BUFFER,this.vertexBuffer),f.vertexAttribPointer(g.aVertexPosition,2,f.FLOAT,!1,0,0),f.bindBuffer(f.ARRAY_BUFFER,this.uvBuffer),f.vertexAttribPointer(g.aTextureCoord,2,f.FLOAT,!1,0,0),f.bindBuffer(f.ARRAY_BUFFER,this.colorBuffer),f.vertexAttribPointer(g.colorAttribute,2,f.FLOAT,!1,0,0),f.bindBuffer(f.ELEMENT_ARRAY_BUFFER,this.indexBuffer),f.drawElements(f.TRIANGLES,6,f.UNSIGNED_SHORT,0),this.renderSession.drawCount++},b.WebGLFilterManager.prototype.initShaderBuffers=function(){var a=this.gl;this.vertexBuffer=a.createBuffer(),this.uvBuffer=a.createBuffer(),this.colorBuffer=a.createBuffer(),this.indexBuffer=a.createBuffer(),this.vertexArray=new Float32Array([0,0,1,0,0,1,1,1]),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),a.bufferData(a.ARRAY_BUFFER,this.vertexArray,a.STATIC_DRAW),this.uvArray=new Float32Array([0,0,1,0,0,1,1,1]),a.bindBuffer(a.ARRAY_BUFFER,this.uvBuffer),a.bufferData(a.ARRAY_BUFFER,this.uvArray,a.STATIC_DRAW),this.colorArray=new Float32Array([1,16777215,1,16777215,1,16777215,1,16777215]),a.bindBuffer(a.ARRAY_BUFFER,this.colorBuffer),a.bufferData(a.ARRAY_BUFFER,this.colorArray,a.STATIC_DRAW),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,new Uint16Array([0,1,2,1,3,2]),a.STATIC_DRAW)},b.WebGLFilterManager.prototype.destroy=function(){var a=this.gl;this.filterStack=null,this.offsetX=0,this.offsetY=0;for(var b=0;b0&&(b.Texture.frameUpdates.length=0)},b.CanvasRenderer.prototype.resize=function(a,b){this.width=a,this.height=b,this.view.width=a,this.view.height=b},b.CanvasRenderer.prototype.renderDisplayObject=function(a,b){this.renderSession.context=b||this.context,a._renderCanvas(this.renderSession)},b.CanvasRenderer.prototype.renderStripFlat=function(a){var b=this.context,c=a.verticies,d=c.length/2;this.count++,b.beginPath();for(var e=1;d-2>e;e++){var f=2*e,g=c[f],h=c[f+2],i=c[f+4],j=c[f+1],k=c[f+3],l=c[f+5];b.moveTo(g,j),b.lineTo(h,k),b.lineTo(i,l)}b.fillStyle="#FF0000",b.fill(),b.closePath()},b.CanvasRenderer.prototype.renderStrip=function(a){var b=this.context,c=a.verticies,d=a.uvs,e=c.length/2;this.count++;for(var f=1;e-2>f;f++){var g=2*f,h=c[g],i=c[g+2],j=c[g+4],k=c[g+1],l=c[g+3],m=c[g+5],n=d[g]*a.texture.width,o=d[g+2]*a.texture.width,p=d[g+4]*a.texture.width,q=d[g+1]*a.texture.height,r=d[g+3]*a.texture.height,s=d[g+5]*a.texture.height;b.save(),b.beginPath(),b.moveTo(h,k),b.lineTo(i,l),b.lineTo(j,m),b.closePath(),b.clip();var t=n*r+q*p+o*s-r*p-q*o-n*s,u=h*r+q*j+i*s-r*j-q*i-h*s,v=n*i+h*p+o*j-i*p-h*o-n*j,w=n*r*j+q*i*p+h*o*s-h*r*p-q*o*j-n*i*s,x=k*r+q*m+l*s-r*m-q*l-k*s,y=n*l+k*p+o*m-l*p-k*o-n*m,z=n*r*m+q*l*p+k*o*s-k*r*p-q*o*m-n*l*s;b.transform(u/t,x/t,v/t,y/t,w/t,z/t),b.drawImage(a.texture.baseTexture.source,0,0),b.restore()}},b.CanvasBuffer=function(a,b){this.width=a,this.height=b,this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.canvas.width=a,this.canvas.height=b},b.CanvasBuffer.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)},b.CanvasBuffer.prototype.resize=function(a,b){this.width=this.canvas.width=a,this.height=this.canvas.height=b},b.CanvasGraphics=function(){},b.CanvasGraphics.renderGraphics=function(a,c){for(var d=a.worldAlpha,e="",f=0;f1&&(d=1,window.console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object"));for(var e=0;1>e;e++){var f=a.graphicsData[e],g=f.points;if(f.type===b.Graphics.POLY){c.beginPath(),c.moveTo(g[0],g[1]);for(var h=1;hd;d++)this.children[d]._renderWebGL(a);a.spriteBatch.stop()}this._filters&&a.filterManager.popFilter(),this._mask&&a.maskManager.popMask(a),a.drawCount++,a.spriteBatch.start()}},b.Graphics.prototype._renderCanvas=function(a){if(this.visible!==!1&&0!==this.alpha&&this.isMask!==!0){var c=a.context,d=this.worldTransform;this.blendMode!==a.currentBlendMode&&(a.currentBlendMode=this.blendMode,c.globalCompositeOperation=b.blendModesCanvas[a.currentBlendMode]),c.setTransform(d.a,d.c,d.b,d.d,d.tx,d.ty),b.CanvasGraphics.renderGraphics(this,c);for(var e=0,f=this.children.length;f>e;e++)this.children[e]._renderCanvas(a)}},b.Graphics.prototype.getBounds=function(a){this.bounds||this.updateBounds();var b=this.bounds.x,c=this.bounds.width+this.bounds.x,d=this.bounds.y,e=this.bounds.height+this.bounds.y,f=a||this.worldTransform,g=f.a,h=f.c,i=f.b,j=f.d,k=f.tx,l=f.ty,m=g*c+i*e+k,n=j*e+h*c+l,o=g*b+i*e+k,p=j*e+h*b+l,q=g*b+i*d+k,r=j*d+h*b+l,s=g*c+i*d+k,t=j*d+h*c+l,u=-1/0,v=-1/0,w=1/0,x=1/0;w=w>m?m:w,w=w>o?o:w,w=w>q?q:w,w=w>s?s:w,x=x>n?n:x,x=x>p?p:x,x=x>r?r:x,x=x>t?t:x,u=m>u?m:u,u=o>u?o:u,u=q>u?q:u,u=s>u?s:u,v=n>v?n:v,v=p>v?p:v,v=r>v?r:v,v=t>v?t:v;var y=this._bounds;return y.x=w,y.width=u-w,y.y=x,y.height=v-x,y},b.Graphics.prototype.updateBounds=function(){for(var a,c,d,e,f,g=1/0,h=-1/0,i=1/0,j=-1/0,k=0;kc?c:g,h=c+e>h?c+e:h,i=i>d?c:i,j=d+f>j?d+f:j;else if(m===b.Graphics.CIRC||m===b.Graphics.ELIP)c=a[0],d=a[1],e=a[2]+n/2,f=a[3]+n/2,g=g>c-e?c-e:g,h=c+e>h?c+e:h,i=i>d-f?d-f:i,j=d+f>j?d+f:j;else for(var o=0;oc-n?c-n:g,h=c+n>h?c+n:h,i=i>d-n?d-n:i,j=d+n>j?d+n:j}var p=this.boundsPadding;this.bounds=new b.Rectangle(g-p,i-p,h-g+2*p,j-i+2*p)},b.Graphics.prototype._generateCachedSprite=function(){var a=this.getLocalBounds();if(this._cachedSprite)this._cachedSprite.buffer.resize(a.width,a.height);else{var c=new b.CanvasBuffer(a.width,a.height),d=b.Texture.fromCanvas(c.canvas);this._cachedSprite=new b.Sprite(d),this._cachedSprite.buffer=c,this._cachedSprite.worldTransform=this.worldTransform}this._cachedSprite.anchor.x=-(a.x/a.width),this._cachedSprite.anchor.y=-(a.y/a.height),this._cachedSprite.buffer.context.translate(-a.x,-a.y),b.CanvasGraphics.renderGraphics(this,this._cachedSprite.buffer.context)},b.Graphics.prototype.destroyCachedSprite=function(){this._cachedSprite.texture.destroy(!0),this._cachedSprite=null},b.Graphics.POLY=0,b.Graphics.RECT=1,b.Graphics.CIRC=2,b.Graphics.ELIP=3,b.TilingSprite=function(a,c,d){b.Sprite.call(this,a),this.width=c||100,this.height=d||100,this.tileScale=new b.Point(1,1),this.tileScaleOffset=new b.Point(1,1),this.tilePosition=new b.Point(0,0),this.renderable=!0,this.tint=16777215,this.blendMode=b.blendModes.NORMAL},b.TilingSprite.prototype=Object.create(b.Sprite.prototype),b.TilingSprite.prototype.constructor=b.TilingSprite,Object.defineProperty(b.TilingSprite.prototype,"width",{get:function(){return this._width},set:function(a){this._width=a}}),Object.defineProperty(b.TilingSprite.prototype,"height",{get:function(){return this._height},set:function(a){this._height=a}}),b.TilingSprite.prototype.onTextureUpdate=function(){this.updateFrame=!0},b.TilingSprite.prototype.setTexture=function(a){this.texture!==a&&(this.texture=a,this.refreshTexture=!0,this.cachedTint=16777215)},b.TilingSprite.prototype._renderWebGL=function(a){if(this.visible!==!1&&0!==this.alpha){var c,d;for(this.mask&&(a.spriteBatch.stop(),a.maskManager.pushMask(this.mask,a),a.spriteBatch.start()),this.filters&&(a.spriteBatch.flush(),a.filterManager.pushFilter(this._filterBlock)),!this.tilingTexture||this.refreshTexture?(this.generateTilingTexture(!0),this.tilingTexture&&this.tilingTexture.needsUpdate&&(b.updateWebGLTexture(this.tilingTexture.baseTexture,a.gl),this.tilingTexture.needsUpdate=!1)):a.spriteBatch.renderTilingSprite(this),c=0,d=this.children.length;d>c;c++)this.children[c]._renderWebGL(a);a.spriteBatch.stop(),this.filters&&a.filterManager.popFilter(),this.mask&&a.maskManager.popMask(a),a.spriteBatch.start()}},b.TilingSprite.prototype._renderCanvas=function(a){if(this.visible!==!1&&0!==this.alpha){var c=a.context;this._mask&&a.maskManager.pushMask(this._mask,c),c.globalAlpha=this.worldAlpha;var d=this.worldTransform;c.setTransform(d.a,d.c,d.b,d.d,d.tx,d.ty),(!this.__tilePattern||this.refreshTexture)&&(this.generateTilingTexture(!1),this.tilingTexture&&(this.__tilePattern=c.createPattern(this.tilingTexture.baseTexture.source,"repeat"))),this.blendMode!==a.currentBlendMode&&(a.currentBlendMode=this.blendMode,c.globalCompositeOperation=b.blendModesCanvas[a.currentBlendMode]),c.beginPath();var e=this.tilePosition,f=this.tileScale;e.x%=this.tilingTexture.baseTexture.width,e.y%=this.tilingTexture.baseTexture.height,c.scale(f.x,f.y),c.translate(e.x,e.y),c.fillStyle=this.__tilePattern,c.fillRect(-e.x,-e.y,this.width/f.x,this.height/f.y),c.scale(1/f.x,1/f.y),c.translate(-e.x,-e.y),c.closePath(),this._mask&&a.maskManager.popMask(a.context)}},b.TilingSprite.prototype.getBounds=function(){var a=this._width,b=this._height,c=a*(1-this.anchor.x),d=a*-this.anchor.x,e=b*(1-this.anchor.y),f=b*-this.anchor.y,g=this.worldTransform,h=g.a,i=g.c,j=g.b,k=g.d,l=g.tx,m=g.ty,n=h*d+j*f+l,o=k*f+i*d+m,p=h*c+j*f+l,q=k*f+i*c+m,r=h*c+j*e+l,s=k*e+i*c+m,t=h*d+j*e+l,u=k*e+i*d+m,v=-1/0,w=-1/0,x=1/0,y=1/0;x=x>n?n:x,x=x>p?p:x,x=x>r?r:x,x=x>t?t:x,y=y>o?o:y,y=y>q?q:y,y=y>s?s:y,y=y>u?u:y,v=n>v?n:v,v=p>v?p:v,v=r>v?r:v,v=t>v?t:v,w=o>w?o:w,w=q>w?q:w,w=s>w?s:w,w=u>w?u:w;var z=this._bounds;return z.x=x,z.width=v-x,z.y=y,z.height=w-y,this._currentBounds=z,z},b.TilingSprite.prototype.generateTilingTexture=function(a){var c=this.texture;if(c.baseTexture.hasLoaded){var d,e,f=c.baseTexture,g=c.frame,h=g.width!==f.width||g.height!==f.height,i=!1;if(a?(d=b.getNextPowerOfTwo(g.width),e=b.getNextPowerOfTwo(g.height),g.width!==d&&g.height!==e&&(i=!0)):h&&(d=g.width,e=g.height,i=!0),i){var j;this.tilingTexture&&this.tilingTexture.isTiling?(j=this.tilingTexture.canvasBuffer,j.resize(d,e),this.tilingTexture.baseTexture.width=d,this.tilingTexture.baseTexture.height=e,this.tilingTexture.needsUpdate=!0):(j=new b.CanvasBuffer(d,e),this.tilingTexture=b.Texture.fromCanvas(j.canvas),this.tilingTexture.canvasBuffer=j,this.tilingTexture.isTiling=!0),j.context.drawImage(c.baseTexture.source,g.x,g.y,g.width,g.height,0,0,d,e),this.tileScaleOffset.x=g.width/d,this.tileScaleOffset.y=g.height/e}else this.tilingTexture&&this.tilingTexture.isTiling&&this.tilingTexture.destroy(!0),this.tileScaleOffset.x=1,this.tileScaleOffset.y=1,this.tilingTexture=c;this.refreshTexture=!1,this.tilingTexture.baseTexture._powerOf2=!0}},b.BaseTextureCache={},b.texturesToUpdate=[],b.texturesToDestroy=[],b.BaseTextureCacheIdGenerator=0,b.BaseTexture=function(a,c){if(b.EventTarget.call(this),this.width=100,this.height=100,this.scaleMode=c||b.scaleModes.DEFAULT,this.hasLoaded=!1,this.source=a,this.id=b.BaseTextureCacheIdGenerator++,this._glTextures=[],a){if(this.source.complete||this.source.getContext)this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,b.texturesToUpdate.push(this);else{var d=this;this.source.onload=function(){d.hasLoaded=!0,d.width=d.source.width,d.height=d.source.height,b.texturesToUpdate.push(d),d.dispatchEvent({type:"loaded",content:d})}}this.imageUrl=null,this._powerOf2=!1}},b.BaseTexture.prototype.constructor=b.BaseTexture,b.BaseTexture.prototype.destroy=function(){this.imageUrl&&(delete b.BaseTextureCache[this.imageUrl],this.imageUrl=null,this.source.src=null),this.source=null,b.texturesToDestroy.push(this)},b.BaseTexture.prototype.updateSourceImage=function(a){this.hasLoaded=!1,this.source.src=null,this.source.src=a},b.BaseTexture.fromImage=function(a,c,d){var e=b.BaseTextureCache[a];if(!e){var f=new Image;c&&(f.crossOrigin=""),f.src=a,e=new b.BaseTexture(f,d),e.imageUrl=a,b.BaseTextureCache[a]=e}return e},b.BaseTexture.fromCanvas=function(a,c){a._pixiId||(a._pixiId="canvas_"+b.TextureCacheIdGenerator++);var d=b.BaseTextureCache[a._pixiId];return d||(d=new b.BaseTexture(a,c),b.BaseTextureCache[a._pixiId]=d),d},b.TextureCache={},b.FrameCache={},b.TextureCacheIdGenerator=0,b.Texture=function(a,c){if(b.EventTarget.call(this),c||(this.noFrame=!0,c=new b.Rectangle(0,0,1,1)),a instanceof b.Texture&&(a=a.baseTexture),this.baseTexture=a,this.frame=c,this.trim=null,this.scope=this,this._uvs=null,a.hasLoaded)this.noFrame&&(c=new b.Rectangle(0,0,a.width,a.height)),this.setFrame(c);else{var d=this;a.addEventListener("loaded",function(){d.onBaseTextureLoaded()})}},b.Texture.prototype.constructor=b.Texture,b.Texture.prototype.onBaseTextureLoaded=function(){var a=this.baseTexture;a.removeEventListener("loaded",this.onLoaded),this.noFrame&&(this.frame=new b.Rectangle(0,0,a.width,a.height)),this.setFrame(this.frame),this.scope.dispatchEvent({type:"update",content:this})},b.Texture.prototype.destroy=function(a){a&&this.baseTexture.destroy()},b.Texture.prototype.setFrame=function(a){if(this.frame=a,this.width=a.width,this.height=a.height,a.x+a.width>this.baseTexture.width||a.y+a.height>this.baseTexture.height)throw new Error("Texture Error: frame does not fit inside the base Texture dimensions "+this);this.updateFrame=!0,b.Texture.frameUpdates.push(this)},b.Texture.prototype._updateWebGLuvs=function(){this._uvs||(this._uvs=new b.TextureUvs);var a=this.frame,c=this.baseTexture.width,d=this.baseTexture.height;this._uvs.x0=a.x/c,this._uvs.y0=a.y/d,this._uvs.x1=(a.x+a.width)/c,this._uvs.y1=a.y/d,this._uvs.x2=(a.x+a.width)/c,this._uvs.y2=(a.y+a.height)/d,this._uvs.x3=a.x/c,this._uvs.y3=(a.y+a.height)/d},b.Texture.fromImage=function(a,c,d){var e=b.TextureCache[a];return e||(e=new b.Texture(b.BaseTexture.fromImage(a,c,d)),b.TextureCache[a]=e),e},b.Texture.fromFrame=function(a){var c=b.TextureCache[a];if(!c)throw new Error('The frameId "'+a+'" does not exist in the texture cache ');return c},b.Texture.fromCanvas=function(a,c){var d=b.BaseTexture.fromCanvas(a,c);return new b.Texture(d)},b.Texture.addTextureToCache=function(a,c){b.TextureCache[c]=a},b.Texture.removeTextureFromCache=function(a){var c=b.TextureCache[a];return delete b.TextureCache[a],delete b.BaseTextureCache[a],c},b.Texture.frameUpdates=[],b.TextureUvs=function(){this.x0=0,this.y0=0,this.x1=0,this.y1=0,this.x2=0,this.y2=0,this.x3=0,this.y4=0},b.RenderTexture=function(a,c,d){if(b.EventTarget.call(this),this.width=a||100,this.height=c||100,this.frame=new b.Rectangle(0,0,this.width,this.height),this.baseTexture=new b.BaseTexture,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.baseTexture._glTextures=[],this.baseTexture.hasLoaded=!0,this.renderer=d||b.defaultRenderer,this.renderer.type===b.WEBGL_RENDERER){var e=this.renderer.gl;this.textureBuffer=new b.FilterTexture(e,this.width,this.height),this.baseTexture._glTextures[e.id]=this.textureBuffer.texture,this.render=this.renderWebGL,this.projection=new b.Point(this.width/2,-this.height/2)}else this.render=this.renderCanvas,this.textureBuffer=new b.CanvasBuffer(this.width,this.height),this.baseTexture.source=this.textureBuffer.canvas;b.Texture.frameUpdates.push(this)},b.RenderTexture.prototype=Object.create(b.Texture.prototype),b.RenderTexture.prototype.constructor=b.RenderTexture,b.RenderTexture.prototype.resize=function(a,c){if(this.width=a,this.height=c,this.frame.width=this.width,this.frame.height=this.height,this.renderer.type===b.WEBGL_RENDERER){this.projection.x=this.width/2,this.projection.y=-this.height/2;var d=this.renderer.gl;d.bindTexture(d.TEXTURE_2D,this.baseTexture._glTextures[d.id]),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,this.width,this.height,0,d.RGBA,d.UNSIGNED_BYTE,null)}else this.textureBuffer.resize(this.width,this.height);b.Texture.frameUpdates.push(this)},b.RenderTexture.prototype.renderWebGL=function(a,c,d){var e=this.renderer.gl;e.colorMask(!0,!0,!0,!0),e.viewport(0,0,this.width,this.height),e.bindFramebuffer(e.FRAMEBUFFER,this.textureBuffer.frameBuffer),d&&this.textureBuffer.clear();var f=a.children,g=a.worldTransform;a.worldTransform=b.RenderTexture.tempMatrix,a.worldTransform.d=-1,a.worldTransform.ty=-2*this.projection.y,c&&(a.worldTransform.tx=c.x,a.worldTransform.ty-=c.y);for(var h=0,i=f.length;i>h;h++)f[h].updateTransform();b.WebGLRenderer.updateTextures(),this.renderer.renderDisplayObject(a,this.projection,this.textureBuffer.frameBuffer),a.worldTransform=g},b.RenderTexture.prototype.renderCanvas=function(a,c,d){var e=a.children,f=a.worldTransform;a.worldTransform=b.RenderTexture.tempMatrix,c&&(a.worldTransform.tx=c.x,a.worldTransform.ty=c.y);for(var g=0,h=e.length;h>g;g++)e[g].updateTransform();d&&this.textureBuffer.clear();var i=this.textureBuffer.context;this.renderer.renderDisplayObject(a,i),i.setTransform(1,0,0,1,0,0),a.worldTransform=f},b.RenderTexture.tempMatrix=new b.Matrix,"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=b),exports.PIXI=b):"undefined"!=typeof define&&define.amd?define("PIXI",function(){return a.PIXI=b}()):a.PIXI=b}).call(this); \ No newline at end of file diff --git a/build/phaser.d.ts b/build/phaser.d.ts index 781fc4ac2..273031665 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -1,76 +1,3 @@ -declare class SAT { - - flattenPointsOn(points: Array, normal: SAT.Vector, result: Array): Array; - isSeparatingAxis(aPos: SAT.Vector, bPos: SAT.Vector, aPoints: Array, bPoints: Array, axis: SAT.Vector, response: SAT.Response): boolean; - vornoiRegion(line: SAT.Vector, point: SAT.Vector): number; - testCircleCircle(a: SAT.Circle, b: SAT.Circle, response: SAT.Response): boolean; - testPolygonCircle(a: SAT.Polygon, b: SAT.Circle, response: SAT.Response): boolean; - testCirclePolygon(a: SAT.Circle, b: SAT.Polygon, response: SAT.Response): boolean; - testPolygonPolygon(a: SAT.Polygon, b: SAT.Polygon, response: SAT.Response): boolean; - -} - -declare module SAT { - - class Vector { - constructor(x: number, y: number); - x: number; - y: number; - copy(other: SAT.Vector): SAT.Vector; - perp(): SAT.Vector; - rotate(angle: number): SAT.Vector; - rotatePrecalc(sin: number, cos: number): SAT.Vector; - reverse(): SAT.Vector; - normalize(): SAT.Vector; - add(other: SAT.Vector): SAT.Vector; - sub(other: SAT.Vector): SAT.Vector; - scale(x: number, y: number): SAT.Vector; - project(other: SAT.Vector): SAT.Vector; - projectN(other: SAT.Vector): SAT.Vector; - reflect(axis: SAT.Vector): SAT.Vector; - reflectN(axis: SAT.Vector): SAT.Vector; - dot(other: SAT.Vector): SAT.Vector; - len2(): SAT.Vector; - len(): SAT.Vector; - } - - class Circle { - constructor(pos: SAT.Vector, radius: number); - pos: SAT.Vector; - r: number; - } - - class Polygon { - constructor(pos: SAT.Vector, points: Array); - pos: SAT.Vector; - points: Array; - recalc(): SAT.Polygon; - rotate(angle: number): SAT.Polygon; - scale(x: number, y: number): SAT.Polygon; - translate(x: number, y: number): SAT.Polygon; - } - - class Box { - constructor(pos: SAT.Vector, w: number, h: number); - pos: SAT.Vector; - w: number; - h: number; - toPolygon(): SAT.Polygon; - } - - class Response { - constructor(); - a: any; - b: any; - overlapN: SAT.Vector; - overlapV: SAT.Vector; - clear(): SAT.Response; - aInB: boolean; - bInA: boolean; - overlap: number; - } -} - // Type definitions for PIXI 1.5.1 // Project: https://github.com/GoodBoyDigital/pixi.js/ // Original 1.3 by: xperiments @@ -2890,6 +2817,7 @@ declare module Phaser { insert(body: any): void; populate(group: Phaser.Group): void; populateHandler(sprite: Phaser.Sprite): void; + reset(x: number, y: number, width: number, height: number, maxObject?: number, maxLevels?: number, level?: number): void; retrieve(sprite: Object): any[]; split(): void; //I am not sure these are relevant? Searching in the code yeilds no result diff --git a/build/phaser.js b/build/phaser.js index 31fae858c..b5570fc6f 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -7,10687 +7,26 @@ * * Phaser - http://www.phaser.io * -* v2.0.0 "Aes Sedai" - Built: Fri Mar 07 2014 15:16:50 +* v2.0.0 "Aes Sedai" - Built: Mon Mar 10 2014 02:30:55 * * By Richard Davey http://www.photonstorm.com @photonstorm * * Phaser is a fun, free and fast 2D game framework for making HTML5 games -* for desktop and mobile web browsers, supporting Canvas and WebGL rendering. +* for desktop and mobile web browsers, supporting Canvas and WebGL. * * Phaser uses Pixi.js for rendering, created by Mat Groves http://matgroves.com @Doormat23 -* Phaser uses p2.js for physics, created by Stefan Hedman https://github.com/schteppe/p2.js @schteppe +* Phaser uses p2.js for full-body physics, created by Stefan Hedman https://github.com/schteppe/p2.js @schteppe +* Phaser contains a port of N+ Physics, converted by Richard Davey, original by http://www.metanetsoftware.com * * Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from which both Phaser -* and my love of framework development originate. +* and my love of framework development can be traced. * -* Follow Phaser development progress at http://phaser.io +* Follow development at http://phaser.io and on our forum * * "If you want your children to be intelligent, read them fairy tales." * "If you want them to be more intelligent, read them more fairy tales." * -- Albert Einstein */ -/** - * The MIT License (MIT) - * - * Copyright (c) 2013 p2.js authors - * - * 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. - */ -!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.p2=e():"undefined"!=typeof global?self.p2=e():"undefined"!=typeof self&&(self.p2=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { - //TODO: evaluate use of glm_invsqrt here? - len = 1 / Math.sqrt(len); - out[0] = a[0] * len; - out[1] = a[1] * len; - } - return out; -}; - -/** - * Caclulates the dot product of two vec2's - * - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {Number} dot product of a and b - */ -vec2.dot = function (a, b) { - return a[0] * b[0] + a[1] * b[1]; -}; - -/** - * Computes the cross product of two vec2's - * Note that the cross product must by definition produce a 3D vector - * - * @param {vec3} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec3} out - */ -vec2.cross = function(out, a, b) { - var z = a[0] * b[1] - a[1] * b[0]; - out[0] = out[1] = 0; - out[2] = z; - return out; -}; - -/** - * Performs a linear interpolation between two vec2's - * - * @param {vec3} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec2} out - */ -vec2.lerp = function (out, a, b, t) { - var ax = a[0], - ay = a[1]; - out[0] = ax + t * (b[0] - ax); - out[1] = ay + t * (b[1] - ay); - return out; -}; - -/** - * Transforms the vec2 with a mat2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat2} m matrix to transform with - * @returns {vec2} out - */ -vec2.transformMat2 = function(out, a, m) { - var x = a[0], - y = a[1]; - out[0] = x * m[0] + y * m[1]; - out[1] = x * m[2] + y * m[3]; - return out; -}; - -/** - * Perform some operation over an array of vec2s. - * - * @param {Array} a the array of vectors to iterate over - * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed - * @param {Number} offset Number of elements to skip at the beginning of the array - * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array - * @param {Function} fn Function to call for each vector in the array - * @param {Object} [arg] additional argument to pass to fn - * @returns {Array} a - * @function - */ -vec2.forEach = (function() { - var vec = new Float32Array(2); - - return function(a, stride, offset, count, fn, arg) { - var i, l; - if(!stride) { - stride = 2; - } - - if(!offset) { - offset = 0; - } - - if(count) { - l = Math.min((count * stride) + offset, a.length); - } else { - l = a.length; - } - - for(i = offset; i < l; i += stride) { - vec[0] = a[i]; vec[1] = a[i+1]; - fn(vec, vec, arg); - a[i] = vec[0]; a[i+1] = vec[1]; - } - - return a; - }; -})(); - -/** - * Returns a string representation of a vector - * - * @param {vec2} vec vector to represent as a string - * @returns {String} string representation of the vector - */ -vec2.str = function (a) { - return 'vec2(' + a[0] + ', ' + a[1] + ')'; -}; - -if(typeof(exports) !== 'undefined') { - exports.vec2 = vec2; -} - -},{}],3:[function(require,module,exports){ -var Scalar = require('./Scalar'); - -module.exports = Line; - -/** - * Container for line-related functions - * @class Line - */ -function Line(){}; - -/** - * Compute the intersection between two lines. - * @static - * @method lineInt - * @param {Array} l1 Line vector 1 - * @param {Array} l2 Line vector 2 - * @param {Number} precision Precision to use when checking if the lines are parallel - * @return {Array} The intersection point. - */ -Line.lineInt = function(l1,l2,precision){ - precision = precision || 0; - var i = [0,0]; // point - var a1, b1, c1, a2, b2, c2, det; // scalars - a1 = l1[1][1] - l1[0][1]; - b1 = l1[0][0] - l1[1][0]; - c1 = a1 * l1[0][0] + b1 * l1[0][1]; - a2 = l2[1][1] - l2[0][1]; - b2 = l2[0][0] - l2[1][0]; - c2 = a2 * l2[0][0] + b2 * l2[0][1]; - det = a1 * b2 - a2*b1; - if (!Scalar.eq(det, 0, precision)) { // lines are not parallel - i[0] = (b2 * c1 - b1 * c2) / det; - i[1] = (a1 * c2 - a2 * c1) / det; - } - return i; -}; - -/** - * Checks if two line segments intersects. - * @method segmentsIntersect - * @param {Array} p1 The start vertex of the first line segment. - * @param {Array} p2 The end vertex of the first line segment. - * @param {Array} q1 The start vertex of the second line segment. - * @param {Array} q2 The end vertex of the second line segment. - * @return {Boolean} True if the two line segments intersect - */ -Line.segmentsIntersect = function(p1, p2, q1, q2){ - var dx = p2[0] - p1[0]; - var dy = p2[1] - p1[1]; - var da = q2[0] - q1[0]; - var db = q2[1] - q1[1]; - - // segments are parallel - if(da*dy - db*dx == 0) - return false; - - var s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx) - var t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy) - - return (s>=0 && s<=1 && t>=0 && t<=1); -}; - - -},{"./Scalar":6}],4:[function(require,module,exports){ -module.exports = Point; - -/** - * Point related functions - * @class Point - */ -function Point(){}; - -/** - * Get the area of a triangle spanned by the three given points. Note that the area will be negative if the points are not given in counter-clockwise order. - * @static - * @method area - * @param {Array} a - * @param {Array} b - * @param {Array} c - * @return {Number} - */ -Point.area = function(a,b,c){ - return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1]))); -}; - -Point.left = function(a,b,c){ - return Point.area(a,b,c) > 0; -}; - -Point.leftOn = function(a,b,c) { - return Point.area(a, b, c) >= 0; -}; - -Point.right = function(a,b,c) { - return Point.area(a, b, c) < 0; -}; - -Point.rightOn = function(a,b,c) { - return Point.area(a, b, c) <= 0; -}; - -var tmpPoint1 = [], - tmpPoint2 = []; - -/** - * Check if three points are collinear - * @method collinear - * @param {Array} a - * @param {Array} b - * @param {Array} c - * @param {Number} [thresholdAngle=0] Threshold angle to use when comparing the vectors. The function will return true if the angle between the resulting vectors is less than this value. Use zero for max precision. - * @return {Boolean} - */ -Point.collinear = function(a,b,c,thresholdAngle) { - if(!thresholdAngle) - return Point.area(a, b, c) == 0; - else { - var ab = tmpPoint1, - bc = tmpPoint2; - - ab[0] = b[0]-a[0]; - ab[1] = b[1]-a[1]; - bc[0] = c[0]-b[0]; - bc[1] = c[1]-b[1]; - - var dot = ab[0]*bc[0] + ab[1]*bc[1], - magA = Math.sqrt(ab[0]*ab[0] + ab[1]*ab[1]), - magB = Math.sqrt(bc[0]*bc[0] + bc[1]*bc[1]), - angle = Math.acos(dot/(magA*magB)); - return angle < thresholdAngle; - } -}; - -Point.sqdist = function(a,b){ - var dx = b[0] - a[0]; - var dy = b[1] - a[1]; - return dx * dx + dy * dy; -}; - -},{}],5:[function(require,module,exports){ -var Line = require("./Line") -, Point = require("./Point") -, Scalar = require("./Scalar") - -module.exports = Polygon; - -/** - * Polygon class. - * @class Polygon - * @constructor - */ -function Polygon(){ - - /** - * Vertices that this polygon consists of. An array of array of numbers, example: [[0,0],[1,0],..] - * @property vertices - * @type {Array} - */ - this.vertices = []; -} - -/** - * Get a vertex at position i. It does not matter if i is out of bounds, this function will just cycle. - * @method at - * @param {Number} i - * @return {Array} - */ -Polygon.prototype.at = function(i){ - var v = this.vertices, - s = v.length; - return v[i < 0 ? i % s + s : i % s]; -}; - -/** - * Get first vertex - * @method first - * @return {Array} - */ -Polygon.prototype.first = function(){ - return this.vertices[0]; -}; - -/** - * Get last vertex - * @method last - * @return {Array} - */ -Polygon.prototype.last = function(){ - return this.vertices[this.vertices.length-1]; -}; - -/** - * Clear the polygon data - * @method clear - * @return {Array} - */ -Polygon.prototype.clear = function(){ - this.vertices.length = 0; -}; - -/** - * Append points "from" to "to"-1 from an other polygon "poly" onto this one. - * @method append - * @param {Polygon} poly The polygon to get points from. - * @param {Number} from The vertex index in "poly". - * @param {Number} to The end vertex index in "poly". Note that this vertex is NOT included when appending. - * @return {Array} - */ -Polygon.prototype.append = function(poly,from,to){ - if(typeof(from) == "undefined") throw new Error("From is not given!"); - if(typeof(to) == "undefined") throw new Error("To is not given!"); - - if(to-1 < from) throw new Error("lol1"); - if(to > poly.vertices.length) throw new Error("lol2"); - if(from < 0) throw new Error("lol3"); - - for(var i=from; i v[br][0])) { - br = i; - } - } - - // reverse poly if clockwise - if (!Point.left(this.at(br - 1), this.at(br), this.at(br + 1))) { - this.reverse(); - } -}; - -/** - * Reverse the vertices in the polygon - * @method reverse - */ -Polygon.prototype.reverse = function(){ - var tmp = []; - for(var i=0, N=this.vertices.length; i!==N; i++){ - tmp.push(this.vertices.pop()); - } - this.vertices = tmp; -}; - -/** - * Check if a point in the polygon is a reflex point - * @method isReflex - * @param {Number} i - * @return {Boolean} - */ -Polygon.prototype.isReflex = function(i){ - return Point.right(this.at(i - 1), this.at(i), this.at(i + 1)); -}; - -var tmpLine1=[], - tmpLine2=[]; - -/** - * Check if two vertices in the polygon can see each other - * @method canSee - * @param {Number} a Vertex index 1 - * @param {Number} b Vertex index 2 - * @return {Boolean} - */ -Polygon.prototype.canSee = function(a,b) { - var p, dist, l1=tmpLine1, l2=tmpLine2; - - if (Point.leftOn(this.at(a + 1), this.at(a), this.at(b)) && Point.rightOn(this.at(a - 1), this.at(a), this.at(b))) { - return false; - } - dist = Point.sqdist(this.at(a), this.at(b)); - for (var i = 0; i !== this.vertices.length; ++i) { // for each edge - if ((i + 1) % this.vertices.length === a || i === a) // ignore incident edges - continue; - if (Point.leftOn(this.at(a), this.at(b), this.at(i + 1)) && Point.rightOn(this.at(a), this.at(b), this.at(i))) { // if diag intersects an edge - l1[0] = this.at(a); - l1[1] = this.at(b); - l2[0] = this.at(i); - l2[1] = this.at(i + 1); - p = Line.lineInt(l1,l2); - if (Point.sqdist(this.at(a), p) < dist) { // if edge is blocking visibility to b - return false; - } - } - } - - return true; -}; - -/** - * Copy the polygon from vertex i to vertex j. - * @method copy - * @param {Number} i - * @param {Number} j - * @param {Polygon} [targetPoly] Optional target polygon to save in. - * @return {Polygon} The resulting copy. - */ -Polygon.prototype.copy = function(i,j,targetPoly){ - var p = targetPoly || new Polygon(); - p.clear(); - if (i < j) { - // Insert all vertices from i to j - for(var k=i; k<=j; k++) - p.vertices.push(this.vertices[k]); - - } else { - - // Insert vertices 0 to j - for(var k=0; k<=j; k++) - p.vertices.push(this.vertices[k]); - - // Insert vertices i to end - for(var k=i; k 0) - return this.slice(edges); - else - return [this]; -}; - -/** - * Slices the polygon given one or more cut edges. If given one, this function will return two polygons (false on failure). If many, an array of polygons. - * @method slice - * @param {Array} cutEdges A list of edges, as returned by .getCutEdges() - * @return {Array} - */ -Polygon.prototype.slice = function(cutEdges){ - if(cutEdges.length == 0) return [this]; - if(cutEdges instanceof Array && cutEdges.length && cutEdges[0] instanceof Array && cutEdges[0].length==2 && cutEdges[0][0] instanceof Array){ - - var polys = [this]; - - for(var i=0; i maxlevel){ - console.warn("quickDecomp: max level ("+maxlevel+") reached."); - return result; - } - - for (var i = 0; i < this.vertices.length; ++i) { - if (poly.isReflex(i)) { - reflexVertices.push(poly.vertices[i]); - upperDist = lowerDist = Number.MAX_VALUE; - - - for (var j = 0; j < this.vertices.length; ++j) { - if (Point.left(poly.at(i - 1), poly.at(i), poly.at(j)) - && Point.rightOn(poly.at(i - 1), poly.at(i), poly.at(j - 1))) { // if line intersects with an edge - p = getIntersectionPoint(poly.at(i - 1), poly.at(i), poly.at(j), poly.at(j - 1)); // find the point of intersection - if (Point.right(poly.at(i + 1), poly.at(i), p)) { // make sure it's inside the poly - d = Point.sqdist(poly.vertices[i], p); - if (d < lowerDist) { // keep only the closest intersection - lowerDist = d; - lowerInt = p; - lowerIndex = j; - } - } - } - if (Point.left(poly.at(i + 1), poly.at(i), poly.at(j + 1)) - && Point.rightOn(poly.at(i + 1), poly.at(i), poly.at(j))) { - p = getIntersectionPoint(poly.at(i + 1), poly.at(i), poly.at(j), poly.at(j + 1)); - if (Point.left(poly.at(i - 1), poly.at(i), p)) { - d = Point.sqdist(poly.vertices[i], p); - if (d < upperDist) { - upperDist = d; - upperInt = p; - upperIndex = j; - } - } - } - } - - // if there are no vertices to connect to, choose a point in the middle - if (lowerIndex == (upperIndex + 1) % this.vertices.length) { - //console.log("Case 1: Vertex("+i+"), lowerIndex("+lowerIndex+"), upperIndex("+upperIndex+"), poly.size("+this.vertices.length+")"); - p[0] = (lowerInt[0] + upperInt[0]) / 2; - p[1] = (lowerInt[1] + upperInt[1]) / 2; - steinerPoints.push(p); - - if (i < upperIndex) { - //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.begin() + upperIndex + 1); - lowerPoly.append(poly, i, upperIndex+1); - lowerPoly.vertices.push(p); - upperPoly.vertices.push(p); - if (lowerIndex != 0){ - //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.end()); - upperPoly.append(poly,lowerIndex,poly.vertices.length); - } - //upperPoly.insert(upperPoly.end(), poly.begin(), poly.begin() + i + 1); - upperPoly.append(poly,0,i+1); - } else { - if (i != 0){ - //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.end()); - lowerPoly.append(poly,i,poly.vertices.length); - } - //lowerPoly.insert(lowerPoly.end(), poly.begin(), poly.begin() + upperIndex + 1); - lowerPoly.append(poly,0,upperIndex+1); - lowerPoly.vertices.push(p); - upperPoly.vertices.push(p); - //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.begin() + i + 1); - upperPoly.append(poly,lowerIndex,i+1); - } - } else { - // connect to the closest point within the triangle - //console.log("Case 2: Vertex("+i+"), closestIndex("+closestIndex+"), poly.size("+this.vertices.length+")\n"); - - if (lowerIndex > upperIndex) { - upperIndex += this.vertices.length; - } - closestDist = Number.MAX_VALUE; - - if(upperIndex < lowerIndex){ - return result; - } - - for (var j = lowerIndex; j <= upperIndex; ++j) { - if (Point.leftOn(poly.at(i - 1), poly.at(i), poly.at(j)) - && Point.rightOn(poly.at(i + 1), poly.at(i), poly.at(j))) { - d = Point.sqdist(poly.at(i), poly.at(j)); - if (d < closestDist) { - closestDist = d; - closestIndex = j % this.vertices.length; - } - } - } - - if (i < closestIndex) { - lowerPoly.append(poly,i,closestIndex+1); - if (closestIndex != 0){ - upperPoly.append(poly,closestIndex,v.length); - } - upperPoly.append(poly,0,i+1); - } else { - if (i != 0){ - lowerPoly.append(poly,i,v.length); - } - lowerPoly.append(poly,0,closestIndex+1); - upperPoly.append(poly,closestIndex,i+1); - } - } - - // solve smallest poly first - if (lowerPoly.vertices.length < upperPoly.vertices.length) { - lowerPoly.quickDecomp(result,reflexVertices,steinerPoints,delta,maxlevel,level); - upperPoly.quickDecomp(result,reflexVertices,steinerPoints,delta,maxlevel,level); - } else { - upperPoly.quickDecomp(result,reflexVertices,steinerPoints,delta,maxlevel,level); - lowerPoly.quickDecomp(result,reflexVertices,steinerPoints,delta,maxlevel,level); - } - - return result; - } - } - result.push(this); - - return result; -}; - -/** - * Remove collinear points in the polygon. - * @method removeCollinearPoints - * @param {Number} [precision] The threshold angle to use when determining whether two edges are collinear. Use zero for finest precision. - * @return {Number} The number of points removed - */ -Polygon.prototype.removeCollinearPoints = function(precision){ - var num = 0; - for(var i=this.vertices.length-1; this.vertices.length>3 && i>=0; --i){ - if(Point.collinear(this.at(i-1),this.at(i),this.at(i+1),precision)){ - // Remove the middle point - this.vertices.splice(i%this.vertices.length,1); - i--; // Jump one point forward. Otherwise we may get a chain removal - num++; - } - } - return num; -}; - -},{"./Line":3,"./Point":4,"./Scalar":6}],6:[function(require,module,exports){ -module.exports = Scalar; - -/** - * Scalar functions - * @class Scalar - */ -function Scalar(){} - -/** - * Check if two scalars are equal - * @static - * @method eq - * @param {Number} a - * @param {Number} b - * @param {Number} [precision] - * @return {Boolean} - */ -Scalar.eq = function(a,b,precision){ - precision = precision || 0; - return Math.abs(a-b) < precision; -}; - -},{}],7:[function(require,module,exports){ -module.exports = { - Polygon : require("./Polygon"), - Point : require("./Point"), -}; - -},{"./Point":4,"./Polygon":5}],8:[function(require,module,exports){ -module.exports={ - "name": "p2", - "version": "0.4.0", - "description": "A JavaScript 2D physics engine.", - "author": "Stefan Hedman (http://steffe.se)", - "keywords": [ - "p2.js", - "p2", - "physics", - "engine", - "2d" - ], - "main": "./src/p2.js", - "engines": { - "node": "*" - }, - "repository": { - "type": "git", - "url": "https://github.com/schteppe/p2.js.git" - }, - "bugs": { - "url": "https://github.com/schteppe/p2.js/issues" - }, - "licenses" : [ - { - "type" : "MIT" - } - ], - "devDependencies" : { - "jshint" : "latest", - "nodeunit" : "latest", - "grunt": "~0.4.0", - "grunt-contrib-jshint": "~0.1.1", - "grunt-contrib-nodeunit": "~0.1.2", - "grunt-contrib-concat": "~0.1.3", - "grunt-contrib-uglify": "*", - "grunt-browserify" : "*", - "browserify":"*" - }, - "dependencies" : { - "underscore":"*", - "poly-decomp" : "git://github.com/schteppe/poly-decomp.js", - "gl-matrix":"2.0.0", - "jsonschema":"*" - } -} - -},{}],9:[function(require,module,exports){ -var vec2 = require('../math/vec2') -, Utils = require('../utils/Utils') - -module.exports = AABB; - -/** - * Axis aligned bounding box class. - * @class AABB - * @constructor - * @param {Object} options - * @param {Array} upperBound - * @param {Array} lowerBound - */ -function AABB(options){ - - /** - * The lower bound of the bounding box. - * @property lowerBound - * @type {Array} - */ - this.lowerBound = vec2.create(); - if(options && options.lowerBound) vec2.copy(this.lowerBound, options.lowerBound); - - /** - * The upper bound of the bounding box. - * @property upperBound - * @type {Array} - */ - this.upperBound = vec2.create(); - if(options && options.upperBound) vec2.copy(this.upperBound, options.upperBound); -} - -var tmp = vec2.create(); - -/** - * Set the AABB bounds from a set of points. - * @method setFromPoints - * @param {Array} points An array of vec2's. - */ -AABB.prototype.setFromPoints = function(points,position,angle){ - var l = this.lowerBound, - u = this.upperBound; - vec2.set(l, Number.MAX_VALUE, Number.MAX_VALUE); - vec2.set(u, -Number.MAX_VALUE, -Number.MAX_VALUE); - for(var i=0; i u[j]){ - u[j] = p[j]; - } - if(p[j] < l[j]){ - l[j] = p[j]; - } - } - } - - // Add offset - if(position){ - vec2.add(this.lowerBound, this.lowerBound, position); - vec2.add(this.upperBound, this.upperBound, position); - } -}; - -/** - * Copy bounds from an AABB to this AABB - * @method copy - * @param {AABB} aabb - */ -AABB.prototype.copy = function(aabb){ - vec2.copy(this.lowerBound, aabb.lowerBound); - vec2.copy(this.upperBound, aabb.upperBound); -}; - -/** - * Extend this AABB so that it covers the given AABB too. - * @method extend - * @param {AABB} aabb - */ -AABB.prototype.extend = function(aabb){ - // Loop over x and y - for(var i=0; i<2; i++){ - // Extend lower bound - if(aabb.lowerBound[i] < this.lowerBound[i]) - this.lowerBound[i] = aabb.lowerBound[i]; - - // Upper - if(aabb.upperBound[i] > this.upperBound[i]) - this.upperBound[i] = aabb.upperBound[i]; - } -}; - -/** - * Returns true if the given AABB overlaps this AABB. - * @method overlaps - * @param {AABB} aabb - * @return {Boolean} - */ -AABB.prototype.overlaps = function(aabb){ - var l1 = this.lowerBound, - u1 = this.upperBound, - l2 = aabb.lowerBound, - u2 = aabb.upperBound; - - // l2 u2 - // |---------| - // |--------| - // l1 u1 - - return ((l2[0] <= u1[0] && u1[0] <= u2[0]) || (l1[0] <= u2[0] && u2[0] <= u1[0])) && - ((l2[1] <= u1[1] && u1[1] <= u2[1]) || (l1[1] <= u2[1] && u2[1] <= u1[1])); -}; - -},{"../math/vec2":33,"../utils/Utils":50}],10:[function(require,module,exports){ -var vec2 = require('../math/vec2') -var Body = require('../objects/Body') - -module.exports = Broadphase; - -/** - * Base class for broadphase implementations. - * @class Broadphase - * @constructor - */ -function Broadphase(type){ - - this.type = type; - - /** - * The resulting overlapping pairs. Will be filled with results during .getCollisionPairs(). - * @property result - * @type {Array} - */ - this.result = []; - - /** - * The world to search for collision pairs in. To change it, use .setWorld() - * @property world - * @type {World} - */ - this.world = null; -}; - -/** - * Set the world that we are searching for collision pairs in - * @method setWorld - * @param {World} world - */ -Broadphase.prototype.setWorld = function(world){ - this.world = world; -}; - -/** - * Get all potential intersecting body pairs. - * @method getCollisionPairs - * @param {World} world The world to search in. - * @return {Array} An array of the bodies, ordered in pairs. Example: A result of [a,b,c,d] means that the potential pairs are: (a,b), (c,d). - */ -Broadphase.prototype.getCollisionPairs = function(world){ - throw new Error("getCollisionPairs must be implemented in a subclass!"); -}; - -var dist = vec2.create(); - -/** - * Check whether the bounding radius of two bodies overlap. - * @method boundingRadiusCheck - * @param {Body} bodyA - * @param {Body} bodyB - * @return {Boolean} - */ -Broadphase.boundingRadiusCheck = function(bodyA, bodyB){ - vec2.sub(dist, bodyA.position, bodyB.position); - var d2 = vec2.squaredLength(dist), - r = bodyA.boundingRadius + bodyB.boundingRadius; - return d2 <= r*r; -}; - -/** - * Check whether the bounding radius of two bodies overlap. - * @method boundingRadiusCheck - * @param {Body} bodyA - * @param {Body} bodyB - * @return {Boolean} - */ -Broadphase.aabbCheck = function(bodyA, bodyB){ - if(bodyA.aabbNeedsUpdate) bodyA.updateAABB(); - if(bodyB.aabbNeedsUpdate) bodyB.updateAABB(); - return bodyA.aabb.overlaps(bodyB.aabb); -}; - -/** - * Check whether two bodies are allowed to collide at all. - * @method canCollide - * @param {Body} bodyA - * @param {Body} bodyB - * @return {Boolean} - */ -Broadphase.canCollide = function(bodyA, bodyB){ - - // Cannot collide static bodies - if(bodyA.motionState == Body.STATIC && bodyB.motionState == Body.STATIC) - return false; - - // Cannot collide static vs kinematic bodies - if( (bodyA.motionState == Body.KINEMATIC && bodyB.motionState == Body.STATIC) || - (bodyA.motionState == Body.STATIC && bodyB.motionState == Body.KINEMATIC)) - return false; - - // Cannot collide kinematic vs kinematic - if(bodyA.motionState == Body.KINEMATIC && bodyB.motionState == Body.KINEMATIC) - return false; - - // Cannot collide both sleeping bodies - if(bodyA.sleepState == Body.SLEEPING && bodyB.sleepState == Body.SLEEPING) - return false; - - return true; -}; - -Broadphase.NAIVE = 1; -Broadphase.SAP = 2; - -},{"../math/vec2":33,"../objects/Body":34}],11:[function(require,module,exports){ -var Circle = require('../shapes/Circle') -, Plane = require('../shapes/Plane') -, Particle = require('../shapes/Particle') -, Broadphase = require('../collision/Broadphase') -, vec2 = require('../math/vec2') - -module.exports = GridBroadphase; - -/** - * Broadphase that uses axis-aligned bins. - * @class GridBroadphase - * @constructor - * @extends Broadphase - * @param {number} xmin Lower x bound of the grid - * @param {number} xmax Upper x bound - * @param {number} ymin Lower y bound - * @param {number} ymax Upper y bound - * @param {number} nx Number of bins along x axis - * @param {number} ny Number of bins along y axis - * @todo test - */ -function GridBroadphase(xmin,xmax,ymin,ymax,nx,ny){ - Broadphase.apply(this); - - nx = nx || 10; - ny = ny || 10; - - this.binsizeX = (xmax-xmin) / nx; - this.binsizeY = (ymax-ymin) / ny; - this.nx = nx; - this.ny = ny; - this.xmin = xmin; - this.ymin = ymin; - this.xmax = xmax; - this.ymax = ymax; -}; -GridBroadphase.prototype = new Broadphase(); - -/** - * Get a bin index given a world coordinate - * @method getBinIndex - * @param {Number} x - * @param {Number} y - * @return {Number} Integer index - */ -GridBroadphase.prototype.getBinIndex = function(x,y){ - var nx = this.nx, - ny = this.ny, - xmin = this.xmin, - ymin = this.ymin, - xmax = this.xmax, - ymax = this.ymax; - - var xi = Math.floor(nx * (x - xmin) / (xmax-xmin)); - var yi = Math.floor(ny * (y - ymin) / (ymax-ymin)); - return xi*ny + yi; -} - -/** - * Get collision pairs. - * @method getCollisionPairs - * @param {World} world - * @return {Array} - */ -GridBroadphase.prototype.getCollisionPairs = function(world){ - var result = [], - collidingBodies = world.bodies, - Ncolliding = Ncolliding=collidingBodies.length, - binsizeX = this.binsizeX, - binsizeY = this.binsizeY; - - var bins=[], Nbins=nx*ny; - for(var i=0; i= 0 && xi*(ny-1) + yi < Nbins) - bins[ xi*(ny-1) + yi ].push(bi); - } - } - } else if(si instanceof Plane){ - // Put in all bins for now - if(bi.angle == 0){ - var y = bi.position[1]; - for(var j=0; j!==Nbins && ymin+binsizeY*(j-1) id2){ - var tmp = id1; - id1 = id2; - id2 = tmp; - } - return !!this.collidingBodiesLastStep[id1 + " " + id2]; -}; - -// "for in" loops aren't optimised in chrome... is there a better way to handle last-step collision memory? -// Maybe do this: http://jsperf.com/reflection-vs-array-of-keys -function clearObject(obj){ - for(var i = 0, l = obj.keys.length; i < l; i++) { - delete obj[obj.keys[i]]; - } - obj.keys.length = 0; - /* - for(var key in this.collidingBodiesLastStep) - delete this.collidingBodiesLastStep[key]; - */ -} - -/** - * Throws away the old equations and gets ready to create new - * @method reset - * @param {World} world - */ -Narrowphase.prototype.reset = function(world){ - - // Save the colliding bodies data - clearObject(this.collidingBodiesLastStep); - for(var i=0; i!==this.contactEquations.length; i++){ - var eq = this.contactEquations[i], - id1 = eq.bi.id, - id2 = eq.bj.id; - if(id1 > id2){ - var tmp = id1; - id1 = id2; - id2 = tmp; - } - var key = id1 + " " + id2; - if(!this.collidingBodiesLastStep[key]){ - this.collidingBodiesLastStep[key] = true; - this.collidingBodiesLastStep.keys.push(key); - } - } - - if(this.reuseObjects){ - var ce = this.contactEquations, - fe = this.frictionEquations, - rfe = this.reusableFrictionEquations, - rce = this.reusableContactEquations; - Utils.appendArray(rce,ce); - Utils.appendArray(rfe,fe); - } - - // Reset - this.contactEquations.length = this.frictionEquations.length = 0; -}; - -/** - * Creates a ContactEquation, either by reusing an existing object or creating a new one. - * @method createContactEquation - * @param {Body} bodyA - * @param {Body} bodyB - * @return {ContactEquation} - */ -Narrowphase.prototype.createContactEquation = function(bodyA,bodyB,shapeA,shapeB){ - var c = this.reusableContactEquations.length ? this.reusableContactEquations.pop() : new ContactEquation(bodyA,bodyB); - c.bi = bodyA; - c.bj = bodyB; - c.shapeA = shapeA; - c.shapeB = shapeB; - c.restitution = this.restitution; - c.firstImpact = !this.collidedLastStep(bodyA,bodyB); - c.enabled = true; - - if(bodyA.allowSleep && (bodyA.motionState == Body.DYNAMIC) && !(bodyB.motionState == Body.STATIC || bodyB.sleepState === Body.SLEEPY)) - bodyA.wakeUp(); - if(bodyB.allowSleep && (bodyB.motionState == Body.DYNAMIC) && !(bodyA.motionState == Body.STATIC || bodyA.sleepState === Body.SLEEPY)) - bodyB.wakeUp(); - - return c; -}; - -/** - * Creates a FrictionEquation, either by reusing an existing object or creating a new one. - * @method createFrictionEquation - * @param {Body} bodyA - * @param {Body} bodyB - * @return {FrictionEquation} - */ -Narrowphase.prototype.createFrictionEquation = function(bodyA,bodyB,shapeA,shapeB){ - var c = this.reusableFrictionEquations.length ? this.reusableFrictionEquations.pop() : new FrictionEquation(bodyA,bodyB); - c.bi = bodyA; - c.bj = bodyB; - c.shapeA = shapeA; - c.shapeB = shapeB; - c.setSlipForce(this.slipForce); - c.frictionCoefficient = this.frictionCoefficient; - c.relativeVelocity = this.surfaceVelocity; - c.enabled = true; - return c; -}; - -/** - * Creates a FrictionEquation given the data in the ContactEquation. Uses same offset vectors ri and rj, but the tangent vector will be constructed from the collision normal. - * @method createFrictionFromContact - * @param {ContactEquation} contactEquation - * @return {FrictionEquation} - */ -Narrowphase.prototype.createFrictionFromContact = function(c){ - var eq = this.createFrictionEquation(c.bi,c.bj,c.shapeA,c.shapeB); - vec2.copy(eq.ri, c.ri); - vec2.copy(eq.rj, c.rj); - vec2.rotate(eq.t, c.ni, -Math.PI / 2); - eq.contactEquation = c; - return eq; -} - -/** - * Convex/line narrowphase - * @method convexLine - * @param {Body} bi - * @param {Convex} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Line} sj - * @param {Array} xj - * @param {Number} aj - * @todo Implement me! - */ -Narrowphase.prototype[Shape.LINE | Shape.CONVEX] = -Narrowphase.prototype.convexLine = function(bi,si,xi,ai, bj,sj,xj,aj, justTest){ - // TODO - if(justTest) - return false; - else - return 0; -}; - -/** - * Line/rectangle narrowphase - * @method lineRectangle - * @param {Body} bi - * @param {Line} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Rectangle} sj - * @param {Array} xj - * @param {Number} aj - * @todo Implement me! - */ -Narrowphase.prototype[Shape.LINE | Shape.RECTANGLE] = -Narrowphase.prototype.lineRectangle = function(bi,si,xi,ai, bj,sj,xj,aj, justTest){ - // TODO - if(justTest) - return false; - else - return 0; -}; - -function setConvexToCapsuleShapeMiddle(convexShape, capsuleShape){ - vec2.set(convexShape.vertices[0], -capsuleShape.length * 0.5, -capsuleShape.radius); - vec2.set(convexShape.vertices[1], capsuleShape.length * 0.5, -capsuleShape.radius); - vec2.set(convexShape.vertices[2], capsuleShape.length * 0.5, capsuleShape.radius); - vec2.set(convexShape.vertices[3], -capsuleShape.length * 0.5, capsuleShape.radius); -} - -var convexCapsule_tempRect = new Rectangle(1,1), - convexCapsule_tempVec = vec2.create(); - -/** - * Convex/capsule narrowphase - * @method convexCapsule - * @param {Body} bi - * @param {Convex} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Capsule} sj - * @param {Array} xj - * @param {Number} aj - * @todo Implement me! - */ -Narrowphase.prototype[Shape.CAPSULE | Shape.CONVEX] = -Narrowphase.prototype[Shape.CAPSULE | Shape.RECTANGLE] = -Narrowphase.prototype.convexCapsule = function(bi,si,xi,ai, bj,sj,xj,aj, justTest){ - - // Check the circles - // Add offsets! - var circlePos = convexCapsule_tempVec; - vec2.set(circlePos, sj.length/2,0); - vec2.rotate(circlePos,circlePos,aj); - vec2.add(circlePos,circlePos,xj); - var result1 = this.circleConvex(bj,sj,circlePos,aj, bi,si,xi,ai, justTest, sj.radius); - - vec2.set(circlePos,-sj.length/2, 0); - vec2.rotate(circlePos,circlePos,aj); - vec2.add(circlePos,circlePos,xj); - var result2 = this.circleConvex(bj,sj,circlePos,aj, bi,si,xi,ai, justTest, sj.radius); - - if(justTest && (result1 || result2)) - return true; - - // Check center rect - var r = convexCapsule_tempRect; - setConvexToCapsuleShapeMiddle(r,sj); - var result = this.convexConvex(bi,si,xi,ai, bj,r,xj,aj, justTest); - - return result + result1 + result2; -}; - -/** - * Capsule/line narrowphase - * @method lineCapsule - * @param {Body} bi - * @param {Line} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Capsule} sj - * @param {Array} xj - * @param {Number} aj - * @todo Implement me! - */ -Narrowphase.prototype[Shape.CAPSULE | Shape.LINE] = -Narrowphase.prototype.lineCapsule = function(bi,si,xi,ai, bj,sj,xj,aj, justTest){ - // TODO - if(justTest) - return false; - else - return 0; -}; - -var capsuleCapsule_tempVec1 = vec2.create(); -var capsuleCapsule_tempVec2 = vec2.create(); -var capsuleCapsule_tempRect1 = new Rectangle(1,1); - -/** - * Capsule/capsule narrowphase - * @method capsuleCapsule - * @param {Body} bi - * @param {Capsule} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Capsule} sj - * @param {Array} xj - * @param {Number} aj - * @todo Implement me! - */ -Narrowphase.prototype[Shape.CAPSULE | Shape.CAPSULE] = -Narrowphase.prototype.capsuleCapsule = function(bi,si,xi,ai, bj,sj,xj,aj, justTest){ - - // Check the circles - // Add offsets! - var circlePosi = capsuleCapsule_tempVec1, - circlePosj = capsuleCapsule_tempVec2; - - var numContacts = 0; - - // Need 4 circle checks, between all - for(var i=0; i<2; i++){ - - vec2.set(circlePosi,(i==0?-1:1)*si.length/2,0); - vec2.rotate(circlePosi,circlePosi,ai); - vec2.add(circlePosi,circlePosi,xi); - - for(var j=0; j<2; j++){ - - vec2.set(circlePosj,(j==0?-1:1)*sj.length/2, 0); - vec2.rotate(circlePosj,circlePosj,aj); - vec2.add(circlePosj,circlePosj,xj); - - var result = this.circleCircle(bi,si,circlePosi,ai, bj,sj,circlePosj,aj, justTest, si.radius, sj.radius); - - if(justTest && result) - return true; - - numContacts += result; - } - } - - // Check circles against the center rectangles - var rect = capsuleCapsule_tempRect1; - setConvexToCapsuleShapeMiddle(rect,si); - var result1 = this.convexCapsule(bi,rect,xi,ai, bj,sj,xj,aj, justTest); - - if(justTest && result1) return true; - numContacts += result1; - - setConvexToCapsuleShapeMiddle(rect,sj); - var result2 = this.convexCapsule(bj,rect,xj,aj, bi,si,xi,ai, justTest); - - if(justTest && result2) return true; - numContacts += result2; - - return numContacts; -}; - -/** - * Line/line narrowphase - * @method lineLine - * @param {Body} bi - * @param {Line} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Line} sj - * @param {Array} xj - * @param {Number} aj - * @todo Implement me! - */ -Narrowphase.prototype[Shape.LINE | Shape.LINE] = -Narrowphase.prototype.lineLine = function(bi,si,xi,ai, bj,sj,xj,aj, justTest){ - // TODO - if(justTest) - return false; - else - return 0; -}; - -/** - * Plane/line Narrowphase - * @method planeLine - * @param {Body} planeBody - * @param {Plane} planeShape - * @param {Array} planeOffset - * @param {Number} planeAngle - * @param {Body} lineBody - * @param {Line} lineShape - * @param {Array} lineOffset - * @param {Number} lineAngle - */ -Narrowphase.prototype[Shape.PLANE | Shape.LINE] = -Narrowphase.prototype.planeLine = function(planeBody, planeShape, planeOffset, planeAngle, - lineBody, lineShape, lineOffset, lineAngle, justTest){ - var worldVertex0 = tmp1, - worldVertex1 = tmp2, - worldVertex01 = tmp3, - worldVertex11 = tmp4, - worldEdge = tmp5, - worldEdgeUnit = tmp6, - dist = tmp7, - worldNormal = tmp8, - worldTangent = tmp9, - verts = tmpArray - numContacts = 0; - - // Get start and end points - vec2.set(worldVertex0, -lineShape.length/2, 0); - vec2.set(worldVertex1, lineShape.length/2, 0); - - // Not sure why we have to use worldVertex*1 here, but it won't work otherwise. Tired. - vec2.rotate(worldVertex01, worldVertex0, lineAngle); - vec2.rotate(worldVertex11, worldVertex1, lineAngle); - - add(worldVertex01, worldVertex01, lineOffset); - add(worldVertex11, worldVertex11, lineOffset); - - vec2.copy(worldVertex0,worldVertex01); - vec2.copy(worldVertex1,worldVertex11); - - // Get vector along the line - sub(worldEdge, worldVertex1, worldVertex0); - vec2.normalize(worldEdgeUnit, worldEdge); - - // Get tangent to the edge. - vec2.rotate(worldTangent, worldEdgeUnit, -Math.PI/2); - - vec2.rotate(worldNormal, yAxis, planeAngle); - - // Check line ends - verts[0] = worldVertex0; - verts[1] = worldVertex1; - for(var i=0; i pos0 && pos < pos1){ - // We got contact! - - if(justTest) return true; - - var c = this.createContactEquation(circleBody,lineBody,si,sj); - - vec2.scale(c.ni, orthoDist, -1); - vec2.normalize(c.ni, c.ni); - - vec2.scale( c.ri, c.ni, circleRadius); - add(c.ri, c.ri, circleOffset); - sub(c.ri, c.ri, circleBody.position); - - sub(c.rj, projectedPoint, lineOffset); - add(c.rj, c.rj, lineOffset); - sub(c.rj, c.rj, lineBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - - return 1; - } - } - - // Add corner - // @todo reuse array object - verts[0] = worldVertex0; - verts[1] = worldVertex1; - - for(var i=0; i 0){ - - // Now project the circle onto the edge - vec2.scale(orthoDist, worldTangent, d); - sub(projectedPoint, circleOffset, orthoDist); - - - // Check if the point is within the edge span - var pos = dot(worldEdgeUnit, projectedPoint); - var pos0 = dot(worldEdgeUnit, worldVertex0); - var pos1 = dot(worldEdgeUnit, worldVertex1); - - if(pos > pos0 && pos < pos1){ - // We got contact! - - if(justTest) return true; - - if(closestEdgeDistance === null || d*d 0){ - for(var i=0; i= 0){ - - // Now project the particle onto the edge - vec2.scale(orthoDist, worldTangent, d); - sub(projectedPoint, particleOffset, orthoDist); - - // Check if the point is within the edge span - var pos = dot(worldEdgeUnit, projectedPoint); - var pos0 = dot(worldEdgeUnit, worldVertex0); - var pos1 = dot(worldEdgeUnit, worldVertex1); - - if(pos > pos0 && pos < pos1){ - // We got contact! - if(justTest) return true; - - if(closestEdgeDistance === null || d*d r*r) - return 0; - - if(justTest) return true; - - var c = this.createContactEquation(bodyA,bodyB,si,sj); - sub(c.ni, offsetB, offsetA); - vec2.normalize(c.ni,c.ni); - - vec2.scale( c.ri, c.ni, radiusA); - vec2.scale( c.rj, c.ni, -radiusB); - - add(c.ri, c.ri, offsetA); - sub(c.ri, c.ri, bodyA.position); - - add(c.rj, c.rj, offsetB); - sub(c.rj, c.rj, bodyB.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - return 1; -}; - -/** - * Plane/Convex Narrowphase - * @method planeConvex - * @param {Body} bi - * @param {Plane} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Convex} sj - * @param {Array} xj - * @param {Number} aj - */ -Narrowphase.prototype[Shape.PLANE | Shape.CONVEX] = -Narrowphase.prototype[Shape.PLANE | Shape.RECTANGLE] = -Narrowphase.prototype.planeConvex = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var convexBody = bj, - convexOffset = xj, - convexShape = sj, - convexAngle = aj, - planeBody = bi, - planeShape = si, - planeOffset = xi, - planeAngle = ai; - - var worldVertex = tmp1, - worldNormal = tmp2, - dist = tmp3; - - var numReported = 0; - vec2.rotate(worldNormal, yAxis, planeAngle); - - for(var i=0; i= 2) - break; - } - } - - return numReported; -}; - -/** - * @method convexPlane - * @deprecated Use .planeConvex() instead! - */ -Narrowphase.prototype.convexPlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - console.warn("Narrowphase.prototype.convexPlane is deprecated. Use planeConvex instead!"); - return this.planeConvex( bj,sj,xj,aj, bi,si,xi,ai, justTest ); -} - -/** - * Narrowphase for particle vs plane - * @method particlePlane - * @param {Body} bi The particle body - * @param {Particle} si Particle shape - * @param {Array} xi World position for the particle - * @param {Number} ai World angle for the particle - * @param {Body} bj Plane body - * @param {Plane} sj Plane shape - * @param {Array} xj World position for the plane - * @param {Number} aj World angle for the plane - */ -Narrowphase.prototype[Shape.PARTICLE | Shape.PLANE] = -Narrowphase.prototype.particlePlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var particleBody = bi, - particleShape = si, - particleOffset = xi, - planeBody = bj, - planeShape = sj, - planeOffset = xj, - planeAngle = aj; - - var dist = tmp1, - worldNormal = tmp2; - - planeAngle = planeAngle || 0; - - sub(dist, particleOffset, planeOffset); - vec2.rotate(worldNormal, yAxis, planeAngle); - - var d = dot(dist, worldNormal); - - if(d > 0) return 0; - if(justTest) return true; - - var c = this.createContactEquation(planeBody,particleBody,sj,si); - - vec2.copy(c.ni, worldNormal); - vec2.scale( dist, c.ni, d ); - // dist is now the distance vector in the normal direction - - // ri is the particle position projected down onto the plane, from the plane center - sub( c.ri, particleOffset, dist); - sub( c.ri, c.ri, planeBody.position); - - // rj is from the body center to the particle center - sub( c.rj, particleOffset, particleBody.position ); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - return 1; -}; - -/** - * Circle/Particle Narrowphase - * @method circleParticle - * @param {Body} bi - * @param {Circle} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Particle} sj - * @param {Array} xj - * @param {Number} aj - */ -Narrowphase.prototype[Shape.CIRCLE | Shape.PARTICLE] = -Narrowphase.prototype.circleParticle = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var circleBody = bi, - circleShape = si, - circleOffset = xi, - particleBody = bj, - particleShape = sj, - particleOffset = xj, - dist = tmp1; - - sub(dist, particleOffset, circleOffset); - if(vec2.squaredLength(dist) > circleShape.radius*circleShape.radius) return 0; - if(justTest) return true; - - var c = this.createContactEquation(circleBody,particleBody,si,sj); - vec2.copy(c.ni, dist); - vec2.normalize(c.ni,c.ni); - - // Vector from circle to contact point is the normal times the circle radius - vec2.scale(c.ri, c.ni, circleShape.radius); - add(c.ri, c.ri, circleOffset); - sub(c.ri, c.ri, circleBody.position); - - // Vector from particle center to contact point is zero - sub(c.rj, particleOffset, particleBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - - return 1; -}; - -var capsulePlane_tmpCircle = new Circle(1), - capsulePlane_tmp1 = vec2.create(), - capsulePlane_tmp2 = vec2.create(), - capsulePlane_tmp3 = vec2.create(); - -Narrowphase.prototype[Shape.PLANE | Shape.CAPSULE] = -Narrowphase.prototype.planeCapsule = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var end1 = capsulePlane_tmp1, - end2 = capsulePlane_tmp2, - circle = capsulePlane_tmpCircle, - dst = capsulePlane_tmp3; - - // Compute world end positions - vec2.set(end1, -sj.length/2, 0); - vec2.rotate(end1,end1,aj); - add(end1,end1,xj); - - vec2.set(end2, sj.length/2, 0); - vec2.rotate(end2,end2,aj); - add(end2,end2,xj); - - circle.radius = sj.radius; - - // Do Narrowphase as two circles - var numContacts1 = this.circlePlane(bj,circle,end1,0, bi,si,xi,ai, justTest), - numContacts2 = this.circlePlane(bj,circle,end2,0, bi,si,xi,ai, justTest); - - if(justTest) - return numContacts1 || numContacts2; - else - return numContacts1 + numContacts2; -}; - -/** - * @method capsulePlane - * @deprecated Use .planeCapsule() instead! - */ -Narrowphase.prototype.capsulePlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - console.warn("Narrowphase.prototype.capsulePlane() is deprecated. Use .planeCapsule() instead!"); - return this.planeCapsule( bj,sj,xj,aj, bi,si,xi,ai, justTest ); -} - -/** - * Creates ContactEquations and FrictionEquations for a collision. - * @method circlePlane - * @param {Body} bi The first body that should be connected to the equations. - * @param {Circle} si The circle shape participating in the collision. - * @param {Array} xi Extra offset to take into account for the Shape, in addition to the one in circleBody.position. Will *not* be rotated by circleBody.angle (maybe it should, for sake of homogenity?). Set to null if none. - * @param {Body} bj The second body that should be connected to the equations. - * @param {Plane} sj The Plane shape that is participating - * @param {Array} xj Extra offset for the plane shape. - * @param {Number} aj Extra angle to apply to the plane - */ -Narrowphase.prototype[Shape.CIRCLE | Shape.PLANE] = -Narrowphase.prototype.circlePlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var circleBody = bi, - circleShape = si, - circleOffset = xi, // Offset from body center, rotated! - planeBody = bj, - shapeB = sj, - planeOffset = xj, - planeAngle = aj; - - planeAngle = planeAngle || 0; - - // Vector from plane to circle - var planeToCircle = tmp1, - worldNormal = tmp2, - temp = tmp3; - - sub(planeToCircle, circleOffset, planeOffset); - - // World plane normal - vec2.rotate(worldNormal, yAxis, planeAngle); - - // Normal direction distance - var d = dot(worldNormal, planeToCircle); - - if(d > circleShape.radius) return 0; // No overlap. Abort. - - if(justTest) return true; - - // Create contact - var contact = this.createContactEquation(planeBody,circleBody,sj,si); - - // ni is the plane world normal - vec2.copy(contact.ni, worldNormal); - - // rj is the vector from circle center to the contact point - vec2.scale(contact.rj, contact.ni, -circleShape.radius); - add(contact.rj, contact.rj, circleOffset); - sub(contact.rj, contact.rj, circleBody.position); - - // ri is the distance from plane center to contact. - vec2.scale(temp, contact.ni, d); - sub(contact.ri, planeToCircle, temp ); // Subtract normal distance vector from the distance vector - add(contact.ri, contact.ri, planeOffset); - sub(contact.ri, contact.ri, planeBody.position); - - this.contactEquations.push(contact); - - if(this.enableFriction){ - this.frictionEquations.push( this.createFrictionFromContact(contact) ); - } - - return 1; -}; - -Narrowphase.convexPrecision = 1e-10; - -/** - * Convex/convex Narrowphase.See this article for more info. - * @method convexConvex - * @param {Body} bi - * @param {Convex} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Convex} sj - * @param {Array} xj - * @param {Number} aj - */ -Narrowphase.prototype[Shape.CONVEX] = -Narrowphase.prototype[Shape.CONVEX | Shape.RECTANGLE] = -Narrowphase.prototype[Shape.RECTANGLE] = -Narrowphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj, justTest, precision ){ - var sepAxis = tmp1, - worldPoint = tmp2, - worldPoint0 = tmp3, - worldPoint1 = tmp4, - worldEdge = tmp5, - projected = tmp6, - penetrationVec = tmp7, - dist = tmp8, - worldNormal = tmp9, - numContacts = 0, - precision = precision || Narrowphase.convexPrecision; - - var found = Narrowphase.findSeparatingAxis(si,xi,ai,sj,xj,aj,sepAxis); - if(!found) return 0; - - // Make sure the separating axis is directed from shape i to shape j - sub(dist,xj,xi); - if(dot(sepAxis,dist) > 0){ - vec2.scale(sepAxis,sepAxis,-1); - } - - // Find edges with normals closest to the separating axis - var closestEdge1 = Narrowphase.getClosestEdge(si,ai,sepAxis,true), // Flipped axis - closestEdge2 = Narrowphase.getClosestEdge(sj,aj,sepAxis); - - if(closestEdge1==-1 || closestEdge2==-1) return 0; - - // Loop over the shapes - for(var k=0; k<2; k++){ - - var closestEdgeA = closestEdge1, - closestEdgeB = closestEdge2, - shapeA = si, shapeB = sj, - offsetA = xi, offsetB = xj, - angleA = ai, angleB = aj, - bodyA = bi, bodyB = bj; - - if(k==0){ - // Swap! - var tmp; - tmp = closestEdgeA; closestEdgeA = closestEdgeB; closestEdgeB = tmp; - tmp = shapeA; shapeA = shapeB; shapeB = tmp; - tmp = offsetA; offsetA = offsetB; offsetB = tmp; - tmp = angleA; angleA = angleB; angleB = tmp; - tmp = bodyA; bodyA = bodyB; bodyB = tmp; - } - - // Loop over 2 points in convex B - for(var j=closestEdgeB; j max) max = value; - if(min === null || value < min) min = value; - } - - if(min > max){ - var t = min; - min = max; - max = t; - } - - // Project the position of the body onto the axis - need to add this to the result - var offset = dot(convexOffset, worldAxis); - - vec2.set( result, min + offset, max + offset); -}; - -// .findSeparatingAxis is called by other functions, need local tmp vectors -var fsa_tmp1 = vec2.fromValues(0,0) -, fsa_tmp2 = vec2.fromValues(0,0) -, fsa_tmp3 = vec2.fromValues(0,0) -, fsa_tmp4 = vec2.fromValues(0,0) -, fsa_tmp5 = vec2.fromValues(0,0) -, fsa_tmp6 = vec2.fromValues(0,0) - -/** - * Find a separating axis between the shapes, that maximizes the separating distance between them. - * @method findSeparatingAxis - * @static - * @param {Convex} c1 - * @param {Array} offset1 - * @param {Number} angle1 - * @param {Convex} c2 - * @param {Array} offset2 - * @param {Number} angle2 - * @param {Array} sepAxis The resulting axis - * @return {Boolean} Whether the axis could be found. - */ -Narrowphase.findSeparatingAxis = function(c1,offset1,angle1,c2,offset2,angle2,sepAxis){ - var maxDist = null, - overlap = false, - found = false, - edge = fsa_tmp1, - worldPoint0 = fsa_tmp2, - worldPoint1 = fsa_tmp3, - normal = fsa_tmp4, - span1 = fsa_tmp5, - span2 = fsa_tmp6; - - for(var j=0; j!==2; j++){ - var c = c1, - angle = angle1; - if(j===1){ - c = c2; - angle = angle2; - } - - for(var i=0; i!==c.vertices.length; i++){ - // Get the world edge - vec2.rotate(worldPoint0, c.vertices[i], angle); - vec2.rotate(worldPoint1, c.vertices[(i+1)%c.vertices.length], angle); - - sub(edge, worldPoint1, worldPoint0); - - // Get normal - just rotate 90 degrees since vertices are given in CCW - vec2.rotate(normal, edge, -Math.PI / 2); - vec2.normalize(normal,normal); - - // Project hulls onto that normal - Narrowphase.projectConvexOntoAxis(c1,offset1,angle1,normal,span1); - Narrowphase.projectConvexOntoAxis(c2,offset2,angle2,normal,span2); - - // Order by span position - var a=span1, - b=span2, - swapped = false; - if(span1[0] > span2[0]){ - b=span1; - a=span2; - swapped = true; - } - - // Get separating distance - var dist = b[0] - a[1]; - overlap = dist < 0; - - if(maxDist===null || dist > maxDist){ - vec2.copy(sepAxis, normal); - maxDist = dist; - found = overlap; - } - } - } - - return found; -}; - -// .getClosestEdge is called by other functions, need local tmp vectors -var gce_tmp1 = vec2.fromValues(0,0) -, gce_tmp2 = vec2.fromValues(0,0) -, gce_tmp3 = vec2.fromValues(0,0) - -/** - * Get the edge that has a normal closest to an axis. - * @method getClosestEdge - * @static - * @param {Convex} c - * @param {Number} angle - * @param {Array} axis - * @param {Boolean} flip - * @return {Number} Index of the edge that is closest. This index and the next spans the resulting edge. Returns -1 if failed. - */ -Narrowphase.getClosestEdge = function(c,angle,axis,flip){ - var localAxis = gce_tmp1, - edge = gce_tmp2, - normal = gce_tmp3; - - // Convert the axis to local coords of the body - vec2.rotate(localAxis, axis, -angle); - if(flip){ - vec2.scale(localAxis,localAxis,-1); - } - - var closestEdge = -1, - N = c.vertices.length, - halfPi = Math.PI / 2; - for(var i=0; i!==N; i++){ - // Get the edge - sub(edge, c.vertices[(i+1)%N], c.vertices[i%N]); - - // Get normal - just rotate 90 degrees since vertices are given in CCW - vec2.rotate(normal, edge, -halfPi); - vec2.normalize(normal,normal); - - var d = dot(normal,localAxis); - if(closestEdge == -1 || d > maxDot){ - closestEdge = i % N; - maxDot = d; - } - } - - return closestEdge; -}; - -var circleHeightfield_candidate = vec2.create(), - circleHeightfield_dist = vec2.create(), - circleHeightfield_v0 = vec2.create(), - circleHeightfield_v1 = vec2.create(), - circleHeightfield_minCandidate = vec2.create(), - circleHeightfield_worldNormal = vec2.create(), - circleHeightfield_minCandidateNormal = vec2.create(); - -/** - * @method circleHeightfield - * @param {Body} bi - * @param {Circle} si - * @param {Array} xi - * @param {Body} bj - * @param {Heightfield} sj - * @param {Array} xj - * @param {Number} aj - */ -Narrowphase.prototype[Shape.CIRCLE | Shape.HEIGHTFIELD] = -Narrowphase.prototype.circleHeightfield = function( circleBody,circleShape,circlePos,circleAngle, - hfBody,hfShape,hfPos,hfAngle, justTest, radius ){ - var data = hfShape.data, - radius = radius || circleShape.radius, - w = hfShape.elementWidth, - dist = circleHeightfield_dist, - candidate = circleHeightfield_candidate, - minCandidate = circleHeightfield_minCandidate, - minCandidateNormal = circleHeightfield_minCandidateNormal, - worldNormal = circleHeightfield_worldNormal, - v0 = circleHeightfield_v0, - v1 = circleHeightfield_v1; - - // Get the index of the points to test against - var idxA = Math.floor( (circlePos[0] - radius - hfPos[0]) / w ), - idxB = Math.ceil( (circlePos[0] + radius - hfPos[0]) / w ); - - /*if(idxB < 0 || idxA >= data.length) - return justTest ? false : 0;*/ - - if(idxA < 0) idxA = 0; - if(idxB >= data.length) idxB = data.length-1; - - // Get max and min - var max = data[idxA], - min = data[idxB]; - for(var i=idxA; i max) max = data[i]; - } - - if(circlePos[1]-radius > max) - return justTest ? false : 0; - - if(circlePos[1]+radius < min){ - // Below the minimum point... We can just guess. - // TODO - } - - // 1. Check so center of circle is not inside the field. If it is, this wont work... - // 2. For each edge - // 2. 1. Get point on circle that is closest to the edge (scale normal with -radius) - // 2. 2. Check if point is inside. - - var found = false, - minDist = false; - - // Check all edges first - for(var i=idxA; i= v0[0] && candidate[0] < v1[0] && d <= 0){ - - if(minDist === false || Math.abs(d) < minDist){ - - // Store the candidate point, projected to the edge - vec2.scale(dist,worldNormal,-d); - vec2.add(minCandidate,candidate,dist); - vec2.copy(minCandidateNormal,worldNormal); - - found = true; - minDist = Math.abs(d); - - if(justTest) - return true; - } - } - } - - if(found){ - - var c = this.createContactEquation(hfBody,circleBody,hfShape,circleShape); - - // Normal is out of the heightfield - vec2.copy(c.ni, minCandidateNormal); - - // Vector from circle to heightfield - vec2.scale(c.rj, c.ni, -radius); - add(c.rj, c.rj, circlePos); - sub(c.rj, c.rj, circleBody.position); - - vec2.copy(c.ri, minCandidate); - //vec2.sub(c.ri, c.ri, hfPos); - vec2.sub(c.ri, c.ri, hfBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction) - this.frictionEquations.push( this.createFrictionFromContact(c) ); - - return 1; - } - - - // Check all vertices - if(radius > 0){ - for(var i=idxA; i<=idxB; i++){ - - // Get point - vec2.set(v0, i*w, data[i]); - vec2.add(v0,v0,hfPos); - - vec2.sub(dist, circlePos, v0); - - if(vec2.squaredLength(dist) < radius*radius){ - - if(justTest) return true; - - var c = this.createContactEquation(hfBody,circleBody,hfShape,circleShape); - - // Construct normal - out of heightfield - vec2.copy(c.ni, dist); - vec2.normalize(c.ni,c.ni); - - vec2.scale(c.rj, c.ni, -radius); - add(c.rj, c.rj, circlePos); - sub(c.rj, c.rj, circleBody.position); - - sub(c.ri, v0, hfPos); - add(c.ri, c.ri, hfPos); - sub(c.ri, c.ri, hfBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - - return 1; - } - } - } - - return 0; - -}; - -},{"../equations/ContactEquation":23,"../equations/FrictionEquation":25,"../math/vec2":33,"../objects/Body":34,"../shapes/Circle":38,"../shapes/Rectangle":44,"../shapes/Shape":45,"../utils/Utils":50}],14:[function(require,module,exports){ -var Plane = require("../shapes/Plane"); -var Broadphase = require("../collision/Broadphase"); - -module.exports = { - QuadTree : QuadTree, - Node : Node, - BoundsNode : BoundsNode, -}; - -/** - * QuadTree data structure. See https://github.com/mikechambers/ExamplesByMesh/tree/master/JavaScript/QuadTree - * @class QuadTree - * @constructor - * @param {Object} An object representing the bounds of the top level of the QuadTree. The object - * should contain the following properties : x, y, width, height - * @param {Boolean} pointQuad Whether the QuadTree will contain points (true), or items with bounds - * (width / height)(false). Default value is false. - * @param {Number} maxDepth The maximum number of levels that the quadtree will create. Default is 4. - * @param {Number} maxChildren The maximum number of children that a node can contain before it is split into sub-nodes. - */ -function QuadTree(bounds, pointQuad, maxDepth, maxChildren){ - var node; - if(pointQuad){ - node = new Node(bounds, 0, maxDepth, maxChildren); - } else { - node = new BoundsNode(bounds, 0, maxDepth, maxChildren); - } - - /** - * The root node of the QuadTree which covers the entire area being segmented. - * @property root - * @type Node - */ - this.root = node; -} - -/** - * Inserts an item into the QuadTree. - * @method insert - * @param {Object|Array} item The item or Array of items to be inserted into the QuadTree. The item should expose x, y - * properties that represents its position in 2D space. - */ -QuadTree.prototype.insert = function(item){ - if(item instanceof Array){ - var len = item.length; - for(var i = 0; i < len; i++){ - this.root.insert(item[i]); - } - } else { - this.root.insert(item); - } -} - -/** - * Clears all nodes and children from the QuadTree - * @method clear - */ -QuadTree.prototype.clear = function(){ - this.root.clear(); -} - -/** - * Retrieves all items / points in the same node as the specified item / point. If the specified item - * overlaps the bounds of a node, then all children in both nodes will be returned. - * @method retrieve - * @param {Object} item An object representing a 2D coordinate point (with x, y properties), or a shape - * with dimensions (x, y, width, height) properties. - */ -QuadTree.prototype.retrieve = function(item){ - //get a copy of the array of items - var out = this.root.retrieve(item).slice(0); - return out; -} - -QuadTree.prototype.getCollisionPairs = function(world){ - - var result = []; - - // Add all bodies - this.insert(world.bodies); - - /* - console.log("bodies",world.bodies.length); - console.log("maxDepth",this.root.maxDepth,"maxChildren",this.root.maxChildren); - */ - - for(var i=0; i!==world.bodies.length; i++){ - var b = world.bodies[i], - items = this.retrieve(b); - - //console.log("items",items.length); - - // Check results - for(var j=0, len=items.length; j!==len; j++){ - var item = items[j]; - - if(b === item) continue; // Do not add self - - // Check if they were already added - var found = false; - for(var k=0, numAdded=result.length; k= this.maxDepth) && len > this.maxChildren) { - this.subdivide(); - - for(var i = 0; i < len; i++){ - this.insert(this.children[i]); - } - - this.children.length = 0; - } -} - -Node.prototype.retrieve = function(item){ - if(this.nodes.length){ - var index = this.findIndex(item); - return this.nodes[index].retrieve(item); - } - - return this.children; -} - -Node.prototype.findIndex = function(item){ - var b = this.bounds; - var left = (item.position[0]-item.boundingRadius > b.x + b.width / 2) ? false : true; - var top = (item.position[1]-item.boundingRadius > b.y + b.height / 2) ? false : true; - - if(item instanceof Plane){ - left = top = false; // Will overlap the left/top boundary since it is infinite - } - - //top left - var index = Node.TOP_LEFT; - if(left){ - if(!top){ - index = Node.BOTTOM_LEFT; - } - } else { - if(top){ - index = Node.TOP_RIGHT; - } else { - index = Node.BOTTOM_RIGHT; - } - } - - return index; -} - - -Node.prototype.subdivide = function(){ - var depth = this.depth + 1; - - var bx = this.bounds.x; - var by = this.bounds.y; - - //floor the values - var b_w_h = (this.bounds.width / 2); - var b_h_h = (this.bounds.height / 2); - var bx_b_w_h = bx + b_w_h; - var by_b_h_h = by + b_h_h; - - //top left - this.nodes[Node.TOP_LEFT] = new this.classConstructor({ - x:bx, - y:by, - width:b_w_h, - height:b_h_h - }, - depth); - - //top right - this.nodes[Node.TOP_RIGHT] = new this.classConstructor({ - x:bx_b_w_h, - y:by, - width:b_w_h, - height:b_h_h - }, - depth); - - //bottom left - this.nodes[Node.BOTTOM_LEFT] = new this.classConstructor({ - x:bx, - y:by_b_h_h, - width:b_w_h, - height:b_h_h - }, - depth); - - - //bottom right - this.nodes[Node.BOTTOM_RIGHT] = new this.classConstructor({ - x:bx_b_w_h, - y:by_b_h_h, - width:b_w_h, - height:b_h_h - }, - depth); -} - -Node.prototype.clear = function(){ - this.children.length = 0; - - var len = this.nodes.length; - for(var i = 0; i < len; i++){ - this.nodes[i].clear(); - } - - this.nodes.length = 0; -} - - -// BoundsQuadTree - -function BoundsNode(bounds, depth, maxChildren, maxDepth){ - Node.call(this, bounds, depth, maxChildren, maxDepth); - this.stuckChildren = []; -} - -BoundsNode.prototype = new Node(); -BoundsNode.prototype.classConstructor = BoundsNode; -BoundsNode.prototype.stuckChildren = null; - -//we use this to collect and conctenate items being retrieved. This way -//we dont have to continuously create new Array instances. -//Note, when returned from QuadTree.retrieve, we then copy the array -BoundsNode.prototype.out = []; - -BoundsNode.prototype.insert = function(item){ - if(this.nodes.length){ - var index = this.findIndex(item); - var node = this.nodes[index]; - - /* - console.log("radius:",item.boundingRadius); - console.log("item x:",item.position[0] - item.boundingRadius,"x range:",node.bounds.x,node.bounds.x+node.bounds.width); - console.log("item y:",item.position[1] - item.boundingRadius,"y range:",node.bounds.y,node.bounds.y+node.bounds.height); - */ - - //todo: make _bounds bounds - if( !(item instanceof Plane) && // Plane is infinite.. Make it a "stuck" child - item.position[0] - item.boundingRadius >= node.bounds.x && - item.position[0] + item.boundingRadius <= node.bounds.x + node.bounds.width && - item.position[1] - item.boundingRadius >= node.bounds.y && - item.position[1] + item.boundingRadius <= node.bounds.y + node.bounds.height){ - this.nodes[index].insert(item); - } else { - this.stuckChildren.push(item); - } - - return; - } - - this.children.push(item); - - var len = this.children.length; - - if(this.depth < this.maxDepth && len > this.maxChildren){ - this.subdivide(); - - for(var i=0; i