-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -23834,7 +26151,7 @@ Phaser.Math = {
},
/**
- * Find the angle of a segment from (x1, y1) -> (x2, y2 ).
+ * Find the angle of a segment from (x1, y1) -> (x2, y2).
* @method Phaser.Math#angleBetween
* @param {number} x1
* @param {number} y1
@@ -23847,24 +26164,58 @@ Phaser.Math = {
},
/**
- * Set an angle within the bounds of -π toπ.
- * @method Phaser.Math#normalizeAngle
- * @param {number} angle
- * @param {boolean} radians - True if angle size is expressed in radians.
- * @return {number}
+ * Reverses an angle.
+ * @method Phaser.Math#reverseAngle
+ * @param {number} angleRad - The angle to reverse, in radians.
+ * @return {number} Returns the reverse angle, in radians.
*/
- normalizeAngle: function (angle, radians) {
+ reverseAngle: function (angleRad) {
+ return this.normalizeAngle(angleRad + Math.PI, true);
+ },
- if (typeof radians === "undefined") { radians = true; }
+ /**
+ * Normalizes an angle to the [0,2pi) range.
+ * @method Phaser.Math#normalizeAngle
+ * @param {number} angleRad - The angle to normalize, in radians.
+ * @return {number} Returns the angle, fit within the [0,2pi] range, in radians.
+ */
+ normalizeAngle: function (angleRad) {
- var rd = (radians) ? Math.PI : 180;
- return this.wrap(angle, -rd, rd);
+ angleRad = angleRad % (2 * Math.PI);
+ return angleRad >= 0 ? angleRad : angleRad + 2 * Math.PI;
},
/**
- * Closest angle between two angles from a1 to a2
- * absolute value the return for exact angle
+ * Normalizes a latitude to the [-90,90] range. Latitudes above 90 or below -90 are capped, not wrapped.
+ * @method Phaser.Math#normalizeLatitude
+ * @param {number} lat - The latitude to normalize, in degrees.
+ * @return {number} Returns the latitude, fit within the [-90,90] range.
+ */
+ normalizeLatitude: function (lat) {
+ return Math.max(-90, Math.min(90, lat));
+ },
+
+ /**
+ * Normalizes a longitude to the [-180,180] range. Longitudes above 180 or below -180 are wrapped.
+ * @method Phaser.Math#normalizeLongitude
+ * @param {number} lng - The longitude to normalize, in degrees.
+ * @return {number} Returns the longitude, fit within the [-180,180] range.
+ */
+ normalizeLongitude: function (lng) {
+
+ if (lng % 360 == 180)
+ {
+ return 180;
+ }
+
+ lng = lng % 360;
+ return lng < -180 ? lng + 360 : lng > 180 ? lng - 360 : lng;
+
+ },
+
+ /**
+ * Closest angle between two angles from a1 to a2 absolute value the return for exact angle
* @method Phaser.Math#nearestAngleBetween
* @param {number} a1
* @param {number} a2
@@ -24018,13 +26369,13 @@ Phaser.Math = {
/**
* Ensures that the value always stays between min and max, by wrapping the value around.
- * max should be larger than min, or the function will return 0
+ * max should be larger than min, or the function will return 0.
*
* @method Phaser.Math#wrap
- * @param value The value to wrap
- * @param min The minimum the value is allowed to be
- * @param max The maximum the value is allowed to be
- * @return {number} The wrapped value
+ * @param {number} value - The value to wrap.
+ * @param {number} min - The minimum the value is allowed to be.
+ * @param {number} max - The maximum the value is allowed to be.
+ * @return {number} The wrapped value.
*/
wrap: function (value, min, max) {
@@ -24133,7 +26484,7 @@ Phaser.Math = {
},
/**
- * Significantly faster version of Math.min
+ * Updated version of Math.min that can be passed either an array of numbers or the numbers as parameters.
* See http://jsperf.com/math-s-min-max-vs-homemade/5
*
* @method Phaser.Math#min
@@ -24141,15 +26492,113 @@ Phaser.Math = {
*/
min: function () {
- for (var i =1 , min = 0, len = arguments.length; i < len; i++)
+ if (arguments.length === 1 && typeof arguments[0] === 'object')
{
- if (arguments[i] < arguments[min])
+ var data = arguments[0];
+ }
+ else
+ {
+ var data = arguments;
+ }
+
+ for (var i = 1, min = 0, len = data.length; i < len; i++)
+ {
+ if (data[i] < data[min])
{
min = i;
}
}
- return arguments[min];
+ return data[min];
+
+ },
+
+ /**
+ * Updated version of Math.max that can be passed either an array of numbers or the numbers as parameters.
+ *
+ * @method Phaser.Math#max
+ * @return {number} The largest value from those given.
+ */
+ max: function () {
+
+ if (arguments.length === 1 && typeof arguments[0] === 'object')
+ {
+ var data = arguments[0];
+ }
+ else
+ {
+ var data = arguments;
+ }
+
+ for (var i = 1, max = 0, len = data.length; i < len; i++)
+ {
+ if (data[i] > data[max])
+ {
+ max = i;
+ }
+ }
+
+ return data[max];
+
+ },
+
+ /**
+ * Updated version of Math.min that can be passed a property and either an array of objects or the objects as parameters.
+ * It will find the lowest matching property value from the given objects.
+ *
+ * @method Phaser.Math#minProperty
+ * @return {number} The lowest value from those given.
+ */
+ minProperty: function (property) {
+
+ if (arguments.length === 2 && typeof arguments[1] === 'object')
+ {
+ var data = arguments[1];
+ }
+ else
+ {
+ var data = arguments.slice(1);
+ }
+
+ for (var i = 1, min = 0, len = data.length; i < len; i++)
+ {
+ if (data[i][property] < data[min][property])
+ {
+ min = i;
+ }
+ }
+
+ return data[min][property];
+
+ },
+
+ /**
+ * Updated version of Math.max that can be passed a property and either an array of objects or the objects as parameters.
+ * It will find the largest matching property value from the given objects.
+ *
+ * @method Phaser.Math#maxProperty
+ * @return {number} The largest value from those given.
+ */
+ maxProperty: function (property) {
+
+ if (arguments.length === 2 && typeof arguments[1] === 'object')
+ {
+ var data = arguments[1];
+ }
+ else
+ {
+ var data = arguments.slice(1);
+ }
+
+ for (var i = 1, max = 0, len = data.length; i < len; i++)
+ {
+ if (data[i][property] > data[max][property])
+ {
+ max = i;
+ }
+ }
+
+ return data[max][property];
},
@@ -24195,7 +26644,7 @@ Phaser.Math = {
},
/**
- * Description.
+ * A Linear Interpolation Method, mostly used by Phaser.Tween.
* @method Phaser.Math#linearInterpolation
* @param {number} v
* @param {number} k
@@ -24222,7 +26671,7 @@ Phaser.Math = {
},
/**
- * Description.
+ * A Bezier Interpolation Method, mostly used by Phaser.Tween.
* @method Phaser.Math#bezierInterpolation
* @param {number} v
* @param {number} k
@@ -24243,7 +26692,7 @@ Phaser.Math = {
},
/**
- * Description.
+ * A Catmull Rom Interpolation Method, mostly used by Phaser.Tween.
* @method Phaser.Math#catmullRomInterpolation
* @param {number} v
* @param {number} k
@@ -24478,7 +26927,7 @@ Phaser.Math = {
* @param {number} y1
* @param {number} x2
* @param {number} y2
- * @return {number} The distance between this Point object and the destination Point object.
+ * @return {number} The distance between the two sets of coordinates.
*/
distance: function (x1, y1, x2, y2) {
@@ -24489,6 +26938,25 @@ Phaser.Math = {
},
+ /**
+ * Returns the distance between the two given set of coordinates at the power given.
+ *
+ * @method Phaser.Math#distancePow
+ * @param {number} x1
+ * @param {number} y1
+ * @param {number} x2
+ * @param {number} y2
+ * @param {number} [pow=2]
+ * @return {number} The distance between the two sets of coordinates.
+ */
+ distancePow: function (x1, y1, x2, y2, pow) {
+
+ if (typeof pow === 'undefined') { pow = 2; }
+
+ return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow));
+
+ },
+
/**
* Returns the rounded distance between the two given set of coordinates.
*
@@ -24676,23 +27144,23 @@ Phaser.Math = {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @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
@@ -24718,27 +27186,23 @@ Phaser.Math = {
*/
/**
- * 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) {
+* 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.physicsManager = physicsManager;
- this.ID = physicsManager.quadTreeID;
- physicsManager.quadTreeID++;
-
this.maxObjects = maxObjects || 10;
this.maxLevels = maxLevels || 4;
this.level = level || 0;
@@ -24762,35 +27226,60 @@ Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, max
Phaser.QuadTree.prototype = {
/*
- * Split the node into 4 subnodes
+ * Populates this quadtree with the members of the given Group.
*
- * @method Phaser.QuadTree#split
+ * @method Phaser.QuadTree#populate
+ * @param {Phaser.Group} group - The Group to add to the quadtree.
*/
- split: function() {
+ populate: function (group) {
- 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);
+ group.forEach(this.populateHandler, this, true);
},
/*
- * Insert the object into the node. If the node
- * exceeds the capacity, it will split and add all
- * objects to their corresponding subnodes.
+ * Handler for the populate method.
+ *
+ * @method Phaser.QuadTree#populateHandler
+ * @param {Phaser.Sprite} sprite - The Sprite to check.
+ */
+ populateHandler: function (sprite) {
+
+ if (sprite.body && sprite.body.checkCollision.none === false && sprite.alive)
+ {
+ 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.
*/
insert: function (body) {
@@ -24842,7 +27331,7 @@ 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) {
@@ -24882,12 +27371,12 @@ Phaser.QuadTree.prototype = {
},
- /*
- * 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) {
@@ -24896,7 +27385,7 @@ Phaser.QuadTree.prototype = {
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.quadTreeIDs.push(this.ID);
if (this.nodes[0])
{
@@ -24929,7 +27418,6 @@ Phaser.QuadTree.prototype = {
for (var i = 0, len = this.nodes.length; i < len; i++)
{
- // if (typeof this.nodes[i] !== 'undefined')
if (this.nodes[i])
{
this.nodes[i].clear();
@@ -24940,9 +27428,11 @@ Phaser.QuadTree.prototype = {
};
+Phaser.QuadTree.prototype.constructor = Phaser.QuadTree;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -24951,9 +27441,9 @@ Phaser.QuadTree.prototype = {
* @class Circle
* @classdesc Phaser - Circle
* @constructor
-* @param {number} [x] The x coordinate of the center of the circle.
-* @param {number} [y] The y coordinate of the center of the circle.
-* @param {number} [diameter] The diameter of the circle.
+* @param {number} [x=0] - The x coordinate of the center of the circle.
+* @param {number} [y=0] - The y coordinate of the center of the circle.
+* @param {number} [diameter=0] - The diameter of the circle.
* @return {Phaser.Circle} This circle object
*/
Phaser.Circle = function (x, y, diameter) {
@@ -25137,6 +27627,8 @@ Phaser.Circle.prototype = {
};
+Phaser.Circle.prototype.constructor = Phaser.Circle;
+
/**
* The largest distance between any two points on the circle. The same as the radius * 2.
* @name Phaser.Circle#diameter
@@ -25418,7 +27910,7 @@ Phaser.Circle.intersectsRectangle = function (c, r) {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -25706,6 +28198,8 @@ Phaser.Point.prototype = {
};
+Phaser.Point.prototype.constructor = Phaser.Point;
+
/**
* Adds the coordinates of two points together to create a new point.
* @method Phaser.Point.add
@@ -25849,7 +28343,7 @@ Phaser.Point.rotate = function (a, x, y, angle, asDegrees, distance) {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -26115,6 +28609,8 @@ Phaser.Rectangle.prototype = {
};
+Phaser.Rectangle.prototype.constructor = Phaser.Rectangle;
+
/**
* @name Phaser.Rectangle#halfWidth
* @property {number} halfWidth - Half of the width of the Rectangle.
@@ -26493,12 +28989,12 @@ Phaser.Rectangle.intersection = function (a, b, out) {
*/
Phaser.Rectangle.intersects = function (a, b) {
- return (a.x < b.right && b.x < a.right && a.y < b.bottom && b.y < a.bottom);
+ if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0)
+ {
+ return false;
+ }
- // return (a.x <= b.right && b.x <= a.right && a.y <= b.bottom && b.y <= a.bottom);
-
- // return (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom);
- // return !(a.x > b.right + tolerance || a.right < b.x - tolerance || a.y > b.bottom + tolerance || a.bottom < b.y - tolerance);
+ return !(a.right < b.x || a.bottom < b.y || a.x > b.right || a.y > b.bottom);
};
@@ -26538,7 +29034,7 @@ Phaser.Rectangle.union = function (a, b, out) {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -26568,7 +29064,7 @@ Phaser.Polygon.prototype = Object.create(PIXI.Polygon.prototype);
Phaser.Polygon.prototype.constructor = Phaser.Polygon;
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -26696,8 +29192,8 @@ Phaser.Net.prototype = {
var output = {};
var keyValues = location.search.substring(1).split('&');
- for (var i in keyValues) {
-
+ for (var i in keyValues)
+ {
var key = keyValues[i].split('=');
if (key.length > 1)
@@ -26731,9 +29227,11 @@ Phaser.Net.prototype = {
};
+Phaser.Net.prototype.constructor = Phaser.Net;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -26761,13 +29259,13 @@ Phaser.TweenManager = function (game) {
this.game = game;
/**
- * @property {array} _tweens - Description.
+ * @property {array} _tweens - All of the currently running tweens.
* @private
*/
this._tweens = [];
/**
- * @property {array} _add - Description.
+ * @property {array} _add - All of the tweens queued to be added in the next update.
* @private
*/
this._add = [];
@@ -26779,13 +29277,6 @@ Phaser.TweenManager = function (game) {
Phaser.TweenManager.prototype = {
- /**
- * Version number of this library.
- * @property {string} REVISION
- * @default
- */
- REVISION: '11dev',
-
/**
* Get all the tween objects in an array.
* @method Phaser.TweenManager#getAll
@@ -26798,12 +29289,17 @@ Phaser.TweenManager.prototype = {
},
/**
- * Remove all tween objects.
+ * Remove all tweens running and in the queue. Doesn't call any of the tween onComplete events.
* @method Phaser.TweenManager#removeAll
*/
removeAll: function () {
- this._tweens = [];
+ for (var i = 0; i < this._tweens.length; i++)
+ {
+ this._tweens[i].pendingDelete = true;
+ }
+
+ this._add = [];
},
@@ -26814,9 +29310,9 @@ Phaser.TweenManager.prototype = {
* @param {Phaser.Tween} tween - The tween object you want to add.
* @returns {Phaser.Tween} The tween object you added to the manager.
*/
- add: function ( tween ) {
+ add: function (tween) {
- this._add.push( tween );
+ this._add.push(tween);
},
@@ -26839,14 +29335,13 @@ Phaser.TweenManager.prototype = {
* @method Phaser.TweenManager#remove
* @param {Phaser.Tween} tween - The tween object you want to remove.
*/
- remove: function ( tween ) {
+ remove: function (tween) {
- var i = this._tweens.indexOf( tween );
-
- if ( i !== -1 ) {
+ var i = this._tweens.indexOf(tween);
+ if (i !== -1)
+ {
this._tweens[i].pendingDelete = true;
-
}
},
@@ -26859,7 +29354,7 @@ Phaser.TweenManager.prototype = {
*/
update: function () {
- if ( this._tweens.length === 0 && this._add.length === 0 )
+ if (this._tweens.length === 0 && this._add.length === 0)
{
return false;
}
@@ -26867,20 +29362,18 @@ Phaser.TweenManager.prototype = {
var i = 0;
var numTweens = this._tweens.length;
- while ( i < numTweens ) {
-
- if ( this._tweens[ i ].update( this.game.time.now ) ) {
-
+ while (i < numTweens)
+ {
+ if (this._tweens[i].update(this.game.time.now))
+ {
i++;
-
- } else {
-
- this._tweens.splice( i, 1 );
+ }
+ else
+ {
+ this._tweens.splice(i, 1);
numTweens--;
-
}
-
}
// If there are any new tweens to be added, do so now - otherwise they can be spliced out of the array before ever running
@@ -26916,7 +29409,8 @@ Phaser.TweenManager.prototype = {
*/
pauseAll: function () {
- for (var i = this._tweens.length - 1; i >= 0; i--) {
+ for (var i = this._tweens.length - 1; i >= 0; i--)
+ {
this._tweens[i].pause();
}
@@ -26929,16 +29423,20 @@ Phaser.TweenManager.prototype = {
*/
resumeAll: function () {
- for (var i = this._tweens.length - 1; i >= 0; i--) {
+ for (var i = this._tweens.length - 1; i >= 0; i--)
+ {
this._tweens[i].resume();
}
}
};
+
+Phaser.TweenManager.prototype.constructor = Phaser.TweenManager;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -26966,119 +29464,112 @@ Phaser.Tween = function (object, game) {
this.game = game;
/**
- * @property {object} _manager - Description.
+ * @property {Phaser.TweenManager} _manager - Reference to the TweenManager.
* @private
*/
this._manager = this.game.tweens;
/**
- * @property {object} _valuesStart - Description.
+ * @property {object} _valuesStart - Private value object.
* @private
*/
this._valuesStart = {};
/**
- * @property {object} _valuesEnd - Description.
+ * @property {object} _valuesEnd - Private value object.
* @private
*/
this._valuesEnd = {};
/**
- * @property {object} _valuesStartRepeat - Description.
+ * @property {object} _valuesStartRepeat - Private value object.
* @private
*/
this._valuesStartRepeat = {};
/**
- * @property {number} _duration - Description.
+ * @property {number} _duration - Private duration counter.
* @private
* @default
*/
this._duration = 1000;
/**
- * @property {number} _repeat - Description.
+ * @property {number} _repeat - Private repeat counter.
* @private
* @default
*/
this._repeat = 0;
/**
- * @property {boolean} _yoyo - Description.
+ * @property {boolean} _yoyo - Private yoyo flag.
* @private
* @default
*/
this._yoyo = false;
/**
- * @property {boolean} _reversed - Description.
+ * @property {boolean} _reversed - Private reversed flag.
* @private
* @default
*/
this._reversed = false;
/**
- * @property {number} _delayTime - Description.
+ * @property {number} _delayTime - Private delay counter.
* @private
* @default
*/
this._delayTime = 0;
/**
- * @property {Description} _startTime - Description.
+ * @property {number} _startTime - Private start time counter.
* @private
* @default null
*/
this._startTime = null;
/**
- * @property {Description} _easingFunction - Description.
+ * @property {function} _easingFunction - The easing function used for the tween.
* @private
*/
this._easingFunction = Phaser.Easing.Linear.None;
/**
- * @property {Description} _interpolationFunction - Description.
+ * @property {function} _interpolationFunction - The interpolation function used for the tween.
* @private
*/
this._interpolationFunction = Phaser.Math.linearInterpolation;
/**
- * @property {Description} _chainedTweens - Description.
+ * @property {array} _chainedTweens - A private array of chained tweens.
* @private
*/
this._chainedTweens = [];
/**
- * @property {Description} _onStartCallback - Description.
- * @private
- * @default
- */
- this._onStartCallback = null;
-
- /**
- * @property {boolean} _onStartCallbackFired - Description.
+ * @property {boolean} _onStartCallbackFired - Private flag.
* @private
* @default
*/
this._onStartCallbackFired = false;
/**
- * @property {Description} _onUpdateCallback - Description.
+ * @property {function} _onUpdateCallback - An onUpdate callback.
* @private
* @default null
*/
this._onUpdateCallback = null;
-
+
/**
- * @property {Description} _onCompleteCallback - Description.
+ * @property {object} _onUpdateCallbackContext - The context in which to call the onUpdate callback.
* @private
* @default null
*/
- this._onCompleteCallback = null;
-
+ this._onUpdateCallbackContext = null;
+
/**
- * @property {number} _pausedTime - Description.
+ * @property {number} _pausedTime - Private pause timer.
* @private
* @default
*/
@@ -27091,22 +29582,28 @@ Phaser.Tween = function (object, game) {
this.pendingDelete = false;
// Set all starting values present on the target object
- for ( var field in object ) {
- this._valuesStart[ field ] = parseFloat(object[field], 10);
+ for (var field in object)
+ {
+ this._valuesStart[field] = parseFloat(object[field], 10);
}
/**
- * @property {Phaser.Signal} onStart - Description.
+ * @property {Phaser.Signal} onStart - The onStart event is fired when the Tween begins.
*/
this.onStart = new Phaser.Signal();
/**
- * @property {Phaser.Signal} onComplete - Description.
+ * @property {Phaser.Signal} onLoop - The onLoop event is fired if the Tween loops.
+ */
+ this.onLoop = new Phaser.Signal();
+
+ /**
+ * @property {Phaser.Signal} onComplete - The onComplete event is fired when the Tween completes. Does not fire if the Tween is set to loop.
*/
this.onComplete = new Phaser.Signal();
/**
- * @property {boolean} isRunning - Description.
+ * @property {boolean} isRunning - If the tween is running this is set to true, otherwise false. Tweens that are in a delayed state, waiting to start, are considered as being running.
* @default
*/
this.isRunning = false;
@@ -27120,15 +29617,15 @@ Phaser.Tween.prototype = {
*
* @method Phaser.Tween#to
* @param {object} properties - Properties you want to tween.
- * @param {number} duration - Duration of this tween.
- * @param {function} ease - Easing function.
- * @param {boolean} autoStart - Whether this tween will start automatically or not.
- * @param {number} delay - Delay before this tween will start, defaults to 0 (no delay).
- * @param {boolean} repeat - Should the tween automatically restart once complete? (ignores any chained tweens).
- * @param {Phaser.Tween} yoyo - Description.
- * @return {Phaser.Tween} Itself.
+ * @param {number} [duration=1000] - Duration of this tween in ms.
+ * @param {function} [ease=null] - Easing function. If not set it will default to Phaser.Easing.Linear.None.
+ * @param {boolean} [autoStart=false] - Whether this tween will start automatically or not.
+ * @param {number} [delay=0] - Delay before this tween will start, defaults to 0 (no delay). Value given is in ms.
+ * @param {boolean} [repeat=0] - Should the tween automatically restart once complete? (ignores any chained tweens).
+ * @param {boolean} [yoyo=false] - A tween that yoyos will reverse itself when it completes.
+ * @return {Phaser.Tween} This Tween object.
*/
- to: function ( properties, duration, ease, autoStart, delay, repeat, yoyo ) {
+ to: function (properties, duration, ease, autoStart, delay, repeat, yoyo) {
duration = duration || 1000;
ease = ease || null;
@@ -27138,6 +29635,7 @@ Phaser.Tween.prototype = {
yoyo = yoyo || false;
var self;
+
if (this._parent)
{
self = this._manager.create(this._object);
@@ -27167,9 +29665,12 @@ Phaser.Tween.prototype = {
self._yoyo = yoyo;
- if (autoStart) {
+ if (autoStart)
+ {
return this.start();
- } else {
+ }
+ else
+ {
return this;
}
@@ -27183,43 +29684,41 @@ Phaser.Tween.prototype = {
*/
start: function () {
- if (this.game === null || this._object === null) {
+ if (this.game === null || this._object === null)
+ {
return;
}
this._manager.add(this);
- this.onStart.dispatch(this._object);
-
this.isRunning = true;
this._onStartCallbackFired = false;
this._startTime = this.game.time.now + this._delayTime;
- for ( var property in this._valuesEnd ) {
-
+ for (var property in this._valuesEnd)
+ {
// check if an Array was provided as property value
- if ( this._valuesEnd[ property ] instanceof Array ) {
-
- if ( this._valuesEnd[ property ].length === 0 ) {
-
+ if (this._valuesEnd[property] instanceof Array)
+ {
+ if (this._valuesEnd[property].length === 0)
+ {
continue;
-
}
// create a local copy of the Array with the start value at the front
- this._valuesEnd[ property ] = [ this._object[ property ] ].concat( this._valuesEnd[ property ] );
-
+ this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]);
}
- this._valuesStart[ property ] = this._object[ property ];
+ this._valuesStart[property] = this._object[property];
- if ( ( this._valuesStart[ property ] instanceof Array ) === false ) {
- this._valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings
+ if ((this._valuesStart[property] instanceof Array) === false)
+ {
+ this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
}
- this._valuesStartRepeat[ property ] = this._valuesStart[ property ] || 0;
+ this._valuesStartRepeat[property] = this._valuesStart[property] || 0;
}
@@ -27237,6 +29736,8 @@ Phaser.Tween.prototype = {
this.isRunning = false;
+ this._onUpdateCallback = null;
+
this._manager.remove(this);
return this;
@@ -27250,7 +29751,7 @@ Phaser.Tween.prototype = {
* @param {number} amount - The amount of the delay in ms.
* @return {Phaser.Tween} Itself.
*/
- delay: function ( amount ) {
+ delay: function (amount) {
this._delayTime = amount;
return this;
@@ -27264,7 +29765,7 @@ Phaser.Tween.prototype = {
* @param {number} times - How many times to repeat.
* @return {Phaser.Tween} Itself.
*/
- repeat: function ( times ) {
+ repeat: function (times) {
this._repeat = times;
return this;
@@ -27279,7 +29780,7 @@ Phaser.Tween.prototype = {
* @param {boolean} yoyo - Set to true to yoyo this tween.
* @return {Phaser.Tween} Itself.
*/
- yoyo: function( yoyo ) {
+ yoyo: function(yoyo) {
this._yoyo = yoyo;
return this;
@@ -27293,7 +29794,7 @@ Phaser.Tween.prototype = {
* @param {function} easing - The easing function this tween will use, i.e. Phaser.Easing.Linear.None.
* @return {Phaser.Tween} Itself.
*/
- easing: function ( easing ) {
+ easing: function (easing) {
this._easingFunction = easing;
return this;
@@ -27302,12 +29803,13 @@ Phaser.Tween.prototype = {
/**
* Set interpolation function the tween will use, by default it uses Phaser.Math.linearInterpolation.
+ * Also available: Phaser.Math.bezierInterpolation and Phaser.Math.catmullRomInterpolation.
*
* @method Phaser.Tween#interpolation
* @param {function} interpolation - The interpolation function to use (Phaser.Math.linearInterpolation by default)
* @return {Phaser.Tween} Itself.
*/
- interpolation: function ( interpolation ) {
+ interpolation: function (interpolation) {
this._interpolationFunction = interpolation;
return this;
@@ -27347,20 +29849,6 @@ Phaser.Tween.prototype = {
},
- /**
- * Sets a callback to be fired when the tween starts. Note: callback will be called in the context of the global scope.
- *
- * @method Phaser.Tween#onStartCallback
- * @param {function} callback - The callback to invoke on start.
- * @return {Phaser.Tween} Itself.
- */
- onStartCallback: function ( callback ) {
-
- this._onStartCallback = callback;
- return this;
-
- },
-
/**
* Sets a callback to be fired each time this tween updates. Note: callback will be called in the context of the global scope.
*
@@ -27368,23 +29856,11 @@ Phaser.Tween.prototype = {
* @param {function} callback - The callback to invoke each time this tween is updated.
* @return {Phaser.Tween} Itself.
*/
- onUpdateCallback: function ( callback ) {
+ onUpdateCallback: function (callback, callbackContext) {
this._onUpdateCallback = callback;
- return this;
+ this._onUpdateCallbackContext = callbackContext;
- },
-
- /**
- * Sets a callback to be fired when the tween completes. Note: callback will be called in the context of the global scope.
- *
- * @method Phaser.Tween#onCompleteCallback
- * @param {function} callback - The callback to invoke on completion.
- * @return {Phaser.Tween} Itself.
- */
- onCompleteCallback: function ( callback ) {
-
- this._onCompleteCallback = callback;
return this;
},
@@ -27395,8 +29871,10 @@ Phaser.Tween.prototype = {
* @method Phaser.Tween#pause
*/
pause: function () {
+
this._paused = true;
this._pausedTime = this.game.time.now;
+
},
/**
@@ -27405,8 +29883,10 @@ Phaser.Tween.prototype = {
* @method Phaser.Tween#resume
*/
resume: function () {
+
this._paused = false;
this._startTime += (this.game.time.now - this._pausedTime);
+
},
/**
@@ -27416,127 +29896,112 @@ Phaser.Tween.prototype = {
* @param {number} time - A timestamp passed in by the TweenManager.
* @return {boolean} false if the tween has completed and should be deleted from the manager, otherwise true (still active).
*/
- update: function ( time ) {
+ update: function (time) {
if (this.pendingDelete)
{
return false;
}
- if (this._paused || time < this._startTime) {
-
+ if (this._paused || time < this._startTime)
+ {
return true;
-
}
var property;
- if ( time < this._startTime ) {
-
+ if (time < this._startTime)
+ {
return true;
-
}
- if ( this._onStartCallbackFired === false ) {
-
- if ( this._onStartCallback !== null ) {
-
- this._onStartCallback.call( this._object );
-
- }
-
+ if (this._onStartCallbackFired === false)
+ {
+ this.onStart.dispatch(this._object);
this._onStartCallbackFired = true;
-
}
- var elapsed = ( time - this._startTime ) / this._duration;
+ var elapsed = (time - this._startTime) / this._duration;
elapsed = elapsed > 1 ? 1 : elapsed;
- var value = this._easingFunction( elapsed );
+ var value = this._easingFunction(elapsed);
- for ( property in this._valuesEnd ) {
-
- var start = this._valuesStart[ property ] || 0;
- var end = this._valuesEnd[ property ];
-
- if ( end instanceof Array ) {
-
- this._object[ property ] = this._interpolationFunction( end, value );
-
- } else {
+ for (property in this._valuesEnd)
+ {
+ var start = this._valuesStart[property] || 0;
+ var end = this._valuesEnd[property];
+ if (end instanceof Array)
+ {
+ this._object[property] = this._interpolationFunction(end, value);
+ }
+ else
+ {
// Parses relative end values with start as base (e.g.: +10, -3)
- if ( typeof(end) === "string" ) {
+ if (typeof(end) === 'string')
+ {
end = start + parseFloat(end, 10);
}
// protect against non numeric properties.
- if ( typeof(end) === "number" ) {
- this._object[ property ] = start + ( end - start ) * value;
+ if (typeof(end) === 'number')
+ {
+ this._object[property] = start + ( end - start ) * value;
}
-
}
-
}
- if ( this._onUpdateCallback !== null ) {
-
- this._onUpdateCallback.call( this._object, value );
-
+ if (this._onUpdateCallback !== null)
+ {
+ this._onUpdateCallback.call(this._onUpdateCallbackContext, this, value);
}
- if ( elapsed == 1 ) {
-
- if ( this._repeat > 0 ) {
-
- if ( isFinite( this._repeat ) ) {
+ if (elapsed == 1)
+ {
+ if (this._repeat > 0)
+ {
+ if (isFinite(this._repeat))
+ {
this._repeat--;
}
// reassign starting values, restart by making startTime = now
- for ( property in this._valuesStartRepeat ) {
-
- if ( typeof( this._valuesEnd[ property ] ) === "string" ) {
- this._valuesStartRepeat[ property ] = this._valuesStartRepeat[ property ] + parseFloat(this._valuesEnd[ property ], 10);
+ for (property in this._valuesStartRepeat)
+ {
+ if (typeof(this._valuesEnd[property]) === 'string')
+ {
+ this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property], 10);
}
- if (this._yoyo) {
- var tmp = this._valuesStartRepeat[ property ];
- this._valuesStartRepeat[ property ] = this._valuesEnd[ property ];
- this._valuesEnd[ property ] = tmp;
+ if (this._yoyo)
+ {
+ var tmp = this._valuesStartRepeat[property];
+ this._valuesStartRepeat[property] = this._valuesEnd[property];
+ this._valuesEnd[property] = tmp;
this._reversed = !this._reversed;
}
- this._valuesStart[ property ] = this._valuesStartRepeat[ property ];
+ this._valuesStart[property] = this._valuesStartRepeat[property];
}
this._startTime = time + this._delayTime;
- this.onComplete.dispatch(this._object);
-
- if ( this._onCompleteCallback !== null ) {
- this._onCompleteCallback.call( this._object );
- }
+ this.onLoop.dispatch(this._object);
return true;
- } else {
-
+ }
+ else
+ {
this.isRunning = false;
this.onComplete.dispatch(this._object);
- if ( this._onCompleteCallback !== null ) {
- this._onCompleteCallback.call( this._object );
- }
-
- for ( var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i ++ ) {
-
- this._chainedTweens[ i ].start( time );
-
+ for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i ++)
+ {
+ this._chainedTweens[i].start(time);
}
return false;
-
}
}
@@ -27547,11 +30012,13 @@ Phaser.Tween.prototype = {
};
+Phaser.Tween.prototype.constructor = Phaser.Tween;
+
/* jshint curly: false */
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -28113,7 +30580,7 @@ Phaser.Easing = {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -28127,243 +30594,358 @@ Phaser.Easing = {
*/
Phaser.Time = function (game) {
- /**
- * @property {Phaser.Game} game - Local reference to game.
- */
- this.game = game;
+ /**
+ * @property {Phaser.Game} game - Local reference to game.
+ */
+ this.game = game;
- /**
- * @property {number} _started - The time at which the Game instance started.
- * @private
- */
- this._started = 0;
+ /**
+ * @property {number} time - Game time counter. If you need a value for in-game calculation please use Phaser.Time.now instead.
+ * @protected
+ */
+ this.time = 0;
- /**
- * @property {number} _timeLastSecond - The time (in ms) that the last second counter ticked over.
- * @private
- */
- this._timeLastSecond = 0;
+ /**
+ * @property {number} now - The time right now.
+ * @protected
+ */
+ this.now = 0;
- /**
- * @property {number} _pauseStarted - The time the game started being paused.
- * @private
- */
- this._pauseStarted = 0;
+ /**
+ * @property {number} elapsed - Elapsed time since the last frame (in ms).
+ * @protected
+ */
+ this.elapsed = 0;
- /**
- * @property {number} physicsElapsed - The elapsed time calculated for the physics motion updates.
- */
- this.physicsElapsed = 0;
+ /**
+ * @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses.
+ * @protected
+ */
+ this.pausedTime = 0;
- /**
- * @property {number} time - Game time counter.
- */
- this.time = 0;
+ /**
+ * @property {number} fps - Frames per second.
+ * @protected
+ */
+ this.fps = 0;
- /**
- * @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses.
- */
- this.pausedTime = 0;
+ /**
+ * @property {number} fpsMin - The lowest rate the fps has dropped to.
+ */
+ this.fpsMin = 1000;
- /**
- * @property {number} now - The time right now.
- */
- this.now = 0;
+ /**
+ * @property {number} fpsMax - The highest rate the fps has reached (usually no higher than 60fps).
+ */
+ this.fpsMax = 0;
- /**
- * @property {number} elapsed - Elapsed time since the last frame.
- */
- this.elapsed = 0;
+ /**
+ * @property {number} msMin - The minimum amount of time the game has taken between two frames.
+ * @default
+ */
+ this.msMin = 1000;
- /**
- * @property {number} fps - Frames per second.
- */
- this.fps = 0;
+ /**
+ * @property {number} msMax - The maximum amount of time the game has taken between two frames.
+ */
+ this.msMax = 0;
- /**
- * @property {number} fpsMin - The lowest rate the fps has dropped to.
- */
- this.fpsMin = 1000;
+ /**
+ * @property {number} physicsElapsed - The elapsed time calculated for the physics motion updates.
+ */
+ this.physicsElapsed = 0;
- /**
- * @property {number} fpsMax - The highest rate the fps has reached (usually no higher than 60fps).
- */
- this.fpsMax = 0;
+ /**
+ * @property {number} frames - The number of frames record in the last second.
+ */
+ this.frames = 0;
- /**
- * @property {number} msMin - The minimum amount of time the game has taken between two frames.
- * @default
- */
- this.msMin = 1000;
+ /**
+ * @property {number} pauseDuration - Records how long the game was paused for in miliseconds.
+ */
+ this.pauseDuration = 0;
- /**
- * @property {number} msMax - The maximum amount of time the game has taken between two frames.
- */
- this.msMax = 0;
+ /**
+ * @property {number} timeToCall - The value that setTimeout needs to work out when to next update
+ */
+ this.timeToCall = 0;
- /**
- * @property {number} frames - The number of frames record in the last second.
- */
- this.frames = 0;
+ /**
+ * @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop
+ */
+ this.lastTime = 0;
- /**
- * @property {number} pauseDuration - Records how long the game was paused for in miliseconds.
- */
- this.pauseDuration = 0;
+ /**
+ * @property {Phaser.Timer} events - This is a Phaser.Timer object bound to the master clock to which you can add timed events.
+ */
+ this.events = new Phaser.Timer(this.game, false);
- /**
- * @property {number} timeToCall - The value that setTimeout needs to work out when to next update
- */
- this.timeToCall = 0;
-
- /**
- * @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop
- */
- this.lastTime = 0;
-
- // Listen for game pause/resume events
- this.game.onPause.add(this.gamePaused, this);
- this.game.onResume.add(this.gameResumed, this);
-
- /**
- * @property {boolean} _justResumed - Internal value used to recover from the game pause state.
+ /**
+ * @property {number} _started - The time at which the Game instance started.
* @private
- */
- this._justResumed = false;
+ */
+ this._started = 0;
+
+ /**
+ * @property {number} _timeLastSecond - The time (in ms) that the last second counter ticked over.
+ * @private
+ */
+ this._timeLastSecond = 0;
+
+ /**
+ * @property {number} _pauseStarted - The time the game started being paused.
+ * @private
+ */
+ this._pauseStarted = 0;
+
+ /**
+ * @property {boolean} _justResumed - Internal value used to recover from the game pause state.
+ * @private
+ */
+ this._justResumed = false;
+
+ /**
+ * @property {array} _timers - Internal store of Phaser.Timer objects.
+ * @private
+ */
+ this._timers = [];
+
+ /**
+ * @property {number} _len - Temp. array length variable.
+ * @private
+ */
+ this._len = 0;
+
+ /**
+ * @property {number} _i - Temp. array counter variable.
+ * @private
+ */
+ this._i = 0;
+
+ // Listen for game pause/resume events
+ this.game.onPause.add(this.gamePaused, this);
+ this.game.onResume.add(this.gameResumed, this);
};
Phaser.Time.prototype = {
- /**
- * Updates the game clock and calculate the fps. This is called automatically by Phaser.Game.
- * @method Phaser.Time#update
- * @param {number} time - The current timestamp, either performance.now or Date.now depending on the browser.
- */
- update: function (time) {
+ /**
+ * @method Phaser.Time#boot
+ */
+ boot: function () {
- this.now = time;
+ this.events.start();
- if (this._justResumed)
- {
- this.time = this.now;
- this._justResumed = false;
- }
+ },
- this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime));
+ /**
+ * Creates a new stand-alone Phaser.Timer object.
+ * @method Phaser.Time#create
+ * @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
+ * @return {Phaser.Timer} The Timer object that was created.
+ */
+ create: function (autoDestroy) {
- this.elapsed = this.now - this.time;
+ if (typeof autoDestroy === 'undefined') { autoDestroy = true; }
- this.msMin = this.game.math.min(this.msMin, this.elapsed);
- this.msMax = this.game.math.max(this.msMax, this.elapsed);
+ var timer = new Phaser.Timer(this.game, autoDestroy);
- this.frames++;
+ this._timers.push(timer);
- if (this.now > this._timeLastSecond + 1000)
- {
- this.fps = Math.round((this.frames * 1000) / (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;
- }
+ return timer;
- this.time = this.now;
+ },
+
+ /**
+ * Remove all Timer objects, regardless of their state.
+ * @method Phaser.Time#removeAll
+ */
+ removeAll: function () {
+
+ for (var i = 0; i < this._timers.length; i++)
+ {
+ this._timers[i].destroy();
+ }
+
+ this._timers = [];
+
+ },
+
+ /**
+ * Updates the game clock and calculate the fps. This is called automatically by Phaser.Game.
+ * @method Phaser.Time#update
+ * @param {number} time - The current timestamp, either performance.now or Date.now depending on the browser.
+ */
+ update: function (time) {
+
+ this.now = time;
+
+ if (this._justResumed)
+ {
+ this.time = this.now;
+ this._justResumed = false;
+
+ this.events.resume();
+
+ for (var i = 0; i < this._timers.length; i++)
+ {
+ this._timers[i].resume();
+ }
+ }
+
+ this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime));
+
+ this.elapsed = this.now - this.time;
+
+ this.msMin = this.game.math.min(this.msMin, this.elapsed);
+ this.msMax = this.game.math.max(this.msMax, this.elapsed);
+
+ this.frames++;
+
+ if (this.now > this._timeLastSecond + 1000)
+ {
+ this.fps = Math.round((this.frames * 1000) / (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 = time + this.timeToCall;
- this.physicsElapsed = 1.0 * (this.elapsed / 1000);
+ this.physicsElapsed = 1.0 * (this.elapsed / 1000);
- // Clamp the delta
- if (this.physicsElapsed > 1)
- {
- this.physicsElapsed = 1;
- }
+ // Clamp the delta
+ if (this.physicsElapsed > 0.05)
+ {
+ this.physicsElapsed = 0.05;
+ }
- // Paused?
- if (this.game.paused)
- {
- this.pausedTime = this.now - this._pauseStarted;
- }
+ // Paused?
+ if (this.game.paused)
+ {
+ this.pausedTime = this.now - this._pauseStarted;
+ }
+ else
+ {
+ // Our internal Phaser.Timer
+ this.events.update(this.now);
- },
+ // Any game level timers
+ this._i = 0;
+ this._len = this._timers.length;
- /**
- * Called when the game enters a paused state.
- * @method Phaser.Time#gamePaused
- * @private
- */
- gamePaused: function () {
-
- this._pauseStarted = this.now;
+ while (this._i < this._len)
+ {
+ if (this._timers[this._i].update(this.now))
+ {
+ this._i++;
+ }
+ else
+ {
+ this._timers.splice(this._i, 1);
- },
+ this._len--;
+ }
+ }
+ }
- /**
- * Called when the game resumes from a paused state.
- * @method Phaser.Time#gameResumed
- * @private
- */
- gameResumed: function () {
+ },
- // Level out the elapsed timer to avoid spikes
- this.time = Date.now();
- this.pauseDuration = this.pausedTime;
- this._justResumed = true;
+ /**
+ * Called when the game enters a paused state.
+ * @method Phaser.Time#gamePaused
+ * @private
+ */
+ gamePaused: function () {
+
+ this._pauseStarted = this.now;
- },
+ this.events.pause();
- /**
- * The number of seconds that have elapsed since the game was started.
- * @method Phaser.Time#totalElapsedSeconds
- * @return {number}
- */
- totalElapsedSeconds: function() {
- return (this.now - this._started) * 0.001;
- },
+ for (var i = 0; i < this._timers.length; i++)
+ {
+ this._timers[i].pause();
+ }
- /**
- * How long has passed since the given time.
- * @method Phaser.Time#elapsedSince
- * @param {number} since - The time you want to measure against.
- * @return {number} The difference between the given time and now.
- */
- elapsedSince: function (since) {
- return this.now - since;
- },
+ },
- /**
- * How long has passed since the given time (in seconds).
- * @method Phaser.Time#elapsedSecondsSince
- * @param {number} since - The time you want to measure (in seconds).
- * @return {number} Duration between given time and now (in seconds).
- */
- elapsedSecondsSince: function (since) {
- return (this.now - since) * 0.001;
- },
+ /**
+ * Called when the game resumes from a paused state.
+ * @method Phaser.Time#gameResumed
+ * @private
+ */
+ gameResumed: function () {
- /**
- * Resets the private _started value to now.
- * @method Phaser.Time#reset
- */
- reset: function () {
- this._started = this.now;
- }
+ // Level out the elapsed timer to avoid spikes
+ this.time = Date.now();
+ this.pauseDuration = this.pausedTime;
+ this._justResumed = true;
+
+ },
+
+ /**
+ * The number of seconds that have elapsed since the game was started.
+ * @method Phaser.Time#totalElapsedSeconds
+ * @return {number}
+ */
+ totalElapsedSeconds: function() {
+ return (this.now - this._started) * 0.001;
+ },
+
+ /**
+ * How long has passed since the given time.
+ * @method Phaser.Time#elapsedSince
+ * @param {number} since - The time you want to measure against.
+ * @return {number} The difference between the given time and now.
+ */
+ elapsedSince: function (since) {
+ return this.now - since;
+ },
+
+ /**
+ * How long has passed since the given time (in seconds).
+ * @method Phaser.Time#elapsedSecondsSince
+ * @param {number} since - The time you want to measure (in seconds).
+ * @return {number} Duration between given time and now (in seconds).
+ */
+ elapsedSecondsSince: function (since) {
+ return (this.now - since) * 0.001;
+ },
+
+ /**
+ * Resets the private _started value to now.
+ * @method Phaser.Time#reset
+ */
+ reset: function () {
+ this._started = this.now;
+ }
};
+
+Phaser.Time.prototype.constructor = Phaser.Time;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
-* Timer constructor.
+* A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.
+* You can add as many events to a Timer as you like, each with their own delays. A Timer uses milliseconds as its unit of time. There are 1000 ms in 1 second.
+* So if you want to fire an event every quarter of a second you'd need to set the delay to 250.
*
* @class Phaser.Timer
-* @classdesc A Timer
+* @classdesc A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.
* @constructor
* @param {Phaser.Game} game A reference to the currently running game.
+* @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
*/
-Phaser.Timer = function (game) {
+Phaser.Timer = function (game, autoDestroy) {
+
+ if (typeof autoDestroy === 'undefined') { autoDestroy = true; }
/**
* @property {Phaser.Game} game - Local reference to game.
@@ -28371,67 +30953,208 @@ Phaser.Timer = function (game) {
this.game = game;
/**
- * The time at which this Timer instance started.
- * @property {number} _started
+ * @property {boolean} running - True if the Timer is actively running. Do not switch this boolean, if you wish to pause the timer then use Timer.pause() instead.
+ * @default
+ */
+ this.running = false;
+
+ /**
+ * @property {boolean} autoDestroy - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
+ */
+ this.autoDestroy = autoDestroy;
+
+ /**
+ * @property {boolean} expired - An expired Timer is one in which all of its events have been dispatched and none are pending.
+ * @readonly
+ * @default
+ */
+ this.expired = false;
+
+ /**
+ * @property {array} events - An array holding all of this timers Phaser.TimerEvent objects. Use the methods add, repeat and loop to populate it.
+ */
+ this.events = [];
+
+ /**
+ * @property {Phaser.Signal} onComplete - This signal will be dispatched when this Timer has completed, meaning there are no more events in the queue.
+ */
+ this.onComplete = new Phaser.Signal();
+
+ /**
+ * @property {number} nextTick - The time the next tick will occur.
+ * @readonly
+ * @protected
+ */
+ this.nextTick = 0;
+
+ /**
+ * @property {boolean} paused - The paused state of the Timer. You can pause the timer by calling Timer.pause() and Timer.resume() or by the game pausing.
+ * @readonly
+ * @default
+ */
+ this.paused = false;
+
+ /**
+ * @property {number} _started - The time at which this Timer instance started running.
* @private
* @default
*/
this._started = 0;
/**
- * The time (in ms) that the last second counter ticked over.
- * @property {number} _timeLastSecond
+ * @property {number} _pauseStarted - The time the game started being paused.
* @private
- * @default
*/
- this._timeLastSecond = 0;
+ this._pauseStarted = 0;
- this.running = false;
+ /**
+ * @property {number} _now - The current start-time adjusted time.
+ * @private
+ */
+ this._now = 0;
- this.events = [];
+ /**
+ * @property {number} _len - Temp. array length variable.
+ * @private
+ */
+ this._len = 0;
- this.onEvent = new Phaser.Signal();
+ /**
+ * @property {number} _i - Temp. array counter variable.
+ * @private
+ */
+ this._i = 0;
- // Need to add custom FPS rate, for now we'll just use seconds
+};
-}
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Timer.MINUTE = 60000;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Timer.SECOND = 1000;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Timer.HALF = 500;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Timer.QUARTER = 250;
Phaser.Timer.prototype = {
- // delay could be from now, when the timer is created, or relative to an already running timer
+ /**
+ * Creates a new TimerEvent on this Timer. Use the methods add, repeat or loop instead of this.
+ * @method Phaser.Timer#create
+ * @private
+ * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
+ * @param {boolean} loop - Should the event loop or not?
+ * @param {number} repeatCount - The number of times the event will repeat.
+ * @param {function} callback - The callback that will be called when the Timer event occurs.
+ * @param {object} callbackContext - The context in which the callback will be called.
+ * @param {array} arguments - The values to be sent to your callback function when it is called.
+ * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
+ */
+ create: function (delay, loop, repeatCount, callback, callbackContext, args) {
- // add: function (delay, callback, callbackContext) {
- add: function (delay) {
+ var tick = delay;
- this.events.push({
- delay: delay,
- dispatched: false,
- args: Array.prototype.splice.call(arguments, 1)
- });
+ if (this.running)
+ {
+ tick += this._now;
+ }
- // this.events.push({
- // delay: delay,
- // dispatched: false,
- // callback: callback,
- // callbackContext: callbackContext,
- // args: Array.prototype.splice.call(arguments, 3)
- // });
+ var event = new Phaser.TimerEvent(this, delay, tick, repeatCount, loop, callback, callbackContext, args);
+
+ this.events.push(event);
+
+ this.order();
+
+ this.expired = false;
+
+ return event;
},
+ /**
+ * Adds a new Event to this Timer. The event will fire after the given amount of 'delay' in milliseconds has passed, once the Timer has started running.
+ * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
+ * If the Timer is already running the delay will be calculated based on the timers current time.
+ * @method Phaser.Timer#add
+ * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
+ * @param {function} callback - The callback that will be called when the Timer event occurs.
+ * @param {object} callbackContext - The context in which the callback will be called.
+ * @param {...*} arguments - The values to be sent to your callback function when it is called.
+ * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
+ */
+ add: function (delay, callback, callbackContext) {
+
+ return this.create(delay, false, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3));
+
+ },
+
+ /**
+ * Adds a new Event to this Timer that will repeat for the given number of iterations.
+ * The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running.
+ * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
+ * If the Timer is already running the delay will be calculated based on the timers current time.
+ * @method Phaser.Timer#repeat
+ * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
+ * @param {number} repeatCount - The number of times the event will repeat.
+ * @param {function} callback - The callback that will be called when the Timer event occurs.
+ * @param {object} callbackContext - The context in which the callback will be called.
+ * @param {...*} arguments - The values to be sent to your callback function when it is called.
+ * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
+ */
+ repeat: function (delay, repeatCount, callback, callbackContext) {
+
+ return this.create(delay, false, repeatCount, callback, callbackContext, Array.prototype.splice.call(arguments, 4));
+
+ },
+
+ /**
+ * Adds a new looped Event to this Timer that will repeat forever or until the Timer is stopped.
+ * The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running.
+ * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
+ * If the Timer is already running the delay will be calculated based on the timers current time.
+ * @method Phaser.Timer#loop
+ * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
+ * @param {function} callback - The callback that will be called when the Timer event occurs.
+ * @param {object} callbackContext - The context in which the callback will be called.
+ * @param {...*} arguments - The values to be sent to your callback function when it is called.
+ * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
+ */
+ loop: function (delay, callback, callbackContext) {
+
+ return this.create(delay, true, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3));
+
+ },
+
+ /**
+ * Starts this Timer running.
+ * @method Phaser.Timer#start
+ */
start: function() {
this._started = this.game.time.now;
this.running = true;
- // sort the events based on delay here, also don't run unless events is populated
- // add ability to auto-stop once all events are done
- // add support for maximum duration
- // add support for delay before starting
- // add signals?
-
},
+ /**
+ * Stops this Timer from running. Does not cause it to be destroyed if autoDestroy is set to true.
+ * @method Phaser.Timer#stop
+ */
stop: function() {
this.running = false;
@@ -28439,36 +31162,329 @@ Phaser.Timer.prototype = {
},
- update: function() {
+ /**
+ * Removes a pending TimerEvent from the queue.
+ * @param {Phaser.TimerEvent} event - The event to remove from the queue.
+ * @method Phaser.Timer#remove
+ */
+ remove: function(event) {
- // TODO: Game Paused support
-
- if (this.running)
+ for (var i = 0; i < this.events.length; i++)
{
- var seconds = this.seconds();
-
- for (var i = 0, len = this.events.length; i < len; i++)
+ if (this.events[i] === event)
{
- if (this.events[i].dispatched === false && seconds >= this.events[i].delay)
- {
- this.events[i].dispatched = true;
- // this.events[i].callback.apply(this.events[i].callbackContext, this.events[i].args);
- this.onEvent.dispatch.apply(this, this.events[i].args);
- // ought to slice it now
- }
+ this.events.splice(i, 1);
+ return true;
}
}
+ return false;
+
+ },
+
+ /**
+ * Orders the events on this Timer so they are in tick order. This is called automatically when new events are created.
+ * @method Phaser.Timer#order
+ */
+ order: function () {
+
+ if (this.events.length > 0)
+ {
+ // Sort the events so the one with the lowest tick is first
+ this.events.sort(this.sortHandler);
+
+ this.nextTick = this.events[0].tick;
+ }
+
},
- seconds: function() {
- return (this.game.time.now - this._started) * 0.001;
+ /**
+ * Sort handler used by Phaser.Timer.order.
+ * @method Phaser.Timer#sortHandler
+ * @protected
+ */
+ sortHandler: function (a, b) {
+
+ if (a.tick < b.tick)
+ {
+ return -1;
+ }
+ else if (a.tick > b.tick)
+ {
+ return 1;
+ }
+
+ return 0;
+
+ },
+
+ /**
+ * The main Timer update event, called automatically by the Game clock.
+ * @method Phaser.Timer#update
+ * @protected
+ * @param {number} time - The time from the core game clock.
+ * @return {boolean} True if there are still events waiting to be dispatched, otherwise false if this Timer can be destroyed.
+ */
+ update: function(time) {
+
+ if (this.paused)
+ {
+ return true;
+ }
+
+ this._now = time - this._started;
+
+ this._len = this.events.length;
+
+ if (this.running && this._now >= this.nextTick && this._len > 0)
+ {
+ this._i = 0;
+
+ while (this._i < this._len)
+ {
+ if (this._now >= this.events[this._i].tick)
+ {
+ if (this.events[this._i].loop === true)
+ {
+ this.events[this._i].tick += this.events[this._i].delay - (this._now - this.events[this._i].tick);
+ this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
+ }
+ else if (this.events[this._i].repeatCount > 0)
+ {
+ this.events[this._i].repeatCount--;
+ this.events[this._i].tick += this.events[this._i].delay - (this._now - this.events[this._i].tick);
+ this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
+ }
+ else
+ {
+ 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++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ // Are there any events left?
+ if (this.events.length > 0)
+ {
+ this.order();
+ }
+ else
+ {
+ this.expired = true;
+ this.onComplete.dispatch(this);
+ }
+ }
+
+ if (this.expired && this.autoDestroy)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+
+ },
+
+ /**
+ * Pauses the Timer and all events in the queue.
+ * @method Phaser.Timer#pause
+ */
+ pause: function () {
+
+ this._pauseStarted = this.game.time.now;
+
+ this.paused = true;
+
+ },
+
+ /**
+ * Resumes the Timer and updates all pending events.
+ * @method Phaser.Timer#resume
+ */
+ resume: function () {
+
+ var pauseDuration = this.game.time.now - this._pauseStarted;
+
+ for (var i = 0; i < this.events.length; i++)
+ {
+ this.events[i].tick += pauseDuration;
+ }
+
+ this.nextTick += pauseDuration;
+
+ this.paused = false;
+
+ },
+
+ /**
+ * Destroys this Timer. Events are not dispatched.
+ * @method Phaser.Timer#destroy
+ */
+ destroy: function() {
+
+ this.onComplete.removeAll();
+ this.running = false;
+ this.events = [];
+
}
-}
+};
+
+/**
+* @name Phaser.Timer#next
+* @property {number} next - The time at which the next event will occur.
+* @readonly
+*/
+Object.defineProperty(Phaser.Timer.prototype, "next", {
+
+ get: function () {
+ return this.nextTick;
+ }
+
+});
+
+/**
+* @name Phaser.Timer#duration
+* @property {number} duration - The duration in ms remaining until the next event will occur.
+* @readonly
+*/
+Object.defineProperty(Phaser.Timer.prototype, "duration", {
+
+ get: function () {
+
+ if (this.running && this.nextTick > this._now)
+ {
+ return this.nextTick - this._now;
+ }
+ else
+ {
+ return 0;
+ }
+
+ }
+
+});
+
+/**
+* @name Phaser.Timer#length
+* @property {number} length - The number of pending events in the queue.
+* @readonly
+*/
+Object.defineProperty(Phaser.Timer.prototype, "length", {
+
+ get: function () {
+ return this.events.length;
+ }
+
+});
+
+/**
+* @name Phaser.Timer#ms
+* @property {number} ms - The duration in milliseconds that this Timer has been running for.
+* @readonly
+*/
+Object.defineProperty(Phaser.Timer.prototype, "ms", {
+
+ get: function () {
+ return this._now;
+ }
+
+});
+
+/**
+* @name Phaser.Timer#seconds
+* @property {number} seconds - The duration in seconds that this Timer has been running for.
+* @readonly
+*/
+Object.defineProperty(Phaser.Timer.prototype, "seconds", {
+
+ get: function () {
+ return this._now * 0.001;
+ }
+
+});
+
+Phaser.Timer.prototype.constructor = Phaser.Timer;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire.
+* It can call a specific callback, passing in optional parameters.
+*
+* @class Phaser.TimerEvent
+* @classdesc A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire.
+* @constructor
+* @param {Phaser.Timer} timer - The Timer object that this TimerEvent belongs to.
+* @param {number} delay - The delay in ms at which this TimerEvent fires.
+* @param {number} tick - The tick is the next game clock time that this event will fire at.
+* @param {number} repeatCount - If this TimerEvent repeats it will do so this many times.
+* @param {boolean} loop - True if this TimerEvent loops, otherwise false.
+* @param {function} callback - The callback that will be called when the TimerEvent occurs.
+* @param {object} callbackContext - The context in which the callback will be called.
+* @param {array} arguments - The values to be passed to the callback.
+*/
+Phaser.TimerEvent = function (timer, delay, tick, repeatCount, loop, callback, callbackContext, args) {
+
+ /**
+ * @property {Phaser.Timer} timer - The Timer object that this TimerEvent belongs to.
+ */
+ this.timer = timer;
+
+ /**
+ * @property {number} delay - The delay in ms at which this TimerEvent fires.
+ */
+ this.delay = delay;
+
+ /**
+ * @property {number} tick - The tick is the next game clock time that this event will fire at.
+ */
+ this.tick = tick;
+
+ /**
+ * @property {number} repeatCount - If this TimerEvent repeats it will do so this many times.
+ */
+ this.repeatCount = repeatCount - 1;
+
+ /**
+ * @property {boolean} loop - True if this TimerEvent loops, otherwise false.
+ */
+ this.loop = loop;
+
+ /**
+ * @property {function} callback - The callback that will be called when the TimerEvent occurs.
+ */
+ this.callback = callback;
+
+ /**
+ * @property {object} callbackContext - The context in which the callback will be called.
+ */
+ this.callbackContext = callbackContext;
+
+ /**
+ * @property {array} arguments - The values to be passed to the callback.
+ */
+ this.args = args;
+
+};
+
+Phaser.TimerEvent.prototype.constructor = Phaser.TimerEvent;
+
+/**
+* @author Richard Davey
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -28734,7 +31750,7 @@ Phaser.AnimationManager.prototype = {
*
* @method Phaser.AnimationManager#getAnimation
* @param {string} name - The name of the animation to be returned, e.g. "fire".
- * @return {Phaser.Animation|boolean} The Animation instance, if found, otherwise false.
+ * @return {Phaser.Animation} The Animation instance, if found, otherwise null.
*/
getAnimation: function (name) {
@@ -28746,7 +31762,7 @@ Phaser.AnimationManager.prototype = {
}
}
- return false;
+ return null;
},
@@ -28779,6 +31795,8 @@ Phaser.AnimationManager.prototype = {
};
+Phaser.AnimationManager.prototype.constructor = Phaser.AnimationManager;
+
/**
* @name Phaser.AnimationManager#frameData
* @property {Phaser.FrameData} frameData - The current animations FrameData.
@@ -28896,7 +31914,7 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frameName', {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -28939,7 +31957,7 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope
this.name = name;
/**
- * @property {object} _frames
+ * @property {array} _frames
* @private
*/
this._frames = [];
@@ -28956,7 +31974,8 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope
this.looped = looped;
/**
- * @property {boolean} looped - The loop state of the Animation.
+ * @property {boolean} killOnComplete - Should the parent of this Animation be killed when the animation completes?
+ * @default
*/
this.killOnComplete = false;
@@ -29223,6 +32242,8 @@ Phaser.Animation.prototype = {
};
+Phaser.Animation.prototype.constructor = Phaser.Animation;
+
/**
* @name Phaser.Animation#paused
* @property {boolean} paused - Gets and sets the paused state of this Animation.
@@ -29367,7 +32388,7 @@ Phaser.Animation.generateFrameNames = function (prefix, start, stop, suffix, zer
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -29526,9 +32547,11 @@ Phaser.Frame.prototype = {
};
+Phaser.Frame.prototype.constructor = Phaser.Frame;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -29751,6 +32774,8 @@ Phaser.FrameData.prototype = {
};
+Phaser.FrameData.prototype.constructor = Phaser.FrameData;
+
/**
* @name Phaser.FrameData#total
* @property {number} total - The total number of frames in this FrameData set.
@@ -29766,7 +32791,7 @@ Object.defineProperty(Phaser.FrameData.prototype, "total", {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -29786,9 +32811,11 @@ Phaser.AnimationParser = {
* @param {number} frameWidth - The fixed width of each frame of the animation.
* @param {number} frameHeight - The fixed height of each frame of the animation.
* @param {number} [frameMax=-1] - The total number of animation frames to extact from the Sprite Sheet. The default value of -1 means "extract all frames".
+ * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
+ * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/
- spriteSheet: function (game, key, frameWidth, frameHeight, frameMax) {
+ spriteSheet: function (game, key, frameWidth, frameHeight, frameMax, margin, spacing) {
// How big is our image?
var img = game.cache.getImage(key);
@@ -29829,8 +32856,8 @@ Phaser.AnimationParser = {
// Let's create some frames then
var data = new Phaser.FrameData();
- var x = 0;
- var y = 0;
+ var x = margin;
+ var y = margin;
for (var i = 0; i < total; i++)
{
@@ -29845,12 +32872,12 @@ Phaser.AnimationParser = {
height: frameHeight
});
- x += frameWidth;
+ x += frameWidth + spacing;
if (x === width)
{
- x = 0;
- y += frameHeight;
+ x = margin;
+ y += frameHeight + spacing;
}
}
@@ -30092,16 +33119,15 @@ Phaser.AnimationParser = {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Phaser.Cache constructor.
*
-* @class Phaser.Cache
-* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such
-* as images, sounds and data files as a result of Loader calls. Cache items use string based keys for look-up.
+* @class Phaser.Cache
+* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such as images, sounds and data files as a result of Loader calls. Cached items use string based keys for look-up.
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
*/
@@ -30149,10 +33175,10 @@ Phaser.Cache = function (game) {
this._tilemaps = {};
/**
- * @property {object} _tilesets - Tileset key-value container.
+ * @property {object} _binary - Binary file key-value container.
* @private
*/
- this._tilesets = {};
+ this._binary = {};
/**
* @property {object} _bitmapDatas - BitmapData key-value container.
@@ -30185,6 +33211,18 @@ Phaser.Cache.prototype = {
},
+ /**
+ * Add a binary object in to the cache.
+ * @method Phaser.Cache#addBinary
+ * @param {string} key - Asset key for this binary data.
+ * @param {object} binaryData - The binary object to be addded to the cache.
+ */
+ addBinary: function (key, binaryData) {
+
+ this._binary[key] = binaryData;
+
+ },
+
/**
* Add a BitmapData object in to the cache.
* @method Phaser.Cache#addBitmapData
@@ -30224,40 +33262,18 @@ Phaser.Cache.prototype = {
* @param {object} data - Extra sprite sheet data.
* @param {number} frameWidth - Width of the sprite sheet.
* @param {number} frameHeight - Height of the sprite sheet.
- * @param {number} frameMax - How many frames stored in the sprite sheet.
+ * @param {number} [frameMax=-1] - How many frames stored in the sprite sheet. If -1 then it divides the whole sheet evenly.
+ * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
+ * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
*/
- addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax) {
+ addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax, margin, spacing) {
- this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight };
+ this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight, margin: margin, spacing: spacing };
PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data);
PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]);
- this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax);
-
- },
-
- /**
- * Add a new tile set in to the cache.
- *
- * @method Phaser.Cache#addTileset
- * @param {string} key - The unique key by which you will reference this object.
- * @param {string} url - URL of this tile set file.
- * @param {object} data - Extra tile set data.
- * @param {number} tileWidth - Width of the sprite sheet.
- * @param {number} tileHeight - Height of the sprite sheet.
- * @param {number} tileMax - How many tiles stored in the sprite sheet.
- * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
- * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
- */
- addTileset: function (key, url, data, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
-
- this._tilesets[key] = { url: url, data: data, tileWidth: tileWidth, tileHeight: tileHeight, tileMargin: tileMargin, tileSpacing: tileSpacing };
-
- PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data);
- PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]);
-
- this._tilesets[key].tileData = Phaser.TilemapParser.tileset(this.game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing);
+ this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax, margin, spacing);
},
@@ -30267,15 +33283,13 @@ Phaser.Cache.prototype = {
* @method Phaser.Cache#addTilemap
* @param {string} key - The unique key by which you will reference this object.
* @param {string} url - URL of the tilemap image.
- * @param {object} mapData - The tilemap data object.
+ * @param {object} mapData - The tilemap data object (either a CSV or JSON file).
* @param {number} format - The format of the tilemap data.
*/
addTilemap: function (key, url, mapData, format) {
this._tilemaps[key] = { url: url, data: mapData, format: format };
- this._tilemaps[key].layers = Phaser.TilemapParser.parse(this.game, mapData, format);
-
},
/**
@@ -30425,12 +33439,13 @@ Phaser.Cache.prototype = {
decoded = true;
}
- this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag };
+ this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag, locked: this.game.sound.touchLocked };
},
/**
* Reload a sound.
+ *
* @method Phaser.Cache#reloadSound
* @param {string} key - Asset key for the sound.
*/
@@ -30451,7 +33466,8 @@ Phaser.Cache.prototype = {
},
/**
- * Description.
+ * Fires the onSoundUnlock event when the sound has completed reloading.
+ *
* @method Phaser.Cache#reloadSoundComplete
* @param {string} key - Asset key for the sound.
*/
@@ -30466,7 +33482,8 @@ Phaser.Cache.prototype = {
},
/**
- * Description.
+ * Updates the sound object in the cache.
+ *
* @method Phaser.Cache#updateSound
* @param {string} key - Asset key for the sound.
*/
@@ -30498,8 +33515,8 @@ Phaser.Cache.prototype = {
* Get a canvas object from the cache by its key.
*
* @method Phaser.Cache#getCanvas
- * @param {string} key - Asset key of the canvas you want.
- * @return {object} The canvas you want.
+ * @param {string} key - Asset key of the canvas to retrieve from the Cache.
+ * @return {object} The canvas object.
*/
getCanvas: function (key) {
@@ -30507,8 +33524,10 @@ Phaser.Cache.prototype = {
{
return this._canvases[key].canvas;
}
-
- return null;
+ else
+ {
+ console.warn('Phaser.Cache.getCanvas: Invalid key: "' + key + '"');
+ }
},
@@ -30516,7 +33535,7 @@ Phaser.Cache.prototype = {
* Get a BitmapData object from the cache by its key.
*
* @method Phaser.Cache#getBitmapData
- * @param {string} key - Asset key of the BitmapData object you want.
+ * @param {string} key - Asset key of the BitmapData object to retrieve from the Cache.
* @return {Phaser.BitmapData} The requested BitmapData object if found, or null if not.
*/
getBitmapData: function (key) {
@@ -30525,8 +33544,10 @@ Phaser.Cache.prototype = {
{
return this._bitmapDatas[key];
}
-
- return null;
+ else
+ {
+ console.warn('Phaser.Cache.getBitmapData: Invalid key: "' + key + '"');
+ }
},
@@ -30534,7 +33555,7 @@ Phaser.Cache.prototype = {
* Checks if an image key exists.
*
* @method Phaser.Cache#checkImageKey
- * @param {string} key - Asset key of the image you want.
+ * @param {string} key - Asset key of the image to check is in the Cache.
* @return {boolean} True if the key exists, otherwise false.
*/
checkImageKey: function (key) {
@@ -30552,8 +33573,8 @@ Phaser.Cache.prototype = {
* Get image data by key.
*
* @method Phaser.Cache#getImage
- * @param {string} key - Asset key of the image you want.
- * @return {object} The image data you want.
+ * @param {string} key - Asset key of the image to retrieve from the Cache.
+ * @return {object} The image data.
*/
getImage: function (key) {
@@ -30561,53 +33582,19 @@ Phaser.Cache.prototype = {
{
return this._images[key].data;
}
-
- return null;
-
- },
-
- /**
- * Get tile set image data by key.
- *
- * @method Phaser.Cache#getTileSetImage
- * @param {string} key - Asset key of the image you want.
- * @return {object} The image data you want.
- */
- getTilesetImage: function (key) {
-
- if (this._tilesets[key])
+ else
{
- return this._tilesets[key].data;
+ console.warn('Phaser.Cache.getImage: Invalid key: "' + key + '"');
}
- return null;
-
- },
-
- /**
- * Get tile set image data by key.
- *
- * @method Phaser.Cache#getTileset
- * @param {string} key - Asset key of the image you want.
- * @return {Phaser.Tileset} The tileset data. The tileset image is in the data property, the tile data in tileData.
- */
- getTileset: function (key) {
-
- if (this._tilesets[key])
- {
- return this._tilesets[key].tileData;
- }
-
- return null;
-
},
/**
* Get tilemap data by key.
*
* @method Phaser.Cache#getTilemap
- * @param {string} key - Asset key of the tilemap you want.
- * @return {Object} The tilemap data. The tileset image is in the data property, the map data in mapData.
+ * @param {string} key - Asset key of the tilemap data to retrieve from the Cache.
+ * @return {Object} The raw tilemap data in CSV or JSON format.
*/
getTilemapData: function (key) {
@@ -30615,16 +33602,19 @@ Phaser.Cache.prototype = {
{
return this._tilemaps[key];
}
+ else
+ {
+ console.warn('Phaser.Cache.getTilemapData: Invalid key: "' + key + '"');
+ }
- return null;
},
/**
* Get frame data by key.
*
* @method Phaser.Cache#getFrameData
- * @param {string} key - Asset key of the frame data you want.
- * @return {Phaser.FrameData} The frame data you want.
+ * @param {string} key - Asset key of the frame data to retrieve from the Cache.
+ * @return {Phaser.FrameData} The frame data.
*/
getFrameData: function (key) {
@@ -30640,8 +33630,8 @@ Phaser.Cache.prototype = {
* Get a single frame out of a frameData set by key.
*
* @method Phaser.Cache#getFrameByIndex
- * @param {string} key - Asset key of the frame data you want.
- * @return {Phaser.Frame} The frame data you want.
+ * @param {string} key - Asset key of the frame data to retrieve from the Cache.
+ * @return {Phaser.Frame} The frame object.
*/
getFrameByIndex: function (key, frame) {
@@ -30657,8 +33647,8 @@ Phaser.Cache.prototype = {
* Get a single frame out of a frameData set by key.
*
* @method Phaser.Cache#getFrameByName
- * @param {string} key - Asset key of the frame data you want.
- * @return {Phaser.Frame} The frame data you want.
+ * @param {string} key - Asset key of the frame data to retrieve from the Cache.
+ * @return {Phaser.Frame} The frame object.
*/
getFrameByName: function (key, frame) {
@@ -30674,8 +33664,8 @@ Phaser.Cache.prototype = {
* Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.
*
* @method Phaser.Cache#getFrame
- * @param {string} key - Asset key of the frame data you want.
- * @return {Phaser.Frame} The frame data you want.
+ * @param {string} key - Asset key of the frame data to retrieve from the Cache.
+ * @return {Phaser.Frame} The frame data.
*/
getFrame: function (key) {
@@ -30688,11 +33678,11 @@ Phaser.Cache.prototype = {
},
/**
- * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.
+ * Get a single texture frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.
*
* @method Phaser.Cache#getTextureFrame
- * @param {string} key - Asset key of the frame data you want.
- * @return {Phaser.Frame} The frame data you want.
+ * @param {string} key - Asset key of the frame to retrieve from the Cache.
+ * @return {Phaser.Frame} The frame data.
*/
getTextureFrame: function (key) {
@@ -30708,8 +33698,8 @@ Phaser.Cache.prototype = {
* Get a RenderTexture by key.
*
* @method Phaser.Cache#getTexture
- * @param {string} key - Asset key of the RenderTexture you want.
- * @return {Phaser.RenderTexture} The RenderTexture you want.
+ * @param {string} key - Asset key of the RenderTexture to retrieve from the Cache.
+ * @return {Phaser.RenderTexture} The RenderTexture object.
*/
getTexture: function (key) {
@@ -30717,8 +33707,10 @@ Phaser.Cache.prototype = {
{
return this._textures[key];
}
-
- return null;
+ else
+ {
+ console.warn('Phaser.Cache.getTexture: Invalid key: "' + key + '"');
+ }
},
@@ -30726,8 +33718,8 @@ Phaser.Cache.prototype = {
* Get sound by key.
*
* @method Phaser.Cache#getSound
- * @param {string} key - Asset key of the sound you want.
- * @return {Phaser.Sound} The sound you want.
+ * @param {string} key - Asset key of the sound to retrieve from the Cache.
+ * @return {Phaser.Sound} The sound object.
*/
getSound: function (key) {
@@ -30735,8 +33727,10 @@ Phaser.Cache.prototype = {
{
return this._sounds[key];
}
-
- return null;
+ else
+ {
+ console.warn('Phaser.Cache.getSound: Invalid key: "' + key + '"');
+ }
},
@@ -30744,8 +33738,8 @@ Phaser.Cache.prototype = {
* Get sound data by key.
*
* @method Phaser.Cache#getSoundData
- * @param {string} key - Asset key of the sound you want.
- * @return {object} The sound data you want.
+ * @param {string} key - Asset key of the sound to retrieve from the Cache.
+ * @return {object} The sound data.
*/
getSoundData: function (key) {
@@ -30753,8 +33747,10 @@ Phaser.Cache.prototype = {
{
return this._sounds[key].data;
}
-
- return null;
+ else
+ {
+ console.warn('Phaser.Cache.getSoundData: Invalid key: "' + key + '"');
+ }
},
@@ -30762,7 +33758,7 @@ Phaser.Cache.prototype = {
* Check if the given sound has finished decoding.
*
* @method Phaser.Cache#isSoundDecoded
- * @param {string} key - Asset key of the sound you want.
+ * @param {string} key - Asset key of the sound in the Cache.
* @return {boolean} The decoded state of the Sound object.
*/
isSoundDecoded: function (key) {
@@ -30778,7 +33774,7 @@ Phaser.Cache.prototype = {
* Check if the given sound is ready for playback. A sound is considered ready when it has finished decoding and the device is no longer touch locked.
*
* @method Phaser.Cache#isSoundReady
- * @param {string} key - Asset key of the sound you want.
+ * @param {string} key - Asset key of the sound in the Cache.
* @return {boolean} True if the sound is decoded and the device is not touch locked.
*/
isSoundReady: function (key) {
@@ -30809,8 +33805,8 @@ Phaser.Cache.prototype = {
* Get text data by key.
*
* @method Phaser.Cache#getText
- * @param {string} key - Asset key of the text data you want.
- * @return {object} The text data you want.
+ * @param {string} key - Asset key of the text data to retrieve from the Cache.
+ * @return {object} The text data.
*/
getText: function (key) {
@@ -30818,8 +33814,30 @@ Phaser.Cache.prototype = {
{
return this._text[key].data;
}
+ else
+ {
+ console.warn('Phaser.Cache.getText: Invalid key: "' + key + '"');
+ }
+
+ },
- return null;
+ /**
+ * Get binary data by key.
+ *
+ * @method Phaser.Cache#getBinary
+ * @param {string} key - Asset key of the binary data object to retrieve from the Cache.
+ * @return {object} The binary data object.
+ */
+ getBinary: function (key) {
+
+ if (this._binary[key])
+ {
+ return this._binary[key];
+ }
+ else
+ {
+ console.warn('Phaser.Cache.getBinary: Invalid key: "' + key + '"');
+ }
},
@@ -30837,7 +33855,7 @@ Phaser.Cache.prototype = {
for (var item in array)
{
- if (item !== '__default')
+ if (item !== '__default' && item !== '__missing')
{
output.push(item);
}
@@ -30947,9 +33965,11 @@ Phaser.Cache.prototype = {
};
+Phaser.Cache.prototype.constructor = Phaser.Cache;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -30983,7 +34003,7 @@ Phaser.Loader = function (game) {
this._fileIndex = 0;
/**
- * @property {number} _progressChunk - Indicates assets loading progress. (from 0 to 100)
+ * @property {number} _progressChunk - Indicates the size of 1 file in terms of a percentage out of 100.
* @private
* @default
*/
@@ -31008,11 +34028,17 @@ Phaser.Loader = function (game) {
this.hasLoaded = false;
/**
- * @property {number} progress - The Load progress percentage value (from 0 to 100)
+ * @property {number} progress - The rounded load progress percentage value (from 0 to 100)
* @default
*/
this.progress = 0;
+ /**
+ * @property {number} progressFloat - The non-rounded load progress value (from 0.0 to 100.0)
+ * @default
+ */
+ this.progressFloat = 0;
+
/**
* You can optionally link a sprite to the preloader.
* If you do so the Sprite's width or height will be cropped based on the percentage loaded.
@@ -31312,6 +34338,29 @@ Phaser.Loader.prototype = {
},
+ /**
+ * Add a binary file to the Loader. It will be loaded via xhr with a responseType of "arraybuffer". You can specify an optional callback to process the file after load.
+ * When the callback is called it will be passed 2 parameters: the key of the file and the file data.
+ * WARNING: If you specify a callback, the file data will be set to whatever your callback returns. So always return the data object, even if you didn't modify it.
+ *
+ * @method Phaser.Loader#binary
+ * @param {string} key - Unique asset key of the binary file.
+ * @param {string} url - URL of the binary file.
+ * @param {function} [callback] - Optional callback that will be passed the file after loading, so you can perform additional processing on it.
+ * @param {function} [callbackContext] - The context under which the callback will be applied. If not specified it will use the callback itself as the context.
+ * @return {Phaser.Loader} This Loader instance.
+ */
+ binary: function (key, url, callback, callbackContext) {
+
+ if (typeof callback === 'undefined') { callback = false; }
+ if (callback !== false && typeof callbackContext === 'undefined') { callbackContext = callback; }
+
+ this.addToFileList('binary', key, url, { callback: callback, callbackContext: callbackContext });
+
+ return this;
+
+ },
+
/**
* Add a new sprite sheet to the loader.
*
@@ -31321,38 +34370,17 @@ Phaser.Loader.prototype = {
* @param {number} frameWidth - Width of each single frame.
* @param {number} frameHeight - Height of each single frame.
* @param {number} [frameMax=-1] - How many frames in this sprite sheet. If not specified it will divide the whole image into frames.
+ * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
+ * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
* @return {Phaser.Loader} This Loader instance.
*/
- spritesheet: function (key, url, frameWidth, frameHeight, frameMax) {
+ spritesheet: function (key, url, frameWidth, frameHeight, frameMax, margin, spacing) {
if (typeof frameMax === "undefined") { frameMax = -1; }
+ if (typeof margin === "undefined") { margin = 0; }
+ if (typeof spacing === "undefined") { spacing = 0; }
- this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax });
-
- return this;
-
- },
-
- /**
- * Add a new tile set to the loader. These are used in the rendering of tile maps.
- *
- * @method Phaser.Loader#tileset
- * @param {string} key - Unique asset key of the tileset file.
- * @param {string} url - URL of the tileset.
- * @param {number} tileWidth - Width of each single tile in pixels.
- * @param {number} tileHeight - Height of each single tile in pixels.
- * @param {number} [tileMax=-1] - How many tiles in this tileset. If not specified it will divide the whole image into tiles.
- * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
- * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
- * @return {Phaser.Loader} This Loader instance.
- */
- tileset: function (key, url, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
-
- if (typeof tileMax === "undefined") { tileMax = -1; }
- if (typeof tileMargin === "undefined") { tileMargin = 0; }
- if (typeof tileSpacing === "undefined") { tileSpacing = 0; }
-
- this.addToFileList('tileset', key, url, { tileWidth: tileWidth, tileHeight: tileHeight, tileMax: tileMax, tileMargin: tileMargin, tileSpacing: tileSpacing });
+ this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax, margin: margin, spacing: spacing });
return this;
@@ -31660,6 +34688,7 @@ Phaser.Loader.prototype = {
}
this.progress = 0;
+ this.progressFloat = 0;
this.hasLoaded = false;
this.isLoading = true;
@@ -31674,6 +34703,7 @@ Phaser.Loader.prototype = {
else
{
this.progress = 100;
+ this.progressFloat = 100;
this.hasLoaded = true;
this.onLoadComplete.dispatch();
}
@@ -31704,7 +34734,6 @@ Phaser.Loader.prototype = {
case 'spritesheet':
case 'textureatlas':
case 'bitmapfont':
- case 'tileset':
file.data = new Image();
file.data.name = file.key;
file.data.onload = function () {
@@ -31795,6 +34824,7 @@ Phaser.Loader.prototype = {
break;
case 'text':
+ case 'script':
this._xhr.open("GET", this.baseURL + file.url, true);
this._xhr.responseType = "text";
this._xhr.onload = function () {
@@ -31806,10 +34836,9 @@ Phaser.Loader.prototype = {
this._xhr.send();
break;
- case 'script':
-
+ case 'binary':
this._xhr.open("GET", this.baseURL + file.url, true);
- this._xhr.responseType = "text";
+ this._xhr.responseType = "arraybuffer";
this._xhr.onload = function () {
return _this.fileComplete(_this._fileIndex);
};
@@ -31882,7 +34911,6 @@ Phaser.Loader.prototype = {
console.warn('Phaser.Loader fileComplete invalid index ' + index);
return;
}
-
var file = this._fileList[index];
file.loaded = true;
@@ -31899,12 +34927,7 @@ Phaser.Loader.prototype = {
case 'spritesheet':
- this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax);
- break;
-
- case 'tileset':
-
- this.game.cache.addTileset(file.key, file.url, file.data, file.tileWidth, file.tileHeight, file.tileMax, file.tileMargin, file.tileSpacing);
+ this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax, file.margin, file.spacing);
break;
case 'textureatlas':
@@ -31987,6 +35010,7 @@ Phaser.Loader.prototype = {
if (buffer)
{
that.game.cache.decodedSound(key, buffer);
+ that.game.sound.onSoundDecode.dispatch(key, that.game.cache.getSound(key));
}
});
}
@@ -32011,6 +35035,20 @@ Phaser.Loader.prototype = {
file.data.text = this._xhr.responseText;
document.head.appendChild(file.data);
break;
+
+ case 'binary':
+ if (file.callback)
+ {
+ file.data = file.callback.call(file.callbackContext, file.key, this._xhr.response);
+ }
+ else
+ {
+ file.data = this._xhr.response;
+ }
+
+ this.game.cache.addBinary(file.key, file.data);
+
+ break;
}
if (loadNext)
@@ -32156,7 +35194,8 @@ Phaser.Loader.prototype = {
*/
nextFile: function (previousIndex, success) {
- this.progress = Math.round(this.progress + this._progressChunk);
+ this.progressFloat += this._progressChunk;
+ this.progress = Math.round(this.progressFloat);
if (this.progress > 100)
{
@@ -32240,9 +35279,11 @@ Phaser.Loader.prototype = {
};
+Phaser.Loader.prototype.constructor = Phaser.Loader;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -32325,7 +35366,7 @@ Phaser.LoaderParser = {
};
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -32671,25 +35712,25 @@ Phaser.Sound.prototype = {
{
if (this.loop)
{
- //console.log('loop1');
+ // console.log('loop1');
// won't work with markers, needs to reset the position
this.onLoop.dispatch(this);
if (this.currentMarker === '')
{
- //console.log('loop2');
+ // console.log('loop2');
this.currentTime = 0;
this.startTime = this.game.time.now;
}
else
{
- //console.log('loop3');
+ // console.log('loop3');
this.play(this.currentMarker, 0, this.volume, true, true);
}
}
else
{
- //console.log('stopping, no loop for marker');
+ // console.log('stopping, no loop for marker');
this.stop();
}
}
@@ -32877,7 +35918,7 @@ Phaser.Sound.prototype = {
else
{
// console.log('sound not locked, state?', this._sound.readyState);
- if (this._sound && this._sound.readyState == 4)
+ if (this._sound && (this.game.device.cocoonJS || this._sound.readyState === 4))
{
this._sound.play();
// This doesn't become available until you call play(), wonderful ...
@@ -32967,7 +36008,20 @@ Phaser.Sound.prototype = {
this._sound = this.context.createBufferSource();
this._sound.buffer = this._buffer;
- this._sound.connect(this.gainNode);
+
+ if (this.externalNode)
+ {
+ this._sound.connect(this.externalNode.input);
+ }
+ else
+ {
+ this._sound.connect(this.gainNode);
+ }
+
+ if (this.loop)
+ {
+ this._sound.loop = true;
+ }
if (typeof this._sound.start === 'undefined')
{
@@ -33028,6 +36082,8 @@ Phaser.Sound.prototype = {
};
+Phaser.Sound.prototype.constructor = Phaser.Sound;
+
/**
* @name Phaser.Sound#isDecoding
* @property {boolean} isDecoding - Returns true if the sound file is still decoding.
@@ -33136,7 +36192,7 @@ Object.defineProperty(Phaser.Sound.prototype, "volume", {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -33424,7 +36480,7 @@ Phaser.SoundManager.prototype = {
that.game.cache.decodedSound(key, buffer);
if (sound)
{
- that.onSoundDecode.dispatch(sound);
+ that.onSoundDecode.dispatch(key, sound);
}
});
}
@@ -33505,6 +36561,8 @@ Phaser.SoundManager.prototype = {
};
+Phaser.SoundManager.prototype.constructor = Phaser.SoundManager;
+
/**
* @name Phaser.SoundManager#mute
* @property {boolean} mute - Gets or sets the muted state of the SoundManager. This effects all sounds in the game.
@@ -33617,7 +36675,7 @@ Object.defineProperty(Phaser.SoundManager.prototype, "volume", {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -33647,6 +36705,11 @@ Phaser.Utils.Debug = function (game) {
*/
this.font = '14px Courier';
+ /**
+ * @property {number} columnWidth - The spacing between columns.
+ */
+ this.columnWidth = 100;
+
/**
* @property {number} lineHeight - The line height between the debug text.
*/
@@ -33682,11 +36745,12 @@ Phaser.Utils.Debug.prototype = {
/**
* Internal method that resets and starts the debug output values.
* @method Phaser.Utils.Debug#start
- * @param {number} x - The X value the debug info will start from.
- * @param {number} y - The Y value the debug info will start from.
- * @param {string} color - The color the debug info will drawn in.
+ * @param {number} [x=0] - The X value the debug info will start from.
+ * @param {number} [y=0] - The Y value the debug info will start from.
+ * @param {string} [color='rgb(255,255,255)'] - The color the debug text will drawn in.
+ * @param {number} [columnWidth=0] - The spacing between columns.
*/
- start: function (x, y, color) {
+ start: function (x, y, color, columnWidth) {
if (this.context == null)
{
@@ -33695,16 +36759,18 @@ Phaser.Utils.Debug.prototype = {
if (typeof x !== 'number') { x = 0; }
if (typeof y !== 'number') { y = 0; }
-
color = color || 'rgb(255,255,255)';
+ if (typeof columnWidth === 'undefined') { columnWidth = 0; }
this.currentX = x;
this.currentY = y;
this.currentColor = color;
this.currentAlpha = this.context.globalAlpha;
+ this.columnWidth = columnWidth;
this.context.save();
this.context.setTransform(1, 0, 0, 1, 0, 0);
+ this.context.strokeStyle = color;
this.context.fillStyle = color;
this.context.font = this.font;
this.context.globalAlpha = 1;
@@ -33717,7 +36783,6 @@ Phaser.Utils.Debug.prototype = {
*/
stop: function () {
-
this.context.restore();
this.context.globalAlpha = this.currentAlpha;
@@ -33727,8 +36792,8 @@ Phaser.Utils.Debug.prototype = {
* Internal method that outputs a single line of text.
* @method Phaser.Utils.Debug#line
* @param {string} text - The line of text to draw.
- * @param {number} x - The X value the debug info will start from.
- * @param {number} y - The Y value the debug info will start from.
+ * @param {number} [x] - The X value the debug info will start from.
+ * @param {number} [y] - The Y value the debug info will start from.
*/
line: function (text, x, y) {
@@ -33737,16 +36802,8 @@ Phaser.Utils.Debug.prototype = {
return;
}
- x = x || null;
- y = y || null;
-
- if (x !== null) {
- this.currentX = x;
- }
-
- if (y !== null) {
- this.currentY = y;
- }
+ if (typeof x !== 'undefined') { this.currentX = x; }
+ if (typeof y !== 'undefined') { this.currentY = y; }
if (this.renderShadow)
{
@@ -33760,6 +36817,38 @@ Phaser.Utils.Debug.prototype = {
},
+ /**
+ * Internal method that outputs a single line of text split over as many columns as needed, one per parameter.
+ * @method Phaser.Utils.Debug#splitline
+ * @param {string} text - The text to render. You can have as many columns of text as you want, just pass them as additional parameters.
+ */
+ splitline: function (text) {
+
+ if (this.context == null)
+ {
+ return;
+ }
+
+ var x = this.currentX;
+
+ for (var i = 0; i < arguments.length; i++)
+ {
+ if (this.renderShadow)
+ {
+ this.context.fillStyle = 'rgb(0,0,0)';
+ this.context.fillText(arguments[i], x + 1, this.currentY + 1);
+ this.context.fillStyle = this.currentColor;
+ }
+
+ this.context.fillText(arguments[i], x, this.currentY);
+
+ x += this.columnWidth;
+ }
+
+ this.currentY += this.lineHeight;
+
+ },
+
/**
* Visually renders a QuadTree to the display.
* @method Phaser.Utils.Debug#renderQuadTree
@@ -34005,25 +37094,27 @@ Phaser.Utils.Debug.prototype = {
},
/**
- * Render Sprite collision.
- * @method Phaser.Utils.Debug#renderSpriteCollision
+ * Render Sprite Body Physics Data as text.
+ * @method Phaser.Utils.Debug#renderBodyInfo
* @param {Phaser.Sprite} sprite - The sprite to be rendered.
* @param {number} x - X position of the debug info to be rendered.
* @param {number} y - Y position of the debug info to be rendered.
* @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
*/
- renderSpriteCollision: function (sprite, x, y, color) {
+ renderBodyInfo: function (sprite, x, y, color) {
color = color || 'rgb(255,255,255)';
- this.start(x, y, color);
- this.line('Sprite Collision: (' + sprite.width + ' x ' + sprite.height + ')');
- this.line('left: ' + sprite.body.touching.left);
- this.line('right: ' + sprite.body.touching.right);
- this.line('up: ' + sprite.body.touching.up);
- this.line('down: ' + sprite.body.touching.down);
- this.line('velocity.x: ' + sprite.body.velocity.x);
- this.line('velocity.y: ' + sprite.body.velocity.y);
+ this.start(x, y, color, 210);
+
+ this.splitline('x: ' + sprite.body.x.toFixed(2), 'y: ' + sprite.body.y.toFixed(2), 'width: ' + sprite.width, 'height: ' + sprite.height);
+ this.splitline('speed: ' + sprite.body.speed.toFixed(2), 'angle: ' + sprite.body.angle.toFixed(2), 'linear damping: ' + sprite.body.linearDamping);
+ this.splitline('blocked left: ' + sprite.body.blocked.left, 'right: ' + sprite.body.blocked.right, 'up: ' + sprite.body.blocked.up, 'down: ' + sprite.body.blocked.down);
+ this.splitline('touching left: ' + sprite.body.touching.left, 'right: ' + sprite.body.touching.right, 'up: ' + sprite.body.touching.up, 'down: ' + sprite.body.touching.down);
+ this.splitline('gravity x: ' + sprite.body.gravity.x, 'y: ' + sprite.body.gravity.y, 'world gravity x: ' + this.game.physics.gravity.x, 'y: ' + this.game.physics.gravity.y);
+ this.splitline('acceleration x: ' + sprite.body.acceleration.x.toFixed(2), 'y: ' + sprite.body.acceleration.y.toFixed(2));
+ this.splitline('velocity x: ' + sprite.body.velocity.x.toFixed(2), 'y: ' + sprite.body.velocity.y.toFixed(2), 'deltaX: ' + sprite.body.deltaX().toFixed(2), 'deltaY: ' + sprite.body.deltaY().toFixed(2));
+ this.splitline('bounce x: ' + sprite.body.bounce.x.toFixed(2), 'y: ' + sprite.body.bounce.y.toFixed(2));
this.stop();
},
@@ -34086,17 +37177,15 @@ Phaser.Utils.Debug.prototype = {
// 4 = scaleY
// 5 = translateY
- // this.line('id: ' + sprite._id);
- // this.line('scale x: ' + sprite.worldTransform[0]);
- // this.line('scale y: ' + sprite.worldTransform[4]);
- // this.line('tx: ' + sprite.worldTransform[2]);
- // this.line('ty: ' + sprite.worldTransform[5]);
- // this.line('skew x: ' + sprite.worldTransform[3]);
- // this.line('skew y: ' + sprite.worldTransform[1]);
- this.line('deltaX: ' + sprite.body.deltaX());
- this.line('deltaY: ' + sprite.body.deltaY());
- // this.line('sdx: ' + sprite.deltaX());
- // this.line('sdy: ' + sprite.deltaY());
+ this.line('id: ' + sprite._id);
+ this.line('scale x: ' + sprite.worldTransform[0]);
+ this.line('scale y: ' + sprite.worldTransform[4]);
+ this.line('tx: ' + sprite.worldTransform[2]);
+ this.line('ty: ' + sprite.worldTransform[5]);
+ this.line('skew x: ' + sprite.worldTransform[3]);
+ this.line('skew y: ' + sprite.worldTransform[1]);
+ this.line('sdx: ' + sprite.deltaX);
+ this.line('sdy: ' + sprite.deltaY);
// this.line('inCamera: ' + this.game.renderer.spriteRenderer.inCamera(this.game.camera, sprite));
this.stop();
@@ -34104,65 +37193,13 @@ Phaser.Utils.Debug.prototype = {
},
/**
- * Render the World Transform information of the given Sprite.
- * @method Phaser.Utils.Debug#renderWorldTransformInfo
- * @param {Phaser.Sprite} sprite - Description.
+ * Renders the sprite coordinates in local, positional and world space.
+ * @method Phaser.Utils.Debug#renderSpriteCoords
+ * @param {Phaser.Sprite} line - The sprite to inspect.
* @param {number} x - X position of the debug info to be rendered.
* @param {number} y - Y position of the debug info to be rendered.
* @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
*/
- renderWorldTransformInfo: function (sprite, x, y, color) {
-
- if (this.context == null)
- {
- return;
- }
-
- color = color || 'rgb(255, 255, 255)';
-
- this.start(x, y, color);
-
- this.line('World Transform');
- this.line('skewX: ' + sprite.worldTransform[3]);
- this.line('skewY: ' + sprite.worldTransform[1]);
- this.line('scaleX: ' + sprite.worldTransform[0]);
- this.line('scaleY: ' + sprite.worldTransform[4]);
- this.line('transX: ' + sprite.worldTransform[2]);
- this.line('transY: ' + sprite.worldTransform[5]);
- this.stop();
-
- },
-
- /**
- * Render the Local Transform information of the given Sprite.
- * @method Phaser.Utils.Debug#renderLocalTransformInfo
- * @param {Phaser.Sprite} sprite - Description.
- * @param {number} x - X position of the debug info to be rendered.
- * @param {number} y - Y position of the debug info to be rendered.
- * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
- */
- renderLocalTransformInfo: function (sprite, x, y, color) {
-
- if (this.context == null)
- {
- return;
- }
-
- color = color || 'rgb(255, 255, 255)';
-
- this.start(x, y, color);
-
- this.line('Local Transform');
- this.line('skewX: ' + sprite.localTransform[3]);
- this.line('skewY: ' + sprite.localTransform[1]);
- this.line('scaleX: ' + sprite.localTransform[0]);
- this.line('scaleY: ' + sprite.localTransform[4]);
- this.line('transX: ' + sprite.localTransform[2]);
- this.line('transY: ' + sprite.localTransform[5]);
- this.stop();
-
- },
-
renderSpriteCoords: function (sprite, x, y, color) {
if (this.context == null)
@@ -34172,29 +37209,28 @@ Phaser.Utils.Debug.prototype = {
color = color || 'rgb(255, 255, 255)';
- this.start(x, y, color);
+ this.start(x, y, color, 100);
if (sprite.name)
{
this.line(sprite.name);
}
- this.line('x: ' + sprite.x);
- this.line('y: ' + sprite.y);
- this.line('pos x: ' + sprite.position.x);
- this.line('pos y: ' + sprite.position.y);
- this.line('local x: ' + sprite.localTransform[2]);
- this.line('local y: ' + sprite.localTransform[5]);
- this.line('t x: ' + sprite.worldTransform[2]);
- this.line('t y: ' + sprite.worldTransform[5]);
- this.line('world x: ' + sprite.world.x);
- this.line('world y: ' + sprite.world.y);
+ this.splitline('x:', sprite.x.toFixed(2), 'y:', sprite.y.toFixed(2));
+ this.splitline('pos x:', sprite.position.x.toFixed(2), 'pos y:', sprite.position.y.toFixed(2));
+ this.splitline('world x:', sprite.world.x.toFixed(2), 'world y:', sprite.world.y.toFixed(2));
this.stop();
},
- renderGroupInfo: function (group, x, y, color) {
+ /**
+ * Renders a Line object in the given color.
+ * @method Phaser.Utils.Debug#renderLine
+ * @param {Phaser.Line} line - The Line to render.
+ * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
+ */
+ renderLine: function (line, color) {
if (this.context == null)
{
@@ -34203,12 +37239,38 @@ Phaser.Utils.Debug.prototype = {
color = color || 'rgb(255, 255, 255)';
- this.start(x, y, color);
+ this.start(0, 0, color);
+ this.context.lineWidth = 1;
+ this.context.beginPath();
+ this.context.moveTo(line.start.x + 0.5, line.start.y + 0.5);
+ this.context.lineTo(line.end.x + 0.5, line.end.y + 0.5);
+ this.context.closePath();
+ this.context.stroke();
+ this.stop();
- this.line('Group (size: ' + group.length + ')');
- this.line('x: ' + group.x);
- this.line('y: ' + group.y);
+ },
+ /**
+ * Renders Line information in the given color.
+ * @method Phaser.Utils.Debug#renderLineInfo
+ * @param {Phaser.Line} line - The Line to render.
+ * @param {number} x - X position of the debug info to be rendered.
+ * @param {number} y - Y position of the debug info to be rendered.
+ * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
+ */
+ renderLineInfo: function (line, x, y, color) {
+
+ if (this.context == null)
+ {
+ return;
+ }
+
+ color = color || 'rgb(255, 255, 255)';
+
+ this.start(x, y, color, 80);
+ this.splitline('start.x:', line.start.x.toFixed(2), 'start.y:', line.start.y.toFixed(2));
+ this.splitline('end.x:', line.end.x.toFixed(2), 'end.y:', line.end.y.toFixed(2));
+ this.splitline('length:', line.length.toFixed(2), 'angle:', line.angle);
this.stop();
},
@@ -34237,24 +37299,36 @@ Phaser.Utils.Debug.prototype = {
},
/**
- * Renders just the Sprite.body bounds.
- * @method Phaser.Utils.Debug#renderSpriteBody
+ * Renders just the full Sprite bounds.
+ * @method Phaser.Utils.Debug#renderSpriteBounds
* @param {Phaser.Sprite} sprite - Description.
* @param {string} [color] - Color of the debug info to be rendered (format is css color string).
+ * @param {boolean} [fill=false] - If false the bounds outline is rendered, if true the whole rectangle is rendered.
*/
- renderSpriteBody: function (sprite, color) {
+ renderSpriteBody: function (sprite, color, fill) {
if (this.context == null)
{
return;
}
- color = color || 'rgba(255,0,255, 0.3)';
+ color = color || 'rgb(255,0,255)';
+
+ if (typeof fill === 'undefined') { fill = false; }
this.start(0, 0, color);
- this.context.fillStyle = color;
- this.context.fillRect(sprite.body.screenX, sprite.body.screenY, sprite.body.width, sprite.body.height);
+ if (fill)
+ {
+ this.context.fillStyle = color;
+ this.context.fillRect(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height);
+ }
+ else
+ {
+ this.context.strokeStyle = color;
+ this.context.strokeRect(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height);
+ this.context.stroke();
+ }
this.stop();
@@ -34416,90 +37490,114 @@ Phaser.Utils.Debug.prototype = {
},
/**
- * Dumps the Linked List to the console.
- *
- * @method Phaser.Utils.Debug#Phaser.LinkedList#dump
- * @param {Phaser.LinkedList} list - The LinkedList to dump.
+ * @method Phaser.Utils.Debug#renderPhysicsBody
+ * @param {array} body
+ * @param {string} [color='rgb(255,255,255)'] - The color the polygon is stroked in.
*/
- dumpLinkedList: function (list) {
+ renderPhysicsBody: function (body, color, context) {
- var spacing = 20;
-
- var output = "\n" + Phaser.Utils.pad('Node', spacing) + "|" + Phaser.Utils.pad('Next', spacing) + "|" + Phaser.Utils.pad('Previous', spacing) + "|" + Phaser.Utils.pad('First', spacing) + "|" + Phaser.Utils.pad('Last', spacing);
- console.log(output);
-
- var output = Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing);
- console.log(output);
-
- var entity = list;
-
- var testObject = entity.last.next;
- entity = entity.first;
-
- do
+ if (this.context === null && context === null)
{
- var name = entity.sprite.name || '*';
- var nameNext = '-';
- var namePrev = '-';
- var nameFirst = '-';
- var nameLast = '-';
-
- if (entity.next)
- {
- nameNext = entity.next.sprite.name;
- }
-
- if (entity.prev)
- {
- namePrev = entity.prev.sprite.name;
- }
-
- if (entity.first)
- {
- nameFirst = entity.first.sprite.name;
- }
-
- if (entity.last)
- {
- nameLast = entity.last.sprite.name;
- }
-
- if (typeof nameNext === 'undefined')
- {
- nameNext = '-';
- }
-
- if (typeof namePrev === 'undefined')
- {
- namePrev = '-';
- }
-
- if (typeof nameFirst === 'undefined')
- {
- nameFirst = '-';
- }
-
- if (typeof nameLast === 'undefined')
- {
- nameLast = '-';
- }
-
- var output = Phaser.Utils.pad(name, spacing) + "|" + Phaser.Utils.pad(nameNext, spacing) + "|" + Phaser.Utils.pad(namePrev, spacing) + "|" + Phaser.Utils.pad(nameFirst, spacing) + "|" + Phaser.Utils.pad(nameLast, spacing);
- console.log(output);
-
- entity = entity.next;
-
+ return;
}
- while(entity != testObject)
+
+ color = color || 'rgb(255,255,255)';
+
+ var x = body.x - this.game.camera.x;
+ var y = body.y - this.game.camera.y;
+
+ if (body.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ this.start(0, 0, color);
+ this.context.beginPath();
+ this.context.strokeStyle = color;
+ this.context.arc(x, y, body.shape.r, 0, Math.PI * 2, false);
+ this.context.stroke();
+ this.context.closePath();
+
+ // this.context.strokeStyle = 'rgb(0,0,255)';
+ // this.context.strokeRect(body.left, body.top, body.width, body.height);
+
+ this.stop();
+ }
+ else
+ {
+ var points = body.polygon.points;
+
+ this.start(0, 0, color);
+
+ this.context.beginPath();
+ this.context.moveTo(x + points[0].x, y + points[0].y);
+
+ for (var i = 1; i < points.length; i++)
+ {
+ this.context.lineTo(x + points[i].x, y + points[i].y);
+ }
+
+ this.context.closePath();
+ this.context.strokeStyle = color;
+ this.context.stroke();
+
+ this.context.fillStyle = 'rgb(255,0,0)';
+ this.context.fillRect(x + points[0].x - 2, y + points[0].y - 2, 5, 5);
+
+ for (var i = 1; i < points.length; i++)
+ {
+ this.context.fillStyle = 'rgb(255,' + (i * 40) + ',0)';
+ this.context.fillRect(x + points[i].x - 2, y + points[i].y - 2, 5, 5);
+ }
+
+ // this.context.strokeStyle = 'rgb(0,255,255)';
+ // this.context.strokeRect(body.left, body.top, body.width, body.height);
+
+ this.stop();
+ }
+
+ },
+
+ /**
+ * @method Phaser.Utils.Debug#renderPolygon
+ * @param {array} polygon
+ * @param {string} [color='rgb(255,255,255)'] - The color the polygon is stroked in.
+ */
+ renderPolygon: function (polygon, color, context) {
+
+ if (this.context === null && context === null)
+ {
+ return;
+ }
+
+ color = color || 'rgb(255,255,255)';
+
+ var points = polygon.points;
+ var x = polygon.pos.x;
+ var y = polygon.pos.y;
+
+ this.start(0, 0, color);
+
+ this.context.beginPath();
+ this.context.moveTo(x + points[0].x, y + points[0].y);
+
+ for (var i = 1; i < points.length; i++)
+ {
+ this.context.lineTo(x + points[i].x, y + points[i].y);
+ }
+
+ this.context.closePath();
+ this.context.strokeStyle = color;
+ this.context.stroke();
+
+ this.stop();
}
-
};
+Phaser.Utils.Debug.prototype.constructor = Phaser.Utils.Debug;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -34849,9 +37947,871 @@ Phaser.Color = {
};
+// Version 0.2 - Copyright 2013 - Jim Riecken
+//
+// Released under the MIT License - https://github.com/jriecken/sat-js
+//
+// A simple library for determining intersections of circles and
+// polygons using the Separating Axis Theorem.
+/** @preserve SAT.js - Version 0.2 - Copyright 2013 - Jim Riecken - released under the MIT License. https://github.com/jriecken/sat-js */
+
+/*global define: false, module: false*/
+/*jshint shadow:true, sub:true, forin:true, noarg:true, noempty:true,
+ eqeqeq:true, bitwise:true, strict:true, undef:true,
+ curly:true, browser:true */
+
+// Create a UMD wrapper for SAT. Works in:
+//
+// - Plain browser via global SAT variable
+// - AMD loader (like require.js)
+// - Node.js
+//
+// The quoted properties all over the place are used so that the Closure Compiler
+// does not mangle the exposed API in advanced mode.
+/**
+ * @param {*} root - The global scope
+ * @param {Function} factory - Factory that creates SAT module
+ */
+(function (root, factory) {
+ "use strict";
+ if (typeof define === 'function' && define['amd']) {
+ define(factory);
+ } else if (typeof exports === 'object') {
+ module['exports'] = factory();
+ } else {
+ root['SAT'] = factory();
+ }
+}(this, function () {
+ "use strict";
+
+ var SAT = {};
+
+ //
+ // ## Vector
+ //
+ // Represents a vector in two dimensions with `x` and `y` properties.
+
+
+ // Create a new Vector, optionally passing in the `x` and `y` coordinates. If
+ // a coordinate is not specified, it will be set to `0`
+ /**
+ * @param {?number=} x The x position.
+ * @param {?number=} y The y position.
+ * @constructor
+ */
+ function Vector(x, y) {
+ this['x'] = x || 0;
+ this['y'] = y || 0;
+ }
+ SAT['Vector'] = Vector;
+ // Alias `Vector` as `V`
+ SAT['V'] = Vector;
+
+
+ // Copy the values of another Vector into this one.
+ /**
+ * @param {Vector} other The other Vector.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['copy'] = Vector.prototype.copy = function(other) {
+ this['x'] = other['x'];
+ this['y'] = other['y'];
+ return this;
+ };
+
+ // Change this vector to be perpendicular to what it was before. (Effectively
+ // roatates it 90 degrees in a clockwise direction)
+ /**
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['perp'] = Vector.prototype.perp = function() {
+ var x = this['x'];
+ this['x'] = this['y'];
+ this['y'] = -x;
+ return this;
+ };
+
+ // Rotate this vector (counter-clockwise) by the specified angle (in radians).
+ /**
+ * @param {number} angle The angle to rotate (in radians)
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['rotate'] = Vector.prototype.rotate = function (angle) {
+ var x = this['x'];
+ var y = this['y'];
+ this['x'] = x * Math.cos(angle) - y * Math.sin(angle);
+ this['y'] = x * Math.sin(angle) + y * Math.cos(angle);
+ return this;
+ };
+
+ // Rotate this vector (counter-clockwise) by the specified angle (in radians) which has already been calculated into sin and cos.
+ /**
+ * @param {number} sin - The Math.sin(angle)
+ * @param {number} cos - The Math.cos(angle)
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['rotatePrecalc'] = Vector.prototype.rotatePrecalc = function (sin, cos) {
+ var x = this['x'];
+ var y = this['y'];
+ this['x'] = x * cos - y * sin;
+ this['y'] = x * sin + y * cos;
+ return this;
+ };
+
+ // Reverse this vector.
+ /**
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['reverse'] = Vector.prototype.reverse = function() {
+ this['x'] = -this['x'];
+ this['y'] = -this['y'];
+ return this;
+ };
+
+
+ // Normalize this vector. (make it have length of `1`)
+ /**
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['normalize'] = Vector.prototype.normalize = function() {
+ var d = this.len();
+ if(d > 0) {
+ this['x'] = this['x'] / d;
+ this['y'] = this['y'] / d;
+ }
+ return this;
+ };
+
+ // Add another vector to this one.
+ /**
+ * @param {Vector} other The other Vector.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['add'] = Vector.prototype.add = function(other) {
+ this['x'] += other['x'];
+ this['y'] += other['y'];
+ return this;
+ };
+
+ // Subtract another vector from this one.
+ /**
+ * @param {Vector} other The other Vector.
+ * @return {Vector} This for chaiing.
+ */
+ Vector.prototype['sub'] = Vector.prototype.sub = function(other) {
+ this['x'] -= other['x'];
+ this['y'] -= other['y'];
+ return this;
+ };
+
+ // Scale this vector. An independant scaling factor can be provided
+ // for each axis, or a single scaling factor that will scale both `x` and `y`.
+ /**
+ * @param {number} x The scaling factor in the x direction.
+ * @param {?number=} y The scaling factor in the y direction. If this
+ * is not specified, the x scaling factor will be used.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['scale'] = Vector.prototype.scale = function(x,y) {
+ this['x'] *= x;
+ this['y'] *= y || x;
+ return this;
+ };
+
+ // Project this vector on to another vector.
+ /**
+ * @param {Vector} other The vector to project onto.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['project'] = Vector.prototype.project = function(other) {
+ var amt = this.dot(other) / other.len2();
+ this['x'] = amt * other['x'];
+ this['y'] = amt * other['y'];
+ return this;
+ };
+
+ // Project this vector onto a vector of unit length. This is slightly more efficient
+ // than `project` when dealing with unit vectors.
+ /**
+ * @param {Vector} other The unit vector to project onto.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['projectN'] = Vector.prototype.projectN = function(other) {
+ var amt = this.dot(other);
+ this['x'] = amt * other['x'];
+ this['y'] = amt * other['y'];
+ return this;
+ };
+
+ // Reflect this vector on an arbitrary axis.
+ /**
+ * @param {Vector} axis The vector representing the axis.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['reflect'] = Vector.prototype.reflect = function(axis) {
+ var x = this['x'];
+ var y = this['y'];
+ this.project(axis).scale(2);
+ this['x'] -= x;
+ this['y'] -= y;
+ return this;
+ };
+
+ // Reflect this vector on an arbitrary axis (represented by a unit vector). This is
+ // slightly more efficient than `reflect` when dealing with an axis that is a unit vector.
+ /**
+ * @param {Vector} axis The unit vector representing the axis.
+ * @return {Vector} This for chaining.
+ */
+ Vector.prototype['reflectN'] = Vector.prototype.reflectN = function(axis) {
+ var x = this['x'];
+ var y = this['y'];
+ this.projectN(axis).scale(2);
+ this['x'] -= x;
+ this['y'] -= y;
+ return this;
+ };
+
+ // Get the dot product of this vector and another.
+ /**
+ * @param {Vector} other The vector to dot this one against.
+ * @return {number} The dot product.
+ */
+ Vector.prototype['dot'] = Vector.prototype.dot = function(other) {
+ return this['x'] * other['x'] + this['y'] * other['y'];
+ };
+
+ // Get the squared length of this vector.
+ /**
+ * @return {number} The length^2 of this vector.
+ */
+ Vector.prototype['len2'] = Vector.prototype.len2 = function() {
+ return this.dot(this);
+ };
+
+ // Get the length of this vector.
+ /**
+ * @return {number} The length of this vector.
+ */
+ Vector.prototype['len'] = Vector.prototype.len = function() {
+ return Math.sqrt(this.len2());
+ };
+
+ // ## Circle
+ //
+ // Represents a circle with a position and a radius.
+
+ // Create a new circle, optionally passing in a position and/or radius. If no position
+ // is given, the circle will be at `(0,0)`. If no radius is provided, the circle will
+ // have a radius of `0`.
+ /**
+ * @param {Vector=} pos A vector representing the position of the center of the circle
+ * @param {?number=} r The radius of the circle
+ * @constructor
+ */
+ function Circle(pos, r) {
+ this['pos'] = pos || new Vector();
+ this['r'] = r || 0;
+ }
+ SAT['Circle'] = Circle;
+
+ // ## Polygon
+ //
+ // Represents a *convex* polygon with any number of points (specified in counter-clockwise order)
+ //
+ // The edges/normals of the polygon will be calculated on creation and stored in the
+ // `edges` and `normals` properties. If you change the polygon's points, you will need
+ // to call `recalc` to recalculate the edges/normals.
+
+ // Create a new polygon, passing in a position vector, and an array of points (represented
+ // by vectors relative to the position vector). If no position is passed in, the position
+ // of the polygon will be `(0,0)`.
+ /**
+ * @param {Vector=} pos A vector representing the origin of the polygon. (all other
+ * points are relative to this one)
+ * @param {Array.=} points An array of vectors representing the points in the polygon,
+ * in counter-clockwise order.
+ * @constructor
+ */
+ function Polygon(pos, points) {
+ this['pos'] = pos || new Vector();
+ this['points'] = points || [];
+ this.recalc();
+ }
+ SAT['Polygon'] = Polygon;
+
+ // Recalculates the edges and normals of the polygon. This **must** be called
+ // if the `points` array is modified at all and the edges or normals are to be
+ // accessed.
+ /**
+ * @return {Polygon} This for chaining.
+ */
+ Polygon.prototype['recalc'] = Polygon.prototype.recalc = function() {
+ // The edges here are the direction of the `n`th edge of the polygon, relative to
+ // the `n`th point. If you want to draw a given edge from the edge value, you must
+ // first translate to the position of the starting point.
+ this['edges'] = [];
+ // The normals here are the direction of the normal for the `n`th edge of the polygon, relative
+ // to the position of the `n`th point. If you want to draw an edge normal, you must first
+ // translate to the position of the starting point.
+ this['normals'] = [];
+ var points = this['points'];
+ var len = points.length;
+ for (var i = 0; i < len; i++) {
+ var p1 = points[i];
+ var p2 = i < len - 1 ? points[i + 1] : points[0];
+ var e = new Vector().copy(p2).sub(p1);
+ var n = new Vector().copy(e).perp().normalize();
+ this['edges'].push(e);
+ this['normals'].push(n);
+ }
+ return this;
+ };
+
+ // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`).
+ //
+ // Note: You do **not** need to call `recalc` after rotation.
+ /**
+ * @param {number} angle The angle to rotate (in radians)
+ * @return {Polygon} This for chaining.
+ */
+ Polygon.prototype['rotate'] = Polygon.prototype.rotate = function(angle) {
+ var i;
+ var points = this['points'];
+ var edges = this['edges'];
+ var normals = this['normals'];
+ var len = points.length;
+
+ // Calc it just the once, rather than 4 times per array element
+ var cos = Math.cos(angle);
+ var sin = Math.sin(angle);
+
+ for (i = 0; i < len; i++) {
+ points[i].rotatePrecalc(sin, cos);
+ edges[i].rotatePrecalc(sin, cos);
+ normals[i].rotatePrecalc(sin, cos);
+ }
+ return this;
+ };
+
+ // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`).
+ //
+ // Note: You do **not** need to call `recalc` after rotation.
+ /**
+ * @param {number} angle The angle to rotate (in radians)
+ * @return {Polygon} This for chaining.
+ */
+ Polygon.prototype['scale'] = Polygon.prototype.scale = function(x, y) {
+ var i;
+ var points = this['points'];
+ var edges = this['edges'];
+ var normals = this['normals'];
+ var len = points.length;
+ for (i = 0; i < len; i++) {
+ points[i].scale(x,y);
+ edges[i].scale(x,y);
+ normals[i].scale(x,y);
+ }
+ return this;
+ };
+
+ // Translates the points of this polygon by a specified amount relative to the origin of *its own coordinate
+ // system* (i.e. `pos`).
+ //
+ // This is most useful to change the "center point" of a polygon.
+ //
+ // Note: You do **not** need to call `recalc` after translation.
+ /**
+ * @param {number} x The horizontal amount to translate.
+ * @param {number} y The vertical amount to translate.
+ * @return {Polygon} This for chaining.
+ */
+ Polygon.prototype['translate'] = Polygon.prototype.translate = function (x, y) {
+ var i;
+ var points = this['points'];
+ var len = points.length;
+ for (i = 0; i < len; i++) {
+ points[i].x += x;
+ points[i].y += y;
+ }
+ return this;
+ };
+
+ // ## Box
+ //
+ // Represents an axis-aligned box, with a width and height.
+
+
+ // Create a new box, with the specified position, width, and height. If no position
+ // is given, the position will be `(0,0)`. If no width or height are given, they will
+ // be set to `0`.
+ /**
+ * @param {Vector=} pos A vector representing the top-left of the box.
+ * @param {?number=} w The width of the box.
+ * @param {?number=} h The height of the box.
+ * @constructor
+ */
+ function Box(pos, w, h) {
+ this['pos'] = pos || new Vector();
+ this['w'] = w || 0;
+ this['h'] = h || 0;
+ }
+ SAT['Box'] = Box;
+
+ // Returns a polygon whose edges are the same as this box.
+ /**
+ * @return {Polygon} A new Polygon that represents this box.
+ */
+ Box.prototype['toPolygon'] = Box.prototype.toPolygon = function() {
+ var pos = this['pos'];
+ var w = this['w'];
+ var h = this['h'];
+ return new Polygon(new Vector(pos['x'], pos['y']), [
+ new Vector(), new Vector(w, 0),
+ new Vector(w,h), new Vector(0,h)
+ ]);
+ };
+
+ // ## Response
+ //
+ // An object representing the result of an intersection. Contains:
+ // - The two objects participating in the intersection
+ // - The vector representing the minimum change necessary to extract the first object
+ // from the second one (as well as a unit vector in that direction and the magnitude
+ // of the overlap)
+ // - Whether the first object is entirely inside the second, and vice versa.
+ /**
+ * @constructor
+ */
+ function Response() {
+ this['a'] = null;
+ this['b'] = null;
+ this['overlapN'] = new Vector();
+ this['overlapV'] = new Vector();
+ this.clear();
+ }
+ SAT['Response'] = Response;
+
+ // Set some values of the response back to their defaults. Call this between tests if
+ // you are going to reuse a single Response object for multiple intersection tests (recommented
+ // as it will avoid allcating extra memory)
+ /**
+ * @return {Response} This for chaining
+ */
+ Response.prototype['clear'] = Response.prototype.clear = function() {
+ this['aInB'] = true;
+ this['bInA'] = true;
+ this['overlap'] = Number.MAX_VALUE;
+ return this;
+ };
+
+ // ## Object Pools
+
+ // A pool of `Vector` objects that are used in calculations to avoid
+ // allocating memory.
+ /**
+ * @type {Array.}
+ */
+ var T_VECTORS = [];
+ for (var i = 0; i < 10; i++) { T_VECTORS.push(new Vector()); }
+
+ // A pool of arrays of numbers used in calculations to avoid allocating
+ // memory.
+ /**
+ * @type {Array.>}
+ */
+ var T_ARRAYS = [];
+ for (var i = 0; i < 5; i++) { T_ARRAYS.push([]); }
+
+ // ## Helper Functions
+
+ // Flattens the specified array of points onto a unit vector axis,
+ // resulting in a one dimensional range of the minimum and
+ // maximum value on that axis.
+ /**
+ * @param {Array.} points The points to flatten.
+ * @param {Vector} normal The unit vector axis to flatten on.
+ * @param {Array.} result An array. After calling this function,
+ * result[0] will be the minimum value,
+ * result[1] will be the maximum value.
+ */
+ function flattenPointsOn(points, normal, result) {
+ var min = Number.MAX_VALUE;
+ var max = -Number.MAX_VALUE;
+ var len = points.length;
+ for (var i = 0; i < len; i++ ) {
+ // The magnitude of the projection of the point onto the normal
+ var dot = points[i].dot(normal);
+ if (dot < min) { min = dot; }
+ if (dot > max) { max = dot; }
+ }
+ result[0] = min; result[1] = max;
+ }
+
+ // Check whether two convex polygons are separated by the specified
+ // axis (must be a unit vector).
+ /**
+ * @param {Vector} aPos The position of the first polygon.
+ * @param {Vector} bPos The position of the second polygon.
+ * @param {Array.} aPoints The points in the first polygon.
+ * @param {Array.} bPoints The points in the second polygon.
+ * @param {Vector} axis The axis (unit sized) to test against. The points of both polygons
+ * will be projected onto this axis.
+ * @param {Response=} response A Response object (optional) which will be populated
+ * if the axis is not a separating axis.
+ * @return {boolean} true if it is a separating axis, false otherwise. If false,
+ * and a response is passed in, information about how much overlap and
+ * the direction of the overlap will be populated.
+ */
+ function isSeparatingAxis(aPos, bPos, aPoints, bPoints, axis, response) {
+ var rangeA = T_ARRAYS.pop();
+ var rangeB = T_ARRAYS.pop();
+ // The magnitude of the offset between the two polygons
+ var offsetV = T_VECTORS.pop().copy(bPos).sub(aPos);
+ var projectedOffset = offsetV.dot(axis);
+ // Project the polygons onto the axis.
+ flattenPointsOn(aPoints, axis, rangeA);
+ flattenPointsOn(bPoints, axis, rangeB);
+ // Move B's range to its position relative to A.
+ rangeB[0] += projectedOffset;
+ rangeB[1] += projectedOffset;
+ // Check if there is a gap. If there is, this is a separating axis and we can stop
+ if (rangeA[0] > rangeB[1] || rangeB[0] > rangeA[1]) {
+ T_VECTORS.push(offsetV);
+ T_ARRAYS.push(rangeA);
+ T_ARRAYS.push(rangeB);
+ return true;
+ }
+ // This is not a separating axis. If we're calculating a response, calculate the overlap.
+ if (response) {
+ var overlap = 0;
+ // A starts further left than B
+ if (rangeA[0] < rangeB[0]) {
+ response['aInB'] = false;
+ // A ends before B does. We have to pull A out of B
+ if (rangeA[1] < rangeB[1]) {
+ overlap = rangeA[1] - rangeB[0];
+ response['bInA'] = false;
+ // B is fully inside A. Pick the shortest way out.
+ } else {
+ var option1 = rangeA[1] - rangeB[0];
+ var option2 = rangeB[1] - rangeA[0];
+ overlap = option1 < option2 ? option1 : -option2;
+ }
+ // B starts further left than A
+ } else {
+ response['bInA'] = false;
+ // B ends before A ends. We have to push A out of B
+ if (rangeA[1] > rangeB[1]) {
+ overlap = rangeA[0] - rangeB[1];
+ response['aInB'] = false;
+ // A is fully inside B. Pick the shortest way out.
+ } else {
+ var option1 = rangeA[1] - rangeB[0];
+ var option2 = rangeB[1] - rangeA[0];
+ overlap = option1 < option2 ? option1 : -option2;
+ }
+ }
+ // If this is the smallest amount of overlap we've seen so far, set it as the minimum overlap.
+ var absOverlap = Math.abs(overlap);
+ if (absOverlap < response['overlap']) {
+ response['overlap'] = absOverlap;
+ response['overlapN'].copy(axis);
+ if (overlap < 0) {
+ response['overlapN'].reverse();
+ }
+ }
+ }
+ T_VECTORS.push(offsetV);
+ T_ARRAYS.push(rangeA);
+ T_ARRAYS.push(rangeB);
+ return false;
+ }
+
+ // Calculates which Vornoi region a point is on a line segment.
+ // It is assumed that both the line and the point are relative to `(0,0)`
+ //
+ // | (0) |
+ // (-1) [S]--------------[E] (1)
+ // | (0) |
+ /**
+ * @param {Vector} line The line segment.
+ * @param {Vector} point The point.
+ * @return {number} LEFT_VORNOI_REGION (-1) if it is the left region,
+ * MIDDLE_VORNOI_REGION (0) if it is the middle region,
+ * RIGHT_VORNOI_REGION (1) if it is the right region.
+ */
+ function vornoiRegion(line, point) {
+ var len2 = line.len2();
+ var dp = point.dot(line);
+ // If the point is beyond the start of the line, it is in the
+ // left vornoi region.
+ if (dp < 0) { return LEFT_VORNOI_REGION; }
+ // If the point is beyond the end of the line, it is in the
+ // right vornoi region.
+ else if (dp > len2) { return RIGHT_VORNOI_REGION; }
+ // Otherwise, it's in the middle one.
+ else { return MIDDLE_VORNOI_REGION; }
+ }
+ // Constants for Vornoi regions
+ /**
+ * @const
+ */
+ var LEFT_VORNOI_REGION = -1;
+ /**
+ * @const
+ */
+ var MIDDLE_VORNOI_REGION = 0;
+ /**
+ * @const
+ */
+ var RIGHT_VORNOI_REGION = 1;
+
+ // ## Collision Tests
+
+ // Check if two circles collide.
+ /**
+ * @param {Circle} a The first circle.
+ * @param {Circle} b The second circle.
+ * @param {Response=} response Response object (optional) that will be populated if
+ * the circles intersect.
+ * @return {boolean} true if the circles intersect, false if they don't.
+ */
+ function testCircleCircle(a, b, response) {
+ // Check if the distance between the centers of the two
+ // circles is greater than their combined radius.
+ var differenceV = T_VECTORS.pop().copy(b['pos']).sub(a['pos']);
+ var totalRadius = a['r'] + b['r'];
+ var totalRadiusSq = totalRadius * totalRadius;
+ var distanceSq = differenceV.len2();
+ // If the distance is bigger than the combined radius, they don't intersect.
+ if (distanceSq > totalRadiusSq) {
+ T_VECTORS.push(differenceV);
+ return false;
+ }
+ // They intersect. If we're calculating a response, calculate the overlap.
+ if (response) {
+ var dist = Math.sqrt(distanceSq);
+ response['a'] = a;
+ response['b'] = b;
+ response['overlap'] = totalRadius - dist;
+ response['overlapN'].copy(differenceV.normalize());
+ response['overlapV'].copy(differenceV).scale(response['overlap']);
+ response['aInB']= a['r'] <= b['r'] && dist <= b['r'] - a['r'];
+ response['bInA'] = b['r'] <= a['r'] && dist <= a['r'] - b['r'];
+ }
+ T_VECTORS.push(differenceV);
+ return true;
+ }
+ SAT['testCircleCircle'] = testCircleCircle;
+
+ // Check if a polygon and a circle collide.
+ /**
+ * @param {Polygon} polygon The polygon.
+ * @param {Circle} circle The circle.
+ * @param {Response=} response Response object (optional) that will be populated if
+ * they interset.
+ * @return {boolean} true if they intersect, false if they don't.
+ */
+ function testPolygonCircle(polygon, circle, response) {
+ // Get the position of the circle relative to the polygon.
+ var circlePos = T_VECTORS.pop().copy(circle['pos']).sub(polygon['pos']);
+ var radius = circle['r'];
+ var radius2 = radius * radius;
+ var points = polygon['points'];
+ var len = points.length;
+ var edge = T_VECTORS.pop();
+ var point = T_VECTORS.pop();
+
+ // For each edge in the polygon:
+ for (var i = 0; i < len; i++) {
+ var next = i === len - 1 ? 0 : i + 1;
+ var prev = i === 0 ? len - 1 : i - 1;
+ var overlap = 0;
+ var overlapN = null;
+
+ // Get the edge.
+ edge.copy(polygon['edges'][i]);
+ // Calculate the center of the circle relative to the starting point of the edge.
+ point.copy(circlePos).sub(points[i]);
+
+ // If the distance between the center of the circle and the point
+ // is bigger than the radius, the polygon is definitely not fully in
+ // the circle.
+ if (response && point.len2() > radius2) {
+ response['aInB'] = false;
+ }
+
+ // Calculate which Vornoi region the center of the circle is in.
+ var region = vornoiRegion(edge, point);
+ // If it's the left region:
+ if (region === LEFT_VORNOI_REGION) {
+ // We need to make sure we're in the RIGHT_VORNOI_REGION of the previous edge.
+ edge.copy(polygon['edges'][prev]);
+ // Calculate the center of the circle relative the starting point of the previous edge
+ var point2 = T_VECTORS.pop().copy(circlePos).sub(points[prev]);
+ region = vornoiRegion(edge, point2);
+ if (region === RIGHT_VORNOI_REGION) {
+ // It's in the region we want. Check if the circle intersects the point.
+ var dist = point.len();
+ if (dist > radius) {
+ // No intersection
+ T_VECTORS.push(circlePos);
+ T_VECTORS.push(edge);
+ T_VECTORS.push(point);
+ T_VECTORS.push(point2);
+ return false;
+ } else if (response) {
+ // It intersects, calculate the overlap.
+ response['bInA'] = false;
+ overlapN = point.normalize();
+ overlap = radius - dist;
+ }
+ }
+ T_VECTORS.push(point2);
+ // If it's the right region:
+ } else if (region === RIGHT_VORNOI_REGION) {
+ // We need to make sure we're in the left region on the next edge
+ edge.copy(polygon['edges'][next]);
+ // Calculate the center of the circle relative to the starting point of the next edge.
+ point.copy(circlePos).sub(points[next]);
+ region = vornoiRegion(edge, point);
+ if (region === LEFT_VORNOI_REGION) {
+ // It's in the region we want. Check if the circle intersects the point.
+ var dist = point.len();
+ if (dist > radius) {
+ // No intersection
+ T_VECTORS.push(circlePos);
+ T_VECTORS.push(edge);
+ T_VECTORS.push(point);
+ return false;
+ } else if (response) {
+ // It intersects, calculate the overlap.
+ response['bInA'] = false;
+ overlapN = point.normalize();
+ overlap = radius - dist;
+ }
+ }
+ // Otherwise, it's the middle region:
+ } else {
+ // Need to check if the circle is intersecting the edge,
+ // Change the edge into its "edge normal".
+ var normal = edge.perp().normalize();
+ // Find the perpendicular distance between the center of the
+ // circle and the edge.
+ var dist = point.dot(normal);
+ var distAbs = Math.abs(dist);
+ // If the circle is on the outside of the edge, there is no intersection.
+ if (dist > 0 && distAbs > radius) {
+ // No intersection
+ T_VECTORS.push(circlePos);
+ T_VECTORS.push(normal);
+ T_VECTORS.push(point);
+ return false;
+ } else if (response) {
+ // It intersects, calculate the overlap.
+ overlapN = normal;
+ overlap = radius - dist;
+ // If the center of the circle is on the outside of the edge, or part of the
+ // circle is on the outside, the circle is not fully inside the polygon.
+ if (dist >= 0 || overlap < 2 * radius) {
+ response['bInA'] = false;
+ }
+ }
+ }
+
+ // If this is the smallest overlap we've seen, keep it.
+ // (overlapN may be null if the circle was in the wrong Vornoi region).
+ if (overlapN && response && Math.abs(overlap) < Math.abs(response['overlap'])) {
+ response['overlap'] = overlap;
+ response['overlapN'].copy(overlapN);
+ }
+ }
+
+ // Calculate the final overlap vector - based on the smallest overlap.
+ if (response) {
+ response['a'] = polygon;
+ response['b'] = circle;
+ response['overlapV'].copy(response['overlapN']).scale(response['overlap']);
+ }
+ T_VECTORS.push(circlePos);
+ T_VECTORS.push(edge);
+ T_VECTORS.push(point);
+ return true;
+ }
+ SAT['testPolygonCircle'] = testPolygonCircle;
+
+ // Check if a circle and a polygon collide.
+ //
+ // **NOTE:** This is slightly less efficient than polygonCircle as it just
+ // runs polygonCircle and reverses everything at the end.
+ /**
+ * @param {Circle} circle The circle.
+ * @param {Polygon} polygon The polygon.
+ * @param {Response=} response Response object (optional) that will be populated if
+ * they interset.
+ * @return {boolean} true if they intersect, false if they don't.
+ */
+ function testCirclePolygon(circle, polygon, response) {
+ // Test the polygon against the circle.
+ var result = testPolygonCircle(polygon, circle, response);
+ if (result && response) {
+ // Swap A and B in the response.
+ var a = response['a'];
+ var aInB = response['aInB'];
+ response['overlapN'].reverse();
+ response['overlapV'].reverse();
+ response['a'] = response['b'];
+ response['b'] = a;
+ response['aInB'] = response['bInA'];
+ response['bInA'] = aInB;
+ }
+ return result;
+ }
+ SAT['testCirclePolygon'] = testCirclePolygon;
+
+ // Checks whether polygons collide.
+ /**
+ * @param {Polygon} a The first polygon.
+ * @param {Polygon} b The second polygon.
+ * @param {Response=} response Response object (optional) that will be populated if
+ * they interset.
+ * @return {boolean} true if they intersect, false if they don't.
+ */
+ function testPolygonPolygon(a, b, response) {
+ var aPoints = a['points'];
+ var aLen = aPoints.length;
+ var bPoints = b['points'];
+ var bLen = bPoints.length;
+ // If any of the edge normals of A is a separating axis, no intersection.
+ for (var i = 0; i < aLen; i++) {
+ if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, a['normals'][i], response)) {
+ return false;
+ }
+ }
+ // If any of the edge normals of B is a separating axis, no intersection.
+ for (var i = 0;i < bLen; i++) {
+ if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, b['normals'][i], response)) {
+ return false;
+ }
+ }
+ // Since none of the edge normals of A or B are a separating axis, there is an intersection
+ // and we've already calculated the smallest overlap (in isSeparatingAxis). Calculate the
+ // final overlap vector.
+ if (response) {
+ response['a'] = a;
+ response['b'] = b;
+ response['overlapV'].copy(response['overlapN']).scale(response['overlap']);
+ }
+ return true;
+ }
+ SAT['testPolygonPolygon'] = testPolygonPolygon;
+
+ return SAT;
+}));
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -34881,9 +38841,34 @@ Phaser.Physics.Arcade = function (game) {
this.gravity = new Phaser.Point();
/**
- * @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds.
+ * @property {SAT.Box} worldLeft - The left hand side of the physics bounds.
*/
- this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
+ this.worldLeft = null;
+
+ /**
+ * @property {SAT.Box} worldRight - The right hand side of the physics bounds.
+ */
+ this.worldRight = null;
+
+ /**
+ * @property {SAT.Box} worldTop - The top side of the physics bounds.
+ */
+ this.worldTop = null;
+
+ /**
+ * @property {SAT.Box} worldBottom - The bottom of the physics bounds.
+ */
+ this.worldBottom = null;
+
+ /**
+ * @property {array} worldPolys - An array of the polygon data from the physics bounds.
+ */
+ this.worldPolys = [ null, null, null, null ];
+
+ /**
+ * @property {Phaser.QuadTree} quadTree - The world QuadTree.
+ */
+ 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);
/**
* @property {number} maxObjects - Used by the QuadTree to set the maximum number of objects per quad.
@@ -34895,77 +38880,6 @@ Phaser.Physics.Arcade = function (game) {
*/
this.maxLevels = 4;
- /**
- * @property {number} OVERLAP_BIAS - A value added to the delta values during collision checks.
- */
- this.OVERLAP_BIAS = 4;
-
- /**
- * @property {Phaser.QuadTree} quadTree - The world QuadTree.
- */
- this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
-
- /**
- * @property {number} quadTreeID - The QuadTree ID.
- */
- this.quadTreeID = 0;
-
- // Avoid gc spikes by caching these values for re-use
-
- /**
- * @property {Phaser.Rectangle} _bounds1 - Internal cache var.
- * @private
- */
- this._bounds1 = new Phaser.Rectangle();
-
- /**
- * @property {Phaser.Rectangle} _bounds2 - Internal cache var.
- * @private
- */
- this._bounds2 = new Phaser.Rectangle();
-
- /**
- * @property {number} _overlap - Internal cache var.
- * @private
- */
- this._overlap = 0;
-
- /**
- * @property {number} _maxOverlap - Internal cache var.
- * @private
- */
- this._maxOverlap = 0;
-
- /**
- * @property {number} _velocity1 - Internal cache var.
- * @private
- */
- this._velocity1 = 0;
-
- /**
- * @property {number} _velocity2 - Internal cache var.
- * @private
- */
- this._velocity2 = 0;
-
- /**
- * @property {number} _newVelocity1 - Internal cache var.
- * @private
- */
- this._newVelocity1 = 0;
-
- /**
- * @property {number} _newVelocity2 - Internal cache var.
- * @private
- */
- this._newVelocity2 = 0;
-
- /**
- * @property {number} _average - Internal cache var.
- * @private
- */
- this._average = 0;
-
/**
* @property {Array} _mapData - Internal cache var.
* @private
@@ -34996,6 +38910,12 @@ Phaser.Physics.Arcade = function (game) {
*/
this._angle = 0;
+ /**
+ * @property {number} _drag - Internal cache var.
+ * @private
+ */
+ this._drag = 0;
+
/**
* @property {number} _dx - Internal cache var.
* @private
@@ -35008,10 +38928,212 @@ Phaser.Physics.Arcade = function (game) {
*/
this._dy = 0;
+ /**
+ * @property {Phaser.Point} _p - Internal cache var.
+ * @private
+ */
+ this._p = new Phaser.Point(0, 0);
+
+ /**
+ * @property {number} _intersection - Internal cache var.
+ * @private
+ */
+ this._intersection = [0,0,0,0];
+
+ /**
+ * @property {number} _gravityX - Internal cache var.
+ * @private
+ */
+ this._gravityX = 0;
+
+ /**
+ * @property {number} _gravityY - Internal cache var.
+ * @private
+ */
+ this._gravityY = 0;
+
+ /**
+ * @property {SAT.Response} _response - Internal cache var.
+ * @private
+ */
+ this._response = new SAT.Response();
+
+ // Set the bounds to the world as default
+ this.setBoundsToWorld(true, true, true, true);
+
};
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Physics.Arcade.RECT = 0;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Physics.Arcade.CIRCLE = 1;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Physics.Arcade.POLYGON = 2;
+
Phaser.Physics.Arcade.prototype = {
+ /**
+ * Checks the given Physics.Body against the Physics Bounds, if any are set, and separates them, setting the blocked flags on the Body as it does so.
+ *
+ * @method Phaser.Physics.Arcade#checkBounds
+ * @param {Phaser.Physics.Arcade.Body} The Body object to be checked.
+ * @return {boolean} True if the body hit the bounds, otherwise false.
+ */
+ checkBounds: function (body) {
+
+ if (!body.collideWorldBounds || (!this.worldLeft && !this.worldRight && !this.worldTop && !this.worldBottom))
+ {
+ return false;
+ }
+
+ this._response.clear();
+
+ var test = SAT.testPolygonPolygon;
+ var part = body.polygon;
+ var rebounded = false;
+
+ if (body.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ test = SAT.testPolygonCircle;
+ part = body.shape;
+ }
+
+ if (this.worldLeft && test(this.worldPolys[0], part, this._response))
+ {
+ body.blocked.left = true;
+ part.pos.add(this._response.overlapV);
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ rebounded = true;
+ }
+ else if (this.worldRight && test(this.worldPolys[1], part, this._response))
+ {
+ body.blocked.right = true;
+ part.pos.add(this._response.overlapV);
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ rebounded = true;
+ }
+
+ this._response.clear();
+
+ if (this.worldTop && test(this.worldPolys[2], part, this._response))
+ {
+ body.blocked.up = true;
+ part.pos.add(this._response.overlapV);
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ rebounded = true;
+ }
+ else if (this.worldBottom && test(this.worldPolys[3], part, this._response))
+ {
+ body.blocked.down = true;
+ part.pos.add(this._response.overlapV);
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ rebounded = true;
+ }
+
+ return rebounded;
+
+ },
+
+ /**
+ * Sets the bounds of the Physics world to match the Game.World.
+ * You can optionally set which 'walls' to create: left, right, top or bottom.
+ *
+ * @method Phaser.Physics.Arcade#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.
+ */
+ setBoundsToWorld: function (left, right, top, bottom) {
+
+ 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);
+
+ },
+
+ /**
+ * 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.Arcade#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.
+ */
+ setBounds: function (x, y, width, height, 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; }
+
+ var thickness = 100;
+
+ if (left)
+ {
+ this.worldLeft = new SAT.Box(new SAT.Vector(x - thickness, y), thickness, height);
+ this.worldPolys[0] = this.worldLeft.toPolygon();
+ }
+ else
+ {
+ this.worldLeft = null;
+ this.worldPolys[0] = null;
+ }
+
+ if (right)
+ {
+ this.worldRight = new SAT.Box(new SAT.Vector(x + width, y), thickness, height);
+ this.worldPolys[1] = this.worldRight.toPolygon();
+ }
+ else
+ {
+ this.worldRight = null;
+ this.worldPolys[1] = null;
+ }
+
+ if (top)
+ {
+ this.worldTop = new SAT.Box(new SAT.Vector(x, y - thickness), width, thickness);
+ this.worldPolys[2] = this.worldTop.toPolygon();
+ }
+ else
+ {
+ this.worldTop = null;
+ this.worldPolys[2] = null;
+ }
+
+ if (bottom)
+ {
+ this.worldBottom = new SAT.Box(new SAT.Vector(x, y + height), width, thickness);
+ this.worldPolys[3] = this.worldBottom.toPolygon();
+ }
+ else
+ {
+ this.worldBottom = null;
+ this.worldPolys[3] = null;
+ }
+
+ },
+
/**
* Called automatically by a Physics body, it updates all motion related values on the Body.
*
@@ -35022,113 +39144,68 @@ Phaser.Physics.Arcade.prototype = {
// If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html
+ // World gravity is allowed
+ if (body.allowGravity)
+ {
+ this._gravityX = this.gravity.x + body.gravity.x;
+ this._gravityY = this.gravity.y + body.gravity.y;
+ }
+ else
+ {
+ this._gravityX = body.gravity.x;
+ this._gravityY = body.gravity.y;
+ }
+
+ // Don't apply gravity to any body that is blocked
+ if ((this._gravityX < 0 && body.blocked.left) || (this._gravityX > 0 && body.blocked.right))
+ {
+ this._gravityX = 0;
+ }
+
+ if ((this._gravityY < 0 && body.blocked.up) || (this._gravityY > 0 && body.blocked.down))
+ {
+ this._gravityY = 0;
+ }
+
// Rotation
- this._velocityDelta = (this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) * this.game.time.physicsElapsed * 0.5 * 60;
- body.angularVelocity += this._velocityDelta;
- body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
- body.angularVelocity += this._velocityDelta;
-
- // Horizontal
- this._velocityDelta = (this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x) - body.velocity.x) * this.game.time.physicsElapsed * 0.5 * 60;
- body.velocity.x += this._velocityDelta;
- body.x += (body.velocity.x * this.game.time.physicsElapsed);
- body.velocity.x += this._velocityDelta;
-
- // Vertical
- this._velocityDelta = (this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y) - body.velocity.y) * this.game.time.physicsElapsed * 0.5 * 60;
- body.velocity.y += this._velocityDelta;
- body.y += (body.velocity.y * this.game.time.physicsElapsed);
- body.velocity.y += this._velocityDelta;
-
- },
-
- /**
- * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
- *
- * @method Phaser.Physics.Arcade#computeVelocity
- * @param {number} axis - 1 for horizontal, 2 for vertical.
- * @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated.
- * @param {number} velocity - Any component of velocity (e.g. 20).
- * @param {number} acceleration - Rate at which the velocity is changing.
- * @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
- * @param {number} mMax - An absolute value cap for the velocity.
- * @return {number} The altered Velocity value.
- */
- computeVelocity: function (axis, body, velocity, acceleration, drag, max) {
-
- max = max || 10000;
-
- if (axis == 1 && body.allowGravity)
+ if (body.allowRotation)
{
- velocity += this.gravity.x + body.gravity.x;
- }
- else if (axis == 2 && body.allowGravity)
- {
- velocity += this.gravity.y + body.gravity.y;
- }
+ this._velocityDelta = body.angularAcceleration * this.game.time.physicsElapsed;
- if (acceleration !== 0)
- {
- velocity += acceleration * this.game.time.physicsElapsed;
- }
- else if (drag !== 0)
- {
- this._drag = drag * this.game.time.physicsElapsed;
-
- if (velocity - this._drag > 0)
+ if (body.angularDrag !== 0 && body.angularAcceleration === 0)
{
- velocity -= this._drag;
+ this._drag = body.angularDrag * this.game.time.physicsElapsed;
+
+ if (body.angularVelocity > 0)
+ {
+ body.angularVelocity -= this._drag;
+ }
+ else if (body.angularVelocity < 0)
+ {
+ body.angularVelocity += this._drag;
+ }
}
- else if (velocity + this._drag < 0)
+
+ body.rotation += this.game.time.physicsElapsed * (body.angularVelocity + this._velocityDelta / 2);
+ body.angularVelocity += this._velocityDelta;
+
+ if (body.angularVelocity > body.maxAngular)
{
- velocity += this._drag;
+ body.angularVelocity = body.maxAngular;
}
- else
+ else if (body.angularVelocity < -body.maxAngular)
{
- velocity = 0;
+ body.angularVelocity = -body.maxAngular;
}
}
- if (velocity > max)
- {
- velocity = max;
- }
- else if (velocity < -max)
- {
- velocity = -max;
- }
+ // temp = acc*dt
+ // pos = pos + dt*(vel + temp/2)
+ // vel = vel + temp
- return velocity;
+ this._p.setTo((body.acceleration.x + this._gravityX) * this.game.time.physicsElapsed, (body.acceleration.y + this._gravityY) * this.game.time.physicsElapsed);
- },
-
- /**
- * Called automatically by the core game loop.
- *
- * @method Phaser.Physics.Arcade#preUpdate
- * @protected
- */
- preUpdate: function () {
-
- // Clear the tree
- this.quadTree.clear();
-
- // Create our tree which all of the Physics bodies will add themselves to
- this.quadTreeID = 0;
- this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
-
- },
-
- /**
- * Called automatically by the core game loop.
- *
- * @method Phaser.Physics.Arcade#postUpdate
- * @protected
- */
- postUpdate: function () {
-
- // Clear the tree ready for the next update
- this.quadTree.clear();
+ return this._p;
},
@@ -35136,10 +39213,11 @@ Phaser.Physics.Arcade.prototype = {
* 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} object2 - The second 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.
@@ -35154,83 +39232,144 @@ Phaser.Physics.Arcade.prototype = {
this._result = false;
this._total = 0;
- // Only test valid objects
- if (object1 && object2 && object1.exists && object2.exists)
+ if (Array.isArray(object2))
{
- // SPRITES
- if (object1.type == Phaser.SPRITE)
+ for (var i = 0, len = object2.length; i < len; i++)
{
- if (object2.type == Phaser.SPRITE)
- {
- this.overlapSpriteVsSprite(object1, object2, overlapCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
- {
- this.overlapSpriteVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
- }
- }
- // GROUPS
- else if (object1.type == Phaser.GROUP)
- {
- if (object2.type == Phaser.SPRITE)
- {
- this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
- {
- this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
- }
- }
- // EMITTER
- else if (object1.type == Phaser.EMITTER)
- {
- if (object2.type == Phaser.SPRITE)
- {
- this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
- {
- this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
- }
+ this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true);
}
}
+ else
+ {
+ this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true);
+ }
return (this._total > 0);
},
/**
- * An internal function. Use Phaser.Physics.Arcade.overlap instead.
+ * 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.Arcade#overlapSpriteVsSprite
- * @private
+ * @method Phaser.Physics.Arcade#collide
+ * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
+ * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap|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.
*/
- overlapSpriteVsSprite: function (sprite1, sprite2, overlapCallback, processCallback, callbackContext) {
+ collide: function (object1, object2, collideCallback, processCallback, callbackContext) {
- this._result = Phaser.Rectangle.intersects(sprite1.body, sprite2.body);
+ collideCallback = collideCallback || null;
+ processCallback = processCallback || null;
+ callbackContext = callbackContext || collideCallback;
- if (this._result)
+ this._result = false;
+ this._total = 0;
+
+ if (Array.isArray(object2))
{
- // They collided, is there a custom process callback?
- if (processCallback)
+ for (var i = 0, len = object2.length; i < len; i++)
{
- if (processCallback.call(callbackContext, sprite1, sprite2))
- {
- this._total++;
+ this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false);
+ }
+ }
+ else
+ {
+ this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false);
+ }
- if (overlapCallback)
- {
- overlapCallback.call(callbackContext, sprite1, sprite2);
- }
+ 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);
}
}
- else
+ // GROUPS
+ else if (object1.type == Phaser.GROUP)
{
- this._total++;
-
- if (overlapCallback)
+ if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{
- overlapCallback.call(callbackContext, sprite1, sprite2);
+ 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);
}
}
}
@@ -35238,12 +39377,32 @@ Phaser.Physics.Arcade.prototype = {
},
/**
- * An internal function. Use Phaser.Physics.Arcade.overlap instead.
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
*
- * @method Phaser.Physics.Arcade#overlapSpriteVsGroup
+ * @method Phaser.Physics.Arcade#collideSpriteVsSprite
* @private
*/
- overlapSpriteVsGroup: function (sprite, group, overlapCallback, processCallback, callbackContext) {
+ 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)
{
@@ -35251,28 +39410,52 @@ 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.populate(group);
+
this._potentials = this.quadTree.retrieve(sprite);
for (var i = 0, len = this._potentials.length; i < len; i++)
{
// We have our potential suspects, are they in this group?
- if (this._potentials[i].sprite.group == group)
+ if (this.separate(sprite.body, this._potentials[i], processCallback, callbackContext, overlapOnly))
{
- this._result = Phaser.Rectangle.intersects(sprite.body, this._potentials[i]);
-
- if (this._result && processCallback)
+ if (collideCallback)
{
- this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite);
+ collideCallback.call(callbackContext, sprite, this._potentials[i].sprite);
}
- if (this._result)
- {
- this._total++;
+ this._total++;
+ }
+ }
- if (overlapCallback)
- {
- overlapCallback.call(callbackContext, sprite, this._potentials[i].sprite);
- }
+ },
+
+ /**
+ * 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._container.children.length;
+
+ for (var i = 0; i < len; i++)
+ {
+ for (var j = i + 1; j <= len; j++)
+ {
+ if (group._container.children[i] && group._container.children[j] && group._container.children[i].exists && group._container.children[j].exists)
+ {
+ this.collideSpriteVsSprite(group._container.children[i], group._container.children[j], collideCallback, processCallback, callbackContext, overlapOnly);
}
}
}
@@ -35280,12 +39463,12 @@ Phaser.Physics.Arcade.prototype = {
},
/**
- * An internal function. Use Phaser.Physics.Arcade.overlap instead.
+ * An internal function. Use Phaser.Physics.Arcade.collide instead.
*
- * @method Phaser.Physics.Arcade#overlapGroupVsGroup
+ * @method Phaser.Physics.Arcade#collideGroupVsGroup
* @private
*/
- overlapGroupVsGroup: function (group1, group2, overlapCallback, processCallback, callbackContext) {
+ collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) {
if (group1.length === 0 || group2.length === 0)
{
@@ -35300,7 +39483,7 @@ Phaser.Physics.Arcade.prototype = {
{
if (currentNode.exists)
{
- this.overlapSpriteVsGroup(currentNode, group2, overlapCallback, processCallback, callbackContext);
+ this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext, overlapOnly);
}
currentNode = currentNode._iNext;
}
@@ -35309,99 +39492,6 @@ Phaser.Physics.Arcade.prototype = {
},
- /**
- * Checks for collision between two game objects. The objects can be Sprites, Groups, Emitters or Tilemap Layers.
- * You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
- * The objects are also automatically separated.
- *
- * @method Phaser.Physics.Arcade#collide
- * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap
- * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap
- * @param {function} [collideCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
- * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collideCallback will only be called if processCallback returns true.
- * @param {object} [callbackContext] - The context in which to run the callbacks.
- * @returns {boolean} True if a collision occured otherwise false.
- */
- collide: function (object1, object2, collideCallback, processCallback, callbackContext) {
-
- collideCallback = collideCallback || null;
- processCallback = processCallback || null;
- callbackContext = callbackContext || collideCallback;
-
- this._result = false;
- this._total = 0;
-
- // Only collide valid objects
- if (object1 && object2 && object1.exists && object2.exists)
- {
- // Can expand to support Buttons, Text, etc at a later date. For now these are the essentials.
-
- // SPRITES
- if (object1.type == Phaser.SPRITE)
- {
- if (object2.type == Phaser.SPRITE)
- {
- this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
- {
- this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.TILEMAPLAYER)
- {
- this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
- }
- }
- // GROUPS
- else if (object1.type == Phaser.GROUP)
- {
- if (object2.type == Phaser.SPRITE)
- {
- this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
- {
- this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.TILEMAPLAYER)
- {
- this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
- }
- }
- // TILEMAP LAYERS
- else if (object1.type == Phaser.TILEMAPLAYER)
- {
- if (object2.type == Phaser.SPRITE)
- {
- 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)
- {
- this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
- {
- this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
- }
- else if (object2.type == Phaser.TILEMAPLAYER)
- {
- this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
- }
- }
- }
-
- return (this._total > 0);
-
- },
-
/**
* An internal function. Use Phaser.Physics.Arcade.collide instead.
*
@@ -35410,15 +39500,21 @@ Phaser.Physics.Arcade.prototype = {
*/
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
- this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true);
+ this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true);
if (this._mapData.length === 0)
{
return;
}
- for (var i = 0; i < this._mapData.length; i++)
+ if (this._mapData.length > 1)
{
+ this.separateTiles(sprite.body, this._mapData);
+ }
+ else
+ {
+ var i = 0;
+
if (this.separateTile(sprite.body, this._mapData[i]))
{
// They collided, is there a custom process callback?
@@ -35461,11 +39557,6 @@ Phaser.Physics.Arcade.prototype = {
return;
}
- if (group.length === 0)
- {
- return;
- }
-
if (group._container.first._iNext)
{
var currentNode = group._container.first._iNext;
@@ -35483,232 +39574,39 @@ Phaser.Physics.Arcade.prototype = {
},
- /**
- * An internal function. Use Phaser.Physics.Arcade.collide instead.
- *
- * @method Phaser.Physics.Arcade#collideSpriteVsSprite
- * @private
- */
- collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext) {
-
- this.separate(sprite1.body, sprite2.body);
-
- if (this._result)
- {
- // They collided, is there a custom process callback?
- if (processCallback)
- {
- if (processCallback.call(callbackContext, sprite1, sprite2))
- {
- this._total++;
-
- if (collideCallback)
- {
- collideCallback.call(callbackContext, sprite1, sprite2);
- }
- }
- }
- else
- {
- this._total++;
-
- if (collideCallback)
- {
- collideCallback.call(callbackContext, sprite1, sprite2);
- }
- }
- }
-
- },
-
- /**
- * An internal function. Use Phaser.Physics.Arcade.collide instead.
- *
- * @method Phaser.Physics.Arcade#collideSpriteVsGroup
- * @private
- */
- collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext) {
-
- if (group.length === 0)
- {
- return;
- }
-
- // What is the sprite colliding with in the quadtree?
- this._potentials = this.quadTree.retrieve(sprite);
-
- for (var i = 0, len = this._potentials.length; i < len; i++)
- {
- // We have our potential suspects, are they in this group?
- if (this._potentials[i].sprite.group == group)
- {
- this.separate(sprite.body, this._potentials[i]);
-
- if (this._result && processCallback)
- {
- this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite);
- }
-
- if (this._result)
- {
- this._total++;
-
- if (collideCallback)
- {
- collideCallback.call(callbackContext, sprite, this._potentials[i].sprite);
- }
- }
- }
- }
-
- },
-
- /**
- * An internal function. Use Phaser.Physics.Arcade.collide instead.
- *
- * @method Phaser.Physics.Arcade#collideGroupVsGroup
- * @private
- */
- collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext) {
-
- if (group1.length === 0 || group2.length === 0)
- {
- return;
- }
-
- if (group1._container.first._iNext)
- {
- var currentNode = group1._container.first._iNext;
-
- do
- {
- if (currentNode.exists)
- {
- this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext);
- }
- currentNode = currentNode._iNext;
- }
- while (currentNode != group1._container.last._iNext);
- }
-
- },
-
/**
* The core separation function to separate two physics bodies.
* @method Phaser.Physics.Arcade#separate
* @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
* @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
- * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ * @param {function} [processCallback=null] - 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] - The context in which to run the process callback.
+ * @returns {boolean} Returns true if the bodies collided, otherwise false.
*/
- separate: function (body1, body2) {
+ separate: function (body1, body2, processCallback, callbackContext, overlapOnly) {
- this._result = (this.separateX(body1, body2) || this.separateY(body1, body2));
-
- },
-
- /**
- * The core separation function to separate two physics bodies on the x axis.
- * @method Phaser.Physics.Arcade#separateX
- * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
- * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
- * @returns {boolean} Returns true if the bodies were separated, otherwise false.
- */
- separateX: function (body1, body2) {
-
- // Can't separate two immovable bodies
- if (body1.immovable && body2.immovable)
+ if (body1 === body2 || this.intersects(body1, body2) === false)
{
return false;
}
- this._overlap = 0;
-
- // Check if the hulls actually overlap
- if (Phaser.Rectangle.intersects(body1, body2))
+ // They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort.
+ if (processCallback && processCallback.call(callbackContext, body1.sprite, body2.sprite) === false)
{
- this._maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + this.OVERLAP_BIAS;
+ return false;
+ }
- if (body1.deltaX() === 0 && body2.deltaX() === 0)
+ this._response.clear();
+
+ if (overlapOnly)
+ {
+ return body1.overlap(body2, this._response);
+ }
+ else
+ {
+ if (body1.overlap(body2, this._response))
{
- // They overlap but neither of them are moving
- body1.embedded = true;
- body2.embedded = true;
- }
- else if (body1.deltaX() > body2.deltaX())
- {
- // Body1 is moving right and/or Body2 is moving left
- this._overlap = body1.x + body1.width - body2.x;
-
- if ((this._overlap > this._maxOverlap) || body1.allowCollision.right === false || body2.allowCollision.left === false)
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching.right = true;
- body2.touching.left = true;
- }
- }
- else if (body1.deltaX() < body2.deltaX())
- {
- // Body1 is moving left and/or Body2 is moving right
- this._overlap = body1.x - body2.width - body2.x;
-
- if ((-this._overlap > this._maxOverlap) || body1.allowCollision.left === false || body2.allowCollision.right === false)
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching.left = true;
- body2.touching.right = true;
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (this._overlap !== 0)
- {
- body1.overlapX = this._overlap;
- body2.overlapX = this._overlap;
-
- if (body1.customSeparateX || body2.customSeparateX)
- {
- return true;
- }
-
- this._velocity1 = body1.velocity.x;
- this._velocity2 = body2.velocity.x;
-
- if (!body1.immovable && !body2.immovable)
- {
- this._overlap *= 0.5;
-
- body1.x = body1.x - this._overlap;
- body2.x += this._overlap;
-
- this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1);
- this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1);
- this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
- this._newVelocity1 -= this._average;
- this._newVelocity2 -= this._average;
-
- body1.velocity.x = this._average + this._newVelocity1 * body1.bounce.x;
- body2.velocity.x = this._average + this._newVelocity2 * body2.bounce.x;
- }
- else if (!body1.immovable)
- {
- body1.x = body1.x - this._overlap;
- body1.velocity.x = this._velocity2 - this._velocity1 * body1.bounce.x;
- }
- else if (!body2.immovable)
- {
- body2.x += this._overlap;
- body2.velocity.x = this._velocity1 - this._velocity2 * body2.bounce.x;
- }
- body1.updateHulls();
- body2.updateHulls();
-
- return true;
+ return body1.separate(body2, this._response);
}
}
@@ -35717,221 +39615,203 @@ Phaser.Physics.Arcade.prototype = {
},
/**
- * The core separation function to separate two physics bodies on the y axis.
- * @method Phaser.Physics.Arcade#separateY
- * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
- * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
- * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ * Performs a rect intersection test against the two objects.
+ * Objects must expose properties: width, height, left, right, top, bottom.
+ * @method Phaser.Physics.Arcade#intersects
+ * @param {object} a - The first object to test.
+ * @param {object} b - The second object to test.
+ * @returns {boolean} Returns true if the objects intersect, otherwise false.
*/
- separateY: function (body1, body2) {
+ intersects: function (a, b) {
- // Can't separate two immovable or non-existing bodys
- if (body1.immovable && body2.immovable)
+ var result = false;
+
+ if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0)
{
- return false;
+ result = false;
}
- this._overlap = 0;
+ result = !(a.right < b.left || a.bottom < b.top || a.left > b.right || a.top > b.bottom);
- // Check if the hulls actually overlap
- if (Phaser.Rectangle.intersects(body1, body2))
+ if (!result && a.inContact(b))
{
- this._maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + this.OVERLAP_BIAS;
-
- if (body1.deltaY() === 0 && body2.deltaY() === 0)
- {
- // They overlap but neither of them are moving
- body1.embedded = true;
- body2.embedded = true;
- }
- else if (body1.deltaY() > body2.deltaY())
- {
- // Body1 is moving down and/or Body2 is moving up
- this._overlap = body1.y + body1.height - body2.y;
-
- if ((this._overlap > this._maxOverlap) || body1.allowCollision.down === false || body2.allowCollision.up === false)
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching.down = true;
- body2.touching.up = true;
- }
- }
- else if (body1.deltaY() < body2.deltaY())
- {
- // Body1 is moving up and/or Body2 is moving down
- this._overlap = body1.y - body2.height - body2.y;
-
- if ((-this._overlap > this._maxOverlap) || body1.allowCollision.up === false || body2.allowCollision.down === false)
- {
- this._overlap = 0;
- }
- else
- {
- body1.touching.up = true;
- body2.touching.down = true;
- }
- }
-
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (this._overlap !== 0)
- {
- body1.overlapY = this._overlap;
- body2.overlapY = this._overlap;
-
- if (body1.customSeparateY || body2.customSeparateY)
- {
- return true;
- }
-
- this._velocity1 = body1.velocity.y;
- this._velocity2 = body2.velocity.y;
-
- if (!body1.immovable && !body2.immovable)
- {
- this._overlap *= 0.5;
-
- body1.y = body1.y - this._overlap;
- body2.y += this._overlap;
-
- this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1);
- this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1);
- this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
- this._newVelocity1 -= this._average;
- this._newVelocity2 -= this._average;
-
- body1.velocity.y = this._average + this._newVelocity1 * body1.bounce.y;
- body2.velocity.y = this._average + this._newVelocity2 * body2.bounce.y;
- }
- else if (!body1.immovable)
- {
- body1.y = body1.y - this._overlap;
- body1.velocity.y = this._velocity2 - this._velocity1 * body1.bounce.y;
-
- // This is special case code that handles things like horizontal moving platforms you can ride
- if (body2.active && body2.moves && (body1.deltaY() > body2.deltaY()))
- {
- body1.x += body2.x - body2.lastX;
- }
- }
- else if (!body2.immovable)
- {
- body2.y += this._overlap;
- body2.velocity.y = this._velocity1 - this._velocity2 * body2.bounce.y;
-
- // This is special case code that handles things like horizontal moving platforms you can ride
- if (body1.sprite.active && body1.moves && (body1.deltaY() < body2.deltaY()))
- {
- body2.x += body1.x - body1.lastX;
- }
- }
- body1.updateHulls();
- body2.updateHulls();
-
- return true;
- }
-
+ a.removeContact(b);
}
- return false;
+ },
+
+ /**
+ * Performs a rect intersection test against the two objects.
+ * Objects must expose properties: width, height, left, right, top, bottom.
+ * @method Phaser.Physics.Arcade#tileIntersects
+ * @param {object} body - The Body to test.
+ * @param {object} tile - The Tile to test.
+ * @returns {boolean} Returns true if the objects intersect, otherwise false.
+ */
+ tileIntersects: function (body, tile) {
+
+ if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0)
+ {
+ this._intersection[4] = 0;
+ return this._intersection;
+ }
+
+ if (!(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom))
+ {
+ this._intersection[0] = Math.max(body.left, tile.x); // x
+ this._intersection[1] = Math.max(body.top, tile.y); // y
+ this._intersection[2] = Math.min(body.right, tile.right) - this._intersection[0]; // width
+ this._intersection[3] = Math.min(body.bottom, tile.bottom) - this._intersection[1]; // height
+ this._intersection[4] = 1;
+
+ return this._intersection;
+ }
+
+ this._intersection[4] = 0;
+
+ return this._intersection;
+
+ },
+
+ /**
+ * The core separation function to separate a physics body and an array of tiles.
+ * @method Phaser.Physics.Arcade#separateTiles
+ * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
+ * @param {array} tiles - The array of tiles to collide against.
+ * @returns {boolean} Returns true if the body was separated, otherwise false.
+ */
+ separateTiles: function (body, tiles) {
+
+ var tile;
+ var result = false;
+
+ for (var i = 0; i < tiles.length; i++)
+ {
+ tile = tiles[i];
+
+ if (this.separateTile(body, tile))
+ {
+ result = true;
+ }
+ }
+
+ return result;
},
/**
* The core separation function to separate a physics body and a tile.
* @method Phaser.Physics.Arcade#separateTile
- * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
+ * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
* @param {Phaser.Tile} tile - The tile to collide against.
- * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ * @returns {boolean} Returns true if the body was separated, otherwise false.
*/
separateTile: function (body, tile) {
- this._result = (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true));
+ this._intersection = this.tileIntersects(body, tile);
- return this._result;
-
- },
-
- /**
- * The core separation function to separate a physics body and a tile on the x axis.
- * @method Phaser.Physics.Arcade#separateTileX
- * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
- * @param {Phaser.Tile} tile - The tile to collide against.
- * @returns {boolean} Returns true if the bodies were separated, otherwise false.
- */
- separateTileX: function (body, tile, separate) {
-
- // Can't separate two immovable objects (tiles are always immovable)
- if (body.immovable || body.deltaX() === 0 || Phaser.Rectangle.intersects(body.hullX, tile) === false)
+ // If the intersection area is either entirely null, or has a width/height of zero, we bail out now
+ if (this._intersection[4] === 0 || this._intersection[2] === 0 || this._intersection[3] === 0)
{
return false;
}
- this._overlap = 0;
-
- // The hulls overlap, let's process it
- // this._maxOverlap = body.deltaAbsX() + this.OVERLAP_BIAS;
-
- if (body.deltaX() < 0)
+ // They overlap. Any custom callbacks?
+ if (tile.tile.callback || tile.layer.callbacks[tile.tile.index])
{
- // Moving left
- this._overlap = tile.right - body.hullX.x;
-
- // if ((this._overlap > this._maxOverlap) || body.allowCollision.left === false || tile.tile.collideRight === false)
- if (body.allowCollision.left === false || tile.tile.collideRight === false)
+ // A local callback takes priority over a global callback.
+ if (tile.tile.callback && tile.tile.callback.call(tile.tile.callbackContext, body.sprite, tile) === false)
{
- this._overlap = 0;
+ // Is there a tile specific collision callback? If it returns true then we can carry on, otherwise we should abort.
+ return false;
}
- else
+ else if (tile.layer.callbacks[tile.tile.index] && tile.layer.callbacks[tile.tile.index].callback.call(tile.layer.callbacks[tile.tile.index].callbackContext, body.sprite, tile) === false)
{
- body.touching.left = true;
- }
- }
- else
- {
- // Moving right
- this._overlap = body.hullX.right - tile.x;
-
- // if ((this._overlap > this._maxOverlap) || body.allowCollision.right === false || tile.tile.collideLeft === false)
- if (body.allowCollision.right === false || tile.tile.collideLeft === false)
- {
- this._overlap = 0;
- }
- else
- {
- body.touching.right = true;
+ // Is there a tile index collision callback? If it returns true then we can carry on, otherwise we should abort.
+ return false;
}
}
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (this._overlap !== 0)
+ body.overlapX = 0;
+ body.overlapY = 0;
+
+ var process = false;
+
+ if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight && !body.blocked.left)
{
- if (separate)
+ // LEFT
+ body.overlapX = body.left - tile.right;
+
+ if (body.overlapX < 0)
{
- if (body.deltaX() < 0)
- {
- body.x = body.x + this._overlap;
- }
- else
- {
- body.x = body.x - this._overlap;
- }
-
- if (body.bounce.x === 0)
- {
- body.velocity.x = 0;
- }
- else
- {
- body.velocity.x = -body.velocity.x * body.bounce.x;
- }
-
- body.updateHulls();
+ process = true;
}
+ else
+ {
+ body.overlapX = 0;
+ }
+ }
+ else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft && !body.blocked.right)
+ {
+ // RIGHT
+ body.overlapX = body.right - tile.x;
- return true;
+ if (body.overlapX > 0)
+ {
+ process = true;
+ }
+ else
+ {
+ body.overlapX = 0;
+ }
+ }
+
+ if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom && !body.blocked.up)
+ {
+ // UP
+ body.overlapY = body.top - tile.bottom;
+
+ if (body.overlapY < 0)
+ {
+ process = true;
+ }
+ else
+ {
+ body.overlapY = 0;
+ }
+ }
+ else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop && !body.blocked.down)
+ {
+ // DOWN
+ body.overlapY = body.bottom - tile.y;
+
+ if (body.overlapY > 0)
+ {
+ process = true;
+ }
+ else
+ {
+ body.overlapY = 0;
+ }
+ }
+
+ // Only separate on the smallest of the two values if it's a single tile
+ if (body.overlapX !== 0 && body.overlapY !== 0)
+ {
+ if (Math.abs(body.overlapX) > Math.abs(body.overlapY))
+ {
+ body.overlapX = 0;
+ }
+ else
+ {
+ body.overlapY = 0;
+ }
+ }
+
+ // Separate in a single sweep
+ if (process)
+ {
+ return this.processTileSeparation(body);
}
else
{
@@ -35941,88 +39821,55 @@ Phaser.Physics.Arcade.prototype = {
},
/**
- * The core separation function to separate a physics body and a tile on the x axis.
- * @method Phaser.Physics.Arcade#separateTileY
+ * Internal function to process the separation of a physics body from a tile.
+ * @method Phaser.Physics.Arcade#processTileSeparation
+ * @protected
* @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
- * @param {Phaser.Tile} tile - The tile to collide against.
- * @returns {boolean} Returns true if the bodies were separated, otherwise false.
+ * @returns {boolean} Returns true if separated, false if not.
*/
- separateTileY: function (body, tile, separate) {
+ processTileSeparation: function (body) {
- // Can't separate two immovable objects (tiles are always immovable)
- if (body.immovable || body.deltaY() === 0 || Phaser.Rectangle.intersects(body.hullY, tile) === false)
+ if (body.overlapX < 0)
{
- return false;
+ body.x -= body.overlapX;
+ body.left -= body.overlapX;
+ body.right -= body.overlapX;
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ body.blocked.left = true;
+ }
+ else if (body.overlapX > 0)
+ {
+ body.x -= body.overlapX;
+ body.left -= body.overlapX;
+ body.right -= body.overlapX;
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ body.blocked.right = true;
}
- this._overlap = 0;
-
- // The hulls overlap, let's process it
- // this._maxOverlap = body.deltaAbsY() + this.OVERLAP_BIAS;
-
- if (body.deltaY() < 0)
+ if (body.overlapY < 0)
{
- // Moving up
- this._overlap = tile.bottom - body.hullY.y;
-
- // if ((this._overlap > this._maxOverlap) || body.allowCollision.up === false || tile.tile.collideDown === false)
- if (body.allowCollision.up === false || tile.tile.collideDown === false)
- {
- this._overlap = 0;
- }
- else
- {
- body.touching.up = true;
- }
+ body.y -= body.overlapY;
+ body.top -= body.overlapY;
+ body.bottom -= body.overlapY;
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ body.blocked.up = true;
}
- else
+ else if (body.overlapY > 0)
{
- // Moving down
- this._overlap = body.hullY.bottom - tile.y;
-
- // if ((this._overlap > this._maxOverlap) || body.allowCollision.down === false || tile.tile.collideUp === false)
- if (body.allowCollision.down === false || tile.tile.collideUp === false)
- {
- this._overlap = 0;
- }
- else
- {
- body.touching.down = true;
- }
+ body.y -= body.overlapY;
+ body.top -= body.overlapY;
+ body.bottom -= body.overlapY;
+ body.blocked.x = Math.floor(body.x);
+ body.blocked.y = Math.floor(body.y);
+ body.blocked.down = true;
}
- // Then adjust their positions and velocities accordingly (if there was any overlap)
- if (this._overlap !== 0)
- {
- if (separate)
- {
- if (body.deltaY() < 0)
- {
- body.y = body.y + this._overlap;
- }
- else
- {
- body.y = body.y - this._overlap;
- }
+ body.reboundCheck(body.overlapX, body.overlapY, true);
- if (body.bounce.y === 0)
- {
- body.velocity.y = 0;
- }
- else
- {
- body.velocity.y = -body.velocity.y * body.bounce.y;
- }
-
- body.updateHulls();
- }
-
- return true;
- }
- else
- {
- return false;
- }
+ return true;
},
@@ -36172,7 +40019,7 @@ Phaser.Physics.Arcade.prototype = {
/**
* Given the rotation (in radians) and speed calculate the acceleration and return it as a Point object, or set it to the given point object.
- * One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.
+ * One way to use this is: accelerationFromRotation(rotation, 200, sprite.acceleration) which will set the values directly to the sprites acceleration and not create a new Point object.
*
* @method Phaser.Physics.Arcade#accelerationFromRotation
* @param {number} rotation - The angle in radians.
@@ -36392,15 +40239,18 @@ Phaser.Physics.Arcade.prototype = {
};
+Phaser.Physics.Arcade.prototype.constructor = Phaser.Physics.Arcade;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @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, acceleration, bounce values etc all on the Body.
+* The Physics Body is 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.
*
* @class Phaser.Physics.Arcade.Body
* @classdesc Arcade Physics Body Constructor
@@ -36424,29 +40274,17 @@ Phaser.Physics.Arcade.Body = function (sprite) {
*/
this.offset = new Phaser.Point();
- /**
- * @property {number} x - The x position of the physics body.
- * @readonly
- */
- this.x = sprite.x;
-
- /**
- * @property {number} y - The y position of the physics body.
- * @readonly
- */
- this.y = sprite.y;
-
/**
* @property {number} preX - The previous x position of the physics body.
* @readonly
*/
- this.preX = sprite.x;
+ this.preX = sprite.world.x;
/**
* @property {number} preY - The previous y position of the physics body.
* @readonly
*/
- this.preY = sprite.y;
+ this.preY = sprite.world.y;
/**
* @property {number} preRotation - The previous rotation of the physics body.
@@ -36455,53 +40293,262 @@ Phaser.Physics.Arcade.Body = function (sprite) {
this.preRotation = sprite.angle;
/**
- * @property {number} screenX - The x position of the physics body translated to screen space.
+ * @property {Phaser.Point} velocity - The velocity of the Body.
+ */
+ this.velocity = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} acceleration - The acceleration in pixels per second sq. of the Body.
+ */
+ this.acceleration = new Phaser.Point();
+
+ /**
+ * @property {number} speed - The speed in pixels per second sq. of the Body.
+ */
+ this.speed = 0;
+
+ /**
+ * @property {number} angle - The angle of the Body based on its velocity in radians.
+ */
+ this.angle = 0;
+
+ /**
+ * @property {Phaser.Point} gravity - The gravity applied to the motion of the Body. This works in addition to any gravity set on the world.
+ */
+ this.gravity = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. This property determines how much energy a body maintains during a collision, i.e. its bounciness.
+ */
+ this.bounce = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} minVelocity - When a body rebounds off another body or a wall the minVelocity is checked. If the new velocity is lower than minVelocity the body is stopped.
+ * @default
+ */
+ this.minVelocity = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} maxVelocity - The maximum velocity that the Body can reach.
+ * @default
+ */
+ this.maxVelocity = new Phaser.Point(1000, 1000);
+
+ /**
+ * @property {number} angularVelocity - The angular velocity of the Body.
+ * @default
+ */
+ this.angularVelocity = 0;
+
+ /**
+ * @property {number} angularAcceleration - The angular acceleration of the Body.
+ * @default
+ */
+ this.angularAcceleration = 0;
+
+ /**
+ * @property {number} angularDrag - angularDrag is used to calculate friction on the body as it rotates.
+ * @default
+ */
+ this.angularDrag = 0;
+
+ /**
+ * @property {number} maxAngular - The maximum angular velocity that the Body can reach.
+ * @default
+ */
+ this.maxAngular = 1000;
+
+ /**
+ * @property {number} mass - The mass property determines how forces affect the body, as well as how much momentum the body has when it is involved in a collision.
+ * @default
+ */
+ this.mass = 1;
+
+ /**
+ * @property {number} linearDamping - linearDamping is used to calculate friction on the body as it moves through the world. For example, this might be used to simulate air or water friction.
+ * @default
+ */
+ this.linearDamping = 0.0;
+
+ /**
+ * Set the checkCollision properties to control which directions collision is processed for this Body.
+ * For example checkCollision.up = false means it won't collide when the collision happened while moving up.
+ * @property {object} checkCollision - An object containing allowed collision.
+ */
+ this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
+
+ /**
+ * This object is populated with boolean values when the Body collides with another.
+ * touching.up = true means the collision happened to the top of this Body for example.
+ * @property {object} touching - An object containing touching results.
+ */
+ this.touching = { none: true, up: false, down: false, left: false, right: false };
+
+ /**
+ * This object is populated with boolean values when the Body collides with the World bounds or a Tile.
+ * For example if blocked.up is true then the Body cannot move up.
+ * @property {object} blocked - An object containing on which faces this Body is blocked from moving, if any.
+ */
+ this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false };
+
+ /**
+ * @property {number} facing - A const reference to the direction the Body is traveling or facing.
+ * @default
+ */
+ this.facing = Phaser.NONE;
+
+ /**
+ * @property {boolean} rebound - A Body set to rebound will exchange velocity with another Body during collision. Set to false to allow this body to be 'pushed' rather than exchange velocity.
+ * @default
+ */
+ this.rebound = true;
+
+ /**
+ * @property {boolean} immovable - An immovable Body will not receive any impacts or exchanges of velocity from other bodies.
+ * @default
+ */
+ this.immovable = false;
+
+ /**
+ * @property {boolean} moves - Set to true to allow the Physics system (such as velocity) to move this Body, or false to move it manually.
+ * @default
+ */
+ this.moves = true;
+
+ /**
+ * @property {number} rotation - The amount the parent Sprite is rotated.
+ * @default
+ */
+ this.rotation = 0;
+
+ /**
+ * @property {boolean} allowRotation - Allow angular rotation? This will cause the Sprite to be rotated via angularVelocity, etc.
+ * @default
+ */
+ this.allowRotation = true;
+
+ /**
+ * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity value? Note: It will always be influenced by the local gravity if set.
+ * @default
+ */
+ this.allowGravity = true;
+
+ /**
+ * @property {function} customSeparateCallback - If set this callback will be used for Body separation instead of the built-in one. Callback should return true if separated, otherwise false.
+ * @default
+ */
+ this.customSeparateCallback = null;
+
+ /**
+ * @property {object} customSeparateContext - The context in which the customSeparateCallback is called.
+ * @default
+ */
+ this.customSeparateContext = null;
+
+ /**
+ * @property {function} collideCallback - If set this callback will be fired whenever this Body is hit (on any face). It will send three parameters, the face it hit on, this Body and the Body that hit it.
+ * @default
+ */
+ this.collideCallback = null;
+
+ /**
+ * @property {object} collideCallbackContext - The context in which the collideCallback is called.
+ * @default
+ */
+ this.collideCallbackContext = null;
+
+ /**
+ * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
+ * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
+ */
+ this.collideWorldBounds = false;
+
+ /**
+ * @property {Phaser.Physics.Arcade.RECT|Phaser.Physics.Arcade.CIRCLE} type - The type of SAT Shape.
+ */
+ this.type = Phaser.Physics.Arcade.RECT;
+
+ /**
+ * @property {SAT.Box|SAT.Circle|SAT.Polygon} shape - The SAT Collision shape.
+ */
+ this.shape = null;
+
+ /**
+ * @property {SAT.Polygon} polygon - The SAT Polygons, as derived from the Shape.
+ */
+ this.polygon = null;
+
+ /**
+ * @property {number} left - The left-most point of this Body.
* @readonly
*/
- this.screenX = sprite.x;
+ this.left = 0;
/**
- * @property {number} screenY - The y position of the physics body translated to screen space.
+ * @property {number} right - The right-most point of this Body.
* @readonly
*/
- this.screenY = sprite.y;
+ this.right = 0;
/**
- * @property {number} sourceWidth - The un-scaled original size.
+ * @property {number} top - The top-most point of this Body.
* @readonly
*/
- this.sourceWidth = sprite.currentFrame.sourceSizeW;
+ this.top = 0;
/**
- * @property {number} sourceHeight - The un-scaled original size.
+ * @property {number} bottom - The bottom-most point of this Body.
* @readonly
*/
- this.sourceHeight = sprite.currentFrame.sourceSizeH;
+ this.bottom = 0;
/**
- * @property {number} width - The calculated width of the physics body.
+ * @property {number} width - The current width of the Body, taking into account the point rotation.
+ * @readonly
*/
- this.width = sprite.currentFrame.sourceSizeW;
+ this.width = 0;
/**
- * @property .numInternal ID cache
+ * @property {number} height - The current height of the Body, taking into account the point rotation.
+ * @readonly
*/
- this.height = sprite.currentFrame.sourceSizeH;
+ this.height = 0;
/**
- * @property {number} halfWidth - The calculated width / 2 of the physics body.
+ * @property {array} contacts - Used to store references to bodies this Body is in contact with.
+ * @protected
*/
- this.halfWidth = Math.floor(sprite.currentFrame.sourceSizeW / 2);
+ this.contacts = [];
/**
- * @property {number} halfHeight - The calculated height / 2 of the physics body.
+ * @property {number} overlapX - Mostly used internally to store the overlap values from Tile seperation.
+ * @protected
*/
- this.halfHeight = Math.floor(sprite.currentFrame.sourceSizeH / 2);
+ this.overlapX = 0;
/**
- * @property {Phaser.Point} center - The center coordinate of the Physics Body.
+ * @property {number} overlapY - Mostly used internally to store the overlap values from Tile seperation.
+ * @protected
*/
- this.center = new Phaser.Point(this.x + this.halfWidth, this.y + this.halfHeight);
+ this.overlapY = 0;
+
+ /**
+ * @property {Phaser.Point} _temp - Internal cache var.
+ * @private
+ */
+ this._temp = null;
+
+ /**
+ * @property {number} _dx - Internal cache var.
+ * @private
+ */
+ this._dx = 0;
+
+ /**
+ * @property {number} _dy - Internal cache var.
+ * @private
+ */
+ this._dy = 0;
/**
* @property {number} _sx - Internal cache var.
@@ -36516,231 +40563,80 @@ Phaser.Physics.Arcade.Body = function (sprite) {
this._sy = sprite.scale.y;
/**
- * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body.
+ * @property {array} _distances - Internal cache var.
+ * @private
*/
- this.velocity = new Phaser.Point();
+ this._distances = [0, 0, 0, 0];
/**
- * @property {Phaser.Point} acceleration - The velocity in pixels per second sq. of the Body.
+ * @property {number} _vx - Internal cache var.
+ * @private
*/
- this.acceleration = new Phaser.Point();
+ this._vx = 0;
/**
- * @property {Phaser.Point} drag - The drag applied to the motion of the Body.
+ * @property {number} _vy - Internal cache var.
+ * @private
*/
- this.drag = new Phaser.Point();
+ this._vy = 0;
- /**
- * @property {Phaser.Point} gravity - A private Gravity setting for the Body.
- */
- this.gravity = new Phaser.Point();
+ // Set-up the default shape
+ this.setRectangle(sprite.width, sprite.height, 0, 0);
- /**
- * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.
- */
- this.bounce = new Phaser.Point();
-
- /**
- * @property {Phaser.Point} maxVelocity - The maximum velocity in pixels per second sq. that the Body can reach.
- * @default
- */
- this.maxVelocity = new Phaser.Point(10000, 10000);
-
- /**
- * @property {number} angularVelocity - The angular velocity in pixels per second sq. of the Body.
- * @default
- */
- this.angularVelocity = 0;
-
- /**
- * @property {number} angularAcceleration - The angular acceleration in pixels per second sq. of the Body.
- * @default
- */
- this.angularAcceleration = 0;
-
- /**
- * @property {number} angularDrag - The angular drag applied to the rotation of the Body.
- * @default
- */
- this.angularDrag = 0;
-
- /**
- * @property {number} maxAngular - The maximum angular velocity in pixels per second sq. that the Body can reach.
- * @default
- */
- this.maxAngular = 1000;
-
- /**
- * @property {number} mass - The mass of the Body.
- * @default
- */
- this.mass = 1;
-
- /**
- * @property {boolean} skipQuadTree - If the Body is an irregular shape you can set this to true to avoid it being added to the World quad tree.
- * @default
- */
- this.skipQuadTree = false;
-
- /**
- * @property {Array} quadTreeIDs - Internal ID cache.
- * @protected
- */
- this.quadTreeIDs = [];
-
- /**
- * @property {number} quadTreeIndex - Internal ID cache.
- * @protected
- */
- this.quadTreeIndex = -1;
-
- // Allow collision
-
- /**
- * Set the allowCollision properties to control which directions collision is processed for this Body.
- * For example allowCollision.up = false means it won't collide when the collision happened while moving up.
- * @property {object} allowCollision - An object containing allowed collision.
- */
- this.allowCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
-
- /**
- * This object is populated with boolean values when the Body collides with another.
- * touching.up = true means the collision happened to the top of this Body for example.
- * @property {object} touching - An object containing touching results.
- */
- this.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} facing - A const reference to the direction the Body is traveling or facing.
- * @default
- */
- this.facing = Phaser.NONE;
-
- /**
- * @property {boolean} immovable - An immovable Body will not receive any impacts from other bodies.
- * @default
- */
- this.immovable = false;
-
- /**
- * @property {boolean} moves - Set to true to allow the Physics system to move this Body, other false to move it manually.
- * @default
- */
- this.moves = true;
-
- /**
- * @property {number} rotation - The amount the Body is rotated.
- * @default
- */
- this.rotation = 0;
-
- /**
- * @property {boolean} allowRotation - Allow this Body to be rotated? (via angularVelocity, etc)
- * @default
- */
- this.allowRotation = true;
-
- /**
- * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity?
- * @default
- */
- this.allowGravity = true;
-
- /**
- * This flag allows you to disable the custom x separation that takes place by Physics.Arcade.separate.
- * Used in combination with your own collision processHandler you can create whatever type of collision response you need.
- * @property {boolean} customSeparateX - Use a custom separation system or the built-in one?
- * @default
- */
- this.customSeparateX = false;
-
- /**
- * This flag allows you to disable the custom y separation that takes place by Physics.Arcade.separate.
- * Used in combination with your own collision processHandler you can create whatever type of collision response you need.
- * @property {boolean} customSeparateY - Use a custom separation system or the built-in one?
- * @default
- */
- this.customSeparateY = false;
-
- /**
- * When this body collides with another, the amount of overlap is stored here.
- * @property {number} overlapX - The amount of horizontal overlap during the collision.
- */
- this.overlapX = 0;
-
- /**
- * When this body collides with another, the amount of overlap is stored here.
- * @property {number} overlapY - The amount of vertical overlap during the collision.
- */
- this.overlapY = 0;
-
- /**
- * @property {Phaser.Rectangle} hullX - The dynamically calculated hull used during collision.
- */
- this.hullX = new Phaser.Rectangle();
-
- /**
- * @property {Phaser.Rectangle} hullY - The dynamically calculated hull used during collision.
- */
- this.hullY = new Phaser.Rectangle();
-
- /**
- * If a body is overlapping with another body, but neither of them are moving (maybe they spawned on-top of each other?) this is set to true.
- * @property {boolean} embedded - Body embed value.
- */
- this.embedded = false;
-
- /**
- * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
- * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
- */
- this.collideWorldBounds = false;
+ // Set-up contact events
+ this.sprite.events.onBeginContact = new Phaser.Signal();
+ this.sprite.events.onEndContact = new Phaser.Signal();
};
Phaser.Physics.Arcade.Body.prototype = {
/**
- * Internal method.
+ * Internal method that updates the Body scale in relation to the parent Sprite.
*
- * @method Phaser.Physics.Arcade#updateBounds
+ * @method Phaser.Physics.Arcade.Body#updateScale
* @protected
*/
- updateBounds: function (centerX, centerY, scaleX, scaleY) {
+ updateScale: function () {
- if (scaleX != this._sx || scaleY != this._sy)
+ if (this.polygon)
{
- this.width = this.sourceWidth * scaleX;
- this.height = this.sourceHeight * scaleY;
- this.halfWidth = Math.floor(this.width / 2);
- this.halfHeight = Math.floor(this.height / 2);
- this._sx = scaleX;
- this._sy = scaleY;
- this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
+ this.polygon.scale(this.sprite.scale.x / this._sx, this.sprite.scale.y / this._sy);
}
+ else
+ {
+ this.shape.r *= Math.max(this.sprite.scale.x, this.sprite.scale.y);
+ }
+
+ this._sx = this.sprite.scale.x;
+ this._sy = this.sprite.scale.y;
},
/**
- * Internal method.
+ * Internal method that updates the Body position in relation to the parent Sprite.
*
- * @method Phaser.Physics.Arcade#preUpdate
+ * @method Phaser.Physics.Arcade.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.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x;
+ this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y;
+
+ // This covers any motion that happens during this frame, not since the last frame
+ this.preX = this.x;
+ this.preY = this.y;
+ this.preRotation = this.sprite.angle;
+
+ this.rotation = this.preRotation;
+
+ if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy)
+ {
+ this.updateScale();
+ }
+
+ this.checkBlocked();
this.touching.none = true;
this.touching.up = false;
@@ -36748,290 +40644,1135 @@ Phaser.Physics.Arcade.Body.prototype = {
this.touching.left = false;
this.touching.right = false;
- this.embedded = false;
-
- this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x;
- this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y;
-
- this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
- this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
-
- this.preRotation = this.sprite.angle;
-
- this.x = this.preX;
- this.y = this.preY;
- this.rotation = this.preRotation;
-
if (this.moves)
{
- this.game.physics.updateMotion(this);
-
- if (this.collideWorldBounds)
+ if (this._vx !== this.velocity.x || this._vy !== this.velocity.y)
{
- this.checkWorldBounds();
+ // No need to re-calc these if they haven't changed
+ this._vx = this.velocity.x;
+ this._vy = this.velocity.y;
+ this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y);
+ this.angle = Math.atan2(this.velocity.y, this.velocity.x);
}
- this.updateHulls();
- }
+ if (this.game.physics.checkBounds(this))
+ {
+ this.reboundCheck(true, true, true);
+ }
- if (this.skipQuadTree === false && this.allowCollision.none === false && this.sprite.visible && this.sprite.alive)
+ this.applyDamping();
+
+ this.integrateVelocity();
+
+ this.updateBounds();
+
+ this.checkBlocked();
+ }
+ else
{
- this.quadTreeIDs = [];
- this.quadTreeIndex = -1;
- this.game.physics.quadTree.insert(this);
+ this.updateBounds();
}
},
/**
- * Internal method.
+ * Internal method that checks and potentially resets the blocked status flags.
*
- * @method Phaser.Physics.Arcade#postUpdate
+ * @method Phaser.Physics.Arcade.Body#checkBlocked
+ * @protected
+ */
+ checkBlocked: function () {
+
+ if ((this.blocked.left || this.blocked.right) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
+ {
+ this.blocked.left = false;
+ this.blocked.right = false;
+ }
+
+ if ((this.blocked.up || this.blocked.down) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
+ {
+ this.blocked.up = false;
+ this.blocked.down = false;
+ }
+
+ },
+
+ /**
+ * Internal method that updates the left, right, top, bottom, width and height properties.
+ *
+ * @method Phaser.Physics.Arcade.Body#updateBounds
+ * @protected
+ */
+ updateBounds: function () {
+
+ if (this.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ this.left = this.shape.pos.x - this.shape.r;
+ this.right = this.shape.pos.x + this.shape.r;
+ this.top = this.shape.pos.y - this.shape.r;
+ this.bottom = this.shape.pos.y + this.shape.r;
+ }
+ else
+ {
+ this.left = Phaser.Math.minProperty('x', this.polygon.points) + this.polygon.pos.x;
+ this.right = Phaser.Math.maxProperty('x', this.polygon.points) + this.polygon.pos.x;
+ this.top = Phaser.Math.minProperty('y', this.polygon.points) + this.polygon.pos.y;
+ this.bottom = Phaser.Math.maxProperty('y', this.polygon.points) + this.polygon.pos.y;
+ }
+
+ this.width = this.right - this.left;
+ this.height = this.bottom - this.top;
+
+ },
+
+ /**
+ * Internal method that checks the acceleration and applies damping if not set.
+ *
+ * @method Phaser.Physics.Arcade.Body#applyDamping
+ * @protected
+ */
+ applyDamping: function () {
+
+ if (this.linearDamping > 0 && this.acceleration.isZero())
+ {
+ if (this.speed > this.linearDamping)
+ {
+ this.speed -= this.linearDamping;
+ }
+ else
+ {
+ this.speed = 0;
+ }
+
+ // Don't bother if speed 0
+ if (this.speed > 0)
+ {
+ this.velocity.x = Math.cos(this.angle) * this.speed;
+ this.velocity.y = Math.sin(this.angle) * this.speed;
+
+ this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y);
+ this.angle = Math.atan2(this.velocity.y, this.velocity.x);
+ }
+ }
+
+ },
+
+ /**
+ * Check if we're below minVelocity and gravity isn't trying to drag us in the opposite direction.
+ *
+ * @method Phaser.Physics.Arcade.Body#reboundCheck
+ * @protected
+ * @param {boolean} x - Check the X axis?
+ * @param {boolean} y - Check the Y axis?
+ * @param {boolean} rebound - If true it will reverse the velocity on the given axis
+ */
+ reboundCheck: function (x, y, rebound) {
+
+ if (x)
+ {
+ if (rebound && this.bounce.x !== 0 && (this.blocked.left || this.blocked.right || this.touching.left || this.touching.right))
+ {
+ // Don't rebound if they've already rebounded in this frame
+ if (!(this._vx <= 0 && this.velocity.x > 0) && !(this._vx >= 0 && this.velocity.x < 0))
+ {
+ this.velocity.x *= -this.bounce.x;
+ this.angle = Math.atan2(this.velocity.y, this.velocity.x);
+ }
+ }
+
+ if (this.bounce.x === 0 || Math.abs(this.velocity.x) < this.minVelocity.x)
+ {
+ var gx = this.getUpwardForce();
+
+ if (((this.blocked.left || this.touching.left) && (gx < 0 || this.velocity.x < 0)) || ((this.blocked.right || this.touching.right) && (gx > 0 || this.velocity.x > 0)))
+ {
+ this.velocity.x = 0;
+ }
+ }
+ }
+
+ if (y)
+ {
+ if (rebound && this.bounce.y !== 0 && (this.blocked.up || this.blocked.down || this.touching.up || this.touching.down))
+ {
+ // Don't rebound if they've already rebounded in this frame
+ if (!(this._vy <= 0 && this.velocity.y > 0) && !(this._vy >= 0 && this.velocity.y < 0))
+ {
+ this.velocity.y *= -this.bounce.y;
+ this.angle = Math.atan2(this.velocity.y, this.velocity.x);
+ }
+ }
+
+ if (this.bounce.y === 0 || Math.abs(this.velocity.y) < this.minVelocity.y)
+ {
+ var gy = this.getDownwardForce();
+
+ if (((this.blocked.up || this.touching.up) && (gy < 0 || this.velocity.y < 0)) || ((this.blocked.down || this.touching.down) && (gy > 0 || this.velocity.y > 0)))
+ {
+ this.velocity.y = 0;
+ }
+ }
+ }
+
+ },
+
+ /**
+ * Gets the total force being applied on the X axis, including gravity and velocity.
+ *
+ * @method Phaser.Physics.Arcade.Body#getUpwardForce
+ * @return {number} The total force being applied on the X axis.
+ */
+ getUpwardForce: function () {
+
+ if (this.allowGravity)
+ {
+ return this.gravity.x + this.game.physics.gravity.x + this.velocity.x;
+ }
+ else
+ {
+ return this.gravity.x + this.velocity.x;
+ }
+
+ },
+
+ /**
+ * Gets the total force being applied on the X axis, including gravity and velocity.
+ *
+ * @method Phaser.Physics.Arcade.Body#getDownwardForce
+ * @return {number} The total force being applied on the Y axis.
+ */
+ getDownwardForce: function () {
+
+ if (this.allowGravity)
+ {
+ return this.gravity.y + this.game.physics.gravity.y + this.velocity.y;
+ }
+ else
+ {
+ return this.gravity.y + this.velocity.y;
+ }
+
+ },
+
+ /**
+ * Subtracts the given Vector from this Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#sub
+ * @protected
+ * @param {SAT.Vector} v - The vector to substract from this Body.
+ */
+ sub: function (v) {
+
+ this.x -= v.x;
+ this.y -= v.y;
+
+ },
+
+ /**
+ * Adds the given Vector to this Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#add
+ * @protected
+ * @param {SAT.Vector} v - The vector to add to this Body.
+ */
+ add: function (v) {
+
+ this.x += v.x;
+ this.y += v.y;
+
+ },
+
+ /**
+ * Separation response handler.
+ *
+ * @method Phaser.Physics.Arcade.Body#give
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ give: function (body, response) {
+
+ this.add(response.overlapV);
+
+ if (this.rebound)
+ {
+ this.processRebound(body);
+ this.reboundCheck(true, true, false);
+ body.reboundCheck(true, true, false);
+ }
+
+ },
+
+ /**
+ * Separation response handler.
+ *
+ * @method Phaser.Physics.Arcade.Body#take
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ take: function (body, response) {
+
+ this.sub(response.overlapV);
+
+ if (this.rebound)
+ {
+ this.processRebound(body);
+ this.reboundCheck(true, true, false);
+ body.reboundCheck(true, true, false);
+ }
+
+ },
+
+ /**
+ * Split the collision response evenly between the two bodies.
+ *
+ * @method Phaser.Physics.Arcade.Body#split
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ split: function (body, response) {
+
+ response.overlapV.scale(0.5);
+ this.sub(response.overlapV);
+ body.add(response.overlapV);
+
+ if (this.rebound)
+ {
+ this.exchange(body);
+ this.reboundCheck(true, true, false);
+ body.reboundCheck(true, true, false);
+ }
+
+ },
+
+ /**
+ * Exchange velocity with the given Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#exchange
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ */
+ exchange: function (body) {
+
+ if (this.mass === body.mass && this.speed > 0 && body.speed > 0)
+ {
+ // A direct velocity exchange (as they are both moving and have the same mass)
+ this._dx = body.velocity.x;
+ this._dy = body.velocity.y;
+
+ body.velocity.x = this.velocity.x * body.bounce.x;
+ body.velocity.y = this.velocity.y * body.bounce.x;
+
+ this.velocity.x = this._dx * this.bounce.x;
+ this.velocity.y = this._dy * this.bounce.y;
+ }
+ else
+ {
+ var nv1 = Math.sqrt((body.velocity.x * body.velocity.x * body.mass) / this.mass) * ((body.velocity.x > 0) ? 1 : -1);
+ var nv2 = Math.sqrt((this.velocity.x * this.velocity.x * this.mass) / body.mass) * ((this.velocity.x > 0) ? 1 : -1);
+ var average = (nv1 + nv2) * 0.5;
+ nv1 -= average;
+ nv2 -= average;
+
+ this.velocity.x = nv1;
+ body.velocity.x = nv2;
+
+ nv1 = Math.sqrt((body.velocity.y * body.velocity.y * body.mass) / this.mass) * ((body.velocity.y > 0) ? 1 : -1);
+ nv2 = Math.sqrt((this.velocity.y * this.velocity.y * this.mass) / body.mass) * ((this.velocity.y > 0) ? 1 : -1);
+ average = (nv1 + nv2) * 0.5;
+ nv1 -= average;
+ nv2 -= average;
+
+ this.velocity.y = nv1;
+ body.velocity.y = nv2;
+ }
+
+ // update speed / angle?
+
+ },
+
+ /**
+ * Rebound the velocity of this Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#processRebound
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ */
+ processRebound: function (body) {
+
+ // Don't rebound again if they've already rebounded in this frame
+ if (!(this._vx <= 0 && this.velocity.x > 0) && !(this._vx >= 0 && this.velocity.x < 0))
+ {
+ this.velocity.x = body.velocity.x - this.velocity.x * this.bounce.x;
+ }
+
+ if (!(this._vy <= 0 && this.velocity.y > 0) && !(this._vy >= 0 && this.velocity.y < 0))
+ {
+ this.velocity.y = body.velocity.y - this.velocity.y * this.bounce.y;
+ }
+
+ this.angle = Math.atan2(this.velocity.y, this.velocity.x);
+
+ this.reboundCheck(true, true, false);
+
+ },
+
+ /**
+ * Checks for an overlap between this Body and the given Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#overlap
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that is being checked against this Body.
+ * @param {SAT.Response} response - SAT Response handler.
+ * @return {boolean} True if the two bodies overlap, otherwise false.
+ */
+ overlap: function (body, response) {
+
+ var result = false;
+
+ if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
+ {
+ result = SAT.testPolygonPolygon(this.polygon, body.polygon, response);
+ }
+ else if (this.type === Phaser.Physics.Arcade.CIRCLE && body.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ result = SAT.testCircleCircle(this.shape, body.shape, response);
+ }
+ else if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && body.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ result = SAT.testPolygonCircle(this.polygon, body.shape, response);
+ }
+ else if (this.type === Phaser.Physics.Arcade.CIRCLE && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
+ {
+ result = SAT.testCirclePolygon(this.shape, body.polygon, response);
+ }
+
+ if (!result)
+ {
+ this.removeContact(body);
+ }
+
+ return result;
+
+ },
+
+ /**
+ * Checks if this Body is already in contact with the given Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#inContact
+ * @param {Phaser.Physics.Arcade.Body} body - The Body to be checked.
+ * @return {boolean} True if the given Body is already in contact with this Body.
+ */
+ inContact: function (body) {
+
+ return (this.contacts.indexOf(body) != -1);
+
+ },
+
+ /**
+ * Adds the given Body to the contact list of this Body. Also adds this Body to the contact list of the given Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#addContact
+ * @param {Phaser.Physics.Arcade.Body} body - The Body to be added.
+ * @return {boolean} True if the given Body was added to this contact list, false if already on it.
+ */
+ addContact: function (body) {
+
+ if (this.inContact(body))
+ {
+ return false;
+ }
+
+ this.contacts.push(body);
+
+ this.sprite.events.onBeginContact.dispatch(this.sprite, body.sprite, this, body);
+
+ body.addContact(this);
+
+ return true;
+
+ },
+
+ /**
+ * Removes the given Body from the contact list of this Body. Also removes this Body from the contact list of the given Body.
+ *
+ * @method Phaser.Physics.Arcade.Body#removeContact
+ * @param {Phaser.Physics.Arcade.Body} body - The Body to be removed.
+ * @return {boolean} True if the given Body was removed from this contact list, false if wasn't on it.
+ */
+ removeContact: function (body) {
+
+ if (!this.inContact(body))
+ {
+ return false;
+ }
+
+ this.contacts.splice(this.contacts.indexOf(body), 1);
+
+ this.sprite.events.onEndContact.dispatch(this.sprite, body.sprite, this, body);
+
+ body.removeContact(this);
+
+ return true;
+
+ },
+
+ /**
+ * This separates this Body from the given Body unless a customSeparateCallback is set.
+ * It assumes they have already been overlap checked and the resulting overlap is stored in the SAT response.
+ *
+ * @method Phaser.Physics.Arcade.Body#separate
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body to be separated from this one.
+ * @param {SAT.Response} response - SAT Response handler.
+ * @return {boolean} True if the bodies were separated, false if not (for example checkCollide allows them to pass through)
+ */
+ separate: function (body, response) {
+
+ if (this.inContact(body))
+ {
+ return false;
+ }
+
+ this._distances[0] = body.right - this.x; // Distance of B to face on left side of A
+ this._distances[1] = this.right - body.x; // Distance of B to face on right side of A
+ this._distances[2] = body.bottom - this.y; // Distance of B to face on bottom side of A
+ this._distances[3] = this.bottom - body.y; // Distance of B to face on top side of A
+
+ // If we've zero distance then check for side-slicing
+ if (response.overlapN.x && (this._distances[0] === 0 || this._distances[1] === 0))
+ {
+ response.overlapN.x = false;
+ response.overlapN.y = true;
+ }
+ else if (response.overlapN.y && (this._distances[2] === 0 || this._distances[3] === 0))
+ {
+ response.overlapN.x = true;
+ response.overlapN.y = false;
+ }
+
+ if (this.customSeparateCallback)
+ {
+ return this.customSeparateCallback.call(this.customSeparateContext, this, response, this._distances);
+ }
+
+ var hasSeparated = false;
+
+ if (response.overlapN.x)
+ {
+ // Which is smaller? Left or Right?
+ if (this._distances[0] < this._distances[1])
+ {
+ hasSeparated = this.hitLeft(body, response);
+ }
+ else if (this._distances[1] < this._distances[0])
+ {
+ hasSeparated = this.hitRight(body, response);
+ }
+ }
+ else if (response.overlapN.y)
+ {
+ // Which is smaller? Top or Bottom?
+ if (this._distances[2] < this._distances[3])
+ {
+ hasSeparated = this.hitTop(body, response);
+ }
+ else if (this._distances[3] < this._distances[2])
+ {
+ hasSeparated = this.hitBottom(body, response);
+ }
+ }
+
+ if (hasSeparated)
+ {
+ this.game.physics.checkBounds(this);
+ this.game.physics.checkBounds(body);
+ }
+ else
+ {
+ // They can only contact like this if at least one of their sides is open, otherwise it's a separation
+ // if (!this.checkCollision.up || !this.checkCollision.down || !this.checkCollision.left || !this.checkCollision.right || !body.checkCollision.up || !body.checkCollision.down || !body.checkCollision.left || !body.checkCollision.right)
+ // {
+ this.addContact(body);
+ // }
+ }
+
+ return hasSeparated;
+
+ },
+
+ /**
+ * Process a collision with the left face of this Body.
+ * Collision and separation can be further checked by setting a collideCallback.
+ * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
+ * If the callback returns true then separation, rebounds and the touching flags will all be set.
+ * If it returns false this will be skipped and must be handled manually.
+ *
+ * @method Phaser.Physics.Arcade.Body#hitLeft
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ hitLeft: function (body, response) {
+
+ if (!this.checkCollision.left || !body.checkCollision.right)
+ {
+ return false;
+ }
+
+ if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.LEFT, this, body, response))
+ {
+ return;
+ }
+
+ if (!this.moves || this.immovable || this.blocked.right || this.touching.right)
+ {
+ body.give(this, response);
+ }
+ else
+ {
+ if (body.immovable || body.blocked.left || body.touching.left)
+ {
+ // We take the full separation
+ this.take(body, response);
+ }
+ else
+ {
+ // Share out the separation
+ this.split(body, response);
+ }
+ }
+
+ this.touching.left = true;
+ body.touching.right = true;
+
+ },
+
+ /**
+ * Process a collision with the right face of this Body.
+ * Collision and separation can be further checked by setting a collideCallback.
+ * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
+ * If the callback returns true then separation, rebounds and the touching flags will all be set.
+ * If it returns false this will be skipped and must be handled manually.
+ *
+ * @method Phaser.Physics.Arcade.Body#hitRight
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ hitRight: function (body, response) {
+
+ if (!this.checkCollision.right || !body.checkCollision.left)
+ {
+ return false;
+ }
+
+ if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.RIGHT, this, body))
+ {
+ return;
+ }
+
+ if (!this.moves || this.immovable || this.blocked.left || this.touching.left)
+ {
+ body.give(this, response);
+ }
+ else
+ {
+ if (body.immovable || body.blocked.right || body.touching.right)
+ {
+ // We take the full separation
+ this.take(body, response);
+ }
+ else
+ {
+ // Share out the separation
+ this.split(body, response);
+ }
+ }
+
+ this.touching.right = true;
+ body.touching.left = true;
+
+ },
+
+ /**
+ * Process a collision with the top face of this Body.
+ * Collision and separation can be further checked by setting a collideCallback.
+ * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
+ * If the callback returns true then separation, rebounds and the touching flags will all be set.
+ * If it returns false this will be skipped and must be handled manually.
+ *
+ * @method Phaser.Physics.Arcade.Body#hitTop
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ hitTop: function (body, response) {
+
+ if (!this.checkCollision.up || !body.checkCollision.down)
+ {
+ return false;
+ }
+
+ if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.UP, this, body))
+ {
+ return false;
+ }
+
+ if (!this.moves || this.immovable || this.blocked.down || this.touching.down)
+ {
+ body.give(this, response);
+ }
+ else
+ {
+ if (body.immovable || body.blocked.up || body.touching.up)
+ {
+ // We take the full separation
+ this.take(body, response);
+ }
+ else
+ {
+ // Share out the separation
+ this.split(body, response);
+ }
+ }
+
+ this.touching.up = true;
+ body.touching.down = true;
+
+ return true;
+
+ },
+
+ /**
+ * Process a collision with the bottom face of this Body.
+ * Collision and separation can be further checked by setting a collideCallback.
+ * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
+ * If the callback returns true then separation, rebounds and the touching flags will all be set.
+ * If it returns false this will be skipped and must be handled manually.
+ *
+ * @method Phaser.Physics.Arcade.Body#hitBottom
+ * @protected
+ * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
+ * @param {SAT.Response} response - The SAT Response object containing the collision data.
+ */
+ hitBottom: function (body, response) {
+
+ if (!this.checkCollision.down || !body.checkCollision.up)
+ {
+ return false;
+ }
+
+ if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.DOWN, this, body))
+ {
+ return false;
+ }
+
+ if (!this.moves || this.immovable || this.blocked.up || this.touching.up)
+ {
+ body.give(this, response);
+ }
+ else
+ {
+ if (body.immovable || body.blocked.down || body.touching.down)
+ {
+ // We take the full separation
+ this.take(body, response);
+ }
+ else
+ {
+ // Share out the separation
+ this.split(body, response);
+ }
+ }
+
+ this.touching.down = true;
+ body.touching.up = true;
+
+ return true;
+
+ },
+
+ /**
+ * Internal method. Integrates velocity, global gravity and the delta timer.
+ *
+ * @method Phaser.Physics.Arcade.Body#integrateVelocity
+ * @protected
+ */
+ integrateVelocity: function () {
+
+ this._temp = this.game.physics.updateMotion(this);
+ this._dx = this.game.time.physicsElapsed * (this.velocity.x + this._temp.x / 2);
+ this._dy = this.game.time.physicsElapsed * (this.velocity.y + this._temp.y / 2);
+
+ // positive = RIGHT / DOWN
+ // negative = LEFT / UP
+
+ if ((this._dx < 0 && !this.blocked.left && !this.touching.left) || (this._dx > 0 && !this.blocked.right && !this.touching.right))
+ {
+ this.x += this._dx;
+ this.velocity.x += this._temp.x;
+ }
+
+ if ((this._dy < 0 && !this.blocked.up && !this.touching.up) || (this._dy > 0 && !this.blocked.down && !this.touching.down))
+ {
+ this.y += this._dy;
+ this.velocity.y += this._temp.y;
+ }
+
+ if (this.velocity.x > this.maxVelocity.x)
+ {
+ this.velocity.x = this.maxVelocity.x;
+ }
+ else if (this.velocity.x < -this.maxVelocity.x)
+ {
+ this.velocity.x = -this.maxVelocity.x;
+ }
+
+ if (this.velocity.y > this.maxVelocity.y)
+ {
+ this.velocity.y = this.maxVelocity.y;
+ }
+ else if (this.velocity.y < -this.maxVelocity.y)
+ {
+ this.velocity.y = -this.maxVelocity.y;
+ }
+
+ },
+
+ /**
+ * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished.
+ *
+ * @method Phaser.Physics.Arcade.Body#postUpdate
* @protected
*/
postUpdate: function () {
- if (this.deltaX() < 0)
+ if (this.moves)
{
- this.facing = Phaser.LEFT;
- }
- else if (this.deltaX() > 0)
- {
- this.facing = Phaser.RIGHT;
- }
+ this.game.physics.checkBounds(this);
- if (this.deltaY() < 0)
- {
- this.facing = Phaser.UP;
- }
- else if (this.deltaY() > 0)
- {
- this.facing = Phaser.DOWN;
- }
+ this.reboundCheck(true, true, true);
- if (this.deltaX() !== 0 || this.deltaY() !== 0)
- {
- this.sprite.x += this.deltaX();
- this.sprite.y += this.deltaY();
- this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
- }
+ this._dx = this.deltaX();
+ this._dy = this.deltaY();
- if (this.allowRotation)
- {
- this.sprite.angle += this.deltaZ();
+ if (this._dx < 0)
+ {
+ this.facing = Phaser.LEFT;
+ }
+ else if (this._dx > 0)
+ {
+ this.facing = Phaser.RIGHT;
+ }
+
+ if (this._dy < 0)
+ {
+ this.facing = Phaser.UP;
+ }
+ else if (this._dy > 0)
+ {
+ this.facing = Phaser.DOWN;
+ }
+
+ if (this._dx !== 0 || this._dy !== 0)
+ {
+ this.sprite.x += this._dx;
+ this.sprite.y += this._dy;
+ }
+
+ if (this.allowRotation && this.deltaZ() !== 0)
+ {
+ this.sprite.angle += this.deltaZ();
+ }
+
+ if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy)
+ {
+ this.updateScale();
+ }
}
},
/**
- * Internal method.
+ * Resets the Body motion values: velocity, acceleration, angularVelocity and angularAcceleration.
+ * Also resets the forces to defaults: gravity, bounce, minVelocity,maxVelocity, angularDrag, maxAngular, mass, friction and checkCollision if 'full' specified.
*
- * @method Phaser.Physics.Arcade#updateHulls
- * @protected
+ * @method Phaser.Physics.Arcade.Body#reset
+ * @param {boolean} [full=false] - A full reset clears down settings you may have set, such as gravity, bounce and drag. A non-full reset just clears motion values.
*/
- updateHulls: function () {
+ reset: function (full) {
- this.hullX.setTo(this.x, this.preY, this.width, this.height);
- this.hullY.setTo(this.preX, this.y, this.width, this.height);
+ if (typeof full === 'undefined') { full = false; }
- },
-
- /**
- * Internal method.
- *
- * @method Phaser.Physics.Arcade#checkWorldBounds
- * @protected
- */
- checkWorldBounds: function () {
-
- if (this.x < this.game.world.bounds.x)
+ if (full)
{
- this.x = this.game.world.bounds.x;
- this.velocity.x *= -this.bounce.x;
+ this.gravity.setTo(0, 0);
+ this.bounce.setTo(0, 0);
+ this.minVelocity.setTo(5, 5);
+ this.maxVelocity.setTo(1000, 1000);
+ this.angularDrag = 0;
+ this.maxAngular = 1000;
+ this.mass = 1;
+ this.friction = 0.0;
+ this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
}
- else if (this.right > this.game.world.bounds.right)
- {
- this.x = this.game.world.bounds.right - this.width;
- this.velocity.x *= -this.bounce.x;
- }
-
- if (this.y < this.game.world.bounds.y)
- {
- this.y = this.game.world.bounds.y;
- this.velocity.y *= -this.bounce.y;
- }
- else if (this.bottom > this.game.world.bounds.bottom)
- {
- this.y = this.game.world.bounds.bottom - this.height;
- this.velocity.y *= -this.bounce.y;
- }
-
- },
-
- /**
- * You can modify the size of the physics Body to be any dimension you need.
- * So it could be smaller or larger than the parent Sprite. You can also control the x and y offset, which
- * is the position of the Body relative to the top-left of the Sprite.
- *
- * @method Phaser.Physics.Arcade#setSize
- * @param {number} width - The width of the Body.
- * @param {number} height - The height of the Body.
- * @param {number} offsetX - The X offset of the Body from the Sprite position.
- * @param {number} offsetY - The Y offset of the Body from the Sprite position.
- */
- setSize: function (width, height, offsetX, offsetY) {
-
- offsetX = offsetX || this.offset.x;
- offsetY = offsetY || this.offset.y;
-
- this.sourceWidth = width;
- this.sourceHeight = height;
- this.width = this.sourceWidth * this._sx;
- this.height = this.sourceHeight * this._sy;
- this.halfWidth = Math.floor(this.width / 2);
- this.halfHeight = Math.floor(this.height / 2);
- this.offset.setTo(offsetX, offsetY);
-
- this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
-
- },
-
- /**
- * Resets all Body values (velocity, acceleration, rotation, etc)
- *
- * @method Phaser.Physics.Arcade#reset
- */
- reset: function () {
this.velocity.setTo(0, 0);
this.acceleration.setTo(0, 0);
-
this.angularVelocity = 0;
this.angularAcceleration = 0;
- this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
- this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
- this.preRotation = this.sprite.angle;
+ this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false };
+ this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x;
+ this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y;
+ this.preX = this.x;
+ this.preY = this.y;
+ this.updateBounds();
- this.x = this.preX;
- this.y = this.preY;
- this.rotation = this.preRotation;
-
- this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
+ this.contacts.length = 0;
},
/**
- * Returns the absolute delta x value.
+ * Destroys this Body and all references it holds to other objects.
*
- * @method Phaser.Physics.Arcade.Body#deltaAbsX
- * @return {number} The absolute delta value.
+ * @method Phaser.Physics.Arcade.Body#destroy
*/
- deltaAbsX: function () {
- return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX());
+ destroy: function () {
+
+ this.sprite = null;
+
+ this.collideCallback = null;
+ this.collideCallbackContext = null;
+
+ this.customSeparateCallback = null;
+ this.customSeparateContext = null;
+
+ this.contacts.length = 0;
+
},
/**
- * Returns the absolute delta y value.
+ * Sets this Body to use a circle of the given radius for all collision.
+ * The Circle will be centered on the center of the Sprite by default, but can be adjusted via the Body.offset property and the setCircle x/y parameters.
*
- * @method Phaser.Physics.Arcade.Body#deltaAbsY
- * @return {number} The absolute delta value.
+ * @method Phaser.Physics.Arcade.Body#setCircle
+ * @param {number} radius - The radius of this circle (in pixels)
+ * @param {number} [offsetX=0] - The x amount the circle will be offset from the Sprites center.
+ * @param {number} [offsetY=0] - The y amount the circle will be offset from the Sprites center.
*/
- deltaAbsY: function () {
- return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY());
+ setCircle: function (radius, offsetX, offsetY) {
+
+ if (typeof offsetX === 'undefined') { offsetX = this.sprite._cache.halfWidth; }
+ if (typeof offsetY === 'undefined') { offsetY = this.sprite._cache.halfHeight; }
+
+ this.type = Phaser.Physics.Arcade.CIRCLE;
+ this.shape = new SAT.Circle(new SAT.Vector(this.sprite.x, this.sprite.y), radius);
+ this.polygon = null;
+
+ this.offset.setTo(offsetX, offsetY);
+
},
/**
- * Returns the delta x value. The difference between Body.x now and in the previous step.
+ * Sets this Body to use a rectangle for all collision.
+ * If you don't specify any parameters it will be sized to match the parent Sprites current width and height (including scale factor) and centered on the sprite.
+ *
+ * @method Phaser.Physics.Arcade.Body#setRectangle
+ * @param {number} [width] - The width of the rectangle. If not specified it will default to the width of the parent Sprite.
+ * @param {number} [height] - The height of the rectangle. If not specified it will default to the height of the parent Sprite.
+ * @param {number} [translateX] - The x amount the rectangle will be translated from the Sprites center.
+ * @param {number} [translateY] - The y amount the rectangle will be translated from the Sprites center.
+ */
+ setRectangle: function (width, height, translateX, translateY) {
+
+ if (typeof width === 'undefined') { width = this.sprite.width; }
+ if (typeof height === 'undefined') { height = this.sprite.height; }
+ if (typeof translateX === 'undefined') { translateX = -this.sprite._cache.halfWidth; }
+ if (typeof translateY === 'undefined') { translateY = -this.sprite._cache.halfHeight; }
+
+ this.type = Phaser.Physics.Arcade.RECT;
+ this.shape = new SAT.Box(new SAT.Vector(this.sprite.world.x, this.sprite.world.y), width, height);
+ this.polygon = this.shape.toPolygon();
+ this.polygon.translate(translateX, translateY);
+
+ this.offset.setTo(0, 0);
+
+ },
+
+ /**
+ * Sets this Body to use a convex polygon for collision.
+ * The points are specified in a counter-clockwise direction and must create a convex polygon.
+ * Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin.
+ *
+ * @method Phaser.Physics.Arcade.Body#setPolygon
+ * @param {(SAT.Vector[]|number[]|...SAT.Vector|...number)} points - This can be an array of Vectors that form the polygon,
+ * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
+ * all the points of the polygon e.g. `setPolygon(new SAT.Vector(), new SAT.Vector(), ...)`, or the
+ * arguments passed can be flat x,y values e.g. `setPolygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers.
+ */
+ setPolygon: function (points) {
+
+ this.type = Phaser.Physics.Arcade.POLYGON;
+ this.shape = null;
+
+ if (!Array.isArray(points))
+ {
+ points = Array.prototype.slice.call(arguments);
+ }
+
+ if (typeof points[0] === 'number')
+ {
+ var p = [];
+
+ for (var i = 0, len = points.length; i < len; i += 2)
+ {
+ p.push(new SAT.Vector(points[i], points[i + 1]));
+ }
+
+ points = p;
+ }
+
+ this.polygon = new SAT.Polygon(new SAT.Vector(this.sprite.center.x, this.sprite.center.y), points);
+
+ this.offset.setTo(0, 0);
+
+ },
+
+ /**
+ * Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles.
+ * See also the Body.offset property.
+ *
+ * @method Phaser.Physics.Arcade.Body#translate
+ * @param {number} x - The x amount the polygon or rectangle will be translated by from the Sprite.
+ * @param {number} y - The y amount the polygon or rectangle will be translated by from the Sprite.
+ */
+ translate: function (x, y) {
+
+ if (this.polygon)
+ {
+ this.polygon.translate(x, y);
+ }
+
+ },
+
+ /**
+ * Determines if this Body is 'on the floor', which means in contact with a Tile or World bounds, or other object that has set 'down' as blocked.
+ *
+ * @method Phaser.Physics.Arcade.Body#onFloor
+ * @return {boolean} True if this Body is 'on the floor', which means in contact with a Tile or World bounds, or object that has set 'down' as blocked.
+ */
+ onFloor: function () {
+ return this.blocked.down;
+ },
+
+ /**
+ * Determins if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground.
+ *
+ * @method Phaser.Physics.Arcade.Body#onWall
+ * @return {boolean} True if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground.
+ */
+ onWall: function () {
+ return (!this.blocked.down && (this.blocked.left || this.blocked.right));
+ },
+
+ /**
+ * Returns the delta x value. The amount the Body has moved horizontally in the current step.
*
* @method Phaser.Physics.Arcade.Body#deltaX
- * @return {number} The delta value.
+ * @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
*/
deltaX: function () {
return this.x - this.preX;
},
/**
- * Returns the delta y value. The difference between Body.y now and in the previous step.
+ * Returns the delta y value. The amount the Body has moved vertically in the current step.
*
* @method Phaser.Physics.Arcade.Body#deltaY
- * @return {number} The delta value.
+ * @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
*/
deltaY: function () {
return this.y - this.preY;
},
+ /**
+ * Returns the delta z value. The amount the Body has rotated in the current step.
+ *
+ * @method Phaser.Physics.Arcade.Body#deltaZ
+ * @return {number} The delta value.
+ */
deltaZ: function () {
return this.rotation - this.preRotation;
}
};
+Phaser.Physics.Arcade.Body.prototype.constructor = Phaser.Physics.Arcade.Body;
+
/**
-* @name Phaser.Physics.Arcade.Body#bottom
-* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
+* @name Phaser.Physics.Arcade.Body#x
+* @property {number} x - The x coordinate of this Body.
*/
-Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", {
+Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "x", {
- /**
- * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
- * @method bottom
- * @return {number}
- */
get: function () {
- return this.y + this.height;
- },
-
- /**
- * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
- * @method bottom
- * @param {number} value
- */
- set: function (value) {
-
- if (value <= this.y)
+
+ if (this.type === Phaser.Physics.Arcade.CIRCLE)
{
- this.height = 0;
+ return this.shape.pos.x;
}
else
{
- this.height = (this.y - value);
+ return this.polygon.pos.x;
}
-
+
+ },
+
+ set: function (value) {
+
+ if (this.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ this.shape.pos.x = value;
+ }
+ else
+ {
+ this.polygon.pos.x = value;
+ }
+
}
});
/**
-* @name Phaser.Physics.Arcade.Body#right
-* @property {number} right - The right value of this Body (same as Body.x + Body.width)
+* @name Phaser.Physics.Arcade.Body#y
+* @property {number} y - The y coordinate of this Body.
*/
-Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
+Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "y", {
- /**
- * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
- * However it does affect the width property.
- * @method right
- * @return {number}
- */
get: function () {
- return this.x + this.width;
- },
-
- /**
- * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
- * However it does affect the width property.
- * @method right
- * @param {number} value
- */
- set: function (value) {
-
- if (value <= this.x)
+
+ if (this.type === Phaser.Physics.Arcade.CIRCLE)
{
- this.width = 0;
+ return this.shape.pos.y;
}
else
{
- this.width = this.x + value;
+ return this.polygon.pos.y;
+ }
+
+ },
+
+ set: function (value) {
+
+ if (this.type === Phaser.Physics.Arcade.CIRCLE)
+ {
+ this.shape.pos.y = value;
+ }
+ else
+ {
+ this.polygon.pos.y = value;
}
}
@@ -37040,7 +41781,7 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -37117,10 +41858,13 @@ Phaser.Particles.prototype = {
}
};
+
+Phaser.Particles.prototype.constructor = Phaser.Particles;
+
Phaser.Particles.Arcade = {}
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -37142,7 +41886,6 @@ Phaser.Particles.Arcade = {}
Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
/**
- * The total number of particles in this emitter.
* @property {number} maxParticles - The total number of particles in this emitter..
* @default
*/
@@ -37156,7 +41899,8 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
this.name = 'emitter' + this.game.particles.ID++;
/**
- * @property {Description} type - Description.
+ * @property {number} type - Internal Phaser Type value.
+ * @protected
*/
this.type = Phaser.EMITTER;
@@ -37185,140 +41929,114 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
this.height = 1;
/**
- * The minimum possible velocity of a particle.
- * The default value is (-100,-100).
- * @property {Phaser.Point} minParticleSpeed
+ * @property {Phaser.Point} minParticleSpeed - The minimum possible velocity of a particle.
+ * @default
*/
this.minParticleSpeed = new Phaser.Point(-100, -100);
/**
- * The maximum possible velocity of a particle.
- * The default value is (100,100).
- * @property {Phaser.Point} maxParticleSpeed
+ * @property {Phaser.Point} maxParticleSpeed - The maximum possible velocity of a particle.
+ * @default
*/
this.maxParticleSpeed = new Phaser.Point(100, 100);
/**
- * The minimum possible scale of a particle.
- * The default value is 1.
- * @property {number} minParticleScale
+ * @property {number} minParticleScale - The minimum possible scale of a particle.
* @default
*/
this.minParticleScale = 1;
/**
- * The maximum possible scale of a particle.
- * The default value is 1.
- * @property {number} maxParticleScale
+ * @property {number} maxParticleScale - The maximum possible scale of a particle.
* @default
*/
this.maxParticleScale = 1;
/**
- * The minimum possible angular velocity of a particle. The default value is -360.
- * @property {number} minRotation
+ * @property {number} minRotation - The minimum possible angular velocity of a particle.
* @default
*/
this.minRotation = -360;
/**
- * The maximum possible angular velocity of a particle. The default value is 360.
- * @property {number} maxRotation
+ * @property {number} maxRotation - The maximum possible angular velocity of a particle.
* @default
*/
this.maxRotation = 360;
/**
- * Sets the gravity.y of each particle to this value on launch.
- * @property {number} gravity
+ * @property {number} gravity - Sets the `body.gravity.y` of each particle sprite to this value on launch.
* @default
*/
- this.gravity = 2;
+ this.gravity = 100;
/**
- * Set your own particle class type here.
- * @property {Description} particleClass
+ * @property {any} particleClass - For emitting your own particle class types.
* @default
*/
this.particleClass = null;
/**
- * The X and Y drag component of particles launched from the emitter.
- * @property {Phaser.Point} particleDrag
+ * @property {number} particleFriction - The friction component of particles launched from the emitter.
+ * @default
*/
- this.particleDrag = new Phaser.Point();
+ this.particleFriction = 0;
/**
- * The angular drag component of particles launched from the emitter if they are rotating.
- * @property {number} angularDrag
+ * @property {number} angularDrag - The angular drag component of particles launched from the emitter if they are rotating.
* @default
*/
this.angularDrag = 0;
/**
- * How often a particle is emitted in ms (if emitter is started with Explode === false).
- * @property {boolean} frequency
+ * @property {boolean} frequency - How often a particle is emitted in ms (if emitter is started with Explode === false).
* @default
*/
this.frequency = 100;
/**
- * How long each particle lives once it is emitted in ms. Default is 2 seconds.
- * Set lifespan to 'zero' for particles to live forever.
- * @property {number} lifespan
+ * @property {number} lifespan - How long each particle lives once it is emitted in ms. Default is 2 seconds. Set lifespan to 'zero' for particles to live forever.
* @default
*/
this.lifespan = 2000;
/**
- * How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce.
- * @property {Phaser.Point} bounce
+ * @property {Phaser.Point} bounce - How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce.
*/
this.bounce = new Phaser.Point();
/**
- * Internal helper for deciding how many particles to launch.
- * @property {number} _quantity
+ * @property {number} _quantity - Internal helper for deciding how many particles to launch.
* @private
- * @default
*/
this._quantity = 0;
/**
- * Internal helper for deciding when to launch particles or kill them.
- * @property {number} _timer
+ * @property {number} _timer - Internal helper for deciding when to launch particles or kill them.
* @private
- * @default
*/
this._timer = 0;
/**
- * Internal counter for figuring out how many particles to launch.
- * @property {number} _counter
+ * @property {number} _counter - Internal counter for figuring out how many particles to launch.
* @private
- * @default
*/
this._counter = 0;
/**
- * Internal helper for the style of particle emission (all at once, or one at a time).
- * @property {boolean} _explode
+ * @property {boolean} _explode - Internal helper for the style of particle emission (all at once, or one at a time).
* @private
- * @default
*/
this._explode = true;
/**
- * Determines whether the emitter is currently emitting particles.
- * It is totally safe to directly toggle this.
- * @property {boolean} on
+ * @property {boolean} on - Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this.
* @default
*/
this.on = false;
/**
- * Determines whether the emitter is being updated by the core game loop.
- * @property {boolean} exists
+ * @property {boolean} exists - Determines whether the emitter is being updated by the core game loop.
* @default
*/
this.exists = true;
@@ -37392,43 +42110,35 @@ Phaser.Particles.Arcade.Emitter.prototype.update = function () {
* This function generates a new array of particle sprites to attach to the emitter.
*
* @method Phaser.Particles.Arcade.Emitter#makeParticles
-* @param {Description} keys - Description.
-* @param {number} frames - Description.
-* @param {number} quantity - The number of particles to generate when using the "create from image" option.
-* @param {number} collide - Description.
-* @param {boolean} collideWorldBounds - Description.
-* @return This Emitter instance (nice for chaining stuff together, if you're into that).
+* @param {array|string} keys - A string or an array of strings that the particle sprites will use as their texture. If an array one is picked at random.
+* @param {array|number} frames - A frame number, or array of frames that the sprite will use. If an array one is picked at random.
+* @param {number} quantity - The number of particles to generate.
+* @param {boolean} [collide=false] - Sets the checkCollision.none flag on the particle sprites body.
+* @param {boolean} [collideWorldBounds=false] - A particle 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.
+* @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
*/
Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames, quantity, collide, collideWorldBounds) {
- if (typeof frames == 'undefined')
- {
- frames = 0;
- }
-
- quantity = quantity || this.maxParticles;
- collide = collide || 0;
-
- if (typeof collideWorldBounds == 'undefined')
- {
- collideWorldBounds = false;
- }
+ if (typeof frames === 'undefined') { frames = 0; }
+ if (typeof quantity === 'undefined') { quantity = this.maxParticles; }
+ if (typeof collide === 'undefined') { collide = false; }
+ if (typeof collideWorldBounds === 'undefined') { collideWorldBounds = false; }
var particle;
var i = 0;
var rndKey = keys;
- var rndFrame = 0;
+ var rndFrame = frames;
while (i < quantity)
{
- if (this.particleClass == null)
+ if (this.particleClass === null)
{
- if (typeof keys == 'object')
+ if (typeof keys === 'object')
{
rndKey = this.game.rnd.pick(keys);
}
- if (typeof frames == 'object')
+ if (typeof frames === 'object')
{
rndFrame = this.game.rnd.pick(frames);
}
@@ -37440,14 +42150,14 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
// particle = new this.particleClass(this.game);
// }
- if (collide > 0)
+ if (collide)
{
- particle.body.allowCollision.any = true;
- particle.body.allowCollision.none = false;
+ particle.body.checkCollision.any = true;
+ particle.body.checkCollision.none = false;
}
else
{
- particle.body.allowCollision.none = true;
+ particle.body.checkCollision.none = true;
}
particle.body.collideWorldBounds = collideWorldBounds;
@@ -37467,9 +42177,9 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
}
/**
- * Call this function to turn off all the particles and the emitter.
- * @method Phaser.Particles.Arcade.Emitter#kill
- */
+* Call this function to turn off all the particles and the emitter.
+* @method Phaser.Particles.Arcade.Emitter#kill
+*/
Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
this.on = false;
@@ -37479,10 +42189,9 @@ Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
}
/**
- * Handy for bringing game objects "back to life". Just sets alive and exists back to true.
- * In practice, this is most often called by Object.reset().
- * @method Phaser.Particles.Arcade.Emitter#revive
- */
+* Handy for bringing game objects "back to life". Just sets alive and exists back to true.
+* @method Phaser.Particles.Arcade.Emitter#revive
+*/
Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
this.alive = true;
@@ -37491,27 +42200,19 @@ Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
}
/**
- * Call this function to start emitting particles.
- * @method Phaser.Particles.Arcade.Emitter#start
- * @param {boolean} explode - Whether the particles should all burst out at once.
- * @param {number} lifespan - How long each particle lives once emitted. 0 = forever.
- * @param {number} frequency - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms.
- * @param {number} quantity - How many particles to launch. 0 = "all of the particles".
- */
+* Call this function to start emitting particles.
+* @method Phaser.Particles.Arcade.Emitter#start
+* @param {boolean} [explode=true] - Whether the particles should all burst out at once.
+* @param {number} [lifespan=0] - How long each particle lives once emitted. 0 = forever.
+* @param {number} [frequency=250] - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms.
+* @param {number} [quantity=0] - How many particles to launch. 0 = "all of the particles".
+*/
Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, frequency, quantity) {
- if (typeof explode !== 'boolean')
- {
- explode = true;
- }
-
- lifespan = lifespan || 0;
-
- // How many ms between emissions?
- frequency = frequency || 250;
-
- // Total number of particles to emit
- quantity = quantity || 0;
+ if (typeof explode === 'undefined') { explode = true; }
+ if (typeof lifespan === 'undefined') { lifespan = 0; }
+ if (typeof frequency === 'undefined') { frequency = 250; }
+ if (typeof quantity === 'undefined') { quantity = 0; }
this.revive();
@@ -37537,9 +42238,9 @@ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, f
}
/**
- * This function can be used both internally and externally to emit the next particle.
- * @method Phaser.Particles.Arcade.Emitter#emitParticle
- */
+* This function can be used both internally and externally to emit the next particle.
+* @method Phaser.Particles.Arcade.Emitter#emitParticle
+*/
Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
var particle = this.getFirstExists(false);
@@ -37597,8 +42298,7 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
particle.scale.setTo(scale, scale);
}
- particle.body.drag.x = this.particleDrag.x;
- particle.body.drag.y = this.particleDrag.y;
+ particle.body.friction = this.particleFriction;
particle.body.angularDrag = this.angularDrag;
}
@@ -37606,8 +42306,8 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
/**
* A more compact way of setting the width and height of the emitter.
* @method Phaser.Particles.Arcade.Emitter#setSize
-* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions).
-* @param {number} height - The desired height of the emitter.
+* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions).
+* @param {number} height - The desired height of the emitter.
*/
Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) {
@@ -37619,8 +42319,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) {
/**
* A more compact way of setting the X velocity range of the emitter.
* @method Phaser.Particles.Arcade.Emitter#setXSpeed
-* @param {number} min - The minimum value for this range.
-* @param {number} max - The maximum value for this range.
+* @param {number} [min=0] - The minimum value for this range.
+* @param {number} [max=0] - The maximum value for this range.
*/
Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
@@ -37635,8 +42335,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
/**
* A more compact way of setting the Y velocity range of the emitter.
* @method Phaser.Particles.Arcade.Emitter#setYSpeed
-* @param {number} min - The minimum value for this range.
-* @param {number} max - The maximum value for this range.
+* @param {number} [min=0] - The minimum value for this range.
+* @param {number} [max=0] - The maximum value for this range.
*/
Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
@@ -37651,8 +42351,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
/**
* A more compact way of setting the angular velocity constraints of the emitter.
* @method Phaser.Particles.Arcade.Emitter#setRotation
-* @param {number} min - The minimum value for this range.
-* @param {number} max - The maximum value for this range.
+* @param {number} [min=0] - The minimum value for this range.
+* @param {number} [max=0] - The maximum value for this range.
*/
Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
@@ -37665,14 +42365,17 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
}
/**
-* Change the emitter's midpoint to match the midpoint of a Object.
+* Change the emitters center to match the center of any object with a `center` property, such as a Sprite.
* @method Phaser.Particles.Arcade.Emitter#at
-* @param {object} object - The Object that you want to sync up with.
+* @param {object|Phaser.Sprite} object - The object that you wish to match the center with.
*/
Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
- this.emitX = object.center.x;
- this.emitY = object.center.y;
+ if (object.center)
+ {
+ this.emitX = object.center.x;
+ this.emitY = object.center.y;
+ }
}
@@ -37796,35 +42499,45 @@ Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "bottom", {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
-* Create a new `Tile` object. Tiles live inside of Tilesets and are rendered via TilemapLayers.
+* Create a new `Tile` object.
*
* @class Phaser.Tile
-* @classdesc A Tile is a single representation of a tile within a Tilemap.
+* @classdesc A Tile is a representation of a single tile within the Tilemap.
* @constructor
-* @param {Phaser.Tileset} tileset - The tileset this tile belongs to.
+* @param {object} layer - The layer in the Tilemap data that this tile belongs to.
* @param {number} index - The index of this tile type in the core map data.
* @param {number} x - The x coordinate of this tile.
* @param {number} y - The y coordinate of this tile.
* @param {number} width - Width of the tile.
* @param {number} height - Height of the tile.
*/
-Phaser.Tile = function (tileset, index, x, y, width, height) {
+Phaser.Tile = function (layer, index, x, y, width, height) {
/**
- * @property {Phaser.Tileset} tileset - The tileset this tile belongs to.
+ * @property {object} layer - The layer in the Tilemap data that this tile belongs to.
*/
- this.tileset = tileset;
-
+ this.layer = layer;
+
/**
- * @property {number} index - The index of this tile within the tileset.
+ * @property {number} index - The index of this tile within the map data corresponding to the tileset.
*/
this.index = index;
+ /**
+ * @property {number} x - The x map coordinate of this tile.
+ */
+ this.x = x;
+
+ /**
+ * @property {number} y - The y map coordinate of this tile.
+ */
+ this.y = y;
+
/**
* @property {number} width - The width of the tile in pixels.
*/
@@ -37836,22 +42549,44 @@ Phaser.Tile = function (tileset, index, x, y, width, height) {
this.height = height;
/**
- * @property {number} x - The top-left corner of the tile within the tileset.
+ * @property {number} alpha - The alpha value at which this tile is drawn to the canvas.
*/
- this.x = x;
-
- /**
- * @property {number} y - The top-left corner of the tile within the tileset.
- */
- this.y = y;
-
- // Any extra meta data info we need here
+ this.alpha = 1;
/**
- * @property {number} mass - The virtual mass of the tile.
- * @default
+ * @property {object} properties - Tile specific properties.
*/
- this.mass = 1.0;
+ this.properties = {};
+
+ /**
+ * @property {boolean} scanned - Has this tile been walked / turned into a poly?
+ */
+ this.scanned = false;
+
+ /**
+ * @property {boolean} faceTop - Is the top of this tile an interesting edge?
+ */
+ this.faceTop = false;
+
+ /**
+ * @property {boolean} faceBottom - Is the bottom of this tile an interesting edge?
+ */
+ this.faceBottom = false;
+
+ /**
+ * @property {boolean} faceLeft - Is the left of this tile an interesting edge?
+ */
+ this.faceLeft = false;
+
+ /**
+ * @property {boolean} faceRight - Is the right of this tile an interesting edge?
+ */
+ this.faceRight = false;
+
+ /**
+ * @property {boolean} collides - Does this tile collide at all?
+ */
+ this.collides = false;
/**
* @property {boolean} collideNone - Indicating this Tile doesn't collide at all.
@@ -37884,38 +42619,27 @@ Phaser.Tile = function (tileset, index, x, y, width, height) {
this.collideDown = false;
/**
- * @property {boolean} separateX - Enable separation at x-axis.
+ * @property {function} callback - Tile collision callback.
* @default
*/
- this.separateX = true;
+ this.callback = null;
/**
- * @property {boolean} separateY - Enable separation at y-axis.
+ * @property {object} callbackContext - The context in which the collision callback will be called.
* @default
*/
- this.separateY = true;
-
- /**
- * @property {boolean} collisionCallback - Tilemap collision callback.
- * @default
- */
- this.collisionCallback = null;
-
- /**
- * @property {boolean} collisionCallback - Tilemap collision callback.
- * @default
- */
- this.collisionCallbackContext = this;
+ this.callbackContext = this;
};
Phaser.Tile.prototype = {
/**
- * Set callback to be called when this tilemap collides.
+ * Set a callback to be called when this tile is hit by an object.
+ * The callback must true true for collision processing to take place.
*
* @method Phaser.Tile#setCollisionCallback
- * @param {Function} callback - Callback function.
+ * @param {function} callback - Callback function.
* @param {object} context - Callback will be called with this context.
*/
setCollisionCallback: function (callback, context) {
@@ -37931,7 +42655,9 @@ Phaser.Tile.prototype = {
*/
destroy: function () {
- this.tileset = null;
+ this.collisionCallback = null;
+ this.collisionCallbackContext = null;
+ this.properties = null;
},
@@ -37973,19 +42699,55 @@ Phaser.Tile.prototype = {
this.collideUp = false;
this.collideDown = false;
+ },
+
+ /**
+ * Copies the tile data and properties from the given tile to this tile.
+ * @method Phaser.Tile#copy
+ * @param {Phaser.Tile} tile - The tile to copy from.
+ */
+ copy: function (tile) {
+
+ this.index = tile.index;
+ this.alpha = tile.alpha;
+ this.properties = tile.properties;
+ this.collides = tile.collides;
+ this.collideNone = tile.collideNone;
+ this.collideUp = tile.collideUp;
+ this.collideDown = tile.collideDown;
+ this.collideLeft = tile.collideLeft;
+ this.collideRight = tile.collideRight;
+ this.collisionCallback = tile.collisionCallback;
+ this.collisionCallbackContext = tile.collisionCallbackContext;
+
}
};
+Phaser.Tile.prototype.constructor = Phaser.Tile;
+
/**
-* @name Phaser.Tile#bottom
-* @property {number} bottom - The sum of the y and height properties.
+* @name Phaser.Tile#canCollide
+* @property {boolean} canCollide - True if this tile can collide or has a collision callback.
* @readonly
*/
-Object.defineProperty(Phaser.Tile.prototype, "bottom", {
+Object.defineProperty(Phaser.Tile.prototype, "canCollide", {
get: function () {
- return this.y + this.height;
+ return (this.collides || this.collisionCallback || this.layer.callbacks[this.index]);
+ }
+
+});
+
+/**
+* @name Phaser.Tile#left
+* @property {number} left - The x value.
+* @readonly
+*/
+Object.defineProperty(Phaser.Tile.prototype, "left", {
+
+ get: function () {
+ return this.x;
}
});
@@ -38003,9 +42765,35 @@ Object.defineProperty(Phaser.Tile.prototype, "right", {
});
+/**
+* @name Phaser.Tile#top
+* @property {number} top - The y value.
+* @readonly
+*/
+Object.defineProperty(Phaser.Tile.prototype, "top", {
+
+ get: function () {
+ return this.y;
+ }
+
+});
+
+/**
+* @name Phaser.Tile#bottom
+* @property {number} bottom - The sum of the y and height properties.
+* @readonly
+*/
+Object.defineProperty(Phaser.Tile.prototype, "bottom", {
+
+ get: function () {
+ return this.y + this.height;
+ }
+
+});
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -38026,22 +42814,52 @@ Phaser.Tilemap = function (game, key) {
this.game = game;
/**
- * @property {array} layers - An array of Tilemap layers.
+ * @property {string} key - The key of this map data in the Phaser.Cache.
*/
- this.layers = null;
+ this.key = key;
- if (typeof key === 'string')
- {
- this.key = key;
+ var data = Phaser.TilemapParser.parse(this.game, key);
- this.layers = game.cache.getTilemapData(key).layers;
- this.calculateIndexes();
- }
- else
+ if (data === null)
{
- this.layers = [];
+ return;
}
+ this.width = data.width;
+ this.height = data.height;
+ this.tileWidth = data.tileWidth;
+ this.tileHeight = data.tileHeight;
+ this.orientation = data.orientation;
+ this.version = data.version;
+ this.properties = data.properties;
+ this.widthInPixels = data.widthInPixels;
+ this.heightInPixels = data.heightInPixels;
+
+ /**
+ * @property {array} layers - An array of Tilemap layer data.
+ */
+ this.layers = data.layers;
+
+ /**
+ * @property {array} tilesets - An array of Tilesets.
+ */
+ this.tilesets = data.tilesets;
+
+ /**
+ * @property {array} tiles - The super array of Tiles.
+ */
+ this.tiles = data.tiles;
+
+ /**
+ * @property {array} objects - An array of Tiled Object Layers.
+ */
+ this.objects = data.objects;
+
+ /**
+ * @property {array} images - An array of Tiled Image Layers.
+ */
+ this.images = data.images;
+
/**
* @property {number} currentLayer - The current layer.
*/
@@ -38050,14 +42868,8 @@ Phaser.Tilemap = function (game, key) {
/**
* @property {array} debugMap - Map data used for debug values only.
*/
-
this.debugMap = [];
- /**
- * @property {boolean} dirty - Internal rendering related flag.
- */
- this.dirty = false;
-
/**
* @property {array} _results - Internal var.
* @private
@@ -38125,36 +42937,500 @@ Phaser.Tilemap.prototype = {
tileSpacing: 0,
format: Phaser.Tilemap.CSV,
data: data,
- indexes: []
+ indexes: [],
+ dirty: true
});
this.currentLayer = this.layers.length - 1;
- this.dirty = true;
+ },
+
+ /**
+ * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets.
+ * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled editor.
+ *
+ * @method Phaser.Tilemap#addTilesetImage
+ * @param {string} tileset - The name of the tileset as specified in the map data.
+ * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If not specified it will look for an image with a key matching the tileset parameter.
+ */
+ addTilesetImage: function (tileset, key) {
+
+ if (typeof key === 'undefined')
+ {
+ if (typeof tileset === 'string')
+ {
+ key = tileset;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (typeof tileset === 'string')
+ {
+ tileset = this.getTilesetIndex(tileset);
+ }
+
+ if (this.tilesets[tileset])
+ {
+ this.tilesets[tileset].image = this.game.cache.getImage(key);
+
+ return true;
+ }
+
+ return false;
+
+ },
+
+ // Region? Remove tile from map data?
+ createFromTiles: function (layer, tileIndex, key, frame, group) {
+
+ if (typeof group === 'undefined') { group = this.game.world; }
},
/**
- * Internal function that calculates the tile indexes for the map data.
+ * Creates a Sprite for every object matching the given gid in the map data. You can optionally specify the group that the Sprite will be created in. If none is
+ * given it will be created in the World. All properties from the map data objectgroup are copied across to the Sprite, so you can use this as an easy way to
+ * configure Sprite properties from within the map editor. For example giving an object a property if alpha: 0.5 in the map editor will duplicate that when the
+ * Sprite is created. You could also give it a value like: body.velocity.x: 100 to set it moving automatically.
*
- * @method Phaser.Tilemap#calculateIndexes
+ * @method Phaser.Tileset#createFromObjects
+ * @param {string} name - The name of the Object Group to create Sprites from.
+ * @param {number} gid - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents.
+ * @param {string} key - The Game.cache key of the image that this Sprite will use.
+ * @param {number|string} [frame] - If the Sprite image contains multiple frames you can specify which one to use here.
+ * @param {boolean} [exists=true] - The default exists state of the Sprite.
+ * @param {boolean} [autoCull=true] - The default autoCull state of the Sprite. Sprites that are autoCulled are culled from the camera if out of its range.
+ * @param {Phaser.Group} [group] - Optional Group to add the Sprite to. If not specified it will be added to the World group.
*/
- calculateIndexes: function () {
+ createFromObjects: function (name, gid, key, frame, exists, autoCull, group) {
- for (var layer = 0; layer < this.layers.length; layer++)
+ if (typeof exists === 'undefined') { exists = true; }
+ if (typeof autoCull === 'undefined') { autoCull = true; }
+ if (typeof group === 'undefined') { group = this.game.world; }
+
+ if (!this.objects[name])
{
- this.layers[layer].indexes = [];
+ console.warn('Tilemap.createFromObjects: Invalid objectgroup name given: ' + name);
+ return;
+ }
- for (var y = 0; y < this.layers[layer].height ; y++)
+ var sprite;
+
+ for (var i = 0, len = this.objects[name].length; i < len; i++)
+ {
+ if (this.objects[name][i].gid === gid)
{
- for (var x = 0; x < this.layers[layer].width; x++)
- {
- var idx = this.layers[layer].data[y][x];
+ sprite = group.create(this.objects[name][i].x, this.objects[name][i].y, key, frame, exists);
- if (this.layers[layer].indexes.indexOf(idx) === -1)
+ sprite.anchor.setTo(0, 1);
+ sprite.name = this.objects[name][i].name;
+ sprite.visible = this.objects[name][i].visible;
+ sprite.autoCull = autoCull;
+
+ for (property in this.objects[name][i].properties)
+ {
+ group.set(sprite, property, this.objects[name][i].properties[property], false, false, 0);
+ }
+ }
+ }
+
+ },
+
+ /**
+ * Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera.
+ *
+ * @method Phaser.Tileset#createLayer
+ * @param {number|string} layer - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents.
+ * @param {number} [width] - The rendered width of the layer, should never be wider than Game.width. If not given it will be set to Game.width.
+ * @param {number} [height] - The rendered height of the layer, should never be wider than Game.height. If not given it will be set to Game.height.
+ * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
+ * @return {Phaser.TilemapLayer} The TilemapLayer object. This is an extension of Phaser.Sprite and can be moved around the display list accordingly.
+ */
+ createLayer: function (layer, width, height, group) {
+
+ // Add Buffer support for the left of the canvas
+
+ if (typeof width === 'undefined') { width = this.game.width; }
+ if (typeof height === 'undefined') { height = this.game.height; }
+ if (typeof group === 'undefined') { group = this.game.world; }
+
+ var index = layer;
+
+ if (typeof layer === 'string')
+ {
+ index = this.getLayerIndex(layer);
+ }
+
+ if (index === null || index > this.layers.length)
+ {
+ console.warn('Tilemap.createLayer: Invalid layer ID given: ' + index);
+ return;
+ }
+
+ return group.add(new Phaser.TilemapLayer(this.game, this, index, width, height));
+
+ },
+
+ /**
+ * Gets the layer index based on the layers name.
+ *
+ * @method Phaser.Tileset#getIndex
+ * @protected
+ * @param {array} location - The local array to search.
+ * @param {string} name - The name of the array element to get.
+ * @return {number} The index of the element in the array, or null if not found.
+ */
+ getIndex: function (location, name) {
+
+ for (var i = 0; i < location.length; i++)
+ {
+ if (location[i].name === name)
+ {
+ return i;
+ }
+ }
+
+ return null;
+
+ },
+
+ /**
+ * Gets the layer index based on its name.
+ *
+ * @method Phaser.Tileset#getLayerIndex
+ * @param {string} name - The name of the layer to get.
+ * @return {number} The index of the layer in this tilemap, or null if not found.
+ */
+ getLayerIndex: function (name) {
+
+ return this.getIndex(this.layers, name);
+
+ },
+
+ /**
+ * Gets the tileset index based on its name.
+ *
+ * @method Phaser.Tileset#getTilesetIndex
+ * @param {string} name - The name of the tileset to get.
+ * @return {number} The index of the tileset in this tilemap, or null if not found.
+ */
+ getTilesetIndex: function (name) {
+
+ return this.getIndex(this.tilesets, name);
+
+ },
+
+ /**
+ * Gets the image index based on its name.
+ *
+ * @method Phaser.Tileset#getImageIndex
+ * @param {string} name - The name of the image to get.
+ * @return {number} The index of the image in this tilemap, or null if not found.
+ */
+ getImageIndex: function (name) {
+
+ return this.getIndex(this.images, name);
+
+ },
+
+ /**
+ * Gets the object index based on its name.
+ *
+ * @method Phaser.Tileset#getObjectIndex
+ * @param {string} name - The name of the object to get.
+ * @return {number} The index of the object in this tilemap, or null if not found.
+ */
+ getObjectIndex: function (name) {
+
+ return this.getIndex(this.objects, name);
+
+ },
+
+ /**
+ * Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index.
+ * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it.
+ * If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback.
+ *
+ * @method Phaser.Tileset#setTileIndexCallback
+ * @param {number|array} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for.
+ * @param {function} callback - The callback that will be invoked when the tile is collided with.
+ * @param {object} callbackContext - The context under which the callback is called.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
+ */
+ setTileIndexCallback: function (indexes, callback, callbackContext, layer) {
+
+ layer = this.getLayer(layer);
+
+ if (typeof indexes === 'number')
+ {
+ // This may seem a bit wasteful, because it will cause empty array elements to be created, but the look-up cost is much
+ // less than having to iterate through the callbacks array hunting down tile indexes each time, so I'll take the small memory hit.
+ this.layers[layer].callbacks[indexes] = { callback: callback, callbackContext: callbackContext };
+ }
+ else
+ {
+ for (var i = 0, len = indexes.length; i < len; i++)
+ {
+ this.layers[layer].callbacks[indexes[i]] = { callback: callback, callbackContext: callbackContext };
+ }
+ }
+
+ },
+
+ /**
+ * Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index.
+ * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it.
+ * If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback.
+ *
+ * @method Phaser.Tileset#setTileLocationCallback
+ * @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels)
+ * @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels)
+ * @param {number} width - The width of the area to copy (given in tiles, not pixels)
+ * @param {number} height - The height of the area to copy (given in tiles, not pixels)
+ * @param {function} callback - The callback that will be invoked when the tile is collided with.
+ * @param {object} callbackContext - The context under which the callback is called.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
+ */
+ setTileLocationCallback: function (x, y, width, height, callback, callbackContext, layer) {
+
+ layer = this.getLayer(layer);
+
+ this.copy(x, y, width, height, layer);
+
+ if (this._results.length < 2)
+ {
+ return;
+ }
+
+ for (var i = 1; i < this._results.length; i++)
+ {
+ this._results[i].setCollisionCallback(callback, callbackContext);
+ }
+
+ },
+
+ /**
+ * Sets collision the given tile or tiles. You can pass in either a single numeric index or an array of indexes: [ 2, 3, 15, 20].
+ * The `collides` parameter controls if collision will be enabled (true) or disabled (false).
+ *
+ * @method Phaser.Tileset#setCollision
+ * @param {number|array} indexes - Either a single tile index, or an array of tile IDs to be checked for collision.
+ * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
+ */
+ setCollision: function (indexes, collides, layer) {
+
+ if (typeof collides === 'undefined') { collides = true; }
+
+ layer = this.getLayer(layer);
+
+ if (typeof indexes === 'number')
+ {
+ return this.setCollisionByIndex(indexes, collides, layer, true);
+ }
+ else
+ {
+ // Collide all of the IDs given in the indexes array
+ for (var i = 0, len = indexes.length; i < len; i++)
+ {
+ this.setCollisionByIndex(indexes[i], collides, layer, false);
+ }
+
+ // Now re-calculate interesting faces
+ this.calculateFaces(layer);
+ }
+
+ },
+
+ /**
+ * Sets collision on a range of tiles where the tile IDs increment sequentially.
+ * Calling this with a start value of 10 and a stop value of 14 would set collision for tiles 10, 11, 12, 13 and 14.
+ * The `collides` parameter controls if collision will be enabled (true) or disabled (false).
+ *
+ * @method Phaser.Tileset#setCollisionBetween
+ * @param {number} start - The first index of the tile to be set for collision.
+ * @param {number} stop - The last index of the tile to be set for collision.
+ * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
+ */
+ setCollisionBetween: function (start, stop, collides, layer) {
+
+ if (typeof collides === 'undefined') { collides = true; }
+
+ layer = this.getLayer(layer);
+
+ if (start > stop)
+ {
+ return;
+ }
+
+ for (var index = start; index <= stop; index++)
+ {
+ this.setCollisionByIndex(index, collides, layer, false);
+ }
+
+ // Now re-calculate interesting faces
+ this.calculateFaces(layer);
+
+ },
+
+ /**
+ * Sets collision on all tiles in the given layer, except for the IDs of those in the given array.
+ * The `collides` parameter controls if collision will be enabled (true) or disabled (false).
+ *
+ * @method Phaser.Tileset#setCollisionByExclusion
+ * @param {array} indexes - An array of the tile IDs to not be counted for collision.
+ * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
+ */
+ setCollisionByExclusion: function (indexes, collides, layer) {
+
+ if (typeof collides === 'undefined') { collides = true; }
+
+ layer = this.getLayer(layer);
+
+ // Collide everything, except the IDs given in the indexes array
+ for (var i = 0, len = this.tiles.length; i < len; i++)
+ {
+ if (indexes.indexOf(i) === -1)
+ {
+ this.setCollisionByIndex(i, collides, layer, false);
+ }
+ }
+
+ // Now re-calculate interesting faces
+ this.calculateFaces(layer);
+
+ },
+
+ /**
+ * Sets collision values on a tile in the set.
+ * You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion.
+ *
+ * @method Phaser.Tileset#setCollisionByIndex
+ * @protected
+ * @param {number} index - The index of the tile on the layer.
+ * @param {boolean} [collides=true] - If true it will enable collision on the tile. If false it will clear collision values from the tile.
+ * @param {number} [layer] - The layer to operate on. If not given will default to this.currentLayer.
+ * @param {boolean} [recalculate=true] - Recalculates the tile faces after the update.
+ */
+ setCollisionByIndex: function (index, collides, layer, recalculate) {
+
+ if (typeof collides === 'undefined') { collides = true; }
+ if (typeof layer === 'undefined') { layer = this.currentLayer; }
+ if (typeof recalculate === 'undefined') { recalculate = true; }
+
+ for (var y = 0; y < this.layers[layer].height ; y++)
+ {
+ for (var x = 0; x < this.layers[layer].width; x++)
+ {
+ var tile = this.layers[layer].data[y][x];
+
+ if (tile && tile.index === index)
+ {
+ tile.collides = collides;
+ tile.faceTop = collides;
+ tile.faceBottom = collides;
+ tile.faceLeft = collides;
+ tile.faceRight = collides;
+ }
+ }
+ }
+
+ if (recalculate)
+ {
+ // Now re-calculate interesting faces
+ this.calculateFaces(layer);
+ }
+
+ return layer;
+
+ },
+
+ /**
+ * Gets the TilemapLayer index as used in the setCollision calls.
+ *
+ * @method Phaser.Tileset#getLayer
+ * @protected
+ * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer.
+ * @return {number} The TilemapLayer index.
+ */
+ getLayer: function (layer) {
+
+ if (typeof layer === 'undefined')
+ {
+ layer = this.currentLayer;
+ }
+ // else if (typeof layer === 'number')
+ // {
+ // layer = layer;
+ // }
+ else if (typeof layer === 'string')
+ {
+ layer = this.getLayerIndex(layer);
+ }
+ else if (layer instanceof Phaser.TilemapLayer)
+ {
+ layer = layer.index;
+ }
+
+ return layer;
+
+ },
+
+ /**
+ * Internal function.
+ *
+ * @method Phaser.Tileset#calculateFaces
+ * @protected
+ * @param {number} layer - The index of the TilemapLayer to operate on.
+ */
+ calculateFaces: function (layer) {
+
+ var above = null;
+ var below = null;
+ var left = null;
+ var right = null;
+
+ for (var y = 0, h = this.layers[layer].height; y < h; y++)
+ {
+ for (var x = 0, w = this.layers[layer].width; x < w; x++)
+ {
+ var tile = this.layers[layer].data[y][x];
+
+ if (tile)
+ {
+ above = this.getTileAbove(layer, x, y);
+ below = this.getTileBelow(layer, x, y);
+ left = this.getTileLeft(layer, x, y);
+ right = this.getTileRight(layer, x, y);
+
+ if (above && above.collides)
{
- this.layers[layer].indexes.push(idx);
+ // There is a tile above this one that also collides, so the top of this tile is no longer interesting
+ tile.faceTop = false;
+ }
+
+ if (below && below.collides)
+ {
+ // There is a tile below this one that also collides, so the bottom of this tile is no longer interesting
+ tile.faceBottom = false;
+ }
+
+ if (left && left.collides)
+ {
+ // There is a tile left this one that also collides, so the left of this tile is no longer interesting
+ tile.faceLeft = false;
+ }
+
+ if (right && right.collides)
+ {
+ // There is a tile right this one that also collides, so the right of this tile is no longer interesting
+ tile.faceRight = false;
}
}
}
@@ -38162,14 +43438,96 @@ Phaser.Tilemap.prototype = {
},
+ /**
+ * Gets the tile above the tile coordinates given.
+ * Mostly used as an internal function by calculateFaces.
+ *
+ * @method Phaser.Tileset#getTileAbove
+ * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
+ * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
+ * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
+ */
+ getTileAbove: function (layer, x, y) {
+
+ if (y > 0)
+ {
+ return this.layers[layer].data[y - 1][x];
+ }
+
+ return null;
+
+ },
+
+ /**
+ * Gets the tile below the tile coordinates given.
+ * Mostly used as an internal function by calculateFaces.
+ *
+ * @method Phaser.Tileset#getTileBelow
+ * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
+ * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
+ * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
+ */
+ getTileBelow: function (layer, x, y) {
+
+ if (y < this.layers[layer].height - 1)
+ {
+ return this.layers[layer].data[y + 1][x];
+ }
+
+ return null;
+
+ },
+
+ /**
+ * Gets the tile to the left of the tile coordinates given.
+ * Mostly used as an internal function by calculateFaces.
+ *
+ * @method Phaser.Tileset#getTileLeft
+ * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
+ * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
+ * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
+ */
+ getTileLeft: function (layer, x, y) {
+
+ if (x > 0)
+ {
+ return this.layers[layer].data[y][x - 1];
+ }
+
+ return null;
+
+ },
+
+ /**
+ * Gets the tile to the right of the tile coordinates given.
+ * Mostly used as an internal function by calculateFaces.
+ *
+ * @method Phaser.Tileset#getTileRight
+ * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
+ * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
+ * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
+ */
+ getTileRight: function (layer, x, y) {
+
+ if (x < this.layers[layer].width - 1)
+ {
+ return this.layers[layer].data[y][x + 1];
+ }
+
+ return null;
+
+ },
+
/**
* Sets the current layer to the given index.
*
* @method Phaser.Tilemap#setLayer
- * @param {number} layer - Sets the current layer to the given index.
+ * @param {number|string|Phaser.TilemapLayer} layer - The layer to set as current.
*/
setLayer: function (layer) {
+ layer = this.getLayer(layer);
+
if (this.layers[layer])
{
this.currentLayer = layer;
@@ -38179,36 +43537,68 @@ Phaser.Tilemap.prototype = {
/**
* Puts a tile of the given index value at the coordinate specified.
+ *
* @method Phaser.Tilemap#putTile
- * @param {number} index - The index of this tile to set.
+ * @param {Phaser.Tile|number} tile - The index of this tile to set or a Phaser.Tile object.
* @param {number} x - X position to place the tile (given in tile units, not pixels)
* @param {number} y - Y position to place the tile (given in tile units, not pixels)
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to modify.
*/
- putTile: function (index, x, y, layer) {
+ putTile: function (tile, x, y, layer) {
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+ layer = this.getLayer(layer);
if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
{
- this.layers[layer].data[y][x] = index;
+ if (tile instanceof Phaser.Tile)
+ {
+ this.layers[layer].data[y][x].copy(tile);
+ }
+ else
+ {
+ this.layers[layer].data[y][x].index = tile;
+ }
+
+ this.layers[layer].dirty = true;
+ this.calculateFaces(layer);
}
- this.dirty = true;
+ },
+
+ /**
+ * Puts a tile into the Tilemap layer. The coordinates are given in pixel values.
+ *
+ * @method Phaser.Tilemap#putTileWorldXY
+ * @param {Phaser.Tile|number} tile - The index of this tile to set or a Phaser.Tile object.
+ * @param {number} x - X position to insert the tile (given in pixels)
+ * @param {number} y - Y position to insert the tile (given in pixels)
+ * @param {number} tileWidth - The width of the tile in pixels.
+ * @param {number} tileHeight - The height of the tile in pixels.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to modify.
+ */
+ putTileWorldXY: function (tile, x, y, tileWidth, tileHeight, layer) {
+
+ layer = this.getLayer(layer);
+
+ x = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
+ y = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
+
+ this.putTile(tile, x, y, layer);
},
/**
* Gets a tile from the Tilemap Layer. The coordinates are given in tile values.
+ *
* @method Phaser.Tilemap#getTile
* @param {number} x - X position to get the tile from (given in tile units, not pixels)
* @param {number} y - Y position to get the tile from (given in tile units, not pixels)
- * @param {number} [layer] - The Tilemap Layer to operate on.
- * @return {number} The index of the tile at the given coordinates.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to get the tile from.
+ * @return {Phaser.Tile} The tile at the given coordinates.
*/
getTile: function (x, y, layer) {
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+ layer = this.getLayer(layer);
if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
{
@@ -38219,65 +43609,38 @@ Phaser.Tilemap.prototype = {
/**
* Gets a tile from the Tilemap layer. The coordinates are given in pixel values.
+ *
* @method Phaser.Tilemap#getTileWorldXY
* @param {number} x - X position to get the tile from (given in pixels)
* @param {number} y - Y position to get the tile from (given in pixels)
- * @param {number} [layer] - The Tilemap Layer to operate on.
- * @return {number} The index of the tile at the given coordinates.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to get the tile from.
+ * @return {Phaser.Tile} The tile at the given coordinates.
*/
getTileWorldXY: function (x, y, tileWidth, tileHeight, layer) {
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+ layer = this.getLayer(layer);
x = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
y = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
- if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
- {
- return this.layers[layer].data[y][x];
- }
-
- },
-
- /**
- * Puts a tile into the Tilemap layer. The coordinates are given in pixel values.
- * @method Phaser.Tilemap#putTileWorldXY
- * @param {number} index - The index of the tile to put into the layer.
- * @param {number} x - X position to insert the tile (given in pixels)
- * @param {number} y - Y position to insert the tile (given in pixels)
- * @param {number} tileWidth - The width of the tile in pixels.
- * @param {number} tileHeight - The height of the tile in pixels.
- * @param {number} [layer] - The Tilemap Layer to operate on.
- */
- putTileWorldXY: function (index, x, y, tileWidth, tileHeight, layer) {
-
- if (typeof layer === "undefined") { layer = this.currentLayer; }
-
- x = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
- y = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
-
- if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
- {
- this.layers[layer].data[y][x] = index;
- }
-
- this.dirty = true;
+ return this.getTile(x, y, layer);
},
/**
* Copies all of the tiles in the given rectangular block into the tilemap data buffer.
+ *
* @method Phaser.Tilemap#copy
* @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels)
* @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels)
* @param {number} width - The width of the area to copy (given in tiles, not pixels)
* @param {number} height - The height of the area to copy (given in tiles, not pixels)
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to copy the tiles from.
* @return {array} An array of the tiles that were copied.
*/
copy: function (x, y, width, height, layer) {
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+ layer = this.getLayer(layer);
if (!this.layers[layer])
{
@@ -38318,7 +43681,7 @@ Phaser.Tilemap.prototype = {
{
for (var tx = x; tx < x + width; tx++)
{
- this._results.push({ x: tx, y: ty, index: this.layers[layer].data[ty][tx] });
+ this._results.push(this.layers[layer].data[ty][tx]);
}
}
@@ -38328,17 +43691,19 @@ Phaser.Tilemap.prototype = {
/**
* Pastes a previously copied block of tile data into the given x/y coordinates. Data should have been prepared with Tilemap.copy.
+ *
* @method Phaser.Tilemap#paste
* @param {number} x - X position of the top left of the area to paste to (given in tiles, not pixels)
* @param {number} y - Y position of the top left of the area to paste to (given in tiles, not pixels)
* @param {array} tileblock - The block of tiles to paste.
- * @param {number} layer - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to paste the tiles into.
*/
paste: function (x, y, tileblock, layer) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+
+ layer = this.getLayer(layer);
if (!tileblock || tileblock.length < 2)
{
@@ -38351,15 +43716,17 @@ Phaser.Tilemap.prototype = {
for (var i = 1; i < tileblock.length; i++)
{
- this.layers[layer].data[ diffY + tileblock[i].y ][ diffX + tileblock[i].x ] = tileblock[i].index;
+ this.layers[layer].data[ diffY + tileblock[i].y ][ diffX + tileblock[i].x ].copy(tileblock[i]);
}
- this.dirty = true;
+ this.layers[layer].dirty = true;
+ this.calculateFaces(layer);
},
/**
- * Swap tiles with 2 kinds of indexes.
+ * Scans the given area for tiles with an index matching tileA and swaps them with tileB.
+ *
* @method Phaser.Tilemap#swapTile
* @param {number} tileA - First tile index.
* @param {number} tileB - Second tile index.
@@ -38367,9 +43734,12 @@ Phaser.Tilemap.prototype = {
* @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} width - The width in tiles of the area to operate on.
* @param {number} height - The height in tiles of the area to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
*/
swap: function (tileA, tileB, x, y, width, height, layer) {
+ layer = this.getLayer(layer);
+
this.copy(x, y, width, height, layer);
if (this._results.length < 2)
@@ -38382,13 +43752,15 @@ Phaser.Tilemap.prototype = {
this._results.forEach(this.swapHandler, this);
- this.paste(x, y, this._results);
+ this.paste(x, y, this._results, layer);
},
/**
* Internal function that handles the swapping of tiles.
+ *
* @method Phaser.Tilemap#swapHandler
+ * @private
* @param {number} value
* @param {number} index
*/
@@ -38406,7 +43778,8 @@ Phaser.Tilemap.prototype = {
},
/**
- * For each tile in the given area (defined by x/y and width/height) run the given callback.
+ * For each tile in the given area defined by x/y and width/height run the given callback.
+ *
* @method Phaser.Tilemap#forEach
* @param {number} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter.
* @param {number} context - The context under which the callback should be run.
@@ -38414,10 +43787,12 @@ Phaser.Tilemap.prototype = {
* @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} width - The width in tiles of the area to operate on.
* @param {number} height - The height in tiles of the area to operate on.
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
*/
forEach: function (callback, context, x, y, width, height, layer) {
+ layer = this.getLayer(layer);
+
this.copy(x, y, width, height, layer);
if (this._results.length < 2)
@@ -38427,22 +43802,25 @@ Phaser.Tilemap.prototype = {
this._results.forEach(callback, context);
- this.paste(x, y, this._results);
+ this.paste(x, y, this._results, layer);
},
/**
- * Replaces one type of tile with another in the given area (defined by x/y and width/height).
+ * Scans the given area for tiles with an index matching `source` and updates their index to match `dest`.
+ *
* @method Phaser.Tilemap#replace
- * @param {number} tileA - First tile index.
- * @param {number} tileB - Second tile index.
+ * @param {number} source - The tile index value to scan for.
+ * @param {number} dest - The tile index value to replace found tiles with.
* @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} width - The width in tiles of the area to operate on.
* @param {number} height - The height in tiles of the area to operate on.
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
*/
- replace: function (tileA, tileB, x, y, width, height, layer) {
+ replace: function (source, dest, x, y, width, height, layer) {
+
+ layer = this.getLayer(layer);
this.copy(x, y, width, height, layer);
@@ -38453,30 +43831,29 @@ Phaser.Tilemap.prototype = {
for (var i = 1; i < this._results.length; i++)
{
- if (this._results[i].index === tileA)
+ if (this._results[i].index === source)
{
- this._results[i].index = tileB;
+ this._results[i].index = dest;
}
}
- this.paste(x, y, this._results);
+ this.paste(x, y, this._results, layer);
},
/**
* Randomises a set of tiles in a given area.
+ *
* @method Phaser.Tilemap#random
- * @param {number} tileA - First tile index.
- * @param {number} tileB - Second tile index.
* @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} width - The width in tiles of the area to operate on.
* @param {number} height - The height in tiles of the area to operate on.
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
*/
random: function (x, y, width, height, layer) {
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+ layer = this.getLayer(layer);
this.copy(x, y, width, height, layer);
@@ -38489,11 +43866,14 @@ Phaser.Tilemap.prototype = {
for (var t = 1; t < this._results.length; t++)
{
- var idx = this._results[t].index;
-
- if (indexes.indexOf(idx) === -1)
+ if (this._results[t].index)
{
- indexes.push(idx);
+ var idx = this._results[t].index;
+
+ if (indexes.indexOf(idx) === -1)
+ {
+ indexes.push(idx);
+ }
}
}
@@ -38502,24 +43882,23 @@ Phaser.Tilemap.prototype = {
this._results[i].index = this.game.rnd.pick(indexes);
}
- this.paste(x, y, this._results);
+ this.paste(x, y, this._results, layer);
},
/**
* Shuffles a set of tiles in a given area. It will only randomise the tiles in that area, so if they're all the same nothing will appear to have changed!
+ *
* @method Phaser.Tilemap#shuffle
- * @param {number} tileA - First tile index.
- * @param {number} tileB - Second tile index.
* @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} width - The width in tiles of the area to operate on.
* @param {number} height - The height in tiles of the area to operate on.
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
*/
shuffle: function (x, y, width, height, layer) {
- if (typeof layer === "undefined") { layer = this.currentLayer; }
+ layer = this.getLayer(layer);
this.copy(x, y, width, height, layer);
@@ -38528,28 +43907,42 @@ Phaser.Tilemap.prototype = {
return;
}
- var header = this._results.shift();
+ var indexes = [];
- Phaser.Utils.shuffle(this._results);
+ for (var t = 1; t < this._results.length; t++)
+ {
+ if (this._results[t].index)
+ {
+ indexes.push(this._results[t].index);
+ }
+ }
- this._results.unshift(header);
+ Phaser.Utils.shuffle(indexes);
- this.paste(x, y, this._results);
+ for (var i = 1; i < this._results.length; i++)
+ {
+ this._results[i].index = indexes[i - 1];
+ }
+
+ this.paste(x, y, this._results, layer);
},
/**
- * Fill a block with a specific tile index.
+ * Fills the given area with the specified tile.
+ *
* @method Phaser.Tilemap#fill
- * @param {number} index - Index of tiles you want to fill with.
+ * @param {number} index - The index of the tile that the area will be filled with.
* @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
* @param {number} width - The width in tiles of the area to operate on.
* @param {number} height - The height in tiles of the area to operate on.
- * @param {number} [layer] - The Tilemap Layer to operate on.
+ * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
*/
fill: function (index, x, y, width, height, layer) {
+ layer = this.getLayer(layer);
+
this.copy(x, y, width, height, layer);
if (this._results.length < 2)
@@ -38562,12 +43955,13 @@ Phaser.Tilemap.prototype = {
this._results[i].index = index;
}
- this.paste(x, y, this._results);
+ this.paste(x, y, this._results, layer);
},
/**
* Removes all layers from this tile map.
+ *
* @method Phaser.Tilemap#removeAllLayers
*/
removeAllLayers: function () {
@@ -38579,6 +43973,7 @@ Phaser.Tilemap.prototype = {
/**
* Dumps the tilemap data out to the console.
+ *
* @method Phaser.Tilemap#dump
*/
dump: function () {
@@ -38619,20 +44014,24 @@ Phaser.Tilemap.prototype = {
/**
* Removes all layers from this tile map and nulls the game reference.
+ *
* @method Phaser.Tilemap#destroy
*/
destroy: function () {
this.removeAllLayers();
+ this.data = [];
this.game = null;
}
};
+Phaser.Tilemap.prototype.constructor = Phaser.Tilemap;
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -38642,25 +44041,37 @@ Phaser.Tilemap.prototype = {
* @class Phaser.TilemapLayer
* @constructor
* @param {Phaser.Game} game - Game reference to the currently running game.
-* @param {number} x - The x coordinate of this layer.
-* @param {number} y - The y coordinate of this layer.
-* @param {number} renderWidth - Width of the layer.
-* @param {number} renderHeight - Height of the layer.
-* @param {Phaser.Tileset|string} tileset - The tile set used for rendering.
* @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs.
-* @param {number} layer - The layer index within the map.
+* @param {number} index - The layer index within the map that this TilemapLayer represents.
+* @param {number} width - Width of the renderable area of the layer.
+* @param {number} height - Height of the renderable area of the layer.
*/
-Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, tilemap, layer) {
+Phaser.TilemapLayer = function (game, tilemap, index, width, height) {
/**
* @property {Phaser.Game} game - A reference to the currently running Game.
*/
this.game = game;
-
+
/**
- * @property {HTMLCanvasElement} canvas - The canvas to which this BitmapData draws.
+ * @property {Phaser.Tilemap} map - The Tilemap to which this layer is bound.
*/
- this.canvas = Phaser.Canvas.create(renderWidth, renderHeight);
+ this.map = tilemap;
+
+ /**
+ * @property {number} index - The index of this layer within the Tilemap.
+ */
+ this.index = index;
+
+ /**
+ * @property {object} layer - The layer object within the Tilemap that this layer represents.
+ */
+ this.layer = tilemap.layers[index];
+
+ /**
+ * @property {HTMLCanvasElement} canvas - The canvas to which this TilemapLayer draws.
+ */
+ this.canvas = Phaser.Canvas.create(width, height);
/**
* @property {CanvasRenderingContext2D} context - The 2d context of the canvas.
@@ -38680,9 +44091,14 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset,
/**
* @property {Phaser.Frame} textureFrame - Dimensions of the renderable area.
*/
- this.textureFrame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid());
+ this.textureFrame = new Phaser.Frame(0, 0, 0, width, height, 'tilemapLayer', game.rnd.uuid());
- Phaser.Sprite.call(this, this.game, x, y, this.texture, this.textureFrame);
+ Phaser.Sprite.call(this, this.game, 0, 0, this.texture, this.textureFrame);
+
+ /**
+ * @property {string} name - The name of the layer.
+ */
+ this.name = '';
/**
* @property {number} type - The const type of this object.
@@ -38691,58 +44107,91 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset,
this.type = Phaser.TILEMAPLAYER;
/**
- * A layer that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.
- * @property {boolean} fixedToCamera - Fixes this layer to the Camera.
+ * An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.
+ * @property {boolean} fixedToCamera - Fixes this object to the Camera.
* @default
*/
this.fixedToCamera = true;
/**
- * @property {Phaser.Tileset} tileset - The tile set used for rendering.
+ * @property {Phaser.Point} cameraOffset - If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.
*/
- this.tileset = null;
+ this.cameraOffset = new Phaser.Point(0, 0);
/**
- * @property {number} tileWidth - The width of a single tile in pixels.
+ * @property {string} tileColor - If no tileset is given the tiles will be rendered as rectangles in this color. Provide in hex or rgb/rgba string format.
+ * @default
*/
- this.tileWidth = 0;
+ this.tileColor = 'rgb(255, 255, 255)';
/**
- * @property {number} tileHeight - The height of a single tile in pixels.
+ * @property {boolean} debug - If set to true the collideable tile edges path will be rendered. Only works when game is running in Phaser.CANVAS mode.
+ * @default
*/
- this.tileHeight = 0;
+ this.debug = false;
/**
- * @property {number} tileMargin - The margin around the tiles.
+ * @property {number} debugAlpha - If debug is true then the tileset is rendered with this alpha level, to make the tile edges clearer.
+ * @default
*/
- this.tileMargin = 0;
+ this.debugAlpha = 0.5;
/**
- * @property {number} tileSpacing - The spacing around the tiles.
+ * @property {string} debugColor - If debug is true this is the color used to outline the edges of collidable tiles. Provide in hex or rgb/rgba string format.
+ * @default
*/
- this.tileSpacing = 0;
+ this.debugColor = 'rgba(0, 255, 0, 1)';
/**
- * @property {number} widthInPixels - Do NOT recommend changing after the map is loaded!
- * @readonly
+ * @property {boolean} debugFill - If true the debug tiles are filled with debugFillColor AND stroked around.
+ * @default
*/
- this.widthInPixels = 0;
+ this.debugFill = false;
/**
- * @property {number} heightInPixels - Do NOT recommend changing after the map is loaded!
- * @readonly
+ * @property {string} debugFillColor - If debugFill is true this is the color used to fill the tiles. Provide in hex or rgb/rgba string format.
+ * @default
*/
- this.heightInPixels = 0;
+ this.debugFillColor = 'rgba(0, 255, 0, 0.2)';
/**
- * @property {number} renderWidth - The width of the area being rendered.
+ * @property {string} debugCallbackColor - If debug is true this is the color used to outline the edges of tiles that have collision callbacks. Provide in hex or rgb/rgba string format.
+ * @default
*/
- this.renderWidth = renderWidth;
+ this.debugCallbackColor = 'rgba(255, 0, 0, 1)';
/**
- * @property {number} renderHeight - The height of the area being rendered.
+ * @property {number} scrollFactorX - speed at which this layer scrolls
+ * horizontally, relative to the camera (e.g. scrollFactorX of 0.5 scrolls
+ * half as quickly as the 'normal' camera-locked layers do)
+ * @default 1
*/
- this.renderHeight = renderHeight;
+ this.scrollFactorX = 1;
+
+ /**
+ * @property {number} scrollFactorY - speed at which this layer scrolls
+ * vertically, relative to the camera (e.g. scrollFactorY of 0.5 scrolls
+ * half as quickly as the 'normal' camera-locked layers do)
+ * @default 1
+ */
+ this.scrollFactorY = 1;
+
+ /**
+ * @property {boolean} dirty - Flag controlling when to re-render the layer.
+ */
+ this.dirty = true;
+
+ /**
+ * @property {number} _cw - Local collision var.
+ * @private
+ */
+ this._cw = tilemap.tileWidth;
+
+ /**
+ * @property {number} _ch - Local collision var.
+ * @private
+ */
+ this._ch = tilemap.tileHeight;
/**
* @property {number} _ga - Local render loop var to help avoid gc spikes.
@@ -38858,51 +44307,7 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset,
*/
this._prevY = 0;
- /**
- * @property {number} scrollFactorX - speed at which this layer scrolls
- * horizontally, relative to the camera (e.g. scrollFactorX of 0.5 scrolls
- * half as quickly as the 'normal' camera-locked layers do)
- * @default 1
- */
- this.scrollFactorX = 1;
-
- /**
- * @property {number} scrollFactorY - speed at which this layer scrolls
- * vertically, relative to the camera (e.g. scrollFactorY of 0.5 scrolls
- * half as quickly as the 'normal' camera-locked layers do)
- * @default 1
- */
- this.scrollFactorY = 1;
-
- /**
- * @property {Phaser.Tilemap} tilemap - The Tilemap to which this layer is bound.
- */
- this.tilemap = null;
-
- /**
- * @property {number} layer - Tilemap layer index.
- */
- this.layer = null;
-
- /**
- * @property {number} index
- */
- this.index = 0;
-
- /**
- * @property {boolean} dirty - Flag controlling when to re-render the layer.
- */
- this.dirty = true;
-
- if (tileset instanceof Phaser.Tileset || typeof tileset === 'string')
- {
- this.updateTileset(tileset);
- }
-
- if (tilemap instanceof Phaser.Tilemap)
- {
- this.updateMapData(tilemap, layer);
- }
+ this.updateMax();
};
@@ -38911,13 +44316,16 @@ Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.TilemapLayer.pr
Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer;
/**
-* Automatically called by World.preUpdate. Handles cache updates.
+* Automatically called by World.postUpdate. Handles cache updates.
*
-* @method Phaser.TilemapLayer#update
+* @method Phaser.TilemapLayer#postUpdate
* @memberof Phaser.TilemapLayer
*/
-Phaser.TilemapLayer.prototype.update = function () {
+Phaser.TilemapLayer.prototype.postUpdate = function () {
+ Phaser.Sprite.prototype.postUpdate.call(this);
+
+ // Stops you being able to auto-scroll the camera if it's not following a sprite
this.scrollX = this.game.camera.x * this.scrollFactorX;
this.scrollY = this.game.camera.y * this.scrollFactorY;
@@ -38933,69 +44341,12 @@ Phaser.TilemapLayer.prototype.update = function () {
*/
Phaser.TilemapLayer.prototype.resizeWorld = function () {
- this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels);
+ this.game.world.setBounds(0, 0, this.layer.widthInPixels, this.layer.heightInPixels);
}
/**
-* Updates the Tileset data.
-*
-* @method Phaser.TilemapLayer#updateTileset
-* @memberof Phaser.TilemapLayer
-* @param {Phaser.Tileset|string} tileset - The tileset to use for this layer.
-*/
-Phaser.TilemapLayer.prototype.updateTileset = function (tileset) {
-
- if (tileset instanceof Phaser.Tileset)
- {
- this.tileset = tileset;
- }
- else if (typeof tileset === 'string')
- {
- this.tileset = this.game.cache.getTileset('tiles');
- }
- else
- {
- return;
- }
-
- this.tileWidth = this.tileset.tileWidth;
- this.tileHeight = this.tileset.tileHeight;
- this.tileMargin = this.tileset.tileMargin;
- this.tileSpacing = this.tileset.tileSpacing;
-
- this.updateMax();
-
-}
-
-/**
-* Updates the Tilemap data.
-*
-* @method Phaser.TilemapLayer#updateMapData
-* @memberof Phaser.TilemapLayer
-* @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs.
-* @param {number} layer - The layer index within the map.
-*/
-Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) {
-
- if (typeof layer === 'undefined')
- {
- layer = 0;
- }
-
- if (tilemap instanceof Phaser.Tilemap)
- {
- this.tilemap = tilemap;
- this.layer = this.tilemap.layers[layer];
- this.index = layer;
- this.updateMax();
- this.tilemap.dirty = true;
- }
-
-}
-
-/**
-* Take an x coordinate that doesn't account for scrollFactorY and 'fix' it
+* Take an x coordinate that doesn't account for scrollFactorX and 'fix' it
* into a scrolled local space. Used primarily internally
* @method Phaser.TilemapLayer#_fixX
* @memberof Phaser.TilemapLayer
@@ -39005,19 +44356,22 @@ Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) {
*/
Phaser.TilemapLayer.prototype._fixX = function(x) {
+ if (x < 0)
+ {
+ x = 0;
+ }
+
if (this.scrollFactorX === 1)
{
return x;
}
- var leftEdge = x - (this._x / this.scrollFactorX);
-
- return this._x + leftEdge;
+ return this._x + (x - (this._x / this.scrollFactorX));
}
/**
-* Take an x coordinate that _does_ account for scrollFactorY and 'unfix' it
+* Take an x coordinate that _does_ account for scrollFactorX and 'unfix' it
* back to camera space. Used primarily internally
* @method Phaser.TilemapLayer#_unfixX
* @memberof Phaser.TilemapLayer
@@ -39032,9 +44386,7 @@ Phaser.TilemapLayer.prototype._unfixX = function(x) {
return x;
}
- var leftEdge = x - this._x;
-
- return (this._x / this.scrollFactorX) + leftEdge;
+ return (this._x / this.scrollFactorX) + (x - this._x);
}
@@ -39049,14 +44401,17 @@ Phaser.TilemapLayer.prototype._unfixX = function(x) {
*/
Phaser.TilemapLayer.prototype._fixY = function(y) {
+ if (y < 0)
+ {
+ y = 0;
+ }
+
if (this.scrollFactorY === 1)
{
return y;
}
- var topEdge = y - (this._y / this.scrollFactorY);
-
- return this._y + topEdge;
+ return this._y + (y - (this._y / this.scrollFactorY));
}
@@ -39076,9 +44431,7 @@ Phaser.TilemapLayer.prototype._unfixY = function(y) {
return y;
}
- var topEdge = y - this._y;
-
- return (this._y / this.scrollFactorY) + topEdge;
+ return (this._y / this.scrollFactorY) + (y - this._y);
}
@@ -39091,9 +44444,9 @@ Phaser.TilemapLayer.prototype._unfixY = function(y) {
*/
Phaser.TilemapLayer.prototype.getTileX = function (x) {
- var tileWidth = this.tileWidth * this.scale.x;
+ // var tileWidth = this.tileWidth * this.scale.x;
- return this.game.math.snapToFloor(this._fixX(x), tileWidth) / tileWidth;
+ return this.game.math.snapToFloor(this._fixX(x), this.map.tileWidth) / this.map.tileWidth;
}
@@ -39106,9 +44459,9 @@ Phaser.TilemapLayer.prototype.getTileX = function (x) {
*/
Phaser.TilemapLayer.prototype.getTileY = function (y) {
- var tileHeight = this.tileHeight * this.scale.y;
+ // var tileHeight = this.tileHeight * this.scale.y;
- return this.game.math.snapToFloor(this._fixY(y), tileHeight) / tileHeight;
+ return this.game.math.snapToFloor(this._fixY(y), this.map.tileHeight) / this.map.tileHeight;
}
@@ -39118,7 +44471,8 @@ Phaser.TilemapLayer.prototype.getTileY = function (y) {
* @memberof Phaser.TilemapLayer
* @param {number} x - X position of the point in target tile.
* @param {number} y - Y position of the point in target tile.
-* @return {Phaser.Tile} The tile with specific properties.
+* @param {Phaser.Point|object} point - The Point object to set the x and y values on.
+* @return {Phaser.Point|object} A Point object with its x and y properties set.
*/
Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) {
@@ -39130,73 +44484,43 @@ Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) {
}
/**
-* Get the tiles within the given area.
+* Get all tiles that exist within the given area, defined by the top-left corner, width and height. Values given are in pixels, not tiles.
* @method Phaser.TilemapLayer#getTiles
* @memberof Phaser.TilemapLayer
-* @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels)
-* @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels)
-* @param {number} width - The width of the area to copy (given in tiles, not pixels)
-* @param {number} height - The height of the area to copy (given in tiles, not pixels)
-* @param {boolean} collides - If true only return tiles that collide on one or more faces.
+* @param {number} x - X position of the top left corner.
+* @param {number} y - Y position of the top left corner.
+* @param {number} width - Width of the area to get.
+* @param {number} height - Height of the area to get.
+* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces.
* @return {array} Array with tiles informations (each contains x, y, and the tile).
*/
Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) {
- if (this.tilemap === null)
- {
- return;
- }
-
// Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all)
if (typeof collides === 'undefined') { collides = false; }
- // Cap the values
-
- if (x < 0)
- {
- x = 0;
- }
-
- if (y < 0)
- {
- y = 0;
- }
-
// adjust the x,y coordinates for scrollFactor
- x = this._fixX( x );
- y = this._fixY( y );
+ x = this._fixX(x);
+ y = this._fixY(y);
- if (width > this.widthInPixels)
+ if (width > this.layer.widthInPixels)
{
- width = this.widthInPixels;
+ width = this.layer.widthInPixels;
}
- if (height > this.heightInPixels)
+ if (height > this.layer.heightInPixels)
{
- height = this.heightInPixels;
+ height = this.layer.heightInPixels;
}
- var tileWidth = this.tileWidth * this.scale.x;
- var tileHeight = this.tileHeight * this.scale.y;
-
// Convert the pixel values into tile coordinates
- this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
- this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
- this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth;
- this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight;
+ this._tx = this.game.math.snapToFloor(x, this._cw) / this._cw;
+ this._ty = this.game.math.snapToFloor(y, this._ch) / this._ch;
+ this._tw = (this.game.math.snapToCeil(width, this._cw) + this._cw) / this._cw;
+ this._th = (this.game.math.snapToCeil(height, this._ch) + this._ch) / this._ch;
// This should apply the layer x/y here
-
- // this._results.length = 0;
- this._results = [];
-
- // pretty sure we don't use this any more?
- // this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th });
-
- var _index = 0;
- var _tile = null;
- var sx = 0;
- var sy = 0;
+ this._results.length = 0;
for (var wy = this._ty; wy < this._ty + this._th; wy++)
{
@@ -39204,19 +44528,20 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
{
if (this.layer.data[wy] && this.layer.data[wy][wx])
{
- // Could combine
- _index = this.layer.data[wy][wx] - 1;
- _tile = this.tileset.getTile(_index);
-
- sx = _tile.width * this.scale.x;
- sy = _tile.height * this.scale.y;
-
- if (collides === false || (collides && _tile.collideNone === false))
+ if (collides === false || (collides && this.layer.data[wy][wx].canCollide))
{
- // convert tile coordinates back to camera space for return
- var _wx = this._unfixX( wx*sx ) / tileWidth;
- var _wy = this._unfixY( wy*sy ) / tileHeight;
- this._results.push({ x: _wx * sx, right: (_wx * sx) + sx, y: _wy * sy, bottom: (_wy * sy) + sy, width: sx, height: sy, tx: _wx, ty: _wy, tile: _tile });
+ // Convert tile coordinates back to camera space for return
+ var _wx = this._unfixX(wx * this._cw) / this._cw;
+ var _wy = this._unfixY(wy * this._ch) / this._ch;
+
+ this._results.push({
+ x: _wx * this._cw,
+ y: _wy * this._ch,
+ right: (_wx * this._cw) + this._cw,
+ bottom: (_wy * this._ch) + this._ch,
+ tile: this.layer.data[wy][wx],
+ layer: this.layer.data[wy][wx].layer
+ });
}
}
}
@@ -39233,8 +44558,8 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
*/
Phaser.TilemapLayer.prototype.updateMax = function () {
- this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1;
- this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1;
+ this._maxX = this.game.math.ceil(this.canvas.width / this.map.tileWidth) + 1;
+ this._maxY = this.game.math.ceil(this.canvas.height / this.map.tileHeight) + 1;
if (this.layer)
{
@@ -39247,9 +44572,6 @@ Phaser.TilemapLayer.prototype.updateMax = function () {
{
this._maxY = this.layer.height;
}
-
- this.widthInPixels = this.layer.width * this.tileWidth;
- this.heightInPixels = this.layer.height * this.tileHeight;
}
this.dirty = true;
@@ -39263,12 +44585,12 @@ Phaser.TilemapLayer.prototype.updateMax = function () {
*/
Phaser.TilemapLayer.prototype.render = function () {
- if (this.tilemap && this.tilemap.dirty)
+ if (this.layer.dirty)
{
this.dirty = true;
}
- if (!this.dirty || !this.tileset || !this.tilemap || !this.visible)
+ if (!this.dirty || !this.visible)
{
return;
}
@@ -39276,101 +44598,194 @@ Phaser.TilemapLayer.prototype.render = function () {
this._prevX = this._dx;
this._prevY = this._dy;
- this._dx = -(this._x - (this._startX * this.tileWidth));
- this._dy = -(this._y - (this._startY * this.tileHeight));
+ 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);
- for (var y = this._startY; y < this._startY + this._maxY; y++)
+ this.context.fillStyle = this.tileColor;
+
+ var tile;
+ var set;
+ var ox = 0;
+ var oy = 0;
+
+ if (this.debug)
+ {
+ this.context.globalAlpha = this.debugAlpha;
+ }
+
+ for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++)
{
this._column = this.layer.data[y];
- for (var x = this._startX; x < this._startX + this._maxX; x++)
+ for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++)
{
- // only -1 on TILED maps, not CSV
- var tile = this.tileset.tiles[this._column[x]-1];
-
- if (tile)
+ if (this._column[x])
{
- this.context.drawImage(
- this.tileset.image,
- tile.x,
- tile.y,
- this.tileWidth,
- this.tileHeight,
- Math.floor(this._tx),
- Math.floor(this._ty),
- this.tileWidth,
- this.tileHeight
- );
+ tile = this._column[x];
+
+ if (this.map.tiles[tile.index])
+ {
+ set = this.map.tilesets[this.map.tiles[tile.index][2]]
+
+ if (set.image)
+ {
+ if (this.debug === false && tile.alpha !== this.context.globalAlpha)
+ {
+ this.context.globalAlpha = tile.alpha;
+ }
+
+ if (set.tileWidth !== this.map.tileWidth || set.tileHeight !== this.map.tileHeight)
+ {
+ // TODO: Smaller sized tile check
+ this.context.drawImage(
+ this.map.tilesets[this.map.tiles[tile.index][2]].image,
+ this.map.tiles[tile.index][0],
+ this.map.tiles[tile.index][1],
+ set.tileWidth,
+ set.tileHeight,
+ Math.floor(this._tx),
+ Math.floor(this._ty) - (set.tileHeight - this.map.tileHeight),
+ set.tileWidth,
+ set.tileHeight
+ );
+ }
+ else
+ {
+ this.context.drawImage(
+ this.map.tilesets[this.map.tiles[tile.index][2]].image,
+ this.map.tiles[tile.index][0],
+ this.map.tiles[tile.index][1],
+ this.map.tileWidth,
+ this.map.tileHeight,
+ Math.floor(this._tx),
+ Math.floor(this._ty),
+ this.map.tileWidth,
+ this.map.tileHeight
+ );
+ }
+
+ if (tile.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);
+ }
+ }
+ else
+ {
+ this.context.fillRect(Math.floor(this._tx), Math.floor(this._ty), this.map.tileWidth, this.map.tileHeight);
+ }
+ }
}
- this._tx += this.tileWidth;
+ this._tx += this.map.tileWidth;
}
this._tx = this._dx;
- this._ty += this.tileHeight;
+ this._ty += this.map.tileHeight;
+
+ }
+
+ if (this.debug)
+ {
+ this.context.globalAlpha = 1;
+ this.renderDebug();
}
// Only needed if running in WebGL, otherwise this array will never get cleared down I don't think!
- if (this.game.renderType == Phaser.WEBGL)
+ if (this.game.renderType === Phaser.WEBGL)
{
PIXI.texturesToUpdate.push(this.baseTexture);
}
this.dirty = false;
-
- if (this.tilemap.dirty)
- {
- this.tilemap.dirty = false;
- }
+ this.layer.dirty = false;
return true;
}
/**
-* Returns the absolute delta x value.
-* @method Phaser.TilemapLayer#deltaAbsX
+* Renders a collision debug overlay on-top of the canvas. Called automatically by render when debug = true.
+* @method Phaser.TilemapLayer#renderDebug
* @memberof Phaser.TilemapLayer
-* @return {number} Absolute delta X value
*/
-Phaser.TilemapLayer.prototype.deltaAbsX = function () {
- return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX());
-}
+Phaser.TilemapLayer.prototype.renderDebug = function () {
-/**
-* Returns the absolute delta y value.
-* @method Phaser.TilemapLayer#deltaAbsY
-* @memberof Phaser.TilemapLayer
-* @return {number} Absolute delta Y value
-*/
-Phaser.TilemapLayer.prototype.deltaAbsY = function () {
- return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY());
-}
+ this._tx = this._dx;
+ this._ty = this._dy;
-/**
-* Returns the delta x value.
-* @method Phaser.TilemapLayer#deltaX
-* @memberof Phaser.TilemapLayer
-* @return {number} Delta X value
-*/
-Phaser.TilemapLayer.prototype.deltaX = function () {
- return this._dx - this._prevX;
-}
+ this.context.strokeStyle = this.debugColor;
+ this.context.fillStyle = this.debugFillColor;
+
+ for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++)
+ {
+ this._column = this.layer.data[y];
+
+ for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++)
+ {
+ var tile = this._column[x];
+
+ if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight))
+ {
+ this._tx = Math.floor(this._tx);
+
+ if (this.debugFill)
+ {
+ this.context.fillRect(this._tx, this._ty, this._cw, this._ch);
+ }
+
+ this.context.beginPath();
+
+ if (tile.faceTop)
+ {
+ this.context.moveTo(this._tx, this._ty);
+ this.context.lineTo(this._tx + this._cw, this._ty);
+ }
+
+ if (tile.faceBottom)
+ {
+ this.context.moveTo(this._tx, this._ty + this._ch);
+ this.context.lineTo(this._tx + this._cw, this._ty + this._ch);
+ }
+
+ if (tile.faceLeft)
+ {
+ this.context.moveTo(this._tx, this._ty);
+ this.context.lineTo(this._tx, this._ty + this._ch);
+ }
+
+ if (tile.faceRight)
+ {
+ this.context.moveTo(this._tx + this._cw, this._ty);
+ this.context.lineTo(this._tx + this._cw, this._ty + this._ch);
+ }
+
+ this.context.stroke();
+ }
+
+ // Collision callback
+ if (tile && (tile.collisionCallback || tile.layer.callbacks[tile.index]))
+ {
+ this.context.fillStyle = this.debugCallbackColor;
+ this.context.fillRect(this._tx, this._ty, this._cw, this._ch);
+ this.context.fillStyle = this.debugFillColor;
+ }
+
+ this._tx += this.map.tileWidth;
+
+ }
+
+ this._tx = this._dx;
+ this._ty += this.map.tileHeight;
+
+ }
-/**
-* Returns the delta y value.
-* @method Phaser.TilemapLayer#deltaY
-* @memberof Phaser.TilemapLayer
-* @return {number} Delta Y value
-*/
-Phaser.TilemapLayer.prototype.deltaY = function () {
- return this._dy - this._prevY;
}
/**
@@ -39385,16 +44800,17 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", {
set: function (value) {
- if (value !== this._x && value >= 0 && this.layer)
+ // if (value !== this._x && value >= 0 && this.layer && this.layer.widthInPixels > this.width)
+ if (value !== this._x && value >= 0 && this.layer.widthInPixels > this.width)
{
this._x = value;
-
- if (this._x > (this.widthInPixels - this.renderWidth))
+
+ if (this._x > (this.layer.widthInPixels - this.width))
{
- this._x = this.widthInPixels - this.renderWidth;
+ this._x = this.layer.widthInPixels - this.width;
}
- this._startX = this.game.math.floor(this._x / this.tileWidth);
+ this._startX = this.game.math.floor(this._x / this.map.tileWidth);
if (this._startX < 0)
{
@@ -39425,16 +44841,17 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", {
set: function (value) {
- if (value !== this._y && value >= 0 && this.layer)
+ // if (value !== this._y && value >= 0 && this.layer && this.heightInPixels > this.renderHeight)
+ if (value !== this._y && value >= 0 && this.layer.heightInPixels > this.height)
{
this._y = value;
- if (this._y > (this.heightInPixels - this.renderHeight))
+ if (this._y > (this.layer.heightInPixels - this.height))
{
- this._y = this.heightInPixels - this.renderHeight;
+ this._y = this.layer.heightInPixels - this.height;
}
- this._startY = this.game.math.floor(this._y / this.tileHeight);
+ this._startY = this.game.math.floor(this._y / this.map.tileHeight);
if (this._startY < 0)
{
@@ -39453,9 +44870,49 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", {
});
+/**
+* @name Phaser.TilemapLayer#collisionWidth
+* @property {number} collisionWidth - The width of the collision tiles.
+*/
+Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionWidth", {
+
+ get: function () {
+ return this._cw;
+ },
+
+ set: function (value) {
+
+ this._cw = value;
+
+ this.dirty = true;
+
+ }
+
+});
+
+/**
+* @name Phaser.TilemapLayer#collisionHeight
+* @property {number} collisionHeight - The height of the collision tiles.
+*/
+Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionHeight", {
+
+ get: function () {
+ return this._ch;
+ },
+
+ set: function (value) {
+
+ this._ch = value;
+
+ this.dirty = true;
+
+ }
+
+});
+
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
@@ -39470,47 +44927,45 @@ Phaser.TilemapParser = {
* Creates a Tileset object.
* @method Phaser.TilemapParser.tileset
* @param {Phaser.Game} game - Game reference to the currently running game.
- * @param {string} key
- * @param {number} tileWidth
- * @param {number} tileHeight
- * @param {number} tileMax
- * @param {number} tileMargin
- * @param {number} tileSpacing
+ * @param {string} key - The Cache key of this tileset.
+ * @param {number} tileWidth - Width of each single tile in pixels.
+ * @param {number} tileHeight - Height of each single tile in pixels.
+ * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
+ * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
+ * @param {number} [rows=-1] - How many tiles are placed horizontally in each row? If -1 it will calculate rows by dividing the image width by tileWidth.
+ * @param {number} [columns=-1] - How many tiles are placed vertically in each column? If -1 it will calculate columns by dividing the image height by tileHeight.
+ * @param {number} [total=-1] - The maximum number of tiles to extract from the image. If -1 it will extract `rows * columns` worth. You can also set a value lower than the actual number of tiles.
* @return {Phaser.Tileset} Generated Tileset object.
*/
- tileset: function (game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
+ tileset: function (game, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total) {
// How big is our image?
var img = game.cache.getTilesetImage(key);
- if (img == null)
+ if (img === null)
{
+ console.warn("Phaser.TilemapParser.tileSet: Invalid image key given");
return null;
}
var width = img.width;
var height = img.height;
- // If no tile width/height is given, try and figure it out (won't work if the tileset has margin/spacing)
- if (tileWidth <= 0)
+ if (rows === -1)
{
- tileWidth = Math.floor(-width / Math.min(-1, tileWidth));
+ rows = Math.round(width / tileWidth);
}
- if (tileHeight <= 0)
+ if (columns === -1)
{
- tileHeight = Math.floor(-height / Math.min(-1, tileHeight));
+ columns = Math.round(height / tileHeight);
}
- var row = Math.round(width / tileWidth);
- var column = Math.round(height / tileHeight);
- var total = row * column;
+ if (total === -1)
+ {
+ total = rows * columns;
+ }
- if (tileMax !== -1)
- {
- total = tileMax;
- }
-
// Zero or smaller than tile sizes?
if (width === 0 || height === 0 || width < tileWidth || height < tileHeight || total === 0)
{
@@ -39518,26 +44973,7 @@ Phaser.TilemapParser = {
return null;
}
- // Let's create some tiles
- var x = tileMargin;
- var y = tileMargin;
-
- var tileset = new Phaser.Tileset(img, key, tileWidth, tileHeight, tileMargin, tileSpacing);
-
- for (var i = 0; i < total; i++)
- {
- tileset.addTile(new Phaser.Tile(tileset, i, x, y, tileWidth, tileHeight));
-
- x += tileWidth + tileSpacing;
-
- if (x === width)
- {
- x = tileMargin;
- y += tileHeight + tileSpacing;
- }
- }
-
- return tileset;
+ return new Phaser.Tileset(img, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total);
},
@@ -39545,19 +44981,27 @@ Phaser.TilemapParser = {
* Parse tileset data from the cache and creates a Tileset object.
* @method Phaser.TilemapParser.parse
* @param {Phaser.Game} game - Game reference to the currently running game.
- * @param {object} data
- * @param {string} format
- * @return {Phaser.Tileset} Generated Tileset object.
+ * @param {string} key - The key of the tilemap in the Cache.
+ * @return {object} The parsed map object.
*/
- parse: function (game, data, format) {
+ parse: function (game, key) {
- if (format === Phaser.Tilemap.CSV)
+ var map = game.cache.getTilemapData(key);
+
+ if (map)
{
- return this.parseCSV(data);
+ if (map.format === Phaser.Tilemap.CSV)
+ {
+ return this.parseCSV(map.data);
+ }
+ else if (map.format === Phaser.Tilemap.TILED_JSON)
+ {
+ return this.parseTiledJSON(map.data);
+ }
}
- else if (format === Phaser.Tilemap.TILED_JSON)
+ else
{
- return this.parseTiledJSON(data);
+ return { layers: [], objects: [], images: [], tilesets: [] };
}
},
@@ -39595,6 +45039,8 @@ Phaser.TilemapParser = {
}
}
+ // Build collision map
+
return [{ name: 'csv', width: width, height: height, alpha: 1, visible: true, indexes: [], tileMargin: 0, tileSpacing: 0, data: output }];
},
@@ -39602,66 +45048,242 @@ Phaser.TilemapParser = {
/**
* Parses a Tiled JSON file into valid map data.
* @method Phaser.TilemapParser.parseJSON
- * @param {object} json- The Tiled JSON data.
- * @return {object} Generated map data.
+ * @param {object} json - The JSON map data.
+ * @return {object} Generated and parsed map data.
*/
parseTiledJSON: function (json) {
+ if (json.orientation !== 'orthogonal')
+ {
+ console.warn('TilemapParser.parseTiledJSON: Only orthogonal map types are supported in this version of Phaser');
+ return null;
+ }
+
+ // Map data will consist of: layers, objects, images, tilesets, sizes
+ var map = {};
+
+ map.width = json.width;
+ map.height = json.height;
+ map.tileWidth = json.tilewidth;
+ map.tileHeight = json.tileheight;
+ map.orientation = json.orientation;
+ map.version = json.version;
+ map.properties = json.properties;
+ map.widthInPixels = map.width * map.tileWidth;
+ map.heightInPixels = map.height * map.tileHeight;
+
+ // Tile Layers
var layers = [];
for (var i = 0; i < json.layers.length; i++)
{
- // Check it's a data layer
- if (!json.layers[i].data)
+ if (json.layers[i].type !== 'tilelayer')
{
continue;
}
- // json.tilewidth
- // json.tileheight
-
var layer = {
name: json.layers[i].name,
+ x: json.layers[i].x,
+ y: json.layers[i].y,
width: json.layers[i].width,
height: json.layers[i].height,
+ widthInPixels: json.layers[i].width * json.tilewidth,
+ heightInPixels: json.layers[i].height * json.tileheight,
alpha: json.layers[i].opacity,
visible: json.layers[i].visible,
+ properties: {},
indexes: [],
-
- tileMargin: json.tilesets[0].margin,
- tileSpacing: json.tilesets[0].spacing
+ callbacks: []
};
- var output = [];
- var c = 0;
- var row;
-
- for (var t = 0; t < json.layers[i].data.length; t++)
+ if (json.layers[i].properties)
{
- if (c === 0)
+ layer.properties = json.layers[i].properties;
+ }
+
+ var x = 0;
+ var row = [];
+ var output = [];
+
+ // Loop through the data field in the JSON.
+
+ // This is an array containing the tile indexes, one after the other. 0 = no tile, everything else = the tile index (starting at 1)
+ // If the map contains multiple tilesets then the indexes are relative to that which the set starts from.
+ // Need to set which tileset in the cache = which tileset in the JSON, if you do this manually it means you can use the same map data but a new tileset.
+
+ for (var t = 0, len = json.layers[i].data.length; t < len; t++)
+ {
+ // index, x, y, width, height
+ if (json.layers[i].data[t] > 0)
{
- row = [];
+ row.push(new Phaser.Tile(layer, json.layers[i].data[t], x, output.length, json.tilewidth, json.tileheight));
+ }
+ else
+ {
+ row.push(null);
}
- row.push(json.layers[i].data[t]);
- c++;
+ x++;
- if (c == json.layers[i].width)
+ if (x === json.layers[i].width)
{
output.push(row);
- c = 0;
+ x = 0;
+ row = [];
}
}
layer.data = output;
-
+
layers.push(layer);
}
- return layers;
+ map.layers = layers;
+
+ // Images
+ var images = [];
+
+ for (var i = 0; i < json.layers.length; i++)
+ {
+ if (json.layers[i].type !== 'imagelayer')
+ {
+ continue;
+ }
+
+ var image = {
+
+ name: json.layers[i].name,
+ image: json.layers[i].image,
+ x: json.layers[i].x,
+ y: json.layers[i].y,
+ alpha: json.layers[i].opacity,
+ visible: json.layers[i].visible,
+ properties: {}
+
+ };
+
+ if (json.layers[i].properties)
+ {
+ image.properties = json.layers[i].properties;
+ }
+
+ images.push(image);
+
+ }
+
+ map.images = images;
+
+ // Objects
+ var objects = {};
+
+ for (var i = 0; i < json.layers.length; i++)
+ {
+ if (json.layers[i].type !== 'objectgroup')
+ {
+ continue;
+ }
+
+ objects[json.layers[i].name] = [];
+
+ for (var v = 0, len = json.layers[i].objects.length; v < len; v++)
+ {
+ // For now we'll just support object tiles
+ if (json.layers[i].objects[v].gid)
+ {
+ var object = {
+
+ gid: json.layers[i].objects[v].gid,
+ name: json.layers[i].objects[v].name,
+ x: json.layers[i].objects[v].x,
+ y: json.layers[i].objects[v].y,
+ visible: json.layers[i].objects[v].visible,
+ properties: json.layers[i].objects[v].properties
+
+ };
+
+ objects[json.layers[i].name].push(object);
+ }
+
+ }
+ }
+
+ map.objects = objects;
+
+ // Tilesets
+ var tilesets = [];
+
+ for (var i = 0; i < json.tilesets.length; i++)
+ {
+ // name, firstgid, width, height, margin, spacing, properties
+ var set = json.tilesets[i];
+ var newSet = new Phaser.Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties);
+
+ if (set.tileproperties)
+ {
+ newSet.tileProperties = set.tileproperties;
+ }
+
+ newSet.rows = (set.imageheight - set.margin) / (set.tileheight + set.spacing);
+ newSet.columns = (set.imagewidth - set.margin) / (set.tilewidth + set.spacing);
+ newSet.total = newSet.rows * newSet.columns;
+
+ tilesets.push(newSet);
+ }
+
+ map.tilesets = tilesets;
+
+ map.tiles = [];
+
+ // Finally lets build our super tileset index
+ for (var i = 0; i < map.tilesets.length; i++)
+ {
+ var set = map.tilesets[i];
+
+ var x = set.tileMargin;
+ var y = set.tileMargin;
+
+ var count = 0;
+ var countX = 0;
+ var countY = 0;
+
+ for (var t = set.firstgid; t < set.firstgid + set.total; t++)
+ {
+ // Can add extra properties here as needed
+ map.tiles[t] = [x, y, i];
+
+ x += set.tileWidth + set.tileSpacing;
+
+ count++;
+
+ if (count === set.total)
+ {
+ break;
+ }
+
+ countX++;
+
+ if (countX === set.columns)
+ {
+ x = set.tileMargin;
+ y += set.tileHeight + set.tileSpacing;
+
+ countX = 0;
+ countY++;
+
+ if (countY === set.rows)
+ {
+ break;
+ }
+ }
+ }
+
+ }
+
+ return map;
}
@@ -39669,97 +45291,129 @@ Phaser.TilemapParser = {
/**
* @author Richard Davey
-* @copyright 2013 Photon Storm Ltd.
+* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* A Tile set is a combination of an image containing the tiles and collision data per tile.
+* You should not normally instantiate this class directly.
*
* @class Phaser.Tileset
* @constructor
-* @param {Image} image - The Image object from the Cache.
-* @param {string} key - The key of the tileset in the cache.
-* @param {number} tileWidth - The width of the tile in pixels.
-* @param {number} tileHeight - The height of the tile in pixels.
-* @param {number} [tileMargin] - The margin around the tiles in the sheet.
-* @param {number} [tileSpacing] - The spacing between the tiles in the sheet.
+* @param {string} name - The name of the tileset in the map data.
+* @param {number} firstgid - The Tiled firstgid value.
+* @param {number} width - Width of each tile in pixels.
+* @param {number} height - Height of each tile in pixels.
+* @param {number} margin - The amount of margin around the tilesheet.
+* @param {number} spacing - The amount of spacing between each tile in the sheet.
+* @param {object} properties - Tileset properties.
*/
-Phaser.Tileset = function (image, key, tileWidth, tileHeight, tileMargin, tileSpacing) {
-
- if (typeof tileMargin === "undefined") { tileMargin = 0; }
- if (typeof tileSpacing === "undefined") { tileSpacing = 0; }
+Phaser.Tileset = function (name, firstgid, width, height, margin, spacing, properties) {
/**
- * @property {string} key - The cache ID.
+ * @property {string} name - The name of the Tileset.
*/
- this.key = key;
+ this.name = name;
/**
- * @property {object} image - The image used for rendering.
+ * @property {number} firstgid - The Tiled firstgid value.
+ * @default
*/
- this.image = image;
+ this.firstgid = firstgid;
/**
* @property {number} tileWidth - The width of a tile in pixels.
*/
- this.tileWidth = tileWidth;
+ this.tileWidth = width;
/**
* @property {number} tileHeight - The height of a tile in pixels.
*/
- this.tileHeight = tileHeight;
+ this.tileHeight = height;
/**
* @property {number} tileMargin - The margin around the tiles in the sheet.
*/
- this.margin = tileMargin;
+ this.tileMargin = margin;
/**
* @property {number} tileSpacing - The margin around the tiles in the sheet.
*/
- this.spacing = tileSpacing;
+ this.tileSpacing = spacing;
/**
- * @property {array} tiles - An array of the tile collision data.
+ * @property {object} properties - Tileset specific properties (typically defined in the Tiled editor).
*/
- this.tiles = [];
+ this.properties = properties;
-}
+ /**
+ * @property {object} tilePproperties - Tile specific properties (typically defined in the Tiled editor).
+ */
+ // this.tileProperties = {};
+
+ /**
+ * @property {object} image - The image used for rendering. This is a reference to the image stored in Phaser.Cache.
+ */
+ this.image = null;
+
+ /**
+ * @property {number} rows - The number of rows in the tile sheet.
+ */
+ this.rows = 0;
+
+ /**
+ * @property {number} columns - The number of columns in the tile sheet.
+ */
+ this.columns = 0;
+
+ /**
+ * @property {number} total - The total number of tiles in the tilesheet.
+ */
+ this.total = 0;
+
+};
Phaser.Tileset.prototype = {
- /**
- * Adds a Tile into this set.
- *
- * @method Phaser.Tileset#addTile
- * @param {Phaser.Tile} tile - The tile to add to this set.
- */
- addTile: function (tile) {
-
- this.tiles.push(tile);
-
- return tile;
-
- },
-
/**
* Gets a Tile from this set.
*
* @method Phaser.Tileset#getTile
* @param {number} index - The index of the tile within the set.
- * @return {Phaser.Tile} The tile.
- */
+ * @return {object} The tile object.
getTile: function (index) {
- if (this.tiles[index])
- {
- return this.tiles[index];
- }
-
- return null;
+ return this.tiles[index];
},
+ */
+
+ /**
+ * Gets a Tile from this set.
+ *
+ * @method Phaser.Tileset#getTileX
+ * @param {number} index - The index of the tile within the set.
+ * @return {object} The tile object.
+ getTileX: function (index) {
+
+ return this.tiles[index][0];
+
+ },
+ */
+
+ /**
+ * Gets a Tile from this set.
+ *
+ * @method Phaser.Tileset#getTileY
+ * @param {number} index - The index of the tile within the set.
+ * @return {object} The tile object.
+ getTileY: function (index) {
+
+ return this.tiles[index][1];
+
+ },
+ */
/**
* Sets tile spacing and margins.
@@ -39775,93 +45429,22 @@ Phaser.Tileset.prototype = {
},
- /**
- * Checks if the tile at the given index can collide.
- *
- * @method Phaser.Tileset#canCollide
- * @param {number} index - The index of the tile within the set.
- * @return {boolean} True or false depending on the tile collision or null if no tile was found at the given index.
- */
- canCollide: function (index) {
-
- if (this.tiles[index])
- {
- return this.tiles[index].collideNone;
- }
-
- return null;
-
- },
-
/**
* Checks if the tile at the given index exists.
*
* @method Phaser.Tileset#checkTileIndex
* @param {number} index - The index of the tile within the set.
* @return {boolean} True if a tile exists at the given index otherwise false.
- */
checkTileIndex: function (index) {
return (this.tiles[index]);
- },
-
- /**
- * Sets collision values on a range of tiles in the set.
- *
- * @method Phaser.Tileset#setCollisionRange
- * @param {number} start - The index to start setting the collision data on.
- * @param {number} stop - The index to stop setting the collision data on.
- * @param {boolean} left - Should the tile collide on the left?
- * @param {boolean} right - Should the tile collide on the right?
- * @param {boolean} up - Should the tile collide on the top?
- * @param {boolean} down - Should the tile collide on the bottom?
- */
- setCollisionRange: function (start, stop, left, right, up, down) {
-
- if (this.tiles[start] && this.tiles[stop] && start < stop)
- {
- for (var i = start; i <= stop; i++)
- {
- this.tiles[i].setCollision(left, right, up, down);
- }
- }
-
- },
-
- /**
- * Sets collision values on a tile in the set.
- *
- * @method Phaser.Tileset#setCollision
- * @param {number} index - The index of the tile within the set.
- * @param {boolean} left - Should the tile collide on the left?
- * @param {boolean} right - Should the tile collide on the right?
- * @param {boolean} up - Should the tile collide on the top?
- * @param {boolean} down - Should the tile collide on the bottom?
- */
- setCollision: function (index, left, right, up, down) {
-
- if (this.tiles[index])
- {
- this.tiles[index].setCollision(left, right, up, down);
- }
-
}
+ */
-}
+};
-/**
-* @name Phaser.Tileset#total
-* @property {number} total - The total number of tiles in this Tileset.
-* @readonly
-*/
-Object.defineProperty(Phaser.Tileset.prototype, "total", {
-
- get: function () {
- return this.tiles.length;
- }
-
-});
+Phaser.Tileset.prototype.constructor = Phaser.Tileset;
/**
* We're replacing a couple of Pixi's methods here to fix or add some vital functionality:
@@ -39869,6 +45452,7 @@ Object.defineProperty(Phaser.Tileset.prototype, "total", {
* 1) Added support for Trimmed sprite sheets
* 2) Skip display objects with an alpha of zero
* 3) Avoid Style Recalculation from the incorrect bgcolor value
+* 4) Added support for Canvas unit rounding via Phaser.CANVAS_PX_ROUND boolean (disabled by default).
*
* Hopefully we can remove this once Pixi has been updated to support these things.
*/
@@ -39888,8 +45472,13 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
stage.updateTransform();
this.context.setTransform(1, 0, 0, 1, 0, 0);
- this.context.clearRect(0, 0, this.width, this.height)
- this.renderDisplayObject(stage);
+
+ if (Phaser.CANVAS_CLEAR_RECT)
+ {
+ this.context.clearRect(0, 0, this.width, this.height)
+ }
+
+ this.renderDisplayObject(stage, false);
// Remove frame updates
if (PIXI.Texture.frameUpdates.length > 0)
@@ -39899,7 +45488,9 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
}
-PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
+// @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered.
+
+PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, renderHidden)
{
// Once the display object hits this we can break the loop
var testObject = displayObject.last._iNext;
@@ -39907,9 +45498,7 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
do
{
- //transform = displayObject.worldTransform;
-
- if (!displayObject.visible)
+ if (!displayObject.visible && !renderHidden)
{
displayObject = displayObject.last._iNext;
continue;
@@ -39923,19 +45512,41 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
if (displayObject instanceof PIXI.Sprite)
{
- // var frame = displayObject.texture.frame;
-
if (displayObject.texture.frame)
{
this.context.globalAlpha = displayObject.worldAlpha;
-
- if (displayObject.texture.trimmed)
+
+ if (Phaser.CANVAS_PX_ROUND)
{
- this.context.setTransform(displayObject.worldTransform[0], displayObject.worldTransform[3], displayObject.worldTransform[1], displayObject.worldTransform[4], displayObject.worldTransform[2] + displayObject.texture.trim.x, displayObject.worldTransform[5] + displayObject.texture.trim.y);
+ this.context.setTransform(
+ displayObject.worldTransform[0],
+ displayObject.worldTransform[3],
+ displayObject.worldTransform[1],
+ displayObject.worldTransform[4],
+ Math.floor(displayObject.worldTransform[2]),
+ Math.floor(displayObject.worldTransform[5]));
}
else
{
- this.context.setTransform(displayObject.worldTransform[0], displayObject.worldTransform[3], displayObject.worldTransform[1], displayObject.worldTransform[4], displayObject.worldTransform[2], displayObject.worldTransform[5]);
+ this.context.setTransform(
+ displayObject.worldTransform[0],
+ displayObject.worldTransform[3],
+ displayObject.worldTransform[1],
+ displayObject.worldTransform[4],
+ displayObject.worldTransform[2],
+ displayObject.worldTransform[5]);
+ }
+
+ if (displayObject.texture.trimmed)
+ {
+ this.context.transform(1, 0, 0, 1, displayObject.texture.trim.x, displayObject.texture.trim.y);
+ }
+
+ //if smoothingEnabled is supported and we need to change the smoothing property for this texture
+ if (this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode)
+ {
+ this.scaleMode = displayObject.texture.baseTexture.scaleMode;
+ this.context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR);
}
this.context.drawImage(
@@ -39944,8 +45555,8 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
displayObject.texture.frame.y,
displayObject.texture.frame.width,
displayObject.texture.frame.height,
- (displayObject.anchor.x) * -displayObject.texture.frame.width,
- (displayObject.anchor.y) * -displayObject.texture.frame.height,
+ Math.floor((displayObject.anchor.x) * -displayObject.texture.frame.width),
+ Math.floor((displayObject.anchor.y) * -displayObject.texture.frame.height),
displayObject.texture.frame.width,
displayObject.texture.frame.height);
}
diff --git a/build/phaser.min.js b/build/phaser.min.js
index 4f17eda8..26cbc352 100644
--- a/build/phaser.min.js
+++ b/build/phaser.min.js
@@ -1,12 +1,13 @@
-/*! Phaser v1.1.3 | (c) 2013 Photon Storm Ltd. */
-!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.Phaser=b()}(this,function(){function a(a){return[(255&a>>16)/255,(255&a>>8)/255,(255&a)/255]}function b(){return c.Matrix="undefined"!=typeof Float32Array?Float32Array:Array,c.Matrix}function a(a){return[(255&a>>16)/255,(255&a>>8)/255,(255&a)/255]}var c=c||{},d=d||{VERSION:"1.1.3",DEV_VERSION:"1.1.3",GAMES:[],AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,SPRITE:0,BUTTON:1,BULLET: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,NONE:0,LEFT:1,RIGHT:2,UP:3,DOWN:4};c.InteractionManager=function(){},d.Utils={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,b,c,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(b in a)c=h[b],e=a[b],h!==e&&(k&&e&&(d.Utils.isPlainObject(e)||(f=Array.isArray(e)))?(f?(f=!1,g=c&&Array.isArray(c)?c:[]):g=c&&d.Utils.isPlainObject(c)?c:{},h[b]=d.Utils.extend(k,g,e)):void 0!==e&&(h[b]=e));return h}},function(){var a=!1;a&&(window.console=void 0),void 0===window.console&&(window.console={debug:function(){return!0},info:function(){return!1},warn:function(){return!1},log:function(){return!1}}),debug=function(a){window.console.debug(a)},info=function(a){window.console.info(a)},warn=function(a){window.console.warn(a)},log=function(a){window.console.log(a)}}(),"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(),c.mat3={},c.mat3.create=function(){var a=new c.Matrix(9);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},c.mat3.identity=function(a){return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},c.mat4={},c.mat4.create=function(){var a=new c.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},c.mat3.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=b[0],n=b[1],o=b[2],p=b[3],q=b[4],r=b[5],s=b[6],t=b[7],u=b[8];return c[0]=m*d+n*g+o*j,c[1]=m*e+n*h+o*k,c[2]=m*f+n*i+o*l,c[3]=p*d+q*g+r*j,c[4]=p*e+q*h+r*k,c[5]=p*f+q*i+r*l,c[6]=s*d+t*g+u*j,c[7]=s*e+t*h+u*k,c[8]=s*f+t*i+u*l,c},c.mat3.clone=function(a){var b=new c.Matrix(9);return b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8],b},c.mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];return a[1]=a[3],a[2]=a[6],a[3]=c,a[5]=a[7],a[6]=d,a[7]=e,a}return b[0]=a[0],b[1]=a[3],b[2]=a[6],b[3]=a[1],b[4]=a[4],b[5]=a[7],b[6]=a[2],b[7]=a[5],b[8]=a[8],b},c.mat3.toMat4=function(a,b){return b||(b=c.mat4.create()),b[15]=1,b[14]=0,b[13]=0,b[12]=0,b[11]=0,b[10]=a[8],b[9]=a[7],b[8]=a[6],b[7]=0,b[6]=a[5],b[5]=a[4],b[4]=a[3],b[3]=0,b[2]=a[2],b[1]=a[1],b[0]=a[0],b},c.mat4.create=function(){var a=new c.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},c.mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],f=a[6],g=a[7],h=a[11];return a[1]=a[4],a[2]=a[8],a[3]=a[12],a[4]=c,a[6]=a[9],a[7]=a[13],a[8]=d,a[9]=f,a[11]=a[14],a[12]=e,a[13]=g,a[14]=h,a}return b[0]=a[0],b[1]=a[4],b[2]=a[8],b[3]=a[12],b[4]=a[1],b[5]=a[5],b[6]=a[9],b[7]=a[13],b[8]=a[2],b[9]=a[6],b[10]=a[10],b[11]=a[14],b[12]=a[3],b[13]=a[7],b[14]=a[11],b[15]=a[15],b},c.mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=a[9],n=a[10],o=a[11],p=a[12],q=a[13],r=a[14],s=a[15],t=b[0],u=b[1],v=b[2],w=b[3];return c[0]=t*d+u*h+v*l+w*p,c[1]=t*e+u*i+v*m+w*q,c[2]=t*f+u*j+v*n+w*r,c[3]=t*g+u*k+v*o+w*s,t=b[4],u=b[5],v=b[6],w=b[7],c[4]=t*d+u*h+v*l+w*p,c[5]=t*e+u*i+v*m+w*q,c[6]=t*f+u*j+v*n+w*r,c[7]=t*g+u*k+v*o+w*s,t=b[8],u=b[9],v=b[10],w=b[11],c[8]=t*d+u*h+v*l+w*p,c[9]=t*e+u*i+v*m+w*q,c[10]=t*f+u*j+v*n+w*r,c[11]=t*g+u*k+v*o+w*s,t=b[12],u=b[13],v=b[14],w=b[15],c[12]=t*d+u*h+v*l+w*p,c[13]=t*e+u*i+v*m+w*q,c[14]=t*f+u*j+v*n+w*r,c[15]=t*g+u*k+v*o+w*s,c},c.Point=function(a,b){this.x=a||0,this.y=b||0},c.Point.prototype.clone=function(){return new c.Point(this.x,this.y)},c.Point.prototype.constructor=c.Point,c.Rectangle=function(a,b,c,d){this.x=a||0,this.y=b||0,this.width=c||0,this.height=d||0},c.Rectangle.prototype.clone=function(){return new c.Rectangle(this.x,this.y,this.width,this.height)},c.Rectangle.prototype.contains=function(a,b){if(this.width<=0||this.height<=0)return!1;var c=this.x;if(a>=c&&a<=c+this.width){var d=this.y;if(b>=d&&b<=d+this.height)return!0}return!1},c.Rectangle.prototype.constructor=c.Rectangle,c.Polygon=function(a){if(a instanceof Array||(a=Array.prototype.slice.call(arguments)),"number"==typeof a[0]){for(var b=[],d=0,e=a.length;e>d;d+=2)b.push(new c.Point(a[d],a[d+1]));a=b}this.points=a},c.Polygon.prototype.clone=function(){for(var a=[],b=0;bb!=i>b&&(h-f)*(b-g)/(i-g)+f>a;j&&(c=!c)}return c},c.Polygon.prototype.constructor=c.Polygon,c.DisplayObject=function(){this.last=this,this.first=this,this.position=new c.Point,this.scale=new c.Point(1,1),this.pivot=new c.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.worldTransform=c.mat3.create(),this.localTransform=c.mat3.create(),this.color=[],this.dynamic=!0,this._sr=0,this._cr=1,this.filterArea=new c.Rectangle(0,0,1,1)},c.DisplayObject.prototype.constructor=c.DisplayObject,c.DisplayObject.prototype.setInteractive=function(a){this.interactive=a},Object.defineProperty(c.DisplayObject.prototype,"interactive",{get:function(){return this._interactive},set:function(a){this._interactive=a,this.stage&&(this.stage.dirty=!0)}}),Object.defineProperty(c.DisplayObject.prototype,"mask",{get:function(){return this._mask},set:function(a){a?this._mask?(a.start=this._mask.start,a.end=this._mask.end):(this.addFilter(a),a.renderable=!1):(this.removeFilter(this._mask),this._mask.renderable=!0),this._mask=a}}),Object.defineProperty(c.DisplayObject.prototype,"filters",{get:function(){return this._filters},set:function(a){if(a){this._filters&&this.removeFilter(this._filters),this.addFilter(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);if(void 0!=a.parent&&a.parent.removeChild(a),a.parent=this,this.stage){var c=a;do c.interactive&&(this.stage.dirty=!0),c.stage=this.stage,c=c._iNext;while(c)}var d,e,f=a.first,g=a.last;if(b==this.children.length){e=this.last;for(var h=this,i=this.last;h;)h.last==i&&(h.last=a.last),h=h.parent}else e=0===b?this:this.children[b-1].last;d=e._iNext,d&&(d._iPrev=g,g._iNext=d),f._iPrev=e,e._iNext=f,this.children.splice(b,0,a),this.__renderGroup&&(a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a),this.__renderGroup.addDisplayObjectAndChildren(a))},c.DisplayObjectContainer.prototype.swapChildren=function(){},c.DisplayObjectContainer.prototype.getChildAt=function(a){if(a>=0&&aa;a++)this.children[a].updateTransform()}},c.blendModes={},c.blendModes.NORMAL=0,c.blendModes.SCREEN=1,c.Sprite=function(a){c.DisplayObjectContainer.call(this),this.anchor=new c.Point,this.texture=a,this.blendMode=c.blendModes.NORMAL,this._width=0,this._height=0,a.baseTexture.hasLoaded?this.updateFrame=!0:(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},c.Sprite.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Sprite.prototype.constructor=c.Sprite,Object.defineProperty(c.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(c.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}}),c.Sprite.prototype.setTexture=function(a){this.texture.baseTexture!=a.baseTexture?(this.textureChange=!0,this.texture=a,this.__renderGroup&&this.__renderGroup.updateTexture(this)):this.texture=a,this.updateFrame=!0},c.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},c.Sprite.fromFrame=function(a){var b=c.TextureCache[a];if(!b)throw new Error("The frameId '"+a+"' does not exist in the texture cache"+this);return new c.Sprite(b)},c.Sprite.fromImage=function(a){var b=c.Texture.fromImage(a);return new c.Sprite(b)},c.Stage=function(a){c.DisplayObjectContainer.call(this),this.worldTransform=c.mat3.create(),this.interactive=!0,this.interactionManager=new c.InteractionManager(this),this.dirty=!0,this.__childrenAdded=[],this.__childrenRemoved=[],this.stage=this,this.stage.hitArea=new c.Rectangle(0,0,1e5,1e5),this.setBackgroundColor(a),this.worldVisible=!0},c.Stage.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Stage.prototype.constructor=c.Stage,c.Stage.prototype.setInteractionDelegate=function(a){this.interactionManager.setTargetDomElement(a)},c.Stage.prototype.updateTransform=function(){this.worldAlpha=1,this.vcount=c.visibleCount;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()},c.Stage.prototype.setBackgroundColor=function(b){this.backgroundColor=b||0,this.backgroundColorSplit=a(this.backgroundColor);var c=this.backgroundColor.toString(16);c="000000".substr(0,6-c.length)+c,this.backgroundColorString="#"+c},c.Stage.prototype.getMousePosition=function(){return this.interactionManager.mouse.global},c.CustomRenderable=function(){c.DisplayObject.call(this),this.renderable=!0},c.CustomRenderable.prototype=Object.create(c.DisplayObject.prototype),c.CustomRenderable.prototype.constructor=c.CustomRenderable,c.CustomRenderable.prototype.renderCanvas=function(){},c.CustomRenderable.prototype.initWebGL=function(){},c.CustomRenderable.prototype.renderWebGL=function(){},c.Strip=function(a,b,d){c.DisplayObjectContainer.call(this),this.texture=a,this.blendMode=c.blendModes.NORMAL;try{this.uvs=new Float32Array([0,1,1,1,1,0,0,1]),this.verticies=new Float32Array([0,0,0,0,0,0,0,0,0]),this.colors=new Float32Array([1,1,1,1]),this.indices=new Uint16Array([0,1,2,3])}catch(e){this.uvs=[0,1,1,1,1,0,0,1],this.verticies=[0,0,0,0,0,0,0,0,0],this.colors=[1,1,1,1],this.indices=[0,1,2,3]}this.width=b,this.height=d,a.baseTexture.hasLoaded?(this.width=this.texture.frame.width,this.height=this.texture.frame.height,this.updateFrame=!0):(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},c.Strip.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Strip.prototype.constructor=c.Strip,c.Strip.prototype.setTexture=function(a){this.texture=a,this.width=a.frame.width,this.height=a.frame.height,this.updateFrame=!0},c.Strip.prototype.onTextureUpdate=function(){this.updateFrame=!0},c.Rope=function(a,b){c.Strip.call(this,a),this.points=b;try{this.verticies=new Float32Array(4*b.length),this.uvs=new Float32Array(4*b.length),this.colors=new Float32Array(2*b.length),this.indices=new Uint16Array(2*b.length)}catch(d){this.verticies=verticies,this.uvs=uvs,this.colors=colors,this.indices=indices}this.refresh()},c.Rope.prototype=Object.create(c.Strip.prototype),c.Rope.prototype.constructor=c.Rope,c.Rope.prototype.refresh=function(){var a=this.points;if(!(a.length<1)){var b=this.uvs,c=this.indices,d=this.colors,e=a[0],f=a[0];this.count-=.2,b[0]=0,b[1]=1,b[2]=0,b[3]=1,d[0]=1,d[1]=1,c[0]=0,c[1]=1;for(var g=a.length,h=1;g>h;h++){var f=a[h],i=4*h,j=h/(g-1);h%2?(b[i]=j,b[i+1]=0,b[i+2]=j,b[i+3]=1):(b[i]=j,b[i+1]=0,b[i+2]=j,b[i+3]=1),i=2*h,d[i]=1,d[i+1]=1,i=2*h,c[i]=i,c[i+1]=i+1,e=f}}},c.Rope.prototype.updateTransform=function(){var a=this.points;if(!(a.length<1)){var b,d=this.verticies,e=a[0],f={x:0,y:0},g=a[0];this.count-=.2,d[0]=g.x+f.x,d[1]=g.y+f.y,d[2]=g.x-f.x,d[3]=g.y-f.y;for(var h=a.length,i=1;h>i;i++){var g=a[i],j=4*i;b=i1&&(k=1);var l=Math.sqrt(f.x*f.x+f.y*f.y),m=this.texture.height/2;f.x/=l,f.y/=l,f.x*=m,f.y*=m,d[j]=g.x+f.x,d[j+1]=g.y+f.y,d[j+2]=g.x-f.x,d[j+3]=g.y-f.y,e=g}c.DisplayObjectContainer.prototype.updateTransform.call(this)}},c.Rope.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},c.TilingSprite=function(a,b,d){c.DisplayObjectContainer.call(this),this.texture=a,this.width=b,this.height=d,this.tileScale=new c.Point(1,1),this.tilePosition=new c.Point(0,0),this.renderable=!0,this.blendMode=c.blendModes.NORMAL},c.TilingSprite.prototype=Object.create(c.DisplayObjectContainer.prototype),c.TilingSprite.prototype.constructor=c.TilingSprite,c.TilingSprite.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},c.TilingSprite.prototype.onTextureUpdate=function(){this.updateFrame=!0},c.AbstractFilter=function(a,b){this.passes=[this],this.dirty=!0,this.padding=0,this.uniforms=b||{},this.fragmentSrc=a||[]},c.FilterBlock=function(){this.visible=!0,this.renderable=!0},c.Graphics=function(){c.DisplayObjectContainer.call(this),this.renderable=!0,this.fillAlpha=1,this.lineWidth=0,this.lineColor="black",this.graphicsData=[],this.currentPath={points:[]}},c.Graphics.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Graphics.prototype.constructor=c.Graphics,c.Graphics.prototype.lineStyle=function(a,b,d){0===this.currentPath.points.length&&this.graphicsData.pop(),this.lineWidth=a||0,this.lineColor=b||0,this.lineAlpha=void 0==d?1:d,this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:c.Graphics.POLY},this.graphicsData.push(this.currentPath)},c.Graphics.prototype.moveTo=function(a,b){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath=this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:c.Graphics.POLY},this.currentPath.points.push(a,b),this.graphicsData.push(this.currentPath)},c.Graphics.prototype.lineTo=function(a,b){this.currentPath.points.push(a,b),this.dirty=!0},c.Graphics.prototype.beginFill=function(a,b){this.filling=!0,this.fillColor=a||0,this.fillAlpha=void 0==b?1:b},c.Graphics.prototype.endFill=function(){this.filling=!1,this.fillColor=null,this.fillAlpha=1},c.Graphics.prototype.drawRect=function(a,b,d,e){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,b,d,e],type:c.Graphics.RECT},this.graphicsData.push(this.currentPath),this.dirty=!0},c.Graphics.prototype.drawCircle=function(a,b,d){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,b,d,d],type:c.Graphics.CIRC},this.graphicsData.push(this.currentPath),this.dirty=!0},c.Graphics.prototype.drawElipse=function(a,b,d,e){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,b,d,e],type:c.Graphics.ELIP},this.graphicsData.push(this.currentPath),this.dirty=!0},c.Graphics.prototype.clear=function(){this.lineWidth=0,this.filling=!1,this.dirty=!0,this.clearDirty=!0,this.graphicsData=[],this.bounds=null},c.Graphics.prototype.updateFilterBounds=function(){if(!this.bounds){for(var a,b,d,e=1/0,f=-1/0,g=1/0,h=-1/0,i=0;ib?b:e,f=b+m>f?b+m:f,g=g>d?b:g,h=d+n>h?d+n:h}else if(k===c.Graphics.CIRC||k===c.Graphics.ELIP){b=a.x,d=a.y;var o=a.radius+l/2;e=e>b-o?b-o:e,f=b+o>f?b+o:f,g=g>d-o?d-o:g,h=d+o>h?d+o:h}else for(var p=0;pb-l?b-l:e,f=b+l>f?b+l:f,g=g>d-l?d-l:g,h=d+l>h?d+l:h}this.bounds=new c.Rectangle(e,g,f-e,h-g)}},c.Graphics.POLY=0,c.Graphics.RECT=1,c.Graphics.CIRC=2,c.Graphics.ELIP=3,c.CanvasGraphics=function(){},c.CanvasGraphics.renderGraphics=function(a,b){for(var d=a.worldAlpha,e=0;e1&&(d=1,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==c.Graphics.POLY){b.beginPath(),b.moveTo(g[0],g[1]);for(var h=1;h0&&(c.Texture.frameUpdates=[])},c.CanvasRenderer.prototype.resize=function(a,b){this.width=a,this.height=b,this.view.width=a,this.view.height=b},c.CanvasRenderer.prototype.renderDisplayObject=function(a){var b,d=this.context;d.globalCompositeOperation="source-over";var e=a.last._iNext;a=a.first;do if(b=a.worldTransform,a.visible)if(a.renderable){if(a instanceof c.Sprite){var f=a.texture.frame;f&&f.width&&f.height&&(d.globalAlpha=a.worldAlpha,d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),d.drawImage(a.texture.baseTexture.source,f.x,f.y,f.width,f.height,a.anchor.x*-f.width,a.anchor.y*-f.height,f.width,f.height))}else if(a instanceof c.Strip)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),this.renderStrip(a);else if(a instanceof c.TilingSprite)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),this.renderTilingSprite(a);else if(a instanceof c.CustomRenderable)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),a.renderCanvas(this);else if(a instanceof c.Graphics)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),c.CanvasGraphics.renderGraphics(a,d);else if(a instanceof c.FilterBlock&&a.data instanceof c.Graphics){var g=a.data;if(a.open){d.save();var h=g.alpha,i=g.worldTransform;d.setTransform(i[0],i[3],i[1],i[4],i[2],i[5]),g.worldAlpha=.5,d.worldAlpha=0,c.CanvasGraphics.renderGraphicsMask(g,d),d.clip(),g.worldAlpha=h}else d.restore()}a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!=e)},c.CanvasRenderer.prototype.renderStripFlat=function(a){var b=this.context,c=a.verticies;a.uvs;var 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()},c.CanvasRenderer.prototype.renderTilingSprite=function(a){var b=this.context;b.globalAlpha=a.worldAlpha,a.__tilePattern||(a.__tilePattern=b.createPattern(a.texture.baseTexture.source,"repeat")),b.beginPath();var c=a.tilePosition,d=a.tileScale;b.scale(d.x,d.y),b.translate(c.x,c.y),b.fillStyle=a.__tilePattern,b.fillRect(-c.x,-c.y,a.width/d.x,a.height/d.y),b.scale(1/d.x,1/d.y),b.translate(-c.x,-c.y),b.closePath()},c.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()}},c.PixiShader=function(){this.program,this.fragmentSrc=["precision lowp float;","varying vec2 vTextureCoord;","varying float vColor;","uniform sampler2D uSampler;","void main(void) {","gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;","}"],this.textureCount=0},c.PixiShader.prototype.init=function(){var a=c.compileProgram(this.vertexSrc||c.PixiShader.defaultVertexSrc,this.fragmentSrc),b=c.gl;b.useProgram(a),this.uSampler=b.getUniformLocation(a,"uSampler"),this.projectionVector=b.getUniformLocation(a,"projectionVector"),this.offsetVector=b.getUniformLocation(a,"offsetVector"),this.dimensions=b.getUniformLocation(a,"dimensions"),this.aVertexPosition=b.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=b.getAttribLocation(a,"aColor"),this.aTextureCoord=b.getAttribLocation(a,"aTextureCoord");for(var d in this.uniforms)this.uniforms[d].uniformLocation=b.getUniformLocation(a,d);this.initUniforms(),this.program=a},c.PixiShader.prototype.initUniforms=function(){this.textureCount=1;var a;for(var b in this.uniforms){var a=this.uniforms[b],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=c.gl.uniformMatrix2fv:"mat3"==d?a.glFunc=c.gl.uniformMatrix3fv:"mat4"==d&&(a.glFunc=c.gl.uniformMatrix4fv)):(a.glFunc=c.gl["uniform"+d],a.glValueLength="2f"==d||"2i"==d?2:"3f"==d||"3i"==d?3:"4f"==d||"4i"==d?4:1)}},c.PixiShader.prototype.initSampler2D=function(a){if(a.value&&a.value.baseTexture&&a.value.baseTexture.hasLoaded){if(c.gl.activeTexture(c.gl["TEXTURE"+this.textureCount]),c.gl.bindTexture(c.gl.TEXTURE_2D,a.value.baseTexture._glTexture),a.textureData){var b=a.textureData,d=b.magFilter?b.magFilter:c.gl.LINEAR,e=b.minFilter?b.minFilter:c.gl.LINEAR,f=b.wrapS?b.wrapS:c.gl.CLAMP_TO_EDGE,g=b.wrapT?b.wrapT:c.gl.CLAMP_TO_EDGE,h=b.luminance?c.gl.LUMINANCE:c.gl.RGBA;if(b.repeat&&(f=c.gl.REPEAT,g=c.gl.REPEAT),c.gl.pixelStorei(c.gl.UNPACK_FLIP_Y_WEBGL,!1),b.width){var i=b.width?b.width:512,j=b.height?b.height:2,k=b.border?b.border:0;c.gl.texImage2D(c.gl.TEXTURE_2D,0,h,i,j,k,h,c.gl.UNSIGNED_BYTE,null)}else c.gl.texImage2D(c.gl.TEXTURE_2D,0,h,c.gl.RGBA,c.gl.UNSIGNED_BYTE,a.value.baseTexture.source);c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_MAG_FILTER,d),c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_MIN_FILTER,e),c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_WRAP_S,f),c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_WRAP_T,g)}c.gl.uniform1i(a.uniformLocation,this.textureCount),a._init=!0,this.textureCount++}},c.PixiShader.prototype.syncUniforms=function(){this.textureCount=1;var a;for(var b in this.uniforms)a=this.uniforms[b],1==a.glValueLength?a.glMatrix===!0?a.glFunc.call(c.gl,a.uniformLocation,a.transpose,a.value):a.glFunc.call(c.gl,a.uniformLocation,a.value):2==a.glValueLength?a.glFunc.call(c.gl,a.uniformLocation,a.value.x,a.value.y):3==a.glValueLength?a.glFunc.call(c.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z):4==a.glValueLength?a.glFunc.call(c.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z,a.value.w):"sampler2D"==a.type&&(a._init?(c.gl.activeTexture(c.gl["TEXTURE"+this.textureCount]),c.gl.bindTexture(c.gl.TEXTURE_2D,a.value.baseTexture._glTexture),c.gl.uniform1i(a.uniformLocation,this.textureCount),this.textureCount++):this.initSampler2D(a))},c.PixiShader.defaultVertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","varying float 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;","vColor = aColor;","}"],c.PrimitiveShader=function(){this.program,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;","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 * alpha;","}"]
-},c.PrimitiveShader.prototype.init=function(){var a=c.compileProgram(this.vertexSrc,this.fragmentSrc),b=c.gl;b.useProgram(a),this.projectionVector=b.getUniformLocation(a,"projectionVector"),this.offsetVector=b.getUniformLocation(a,"offsetVector"),this.aVertexPosition=b.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=b.getAttribLocation(a,"aColor"),this.translationMatrix=b.getUniformLocation(a,"translationMatrix"),this.alpha=b.getUniformLocation(a,"alpha"),this.program=a},c.StripShader=function(){this.program,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;","varying 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;","}"]},c.StripShader.prototype.init=function(){var a=c.compileProgram(this.vertexSrc,this.fragmentSrc),b=c.gl;b.useProgram(a),this.uSampler=b.getUniformLocation(a,"uSampler"),this.projectionVector=b.getUniformLocation(a,"projectionVector"),this.offsetVector=b.getUniformLocation(a,"offsetVector"),this.colorAttribute=b.getAttribLocation(a,"aColor"),this.aVertexPosition=b.getAttribLocation(a,"aVertexPosition"),this.aTextureCoord=b.getAttribLocation(a,"aTextureCoord"),this.translationMatrix=b.getUniformLocation(a,"translationMatrix"),this.alpha=b.getUniformLocation(a,"alpha"),this.program=a},c._batchs=[],c._getBatch=function(a){return 0===c._batchs.length?new c.WebGLBatch(a):c._batchs.pop()},c._returnBatch=function(a){a.clean(),c._batchs.push(a)},c._restoreBatchs=function(a){for(var b=0;bc;c++){var d=6*c,e=4*c;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}a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,this.indices,a.STATIC_DRAW)},c.WebGLBatch.prototype.refresh=function(){this.gl,this.dynamicSizethis.width&&(f.width=this.width),f.y<0&&(f.y=0),f.height>this.height&&(f.height=this.height),b.bindFramebuffer(b.FRAMEBUFFER,e.frameBuffer),b.viewport(0,0,f.width,f.height),c.projection.x=f.width/2,c.projection.y=-f.height/2,c.offset.x=-f.x,c.offset.y=-f.y,b.uniform2f(c.defaultShader.projectionVector,f.width/2,-f.height/2),b.uniform2f(c.defaultShader.offsetVector,-f.x,-f.y),b.colorMask(!0,!0,!0,!0),b.clearColor(0,0,0,0),b.clear(b.COLOR_BUFFER_BIT),a._glFilterTexture=e},c.WebGLFilterManager.prototype.popFilter=function(){var a=c.gl,b=this.filterStack.pop(),d=b.target.filterArea,e=b._glFilterTexture;if(b.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 f=e,g=this.texturePool.pop();g||(g=new c.FilterTexture(this.width,this.height)),a.bindFramebuffer(a.FRAMEBUFFER,g.frameBuffer),a.clear(a.COLOR_BUFFER_BIT),a.disable(a.BLEND);for(var h=0;hs?s:E,E=E>t?t:E,E=E>u?u:E,E=E>v?v:E,F=F>w?w:F,F=F>x?x:F,F=F>y?y:F,F=F>z?z:F,C=s>C?s:C,C=t>C?t:C,C=u>C?u:C,C=v>C?v:C,D=w>D?w:D,D=x>D?x:D,D=y>D?y:D,D=z>D?z:D),l=!1,A=A._iNext}while(A!=B);a.filterArea.x=E,a.filterArea.y=F,a.filterArea.width=C-E,a.filterArea.height=D-F},c.FilterTexture=function(a,b){var d=c.gl;this.frameBuffer=d.createFramebuffer(),this.texture=d.createTexture(),d.bindTexture(d.TEXTURE_2D,this.texture),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MAG_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MIN_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.bindFramebuffer(d.FRAMEBUFFER,this.framebuffer),d.bindFramebuffer(d.FRAMEBUFFER,this.frameBuffer),d.framebufferTexture2D(d.FRAMEBUFFER,d.COLOR_ATTACHMENT0,d.TEXTURE_2D,this.texture,0),this.resize(a,b)},c.FilterTexture.prototype.resize=function(a,b){this.width=a,this.height=b;var d=c.gl;d.bindTexture(d.TEXTURE_2D,this.texture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,a,b,0,d.RGBA,d.UNSIGNED_BYTE,null)},c.WebGLGraphics=function(){},c.WebGLGraphics.renderGraphics=function(a,b){var d=c.gl;a._webGL||(a._webGL={points:[],indices:[],lastIndex:0,buffer:d.createBuffer(),indexBuffer:d.createBuffer()}),a.dirty&&(a.dirty=!1,a.clearDirty&&(a.clearDirty=!1,a._webGL.lastIndex=0,a._webGL.points=[],a._webGL.indices=[]),c.WebGLGraphics.updateGraphics(a)),c.activatePrimitiveShader();var e=c.mat3.clone(a.worldTransform);c.mat3.transpose(e),d.blendFunc(d.ONE,d.ONE_MINUS_SRC_ALPHA),d.uniformMatrix3fv(c.primitiveShader.translationMatrix,!1,e),d.uniform2f(c.primitiveShader.projectionVector,b.x,-b.y),d.uniform2f(c.primitiveShader.offsetVector,-c.offset.x,-c.offset.y),d.uniform1f(c.primitiveShader.alpha,a.worldAlpha),d.bindBuffer(d.ARRAY_BUFFER,a._webGL.buffer),d.vertexAttribPointer(c.primitiveShader.aVertexPosition,2,d.FLOAT,!1,24,0),d.vertexAttribPointer(c.primitiveShader.colorAttribute,4,d.FLOAT,!1,24,8),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),d.drawElements(d.TRIANGLE_STRIP,a._webGL.indices.length,d.UNSIGNED_SHORT,0),c.deactivatePrimitiveShader()},c.WebGLGraphics.updateGraphics=function(a){for(var b=a._webGL.lastIndex;b3&&c.WebGLGraphics.buildPoly(d,a._webGL),d.lineWidth>0&&c.WebGLGraphics.buildLine(d,a._webGL)):d.type==c.Graphics.RECT?c.WebGLGraphics.buildRectangle(d,a._webGL):(d.type==c.Graphics.CIRC||d.type==c.Graphics.ELIP)&&c.WebGLGraphics.buildCircle(d,a._webGL)}a._webGL.lastIndex=a.graphicsData.length;var e=c.gl;a._webGL.glPoints=new Float32Array(a._webGL.points),e.bindBuffer(e.ARRAY_BUFFER,a._webGL.buffer),e.bufferData(e.ARRAY_BUFFER,a._webGL.glPoints,e.STATIC_DRAW),a._webGL.glIndicies=new Uint16Array(a._webGL.indices),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,a._webGL.glIndicies,e.STATIC_DRAW)},c.WebGLGraphics.buildRectangle=function(b,d){var e=b.points,f=e[0],g=e[1],h=e[2],i=e[3];if(b.fill){var j=a(b.fillColor),k=b.fillAlpha,l=j[0]*k,m=j[1]*k,n=j[2]*k,o=d.points,p=d.indices,q=o.length/6;o.push(f,g),o.push(l,m,n,k),o.push(f+h,g),o.push(l,m,n,k),o.push(f,g+i),o.push(l,m,n,k),o.push(f+h,g+i),o.push(l,m,n,k),p.push(q,q,q+1,q+2,q+3,q+3)}b.lineWidth&&(b.points=[f,g,f+h,g,f+h,g+i,f,g+i,f,g],c.WebGLGraphics.buildLine(b,d))},c.WebGLGraphics.buildCircle=function(b,d){var e=b.points,f=e[0],g=e[1],h=e[2],i=e[3],j=40,k=2*Math.PI/j;if(b.fill){var l=a(b.fillColor),m=b.fillAlpha,n=l[0]*m,o=l[1]*m,p=l[2]*m,q=d.points,r=d.indices,s=q.length/6;r.push(s);for(var t=0;j+1>t;t++)q.push(f,g,n,o,p,m),q.push(f+Math.sin(k*t)*h,g+Math.cos(k*t)*i,n,o,p,m),r.push(s++,s++);r.push(s-1)}if(b.lineWidth){b.points=[];for(var t=0;j+1>t;t++)b.points.push(f+Math.sin(k*t)*h,g+Math.cos(k*t)*i);c.WebGLGraphics.buildLine(b,d)}},c.WebGLGraphics.buildLine=function(b,d){var e=b.points;if(0!==e.length){if(b.lineWidth%2)for(var f=0;ff;f++)k=e[2*(f-1)],l=e[2*(f-1)+1],m=e[2*f],n=e[2*f+1],o=e[2*(f+1)],p=e[2*(f+1)+1],q=-(l-n),r=k-m,E=Math.sqrt(q*q+r*r),q/=E,r/=E,q*=K,r*=K,s=-(n-p),t=m-o,E=Math.sqrt(s*s+t*t),s/=E,t/=E,s*=K,t*=K,w=-r+l-(-r+n),x=-q+m-(-q+k),y=(-q+k)*(-r+n)-(-q+m)*(-r+l),z=-t+p-(-t+n),A=-s+m-(-s+o),B=(-s+o)*(-t+n)-(-s+m)*(-t+p),C=w*A-z*x,Math.abs(C)<.1?(C+=10.1,F.push(m-q,n-r,N,O,P,M),F.push(m+q,n+r,N,O,P,M)):(px=(x*B-A*y)/C,py=(z*y-w*B)/C,D=(px-m)*(px-m)+(py-n)+(py-n),D>19600?(u=q-s,v=r-t,E=Math.sqrt(u*u+v*v),u/=E,v/=E,u*=K,v*=K,F.push(m-u,n-v),F.push(N,O,P,M),F.push(m+u,n+v),F.push(N,O,P,M),F.push(m-u,n-v),F.push(N,O,P,M),I++):(F.push(px,py),F.push(N,O,P,M),F.push(m-(px-m),n-(py-n)),F.push(N,O,P,M)));k=e[2*(H-2)],l=e[2*(H-2)+1],m=e[2*(H-1)],n=e[2*(H-1)+1],q=-(l-n),r=k-m,E=Math.sqrt(q*q+r*r),q/=E,r/=E,q*=K,r*=K,F.push(m-q,n-r),F.push(N,O,P,M),F.push(m+q,n+r),F.push(N,O,P,M),G.push(J);for(var f=0;I>f;f++)G.push(J++);G.push(J-1)}},c.WebGLGraphics.buildPoly=function(b,d){var e=b.points;if(!(e.length<6)){for(var f=d.points,g=d.indices,h=e.length/2,i=a(b.fillColor),j=b.fillAlpha,k=i[0]*j,l=i[1]*j,m=i[2]*j,n=c.PolyK.Triangulate(e),o=f.length/6,p=0;pp;p++)f.push(e[2*p],e[2*p+1],k,l,m,j)}},c._defaultFrame=new c.Rectangle(0,0,1,1),c.gl,c.WebGLRenderer=function(a,b,d,e,f){this.transparent=!!e,this.width=a||800,this.height=b||600,this.view=d||document.createElement("canvas"),this.view.width=this.width,this.view.height=this.height;var g=this;this.view.addEventListener("webglcontextlost",function(a){g.handleContextLost(a)},!1),this.view.addEventListener("webglcontextrestored",function(a){g.handleContextRestored(a)},!1),this.batchs=[];var h={alpha:this.transparent,antialias:!!f,premultipliedAlpha:!1,stencil:!0};try{c.gl=this.gl=this.view.getContext("experimental-webgl",h)}catch(i){try{c.gl=this.gl=this.view.getContext("webgl",h)}catch(i){throw new Error(" This browser does not support webGL. Try using the canvas renderer"+this)}}c.initDefaultShaders();var j=this.gl;j.useProgram(c.defaultShader.program),c.WebGLRenderer.gl=j,this.batch=new c.WebGLBatch(j),j.disable(j.DEPTH_TEST),j.disable(j.CULL_FACE),j.enable(j.BLEND),j.colorMask(!0,!0,!0,this.transparent),c.projection=new c.Point(400,300),c.offset=new c.Point(0,0),this.resize(this.width,this.height),this.contextLost=!1,this.stageRenderGroup=new c.WebGLRenderGroup(this.gl,this.transparent)},c.WebGLRenderer.prototype.constructor=c.WebGLRenderer,c.WebGLRenderer.getBatch=function(){return 0===c._batchs.length?new c.WebGLBatch(c.WebGLRenderer.gl):c._batchs.pop()},c.WebGLRenderer.returnBatch=function(a){a.clean(),c._batchs.push(a)},c.WebGLRenderer.prototype.render=function(a){if(!this.contextLost){this.__stage!==a&&(this.__stage=a,this.stageRenderGroup.setRenderable(a)),c.WebGLRenderer.updateTextures(),c.visibleCount++,a.updateTransform();var b=this.gl;if(b.colorMask(!0,!0,!0,this.transparent),b.viewport(0,0,this.width,this.height),b.bindFramebuffer(b.FRAMEBUFFER,null),b.clearColor(a.backgroundColorSplit[0],a.backgroundColorSplit[1],a.backgroundColorSplit[2],!this.transparent),b.clear(b.COLOR_BUFFER_BIT),this.stageRenderGroup.backgroundColor=a.backgroundColorSplit,c.projection.x=this.width/2,c.projection.y=-this.height/2,this.stageRenderGroup.render(c.projection),a.interactive&&(a._interactiveEventsAdded||(a._interactiveEventsAdded=!0,a.interactionManager.setTarget(this))),c.Texture.frameUpdates.length>0){for(var d=0;dn;n++)renderable=this.batchs[n],renderable instanceof c.WebGLBatch?this.batchs[n].render():this.renderSpecial(renderable,b);endBatch instanceof c.WebGLBatch?endBatch.render(0,h+1):this.renderSpecial(endBatch,b)},c.WebGLRenderGroup.prototype.renderSpecial=function(a,b){var d=a.vcount===c.visibleCount;a instanceof c.TilingSprite?d&&this.renderTilingSprite(a,b):a instanceof c.Strip?d&&this.renderStrip(a,b):a instanceof c.CustomRenderable?d&&a.renderWebGL(this,b):a instanceof c.Graphics?d&&a.renderable&&c.WebGLGraphics.renderGraphics(a,b):a instanceof c.FilterBlock&&this.handleFilterBlock(a,b)},flip=!1;var e=[],f=0;return c.WebGLRenderGroup.prototype.handleFilterBlock=function(a,b){var d=c.gl;if(a.open)a.data instanceof Array?this.filterManager.pushFilter(a):(f++,e.push(a),d.enable(d.STENCIL_TEST),d.colorMask(!1,!1,!1,!1),d.stencilFunc(d.ALWAYS,1,1),d.stencilOp(d.KEEP,d.KEEP,d.INCR),c.WebGLGraphics.renderGraphics(a.data,b),d.colorMask(!0,!0,!0,!0),d.stencilFunc(d.NOTEQUAL,0,e.length),d.stencilOp(d.KEEP,d.KEEP,d.KEEP));else if(a.data instanceof Array)this.filterManager.popFilter();else{var g=e.pop(a);g&&(d.colorMask(!1,!1,!1,!1),d.stencilFunc(d.ALWAYS,1,1),d.stencilOp(d.KEEP,d.KEEP,d.DECR),c.WebGLGraphics.renderGraphics(g.data,b),d.colorMask(!0,!0,!0,!0),d.stencilFunc(d.NOTEQUAL,0,e.length),d.stencilOp(d.KEEP,d.KEEP,d.KEEP)),d.disable(d.STENCIL_TEST)}},c.WebGLRenderGroup.prototype.updateTexture=function(a){this.removeObject(a);for(var b=a.first;b!=this.root&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););this.insertObject(a,b,c)},c.WebGLRenderGroup.prototype.addFilterBlocks=function(a,b){a.__renderGroup=this,b.__renderGroup=this;for(var c=a;c!=this.root.first&&(c=c._iPrev,!c.renderable||!c.__renderGroup););this.insertAfter(a,c);for(var d=b;d!=this.root.first&&(d=d._iPrev,!d.renderable||!d.__renderGroup););this.insertAfter(b,d)},c.WebGLRenderGroup.prototype.removeFilterBlocks=function(a,b){this.removeObject(a),this.removeObject(b)},c.WebGLRenderGroup.prototype.addDisplayObjectAndChildren=function(a){a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a);for(var b=a.first;b!=this.root.first&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););var d=a.first,e=a.last._iNext;do d.__renderGroup=this,d.renderable&&(this.insertObject(d,b,c),b=d),d=d._iNext;while(d!=e)},c.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren=function(a){if(a.__renderGroup==this){a.last;do a.__renderGroup=null,a.renderable&&this.removeObject(a),a=a._iNext;while(a)}},c.WebGLRenderGroup.prototype.insertObject=function(a,b,d){var e=b,f=d;if(a instanceof c.Sprite){var g,h;if(e instanceof c.Sprite){if(g=e.batch,g&&g.texture==a.texture.baseTexture&&g.blendMode==a.blendMode)return g.insertAfter(a,e),void 0}else g=e;if(f)if(f instanceof c.Sprite){if(h=f.batch){if(h.texture==a.texture.baseTexture&&h.blendMode==a.blendMode)return h.insertBefore(a,f),void 0;if(h==g){var i=g.split(f),j=c.WebGLRenderer.getBatch(),k=this.batchs.indexOf(g);return j.init(a),this.batchs.splice(k+1,0,j,i),void 0}}}else h=f;var j=c.WebGLRenderer.getBatch();if(j.init(a),g){var k=this.batchs.indexOf(g);this.batchs.splice(k+1,0,j)}else this.batchs.push(j)}else a instanceof c.TilingSprite?this.initTilingSprite(a):a instanceof c.Strip&&this.initStrip(a),this.insertAfter(a,e)},c.WebGLRenderGroup.prototype.insertAfter=function(a,b){if(b instanceof c.Sprite){var d=b.batch;if(d)if(d.tail==b){var e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a)}else{var f=d.split(b.__next),e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a,f)}else this.batchs.push(a)}else{var e=this.batchs.indexOf(b);this.batchs.splice(e+1,0,a)}},c.WebGLRenderGroup.prototype.removeObject=function(a){var b;if(a instanceof c.Sprite){var d=a.batch;if(!d)return;d.remove(a),0==d.size&&(b=d)}else b=a;if(b){var e=this.batchs.indexOf(b);if(-1==e)return;if(0===e||e==this.batchs.length-1)return this.batchs.splice(e,1),b instanceof c.WebGLBatch&&c.WebGLRenderer.returnBatch(b),void 0;if(this.batchs[e-1]instanceof c.WebGLBatch&&this.batchs[e+1]instanceof c.WebGLBatch&&this.batchs[e-1].texture==this.batchs[e+1].texture&&this.batchs[e-1].blendMode==this.batchs[e+1].blendMode)return this.batchs[e-1].merge(this.batchs[e+1]),b instanceof c.WebGLBatch&&c.WebGLRenderer.returnBatch(b),c.WebGLRenderer.returnBatch(this.batchs[e+1]),this.batchs.splice(e,2),void 0;this.batchs.splice(e,1),b instanceof c.WebGLBatch&&c.WebGLRenderer.returnBatch(b)}},c.WebGLRenderGroup.prototype.initTilingSprite=function(a){var b=this.gl;a.verticies=new Float32Array([0,0,a.width,0,a.width,a.height,0,a.height]),a.uvs=new Float32Array([0,0,1,0,1,1,0,1]),a.colors=new Float32Array([1,1,1,1]),a.indices=new Uint16Array([0,1,3,2]),a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW),a.texture.baseTexture._glTexture?(b.bindTexture(b.TEXTURE_2D,a.texture.baseTexture._glTexture),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.REPEAT),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.REPEAT),a.texture.baseTexture._powerOf2=!0):a.texture.baseTexture._powerOf2=!0},c.WebGLRenderGroup.prototype.renderStrip=function(a,b){var d=this.gl;c.activateStripShader();var e=c.stripShader;e.program;var f=c.mat3.clone(a.worldTransform);c.mat3.transpose(f),d.uniformMatrix3fv(e.translationMatrix,!1,f),d.uniform2f(e.projectionVector,b.x,b.y),d.uniform2f(e.offsetVector,-c.offset.x,-c.offset.y),d.uniform1f(e.alpha,a.worldAlpha),a.dirty?(a.dirty=!1,d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferData(d.ARRAY_BUFFER,a.verticies,d.STATIC_DRAW),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferData(d.ARRAY_BUFFER,a.uvs,d.STATIC_DRAW),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.bufferData(d.ARRAY_BUFFER,a.colors,d.STATIC_DRAW),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer),d.bufferData(d.ELEMENT_ARRAY_BUFFER,a.indices,d.STATIC_DRAW)):(d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.verticies),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer)),d.drawElements(d.TRIANGLE_STRIP,a.indices.length,d.UNSIGNED_SHORT,0),c.deactivateStripShader()
-},c.WebGLRenderGroup.prototype.renderTilingSprite=function(a,b){var d=this.gl;c.shaderProgram;var e=a.tilePosition,f=a.tileScale,g=e.x/a.texture.baseTexture.width,h=e.y/a.texture.baseTexture.height,i=a.width/a.texture.baseTexture.width/f.x,j=a.height/a.texture.baseTexture.height/f.y;a.uvs[0]=0-g,a.uvs[1]=0-h,a.uvs[2]=1*i-g,a.uvs[3]=0-h,a.uvs[4]=1*i-g,a.uvs[5]=1*j-h,a.uvs[6]=0-g,a.uvs[7]=1*j-h,d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.uvs),this.renderStrip(a,b)},c.WebGLRenderGroup.prototype.initStrip=function(a){var b=this.gl;this.shaderProgram,a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW)},c.initDefaultShaders=function(){c.primitiveShader=new c.PrimitiveShader,c.primitiveShader.init(),c.stripShader=new c.StripShader,c.stripShader.init(),c.defaultShader=new c.PixiShader,c.defaultShader.init();var a=c.gl,b=c.defaultShader.program;a.useProgram(b),a.enableVertexAttribArray(c.defaultShader.aVertexPosition),a.enableVertexAttribArray(c.defaultShader.colorAttribute),a.enableVertexAttribArray(c.defaultShader.aTextureCoord)},c.activatePrimitiveShader=function(){var a=c.gl;a.useProgram(c.primitiveShader.program),a.disableVertexAttribArray(c.defaultShader.aVertexPosition),a.disableVertexAttribArray(c.defaultShader.colorAttribute),a.disableVertexAttribArray(c.defaultShader.aTextureCoord),a.enableVertexAttribArray(c.primitiveShader.aVertexPosition),a.enableVertexAttribArray(c.primitiveShader.colorAttribute)},c.deactivatePrimitiveShader=function(){var a=c.gl;a.useProgram(c.defaultShader.program),a.disableVertexAttribArray(c.primitiveShader.aVertexPosition),a.disableVertexAttribArray(c.primitiveShader.colorAttribute),a.enableVertexAttribArray(c.defaultShader.aVertexPosition),a.enableVertexAttribArray(c.defaultShader.colorAttribute),a.enableVertexAttribArray(c.defaultShader.aTextureCoord)},c.activateStripShader=function(){var a=c.gl;a.useProgram(c.stripShader.program)},c.deactivateStripShader=function(){var a=c.gl;a.useProgram(c.defaultShader.program)},c.CompileVertexShader=function(a,b){return c._CompileShader(a,b,a.VERTEX_SHADER)},c.CompileFragmentShader=function(a,b){return c._CompileShader(a,b,a.FRAGMENT_SHADER)},c._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:(console.log(a.getShaderInfoLog(e)),null)},c.compileProgram=function(a,b){var d=c.gl,e=c.CompileFragmentShader(d,b),f=c.CompileVertexShader(d,a),g=d.createProgram();return d.attachShader(g,f),d.attachShader(g,e),d.linkProgram(g),d.getProgramParameter(g,d.LINK_STATUS)||console.log("Could not initialise shaders"),g},c.BitmapText=function(a,b){c.DisplayObjectContainer.call(this),this.setText(a),this.setStyle(b),this.updateText(),this.dirty=!1},c.BitmapText.prototype=Object.create(c.DisplayObjectContainer.prototype),c.BitmapText.prototype.constructor=c.BitmapText,c.BitmapText.prototype.setText=function(a){this.text=a||" ",this.dirty=!0},c.BitmapText.prototype.setStyle=function(a){a=a||{},a.align=a.align||"left",this.style=a;var b=a.font.split(" ");this.fontName=b[b.length-1],this.fontSize=b.length>=2?parseInt(b[b.length-2],10):c.BitmapText.fonts[this.fontName].size,this.dirty=!0},c.BitmapText.prototype.updateText=function(){for(var a=c.BitmapText.fonts[this.fontName],b=new c.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)}for(j=0;j0;)this.removeChild(this.getChildAt(0));this.updateText(),this.dirty=!1}c.DisplayObjectContainer.prototype.updateTransform.call(this)},c.BitmapText.fonts={},c.Text=function(a,b){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),c.Sprite.call(this,c.Texture.fromCanvas(this.canvas)),this.setText(a),this.setStyle(b),this.updateText(),this.dirty=!1},c.Text.prototype=Object.create(c.Sprite.prototype),c.Text.prototype.constructor=c.Text,c.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,this.style=a,this.dirty=!0},c.Text.prototype.setText=function(a){this.text=a.toString()||" ",this.dirty=!0},c.Text.prototype.updateText=function(){this.context.font=this.style.font;var a=this.text;this.style.wordWrap&&(a=this.wordWrap(this.text));for(var b=a.split(/(?:\r\n|\r|\n)/),d=[],e=0,f=0;fe?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}b+="\n"}return b},c.Text.prototype.destroy=function(a){a&&this.texture.destroy()},c.Text.heightCache={},c.BaseTextureCache={},c.texturesToUpdate=[],c.texturesToDestroy=[],c.BaseTexture=function(a){if(c.EventTarget.call(this),this.width=100,this.height=100,this.hasLoaded=!1,this.source=a,a){if(this.source instanceof Image||this.source instanceof HTMLImageElement)if(this.source.complete)this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,c.texturesToUpdate.push(this);else{var b=this;this.source.onload=function(){b.hasLoaded=!0,b.width=b.source.width,b.height=b.source.height,c.texturesToUpdate.push(b),b.dispatchEvent({type:"loaded",content:b})}}else this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,c.texturesToUpdate.push(this);this._powerOf2=!1}},c.BaseTexture.prototype.constructor=c.BaseTexture,c.BaseTexture.prototype.destroy=function(){this.source instanceof Image&&(this.source.src=null),this.source=null,c.texturesToDestroy.push(this)},c.BaseTexture.fromImage=function(a,b){var d=c.BaseTextureCache[a];if(!d){var e=new Image;b&&(e.crossOrigin=""),e.src=a,d=new c.BaseTexture(e),c.BaseTextureCache[a]=d}return d},c.TextureCache={},c.FrameCache={},c.Texture=function(a,b){if(c.EventTarget.call(this),b||(this.noFrame=!0,b=new c.Rectangle(0,0,1,1)),a instanceof c.Texture&&(a=a.baseTexture),this.baseTexture=a,this.frame=b,this.trim=new c.Point,this.scope=this,a.hasLoaded)this.noFrame&&(b=new c.Rectangle(0,0,a.width,a.height)),this.setFrame(b);else{var d=this;a.addEventListener("loaded",function(){d.onBaseTextureLoaded()})}},c.Texture.prototype.constructor=c.Texture,c.Texture.prototype.onBaseTextureLoaded=function(){var a=this.baseTexture;a.removeEventListener("loaded",this.onLoaded),this.noFrame&&(this.frame=new c.Rectangle(0,0,a.width,a.height)),this.noFrame=!1,this.width=this.frame.width,this.height=this.frame.height,this.scope.dispatchEvent({type:"update",content:this})},c.Texture.prototype.destroy=function(a){a&&this.baseTexture.destroy()},c.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,c.Texture.frameUpdates.push(this)},c.Texture.fromImage=function(a,b){var d=c.TextureCache[a];return d||(d=new c.Texture(c.BaseTexture.fromImage(a,b)),c.TextureCache[a]=d),d},c.Texture.fromFrame=function(a){var b=c.TextureCache[a];if(!b)throw new Error("The frameId '"+a+"' does not exist in the texture cache "+this);return b},c.Texture.fromCanvas=function(a){var b=new c.BaseTexture(a);return new c.Texture(b)},c.Texture.addTextureToCache=function(a,b){c.TextureCache[b]=a},c.Texture.removeTextureFromCache=function(a){var b=c.TextureCache[a];return c.TextureCache[a]=null,b},c.Texture.frameUpdates=[],c.RenderTexture=function(a,b){c.EventTarget.call(this),this.width=a||100,this.height=b||100,this.indetityMatrix=c.mat3.create(),this.frame=new c.Rectangle(0,0,this.width,this.height),c.gl?this.initWebGL():this.initCanvas()},c.RenderTexture.prototype=Object.create(c.Texture.prototype),c.RenderTexture.prototype.constructor=c.RenderTexture,c.RenderTexture.prototype.initWebGL=function(){var a=c.gl;this.glFramebuffer=a.createFramebuffer(),a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),this.glFramebuffer.width=this.width,this.glFramebuffer.height=this.height,this.baseTexture=new c.BaseTexture,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.baseTexture._glTexture=a.createTexture(),a.bindTexture(a.TEXTURE_2D,this.baseTexture._glTexture),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,this.width,this.height,0,a.RGBA,a.UNSIGNED_BYTE,null),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),this.baseTexture.isRender=!0,a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),a.framebufferTexture2D(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,this.baseTexture._glTexture,0),this.projection=new c.Point(this.width/2,-this.height/2),this.render=this.renderWebGL},c.RenderTexture.prototype.resize=function(a,b){if(this.width=a,this.height=b,c.gl){this.projection.x=this.width/2,this.projection.y=-this.height/2;var d=c.gl;d.bindTexture(d.TEXTURE_2D,this.baseTexture._glTexture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,this.width,this.height,0,d.RGBA,d.UNSIGNED_BYTE,null)}else this.frame.width=this.width,this.frame.height=this.height,this.renderer.resize(this.width,this.height)},c.RenderTexture.prototype.initCanvas=function(){this.renderer=new c.CanvasRenderer(this.width,this.height,null,0),this.baseTexture=new c.BaseTexture(this.renderer.view),this.frame=new c.Rectangle(0,0,this.width,this.height),this.render=this.renderCanvas},c.RenderTexture.prototype.renderWebGL=function(a,b,d){var e=c.gl;e.colorMask(!0,!0,!0,!0),e.viewport(0,0,this.width,this.height),e.bindFramebuffer(e.FRAMEBUFFER,this.glFramebuffer),d&&(e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT));var f=a.children,g=a.worldTransform;a.worldTransform=c.mat3.create(),a.worldTransform[4]=-1,a.worldTransform[5]=-2*this.projection.y,b&&(a.worldTransform[2]=b.x,a.worldTransform[5]-=b.y),c.visibleCount++,a.vcount=c.visibleCount;for(var h=0,i=f.length;i>h;h++)f[h].updateTransform();var j=a.__renderGroup;j?a==j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new c.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},c.RenderTexture.prototype.renderCanvas=function(a,b,d){var e=a.children;a.worldTransform=c.mat3.create(),b&&(a.worldTransform[2]=b.x,a.worldTransform[5]=b.y);for(var f=0,g=e.length;g>f;f++)e[f].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a),this.renderer.context.setTransform(1,0,0,1,0,0)},c.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)}},c.PolyK={},c.PolyK.Triangulate=function(a){var b=!0,d=a.length>>1;if(3>d)return[];for(var e=[],f=[],g=0;d>g;g++)f.push(g);for(var g=0,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(c.PolyK._convex(l,m,n,o,p,q,b)){r=!0;for(var s=0;h>s;s++){var t=f[s];if(t!=i&&t!=j&&t!=k&&c.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(!b)return console.log("PIXI Warning: shape too complex to fill"),[];var e=[];f=[];for(var g=0;d>g;g++)f.push(g);g=0,h=d,b=!1}}return e.push(f[0],f[1],f[2]),e},c.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},c.PolyK._convex=function(a,b,c,d,e,f,g){return(b-d)*(e-c)+(c-a)*(f-d)>=0==g},d.Camera=function(a,b,c,e,f,g){this.game=a,this.world=a.world,this.id=0,this.view=new d.Rectangle(c,e,f,g),this.screenView=new d.Rectangle(c,e,f,g),this.bounds=new d.Rectangle(c,e,f,g),this.deadzone=null,this.visible=!0,this.atLimit={x:!1,y:!1},this.target=null,this._edge=0,this.displayObject=null},d.Camera.FOLLOW_LOCKON=0,d.Camera.FOLLOW_PLATFORMER=1,d.Camera.FOLLOW_TOPDOWN=2,d.Camera.FOLLOW_TOPDOWN_TIGHT=3,d.Camera.prototype={follow:function(a,b){"undefined"==typeof b&&(b=d.Camera.FOLLOW_LOCKON),this.target=a;var c;switch(b){case d.Camera.FOLLOW_PLATFORMER:var e=this.width/8,f=this.height/3;this.deadzone=new d.Rectangle((this.width-e)/2,(this.height-f)/2-.25*f,e,f);break;case d.Camera.FOLLOW_TOPDOWN:c=Math.max(this.width,this.height)/4,this.deadzone=new d.Rectangle((this.width-c)/2,(this.height-c)/2,c,c);break;case d.Camera.FOLLOW_TOPDOWN_TIGHT:c=Math.max(this.width,this.height)/8,this.deadzone=new d.Rectangle((this.width-c)/2,(this.height-c)/2,c,c);break;case d.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.width&&(this.atLimit.x=!0,this.view.x=this.bounds.right-this.width+1),this.view.ythis.bounds.bottom-this.height&&(this.atLimit.y=!0,this.view.y=this.bounds.bottom-this.height+1),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}},Object.defineProperty(d.Camera.prototype,"x",{get:function(){return this.view.x},set:function(a){this.view.x=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(d.Camera.prototype,"y",{get:function(){return this.view.y},set:function(a){this.view.y=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(d.Camera.prototype,"width",{get:function(){return this.view.width},set:function(a){this.view.width=a}}),Object.defineProperty(d.Camera.prototype,"height",{get:function(){return this.view.height},set:function(a){this.view.height=a}}),d.State=function(){this.game=null,this.add=null,this.camera=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.particles=null,this.physics=null},d.State.prototype={preload:function(){},loadUpdate:function(){},loadRender:function(){},create:function(){},update:function(){},render:function(){},paused:function(){},destroy:function(){}},d.StateManager=function(a,b){this.game=a,this.states={},this._pendingState=null,null!==b&&(this._pendingState=b),this._created=!1,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.onShutDownCallback=null},d.StateManager.prototype={boot:function(){this.game.onPause.add(this.pause,this),this.game.onResume.add(this.resume,this),null!==this._pendingState&&("string"==typeof this._pendingState?this.start(this._pendingState,!1,!1):this.add("default",this._pendingState,!0))},add:function(a,b,c){"undefined"==typeof c&&(c=!1);var e;return b instanceof d.State?e=b:"object"==typeof b?(e=b,e.game=this.game):"function"==typeof b&&(e=new b(this.game)),this.states[a]=e,c&&(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.onDestroyCallback=null),delete this.states[a]},start:function(a,b,c){return"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!1),this.game.isBooted===!1?(this._pendingState=a,void 0):(this.checkState(a)!==!1&&(this.current&&this.onShutDownCallback.call(this.callbackContext,this.game),b&&(this.game.tweens.removeAll(),this.game.world.destroy(),c===!0&&this.game.cache.destroy()),this.setCurrentState(a),this.onPreloadCallback?(this.game.load.reset(),this.onPreloadCallback.call(this.callbackContext,this.game),0===this.game.load.totalQueuedFiles()?this.game.loadComplete():this.game.load.start()):this.game.loadComplete()),void 0)},dummy:function(){},checkState:function(a){if(this.states[a]){var b=!1;return this.states[a].preload&&(b=!0),b===!1&&this.states[a].loadRender&&(b=!0),b===!1&&this.states[a].loadUpdate&&(b=!0),b===!1&&this.states[a].create&&(b=!0),b===!1&&this.states[a].update&&(b=!0),b===!1&&this.states[a].preRender&&(b=!0),b===!1&&this.states[a].render&&(b=!0),b===!1&&this.states[a].paused&&(b=!0),b===!1?(console.warn("Invalid Phaser State object given. Must contain at least a one of the required functions."),!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].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].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].physics=this.game.physics,this.states[a].rnd=this.game.rnd},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.onShutDownCallback=this.states[a].shutdown||this.dummy,this.current=a,this._created=!1,this.onInitCallback.call(this.callbackContext,this.game)},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,!0)},resume:function(){this._created&&this.onre&&this.onPausedCallback.call(this.callbackContext,this.game,!1)},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===d.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===d.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.onDestroyCallback=null,this.game=null,this.states={},this._pendingState=null}},d.LinkedList=function(){this.next=null,this.prev=null,this.first=null,this.last=null,this.total=0},d.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)}}},d.Signal=function(){this._bindings=[],this._prevParams=null;var a=this;this.dispatch=function(){d.Signal.prototype.dispatch.apply(a,arguments)}},d.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,b,c,e){var f,g=this._indexOfListener(a,c);if(-1!==g){if(f=this._bindings[g],f.isOnce()!==b)throw new Error("You cannot add"+(b?"":"Once")+"() then add"+(b?"Once":"")+"() the same listener without removing the relationship first.")}else f=new d.SignalBinding(this,a,b,c,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()+"]"}},d.SignalBinding=function(a,b,c,d,e){this._listener=b,this._isOnce=c,this.context=d,this._signal=a,this._priority=e||0},d.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+"]"}},d.Filter=function(a,b,c){this.game=a,this.type=d.WEBGL_FILTER,this.passes=[this],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=c||[]},d.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}},Object.defineProperty(d.Filter.prototype,"width",{get:function(){return this.uniforms.resolution.value.x},set:function(a){this.uniforms.resolution.value.x=a}}),Object.defineProperty(d.Filter.prototype,"height",{get:function(){return this.uniforms.resolution.value.y},set:function(a){this.uniforms.resolution.value.y=a}}),d.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},d.Plugin.prototype={preUpdate:function(){},update:function(){},render:function(){},postRender:function(){},destroy:function(){this.game=null,this.parent=null,this.active=!1,this.visible=!1}},d.PluginManager=function(a,b){this.game=a,this._parent=b,this.plugins=[],this._pluginsLength=0},d.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._pthis._nextOffsetCheck&&(d.Canvas.getOffset(this.canvas,this.offset),this._nextOffsetCheck=this.game.time.now+this.checkOffsetInterval)},visibilityChange:function(a){this.disableVisibilityChange||(this.game.paused="pagehide"==a.type||"blur"==a.type||document.hidden===!0||document.webkitHidden===!0?!0:!1)}},Object.defineProperty(d.Stage.prototype,"backgroundColor",{get:function(){return this._backgroundColor},set:function(a){this._backgroundColor=a,this.game.transparent===!1&&(this.game.renderType==d.CANVAS?this.game.canvas.style.backgroundColor=a:("string"==typeof a&&(a=d.Color.hexToRGB(a)),this._stage.setBackgroundColor(a)))}}),d.Group=function(a,b,e,f){("undefined"==typeof b||null===typeof b)&&(b=a.world),"undefined"==typeof f&&(f=!1),this.game=a,this.name=e||"group",f?this._container=this.game.stage._stage:(this._container=new c.DisplayObjectContainer,this._container.name=this.name,b?b instanceof d.Group?(b._container.addChild(this._container),b._container.updateTransform()):(b.addChild(this._container),b.updateTransform()):(this.game.stage._stage.addChild(this._container),this.game.stage._stage.updateTransform())),this.type=d.GROUP,this.exists=!0,this.scale=new d.Point(1,1),this.cursor=null},d.Group.RETURN_NONE=0,d.Group.RETURN_TOTAL=1,d.Group.RETURN_CHILD=2,d.Group.SORT_ASCENDING=-1,d.Group.SORT_DESCENDING=1,d.Group.prototype={add:function(a){return a.group!==this&&(a.group=this,a.events&&a.events.onAddedToGroup.dispatch(a,this),this._container.addChild(a),a.updateTransform(),null===this.cursor&&(this.cursor=a)),a},addAt:function(a,b){return a.group!==this&&(a.group=this,a.events&&a.events.onAddedToGroup.dispatch(a,this),this._container.addChildAt(a,b),a.updateTransform(),null===this.cursor&&(this.cursor=a)),a},getAt:function(a){return this._container.getChildAt(a)},create:function(a,b,c,e,f){"undefined"==typeof f&&(f=!0);var g=new d.Sprite(this.game,a,b,c,e);return g.group=this,g.exists=f,g.visible=f,g.alive=f,g.events&&g.events.onAddedToGroup.dispatch(g,this),this._container.addChild(g),g.updateTransform(),null===this.cursor&&(this.cursor=g),g},createMultiple:function(a,b,c,e){"undefined"==typeof e&&(e=!1);for(var f=0;a>f;f++){var g=new d.Sprite(this.game,0,0,b,c);g.group=this,g.exists=e,g.visible=e,g.alive=e,g.events&&g.events.onAddedToGroup.dispatch(g,this),this._container.addChild(g),g.updateTransform(),null===this.cursor&&(this.cursor=g)}},next:function(){this.cursor&&(this.cursor=this.cursor==this._container.last?this._container._iNext:this.cursor._iNext)},previous:function(){this.cursor&&(this.cursor=this.cursor==this._container._iNext?this._container.last:this.cursor._iPrev)},childTest:function(a,b){var c=a+" next: ";c+=b._iNext?b._iNext.name:"-null-",c=c+" "+a+" prev: ",c+=b._iPrev?b._iPrev.name:"-null-",console.log(c)},swapIndex:function(a,b){var c=this.getAt(a),d=this.getAt(b);console.log("swapIndex ",a," with ",b),this.swap(c,d)},swap:function(a,b){if(a===b||!a.parent||!b.parent||a.group!==this||b.group!==this)return!1;var c=a._iPrev,d=a._iNext,e=b._iPrev,f=b._iNext,g=this._container.last._iNext,h=this.game.stage._stage;do h!==a&&h!==b&&(h.first===a?h.first=b:h.first===b&&(h.first=a),h.last===a?h.last=b:h.last===b&&(h.last=a)),h=h._iNext;while(h!=g);return a._iNext==b?(a._iNext=f,a._iPrev=b,b._iNext=a,b._iPrev=c,c&&(c._iNext=b),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):b._iNext==a?(a._iNext=b,a._iPrev=e,b._iNext=d,b._iPrev=a,e&&(e._iNext=a),d&&(d._iPrev=b),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):(a._iNext=f,a._iPrev=e,b._iNext=d,b._iPrev=c,c&&(c._iNext=b),d&&(d._iPrev=b),e&&(e._iNext=a),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0)},bringToTop:function(a){return a.group===this&&(this.remove(a),this.add(a)),a},getIndex:function(a){return this._container.children.indexOf(a)},replace:function(a,b){if(this._container.first._iNext){var c=this.getIndex(a);-1!=c&&(void 0!==b.parent&&(b.events.onRemovedFromGroup.dispatch(b,this),b.parent.removeChild(b)),this._container.removeChild(a),this._container.addChildAt(b,c),b.events.onAddedToGroup.dispatch(b,this),b.updateTransform(),this.cursor==a&&(this.cursor=this._container._iNext))}},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))},setAll:function(a,b,c,d,e){if(a=a.split("."),"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),e=e||0,this._container.children.length>0&&this._container.first._iNext){var f=this._container.first._iNext;do(c===!1||c&&f.alive)&&(d===!1||d&&f.visible)&&this.setProperty(f,a,b,e),f=f._iNext;while(f!=this._container.last._iNext)}},addAll:function(a,b,c,d){this.setAll(a,b,c,d,1)},subAll:function(a,b,c,d){this.setAll(a,b,c,d,2)},multiplyAll:function(a,b,c,d){this.setAll(a,b,c,d,3)},divideAll:function(a,b,c,d){this.setAll(a,b,c,d,4)},callAllExists:function(a,b){var c=Array.prototype.splice.call(arguments,2);if(this._container.children.length>0&&this._container.first._iNext){var d=this._container.first._iNext;do d.exists==b&&d[a]&&d[a].apply(d,c),d=d._iNext;while(d!=this._container.last._iNext)}},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},callAll:function(a,b){if("undefined"!=typeof a){a=a.split(".");var c=a.length;if("undefined"==typeof b)b=null;else if("string"==typeof b){b=b.split(".");var d=b.length}var e=Array.prototype.splice.call(arguments,2),f=null,g=null;if(this._container.children.length>0&&this._container.first._iNext){var h=this._container.first._iNext;do f=this.callbackFromArray(h,a,c),b&&f?(g=this.callbackFromArray(h,b,d),f&&f.apply(g,e)):f&&f.apply(h,e),h=h._iNext;while(h!=this._container.last._iNext)}}},forEach:function(a,b,c){"undefined"==typeof c&&(c=!1);var d=Array.prototype.splice.call(arguments,3);if(d.unshift(null),this._container.children.length>0&&this._container.first._iNext){var e=this._container.first._iNext;do(c===!1||c&&e.exists)&&(d[0]=e,a.apply(b,d)),e=e._iNext;while(e!=this._container.last._iNext)}},forEachExists:function(a,b){var c=Array.prototype.splice.call(arguments,2);c.unshift(null),this.iterate("exists",!0,d.Group.RETURN_TOTAL,a,b,c)},forEachAlive:function(a,b){var c=Array.prototype.splice.call(arguments,2);c.unshift(null),this.iterate("alive",!0,d.Group.RETURN_TOTAL,a,b,c)},forEachDead:function(a,b){var c=Array.prototype.splice.call(arguments,2);c.unshift(null),this.iterate("alive",!1,d.Group.RETURN_TOTAL,a,b,c)},sort:function(a,b){"undefined"==typeof a&&(a="y"),"undefined"==typeof b&&(b=d.Group.SORT_ASCENDING);var c,e;do{c=!1;for(var f=0,g=this._container.children.length-1;g>f;f++)b==d.Group.SORT_ASCENDING?this._container.children[f][a]>this._container.children[f+1][a]&&(this.swap(this.getAt(f),this.getAt(f+1)),e=this._container.children[f],this._container.children[f]=this._container.children[f+1],this._container.children[f+1]=e,c=!0):this._container.children[f][a]0&&this._container.first._iNext){var i=this._container.first._iNext;do{if(i[a]===b&&(h++,e&&(g[0]=i,e.apply(f,g)),c==d.Group.RETURN_CHILD))return i;i=i._iNext}while(i!=this._container.last._iNext)}return c==d.Group.RETURN_TOTAL?h:c==d.Group.RETURN_CHILD?null:void 0},getFirstExists:function(a){return"boolean"!=typeof a&&(a=!0),this.iterate("exists",a,d.Group.RETURN_CHILD)},getFirstAlive:function(){return this.iterate("alive",!0,d.Group.RETURN_CHILD)},getFirstDead:function(){return this.iterate("alive",!1,d.Group.RETURN_CHILD)},countLiving:function(){return this.iterate("alive",!0,d.Group.RETURN_TOTAL)},countDead:function(){return this.iterate("alive",!1,d.Group.RETURN_TOTAL)},getRandom:function(a,b){return 0===this._container.children.length?null:(a=a||0,b=b||this._container.children.length,this.game.math.getRandom(this._container.children,a,b))},remove:function(a){return a.group!==this?!1:(a.events&&a.events.onRemovedFromGroup.dispatch(a,this),a.parent===this._container&&this._container.removeChild(a),this.cursor==a&&(this.cursor=this._container._iNext?this._container._iNext:null),a.group=null,!0)},removeAll:function(){if(0!==this._container.children.length){do this._container.children[0].events&&this._container.children[0].events.onRemovedFromGroup.dispatch(this._container.children[0],this),this._container.removeChild(this._container.children[0]);while(this._container.children.length>0);this.cursor=null}},removeBetween:function(a,b){if(0!==this._container.children.length){if(a>b||0>a||b>this._container.children.length)return!1;for(var c=a;b>c;c++){var d=this._container.children[c];d.events.onRemovedFromGroup.dispatch(d,this),this._container.removeChild(d),this.cursor==d&&(this.cursor=this._container._iNext?this._container._iNext:null)}}},destroy:function(){this.removeAll(),this._container.parent.removeChild(this._container),this._container=null,this.game=null,this.exists=!1,this.cursor=null},validate:function(){var a=this.game.stage._stage.last._iNext,b=this.game.stage._stage,c=null,d=null,e=0;do{if(e>0){if(b!==c)return console.log("check next fail"),!1;if(b._iPrev!==d)return console.log("check previous fail"),!1}c=b._iNext,d=b,b=b._iNext,e++}while(b!=a);return!0},dump:function(a){"undefined"==typeof a&&(a=!1);var b=20,c="\n"+d.Utils.pad("Node",b)+"|"+d.Utils.pad("Next",b)+"|"+d.Utils.pad("Previous",b)+"|"+d.Utils.pad("First",b)+"|"+d.Utils.pad("Last",b);console.log(c);var c=d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b);if(console.log(c),a)var e=this.game.stage._stage.last._iNext,f=this.game.stage._stage;else var e=this._container.last._iNext,f=this._container;do{var g=f.name||"*";if(this.cursor==f)var g="> "+g;var h="-",i="-",j="-",k="-";f._iNext&&(h=f._iNext.name),f._iPrev&&(i=f._iPrev.name),f.first&&(j=f.first.name),f.last&&(k=f.last.name),"undefined"==typeof h&&(h="-"),"undefined"==typeof i&&(i="-"),"undefined"==typeof j&&(j="-"),"undefined"==typeof k&&(k="-");var c=d.Utils.pad(g,b)+"|"+d.Utils.pad(h,b)+"|"+d.Utils.pad(i,b)+"|"+d.Utils.pad(j,b)+"|"+d.Utils.pad(k,b);console.log(c),f=f._iNext}while(f!=e)}},Object.defineProperty(d.Group.prototype,"total",{get:function(){return this.iterate("exists",!0,d.Group.RETURN_TOTAL)}}),Object.defineProperty(d.Group.prototype,"length",{get:function(){return this.iterate("exists",!0,d.Group.RETURN_TOTAL)}}),Object.defineProperty(d.Group.prototype,"x",{get:function(){return this._container.position.x},set:function(a){this._container.position.x=a}}),Object.defineProperty(d.Group.prototype,"y",{get:function(){return this._container.position.y},set:function(a){this._container.position.y=a}}),Object.defineProperty(d.Group.prototype,"angle",{get:function(){return d.Math.radToDeg(this._container.rotation)},set:function(a){this._container.rotation=d.Math.degToRad(a)}}),Object.defineProperty(d.Group.prototype,"rotation",{get:function(){return this._container.rotation},set:function(a){this._container.rotation=a}}),Object.defineProperty(d.Group.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(d.Group.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),d.World=function(a){d.Group.call(this,a,null,"__world",!1),this.scale=new d.Point(1,1),this.bounds=new d.Rectangle(0,0,a.width,a.height),this.camera=null,this.currentRenderOrderID=0},d.World.prototype=Object.create(d.Group.prototype),d.World.prototype.constructor=d.World,d.World.prototype.boot=function(){this.camera=new d.Camera(this.game,0,0,0,this.game.width,this.game.height),this.camera.displayObject=this._container,this.game.camera=this.camera},d.World.prototype.update=function(){if(this.currentRenderOrderID=0,this.game.stage._stage.first._iNext){var a,b=this.game.stage._stage.first._iNext;do a=!1,b.preUpdate&&(a=b.preUpdate()===!1),b.update&&(a=b.update()===!1||a),b=a?b.last._iNext:b._iNext;while(b!=this.game.stage._stage.last._iNext)}},d.World.prototype.postUpdate=function(){if(this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a.postUpdate&&a.postUpdate(),a=a._iNext;while(a!=this.game.stage._stage.last._iNext)}this.camera.update()},d.World.prototype.setBounds=function(a,b,c,d){this.bounds.setTo(a,b,c,d),this.camera.bounds&&this.camera.bounds.setTo(a,b,c,d)},d.World.prototype.destroy=function(){this.camera.x=0,this.camera.y=0,this.game.input.reset(!0),this.removeAll()},Object.defineProperty(d.World.prototype,"width",{get:function(){return this.bounds.width},set:function(a){this.bounds.width=a}}),Object.defineProperty(d.World.prototype,"height",{get:function(){return this.bounds.height},set:function(a){this.bounds.height=a}}),Object.defineProperty(d.World.prototype,"centerX",{get:function(){return this.bounds.halfWidth}}),Object.defineProperty(d.World.prototype,"centerY",{get:function(){return this.bounds.halfHeight}}),Object.defineProperty(d.World.prototype,"randomX",{get:function(){return this.bounds.x<0?this.game.rnd.integerInRange(this.bounds.x,this.bounds.width-Math.abs(this.bounds.x)):this.game.rnd.integerInRange(this.bounds.x,this.bounds.width)}}),Object.defineProperty(d.World.prototype,"randomY",{get:function(){return this.bounds.y<0?this.game.rnd.integerInRange(this.bounds.y,this.bounds.height-Math.abs(this.bounds.y)):this.game.rnd.integerInRange(this.bounds.y,this.bounds.height)}}),Object.defineProperty(d.World.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),d.Game=function(a,b,c,e,f,g,h){a=a||800,b=b||600,c=c||d.AUTO,e=e||"",f=f||null,"undefined"==typeof g&&(g=!1),"undefined"==typeof h&&(h=!0),this.id=d.GAMES.push(this)-1,this.parent=e,this.width=a,this.height=b,this.transparent=g,this.antialias=h,this.renderer=null,this.state=new d.StateManager(this,f),this._paused=!1,this.renderType=c,this._loadComplete=!1,this.isBooted=!1,this.isRunning=!1,this.raf=null,this.add=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.net=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;var i=this;return this._onBoot=function(){return i.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},d.Game.prototype={boot:function(){this.isBooted||(document.body?(document.removeEventListener("DOMContentLoaded",this._onBoot),window.removeEventListener("load",this._onBoot),this.onPause=new d.Signal,this.onResume=new d.Signal,this.isBooted=!0,this.device=new d.Device,this.math=d.Math,this.rnd=new d.RandomDataGenerator([(Date.now()*Math.random()).toString()]),this.stage=new d.Stage(this,this.width,this.height),this.setUpRenderer(),this.world=new d.World(this),this.add=new d.GameObjectFactory(this),this.cache=new d.Cache(this),this.load=new d.Loader(this),this.time=new d.Time(this),this.tweens=new d.TweenManager(this),this.input=new d.Input(this),this.sound=new d.SoundManager(this),this.physics=new d.Physics.Arcade(this),this.particles=new d.Particles(this),this.plugins=new d.PluginManager(this,this),this.net=new d.Net(this),this.debug=new d.Utils.Debug(this),this.stage.boot(),this.world.boot(),this.input.boot(),this.sound.boot(),this.state.boot(),this.load.onLoadComplete.add(this.loadComplete,this),this.showDebugHeader(),this.isRunning=!0,this._loadComplete=!1,this.raf=new d.RequestAnimationFrame(this),this.raf.start()):window.setTimeout(this._onBoot,20))},showDebugHeader:function(){var a=d.DEV_VERSION,b="Canvas",c="HTML Audio";if(this.renderType==d.WEBGL?b="WebGL":this.renderType==d.HEADLESS&&(b="Headless"),this.device.webAudio&&(c="WebAudio"),this.device.chrome){var e=["%c %c %c Phaser v"+a+" - Renderer: "+b+" - Audio: "+c+" %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: "+b+" - Audio: "+c)},setUpRenderer:function(){if(this.renderType===d.HEADLESS||this.renderType===d.CANVAS||this.renderType===d.AUTO&&this.device.webGL===!1){if(!this.device.canvas)throw new Error("Phaser.Game - cannot create Canvas or WebGL context, aborting.");this.renderType===d.AUTO&&(this.renderType=d.CANVAS),this.renderer=new c.CanvasRenderer(this.width,this.height,this.stage.canvas,this.transparent),d.Canvas.setSmoothingEnabled(this.renderer.context,this.antialias),this.canvas=this.renderer.view,this.context=this.renderer.context}else this.renderType=d.WEBGL,this.renderer=new c.WebGLRenderer(this.width,this.height,this.stage.canvas,this.transparent,this.antialias),this.canvas=this.renderer.view,this.context=null;d.Canvas.addToDOM(this.renderer.view,this.parent,!0),d.Canvas.setTouchAction(this.renderer.view)},loadComplete:function(){this._loadComplete=!0,this.state.loadComplete()},update:function(a){this.time.update(a),this._paused?(this.renderer.render(this.stage._stage),this.plugins.render(),this.state.render()):(this.plugins.preUpdate(),this.physics.preUpdate(),this.stage.update(),this.input.update(),this.tweens.update(),this.sound.update(),this.world.update(),this.particles.update(),this.state.update(),this.plugins.update(),this.world.postUpdate(),this.plugins.postUpdate(),this.renderType!==d.HEADLESS&&(this.renderer.render(this.stage._stage),this.plugins.render(),this.state.render(),this.plugins.postRender()))},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}},Object.defineProperty(d.Game.prototype,"paused",{get:function(){return this._paused},set:function(a){a===!0?this._paused===!1&&(this._paused=!0,this.onPause.dispatch(this)):this._paused&&(this._paused=!1,this.onResume.dispatch(this))}}),d.Input=function(a){this.game=a,this.hitCanvas=null,this.hitContext=null},d.Input.MOUSE_OVERRIDES_TOUCH=0,d.Input.TOUCH_OVERRIDES_MOUSE=1,d.Input.MOUSE_TOUCH_COMBINE=2,d.Input.prototype={pollRate:0,_pollCounter:0,_oldPosition:null,_x:0,_y:0,disabled:!1,multiInputOverride:d.Input.MOUSE_TOUCH_COMBINE,position:null,speed:null,circle:null,scale:null,maxPointers:10,currentPointers:0,tapRate:200,doubleTapRate:300,holdRate:2e3,justPressedRate:200,justReleasedRate:200,recordPointerHistory:!1,recordRate:100,recordLimit:100,pointer1:null,pointer2:null,pointer3:null,pointer4:null,pointer5:null,pointer6:null,pointer7:null,pointer8:null,pointer9:null,pointer10:null,activePointer:null,mousePointer:null,mouse:null,keyboard:null,touch:null,mspointer:null,onDown:null,onUp:null,onTap:null,onHold:null,interactiveItems:new d.LinkedList,boot:function(){this.mousePointer=new d.Pointer(this.game,0),this.pointer1=new d.Pointer(this.game,1),this.pointer2=new d.Pointer(this.game,2),this.mouse=new d.Mouse(this.game),this.keyboard=new d.Keyboard(this.game),this.touch=new d.Touch(this.game),this.mspointer=new d.MSPointer(this.game),this.onDown=new d.Signal,this.onUp=new d.Signal,this.onTap=new d.Signal,this.onHold=new d.Signal,this.scale=new d.Point(1,1),this.speed=new d.Point,this.position=new d.Point,this._oldPosition=new d.Point,this.circle=new d.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()},addPointer:function(){for(var a=0,b=10;b>0;b--)null===this["pointer"+b]&&(a=b);return 0===a?(console.warn("You can only have 10 Pointer objects"),null):(this["pointer"+a]=new d.Pointer(this.game,a),this["pointer"+a])},update:function(){return this.pollRate>0&&this._pollCounter=b;b++)this["pointer"+b]&&this["pointer"+b].reset();this.currentPointers=0,this.game.stage.canvas.style.cursor="default",a===!0&&(this.onDown.dispose(),this.onUp.dispose(),this.onTap.dispose(),this.onHold.dispose(),this.onDown=new d.Signal,this.onUp=new d.Signal,this.onTap=new d.Signal,this.onHold=new d.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}},Object.defineProperty(d.Input.prototype,"x",{get:function(){return this._x},set:function(a){this._x=Math.floor(a)}}),Object.defineProperty(d.Input.prototype,"y",{get:function(){return this._y},set:function(a){this._y=Math.floor(a)}}),Object.defineProperty(d.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(d.Input.prototype,"worldX",{get:function(){return this.game.camera.view.x+this.x}}),Object.defineProperty(d.Input.prototype,"worldY",{get:function(){return this.game.camera.view.y+this.y}}),d.Key=function(a,b){this.game=a,this.isDown=!1,this.isUp=!1,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.timeDown=0,this.duration=0,this.timeUp=0,this.repeats=0,this.keyCode=b,this.onDown=new d.Signal,this.onUp=new d.Signal},d.Key.prototype={processKeyDown:function(a){this.altKey=a.altKey,this.ctrlKey=a.ctrlKey,this.shiftKey=a.shiftKey,this.isDown?(this.duration=a.timeStamp-this.timeDown,this.repeats++):(this.isDown=!0,this.isUp=!1,this.timeDown=a.timeStamp,this.duration=0,this.repeats=0,this.onDown.dispatch(this))},processKeyUp:function(a){this.isDown=!1,this.isUp=!0,this.timeUp=a.timeStamp,this.onUp.dispatch(this)},justPressed:function(a){return"undefined"==typeof a&&(a=250),this.isDown&&this.duration=this.game.input.holdRate&&((this.game.input.multiInputOverride==d.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==d.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==d.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){if(!this.game.input.pollLocked){if("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==d.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==d.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==d.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(null!==this.targetObject&&this.targetObject.isDragged===!0)return this.targetObject.update(this)===!1&&(this.targetObject=null),this;if(this._highestRenderOrderID=-1,this._highestRenderObject=null,this._highestInputPriorityID=-1,this.game.input.interactiveItems.total>0){var b=this.game.input.interactiveItems.next;do(b.pixelPerfect||b.priorityID>this._highestInputPriorityID||b.priorityID==this._highestInputPriorityID&&b.sprite.renderOrderID>this._highestRenderOrderID)&&b.checkPointerOver(this)&&(this._highestRenderOrderID=b.sprite.renderOrderID,this._highestInputPriorityID=b.priorityID,this._highestRenderObject=b),b=b.next;while(null!=b)}return null==this._highestRenderObject?this.targetObject&&(this.targetObject._pointerOutHandler(this),this.targetObject=null):null==this.targetObject?(this.targetObject=this._highestRenderObject,this._highestRenderObject._pointerOverHandler(this)):this.targetObject==this._highestRenderObject?this._highestRenderObject.update(this)===!1&&(this.targetObject=null):(this.targetObject._pointerOutHandler(this),this.targetObject=this._highestRenderObject,this.targetObject._pointerOverHandler(this)),this}},leave:function(a){this.withinGame=!1,this.move(a)},stop:function(a){if(this._stateReset)return a.preventDefault(),void 0;if(this.timeUp=this.game.time.now,(this.game.input.multiInputOverride==d.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==d.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==d.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.onUp.dispatch(this,a),this.duration>=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 b=this.game.input.interactiveItems.next;do b&&b._releasedHandler(this),b=b.next;while(null!=b)}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}},Object.defineProperty(d.Pointer.prototype,"duration",{get:function(){return this.isUp?-1:this.game.time.now-this.timeDown}}),Object.defineProperty(d.Pointer.prototype,"worldX",{get:function(){return this.game.world.camera.x+this.x}}),Object.defineProperty(d.Pointer.prototype,"worldY",{get:function(){return this.game.world.camera.y+this.y}}),d.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},d.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.renderer.view.addEventListener("touchstart",this._onTouchStart,!1),this.game.renderer.view.addEventListener("touchmove",this._onTouchMove,!1),this.game.renderer.view.addEventListener("touchend",this._onTouchEnd,!1),this.game.renderer.view.addEventListener("touchenter",this._onTouchEnter,!1),this.game.renderer.view.addEventListener("touchleave",this._onTouchLeave,!1),this.game.renderer.view.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;bc;c++)this._pointerData[c]={id:c,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 d.Point,this.enabled=!0,this.sprite.events&&null==this.sprite.events.onInputOver&&(this.sprite.events.onInputOver=new d.Signal,this.sprite.events.onInputOut=new d.Signal,this.sprite.events.onInputDown=new d.Signal,this.sprite.events.onInputUp=new d.Signal,this.sprite.events.onDragStart=new d.Signal,this.sprite.events.onDragStop=new d.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.stop(),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},checkPointerOver:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?!1:(this.sprite.getLocalUnmodifiedPosition(this._tempPoint,a.x,a.y),this._tempPoint.x>=0&&this._tempPoint.x<=this.sprite.currentFrame.width&&this._tempPoint.y>=0&&this._tempPoint.y<=this.sprite.currentFrame.height?this.pixelPerfect?this.checkPixel(this._tempPoint.x,this._tempPoint.y):!0:void 0)},checkPixel:function(a,b){if(this.sprite.texture.baseTexture.source){this.game.input.hitContext.clearRect(0,0,1,1),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 c=this.game.input.hitContext.getImageData(0,0,1,1);if(c.data[3]>=this.pixelPerfectAlpha)return!0}return!1},update:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?(this._pointerOutHandler(a),!1):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},_pointerOverHandler:function(a){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.stage.canvas.style.cursor="pointer"),this.sprite.events.onInputOver.dispatch(this.sprite,a))},_pointerOutHandler:function(a){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.stage.canvas.style.cursor="default"),this.sprite&&this.sprite.events&&this.sprite.events.onInputOut.dispatch(this.sprite,a)},_touchedHandler:function(a){return this._pointerData[a.id].isDown===!1&&this._pointerData[a.id].isOver===!0&&(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()),this.consumePointerEvent},_releasedHandler:function(a){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):this.useHandCursor&&(this.game.stage.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.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.snapX)*this.snapX,this.sprite.y=Math.round(this.sprite.y/this.snapY)*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.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.x=Math.round(this.sprite.x/this.snapX)*this.snapX,this.sprite.y=Math.round(this.sprite.y/this.snapY)*this.snapY),this.sprite.events.onDragStop.dispatch(this.sprite,a),this.sprite.events.onInputUp.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){"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!1),this.snapX=a,this.snapY=b,this.snapOnDrag=c,this.snapOnRelease=d},disableSnap:function(){this.snapOnDrag=!1,this.snapOnRelease=!1},checkBoundsRect:function(){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.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)}},d.Events=function(a){this.parent=a,this.onAddedToGroup=new d.Signal,this.onRemovedFromGroup=new d.Signal,this.onKilled=new d.Signal,this.onRevived=new d.Signal,this.onOutOfBounds=new d.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},d.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())}},d.GameObjectFactory=function(a){this.game=a,this.world=this.game.world},d.GameObjectFactory.prototype={existing:function(a){return this.world.add(a)},sprite:function(a,b,c,d){return this.world.create(a,b,c,d)},child:function(a,b,c,d,e){return a.create(b,c,d,e)},tween:function(a){return this.game.tweens.create(a)},group:function(a,b){return new d.Group(this.game,a,b)},audio:function(a,b,c,d){return this.game.sound.add(a,b,c,d)},tileSprite:function(a,b,c,e,f,g){return this.world.add(new d.TileSprite(this.game,a,b,c,e,f,g))},text:function(a,b,c,e){return this.world.add(new d.Text(this.game,a,b,c,e))},button:function(a,b,c,e,f,g,h,i){return this.world.add(new d.Button(this.game,a,b,c,e,f,g,h,i))},graphics:function(a,b){return this.world.add(new d.Graphics(this.game,a,b))},emitter:function(a,b,c){return this.game.particles.add(new d.Particles.Arcade.Emitter(this.game,a,b,c))},bitmapText:function(a,b,c,e){return this.world.add(new d.BitmapText(this.game,a,b,c,e))},tilemap:function(a){return new d.Tilemap(this.game,a)},tileset:function(a){return this.game.cache.getTileset(a)},tilemapLayer:function(a,b,c,e,f,g,h){return this.world.add(new d.TilemapLayer(this.game,a,b,c,e,f,g,h))},renderTexture:function(a,b,c){var e=new d.RenderTexture(this.game,a,b,c);return this.game.cache.addRenderTexture(a,e),e},bitmapData:function(a,b){return new d.BitmapData(this.game,a,b)},filter:function(a){var b=Array.prototype.splice.call(arguments,1),a=new d.Filter[a](this.game);return a.init.apply(a,b),a}},d.BitmapData=function(a,b,e){"undefined"==typeof b&&(b=256),"undefined"==typeof e&&(e=256),this.game=a,this.name="",this.width=b,this.height=e,this.canvas=d.Canvas.create(b,e),this.context=this.canvas.getContext("2d"),this.imageData=this.context.getImageData(0,0,b,e),this.pixels=this.imageData.data.buffer?this.imageData.data.buffer:this.imageData.data,this.baseTexture=new c.BaseTexture(this.canvas),this.texture=new c.Texture(this.baseTexture),this.textureFrame=new d.Frame(0,0,0,b,e,"bitmapData",a.rnd.uuid()),this.type=d.BITMAPDATA,this._dirty=!1},d.BitmapData.prototype={add:function(a){a.loadTexture(this)},addTo:function(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)},arc:function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=!1),this._dirty=!0,this.context.arc(a,b,c,d,e,f),this},arcTo:function(a,b,c,d,e){return this._dirty=!0,this.context.arcTo(a,b,c,d,e),this},beginFill:function(a){return this.fillStyle(a),this},beginLinearGradientFill:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.fillStyle(g),this},beginLinearGradientStroke:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.strokeStyle(g),this},beginRadialGradientStroke:function(a,b,c,d,e,f,g,h){for(var i=this.createRadialGradient(c,d,e,f,g,h),j=0,k=a.length;k>j;j++)i.addColorStop(b[j],a[j]);return this.strokeStyle(i),this},beginPath:function(){return this.context.beginPath(),this},beginStroke:function(a){return this.strokeStyle(a),this},bezierCurveTo:function(a,b,c,d,e,f){return this._dirty=!0,this.context.bezierCurveTo(a,b,c,d,e,f),this},circle:function(a,b,c){return this.arc(a,b,c,0,2*Math.PI),this},clearRect:function(a,b,c,d){return this._dirty=!0,this.context.clearRect(a,b,c,d),this},clip:function(){return this._dirty=!0,this.context.clip(),this},closePath:function(){return this._dirty=!0,this.context.closePath(),this},createLinearGradient:function(a,b,c,d){return this.context.createLinearGradient(a,b,c,d)},createRadialGradient:function(a,b,c,d,e,f){return this.context.createRadialGradient(a,b,c,d,e,f)},ellipse:function(a,b,c,d){var e=.5522848,f=c/2*e,g=d/2*e,h=a+c,i=b+d,j=a+c/2,k=b+d/2;return this.moveTo(a,k),this.bezierCurveTo(a,k-g,j-f,b,j,b),this.bezierCurveTo(j+f,b,h,k-g,h,k),this.bezierCurveTo(h,k+g,j+f,i,j,i),this.bezierCurveTo(j-f,i,a,k+g,a,k),this},fill:function(){return this._dirty=!0,this.context.fill(),this},fillRect:function(a,b,c,d){return this._dirty=!0,this.context.fillRect(a,b,c,d),this},fillStyle:function(a){return this.context.fillStyle=a,this},font:function(a){return this.context.font=a,this},globalAlpha:function(a){return this.context.globalAlpha=a,this},globalCompositeOperation:function(a){return this.context.globalCompositeOperation=a,this},lineCap:function(a){return this.context.lineCap=a,this},lineDashOffset:function(a){return this.context.lineDashOffset=a,this},lineJoin:function(a){return this.context.lineJoin=a,this},lineWidth:function(a){return this.context.lineWidth=a,this},miterLimit:function(a){return this.context.miterLimit=a,this},lineTo:function(a,b){return this._dirty=!0,this.context.lineTo(a,b),this},moveTo:function(a,b){return this.context.moveTo(a,b),this},quadraticCurveTo:function(a,b,c,d){return this._dirty=!0,this.context.quadraticCurveTo(a,b,c,d),this},rect:function(a,b,c,d){return this._dirty=!0,this.context.rect(a,b,c,d),this},restore:function(){return this._dirty=!0,this.context.restore(),this},rotate:function(a){return this._dirty=!0,this.context.rotate(a),this},setStrokeStyle:function(a,b,c,d,e){return"undefined"==typeof a&&(a=1),"undefined"==typeof b&&(b="butt"),"undefined"==typeof c&&(c="miter"),"undefined"==typeof d&&(d=10),e=!1,this.lineWidth(a),this.lineCap(b),this.lineJoin(c),this.miterLimit(d),this},save:function(){return this._dirty=!0,this.context.save(),this},scale:function(a,b){return this._dirty=!0,this.context.scale(a,b),this},scrollPathIntoView:function(){return this._dirty=!0,this.context.scrollPathIntoView(),this},stroke:function(){return this._dirty=!0,this.context.stroke(),this},strokeRect:function(a,b,c,d){return this._dirty=!0,this.context.strokeRect(a,b,c,d),this},strokeStyle:function(a){return this.context.strokeStyle=a,this},render:function(){this._dirty&&(this.game.renderType==d.WEBGL&&c.texturesToUpdate.push(this.baseTexture),this._dirty=!1)}},d.BitmapData.prototype.mt=d.BitmapData.prototype.moveTo,d.BitmapData.prototype.lt=d.BitmapData.prototype.lineTo,d.BitmapData.prototype.at=d.BitmapData.prototype.arcTo,d.BitmapData.prototype.bt=d.BitmapData.prototype.bezierCurveTo,d.BitmapData.prototype.qt=d.BitmapData.prototype.quadraticCurveTo,d.BitmapData.prototype.a=d.BitmapData.prototype.arc,d.BitmapData.prototype.r=d.BitmapData.prototype.rect,d.BitmapData.prototype.cp=d.BitmapData.prototype.closePath,d.BitmapData.prototype.c=d.BitmapData.prototype.clear,d.BitmapData.prototype.f=d.BitmapData.prototype.beginFill,d.BitmapData.prototype.lf=d.BitmapData.prototype.beginLinearGradientFill,d.BitmapData.prototype.rf=d.BitmapData.prototype.beginRadialGradientFill,d.BitmapData.prototype.ef=d.BitmapData.prototype.endFill,d.BitmapData.prototype.ss=d.BitmapData.prototype.setStrokeStyle,d.BitmapData.prototype.s=d.BitmapData.prototype.beginStroke,d.BitmapData.prototype.ls=d.BitmapData.prototype.beginLinearGradientStroke,d.BitmapData.prototype.rs=d.BitmapData.prototype.beginRadialGradientStroke,d.BitmapData.prototype.dr=d.BitmapData.prototype.rect,d.BitmapData.prototype.dc=d.BitmapData.prototype.circle,d.BitmapData.prototype.de=d.BitmapData.prototype.ellipse,d.Sprite=function(a,b,e,f,g){b=b||0,e=e||0,f=f||null,g=g||null,this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=d.SPRITE,this.renderOrderID=-1,this.lifespan=0,this.events=new d.Events(this),this.animations=new d.AnimationManager(this),this.input=new d.InputHandler(this),this.key=f,this.currentFrame=null,f instanceof d.RenderTexture?(c.Sprite.call(this,f),this.currentFrame=this.game.cache.getTextureFrame(f.name)):f instanceof d.BitmapData?(c.Sprite.call(this,f.texture,f.textureFrame),this.currentFrame=f.textureFrame):f instanceof c.Texture?(c.Sprite.call(this,f),this.currentFrame=g):(null===f||"undefined"==typeof f?(f="__default",this.key=f):"string"==typeof f&&this.game.cache.checkImageKey(f)===!1&&(f="__missing",this.key=f),c.Sprite.call(this,c.TextureCache[f]),this.game.cache.isSpriteSheet(f)?(this.animations.loadFrameData(this.game.cache.getFrameData(f)),null!==g&&("string"==typeof g?this.frameName=g:this.frame=g)):this.currentFrame=this.game.cache.getFrame(f)),this.textureRegion=new d.Rectangle(this.texture.frame.x,this.texture.frame.y,this.texture.frame.width,this.texture.frame.height),this.anchor=new d.Point,this.x=b,this.y=e,this.position.x=b,this.position.y=e,this.world=new d.Point(b,e),this.autoCull=!1,this.scale=new d.Point(1,1),this._cache={dirty:!1,a00:-1,a01:-1,a02:-1,a10:-1,a11:-1,a12:-1,id:-1,i01:-1,i10:-1,idi:-1,left:null,right:null,top:null,bottom:null,prevX:b,prevY:e,x:-1,y:-1,scaleX:1,scaleY:1,width:this.currentFrame.sourceSizeW,height:this.currentFrame.sourceSizeH,halfWidth:Math.floor(this.currentFrame.sourceSizeW/2),halfHeight:Math.floor(this.currentFrame.sourceSizeH/2),calcWidth:-1,calcHeight:-1,frameID:-1,frameWidth:this.currentFrame.width,frameHeight:this.currentFrame.height,cameraVisible:!0,cropX:0,cropY:0,cropWidth:this.currentFrame.sourceSizeW,cropHeight:this.currentFrame.sourceSizeH},this.offset=new d.Point,this.center=new d.Point(b+Math.floor(this._cache.width/2),e+Math.floor(this._cache.height/2)),this.topLeft=new d.Point(b,e),this.topRight=new d.Point(b+this._cache.width,e),this.bottomRight=new d.Point(b+this._cache.width,e+this._cache.height),this.bottomLeft=new d.Point(b,e+this._cache.height),this.bounds=new d.Rectangle(b,e,this._cache.width,this._cache.height),this.body=new d.Physics.Arcade.Body(this),this.health=1,this.inWorld=d.Rectangle.intersects(this.bounds,this.game.world.bounds),this.inWorldThreshold=0,this.outOfBoundsKill=!1,this._outOfBoundsFired=!1,this.fixedToCamera=!1,this.cameraOffset=new d.Point,this.crop=new d.Rectangle(0,0,this._cache.width,this._cache.height),this.cropEnabled=!1,this.updateCache(),this.updateBounds()
-},d.Sprite.prototype=Object.create(c.Sprite.prototype),d.Sprite.prototype.constructor=d.Sprite,d.Sprite.prototype.preUpdate=function(){return!this.exists||this.group&&!this.group.exists?(this.renderOrderID=-1,!1):this.lifespan>0&&(this.lifespan-=this.game.time.elapsed,this.lifespan<=0)?(this.kill(),!1):(this._cache.dirty=!1,this.visible&&(this.renderOrderID=this.game.world.currentRenderOrderID++),this.updateCache(),this.updateAnimation(),this.updateCrop(),(this._cache.dirty||this.world.x!==this._cache.prevX||this.world.y!==this._cache.prevY)&&this.updateBounds(),this.body&&this.body.preUpdate(),!0)},d.Sprite.prototype.updateCache=function(){this._cache.prevX=this.world.x,this._cache.prevY=this.world.y,this.fixedToCamera&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),(this.worldTransform[1]!=this._cache.i01||this.worldTransform[3]!=this._cache.i10||this.worldTransform[0]!=this._cache.a00||this.worldTransform[41]!=this._cache.a11)&&(this._cache.a00=this.worldTransform[0],this._cache.a01=this.worldTransform[1],this._cache.a10=this.worldTransform[3],this._cache.a11=this.worldTransform[4],this._cache.i01=this.worldTransform[1],this._cache.i10=this.worldTransform[3],this._cache.scaleX=Math.sqrt(this._cache.a00*this._cache.a00+this._cache.a01*this._cache.a01),this._cache.scaleY=Math.sqrt(this._cache.a10*this._cache.a10+this._cache.a11*this._cache.a11),this._cache.a01*=-1,this._cache.a10*=-1,this._cache.id=1/(this._cache.a00*this._cache.a11+this._cache.a01*-this._cache.a10),this._cache.idi=1/(this._cache.a00*this._cache.a11+this._cache.i01*-this._cache.i10),this._cache.dirty=!0),this._cache.a02=this.worldTransform[2],this._cache.a12=this.worldTransform[5]},d.Sprite.prototype.updateAnimation=function(){(this.animations.update()||this.currentFrame&&this.currentFrame.uuid!=this._cache.frameID)&&(this._cache.frameID=this.currentFrame.uuid,this._cache.frameWidth=this.texture.frame.width,this._cache.frameHeight=this.texture.frame.height,this._cache.width=this.currentFrame.width,this._cache.height=this.currentFrame.height,this._cache.halfWidth=Math.floor(this._cache.width/2),this._cache.halfHeight=Math.floor(this._cache.height/2),this._cache.dirty=!0)},d.Sprite.prototype.updateCrop=function(){!this.cropEnabled||this.crop.width==this._cache.cropWidth&&this.crop.height==this._cache.cropHeight&&this.crop.x==this._cache.cropX&&this.crop.y==this._cache.cropY||(this.crop.floorAll(),this._cache.cropX=this.crop.x,this._cache.cropY=this.crop.y,this._cache.cropWidth=this.crop.width,this._cache.cropHeight=this.crop.height,this.texture.frame=this.crop,this.texture.width=this.crop.width,this.texture.height=this.crop.height,this.texture.updateFrame=!0,c.Texture.frameUpdates.push(this.texture))},d.Sprite.prototype.updateBounds=function(){this.offset.setTo(this._cache.a02-this.anchor.x*this.width,this._cache.a12-this.anchor.y*this.height),this.getLocalPosition(this.center,this.offset.x+this.width/2,this.offset.y+this.height/2),this.getLocalPosition(this.topLeft,this.offset.x,this.offset.y),this.getLocalPosition(this.topRight,this.offset.x+this.width,this.offset.y),this.getLocalPosition(this.bottomLeft,this.offset.x,this.offset.y+this.height),this.getLocalPosition(this.bottomRight,this.offset.x+this.width,this.offset.y+this.height),this._cache.left=d.Math.min(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.right=d.Math.max(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.top=d.Math.min(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this._cache.bottom=d.Math.max(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this.bounds.setTo(this._cache.left,this._cache.top,this._cache.right-this._cache.left,this._cache.bottom-this._cache.top),this.updateFrame=!0,this.inWorld===!1?(this.inWorld=d.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld&&(this._outOfBoundsFired=!1)):(this.inWorld=d.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld===!1&&(this.events.onOutOfBounds.dispatch(this),this._outOfBoundsFired=!0,this.outOfBoundsKill&&this.kill())),this._cache.cameraVisible=d.Rectangle.intersects(this.game.world.camera.screenView,this.bounds,0),this.autoCull&&(this.renderable=this._cache.cameraVisible),this.body&&this.body.updateBounds(this.center.x,this.center.y,this._cache.scaleX,this._cache.scaleY)},d.Sprite.prototype.getLocalPosition=function(a,b,c){return a.x=(this._cache.a11*this._cache.id*b+-this._cache.a01*this._cache.id*c+(this._cache.a12*this._cache.a01-this._cache.a02*this._cache.a11)*this._cache.id)*this.scale.x+this._cache.a02,a.y=(this._cache.a00*this._cache.id*c+-this._cache.a10*this._cache.id*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.a10)*this._cache.id)*this.scale.y+this._cache.a12,a},d.Sprite.prototype.getLocalUnmodifiedPosition=function(a,b,c){return a.x=this._cache.a11*this._cache.idi*b+-this._cache.i01*this._cache.idi*c+(this._cache.a12*this._cache.i01-this._cache.a02*this._cache.a11)*this._cache.idi+this.anchor.x*this._cache.width,a.y=this._cache.a00*this._cache.idi*c+-this._cache.i10*this._cache.idi*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.i10)*this._cache.idi+this.anchor.y*this._cache.height,a},d.Sprite.prototype.resetCrop=function(){this.crop=new d.Rectangle(0,0,this._cache.width,this._cache.height),this.texture.setFrame(this.crop),this.cropEnabled=!1},d.Sprite.prototype.postUpdate=function(){this.key instanceof d.BitmapData&&this.key._dirty&&this.key.render(),this.exists&&(this.body&&this.body.postUpdate(),this.fixedToCamera?(this._cache.x=this.game.camera.view.x+this.cameraOffset.x,this._cache.y=this.game.camera.view.y+this.cameraOffset.y):(this._cache.x=this.x,this._cache.y=this.y),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),this.position.x=this._cache.x,this.position.y=this._cache.y)},d.Sprite.prototype.loadTexture=function(a,b){this.key=a,a instanceof d.RenderTexture?this.currentFrame=this.game.cache.getTextureFrame(a.name):a instanceof d.BitmapData?(this.setTexture(a.texture),this.currentFrame=a.textureFrame):a instanceof c.Texture?this.currentFrame=b:(("undefined"==typeof a||this.game.cache.checkImageKey(a)===!1)&&(a="__default",this.key=a),this.game.cache.isSpriteSheet(a)?(this.animations.loadFrameData(this.game.cache.getFrameData(a)),"undefined"!=typeof b&&("string"==typeof b?this.frameName=b:this.frame=b)):(this.currentFrame=this.game.cache.getFrame(a),this.setTexture(c.TextureCache[a])))},d.Sprite.prototype.centerOn=function(a,b){return this.x=a+(this.x-this.center.x),this.y=b+(this.y-this.center.y),this},d.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},d.Sprite.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},d.Sprite.prototype.destroy=function(){this.group&&this.group.remove(this),this.input&&this.input.destroy(),this.events&&this.events.destroy(),this.animations&&this.animations.destroy(),this.alive=!1,this.exists=!1,this.visible=!1,this.game=null},d.Sprite.prototype.damage=function(a){return this.alive&&(this.health-=a,this.health<0&&this.kill()),this},d.Sprite.prototype.reset=function(a,b,c){return"undefined"==typeof c&&(c=1),this.x=a,this.y=b,this.position.x=this.x,this.position.y=this.y,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this._outOfBoundsFired=!1,this.health=c,this.body&&this.body.reset(),this},d.Sprite.prototype.bringToTop=function(){return this.group?this.group.bringToTop(this):this.game.world.bringToTop(this),this},d.Sprite.prototype.play=function(a,b,c,d){return this.animations?this.animations.play(a,b,c,d):void 0},Object.defineProperty(d.Sprite.prototype,"angle",{get:function(){return d.Math.wrapAngle(d.Math.radToDeg(this.rotation))},set:function(a){this.rotation=d.Math.degToRad(d.Math.wrapAngle(a))}}),Object.defineProperty(d.Sprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(d.Sprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(d.Sprite.prototype,"inCamera",{get:function(){return this._cache.cameraVisible}}),Object.defineProperty(d.Sprite.prototype,"width",{get:function(){return this.scale.x*this.currentFrame.width},set:function(a){this.scale.x=a/this.currentFrame.width,this._cache.scaleX=a/this.currentFrame.width,this._width=a}}),Object.defineProperty(d.Sprite.prototype,"height",{get:function(){return this.scale.y*this.currentFrame.height},set:function(a){this.scale.y=a/this.currentFrame.height,this._cache.scaleY=a/this.currentFrame.height,this._height=a}}),Object.defineProperty(d.Sprite.prototype,"inputEnabled",{get:function(){return this.input.enabled},set:function(a){console.log("inputEnabled",a,this.input),a?this.input.enabled===!1&&this.input.start():this.input.enabled&&this.input.stop()}}),d.TileSprite=function(a,b,e,f,g,h,i){b=b||0,e=e||0,f=f||256,g=g||256,h=h||null,i=i||null,d.Sprite.call(this,a,b,e,h,i),this.texture=c.TextureCache[h],c.TilingSprite.call(this,this.texture,f,g),this.type=d.TILESPRITE,this.tileScale=new d.Point(1,1),this.tilePosition=new d.Point(0,0)},d.TileSprite.prototype=d.Utils.extend(!0,c.TilingSprite.prototype,d.Sprite.prototype),d.TileSprite.prototype.constructor=d.TileSprite,d.Text=function(a,b,e,f,g){b=b||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=d.TEXT,this._text=f,this._style=g,c.Text.call(this,f,g),this.position.x=this.x=b,this.position.y=this.y=e,this.anchor=new d.Point,this.scale=new d.Point(1,1),this._cache={dirty:!1,a00:1,a01:0,a02:b,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y,this.renderable=!0},d.Text.prototype=Object.create(c.Text.prototype),d.Text.prototype.constructor=d.Text,d.Text.prototype.update=function(){this.exists&&(this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0))},d.Text.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(d.Text.prototype,"angle",{get:function(){return d.Math.radToDeg(this.rotation)},set:function(a){this.rotation=d.Math.degToRad(a)}}),Object.defineProperty(d.Text.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(d.Text.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),Object.defineProperty(d.Text.prototype,"content",{get:function(){return this._text},set:function(a){a!==this._text&&(this._text=a,this.setText(a))}}),Object.defineProperty(d.Text.prototype,"font",{get:function(){return this._style},set:function(a){a!==this._style&&(this._style=a,this.setStyle(a))}}),d.BitmapText=function(a,b,e,f,g){b=b||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=d.BITMAPTEXT,c.BitmapText.call(this,f,g),this.position.x=b,this.position.y=e,this.anchor=new d.Point,this.scale=new d.Point(1,1),this._cache={dirty:!1,a00:1,a01:0,a02:b,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y,this.renderable=!0},d.BitmapText.prototype=Object.create(c.BitmapText.prototype),d.BitmapText.prototype.constructor=d.BitmapText,d.BitmapText.prototype.update=function(){this.exists&&(this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0),this.pivot.x=this.anchor.x*this.width,this.pivot.y=this.anchor.y*this.height)},d.BitmapText.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas&&this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(d.BitmapText.prototype,"angle",{get:function(){return d.Math.radToDeg(this.rotation)},set:function(a){this.rotation=d.Math.degToRad(a)}}),Object.defineProperty(d.BitmapText.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(d.BitmapText.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),d.Button=function(a,b,c,e,f,g,h,i,j){b=b||0,c=c||0,e=e||null,f=f||null,g=g||this,d.Sprite.call(this,a,b,c,e,i),this.type=d.BUTTON,this._onOverFrameName=null,this._onOutFrameName=null,this._onDownFrameName=null,this._onUpFrameName=null,this._onOverFrameID=null,this._onOutFrameID=null,this._onDownFrameID=null,this._onUpFrameID=null,this.onOverSound=null,this.onOutSound=null,this.onDownSound=null,this.onUpSound=null,this.onOverSoundMarker="",this.onOutSoundMarker="",this.onDownSoundMarker="",this.onUpSoundMarker="",this.onInputOver=new d.Signal,this.onInputOut=new d.Signal,this.onInputDown=new d.Signal,this.onInputUp=new d.Signal,this.freezeFrames=!1,this.forceOut=!0,this.setFrames(h,i,j),null!==f&&this.onInputUp.add(f,g),this.input.start(0,!0),this.events.onInputOver.add(this.onInputOverHandler,this),this.events.onInputOut.add(this.onInputOutHandler,this),this.events.onInputDown.add(this.onInputDownHandler,this),this.events.onInputUp.add(this.onInputUpHandler,this)},d.Button.prototype=Object.create(d.Sprite.prototype),d.Button.prototype=d.Utils.extend(!0,d.Button.prototype,d.Sprite.prototype,c.Sprite.prototype),d.Button.prototype.constructor=d.Button,d.Button.prototype.setFrames=function(a,b,c){null!==a&&("string"==typeof a?(this._onOverFrameName=a,this.input.pointerOver()&&(this.frameName=a)):(this._onOverFrameID=a,this.input.pointerOver()&&(this.frame=a))),null!==b&&("string"==typeof b?(this._onOutFrameName=b,this._onUpFrameName=b,this.input.pointerOver()===!1&&(this.frameName=b)):(this._onOutFrameID=b,this._onUpFrameID=b,this.input.pointerOver()===!1&&(this.frame=b))),null!==c&&("string"==typeof c?(this._onDownFrameName=c,this.input.pointerDown()&&(this.frameName=c)):(this._onDownFrameID=c,this.input.pointerDown()&&(this.frame=c)))},d.Button.prototype.setSounds=function(a,b,c,d,e,f,g,h){this.setOverSound(a,b),this.setOutSound(e,f),this.setUpSound(g,h),this.setDownSound(c,d)},d.Button.prototype.setOverSound=function(a,b){this.onOverSound=null,this.onOverSoundMarker="",a instanceof d.Sound&&(this.onOverSound=a),"string"==typeof b&&(this.onOverSoundMarker=b)},d.Button.prototype.setOutSound=function(a,b){this.onOutSound=null,this.onOutSoundMarker="",a instanceof d.Sound&&(this.onOutSound=a),"string"==typeof b&&(this.onOutSoundMarker=b)},d.Button.prototype.setUpSound=function(a,b){this.onUpSound=null,this.onUpSoundMarker="",a instanceof d.Sound&&(this.onUpSound=a),"string"==typeof b&&(this.onUpSoundMarker=b)},d.Button.prototype.setDownSound=function(a,b){this.onDownSound=null,this.onDownSoundMarker="",a instanceof d.Sound&&(this.onDownSound=a),"string"==typeof b&&(this.onDownSoundMarker=b)},d.Button.prototype.onInputOverHandler=function(a){this.freezeFrames===!1&&(null!=this._onOverFrameName?this.frameName=this._onOverFrameName:null!=this._onOverFrameID&&(this.frame=this._onOverFrameID)),this.onOverSound&&this.onOverSound.play(this.onOverSoundMarker),this.onInputOver&&this.onInputOver.dispatch(this,a)},d.Button.prototype.onInputOutHandler=function(a){this.freezeFrames===!1&&(null!=this._onOutFrameName?this.frameName=this._onOutFrameName:null!=this._onOutFrameID&&(this.frame=this._onOutFrameID)),this.onOutSound&&this.onOutSound.play(this.onOutSoundMarker),this.onInputOut&&this.onInputOut.dispatch(this,a)},d.Button.prototype.onInputDownHandler=function(a){this.freezeFrames===!1&&(null!=this._onDownFrameName?this.frameName=this._onDownFrameName:null!=this._onDownFrameID&&(this.frame=this._onDownFrameID)),this.onDownSound&&this.onDownSound.play(this.onDownSoundMarker),this.onInputDown&&this.onInputDown.dispatch(this,a)},d.Button.prototype.onInputUpHandler=function(a){this.freezeFrames===!1&&(null!=this._onUpFrameName?this.frameName=this._onUpFrameName:null!=this._onUpFrameID&&(this.frame=this._onUpFrameID)),this.onUpSound&&this.onUpSound.play(this.onUpSoundMarker),this.forceOut&&this.freezeFrames===!1&&(null!=this._onOutFrameName?this.frameName=this._onOutFrameName:null!=this._onOutFrameID&&(this.frame=this._onOutFrameID)),this.onInputUp&&this.onInputUp.dispatch(this,a)},d.Graphics=function(a,b,e){this.game=a,c.Graphics.call(this),this.type=d.GRAPHICS,this.position.x=b,this.position.y=e},d.Graphics.prototype=Object.create(c.Graphics.prototype),d.Graphics.prototype.constructor=d.Graphics,d.Graphics.prototype.destroy=function(){this.clear(),this.group&&this.group.remove(this),this.game=null},d.Graphics.prototype.drawPolygon=function(a){this.moveTo(a.points[0].x,a.points[0].y);for(var b=1;bh;h++)f[h].updateTransform();var j=a.__renderGroup;j?a==j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new c.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},d.RenderTexture.prototype.renderCanvas=function(a,b,d){var e=a.children;a.worldTransform=c.mat3.create(),b&&(a.worldTransform[2]=b.x,a.worldTransform[5]=b.y);for(var f=0,g=e.length;g>f;f++)e[f].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a),this.renderer.context.setTransform(1,0,0,1,0,0)},d.Canvas={create:function(a,b){a=a||256,b=b||256;var c=document.createElement("canvas");return c.width=a,c.height=b,c.style.display="block",c},getOffset:function(a,b){b=b||new d.Point;var c=a.getBoundingClientRect(),e=a.clientTop||document.body.clientTop||0,f=a.clientLeft||document.body.clientLeft||0,g=window.pageYOffset||a.scrollTop||document.body.scrollTop,h=window.pageXOffset||a.scrollLeft||document.body.scrollLeft;return b.x=c.left+h-f,b.y=c.top+g-e,b},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),c&&(d.style.overflow="hidden")),d||(d=document.body),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"]="crisp-edges",a.style["image-rendering"]="-moz-crisp-edges",a.style["image-rendering"]="-webkit-optimize-contrast",a.style.msInterpolationMode="nearest-neighbor",a},setImageRenderingBicubic:function(a){return a.style["image-rendering"]="auto",a.style.msInterpolationMode="bicubic",a}},d.StageScaleMode=function(a,b,c){this.game=a,this.width=b,this.height=c,this.minWidth=null,this.maxWidth=null,this.minHeight=null,this.maxHeight=null,this._startHeight=0,this.forceLandscape=!1,this.forcePortrait=!1,this.incorrectOrientation=!1,this.pageAlignHorizontally=!1,this.pageAlignVertically=!1,this._width=0,this._height=0,this.maxIterations=5,this.orientationSprite=null,this.enterLandscape=new d.Signal,this.enterPortrait=new d.Signal,this.enterIncorrectOrientation=new d.Signal,this.leaveIncorrectOrientation=new d.Signal,this.hasResized=new d.Signal,this.orientation=window.orientation?window.orientation:window.outerWidth>window.outerHeight?90:0,this.scaleFactor=new d.Point(1,1),this.scaleFactorInversed=new d.Point(1,1),this.margin=new d.Point(0,0),this.aspectRatio=0,this.event=null;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)},d.StageScaleMode.EXACT_FIT=0,d.StageScaleMode.NO_SCALE=1,d.StageScaleMode.SHOW_ALL=2,d.StageScaleMode.prototype={startFullScreen:function(a){if(!this.isFullScreen){"undefined"!=typeof a&&d.Canvas.setSmoothingEnabled(this.game.context,a);var b=this.game.canvas;this._width=this.width,this._height=this.height,console.log("startFullScreen",this._width,this._height),b.requestFullScreen?b.requestFullScreen():b.mozRequestFullScreen?b.mozRequestFullScreen():b.webkitRequestFullScreen&&b.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}},stopFullScreen:function(){document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen()},fullScreenChange:function(a){this.event=a,this.isFullScreen?(this.game.stage.canvas.style.width="100%",this.game.stage.canvas.style.height="100%",this.setMaximum(),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.game.stage.canvas.style.width=this.game.width+"px",this.game.stage.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)},forceOrientation:function(a,b,d){"undefined"==typeof b&&(b=!1),this.forceLandscape=a,this.forcePortrait=b,"undefined"!=typeof d&&((null==d||this.game.cache.checkImageKey(d)===!1)&&(d="__default"),this.orientationSprite=new c.Sprite(c.TextureCache[d]),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._stage.addChild(this.orientationSprite))},checkOrientationState:function(){this.incorrectOrientation?(this.forceLandscape&&window.innerWidth>window.innerHeight||this.forcePortrait&&window.innerHeight>window.innerWidth)&&(this.game.paused=!1,this.incorrectOrientation=!1,this.leaveIncorrectOrientation.dispatch(),this.orientationSprite&&(this.orientationSprite.visible=!1,this.game.world.visible=!0),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.game.stage.scaleMode!==d.StageScaleMode.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.game.stage.scaleMode==d.StageScaleMode.EXACT_FIT?this.setExactFit():this.game.stage.scaleMode==d.StageScaleMode.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}},Object.defineProperty(d.StageScaleMode.prototype,"isFullScreen",{get:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement}}),Object.defineProperty(d.StageScaleMode.prototype,"isPortrait",{get:function(){return 0===this.orientation||180==this.orientation}}),Object.defineProperty(d.StageScaleMode.prototype,"isLandscape",{get:function(){return 90===this.orientation||-90===this.orientation}}),d.Device=function(){this.patchAndroidClearRectBug=!1,this.desktop=!1,this.iOS=!1,this.cocoonJS=!1,this.android=!1,this.chromeOS=!1,this.linux=!1,this.macOS=!1,this.windows=!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.arora=!1,this.chrome=!1,this.epiphany=!1,this.firefox=!1,this.ie=!1,this.ieVersion=0,this.mobileSafari=!1,this.midori=!1,this.opera=!1,this.safari=!1,this.webApp=!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._checkAudio(),this._checkBrowser(),this._checkCSS3D(),this._checkDevice(),this._checkFeatures(),this._checkOS()
-},d.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),(this.windows||this.macOS||this.linux)&&(this.desktop=!0)},_checkFeatures:function(){this.canvas=!!window.CanvasRenderingContext2D;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},_checkBrowser:function(){var a=navigator.userAgent;/Arora/.test(a)?this.arora=!0:/Chrome/.test(a)?this.chrome=!0:/Epiphany/.test(a)?this.epiphany=!0:/Firefox/.test(a)?this.firefox=!0:/Mobile Safari/.test(a)?this.mobileSafari=!0:/MSIE (\d+\.\d+);/.test(a)?(this.ie=!0,this.ieVersion=parseInt(RegExp.$1,10)):/Midori/.test(a)?this.midori=!0:/Opera/.test(a)?this.opera=!0:/Safari/.test(a)&&(this.safari=!0),navigator.standalone&&(this.webApp=!0),navigator.isCocoonJS&&(this.cocoonJS=!0)},_checkAudio:function(){this.audioData=!!window.Audio,this.webAudio=!(!window.webkitAudioContext&&!window.AudioContext);var a=document.createElement("audio"),b=!1;try{(b=!!a.canPlayType)&&(a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,"")&&(this.ogg=!0),a.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,"")&&(this.opus=!0),a.canPlayType("audio/mpeg;").replace(/^no$/,"")&&(this.mp3=!0),a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,"")&&(this.wav=!0),(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;").replace(/^no$/,""))&&(this.m4a=!0),a.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")&&(this.webm=!0))}catch(c){}},_checkDevice:function(){this.pixelRatio=window.devicePixelRatio||1,this.iPhone=-1!=navigator.userAgent.toLowerCase().indexOf("iphone"),this.iPhone4=2==this.pixelRatio&&this.iPhone,this.iPad=-1!=navigator.userAgent.toLowerCase().indexOf("ipad"),"undefined"!=typeof Int8Array?(this.littleEndian=new Int8Array(new Int16Array([1]).buffer)[0]>0,this.typedArray=!0):(this.littleEndian=!1,this.typedArray=!1)},_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}},d.RequestAnimationFrame=function(a){this.game=a,this.isRunning=!1;for(var b=["ms","moz","webkit","o"],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*(0|2097152*this.rnd.apply(this))},real:function(){return this.integer()+this.frac()},integerInRange:function(a,b){return Math.floor(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|4&3*a?(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)}},d.Math={PI2:2*Math.PI,fuzzyEqual:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),Math.abs(a-b)a},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(d-b,c-a)},normalizeAngle:function(a,b){"undefined"==typeof b&&(b=!0);var c=b?Math.PI:180;return this.wrap(a,-c,c)},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]a;a++)arguments[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)},distanceRounded:function(a,b,c,e){return Math.round(d.Math.distance(a,b,c,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},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}}()},d.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=[]},d.QuadTree.prototype={split:function(){this.level++,this.nodes[0]=new d.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 d.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 d.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 d.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 this.nodes[b].insert(a),void 0;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])}},d.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},d.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,b){return"undefined"==typeof b&&(b=!1),b?d.Math.distanceRound(this.x,this.y,a.x,a.y):d.Math.distance(this.x,this.y,a.x,a.y)},clone:function(a){return"undefined"==typeof a&&(a=new d.Circle),a.setTo(this.x,this.y,this.diameter)},contains:function(a,b){return d.Circle.contains(this,a,b)},circumferencePoint:function(a,b,c){return d.Circle.circumferencePoint(this,a,b,c)},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+")}]"}},Object.defineProperty(d.Circle.prototype,"diameter",{get:function(){return this._diameter},set:function(a){a>0&&(this._diameter=a,this._radius=.5*a)}}),Object.defineProperty(d.Circle.prototype,"radius",{get:function(){return this._radius},set:function(a){a>0&&(this._radius=a,this._diameter=2*a)}}),Object.defineProperty(d.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(d.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(d.Circle.prototype,"bottom",{get:function(){return this.y+this._radius},set:function(a){a0?Math.PI*this._radius*this._radius:0}}),Object.defineProperty(d.Circle.prototype,"empty",{get:function(){return 0===this._diameter},set:function(a){a===!0&&this.setTo(0,0,0)}}),d.Circle.contains=function(a,b,c){if(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},d.Circle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.diameter==b.diameter},d.Circle.intersects=function(a,b){return d.Math.distance(a.x,a.y,b.x,b.y)<=a.radius+b.radius},d.Circle.circumferencePoint=function(a,b,c,e){return"undefined"==typeof c&&(c=!1),"undefined"==typeof e&&(e=new d.Point),c===!0&&(b=d.Math.radToDeg(b)),e.x=a.x+a.radius*Math.cos(b),e.y=a.y+a.radius*Math.sin(b),e},d.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},d.Point=function(a,b){a=a||0,b=b||0,this.x=a,this.y=b},d.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,this.y=b,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,b){return this.x=d.Math.clamp(this.x,a,b),this},clampY:function(a,b){return this.y=d.Math.clamp(this.y,a,b),this},clamp:function(a,b){return this.x=d.Math.clamp(this.x,a,b),this.y=d.Math.clamp(this.y,a,b),this},clone:function(a){return"undefined"==typeof a&&(a=new d.Point),a.setTo(this.x,this.y)},copyTo:function(a){return a.x=this.x,a.y=this.y,a},distance:function(a,b){return d.Point.distance(this,a,b)},equals:function(a){return a.x==this.x&&a.y==this.y},rotate:function(a,b,c,e,f){return d.Point.rotate(this,a,b,c,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+")}]"}},d.Point.add=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x+b.x,c.y=a.y+b.y,c},d.Point.subtract=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x-b.x,c.y=a.y-b.y,c},d.Point.multiply=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x*b.x,c.y=a.y*b.y,c},d.Point.divide=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x/b.x,c.y=a.y/b.y,c},d.Point.equals=function(a,b){return a.x==b.x&&a.y==b.y},d.Point.distance=function(a,b,c){return"undefined"==typeof c&&(c=!1),c?d.Math.distanceRound(a.x,a.y,b.x,b.y):d.Math.distance(a.x,a.y,b.x,b.y)},d.Point.rotate=function(a,b,c,e,f,g){return f=f||!1,g=g||null,f&&(e=d.Math.degToRad(e)),null===g&&(g=Math.sqrt((b-a.x)*(b-a.x)+(c-a.y)*(c-a.y))),a.setTo(b+g*Math.cos(e),c+g*Math.sin(e))},d.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},d.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,b){return d.Rectangle.inflate(this,a,b)},size:function(a){return d.Rectangle.size(this,a)},clone:function(a){return d.Rectangle.clone(this,a)},contains:function(a,b){return d.Rectangle.contains(this,a,b)},containsRect:function(a){return d.Rectangle.containsRect(this,a)},equals:function(a){return d.Rectangle.equals(this,a)},intersection:function(a,b){return d.Rectangle.intersection(this,a,b)},intersects:function(a,b){return d.Rectangle.intersects(this,a,b)},intersectsRaw:function(a,b,c,e,f){return d.Rectangle.intersectsRaw(this,a,b,c,e,f)},union:function(a,b){return d.Rectangle.union(this,a,b)},toString:function(){return"[{Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+" empty="+this.empty+")}]"}},Object.defineProperty(d.Rectangle.prototype,"halfWidth",{get:function(){return Math.round(this.width/2)}}),Object.defineProperty(d.Rectangle.prototype,"halfHeight",{get:function(){return Math.round(this.height/2)}}),Object.defineProperty(d.Rectangle.prototype,"bottom",{get:function(){return this.y+this.height},set:function(a){this.height=a<=this.y?0:this.y-a}}),Object.defineProperty(d.Rectangle.prototype,"bottomRight",{get:function(){return new d.Point(this.right,this.bottom)},set:function(a){this.right=a.x,this.bottom=a.y}}),Object.defineProperty(d.Rectangle.prototype,"left",{get:function(){return this.x},set:function(a){this.width=a>=this.right?0:this.right-a,this.x=a}}),Object.defineProperty(d.Rectangle.prototype,"right",{get:function(){return this.x+this.width},set:function(a){this.width=a<=this.x?0:this.x+a}}),Object.defineProperty(d.Rectangle.prototype,"volume",{get:function(){return this.width*this.height}}),Object.defineProperty(d.Rectangle.prototype,"perimeter",{get:function(){return 2*this.width+2*this.height}}),Object.defineProperty(d.Rectangle.prototype,"centerX",{get:function(){return this.x+this.halfWidth},set:function(a){this.x=a-this.halfWidth}}),Object.defineProperty(d.Rectangle.prototype,"centerY",{get:function(){return this.y+this.halfHeight},set:function(a){this.y=a-this.halfHeight}}),Object.defineProperty(d.Rectangle.prototype,"top",{get:function(){return this.y},set:function(a){a>=this.bottom?(this.height=0,this.y=a):this.height=this.bottom-a}}),Object.defineProperty(d.Rectangle.prototype,"topLeft",{get:function(){return new d.Point(this.x,this.y)},set:function(a){this.x=a.x,this.y=a.y}}),Object.defineProperty(d.Rectangle.prototype,"empty",{get:function(){return!this.width||!this.height},set:function(a){a===!0&&this.setTo(0,0,0,0)}}),d.Rectangle.inflate=function(a,b,c){return a.x-=b,a.width+=2*b,a.y-=c,a.height+=2*c,a},d.Rectangle.inflatePoint=function(a,b){return d.Rectangle.inflate(a,b.x,b.y)},d.Rectangle.size=function(a,b){return"undefined"==typeof b&&(b=new d.Point),b.setTo(a.width,a.height)},d.Rectangle.clone=function(a,b){return"undefined"==typeof b&&(b=new d.Rectangle),b.setTo(a.x,a.y,a.width,a.height)},d.Rectangle.contains=function(a,b,c){return b>=a.x&&b<=a.right&&c>=a.y&&c<=a.bottom},d.Rectangle.containsRaw=function(a,b,c,d,e,f){return e>=a&&a+c>=e&&f>=b&&b+d>=f},d.Rectangle.containsPoint=function(a,b){return d.Rectangle.contains(a,b.x,b.y)},d.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},d.Rectangle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.width==b.width&&a.height==b.height},d.Rectangle.intersection=function(a,b,c){return c=c||new d.Rectangle,d.Rectangle.intersects(a,b)&&(c.x=Math.max(a.x,b.x),c.y=Math.max(a.y,b.y),c.width=Math.min(a.right,b.right)-c.x,c.height=Math.min(a.bottom,b.bottom)-c.y),c},d.Rectangle.intersects=function(a,b){return a.xa.right+f||ca.bottom+f||e1){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," "))}},d.TweenManager=function(a){this.game=a,this._tweens=[],this._add=[],this.game.onPause.add(this.pauseAll,this),this.game.onResume.add(this.resumeAll,this)},d.TweenManager.prototype={REVISION:"11dev",getAll:function(){return this._tweens},removeAll:function(){this._tweens=[]},add:function(a){this._add.push(a)},create:function(a){return new d.Tween(a,this.game)},remove:function(a){var b=this._tweens.indexOf(a);-1!==b&&(this._tweens[b].pendingDelete=!0)},update:function(){if(0===this._tweens.length&&0===this._add.length)return!1;for(var a=0,b=this._tweens.length;b>a;)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()}},d.Tween=function(a,b){this._object=a,this.game=b,this._manager=this.game.tweens,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=d.Easing.Linear.None,this._interpolationFunction=d.Math.linearInterpolation,this._chainedTweens=[],this._onStartCallback=null,this._onStartCallbackFired=!1,this._onUpdateCallback=null,this._onCompleteCallback=null,this._pausedTime=0,this.pendingDelete=!1;for(var c in a)this._valuesStart[c]=parseFloat(a[c],10);this.onStart=new d.Signal,this.onComplete=new d.Signal,this.isRunning=!1},d.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.onStart.dispatch(this._object),this.isRunning=!0,this._onStartCallbackFired=!1,this._startTime=this.game.time.now+this._delayTime;for(var a in this._valuesEnd){if(this._valuesEnd[a]instanceof Array){if(0===this._valuesEnd[a].length)continue;this._valuesEnd[a]=[this._object[a]].concat(this._valuesEnd[a])}this._valuesStart[a]=this._object[a],this._valuesStart[a]instanceof Array==!1&&(this._valuesStart[a]*=1),this._valuesStartRepeat[a]=this._valuesStart[a]||0}return this}},stop:function(){return this.isRunning=!1,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},onStartCallback:function(a){return this._onStartCallback=a,this},onUpdateCallback:function(a){return this._onUpdateCallback=a,this},onCompleteCallback:function(a){return this._onCompleteCallback=a,this},pause:function(){this._paused=!0,this._pausedTime=this.game.time.now},resume:function(){this._paused=!1,this._startTime+=this.game.time.now-this._pausedTime},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._object,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.onComplete.dispatch(this._object),null!==this._onCompleteCallback&&this._onCompleteCallback.call(this._object),!0}this.isRunning=!1,this.onComplete.dispatch(this._object),null!==this._onCompleteCallback&&this._onCompleteCallback.call(this._object);for(var h=0,i=this._chainedTweens.length;i>h;h++)this._chainedTweens[h].start(a);return!1}return!0}},d.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((a-b)*2*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((a-b)*2*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((a-b)*2*Math.PI/d):.5*c*Math.pow(2,-10*(a-=1))*Math.sin((a-b)*2*Math.PI/d)+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-d.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*d.Easing.Bounce.In(2*a):.5*d.Easing.Bounce.Out(2*a-1)+.5}}},d.Time=function(a){this.game=a,this._started=0,this._timeLastSecond=0,this._pauseStarted=0,this.physicsElapsed=0,this.time=0,this.pausedTime=0,this.now=0,this.elapsed=0,this.fps=0,this.fpsMin=1e3,this.fpsMax=0,this.msMin=1e3,this.msMax=0,this.frames=0,this.pauseDuration=0,this.timeToCall=0,this.lastTime=0,this.game.onPause.add(this.gamePaused,this),this.game.onResume.add(this.gameResumed,this),this._justResumed=!1},d.Time.prototype={update:function(a){this.now=a,this._justResumed&&(this.time=this.now,this._justResumed=!1),this.timeToCall=this.game.math.max(0,16-(a-this.lastTime)),this.elapsed=this.now-this.time,this.msMin=this.game.math.min(this.msMin,this.elapsed),this.msMax=this.game.math.max(this.msMax,this.elapsed),this.frames++,this.now>this._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.physicsElapsed=1*(this.elapsed/1e3),this.physicsElapsed>1&&(this.physicsElapsed=1),this.game.paused&&(this.pausedTime=this.now-this._pauseStarted)},gamePaused:function(){this._pauseStarted=this.now},gameResumed:function(){this.time=Date.now(),this.pauseDuration=this.pausedTime,this._justResumed=!0},totalElapsedSeconds:function(){return.001*(this.now-this._started)},elapsedSince:function(a){return this.now-a},elapsedSecondsSince:function(a){return.001*(this.now-a)},reset:function(){this._started=this.now}},d.Timer=function(a){this.game=a,this._started=0,this._timeLastSecond=0,this.running=!1,this.events=[],this.onEvent=new d.Signal},d.Timer.prototype={add:function(a){this.events.push({delay:a,dispatched:!1,args:Array.prototype.splice.call(arguments,1)})},start:function(){this._started=this.game.time.now,this.running=!0},stop:function(){this.running=!1,this.events.length=0},update:function(){if(this.running)for(var a=this.seconds(),b=0,c=this.events.length;c>b;b++)this.events[b].dispatched===!1&&a>=this.events[b].delay&&(this.events[b].dispatched=!0,this.onEvent.dispatch.apply(this,this.events[b].args))},seconds:function(){return.001*(this.game.time.now-this._started)}},d.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=[]},d.AnimationManager.prototype={loadFrameData:function(a){this._frameData=a,this.frame=0,this.isLoaded=!0},add:function(a,b,e,f,g){return null==this._frameData?(console.warn("No FrameData available for Phaser.Animation "+a),void 0):(e=e||60,"undefined"==typeof f&&(f=!1),"undefined"==typeof g&&(g=b&&"number"==typeof b[0]?!0:!1),null==this.sprite.events.onAnimationStart&&(this.sprite.events.onAnimationStart=new d.Signal,this.sprite.events.onAnimationComplete=new d.Signal,this.sprite.events.onAnimationLoop=new d.Signal),this._outputFrames.length=0,this._frameData.getFrameIndexes(b,g,this._outputFrames),this._anims[a]=new d.Animation(this.game,this.sprite,a,this._frameData,this._outputFrames,e,f),this.currentAnim=this._anims[a],this.currentFrame=this.currentAnim.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid]),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?!1:this.currentAnim&&this.currentAnim.update()===!0?(this.currentFrame=this.currentAnim.currentFrame,this.sprite.currentFrame=this.currentFrame,!0):!1},getAnimation:function(a){return"string"==typeof a&&this._anims[a]?this._anims[a]:!1},refreshFrame:function(){this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid])},destroy:function(){this._anims={},this._frameData=null,this._frameIndex=0,this.currentAnim=null,this.currentFrame=null}},Object.defineProperty(d.AnimationManager.prototype,"frameData",{get:function(){return this._frameData}}),Object.defineProperty(d.AnimationManager.prototype,"frameTotal",{get:function(){return this._frameData?this._frameData.total:-1}}),Object.defineProperty(d.AnimationManager.prototype,"paused",{get:function(){return this.currentAnim.isPaused},set:function(a){this.currentAnim.paused=a}}),Object.defineProperty(d.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.currentFrame=this.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid]))}}),Object.defineProperty(d.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.currentFrame=this.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid])):console.warn("Cannot set frameName: "+a)}}),d.Animation=function(a,b,c,d,e,f,g){this.game=a,this._parent=b,this._frameData=d,this.name=c,this._frames=[],this._frames=this._frames.concat(e),this.delay=1e3/f,this.looped=g,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])},d.Animation.prototype={play:function(a,b,d){return"number"==typeof a&&(this.delay=1e3/a),"boolean"==typeof b&&(this.looped=b),"undefined"!=typeof d&&(this.killOnComplete=d),this.isPlaying=!0,this.isFinished=!1,this.paused=!1,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(c.TextureCache[this.currentFrame.uuid]),this._parent.events&&this._parent.events.onAnimationStart.dispatch(this._parent,this),this},restart:function(){this.isPlaying=!0,this.isFinished=!1,this.paused=!1,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])},stop:function(a){"undefined"==typeof a&&(a=!1),this.isPlaying=!1,this.isFinished=!0,this.paused=!1,a&&(this.currentFrame=this._frameData.getFrame(this._frames[0]))},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.looped?(this._frameIndex%=this._frames.length,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&this._parent.setTexture(c.TextureCache[this.currentFrame.uuid]),this._parent.events.onAnimationLoop.dispatch(this._parent,this)):this.onComplete():(this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&this._parent.setTexture(c.TextureCache[this.currentFrame.uuid])),!0):!1},destroy:function(){this.game=null,this._parent=null,this._frames=null,this._frameData=null,this.currentFrame=null,this.isPlaying=!1},onComplete:function(){this.isPlaying=!1,this.isFinished=!0,this.paused=!1,this._parent.events&&this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.killOnComplete&&this._parent.kill()}},Object.defineProperty(d.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(d.Animation.prototype,"frameTotal",{get:function(){return this._frames.length}}),Object.defineProperty(d.Animation.prototype,"frame",{get:function(){return null!==this.currentFrame?this.currentFrame.index:this._frameIndex},set:function(a){this.currentFrame=this._frameData.getFrame(a),null!==this.currentFrame&&(this._frameIndex=a,this._parent.setTexture(c.TextureCache[this.currentFrame.uuid]))}}),d.Animation.generateFrameNames=function(a,b,c,e,f){"undefined"==typeof e&&(e="");var g=[],h="";if(c>b)for(var i=b;c>=i;i++)h="number"==typeof f?d.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);else for(var i=b;i>=c;i--)h="number"==typeof f?d.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);return g},d.Frame=function(a,b,c,e,f,g,h){this.index=a,this.x=b,this.y=c,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=d.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},d.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)}},d.FrameData=function(){this._frames=[],this._frameNames=[]},d.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 this._frames.length>a?this._frames[a]:null},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++)b?c.push(this.getFrame(a[d])):c.push(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}},Object.defineProperty(d.FrameData.prototype,"total",{get:function(){return this._frames.length}}),d.AnimationParser={spriteSheet:function(a,b,e,f,g){var h=a.cache.getImage(b);if(null==h)return null;var i=h.width,j=h.height;0>=e&&(e=Math.floor(-i/Math.min(-1,e))),0>=f&&(f=Math.floor(-j/Math.min(-1,f)));var k=Math.round(i/e),l=Math.round(j/f),m=k*l;if(-1!==g&&(m=g),0===i||0===j||e>i||f>j||0===m)return console.warn("Phaser.AnimationParser.spriteSheet: width/height zero or width/height < given frameWidth/frameHeight"),null;for(var n=new d.FrameData,o=0,p=0,q=0;m>q;q++){var r=a.rnd.uuid();n.addFrame(new d.Frame(q,o,p,e,f,"",r)),c.TextureCache[r]=new c.Texture(c.BaseTextureCache[b],{x:o,y:p,width:e,height:f}),o+=e,o===i&&(o=0,p+=f)}return n},JSONData:function(a,b,e){if(!b.frames)return console.warn("Phaser.AnimationParser.JSONData: Invalid Texture Atlas JSON given, missing 'frames' array"),console.log(b),void 0;for(var f,g=new d.FrameData,h=b.frames,i=0;i tag"),void 0;for(var f,g,h,i,j,k,l,m,n,o,p,q,r=new d.FrameData,s=b.getElementsByTagName("SubTexture"),t=0;t0)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.hasLoaded=!0,this.onLoadComplete.dispatch()))},loadFile:function(){if(!this._fileList[this._fileIndex])return console.warn("Phaser.Loader loadFile invalid index "+this._fileIndex),void 0;var a=this._fileList[this._fileIndex],b=this;switch(a.type){case"image":case"spritesheet":case"textureatlas":case"bitmapfont":case"tileset":a.data=new Image,a.data.name=a.key,a.data.onload=function(){return b.fileComplete(b._fileIndex)},a.data.onerror=function(){return b.fileError(b._fileIndex)},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 b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._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 b.fileError(b._fileIndex)},a.data.preload="auto",a.data.src=this.baseURL+a.url,a.data.addEventListener("canplaythrough",d.GAMES[this.game.id].load.fileComplete(this._fileIndex),!1),a.data.load())):this.fileError(this._fileIndex);break;case"tilemap":if(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",a.format===d.Tilemap.TILED_JSON)this._xhr.onload=function(){return b.jsonLoadComplete(b._fileIndex)};else{if(a.format!==d.Tilemap.CSV)throw new Error("Phaser.Loader. Invalid Tilemap format: "+a.format);this._xhr.onload=function(){return b.csvLoadComplete(b._fileIndex)}}this._xhr.onerror=function(){return b.dataLoadError(b._fileIndex)},this._xhr.send();break;case"text":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send();break;case"script":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._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.preloadSprite.sprite.crop=this.preloadSprite.crop),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 tag"),void 0;var e=c.TextureCache[d],f={},g=b.getElementsByTagName("info")[0],h=b.getElementsByTagName("common")[0];f.font=g.attributes.getNamedItem("face").nodeValue,f.size=parseInt(g.attributes.getNamedItem("size").nodeValue,10),f.lineHeight=parseInt(h.attributes.getNamedItem("lineHeight").nodeValue,10),f.chars={};for(var i=b.getElementsByTagName("char"),j=0;j=this.durationMS&&(this.usingWebAudio?this.loop?(this.onLoop.dispatch(this),""===this.currentMarker?(this.currentTime=0,this.startTime=this.game.time.now):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=!1),"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 console.warn("Phaser.Sound.play: audio marker "+a+" doesn't exist"),void 0;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.externalNode?this._sound.connect(this.externalNode.input):this._sound.connect(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&&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.gainNode),"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.onStop.dispatch(this,a)}},Object.defineProperty(d.Sound.prototype,"isDecoding",{get:function(){return this.game.cache.getSound(this.key).isDecoding}}),Object.defineProperty(d.Sound.prototype,"isDecoded",{get:function(){return this.game.cache.isSoundDecoded(this.key)}}),Object.defineProperty(d.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(d.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)}}),d.SoundManager=function(a){this.game=a,this.onSoundDecode=new d.Signal,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},d.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,this.noAudio=!0,void 0;if(window.PhaserGlobal.disableWebAudio===!0)return this.usingWebAudio=!1,this.usingAudioTag=!0,this.noAudio=!1,void 0}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 d.Color.getColor(255,255,255);if(a>b)return d.Color.getColor(255,255,255);var e=a+Math.round(Math.random()*(b-a)),f=a+Math.round(Math.random()*(b-a)),g=a+Math.round(Math.random()*(b-a));return d.Color.getColor32(c,e,f,g)},getRGB:function(a){return{alpha:a>>>24,red:255&a>>16,green:255&a>>8,blue:255&a}},getWebRGB:function(a){var b=(a>>>24)/255,c=255&a>>16,d=255&a>>8,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 255&a>>16},getGreen:function(a){return 255&a>>8},getBlue:function(a){return 255&a}},d.Physics={},d.Physics.Arcade=function(a){this.game=a,this.gravity=new d.Point,this.bounds=new d.Rectangle(0,0,a.world.width,a.world.height),this.maxObjects=10,this.maxLevels=4,this.OVERLAP_BIAS=4,this.quadTree=new d.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 d.Rectangle,this._bounds2=new d.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},d.Physics.Arcade.prototype={updateMotion:function(a){this._velocityDelta=60*.5*(this.computeVelocity(0,a,a.angularVelocity,a.angularAcceleration,a.angularDrag,a.maxAngular)-a.angularVelocity)*this.game.time.physicsElapsed,a.angularVelocity+=this._velocityDelta,a.rotation+=a.angularVelocity*this.game.time.physicsElapsed,a.angularVelocity+=this._velocityDelta,this._velocityDelta=60*.5*(this.computeVelocity(1,a,a.velocity.x,a.acceleration.x,a.drag.x,a.maxVelocity.x)-a.velocity.x)*this.game.time.physicsElapsed,a.velocity.x+=this._velocityDelta,a.x+=a.velocity.x*this.game.time.physicsElapsed,a.velocity.x+=this._velocityDelta,this._velocityDelta=60*.5*(this.computeVelocity(2,a,a.velocity.y,a.acceleration.y,a.drag.y,a.maxVelocity.y)-a.velocity.y)*this.game.time.physicsElapsed,a.velocity.y+=this._velocityDelta,a.y+=a.velocity.y*this.game.time.physicsElapsed,a.velocity.y+=this._velocityDelta},computeVelocity:function(a,b,c,d,e,f){return f=f||1e4,1==a&&b.allowGravity?c+=this.gravity.x+b.gravity.x:2==a&&b.allowGravity&&(c+=this.gravity.y+b.gravity.y),0!==d?c+=d*this.game.time.physicsElapsed:0!==e&&(this._drag=e*this.game.time.physicsElapsed,c-this._drag>0?c-=this._drag:c+this._drag<0?c+=this._drag:c=0),c>f?c=f:-f>c&&(c=-f),c},preUpdate:function(){this.quadTree.clear(),this.quadTreeID=0,this.quadTree=new d.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)},postUpdate:function(){this.quadTree.clear()},overlap:function(a,b,c,e,f){return c=c||null,e=e||null,f=f||c,this._result=!1,this._total=0,a&&b&&a.exists&&b.exists&&(a.type==d.SPRITE?b.type==d.SPRITE?this.overlapSpriteVsSprite(a,b,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.overlapSpriteVsGroup(a,b,c,e,f):a.type==d.GROUP?b.type==d.SPRITE?this.overlapSpriteVsGroup(b,a,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.overlapGroupVsGroup(a,b,c,e,f):a.type==d.EMITTER&&(b.type==d.SPRITE?this.overlapSpriteVsGroup(b,a,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.overlapGroupVsGroup(a,b,c,e,f))),this._total>0},overlapSpriteVsSprite:function(a,b,c,e,f){this._result=d.Rectangle.intersects(a.body,b.body),this._result&&(e?e.call(f,a,b)&&(this._total++,c&&c.call(f,a,b)):(this._total++,c&&c.call(f,a,b)))},overlapSpriteVsGroup:function(a,b,c,e,f){if(0!==b.length){this._potentials=this.quadTree.retrieve(a);for(var g=0,h=this._potentials.length;h>g;g++)this._potentials[g].sprite.group==b&&(this._result=d.Rectangle.intersects(a.body,this._potentials[g]),this._result&&e&&(this._result=e.call(f,a,this._potentials[g].sprite)),this._result&&(this._total++,c&&c.call(f,a,this._potentials[g].sprite)))}},overlapGroupVsGroup:function(a,b,c,d,e){if(0!==a.length&&0!==b.length&&a._container.first._iNext){var f=a._container.first._iNext;do f.exists&&this.overlapSpriteVsGroup(f,b,c,d,e),f=f._iNext;while(f!=a._container.last._iNext)}},collide:function(a,b,c,e,f){return c=c||null,e=e||null,f=f||c,this._result=!1,this._total=0,a&&b&&a.exists&&b.exists&&(a.type==d.SPRITE?b.type==d.SPRITE?this.collideSpriteVsSprite(a,b,c,e,f):b.type==d.GROUP||b.type==d.EMITTER?this.collideSpriteVsGroup(a,b,c,e,f):b.type==d.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,b,c,e,f):a.type==d.GROUP?b.type==d.SPRITE?this.collideSpriteVsGroup(b,a,c,e,f):b.type==d.GROUP||b.type==d.EMITTER?this.collideGroupVsGroup(a,b,c,e,f):b.type==d.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,e,f):a.type==d.TILEMAPLAYER?b.type==d.SPRITE?this.collideSpriteVsTilemapLayer(b,a,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.collideGroupVsTilemapLayer(b,a,c,e,f):a.type==d.EMITTER&&(b.type==d.SPRITE?this.collideSpriteVsGroup(b,a,c,e,f):b.type==d.GROUP||b.type==d.EMITTER?this.collideGroupVsGroup(a,b,c,e,f):b.type==d.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,e,f))),this._total>0},collideSpriteVsTilemapLayer:function(a,b,c,d,e){if(this._mapData=b.getTiles(a.body.x,a.body.y,a.body.width,a.body.height,!0),0!==this._mapData.length)for(var f=0;ff;f++)this._potentials[f].sprite.group==b&&(this.separate(a.body,this._potentials[f]),this._result&&d&&(this._result=d.call(e,a,this._potentials[f].sprite)),this._result&&(this._total++,c&&c.call(e,a,this._potentials[f].sprite)))}},collideGroupVsGroup:function(a,b,c,d,e){if(0!==a.length&&0!==b.length&&a._container.first._iNext){var f=a._container.first._iNext;do f.exists&&this.collideSpriteVsGroup(f,b,c,d,e),f=f._iNext;while(f!=a._container.last._iNext)}},separate:function(a,b){this._result=this.separateX(a,b)||this.separateY(a,b)},separateX:function(a,b){return a.immovable&&b.immovable?!1:(this._overlap=0,d.Rectangle.intersects(a,b)&&(this._maxOverlap=a.deltaAbsX()+b.deltaAbsX()+this.OVERLAP_BIAS,0===a.deltaX()&&0===b.deltaX()?(a.embedded=!0,b.embedded=!0):a.deltaX()>b.deltaX()?(this._overlap=a.x+a.width-b.x,this._overlap>this._maxOverlap||a.allowCollision.right===!1||b.allowCollision.left===!1?this._overlap=0:(a.touching.right=!0,b.touching.left=!0)):a.deltaX()this._maxOverlap||a.allowCollision.left===!1||b.allowCollision.right===!1?this._overlap=0:(a.touching.left=!0,b.touching.right=!0)),0!==this._overlap)?(a.overlapX=this._overlap,b.overlapX=this._overlap,a.customSeparateX||b.customSeparateX?!0:(this._velocity1=a.velocity.x,this._velocity2=b.velocity.x,a.immovable||b.immovable?a.immovable?b.immovable||(b.x+=this._overlap,b.velocity.x=this._velocity1-this._velocity2*b.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,b.x+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.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,b.velocity.x=this._average+this._newVelocity2*b.bounce.x),a.updateHulls(),b.updateHulls(),!0)):!1)},separateY:function(a,b){return a.immovable&&b.immovable?!1:(this._overlap=0,d.Rectangle.intersects(a,b)&&(this._maxOverlap=a.deltaAbsY()+b.deltaAbsY()+this.OVERLAP_BIAS,0===a.deltaY()&&0===b.deltaY()?(a.embedded=!0,b.embedded=!0):a.deltaY()>b.deltaY()?(this._overlap=a.y+a.height-b.y,this._overlap>this._maxOverlap||a.allowCollision.down===!1||b.allowCollision.up===!1?this._overlap=0:(a.touching.down=!0,b.touching.up=!0)):a.deltaY()this._maxOverlap||a.allowCollision.up===!1||b.allowCollision.down===!1?this._overlap=0:(a.touching.up=!0,b.touching.down=!0)),0!==this._overlap)?(a.overlapY=this._overlap,b.overlapY=this._overlap,a.customSeparateY||b.customSeparateY?!0:(this._velocity1=a.velocity.y,this._velocity2=b.velocity.y,a.immovable||b.immovable?a.immovable?b.immovable||(b.y+=this._overlap,b.velocity.y=this._velocity1-this._velocity2*b.bounce.y,a.sprite.active&&a.moves&&a.deltaY()b.deltaY()&&(a.x+=b.x-b.lastX)):(this._overlap*=.5,a.y=a.y-this._overlap,b.y+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.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,b.velocity.y=this._average+this._newVelocity2*b.bounce.y),a.updateHulls(),b.updateHulls(),!0)):!1)},separateTile:function(a,b){return this._result=this.separateTileX(a,b,!0)||this.separateTileY(a,b,!0),this._result},separateTileX:function(a,b,c){return a.immovable||0===a.deltaX()||d.Rectangle.intersects(a.hullX,b)===!1?!1:(this._overlap=0,a.deltaX()<0?(this._overlap=b.right-a.hullX.x,a.allowCollision.left===!1||b.tile.collideRight===!1?this._overlap=0:a.touching.left=!0):(this._overlap=a.hullX.right-b.x,a.allowCollision.right===!1||b.tile.collideLeft===!1?this._overlap=0:a.touching.right=!0),0!==this._overlap?(c&&(a.x=a.deltaX()<0?a.x+this._overlap:a.x-this._overlap,a.velocity.x=0===a.bounce.x?0:-a.velocity.x*a.bounce.x,a.updateHulls()),!0):!1)},separateTileY:function(a,b,c){return a.immovable||0===a.deltaY()||d.Rectangle.intersects(a.hullY,b)===!1?!1:(this._overlap=0,a.deltaY()<0?(this._overlap=b.bottom-a.hullY.y,a.allowCollision.up===!1||b.tile.collideDown===!1?this._overlap=0:a.touching.up=!0):(this._overlap=a.hullY.bottom-b.y,a.allowCollision.down===!1||b.tile.collideUp===!1?this._overlap=0:a.touching.down=!0),0!==this._overlap?(c&&(a.y=a.deltaY()<0?a.y+this._overlap:a.y-this._overlap,a.velocity.y=0===a.bounce.y?0:-a.velocity.y*a.bounce.y,a.updateHulls()),!0):!1)},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,b,c){return"undefined"==typeof b&&(b=60),c=c||new d.Point,c.setTo(Math.cos(this.game.math.degToRad(a))*b,Math.sin(this.game.math.degToRad(a))*b)},velocityFromRotation:function(a,b,c){return"undefined"==typeof b&&(b=60),c=c||new d.Point,c.setTo(Math.cos(a)*b,Math.sin(a)*b)},accelerationFromRotation:function(a,b,c){return"undefined"==typeof b&&(b=60),c=c||new d.Point,c.setTo(Math.cos(a)*b,Math.sin(a)*b)},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)}},d.Physics.Arcade.Body=function(a){this.sprite=a,this.game=a.game,this.offset=new d.Point,this.x=a.x,this.y=a.y,this.preX=a.x,this.preY=a.y,this.preRotation=a.angle,this.screenX=a.x,this.screenY=a.y,this.sourceWidth=a.currentFrame.sourceSizeW,this.sourceHeight=a.currentFrame.sourceSizeH,this.width=a.currentFrame.sourceSizeW,this.height=a.currentFrame.sourceSizeH,this.halfWidth=Math.floor(a.currentFrame.sourceSizeW/2),this.halfHeight=Math.floor(a.currentFrame.sourceSizeH/2),this.center=new d.Point(this.x+this.halfWidth,this.y+this.halfHeight),this._sx=a.scale.x,this._sy=a.scale.y,this.velocity=new d.Point,this.acceleration=new d.Point,this.drag=new d.Point,this.gravity=new d.Point,this.bounce=new d.Point,this.maxVelocity=new d.Point(1e4,1e4),this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.skipQuadTree=!1,this.quadTreeIDs=[],this.quadTreeIndex=-1,this.allowCollision={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.facing=d.NONE,this.immovable=!1,this.moves=!0,this.rotation=0,this.allowRotation=!0,this.allowGravity=!0,this.customSeparateX=!1,this.customSeparateY=!1,this.overlapX=0,this.overlapY=0,this.hullX=new d.Rectangle,this.hullY=new d.Rectangle,this.embedded=!1,this.collideWorldBounds=!1},d.Physics.Arcade.Body.prototype={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.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.screenX=this.sprite.worldTransform[2]-this.sprite.anchor.x*this.width+this.offset.x,this.screenY=this.sprite.worldTransform[5]-this.sprite.anchor.y*this.height+this.offset.y,this.preX=this.sprite.world.x-this.sprite.anchor.x*this.width+this.offset.x,this.preY=this.sprite.world.y-this.sprite.anchor.y*this.height+this.offset.y,this.preRotation=this.sprite.angle,this.x=this.preX,this.y=this.preY,this.rotation=this.preRotation,this.moves&&(this.game.physics.updateMotion(this),this.collideWorldBounds&&this.checkWorldBounds(),this.updateHulls()),this.skipQuadTree===!1&&this.allowCollision.none===!1&&this.sprite.visible&&this.sprite.alive&&(this.quadTreeIDs=[],this.quadTreeIndex=-1,this.game.physics.quadTree.insert(this))},postUpdate:function(){this.deltaX()<0?this.facing=d.LEFT:this.deltaX()>0&&(this.facing=d.RIGHT),this.deltaY()<0?this.facing=d.UP:this.deltaY()>0&&(this.facing=d.DOWN),(0!==this.deltaX()||0!==this.deltaY())&&(this.sprite.x+=this.deltaX(),this.sprite.y+=this.deltaY(),this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight)),this.allowRotation&&(this.sprite.angle+=this.deltaZ())},updateHulls:function(){this.hullX.setTo(this.x,this.preY,this.width,this.height),this.hullY.setTo(this.preX,this.y,this.width,this.height)},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.x-this.preX},deltaY:function(){return this.y-this.preY},deltaZ:function(){return this.rotation-this.preRotation}},Object.defineProperty(d.Physics.Arcade.Body.prototype,"bottom",{get:function(){return this.y+this.height},set:function(a){this.height=a<=this.y?0:this.y-a}}),Object.defineProperty(d.Physics.Arcade.Body.prototype,"right",{get:function(){return this.x+this.width},set:function(a){this.width=a<=this.x?0:this.x+a}}),d.Particles=function(a){this.game=a,this.emitters={},this.ID=0},d.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()}},d.Particles.Arcade={},d.Particles.Arcade.Emitter=function(a,b,c,e){this.maxParticles=e||50,d.Group.call(this,a),this.name="emitter"+this.game.particles.ID++,this.type=d.EMITTER,this.x=0,this.y=0,this.width=1,this.height=1,this.minParticleSpeed=new d.Point(-100,-100),this.maxParticleSpeed=new d.Point(100,100),this.minParticleScale=1,this.maxParticleScale=1,this.minRotation=-360,this.maxRotation=360,this.gravity=2,this.particleClass=null,this.particleDrag=new d.Point,this.angularDrag=0,this.frequency=100,this.lifespan=2e3,this.bounce=new d.Point,this._quantity=0,this._timer=0,this._counter=0,this._explode=!0,this.on=!1,this.exists=!0,this.emitX=b,this.emitY=c},d.Particles.Arcade.Emitter.prototype=Object.create(d.Group.prototype),d.Particles.Arcade.Emitter.prototype.constructor=d.Particles.Arcade.Emitter,d.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)},d.Particles.Arcade.Emitter.prototype.makeParticles=function(a,b,c,e,f){"undefined"==typeof b&&(b=0),c=c||this.maxParticles,e=e||0,"undefined"==typeof f&&(f=!1);for(var g,h=0,i=a,j=0;c>h;)null==this.particleClass&&("object"==typeof a&&(i=this.game.rnd.pick(a)),"object"==typeof b&&(j=this.game.rnd.pick(b)),g=new d.Sprite(this.game,0,0,i,j)),e>0?(g.body.allowCollision.any=!0,g.body.allowCollision.none=!1):g.body.allowCollision.none=!0,g.body.collideWorldBounds=f,g.exists=!1,g.visible=!1,g.anchor.setTo(.5,.5),this.add(g),h++;return this},d.Particles.Arcade.Emitter.prototype.kill=function(){this.on=!1,this.alive=!1,this.exists=!1},d.Particles.Arcade.Emitter.prototype.revive=function(){this.alive=!0,this.exists=!0},d.Particles.Arcade.Emitter.prototype.start=function(a,b,c,d){"boolean"!=typeof a&&(a=!0),b=b||0,c=c||250,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},d.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.drag.x=this.particleDrag.x,a.body.drag.y=this.particleDrag.y,a.body.angularDrag=this.angularDrag}},d.Particles.Arcade.Emitter.prototype.setSize=function(a,b){this.width=a,this.height=b},d.Particles.Arcade.Emitter.prototype.setXSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.x=a,this.maxParticleSpeed.x=b},d.Particles.Arcade.Emitter.prototype.setYSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.y=a,this.maxParticleSpeed.y=b},d.Particles.Arcade.Emitter.prototype.setRotation=function(a,b){a=a||0,b=b||0,this.minRotation=a,this.maxRotation=b},d.Particles.Arcade.Emitter.prototype.at=function(a){this.emitX=a.center.x,this.emitY=a.center.y},Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"x",{get:function(){return this.emitX},set:function(a){this.emitX=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"y",{get:function(){return this.emitY},set:function(a){this.emitY=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"left",{get:function(){return Math.floor(this.x-this.width/2)}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"right",{get:function(){return Math.floor(this.x+this.width/2)}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"top",{get:function(){return Math.floor(this.y-this.height/2)}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"bottom",{get:function(){return Math.floor(this.y+this.height/2)}}),d.Tile=function(a,b,c,d,e,f){this.tileset=a,this.index=b,this.width=e,this.height=f,this.x=c,this.y=d,this.mass=1,this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.separateX=!0,this.separateY=!0,this.collisionCallback=null,this.collisionCallbackContext=this},d.Tile.prototype={setCollisionCallback:function(a,b){this.collisionCallbackContext=b,this.collisionCallback=a},destroy:function(){this.tileset=null},setCollision:function(a,b,c,d){this.collideLeft=a,this.collideRight=b,this.collideUp=c,this.collideDown=d,this.collideNone=a||b||c||d?!1:!0},resetCollision:function(){this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1}},Object.defineProperty(d.Tile.prototype,"bottom",{get:function(){return this.y+this.height}}),Object.defineProperty(d.Tile.prototype,"right",{get:function(){return this.x+this.width}}),d.Tilemap=function(a,b){this.game=a,this.layers=null,"string"==typeof b?(this.key=b,this.layers=a.cache.getTilemapData(b).layers,this.calculateIndexes()):this.layers=[],this.currentLayer=0,this.debugMap=[],this.dirty=!1,this._results=[],this._tempA=0,this._tempB=0},d.Tilemap.CSV=0,d.Tilemap.TILED_JSON=1,d.Tilemap.prototype={create:function(a,b,c){for(var e=[],f=0;c>f;f++){e[f]=[];for(var g=0;b>g;g++)e[f][g]=0}this.layers.push({name:a,width:b,height:c,alpha:1,visible:!0,tileMargin:0,tileSpacing:0,format:d.Tilemap.CSV,data:e,indexes:[]}),this.currentLayer=this.layers.length-1,this.dirty=!0},calculateIndexes:function(){for(var a=0;a=0&&b=0&&c=0&&a=0&&b=0&&a=0&&b=0&&b=0&&ca&&(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({x:g,y:f,index: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),"undefined"==typeof d&&(d=this.currentLayer),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]]?b.push("background: "+this.debugMap[this.layers[this.currentLayer].data[c][d]]):b.push("background: #ffffff"):b.push("background: rgb(0, 0, 0)");a+="\n"}b[0]=a,console.log.apply(console,b)},destroy:function(){this.removeAllLayers(),this.game=null}},d.TilemapLayer=function(a,b,e,f,g,h,i,j){this.game=a,this.canvas=d.Canvas.create(f,g),this.context=this.canvas.getContext("2d"),this.baseTexture=new c.BaseTexture(this.canvas),this.texture=new c.Texture(this.baseTexture),this.textureFrame=new d.Frame(0,0,0,f,g,"tilemaplayer",a.rnd.uuid()),d.Sprite.call(this,this.game,b,e,this.texture,this.textureFrame),this.type=d.TILEMAPLAYER,this.fixedToCamera=!0,this.tileset=null,this.tileWidth=0,this.tileHeight=0,this.tileMargin=0,this.tileSpacing=0,this.widthInPixels=0,this.heightInPixels=0,this.renderWidth=f,this.renderHeight=g,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.scrollFactorX=1,this.scrollFactorY=1,this.tilemap=null,this.layer=null,this.index=0,this.dirty=!0,(h instanceof d.Tileset||"string"==typeof h)&&this.updateTileset(h),i instanceof d.Tilemap&&this.updateMapData(i,j)},d.TilemapLayer.prototype=Object.create(d.Sprite.prototype),d.TilemapLayer.prototype=d.Utils.extend(!0,d.TilemapLayer.prototype,d.Sprite.prototype,c.Sprite.prototype),d.TilemapLayer.prototype.constructor=d.TilemapLayer,d.TilemapLayer.prototype.update=function(){this.scrollX=this.game.camera.x*this.scrollFactorX,this.scrollY=this.game.camera.y*this.scrollFactorY,this.render()},d.TilemapLayer.prototype.resizeWorld=function(){this.game.world.setBounds(0,0,this.widthInPixels,this.heightInPixels)},d.TilemapLayer.prototype.updateTileset=function(a){if(a instanceof d.Tileset)this.tileset=a;else{if("string"!=typeof a)return;this.tileset=this.game.cache.getTileset("tiles")}this.tileWidth=this.tileset.tileWidth,this.tileHeight=this.tileset.tileHeight,this.tileMargin=this.tileset.tileMargin,this.tileSpacing=this.tileset.tileSpacing,this.updateMax()},d.TilemapLayer.prototype.updateMapData=function(a,b){"undefined"==typeof b&&(b=0),a instanceof d.Tilemap&&(this.tilemap=a,this.layer=this.tilemap.layers[b],this.index=b,this.updateMax(),this.tilemap.dirty=!0)},d.TilemapLayer.prototype._fixX=function(a){if(1===this.scrollFactorX)return a;var b=a-this._x/this.scrollFactorX;return this._x+b},d.TilemapLayer.prototype._unfixX=function(a){if(1===this.scrollFactorX)return a;var b=a-this._x;return this._x/this.scrollFactorX+b},d.TilemapLayer.prototype._fixY=function(a){if(1===this.scrollFactorY)return a;var b=a-this._y/this.scrollFactorY;return this._y+b},d.TilemapLayer.prototype._unfixY=function(a){if(1===this.scrollFactorY)return a;var b=a-this._y;return this._y/this.scrollFactorY+b},d.TilemapLayer.prototype.getTileX=function(a){var b=this.tileWidth*this.scale.x;return this.game.math.snapToFloor(this._fixX(a),b)/b},d.TilemapLayer.prototype.getTileY=function(a){var b=this.tileHeight*this.scale.y;return this.game.math.snapToFloor(this._fixY(a),b)/b},d.TilemapLayer.prototype.getTileXY=function(a,b,c){return c.x=this.getTileX(a),c.y=this.getTileY(b),c},d.TilemapLayer.prototype.getTiles=function(a,b,c,d,e){if(null!==this.tilemap){"undefined"==typeof e&&(e=!1),0>a&&(a=0),0>b&&(b=0),a=this._fixX(a),b=this._fixY(b),c>this.widthInPixels&&(c=this.widthInPixels),d>this.heightInPixels&&(d=this.heightInPixels);var f=this.tileWidth*this.scale.x,g=this.tileHeight*this.scale.y;this._tx=this.game.math.snapToFloor(a,f)/f,this._ty=this.game.math.snapToFloor(b,g)/g,this._tw=(this.game.math.snapToCeil(c,f)+f)/f,this._th=(this.game.math.snapToCeil(d,g)+g)/g,this._results=[];for(var h=0,i=null,j=0,k=0,l=this._ty;lthis.layer.width&&(this._maxX=this.layer.width),this._maxY>this.layer.height&&(this._maxY=this.layer.height),this.widthInPixels=this.layer.width*this.tileWidth,this.heightInPixels=this.layer.height*this.tileHeight),this.dirty=!0},d.TilemapLayer.prototype.render=function(){if(this.tilemap&&this.tilemap.dirty&&(this.dirty=!0),this.dirty&&this.tileset&&this.tilemap&&this.visible){this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.tileWidth),this._dy=-(this._y-this._startY*this.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height);for(var a=this._startY;a0?this.deltaX():-this.deltaX()},d.TilemapLayer.prototype.deltaAbsY=function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},d.TilemapLayer.prototype.deltaX=function(){return this._dx-this._prevX},d.TilemapLayer.prototype.deltaY=function(){return this._dy-this._prevY},Object.defineProperty(d.TilemapLayer.prototype,"scrollX",{get:function(){return this._x},set:function(a){a!==this._x&&a>=0&&this.layer&&(this._x=a,this._x>this.widthInPixels-this.renderWidth&&(this._x=this.widthInPixels-this.renderWidth),this._startX=this.game.math.floor(this._x/this.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(d.TilemapLayer.prototype,"scrollY",{get:function(){return this._y},set:function(a){a!==this._y&&a>=0&&this.layer&&(this._y=a,this._y>this.heightInPixels-this.renderHeight&&(this._y=this.heightInPixels-this.renderHeight),this._startY=this.game.math.floor(this._y/this.tileHeight),this._startY<0&&(this._startY=0),this._startY+this._maxY>this.layer.height&&(this._startY=this.layer.height-this._maxY),this.dirty=!0)}}),d.TilemapParser={tileset:function(a,b,c,e,f,g,h){var i=a.cache.getTilesetImage(b);if(null==i)return null;var j=i.width,k=i.height;0>=c&&(c=Math.floor(-j/Math.min(-1,c))),0>=e&&(e=Math.floor(-k/Math.min(-1,e)));var l=Math.round(j/c),m=Math.round(k/e),n=l*m;if(-1!==f&&(n=f),0===j||0===k||c>j||e>k||0===n)return console.warn("Phaser.TilemapParser.tileSet: width/height zero or width/height < given tileWidth/tileHeight"),null;for(var o=g,p=g,q=new d.Tileset(i,b,c,e,g,h),r=0;n>r;r++)q.addTile(new d.Tile(q,r,o,p,c,e)),o+=c+h,o===j&&(o=g,p+=e+h);return q},parse:function(a,b,c){return c===d.Tilemap.CSV?this.parseCSV(b):c===d.Tilemap.TILED_JSON?this.parseTiledJSON(b):void 0},parseCSV:function(a){a=a.trim();for(var b=[],c=a.split("\n"),d=c.length,e=0,f=0;fa)for(var g=a;b>=g;g++)this.tiles[g].setCollision(c,d,e,f)},setCollision:function(a,b,c,d,e){this.tiles[a]&&this.tiles[a].setCollision(b,c,d,e)}},Object.defineProperty(d.Tileset.prototype,"total",{get:function(){return this.tiles.length}}),c.CanvasRenderer.prototype.render=function(a){c.texturesToUpdate.length=0,c.texturesToDestroy.length=0,c.visibleCount++,a.updateTransform(),this.context.setTransform(1,0,0,1,0,0),this.context.clearRect(0,0,this.width,this.height),this.renderDisplayObject(a),c.Texture.frameUpdates.length>0&&(c.Texture.frameUpdates.length=0)},c.CanvasRenderer.prototype.renderDisplayObject=function(a){var b=a.last._iNext;a=a.first;do if(a.visible)if(a.renderable&&0!==a.alpha){if(a instanceof c.Sprite)a.texture.frame&&(this.context.globalAlpha=a.worldAlpha,a.texture.trimmed?this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2]+a.texture.trim.x,a.worldTransform[5]+a.texture.trim.y):this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.context.drawImage(a.texture.baseTexture.source,a.texture.frame.x,a.texture.frame.y,a.texture.frame.width,a.texture.frame.height,a.anchor.x*-a.texture.frame.width,a.anchor.y*-a.texture.frame.height,a.texture.frame.width,a.texture.frame.height));else if(a instanceof c.Strip)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.renderStrip(a);else if(a instanceof c.TilingSprite)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.renderTilingSprite(a);else if(a instanceof c.CustomRenderable)a.renderCanvas(this);else if(a instanceof c.Graphics)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),c.CanvasGraphics.renderGraphics(a,this.context);else if(a instanceof c.FilterBlock)if(a.open){this.context.save();var d=a.mask.alpha,e=a.mask.worldTransform;this.context.setTransform(e[0],e[3],e[1],e[4],e[2],e[5]),a.mask.worldAlpha=.5,this.context.worldAlpha=0,c.CanvasGraphics.renderGraphicsMask(a.mask,this.context),this.context.clip(),a.mask.worldAlpha=d}else this.context.restore();a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!=b)},c.WebGLBatch.prototype.update=function(){for(var a,b,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=0,s=this.head;s;){if(s.vcount===c.visibleCount){if(b=s.texture.frame.width,d=s.texture.frame.height,e=s.anchor.x,f=s.anchor.y,g=b*(1-e),h=b*-e,i=d*(1-f),j=d*-f,k=8*r,a=s.worldTransform,l=a[0],m=a[3],n=a[1],o=a[4],p=a[2],q=a[5],s.texture.trimmed&&(p+=s.texture.trim.x,q+=s.texture.trim.y),this.verticies[k+0]=l*h+n*j+p,this.verticies[k+1]=o*j+m*h+q,this.verticies[k+2]=l*g+n*j+p,this.verticies[k+3]=o*j+m*g+q,this.verticies[k+4]=l*g+n*i+p,this.verticies[k+5]=o*i+m*g+q,this.verticies[k+6]=l*h+n*i+p,this.verticies[k+7]=o*i+m*h+q,s.updateFrame||s.texture.updateFrame){this.dirtyUVS=!0;var t=s.texture,u=t.frame,v=t.baseTexture.width,w=t.baseTexture.height;this.uvs[k+0]=u.x/v,this.uvs[k+1]=u.y/w,this.uvs[k+2]=(u.x+u.width)/v,this.uvs[k+3]=u.y/w,this.uvs[k+4]=(u.x+u.width)/v,this.uvs[k+5]=(u.y+u.height)/w,this.uvs[k+6]=u.x/v,this.uvs[k+7]=(u.y+u.height)/w,s.updateFrame=!1}if(s.cacheAlpha!=s.worldAlpha){s.cacheAlpha=s.worldAlpha;var x=4*r;this.colors[x]=this.colors[x+1]=this.colors[x+2]=this.colors[x+3]=s.worldAlpha,this.dirtyColors=!0}}else k=8*r,this.verticies[k+0]=0,this.verticies[k+1]=0,this.verticies[k+2]=0,this.verticies[k+3]=0,this.verticies[k+4]=0,this.verticies[k+5]=0,this.verticies[k+6]=0,this.verticies[k+7]=0;r++,s=s.__next}},d});
\ No newline at end of file
+/*! Phaser v1.1.4 | (c) 2013 Photon Storm Ltd. */
+!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.Phaser=b()}(this,function(){function a(){return b.Matrix="undefined"!=typeof Float32Array?Float32Array:Array,b.Matrix}var b=b||{},c=c||{VERSION:"1.1.4",DEV_VERSION:"1.1.4",GAMES:[],AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,SPRITE:0,BUTTON:1,BULLET: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,NONE:0,LEFT:1,RIGHT:2,UP:3,DOWN:4,CANVAS_PX_ROUND:!1,CANVAS_CLEAR_RECT:!0};b.InteractionManager=function(){},c.Utils={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,b,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(b in a)d=h[b],e=a[b],h!==e&&(k&&e&&(c.Utils.isPlainObject(e)||(f=Array.isArray(e)))?(f?(f=!1,g=d&&Array.isArray(d)?d:[]):g=d&&c.Utils.isPlainObject(d)?d:{},h[b]=c.Utils.extend(k,g,e)):void 0!==e&&(h[b]=e));return h}},b.hex2rgb=function(a){return[(255&a>>16)/255,(255&a>>8)/255,(255&a)/255]},"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)}),a(),b.mat3={},b.mat3.create=function(){var a=new b.Matrix(9);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},b.mat3.identity=function(a){return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},b.mat4={},b.mat4.create=function(){var a=new b.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},b.mat3.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=b[0],n=b[1],o=b[2],p=b[3],q=b[4],r=b[5],s=b[6],t=b[7],u=b[8];return c[0]=m*d+n*g+o*j,c[1]=m*e+n*h+o*k,c[2]=m*f+n*i+o*l,c[3]=p*d+q*g+r*j,c[4]=p*e+q*h+r*k,c[5]=p*f+q*i+r*l,c[6]=s*d+t*g+u*j,c[7]=s*e+t*h+u*k,c[8]=s*f+t*i+u*l,c},b.mat3.clone=function(a){var c=new b.Matrix(9);return c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[8]=a[8],c},b.mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];return a[1]=a[3],a[2]=a[6],a[3]=c,a[5]=a[7],a[6]=d,a[7]=e,a}return b[0]=a[0],b[1]=a[3],b[2]=a[6],b[3]=a[1],b[4]=a[4],b[5]=a[7],b[6]=a[2],b[7]=a[5],b[8]=a[8],b},b.mat3.toMat4=function(a,c){return c||(c=b.mat4.create()),c[15]=1,c[14]=0,c[13]=0,c[12]=0,c[11]=0,c[10]=a[8],c[9]=a[7],c[8]=a[6],c[7]=0,c[6]=a[5],c[5]=a[4],c[4]=a[3],c[3]=0,c[2]=a[2],c[1]=a[1],c[0]=a[0],c},b.mat4.create=function(){var a=new b.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},b.mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],f=a[6],g=a[7],h=a[11];return a[1]=a[4],a[2]=a[8],a[3]=a[12],a[4]=c,a[6]=a[9],a[7]=a[13],a[8]=d,a[9]=f,a[11]=a[14],a[12]=e,a[13]=g,a[14]=h,a}return b[0]=a[0],b[1]=a[4],b[2]=a[8],b[3]=a[12],b[4]=a[1],b[5]=a[5],b[6]=a[9],b[7]=a[13],b[8]=a[2],b[9]=a[6],b[10]=a[10],b[11]=a[14],b[12]=a[3],b[13]=a[7],b[14]=a[11],b[15]=a[15],b},b.mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=a[9],n=a[10],o=a[11],p=a[12],q=a[13],r=a[14],s=a[15],t=b[0],u=b[1],v=b[2],w=b[3];return c[0]=t*d+u*h+v*l+w*p,c[1]=t*e+u*i+v*m+w*q,c[2]=t*f+u*j+v*n+w*r,c[3]=t*g+u*k+v*o+w*s,t=b[4],u=b[5],v=b[6],w=b[7],c[4]=t*d+u*h+v*l+w*p,c[5]=t*e+u*i+v*m+w*q,c[6]=t*f+u*j+v*n+w*r,c[7]=t*g+u*k+v*o+w*s,t=b[8],u=b[9],v=b[10],w=b[11],c[8]=t*d+u*h+v*l+w*p,c[9]=t*e+u*i+v*m+w*q,c[10]=t*f+u*j+v*n+w*r,c[11]=t*g+u*k+v*o+w*s,t=b[12],u=b[13],v=b[14],w=b[15],c[12]=t*d+u*h+v*l+w*p,c[13]=t*e+u*i+v*m+w*q,c[14]=t*f+u*j+v*n+w*r,c[15]=t*g+u*k+v*o+w*s,c},b.Point=function(a,b){this.x=a||0,this.y=b||0},b.Point.prototype.clone=function(){return new b.Point(this.x,this.y)},b.Point.prototype.constructor=b.Point,b.Rectangle=function(a,b,c,d){this.x=a||0,this.y=b||0,this.width=c||0,this.height=d||0},b.Rectangle.prototype.clone=function(){return new b.Rectangle(this.x,this.y,this.width,this.height)},b.Rectangle.prototype.contains=function(a,b){if(this.width<=0||this.height<=0)return!1;var c=this.x;if(a>=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.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.DisplayObject=function(){this.last=this,this.first=this,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=b.mat3.create(),this.localTransform=b.mat3.create(),this.color=[],this.dynamic=!0,this._sr=0,this._cr=1,this.filterArea=new b.Rectangle(0,0,1,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,"mask",{get:function(){return this._mask},set:function(a){a?this._mask?(a.start=this._mask.start,a.end=this._mask.end):(this.addFilter(a),a.renderable=!1):(this.removeFilter(this._mask),this._mask.renderable=!0),this._mask=a}}),Object.defineProperty(b.DisplayObject.prototype,"filters",{get:function(){return this._filters},set:function(a){if(a){this._filters&&this.removeFilter(this._filters),this.addFilter(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);if(void 0!==a.parent&&a.parent.removeChild(a),a.parent=this,this.stage){var c=a;do c.interactive&&(this.stage.dirty=!0),c.stage=this.stage,c=c._iNext;while(c)}var d,e,f=a.first,g=a.last;if(b===this.children.length){e=this.last;for(var h=this,i=this.last;h;)h.last===i&&(h.last=a.last),h=h.parent}else e=0===b?this:this.children[b-1].last;d=e._iNext,d&&(d._iPrev=g,g._iNext=d),f._iPrev=e,e._iNext=f,this.children.splice(b,0,a),this.__renderGroup&&(a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a),this.__renderGroup.addDisplayObjectAndChildren(a))},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.removeChild(a),this.removeChild(b),d>c?(this.addChildAt(b,c),this.addChildAt(a,d)):(this.addChildAt(a,d),this.addChildAt(b,c))}},b.DisplayObjectContainer.prototype.getChildAt=function(a){if(a>=0&&aa;a++)this.children[a].updateTransform()}},b.blendModes={},b.blendModes.NORMAL=0,b.blendModes.SCREEN=1,b.Sprite=function(a){b.DisplayObjectContainer.call(this),this.anchor=new b.Point,this.texture=a,this.blendMode=b.blendModes.NORMAL,this._width=0,this._height=0,a.baseTexture.hasLoaded?this.updateFrame=!0:(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.__renderGroup&&this.__renderGroup.updateTexture(this)):this.texture=a,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.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){var c=b.Texture.fromImage(a);return new b.Sprite(c)},b.Stage=function(a){b.DisplayObjectContainer.call(this),this.worldTransform=b.mat3.create(),this.interactive=!0,this.interactionManager=new b.InteractionManager(this),this.dirty=!0,this.__childrenAdded=[],this.__childrenRemoved=[],this.stage=this,this.stage.hitArea=new b.Rectangle(0,0,1e5,1e5),this.setBackgroundColor(a),this.worldVisible=!0},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,this.vcount=b.visibleCount;for(var a=0,c=this.children.length;c>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},b.CustomRenderable=function(){b.DisplayObject.call(this),this.renderable=!0},b.CustomRenderable.prototype=Object.create(b.DisplayObject.prototype),b.CustomRenderable.prototype.constructor=b.CustomRenderable,b.CustomRenderable.prototype.renderCanvas=function(){},b.CustomRenderable.prototype.initWebGL=function(){},b.CustomRenderable.prototype.renderWebGL=function(){},b.Strip=function(a,c,d){b.DisplayObjectContainer.call(this),this.texture=a,this.blendMode=b.blendModes.NORMAL;try{this.uvs=new Float32Array([0,1,1,1,1,0,0,1]),this.verticies=new Float32Array([0,0,0,0,0,0,0,0,0]),this.colors=new Float32Array([1,1,1,1]),this.indices=new Uint16Array([0,1,2,3])}catch(e){this.uvs=[0,1,1,1,1,0,0,1],this.verticies=[0,0,0,0,0,0,0,0,0],this.colors=[1,1,1,1],this.indices=[0,1,2,3]}this.width=c,this.height=d,a.baseTexture.hasLoaded?(this.width=this.texture.frame.width,this.height=this.texture.frame.height,this.updateFrame=!0):(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},b.Strip.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Strip.prototype.constructor=b.Strip,b.Strip.prototype.setTexture=function(a){this.texture=a,this.width=a.frame.width,this.height=a.frame.height,this.updateFrame=!0},b.Strip.prototype.onTextureUpdate=function(){this.updateFrame=!0},b.Rope=function(a,c){b.Strip.call(this,a),this.points=c;try{this.verticies=new Float32Array(4*c.length),this.uvs=new Float32Array(4*c.length),this.colors=new Float32Array(2*c.length),this.indices=new Uint16Array(2*c.length)}catch(d){this.verticies=new Array(4*c.length),this.uvs=new Array(4*c.length),this.colors=new Array(2*c.length),this.indices=new Array(2*c.length)}this.refresh()},b.Rope.prototype=Object.create(b.Strip.prototype),b.Rope.prototype.constructor=b.Rope,b.Rope.prototype.refresh=function(){var a=this.points;if(!(a.length<1)){var b=this.uvs,c=a[0],d=this.indices,e=this.colors;this.count-=.2,b[0]=0,b[1]=1,b[2]=0,b[3]=1,e[0]=1,e[1]=1,d[0]=0,d[1]=1;for(var f,g,h,i=a.length,j=1;i>j;j++)f=a[j],g=4*j,h=j/(i-1),j%2?(b[g]=h,b[g+1]=0,b[g+2]=h,b[g+3]=1):(b[g]=h,b[g+1]=0,b[g+2]=h,b[g+3]=1),g=2*j,e[g]=1,e[g+1]=1,g=2*j,d[g]=g,d[g+1]=g+1,c=f}},b.Rope.prototype.updateTransform=function(){var a=this.points;if(!(a.length<1)){var c,d=a[0],e={x:0,y:0};this.count-=.2;var f=this.verticies;f[0]=d.x+e.x,f[1]=d.y+e.y,f[2]=d.x-e.x,f[3]=d.y-e.y;for(var g,h,i,j,k,l=a.length,m=1;l>m;m++)g=a[m],h=4*m,c=m1&&(i=1),j=Math.sqrt(e.x*e.x+e.y*e.y),k=this.texture.height/2,e.x/=j,e.y/=j,e.x*=k,e.y*=k,f[h]=g.x+e.x,f[h+1]=g.y+e.y,f[h+2]=g.x-e.x,f[h+3]=g.y-e.y,d=g;b.DisplayObjectContainer.prototype.updateTransform.call(this)}},b.Rope.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},b.TilingSprite=function(a,c,d){b.DisplayObjectContainer.call(this),this.texture=a,this.width=c,this.height=d,this.tileScale=new b.Point(1,1),this.tilePosition=new b.Point(0,0),this.renderable=!0,this.blendMode=b.blendModes.NORMAL},b.TilingSprite.prototype=Object.create(b.DisplayObjectContainer.prototype),b.TilingSprite.prototype.constructor=b.TilingSprite,b.TilingSprite.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},b.TilingSprite.prototype.onTextureUpdate=function(){this.updateFrame=!0},b.AbstractFilter=function(a,b){this.passes=[this],this.dirty=!0,this.padding=0,this.uniforms=b||{},this.fragmentSrc=a||[]},b.FilterBlock=function(){this.visible=!0,this.renderable=!0},b.Graphics=function(){b.DisplayObjectContainer.call(this),this.renderable=!0,this.fillAlpha=1,this.lineWidth=0,this.lineColor="black",this.graphicsData=[],this.currentPath={points:[]}},b.Graphics.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Graphics.prototype.constructor=b.Graphics,b.Graphics.prototype.lineStyle=function(a,c,d){this.currentPath.points.length||this.graphicsData.pop(),this.lineWidth=a||0,this.lineColor=c||0,this.lineAlpha=arguments.length<3?1:d,this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:b.Graphics.POLY},this.graphicsData.push(this.currentPath)},b.Graphics.prototype.moveTo=function(a,c){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath=this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:b.Graphics.POLY},this.currentPath.points.push(a,c),this.graphicsData.push(this.currentPath)},b.Graphics.prototype.lineTo=function(a,b){this.currentPath.points.push(a,b),this.dirty=!0},b.Graphics.prototype.beginFill=function(a,b){this.filling=!0,this.fillColor=a||0,this.fillAlpha=arguments.length<2?1:b},b.Graphics.prototype.endFill=function(){this.filling=!1,this.fillColor=null,this.fillAlpha=1},b.Graphics.prototype.drawRect=function(a,c,d,e){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,c,d,e],type:b.Graphics.RECT},this.graphicsData.push(this.currentPath),this.dirty=!0},b.Graphics.prototype.drawCircle=function(a,c,d){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,c,d,d],type:b.Graphics.CIRC},this.graphicsData.push(this.currentPath),this.dirty=!0},b.Graphics.prototype.drawEllipse=function(a,c,d,e){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,c,d,e],type:b.Graphics.ELIP},this.graphicsData.push(this.currentPath),this.dirty=!0},b.Graphics.prototype.clear=function(){this.lineWidth=0,this.filling=!1,this.dirty=!0,this.clearDirty=!0,this.graphicsData=[],this.bounds=null},b.Graphics.prototype.updateFilterBounds=function(){if(!this.bounds){for(var a,c,d,e=1/0,f=-1/0,g=1/0,h=-1/0,i=0;ic?c:e,f=c+m>f?c+m:f,g=g>d?c:g,h=d+n>h?d+n:h}else if(k===b.Graphics.CIRC||k===b.Graphics.ELIP){c=a.x,d=a.y;var o=a.radius+l/2;e=e>c-o?c-o:e,f=c+o>f?c+o:f,g=g>d-o?d-o:g,h=d+o>h?d+o:h}else for(var p=0;pc-l?c-l:e,f=c+l>f?c+l:f,g=g>d-l?d-l:g,h=d+l>h?d+l:h}this.bounds=new b.Rectangle(e,g,f-e,h-g)}},b.Graphics.POLY=0,b.Graphics.RECT=1,b.Graphics.CIRC=2,b.Graphics.ELIP=3,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;h0&&(b.Texture.frameUpdates=[])},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){var c,d=this.context;d.globalCompositeOperation="source-over";var e=a.last._iNext;a=a.first;do if(c=a.worldTransform,a.visible)if(a.renderable){if(a instanceof b.Sprite){var f=a.texture.frame;f&&f.width&&f.height&&a.texture.baseTexture.source&&(d.globalAlpha=a.worldAlpha,d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),this.smoothProperty&&this.scaleMode!==a.texture.baseTexture.scaleMode&&(this.scaleMode=a.texture.baseTexture.scaleMode,d[this.smoothProperty]=this.scaleMode===b.BaseTexture.SCALE_MODE.LINEAR),d.drawImage(a.texture.baseTexture.source,f.x,f.y,f.width,f.height,a.anchor.x*-f.width,a.anchor.y*-f.height,f.width,f.height))}else if(a instanceof b.Strip)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),this.renderStrip(a);else if(a instanceof b.TilingSprite)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),this.renderTilingSprite(a);else if(a instanceof b.CustomRenderable)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),a.renderCanvas(this);else if(a instanceof b.Graphics)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),b.CanvasGraphics.renderGraphics(a,d);else if(a instanceof b.FilterBlock&&a.data instanceof b.Graphics){var g=a.data;if(a.open){d.save();var h=g.alpha,i=g.worldTransform;d.setTransform(i[0],i[3],i[1],i[4],i[2],i[5]),g.worldAlpha=.5,d.worldAlpha=0,b.CanvasGraphics.renderGraphicsMask(g,d),d.clip(),g.worldAlpha=h}else d.restore()}a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!==e)},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.renderTilingSprite=function(a){var b=this.context;b.globalAlpha=a.worldAlpha,a.__tilePattern||(a.__tilePattern=b.createPattern(a.texture.baseTexture.source,"repeat")),b.beginPath();var c=a.tilePosition,d=a.tileScale;b.scale(d.x,d.y),b.translate(c.x,c.y),b.fillStyle=a.__tilePattern,b.fillRect(-c.x,-c.y,a.width/d.x,a.height/d.y),b.scale(1/d.x,1/d.y),b.translate(-c.x,-c.y),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.PixiShader=function(){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.textureCount=0},b.PixiShader.prototype.init=function(){var a=b.compileProgram(this.vertexSrc||b.PixiShader.defaultVertexSrc,this.fragmentSrc),c=b.gl;c.useProgram(a),this.uSampler=c.getUniformLocation(a,"uSampler"),this.projectionVector=c.getUniformLocation(a,"projectionVector"),this.offsetVector=c.getUniformLocation(a,"offsetVector"),this.dimensions=c.getUniformLocation(a,"dimensions"),this.aVertexPosition=c.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=c.getAttribLocation(a,"aColor"),this.aTextureCoord=c.getAttribLocation(a,"aTextureCoord");for(var d in this.uniforms)this.uniforms[d].uniformLocation=c.getUniformLocation(a,d);this.initUniforms(),this.program=a},b.PixiShader.prototype.initUniforms=function(){this.textureCount=1;var a;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.gl.uniformMatrix2fv:"mat3"===d?a.glFunc=b.gl.uniformMatrix3fv:"mat4"===d&&(a.glFunc=b.gl.uniformMatrix4fv)):(a.glFunc=b.gl["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){if(b.gl.activeTexture(b.gl["TEXTURE"+this.textureCount]),b.gl.bindTexture(b.gl.TEXTURE_2D,a.value.baseTexture._glTexture),a.textureData){var c=a.textureData,d=c.magFilter?c.magFilter:b.gl.LINEAR,e=c.minFilter?c.minFilter:b.gl.LINEAR,f=c.wrapS?c.wrapS:b.gl.CLAMP_TO_EDGE,g=c.wrapT?c.wrapT:b.gl.CLAMP_TO_EDGE,h=c.luminance?b.gl.LUMINANCE:b.gl.RGBA;if(c.repeat&&(f=b.gl.REPEAT,g=b.gl.REPEAT),b.gl.pixelStorei(b.gl.UNPACK_FLIP_Y_WEBGL,!1),c.width){var i=c.width?c.width:512,j=c.height?c.height:2,k=c.border?c.border:0;b.gl.texImage2D(b.gl.TEXTURE_2D,0,h,i,j,k,h,b.gl.UNSIGNED_BYTE,null)}else b.gl.texImage2D(b.gl.TEXTURE_2D,0,h,b.gl.RGBA,b.gl.UNSIGNED_BYTE,a.value.baseTexture.source);b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_MAG_FILTER,d),b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_MIN_FILTER,e),b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_WRAP_S,f),b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_WRAP_T,g)}b.gl.uniform1i(a.uniformLocation,this.textureCount),a._init=!0,this.textureCount++}},b.PixiShader.prototype.syncUniforms=function(){this.textureCount=1;var a;for(var c in this.uniforms)a=this.uniforms[c],1===a.glValueLength?a.glMatrix===!0?a.glFunc.call(b.gl,a.uniformLocation,a.transpose,a.value):a.glFunc.call(b.gl,a.uniformLocation,a.value):2===a.glValueLength?a.glFunc.call(b.gl,a.uniformLocation,a.value.x,a.value.y):3===a.glValueLength?a.glFunc.call(b.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z):4===a.glValueLength?a.glFunc.call(b.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z,a.value.w):"sampler2D"===a.type&&(a._init?(b.gl.activeTexture(b.gl["TEXTURE"+this.textureCount]),b.gl.bindTexture(b.gl.TEXTURE_2D,a.value.baseTexture._glTexture),b.gl.uniform1i(a.uniformLocation,this.textureCount),this.textureCount++):this.initSampler2D(a))},b.PixiShader.defaultVertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","varying float 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;"," vColor = aColor;","}"],b.PrimitiveShader=function(){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;","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 * alpha;","}"]
+},b.PrimitiveShader.prototype.init=function(){var a=b.compileProgram(this.vertexSrc,this.fragmentSrc),c=b.gl;c.useProgram(a),this.projectionVector=c.getUniformLocation(a,"projectionVector"),this.offsetVector=c.getUniformLocation(a,"offsetVector"),this.aVertexPosition=c.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=c.getAttribLocation(a,"aColor"),this.translationMatrix=c.getUniformLocation(a,"translationMatrix"),this.alpha=c.getUniformLocation(a,"alpha"),this.program=a},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;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","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.compileProgram(this.vertexSrc,this.fragmentSrc),c=b.gl;c.useProgram(a),this.uSampler=c.getUniformLocation(a,"uSampler"),this.projectionVector=c.getUniformLocation(a,"projectionVector"),this.offsetVector=c.getUniformLocation(a,"offsetVector"),this.colorAttribute=c.getAttribLocation(a,"aColor"),this.aVertexPosition=c.getAttribLocation(a,"aVertexPosition"),this.aTextureCoord=c.getAttribLocation(a,"aTextureCoord"),this.translationMatrix=c.getUniformLocation(a,"translationMatrix"),this.alpha=c.getUniformLocation(a,"alpha"),this.program=a},b._batchs=[],b._getBatch=function(a){return 0===b._batchs.length?new b.WebGLBatch(a):b._batchs.pop()},b._returnBatch=function(a){a.clean(),b._batchs.push(a)},b._restoreBatchs=function(a){for(var c=0;cc;c++){var d=6*c,e=4*c;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}a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,this.indices,a.STATIC_DRAW)},b.WebGLBatch.prototype.refresh=function(){this.dynamicSizethis.width&&(f.width=this.width),f.y<0&&(f.y=0),f.height>this.height&&(f.height=this.height),c.bindFramebuffer(c.FRAMEBUFFER,e.frameBuffer),c.viewport(0,0,f.width,f.height),b.projection.x=f.width/2,b.projection.y=-f.height/2,b.offset.x=-f.x,b.offset.y=-f.y,c.uniform2f(b.defaultShader.projectionVector,f.width/2,-f.height/2),c.uniform2f(b.defaultShader.offsetVector,-f.x,-f.y),c.colorMask(!0,!0,!0,!0),c.clearColor(0,0,0,0),c.clear(c.COLOR_BUFFER_BIT),a._glFilterTexture=e},b.WebGLFilterManager.prototype.popFilter=function(){var a=b.gl,c=this.filterStack.pop(),d=c.target.filterArea,e=c._glFilterTexture;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 f=e,g=this.texturePool.pop();g||(g=new b.FilterTexture(this.width,this.height)),a.bindFramebuffer(a.FRAMEBUFFER,g.frameBuffer),a.clear(a.COLOR_BUFFER_BIT),a.disable(a.BLEND);for(var h=0;hs?s:E,E=E>t?t:E,E=E>u?u:E,E=E>v?v:E,F=F>w?w:F,F=F>x?x:F,F=F>y?y:F,F=F>z?z:F,C=s>C?s:C,C=t>C?t:C,C=u>C?u:C,C=v>C?v:C,D=w>D?w:D,D=x>D?x:D,D=y>D?y:D,D=z>D?z:D),l=!1,A=A._iNext}while(A!==B);a.filterArea.x=E,a.filterArea.y=F,a.filterArea.width=C-E,a.filterArea.height=D-F},b.FilterTexture=function(a,c){var d=b.gl;this.frameBuffer=d.createFramebuffer(),this.texture=d.createTexture(),d.bindTexture(d.TEXTURE_2D,this.texture),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MAG_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MIN_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.bindFramebuffer(d.FRAMEBUFFER,this.framebuffer),d.bindFramebuffer(d.FRAMEBUFFER,this.frameBuffer),d.framebufferTexture2D(d.FRAMEBUFFER,d.COLOR_ATTACHMENT0,d.TEXTURE_2D,this.texture,0),this.resize(a,c)},b.FilterTexture.prototype.resize=function(a,c){if(this.width!==a||this.height!==c){this.width=a,this.height=c;var d=b.gl;d.bindTexture(d.TEXTURE_2D,this.texture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,a,c,0,d.RGBA,d.UNSIGNED_BYTE,null)}},b.WebGLGraphics=function(){},b.WebGLGraphics.renderGraphics=function(a,c){var d=b.gl;a._webGL||(a._webGL={points:[],indices:[],lastIndex:0,buffer:d.createBuffer(),indexBuffer:d.createBuffer()}),a.dirty&&(a.dirty=!1,a.clearDirty&&(a.clearDirty=!1,a._webGL.lastIndex=0,a._webGL.points=[],a._webGL.indices=[]),b.WebGLGraphics.updateGraphics(a)),b.activatePrimitiveShader();var e=b.mat3.clone(a.worldTransform);b.mat3.transpose(e),d.blendFunc(d.ONE,d.ONE_MINUS_SRC_ALPHA),d.uniformMatrix3fv(b.primitiveShader.translationMatrix,!1,e),d.uniform2f(b.primitiveShader.projectionVector,c.x,-c.y),d.uniform2f(b.primitiveShader.offsetVector,-b.offset.x,-b.offset.y),d.uniform1f(b.primitiveShader.alpha,a.worldAlpha),d.bindBuffer(d.ARRAY_BUFFER,a._webGL.buffer),d.vertexAttribPointer(b.primitiveShader.aVertexPosition,2,d.FLOAT,!1,24,0),d.vertexAttribPointer(b.primitiveShader.colorAttribute,4,d.FLOAT,!1,24,8),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),d.drawElements(d.TRIANGLE_STRIP,a._webGL.indices.length,d.UNSIGNED_SHORT,0),b.deactivatePrimitiveShader()},b.WebGLGraphics.updateGraphics=function(a){for(var c=a._webGL.lastIndex;c3&&b.WebGLGraphics.buildPoly(d,a._webGL),d.lineWidth>0&&b.WebGLGraphics.buildLine(d,a._webGL)):d.type===b.Graphics.RECT?b.WebGLGraphics.buildRectangle(d,a._webGL):(d.type===b.Graphics.CIRC||d.type===b.Graphics.ELIP)&&b.WebGLGraphics.buildCircle(d,a._webGL)}a._webGL.lastIndex=a.graphicsData.length;var e=b.gl;a._webGL.glPoints=new Float32Array(a._webGL.points),e.bindBuffer(e.ARRAY_BUFFER,a._webGL.buffer),e.bufferData(e.ARRAY_BUFFER,a._webGL.glPoints,e.STATIC_DRAW),a._webGL.glIndicies=new Uint16Array(a._webGL.indices),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,a._webGL.glIndicies,e.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)}a.lineWidth&&(a.points=[e,f,e+g,f,e+g,f+h,e,f+h,e,f],b.WebGLGraphics.buildLine(a,c))},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){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)}},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._defaultFrame=new b.Rectangle(0,0,1,1),b.gl=null,b.WebGLRenderer=function(a,c,d,e,f){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;var g=this;this.view.addEventListener("webglcontextlost",function(a){g.handleContextLost(a)},!1),this.view.addEventListener("webglcontextrestored",function(a){g.handleContextRestored(a)},!1),this.batchs=[];var h={alpha:this.transparent,antialias:!!f,premultipliedAlpha:!1,stencil:!0};try{b.gl=this.gl=this.view.getContext("experimental-webgl",h)}catch(i){try{b.gl=this.gl=this.view.getContext("webgl",h)}catch(j){throw new Error(" This browser does not support webGL. Try using the canvas renderer"+this)}}b.initDefaultShaders();var k=this.gl;k.useProgram(b.defaultShader.program),b.WebGLRenderer.gl=k,this.batch=new b.WebGLBatch(k),k.disable(k.DEPTH_TEST),k.disable(k.CULL_FACE),k.enable(k.BLEND),k.colorMask(!0,!0,!0,this.transparent),b.projection=new b.Point(400,300),b.offset=new b.Point(0,0),this.resize(this.width,this.height),this.contextLost=!1,this.stageRenderGroup=new b.WebGLRenderGroup(this.gl,this.transparent)},b.WebGLRenderer.prototype.constructor=b.WebGLRenderer,b.WebGLRenderer.getBatch=function(){return 0===b._batchs.length?new b.WebGLBatch(b.WebGLRenderer.gl):b._batchs.pop()},b.WebGLRenderer.returnBatch=function(a){a.clean(),b._batchs.push(a)},b.WebGLRenderer.prototype.render=function(a){if(!this.contextLost){this.__stage!==a&&(this.__stage=a,this.stageRenderGroup.setRenderable(a)),b.WebGLRenderer.updateTextures(),b.visibleCount++,a.updateTransform();var c=this.gl;if(c.colorMask(!0,!0,!0,this.transparent),c.viewport(0,0,this.width,this.height),c.bindFramebuffer(c.FRAMEBUFFER,null),c.clearColor(a.backgroundColorSplit[0],a.backgroundColorSplit[1],a.backgroundColorSplit[2],!this.transparent),c.clear(c.COLOR_BUFFER_BIT),this.stageRenderGroup.backgroundColor=a.backgroundColorSplit,b.projection.x=this.width/2,b.projection.y=-this.height/2,this.stageRenderGroup.render(b.projection),a.interactive&&(a._interactiveEventsAdded||(a._interactiveEventsAdded=!0,a.interactionManager.setTarget(this))),b.Texture.frameUpdates.length>0){for(var d=0;dn;n++)renderable=this.batchs[n],renderable instanceof b.WebGLBatch?this.batchs[n].render():this.renderSpecial(renderable,c);endBatch instanceof b.WebGLBatch?endBatch.render(0,h+1):this.renderSpecial(endBatch,c)},b.WebGLRenderGroup.prototype.renderSpecial=function(a,c){var d=a.vcount===b.visibleCount;a instanceof b.TilingSprite?d&&this.renderTilingSprite(a,c):a instanceof b.Strip?d&&this.renderStrip(a,c):a instanceof b.CustomRenderable?d&&a.renderWebGL(this,c):a instanceof b.Graphics?d&&a.renderable&&b.WebGLGraphics.renderGraphics(a,c):a instanceof b.FilterBlock&&this.handleFilterBlock(a,c)},flip=!1;var d=[],e=0;return b.WebGLRenderGroup.prototype.handleFilterBlock=function(a,c){var f=b.gl;if(a.open)a.data instanceof Array?this.filterManager.pushFilter(a):(e++,d.push(a),f.enable(f.STENCIL_TEST),f.colorMask(!1,!1,!1,!1),f.stencilFunc(f.ALWAYS,1,1),f.stencilOp(f.KEEP,f.KEEP,f.INCR),b.WebGLGraphics.renderGraphics(a.data,c),f.colorMask(!0,!0,!0,!0),f.stencilFunc(f.NOTEQUAL,0,d.length),f.stencilOp(f.KEEP,f.KEEP,f.KEEP));else if(a.data instanceof Array)this.filterManager.popFilter();else{var g=d.pop(a);g&&(f.colorMask(!1,!1,!1,!1),f.stencilFunc(f.ALWAYS,1,1),f.stencilOp(f.KEEP,f.KEEP,f.DECR),b.WebGLGraphics.renderGraphics(g.data,c),f.colorMask(!0,!0,!0,!0),f.stencilFunc(f.NOTEQUAL,0,d.length),f.stencilOp(f.KEEP,f.KEEP,f.KEEP)),f.disable(f.STENCIL_TEST)}},b.WebGLRenderGroup.prototype.updateTexture=function(a){this.removeObject(a);for(var b=a.first;b!=this.root&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););this.insertObject(a,b,c)},b.WebGLRenderGroup.prototype.addFilterBlocks=function(a,b){a.__renderGroup=this,b.__renderGroup=this;for(var c=a;c!=this.root.first&&(c=c._iPrev,!c.renderable||!c.__renderGroup););this.insertAfter(a,c);for(var d=b;d!=this.root.first&&(d=d._iPrev,!d.renderable||!d.__renderGroup););this.insertAfter(b,d)},b.WebGLRenderGroup.prototype.removeFilterBlocks=function(a,b){this.removeObject(a),this.removeObject(b)},b.WebGLRenderGroup.prototype.addDisplayObjectAndChildren=function(a){a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a);for(var b=a.first;b!=this.root.first&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););var d=a.first,e=a.last._iNext;do d.__renderGroup=this,d.renderable&&(this.insertObject(d,b,c),b=d),d=d._iNext;while(d!=e)},b.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren=function(a){if(a.__renderGroup==this){a.last;do a.__renderGroup=null,a.renderable&&this.removeObject(a),a=a._iNext;while(a)}},b.WebGLRenderGroup.prototype.insertObject=function(a,c,d){var e=c,f=d;if(a instanceof b.Sprite){var g,h;if(e instanceof b.Sprite){if(g=e.batch,g&&g.texture==a.texture.baseTexture&&g.blendMode==a.blendMode)return g.insertAfter(a,e),void 0}else g=e;if(f)if(f instanceof b.Sprite){if(h=f.batch){if(h.texture==a.texture.baseTexture&&h.blendMode==a.blendMode)return h.insertBefore(a,f),void 0;if(h==g){var i=g.split(f),j=b.WebGLRenderer.getBatch(),k=this.batchs.indexOf(g);return j.init(a),this.batchs.splice(k+1,0,j,i),void 0}}}else h=f;var j=b.WebGLRenderer.getBatch();if(j.init(a),g){var k=this.batchs.indexOf(g);this.batchs.splice(k+1,0,j)}else this.batchs.push(j)}else a instanceof b.TilingSprite?this.initTilingSprite(a):a instanceof b.Strip&&this.initStrip(a),this.insertAfter(a,e)},b.WebGLRenderGroup.prototype.insertAfter=function(a,c){if(c instanceof b.Sprite){var d=c.batch;if(d)if(d.tail==c){var e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a)}else{var f=d.split(c.__next),e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a,f)}else this.batchs.push(a)}else{var e=this.batchs.indexOf(c);this.batchs.splice(e+1,0,a)}},b.WebGLRenderGroup.prototype.removeObject=function(a){var c;if(a instanceof b.Sprite){var d=a.batch;if(!d)return;d.remove(a),0==d.size&&(c=d)}else c=a;if(c){var e=this.batchs.indexOf(c);if(-1==e)return;if(0==e||e==this.batchs.length-1)return this.batchs.splice(e,1),c instanceof b.WebGLBatch&&b.WebGLRenderer.returnBatch(c),void 0;if(this.batchs[e-1]instanceof b.WebGLBatch&&this.batchs[e+1]instanceof b.WebGLBatch&&this.batchs[e-1].texture==this.batchs[e+1].texture&&this.batchs[e-1].blendMode==this.batchs[e+1].blendMode)return this.batchs[e-1].merge(this.batchs[e+1]),c instanceof b.WebGLBatch&&b.WebGLRenderer.returnBatch(c),b.WebGLRenderer.returnBatch(this.batchs[e+1]),this.batchs.splice(e,2),void 0;this.batchs.splice(e,1),c instanceof b.WebGLBatch&&b.WebGLRenderer.returnBatch(c)}},b.WebGLRenderGroup.prototype.initTilingSprite=function(a){var b=this.gl;a.verticies=new Float32Array([0,0,a.width,0,a.width,a.height,0,a.height]),a.uvs=new Float32Array([0,0,1,0,1,1,0,1]),a.colors=new Float32Array([1,1,1,1]),a.indices=new Uint16Array([0,1,3,2]),a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW),a.texture.baseTexture._glTexture?(b.bindTexture(b.TEXTURE_2D,a.texture.baseTexture._glTexture),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.REPEAT),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.REPEAT),a.texture.baseTexture._powerOf2=!0):a.texture.baseTexture._powerOf2=!0},b.WebGLRenderGroup.prototype.renderStrip=function(a,c){var d=this.gl;b.activateStripShader();var e=b.stripShader;e.program;var f=b.mat3.clone(a.worldTransform);b.mat3.transpose(f),d.uniformMatrix3fv(e.translationMatrix,!1,f),d.uniform2f(e.projectionVector,c.x,c.y),d.uniform2f(e.offsetVector,-b.offset.x,-b.offset.y),d.uniform1f(e.alpha,a.worldAlpha),a.dirty?(a.dirty=!1,d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferData(d.ARRAY_BUFFER,a.verticies,d.STATIC_DRAW),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferData(d.ARRAY_BUFFER,a.uvs,d.STATIC_DRAW),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.bufferData(d.ARRAY_BUFFER,a.colors,d.STATIC_DRAW),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer),d.bufferData(d.ELEMENT_ARRAY_BUFFER,a.indices,d.STATIC_DRAW)):(d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.verticies),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer)),d.drawElements(d.TRIANGLE_STRIP,a.indices.length,d.UNSIGNED_SHORT,0),b.deactivateStripShader()
+},b.WebGLRenderGroup.prototype.renderTilingSprite=function(a,c){var d=this.gl;b.shaderProgram;var e=a.tilePosition,f=a.tileScale,g=e.x/a.texture.baseTexture.width,h=e.y/a.texture.baseTexture.height,i=a.width/a.texture.baseTexture.width/f.x,j=a.height/a.texture.baseTexture.height/f.y;a.uvs[0]=0-g,a.uvs[1]=0-h,a.uvs[2]=1*i-g,a.uvs[3]=0-h,a.uvs[4]=1*i-g,a.uvs[5]=1*j-h,a.uvs[6]=0-g,a.uvs[7]=1*j-h,d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.uvs),this.renderStrip(a,c)},b.WebGLRenderGroup.prototype.initStrip=function(a){var b=this.gl;this.shaderProgram,a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW)},b.initDefaultShaders=function(){b.primitiveShader=new b.PrimitiveShader,b.primitiveShader.init(),b.stripShader=new b.StripShader,b.stripShader.init(),b.defaultShader=new b.PixiShader,b.defaultShader.init();var a=b.gl,c=b.defaultShader.program;a.useProgram(c),a.enableVertexAttribArray(b.defaultShader.aVertexPosition),a.enableVertexAttribArray(b.defaultShader.colorAttribute),a.enableVertexAttribArray(b.defaultShader.aTextureCoord)},b.activatePrimitiveShader=function(){var a=b.gl;a.useProgram(b.primitiveShader.program),a.disableVertexAttribArray(b.defaultShader.aVertexPosition),a.disableVertexAttribArray(b.defaultShader.colorAttribute),a.disableVertexAttribArray(b.defaultShader.aTextureCoord),a.enableVertexAttribArray(b.primitiveShader.aVertexPosition),a.enableVertexAttribArray(b.primitiveShader.colorAttribute)},b.deactivatePrimitiveShader=function(){var a=b.gl;a.useProgram(b.defaultShader.program),a.disableVertexAttribArray(b.primitiveShader.aVertexPosition),a.disableVertexAttribArray(b.primitiveShader.colorAttribute),a.enableVertexAttribArray(b.defaultShader.aVertexPosition),a.enableVertexAttribArray(b.defaultShader.colorAttribute),a.enableVertexAttribArray(b.defaultShader.aTextureCoord)},b.activateStripShader=function(){var a=b.gl;a.useProgram(b.stripShader.program)},b.deactivateStripShader=function(){var a=b.gl;a.useProgram(b.defaultShader.program)},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){var d=b.gl,e=b.CompileFragmentShader(d,c),f=b.CompileVertexShader(d,a),g=d.createProgram();return d.attachShader(g,f),d.attachShader(g,e),d.linkProgram(g),d.getProgramParameter(g,d.LINK_STATUS)||window.console.log("Could not initialise shaders"),g},b.BitmapText=function(a,c){b.DisplayObjectContainer.call(this),this.setText(a),this.setStyle(c),this.updateText(),this.dirty=!1},b.BitmapText.prototype=Object.create(b.DisplayObjectContainer.prototype),b.BitmapText.prototype.constructor=b.BitmapText,b.BitmapText.prototype.setText=function(a){this.text=a||" ",this.dirty=!0},b.BitmapText.prototype.setStyle=function(a){a=a||{},a.align=a.align||"left",this.style=a;var c=a.font.split(" ");this.fontName=c[c.length-1],this.fontSize=c.length>=2?parseInt(c[c.length-2],10):b.BitmapText.fonts[this.fontName].size,this.dirty=!0},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)}for(j=0;j0;)this.removeChild(this.getChildAt(0));this.updateText(),this.dirty=!1}b.DisplayObjectContainer.prototype.updateTransform.call(this)},b.BitmapText.fonts={},b.Text=function(a,c){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),b.Sprite.call(this,b.Texture.fromCanvas(this.canvas)),this.setText(a),this.setStyle(c),this.updateText(),this.dirty=!1},b.Text.prototype=Object.create(b.Sprite.prototype),b.Text.prototype.constructor=b.Text,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,this.style=a,this.dirty=!0},b.Text.prototype.setText=function(a){this.text=a.toString()||" ",this.dirty=!0},b.Text.prototype.updateText=function(){this.context.font=this.style.font;var a=this.text;this.style.wordWrap&&(a=this.wordWrap(this.text));for(var c=a.split(/(?:\r\n|\r|\n)/),d=[],e=0,f=0;fe?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}b+="\n"}return b},b.Text.prototype.destroy=function(a){a&&this.texture.destroy()},b.Text.heightCache={},b.BaseTextureCache={},b.texturesToUpdate=[],b.texturesToDestroy=[],b.BaseTexture=function(a,c){if(b.EventTarget.call(this),this.width=100,this.height=100,this.scaleMode=c||b.BaseTexture.SCALE_MODE.DEFAULT,this.hasLoaded=!1,this.source=a,a){if(this.source instanceof Image||this.source instanceof HTMLImageElement)if(this.source.complete)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})}}else this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,b.texturesToUpdate.push(this);this.imageUrl=null,this._powerOf2=!1}},b.BaseTexture.prototype.constructor=b.BaseTexture,b.BaseTexture.prototype.destroy=function(){this.source instanceof Image&&(this.imageUrl in b.BaseTextureCache&&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.SCALE_MODE={DEFAULT:0,LINEAR:0,NEAREST:1},b.TextureCache={},b.FrameCache={},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=new b.Point,this.scope=this,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.noFrame=!1,this.width=this.frame.width,this.height=this.frame.height,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.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 '+this);return c},b.Texture.fromCanvas=function(a,c){var d=new b.BaseTexture(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 b.TextureCache[a]=null,c},b.Texture.frameUpdates=[],b.Texture.SCALE_MODE=b.BaseTexture.SCALE_MODE,b.RenderTexture=function(a,c){b.EventTarget.call(this),this.width=a||100,this.height=c||100,this.indetityMatrix=b.mat3.create(),this.frame=new b.Rectangle(0,0,this.width,this.height),b.gl?this.initWebGL():this.initCanvas()},b.RenderTexture.prototype=Object.create(b.Texture.prototype),b.RenderTexture.prototype.constructor=b.RenderTexture,b.RenderTexture.prototype.initWebGL=function(){var a=b.gl;this.glFramebuffer=a.createFramebuffer(),a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),this.glFramebuffer.width=this.width,this.glFramebuffer.height=this.height,this.baseTexture=new b.BaseTexture,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.baseTexture._glTexture=a.createTexture(),a.bindTexture(a.TEXTURE_2D,this.baseTexture._glTexture),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,this.width,this.height,0,a.RGBA,a.UNSIGNED_BYTE,null),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),this.baseTexture.isRender=!0,a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),a.framebufferTexture2D(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,this.baseTexture._glTexture,0),this.projection=new b.Point(this.width/2,-this.height/2),this.render=this.renderWebGL},b.RenderTexture.prototype.resize=function(a,c){if(this.width=a,this.height=c,b.gl){this.projection.x=this.width/2,this.projection.y=-this.height/2;var d=b.gl;d.bindTexture(d.TEXTURE_2D,this.baseTexture._glTexture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,this.width,this.height,0,d.RGBA,d.UNSIGNED_BYTE,null)}else this.frame.width=this.width,this.frame.height=this.height,this.renderer.resize(this.width,this.height)},b.RenderTexture.prototype.initCanvas=function(){this.renderer=new b.CanvasRenderer(this.width,this.height,null,0),this.baseTexture=new b.BaseTexture(this.renderer.view),this.frame=new b.Rectangle(0,0,this.width,this.height),this.render=this.renderCanvas},b.RenderTexture.prototype.renderWebGL=function(a,c,d){var e=b.gl;e.colorMask(!0,!0,!0,!0),e.viewport(0,0,this.width,this.height),e.bindFramebuffer(e.FRAMEBUFFER,this.glFramebuffer),d&&(e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT));var f=a.children,g=a.worldTransform;a.worldTransform=b.mat3.create(),a.worldTransform[4]=-1,a.worldTransform[5]=-2*this.projection.y,c&&(a.worldTransform[2]=c.x,a.worldTransform[5]-=c.y),b.visibleCount++,a.vcount=b.visibleCount;for(var h=0,i=f.length;i>h;h++)f[h].updateTransform();var j=a.__renderGroup;j?a===j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new b.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},b.RenderTexture.prototype.renderCanvas=function(a,c,d){var e=a.children;a.worldTransform=b.mat3.create(),c&&(a.worldTransform[2]=c.x,a.worldTransform[5]=c.y);for(var f=0,g=e.length;g>f;f++)e[f].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a),this.renderer.context.setTransform(1,0,0,1,0,0)},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},c.Camera=function(a,b,d,e,f,g){this.game=a,this.world=a.world,this.id=0,this.view=new c.Rectangle(d,e,f,g),this.screenView=new c.Rectangle(d,e,f,g),this.bounds=new c.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},c.Camera.FOLLOW_LOCKON=0,c.Camera.FOLLOW_PLATFORMER=1,c.Camera.FOLLOW_TOPDOWN=2,c.Camera.FOLLOW_TOPDOWN_TIGHT=3,c.Camera.prototype={follow:function(a,b){"undefined"==typeof b&&(b=c.Camera.FOLLOW_LOCKON),this.target=a;var d;switch(b){case c.Camera.FOLLOW_PLATFORMER:var e=this.width/8,f=this.height/3;this.deadzone=new c.Rectangle((this.width-e)/2,(this.height-f)/2-.25*f,e,f);break;case c.Camera.FOLLOW_TOPDOWN:d=Math.max(this.width,this.height)/4,this.deadzone=new c.Rectangle((this.width-d)/2,(this.height-d)/2,d,d);break;case c.Camera.FOLLOW_TOPDOWN_TIGHT:d=Math.max(this.width,this.height)/8,this.deadzone=new c.Rectangle((this.width-d)/2,(this.height-d)/2,d,d);break;case c.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}},c.Camera.prototype.constructor=c.Camera,Object.defineProperty(c.Camera.prototype,"x",{get:function(){return this.view.x},set:function(a){this.view.x=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(c.Camera.prototype,"y",{get:function(){return this.view.y},set:function(a){this.view.y=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(c.Camera.prototype,"width",{get:function(){return this.view.width},set:function(a){this.view.width=a}}),Object.defineProperty(c.Camera.prototype,"height",{get:function(){return this.view.height},set:function(a){this.view.height=a}}),c.State=function(){this.game=null,this.add=null,this.camera=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.particles=null,this.physics=null},c.State.prototype={preload:function(){},loadUpdate:function(){},loadRender:function(){},create:function(){},update:function(){},render:function(){},paused:function(){},destroy:function(){}},c.State.prototype.constructor=c.State,c.StateManager=function(a,b){this.game=a,this.states={},this._pendingState=null,"undefined"!=typeof b&&null!==b&&(this._pendingState=b),this._created=!1,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.onShutDownCallback=null},c.StateManager.prototype={boot:function(){this.game.onPause.add(this.pause,this),this.game.onResume.add(this.resume,this),null!==this._pendingState&&("string"==typeof this._pendingState?this.start(this._pendingState,!1,!1):this.add("default",this._pendingState,!0))},add:function(a,b,d){"undefined"==typeof d&&(d=!1);var e;return b instanceof c.State?e=b:"object"==typeof b?(e=b,e.game=this.game):"function"==typeof b&&(e=new b(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.onDestroyCallback=null),delete this.states[a]},start:function(a,b,c){return"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!1),this.game.isBooted===!1?(this._pendingState=a,void 0):(this.checkState(a)!==!1&&(this.current&&this.onShutDownCallback.call(this.callbackContext,this.game),b&&(this.game.tweens.removeAll(),this.game.world.destroy(),c===!0&&this.game.cache.destroy()),this.setCurrentState(a),this.onPreloadCallback?(this.game.load.reset(),this.onPreloadCallback.call(this.callbackContext,this.game),0===this.game.load.totalQueuedFiles()?this.game.loadComplete():this.game.load.start()):this.game.loadComplete()),void 0)},dummy:function(){},checkState:function(a){if(this.states[a]){var b=!1;return this.states[a].preload&&(b=!0),b===!1&&this.states[a].loadRender&&(b=!0),b===!1&&this.states[a].loadUpdate&&(b=!0),b===!1&&this.states[a].create&&(b=!0),b===!1&&this.states[a].update&&(b=!0),b===!1&&this.states[a].preRender&&(b=!0),b===!1&&this.states[a].render&&(b=!0),b===!1&&this.states[a].paused&&(b=!0),b===!1?(console.warn("Invalid Phaser State object given. Must contain at least a one of the required functions."),!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].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].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].physics=this.game.physics,this.states[a].rnd=this.game.rnd},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.onShutDownCallback=this.states[a].shutdown||this.dummy,this.current=a,this._created=!1,this.onInitCallback.call(this.callbackContext,this.game)},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,!0)},resume:function(){this._created&&this.onre&&this.onPausedCallback.call(this.callbackContext,this.game,!1)},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===c.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===c.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.onDestroyCallback=null,this.game=null,this.states={},this._pendingState=null}},c.StateManager.prototype.constructor=c.StateManager,c.LinkedList=function(){this.next=null,this.prev=null,this.first=null,this.last=null,this.total=0},c.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)}}},c.LinkedList.prototype.constructor=c.LinkedList,c.Signal=function(){this._bindings=[],this._prevParams=null;var a=this;this.dispatch=function(){c.Signal.prototype.dispatch.apply(a,arguments)}},c.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,b,d,e){var f,g=this._indexOfListener(a,d);if(-1!==g){if(f=this._bindings[g],f.isOnce()!==b)throw new Error("You cannot add"+(b?"":"Once")+"() then add"+(b?"Once":"")+"() the same listener without removing the relationship first.")}else f=new c.SignalBinding(this,a,b,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()+"]"}},c.Signal.prototype.constructor=c.Signal,c.SignalBinding=function(a,b,c,d,e){this._listener=b,this._isOnce=c,this.context=d,this._signal=a,this._priority=e||0},c.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+"]"}},c.SignalBinding.prototype.constructor=c.SignalBinding,c.Filter=function(a,b,d){this.game=a,this.type=c.WEBGL_FILTER,this.passes=[this],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||[]},c.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}},c.Filter.prototype.constructor=c.Filter,Object.defineProperty(c.Filter.prototype,"width",{get:function(){return this.uniforms.resolution.value.x},set:function(a){this.uniforms.resolution.value.x=a}}),Object.defineProperty(c.Filter.prototype,"height",{get:function(){return this.uniforms.resolution.value.y},set:function(a){this.uniforms.resolution.value.y=a}}),c.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},c.Plugin.prototype={preUpdate:function(){},update:function(){},render:function(){},postRender:function(){},destroy:function(){this.game=null,this.parent=null,this.active=!1,this.visible=!1}},c.Plugin.prototype.constructor=c.Plugin,c.PluginManager=function(a,b){this.game=a,this._parent=b,this.plugins=[],this._pluginsLength=0},c.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._pthis._nextOffsetCheck&&(c.Canvas.getOffset(this.canvas,this.offset),this._nextOffsetCheck=this.game.time.now+this.checkOffsetInterval)},visibilityChange:function(a){this.disableVisibilityChange||(this.game.paused=this.game.paused!==!1||"pagehide"!=a.type&&"blur"!=a.type&&document.hidden!==!0&&document.webkitHidden!==!0?!1:!0)}},c.Stage.prototype.constructor=c.Stage,Object.defineProperty(c.Stage.prototype,"backgroundColor",{get:function(){return this._backgroundColor},set:function(a){this._backgroundColor=a,this.game.transparent===!1&&(this.game.renderType==c.CANVAS?this.game.canvas.style.backgroundColor=a:("string"==typeof a&&(a=c.Color.hexToRGB(a)),this._stage.setBackgroundColor(a)))}}),c.Group=function(a,d,e,f){this.game=a,"undefined"==typeof d&&(d=a.world),this.name=e||"group","undefined"==typeof f&&(f=!1),f?this._container=this.game.stage._stage:(this._container=new b.DisplayObjectContainer,this._container.name=this.name,d?d instanceof c.Group?d._container.addChild(this._container):(d.addChild(this._container),d.updateTransform()):(this.game.stage._stage.addChild(this._container),this.game.stage._stage.updateTransform())),this.type=c.GROUP,this.alive=!0,this.exists=!0,this.group=null,this._container.scale=new c.Point(1,1),this.scale=this._container.scale,this.pivot=this._container.pivot,this.cursor=null},c.Group.RETURN_NONE=0,c.Group.RETURN_TOTAL=1,c.Group.RETURN_CHILD=2,c.Group.SORT_ASCENDING=-1,c.Group.SORT_DESCENDING=1,c.Group.prototype={add:function(a){return a.group!==this&&(a.type&&a.type===c.GROUP?(a.group=this,this._container.addChild(a._container),a._container.updateTransform()):(a.group=this,this._container.addChild(a),a.updateTransform(),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a)),a},addAt:function(a,b){return a.group!==this&&(a.type&&a.type===c.GROUP?(a.group=this,this._container.addChildAt(a._container,b),a._container.updateTransform()):(a.group=this,this._container.addChildAt(a,b),a.updateTransform(),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a)),a},getAt:function(a){return this._container.getChildAt(a)},create:function(a,b,d,e,f){"undefined"==typeof f&&(f=!0);var g=new c.Sprite(this.game,a,b,d,e);return g.group=this,g.exists=f,g.visible=f,g.alive=f,this._container.addChild(g),g.updateTransform(),g.events&&g.events.onAddedToGroup.dispatch(g,this),null===this.cursor&&(this.cursor=g),g},createMultiple:function(a,b,d,e){"undefined"==typeof e&&(e=!1);for(var f=0;a>f;f++){var g=new c.Sprite(this.game,0,0,b,d);g.group=this,g.exists=e,g.visible=e,g.alive=e,this._container.addChild(g),g.updateTransform(),g.events&&g.events.onAddedToGroup.dispatch(g,this),null===this.cursor&&(this.cursor=g)}},next:function(){this.cursor&&(this.cursor=this.cursor==this._container.last?this._container._iNext:this.cursor._iNext)},previous:function(){this.cursor&&(this.cursor=this.cursor==this._container._iNext?this._container.last:this.cursor._iPrev)},childTest:function(a,b){var c=a+" next: ";c+=b._iNext?b._iNext.name:"-null-",c=c+" "+a+" prev: ",c+=b._iPrev?b._iPrev.name:"-null-",console.log(c)},swapIndex:function(a,b){var c=this.getAt(a),d=this.getAt(b);this.swap(c,d)},swap:function(a,b){if(a===b||!a.parent||!b.parent||a.group!==this||b.group!==this)return!1;var c=a._iPrev,d=a._iNext,e=b._iPrev,f=b._iNext,g=this._container.last._iNext,h=this.game.stage._stage;do h!==a&&h!==b&&(h.first===a?h.first=b:h.first===b&&(h.first=a),h.last===a?h.last=b:h.last===b&&(h.last=a)),h=h._iNext;while(h!=g);return a._iNext==b?(a._iNext=f,a._iPrev=b,b._iNext=a,b._iPrev=c,c&&(c._iNext=b),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):b._iNext==a?(a._iNext=b,a._iPrev=e,b._iNext=d,b._iPrev=a,e&&(e._iNext=a),d&&(d._iPrev=b),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):(a._iNext=f,a._iPrev=e,b._iNext=d,b._iPrev=c,c&&(c._iNext=b),d&&(d._iPrev=b),e&&(e._iNext=a),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0)},bringToTop:function(a){return a.group===this&&(this.remove(a),this.add(a)),a},getIndex:function(a){return this._container.children.indexOf(a)},replace:function(a,b){if(this._container.first._iNext){var c=this.getIndex(a);-1!=c&&(void 0!==b.parent&&(b.events.onRemovedFromGroup.dispatch(b,this),b.parent.removeChild(b)),this._container.removeChild(a),this._container.addChildAt(b,c),b.events.onAddedToGroup.dispatch(b,this),b.updateTransform(),this.cursor==a&&(this.cursor=this._container._iNext))}},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))},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)},setAll:function(a,b,c,d,e){if(a=a.split("."),"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),e=e||0,this._container.children.length>0&&this._container.first._iNext){var f=this._container.first._iNext;do(c===!1||c&&f.alive)&&(d===!1||d&&f.visible)&&this.setProperty(f,a,b,e),f=f._iNext;while(f!=this._container.last._iNext)}},addAll:function(a,b,c,d){this.setAll(a,b,c,d,1)},subAll:function(a,b,c,d){this.setAll(a,b,c,d,2)},multiplyAll:function(a,b,c,d){this.setAll(a,b,c,d,3)},divideAll:function(a,b,c,d){this.setAll(a,b,c,d,4)},callAllExists:function(a,b){var c=Array.prototype.splice.call(arguments,2);if(this._container.children.length>0&&this._container.first._iNext){var d=this._container.first._iNext;do d.exists==b&&d[a]&&d[a].apply(d,c),d=d._iNext;while(d!=this._container.last._iNext)}},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},callAll:function(a,b){if("undefined"!=typeof a){a=a.split(".");var c=a.length;if("undefined"==typeof b)b=null;else if("string"==typeof b){b=b.split(".");var d=b.length}var e=Array.prototype.splice.call(arguments,2),f=null,g=null;if(this._container.children.length>0&&this._container.first._iNext){var h=this._container.first._iNext;do f=this.callbackFromArray(h,a,c),b&&f?(g=this.callbackFromArray(h,b,d),f&&f.apply(g,e)):f&&f.apply(h,e),h=h._iNext;while(h!=this._container.last._iNext)}}},forEach:function(a,b,c){"undefined"==typeof c&&(c=!1);var d=Array.prototype.splice.call(arguments,3);if(d.unshift(null),this._container.children.length>0&&this._container.first._iNext){var e=this._container.first._iNext;do(c===!1||c&&e.exists)&&(d[0]=e,a.apply(b,d)),e=e._iNext;while(e!=this._container.last._iNext)}},forEachExists:function(a,b){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("exists",!0,c.Group.RETURN_TOTAL,a,b,d)},forEachAlive:function(a,b){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!0,c.Group.RETURN_TOTAL,a,b,d)},forEachDead:function(a,b){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!1,c.Group.RETURN_TOTAL,a,b,d)},sort:function(a,b){"undefined"==typeof a&&(a="y"),"undefined"==typeof b&&(b=c.Group.SORT_ASCENDING);var d,e;do{d=!1;for(var f=0,g=this._container.children.length-1;g>f;f++)b==c.Group.SORT_ASCENDING?this._container.children[f][a]>this._container.children[f+1][a]&&(this.swap(this.getAt(f),this.getAt(f+1)),e=this._container.children[f],this._container.children[f]=this._container.children[f+1],this._container.children[f+1]=e,d=!0):this._container.children[f][a]0&&this._container.first._iNext){var i=this._container.first._iNext;do{if(i[a]===b&&(h++,e&&(g[0]=i,e.apply(f,g)),d===c.Group.RETURN_CHILD))return i;i=i._iNext}while(i!=this._container.last._iNext)}return d===c.Group.RETURN_TOTAL?h:d===c.Group.RETURN_CHILD?null:void 0},getFirstExists:function(a){return"boolean"!=typeof a&&(a=!0),this.iterate("exists",a,c.Group.RETURN_CHILD)},getFirstAlive:function(){return this.iterate("alive",!0,c.Group.RETURN_CHILD)},getFirstDead:function(){return this.iterate("alive",!1,c.Group.RETURN_CHILD)},countLiving:function(){return this.iterate("alive",!0,c.Group.RETURN_TOTAL)},countDead:function(){return this.iterate("alive",!1,c.Group.RETURN_TOTAL)},getRandom:function(a,b){return 0===this._container.children.length?null:(a=a||0,b=b||this._container.children.length,this.game.math.getRandom(this._container.children,a,b))},remove:function(a){return a.group!==this?!1:(a.events&&a.events.onRemovedFromGroup.dispatch(a,this),a.parent===this._container&&this._container.removeChild(a),this.cursor==a&&(this.cursor=this._container._iNext?this._container._iNext:null),a.group=null,!0)},removeAll:function(){if(0!==this._container.children.length){do this._container.children[0].events&&this._container.children[0].events.onRemovedFromGroup.dispatch(this._container.children[0],this),this._container.removeChild(this._container.children[0]);while(this._container.children.length>0);this.cursor=null}},removeBetween:function(a,b){if(0!==this._container.children.length){if(a>b||0>a||b>this._container.children.length)return!1;for(var c=a;b>c;c++){var d=this._container.children[c];d.events.onRemovedFromGroup.dispatch(d,this),this._container.removeChild(d),this.cursor==d&&(this.cursor=this._container._iNext?this._container._iNext:null)}}},destroy:function(a){if("undefined"==typeof a&&(a=!1),a){if(this._container.children.length>0)do this._container.children[0].group&&this._container.children[0].destroy();while(this._container.children.length>0)}else this.removeAll();this._container.parent.removeChild(this._container),this._container=null,this.game=null,this.exists=!1,this.cursor=null},validate:function(){var a=this.game.stage._stage.last._iNext,b=this.game.stage._stage,c=null,d=null,e=0;do{if(e>0){if(b!==c)return console.log("check next fail"),!1;if(b._iPrev!==d)return console.log("check previous fail"),!1}c=b._iNext,d=b,b=b._iNext,e++}while(b!=a);return!0}},c.Group.prototype.constructor=c.Group,Object.defineProperty(c.Group.prototype,"total",{get:function(){return this._container?this.iterate("exists",!0,c.Group.RETURN_TOTAL):0}}),Object.defineProperty(c.Group.prototype,"length",{get:function(){return this._container?this._container.children.length:0}}),Object.defineProperty(c.Group.prototype,"x",{get:function(){return this._container.position.x},set:function(a){this._container.position.x=a}}),Object.defineProperty(c.Group.prototype,"y",{get:function(){return this._container.position.y},set:function(a){this._container.position.y=a}}),Object.defineProperty(c.Group.prototype,"angle",{get:function(){return c.Math.radToDeg(this._container.rotation)},set:function(a){this._container.rotation=c.Math.degToRad(a)}}),Object.defineProperty(c.Group.prototype,"rotation",{get:function(){return this._container.rotation},set:function(a){this._container.rotation=a}}),Object.defineProperty(c.Group.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(c.Group.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),c.World=function(a){c.Group.call(this,a,null,"__world",!1),this.bounds=new c.Rectangle(0,0,a.width,a.height),this.camera=null,this.currentRenderOrderID=0},c.World.prototype=Object.create(c.Group.prototype),c.World.prototype.constructor=c.World,c.World.prototype.boot=function(){this.camera=new c.Camera(this.game,0,0,0,this.game.width,this.game.height),this.camera.displayObject=this._container,this.game.camera=this.camera},c.World.prototype.preUpdate=function(){if(this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a=a.preUpdate&&!a.preUpdate()?a.last._iNext:a._iNext;while(a!=this.game.stage._stage.last._iNext)}},c.World.prototype.update=function(){if(this.currentRenderOrderID=0,this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a=a.update&&!a.update()?a.last._iNext:a._iNext;while(a!=this.game.stage._stage.last._iNext)}},c.World.prototype.postUpdate=function(){if(this.camera.target&&this.camera.target.postUpdate){if(this.camera.target.postUpdate(),this.camera.update(),this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a.postUpdate&&a!==this.camera.target&&a.postUpdate(),a=a._iNext;while(a!=this.game.stage._stage.last._iNext)}}else if(this.camera.update(),this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a.postUpdate&&a.postUpdate(),a=a._iNext;while(a!=this.game.stage._stage.last._iNext)}},c.World.prototype.setBounds=function(a,b,c,d){c0;b--)null===this["pointer"+b]&&(a=b);return 0===a?(console.warn("You can only have 10 Pointer objects"),null):(this["pointer"+a]=new c.Pointer(this.game,a),this["pointer"+a])},update:function(){return this.pollRate>0&&this._pollCounter=b;b++)this["pointer"+b]&&this["pointer"+b].reset();this.currentPointers=0,"none"!==this.game.canvas.style.cursor&&(this.game.canvas.style.cursor="default"),a===!0&&(this.onDown.dispose(),this.onUp.dispose(),this.onTap.dispose(),this.onHold.dispose(),this.onDown=new c.Signal,this.onUp=new c.Signal,this.onTap=new c.Signal,this.onHold=new c.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}},c.Input.prototype.constructor=c.Input,Object.defineProperty(c.Input.prototype,"x",{get:function(){return this._x},set:function(a){this._x=Math.floor(a)}}),Object.defineProperty(c.Input.prototype,"y",{get:function(){return this._y},set:function(a){this._y=Math.floor(a)}}),Object.defineProperty(c.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(c.Input.prototype,"worldX",{get:function(){return this.game.camera.view.x+this.x}}),Object.defineProperty(c.Input.prototype,"worldY",{get:function(){return this.game.camera.view.y+this.y}}),c.Key=function(a,b){this.game=a,this.isDown=!1,this.isUp=!1,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.timeDown=0,this.duration=0,this.timeUp=0,this.repeats=0,this.keyCode=b,this.onDown=new c.Signal,this.onUp=new c.Signal},c.Key.prototype={processKeyDown:function(a){this.altKey=a.altKey,this.ctrlKey=a.ctrlKey,this.shiftKey=a.shiftKey,this.isDown?(this.duration=a.timeStamp-this.timeDown,this.repeats++):(this.isDown=!0,this.isUp=!1,this.timeDown=a.timeStamp,this.duration=0,this.repeats=0,this.onDown.dispatch(this))},processKeyUp:function(a){this.isDown=!1,this.isUp=!0,this.timeUp=a.timeStamp,this.onUp.dispatch(this)},justPressed:function(a){return"undefined"==typeof a&&(a=250),this.isDown&&this.duration=this.game.input.holdRate&&((this.game.input.multiInputOverride==c.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==c.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==c.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){if(!this.game.input.pollLocked){if("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==c.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==c.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==c.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=-1,this._highestRenderObject=null,this._highestInputPriorityID=-1,this.game.input.interactiveItems.total>0){var b=this.game.input.interactiveItems.next;do(b.pixelPerfect||b.priorityID>this._highestInputPriorityID||b.priorityID==this._highestInputPriorityID&&b.sprite.renderOrderID>this._highestRenderOrderID)&&b.checkPointerOver(this)&&(this._highestRenderOrderID=b.sprite.renderOrderID,this._highestInputPriorityID=b.priorityID,this._highestRenderObject=b),b=b.next;while(null!=b)}return null==this._highestRenderObject?this.targetObject&&(this.targetObject._pointerOutHandler(this),this.targetObject=null):null==this.targetObject?(this.targetObject=this._highestRenderObject,this._highestRenderObject._pointerOverHandler(this)):this.targetObject==this._highestRenderObject?this._highestRenderObject.update(this)===!1&&(this.targetObject=null):(this.targetObject._pointerOutHandler(this),this.targetObject=this._highestRenderObject,this.targetObject._pointerOverHandler(this)),this}},leave:function(a){this.withinGame=!1,this.move(a)},stop:function(a){if(this._stateReset)return a.preventDefault(),void 0;if(this.timeUp=this.game.time.now,(this.game.input.multiInputOverride==c.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==c.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==c.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.onUp.dispatch(this,a),this.duration>=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 b=this.game.input.interactiveItems.next;do b&&b._releasedHandler(this),b=b.next;while(null!=b)}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}},c.Pointer.prototype.constructor=c.Pointer,Object.defineProperty(c.Pointer.prototype,"duration",{get:function(){return this.isUp?-1:this.game.time.now-this.timeDown}}),Object.defineProperty(c.Pointer.prototype,"worldX",{get:function(){return this.game.world.camera.x+this.x}}),Object.defineProperty(c.Pointer.prototype,"worldY",{get:function(){return this.game.world.camera.y+this.y}}),c.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},c.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.renderer.view.addEventListener("touchstart",this._onTouchStart,!1),this.game.renderer.view.addEventListener("touchmove",this._onTouchMove,!1),this.game.renderer.view.addEventListener("touchend",this._onTouchEnd,!1),this.game.renderer.view.addEventListener("touchenter",this._onTouchEnter,!1),this.game.renderer.view.addEventListener("touchleave",this._onTouchLeave,!1),this.game.renderer.view.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;bd;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 c.Point,this.enabled=!0,this.sprite.events&&null==this.sprite.events.onInputOver&&(this.sprite.events.onInputOver=new c.Signal,this.sprite.events.onInputOut=new c.Signal,this.sprite.events.onInputDown=new c.Signal,this.sprite.events.onInputUp=new c.Signal,this.sprite.events.onDragStart=new c.Signal,this.sprite.events.onDragStop=new c.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.stop(),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},checkPointerOver:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?!1:(this.sprite.getLocalUnmodifiedPosition(this._tempPoint,a.x,a.y),this._tempPoint.x>=0&&this._tempPoint.x<=this.sprite.currentFrame.width&&this._tempPoint.y>=0&&this._tempPoint.y<=this.sprite.currentFrame.height?this.pixelPerfect?this.checkPixel(this._tempPoint.x,this._tempPoint.y):!0:void 0)},checkPixel:function(a,b){if(this.sprite.texture.baseTexture.source){this.game.input.hitContext.clearRect(0,0,1,1),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 c=this.game.input.hitContext.getImageData(0,0,1,1);if(c.data[3]>=this.pixelPerfectAlpha)return!0}return!1},update:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?(this._pointerOutHandler(a),!1):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},_pointerOverHandler:function(a){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){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){return this._pointerData[a.id].isDown===!1&&this._pointerData[a.id].isOver===!0&&(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()),this.consumePointerEvent},_releasedHandler:function(a){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.sprite.events.onInputUp.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){"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!1),"undefined"==typeof snapOffsetX&&(snapOffsetX=0),"undefined"==typeof snapOffsetY&&(snapOffsetY=0),this.snapX=a,this.snapY=b,this.snapOffsetX=snapOffsetX,this.snapOffsetY=snapOffsetY,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))}},c.InputHandler.prototype.constructor=c.InputHandler,c.Gamepad=function(a){this.game=a,this._gamepads=[new c.SinglePad(a,this),new c.SinglePad(a,this),new c.SinglePad(a,this),new c.SinglePad(a,this)],this._gamepadIndexMap={},this._rawPads=[],this._active=!1,this.disabled=!1,this._gamepadSupportAvailable=!!navigator.webkitGetGamepads||!!navigator.webkitGamepads||-1!=navigator.userAgent.indexOf("Firefox/"),this._prevRawGamepadTypes=[],this._prevTimestamps=[],this.callbackContext=this,this.onConnectCallback=null,this.onDisconnectCallback=null,this.onDownCallback=null,this.onUpCallback=null,this.onAxisCallback=null,this.onFloatCallback=null,this._ongamepadconnected=null,this._gamepaddisconnected=null},c.Gamepad.prototype={addCallbacks:function(a,b){"undefined"!=typeof b&&(this.onConnectCallback="function"==typeof b.onConnect?b.onConnect:this.onConnectCallback,this.onDisconnectCallback="function"==typeof b.onDisconnect?b.onDisconnect:this.onDisconnectCallback,this.onDownCallback="function"==typeof b.onDown?b.onDown:this.onDownCallback,this.onUpCallback="function"==typeof b.onUp?b.onUp:this.onUpCallback,this.onAxisCallback="function"==typeof b.onAxis?b.onAxis:this.onAxisCallback,this.onFloatCallback="function"==typeof b.onFloat?b.onFloat:this.onFloatCallback)},start:function(){this._active=!0;var a=this;this._ongamepadconnected=function(b){var c=b.gamepad;a._rawPads.push(c),a._gamepads[c.index].connect(c)},window.addEventListener("gamepadconnected",this._ongamepadconnected,!1),this._ongamepaddisconnected=function(b){var c=b.gamepad;for(var d in a._rawPads)a._rawPads[d].index===c.index&&a._rawPads.splice(d,1);a._gamepads[c.index].disconnect()},window.addEventListener("gamepaddisconnected",this._ongamepaddisconnected,!1)
+},update:function(){this._pollGamepads();for(var a=0;a0&&e>this.deadZone||0>e&&e<-this.deadZone?this.processAxisChange({axis:d,value:e}):this.processAxisChange({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].timeUp=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)},arc:function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=!1),this._dirty=!0,this.context.arc(a,b,c,d,e,f),this},arcTo:function(a,b,c,d,e){return this._dirty=!0,this.context.arcTo(a,b,c,d,e),this},beginFill:function(a){return this.fillStyle(a),this},beginLinearGradientFill:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.fillStyle(g),this},beginLinearGradientStroke:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.strokeStyle(g),this},beginRadialGradientStroke:function(a,b,c,d,e,f,g,h){for(var i=this.createRadialGradient(c,d,e,f,g,h),j=0,k=a.length;k>j;j++)i.addColorStop(b[j],a[j]);return this.strokeStyle(i),this},beginPath:function(){return this.context.beginPath(),this},beginStroke:function(a){return this.strokeStyle(a),this},bezierCurveTo:function(a,b,c,d,e,f){return this._dirty=!0,this.context.bezierCurveTo(a,b,c,d,e,f),this},circle:function(a,b,c){return this.arc(a,b,c,0,2*Math.PI),this},clearRect:function(a,b,c,d){return this._dirty=!0,this.context.clearRect(a,b,c,d),this},clip:function(){return this._dirty=!0,this.context.clip(),this},closePath:function(){return this._dirty=!0,this.context.closePath(),this},createLinearGradient:function(a,b,c,d){return this.context.createLinearGradient(a,b,c,d)},createRadialGradient:function(a,b,c,d,e,f){return this.context.createRadialGradient(a,b,c,d,e,f)},ellipse:function(a,b,c,d){var e=.5522848,f=c/2*e,g=d/2*e,h=a+c,i=b+d,j=a+c/2,k=b+d/2;return this.moveTo(a,k),this.bezierCurveTo(a,k-g,j-f,b,j,b),this.bezierCurveTo(j+f,b,h,k-g,h,k),this.bezierCurveTo(h,k+g,j+f,i,j,i),this.bezierCurveTo(j-f,i,a,k+g,a,k),this},fill:function(){return this._dirty=!0,this.context.fill(),this},fillRect:function(a,b,c,d){return this._dirty=!0,this.context.fillRect(a,b,c,d),this},fillStyle:function(a){return this.context.fillStyle=a,this},font:function(a){return this.context.font=a,this},globalAlpha:function(a){return this.context.globalAlpha=a,this},globalCompositeOperation:function(a){return this.context.globalCompositeOperation=a,this},lineCap:function(a){return this.context.lineCap=a,this},lineDashOffset:function(a){return this.context.lineDashOffset=a,this},lineJoin:function(a){return this.context.lineJoin=a,this},lineWidth:function(a){return this.context.lineWidth=a,this},miterLimit:function(a){return this.context.miterLimit=a,this},lineTo:function(a,b){return this._dirty=!0,this.context.lineTo(a,b),this},moveTo:function(a,b){return this.context.moveTo(a,b),this},quadraticCurveTo:function(a,b,c,d){return this._dirty=!0,this.context.quadraticCurveTo(a,b,c,d),this},rect:function(a,b,c,d){return this._dirty=!0,this.context.rect(a,b,c,d),this},restore:function(){return this._dirty=!0,this.context.restore(),this},rotate:function(a){return this._dirty=!0,this.context.rotate(a),this},setStrokeStyle:function(a,b,c,d,e){return"undefined"==typeof a&&(a=1),"undefined"==typeof b&&(b="butt"),"undefined"==typeof c&&(c="miter"),"undefined"==typeof d&&(d=10),e=!1,this.lineWidth(a),this.lineCap(b),this.lineJoin(c),this.miterLimit(d),this},save:function(){return this._dirty=!0,this.context.save(),this},scale:function(a,b){return this._dirty=!0,this.context.scale(a,b),this},scrollPathIntoView:function(){return this._dirty=!0,this.context.scrollPathIntoView(),this},stroke:function(){return this._dirty=!0,this.context.stroke(),this},strokeRect:function(a,b,c,d){return this._dirty=!0,this.context.strokeRect(a,b,c,d),this},strokeStyle:function(a){return this.context.strokeStyle=a,this},render:function(){this._dirty&&(this.game.renderType==c.WEBGL&&b.texturesToUpdate.push(this.baseTexture),this._dirty=!1)}},c.BitmapData.prototype.constructor=c.BitmapData,c.BitmapData.prototype.mt=c.BitmapData.prototype.moveTo,c.BitmapData.prototype.lt=c.BitmapData.prototype.lineTo,c.BitmapData.prototype.at=c.BitmapData.prototype.arcTo,c.BitmapData.prototype.bt=c.BitmapData.prototype.bezierCurveTo,c.BitmapData.prototype.qt=c.BitmapData.prototype.quadraticCurveTo,c.BitmapData.prototype.a=c.BitmapData.prototype.arc,c.BitmapData.prototype.r=c.BitmapData.prototype.rect,c.BitmapData.prototype.cp=c.BitmapData.prototype.closePath,c.BitmapData.prototype.c=c.BitmapData.prototype.clear,c.BitmapData.prototype.f=c.BitmapData.prototype.beginFill,c.BitmapData.prototype.lf=c.BitmapData.prototype.beginLinearGradientFill,c.BitmapData.prototype.rf=c.BitmapData.prototype.beginRadialGradientFill,c.BitmapData.prototype.ef=c.BitmapData.prototype.endFill,c.BitmapData.prototype.ss=c.BitmapData.prototype.setStrokeStyle,c.BitmapData.prototype.s=c.BitmapData.prototype.beginStroke,c.BitmapData.prototype.ls=c.BitmapData.prototype.beginLinearGradientStroke,c.BitmapData.prototype.rs=c.BitmapData.prototype.beginRadialGradientStroke,c.BitmapData.prototype.dr=c.BitmapData.prototype.rect,c.BitmapData.prototype.dc=c.BitmapData.prototype.circle,c.BitmapData.prototype.de=c.BitmapData.prototype.ellipse,c.Sprite=function(a,d,e,f,g){d=d||0,e=e||0,f=f||null,g=g||null,this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=c.SPRITE,this.renderOrderID=-1,this.lifespan=0,this.events=new c.Events(this),this.animations=new c.AnimationManager(this),this.input=new c.InputHandler(this),this.key=f,this.currentFrame=null,f instanceof c.RenderTexture?(b.Sprite.call(this,f),this.currentFrame=this.game.cache.getTextureFrame(f.name)):f instanceof c.BitmapData?(b.Sprite.call(this,f.texture,f.textureFrame),this.currentFrame=f.textureFrame):f instanceof b.Texture?(b.Sprite.call(this,f),this.currentFrame=g):(null===f||"undefined"==typeof f?(f="__default",this.key=f):"string"==typeof f&&this.game.cache.checkImageKey(f)===!1&&(f="__missing",this.key=f),b.Sprite.call(this,b.TextureCache[f]),this.game.cache.isSpriteSheet(f)?(this.animations.loadFrameData(this.game.cache.getFrameData(f)),null!==g&&("string"==typeof g?this.frameName=g:this.frame=g)):this.currentFrame=this.game.cache.getFrame(f)),this.textureRegion=new c.Rectangle(this.texture.frame.x,this.texture.frame.y,this.texture.frame.width,this.texture.frame.height),this.anchor=new c.Point,this.x=d,this.y=e,this.position.x=d,this.position.y=e,this.world=new c.Point(d,e),this.autoCull=!1,this.scale=new c.Point(1,1),this._cache={fresh:!0,dirty:!1,a00:-1,a01:-1,a02:-1,a10:-1,a11:-1,a12:-1,id:-1,i01:-1,i10:-1,idi:-1,left:null,right:null,top:null,bottom:null,prevX:d,prevY:e,x:-1,y:-1,scaleX:1,scaleY:1,width:this.currentFrame.sourceSizeW,height:this.currentFrame.sourceSizeH,halfWidth:Math.floor(this.currentFrame.sourceSizeW/2),halfHeight:Math.floor(this.currentFrame.sourceSizeH/2),calcWidth:-1,calcHeight:-1,frameID:-1,frameWidth:this.currentFrame.width,frameHeight:this.currentFrame.height,cameraVisible:!0,cropX:0,cropY:0,cropWidth:this.currentFrame.sourceSizeW,cropHeight:this.currentFrame.sourceSizeH},this.offset=new c.Point,this.center=new c.Point(d+Math.floor(this._cache.width/2),e+Math.floor(this._cache.height/2)),this.topLeft=new c.Point(d,e),this.topRight=new c.Point(d+this._cache.width,e),this.bottomRight=new c.Point(d+this._cache.width,e+this._cache.height),this.bottomLeft=new c.Point(d,e+this._cache.height),this.bounds=new c.Rectangle(d,e,this._cache.width,this._cache.height),this.body=new c.Physics.Arcade.Body(this),this.health=1,this.inWorld=c.Rectangle.intersects(this.bounds,this.game.world.bounds),this.inWorldThreshold=0,this.outOfBoundsKill=!1,this._outOfBoundsFired=!1,this.fixedToCamera=!1,this.cameraOffset=new c.Point(d,e),this.crop=new c.Rectangle(0,0,this._cache.width,this._cache.height),this.cropEnabled=!1,this.debug=!1,this.updateCache(),this.updateBounds()},c.Sprite.prototype=Object.create(b.Sprite.prototype),c.Sprite.prototype.constructor=c.Sprite,c.Sprite.prototype.preUpdate=function(){return this._cache.fresh?(this.world.setTo(this.parent.position.x+this.x,this.parent.position.y+this.y),this.worldTransform[2]=this.world.x,this.worldTransform[5]=this.world.y,this._cache.fresh=!1,this.body&&(this.body.x=this.world.x-this.anchor.x*this.width+this.body.offset.x,this.body.y=this.world.y-this.anchor.y*this.height+this.body.offset.y,this.body.preX=this.body.x,this.body.preY=this.body.y),void 0):!this.exists||this.group&&!this.group.exists?(this.renderOrderID=-1,!1):this.lifespan>0&&(this.lifespan-=this.game.time.elapsed,this.lifespan<=0)?(this.kill(),!1):(this._cache.dirty=!1,this.visible&&(this.renderOrderID=this.game.world.currentRenderOrderID++),this.updateCache(),this.updateAnimation(),this.updateCrop(),(this._cache.dirty||this.world.x!==this._cache.prevX||this.world.y!==this._cache.prevY)&&this.updateBounds(),this.body&&this.body.preUpdate(),!0)},c.Sprite.prototype.updateCache=function(){this._cache.prevX=this.world.x,this._cache.prevY=this.world.y,this.fixedToCamera&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),(this.worldTransform[1]!=this._cache.i01||this.worldTransform[3]!=this._cache.i10||this.worldTransform[0]!=this._cache.a00||this.worldTransform[41]!=this._cache.a11)&&(this._cache.a00=this.worldTransform[0],this._cache.a01=this.worldTransform[1],this._cache.a10=this.worldTransform[3],this._cache.a11=this.worldTransform[4],this._cache.i01=this.worldTransform[1],this._cache.i10=this.worldTransform[3],this._cache.scaleX=Math.sqrt(this._cache.a00*this._cache.a00+this._cache.a01*this._cache.a01),this._cache.scaleY=Math.sqrt(this._cache.a10*this._cache.a10+this._cache.a11*this._cache.a11),this._cache.a01*=-1,this._cache.a10*=-1,this._cache.id=1/(this._cache.a00*this._cache.a11+this._cache.a01*-this._cache.a10),this._cache.idi=1/(this._cache.a00*this._cache.a11+this._cache.i01*-this._cache.i10),this._cache.dirty=!0),this._cache.a02=this.worldTransform[2],this._cache.a12=this.worldTransform[5]},c.Sprite.prototype.updateAnimation=function(){(this.animations.update()||this.currentFrame&&this.currentFrame.uuid!=this._cache.frameID)&&(this._cache.frameID=this.currentFrame.uuid,this._cache.frameWidth=this.texture.frame.width,this._cache.frameHeight=this.texture.frame.height,this._cache.width=this.currentFrame.width,this._cache.height=this.currentFrame.height,this._cache.halfWidth=Math.floor(this._cache.width/2),this._cache.halfHeight=Math.floor(this._cache.height/2),this._cache.dirty=!0)},c.Sprite.prototype.updateCrop=function(){!this.cropEnabled||this.crop.width==this._cache.cropWidth&&this.crop.height==this._cache.cropHeight&&this.crop.x==this._cache.cropX&&this.crop.y==this._cache.cropY||(this.crop.floorAll(),this._cache.cropX=this.crop.x,this._cache.cropY=this.crop.y,this._cache.cropWidth=this.crop.width,this._cache.cropHeight=this.crop.height,this.texture.frame=this.crop,this.texture.width=this.crop.width,this.texture.height=this.crop.height,this.texture.updateFrame=!0,b.Texture.frameUpdates.push(this.texture))},c.Sprite.prototype.updateBounds=function(){this.offset.setTo(this._cache.a02-this.anchor.x*this.width,this._cache.a12-this.anchor.y*this.height),this.getLocalPosition(this.center,this.offset.x+this.width/2,this.offset.y+this.height/2),this.getLocalPosition(this.topLeft,this.offset.x,this.offset.y),this.getLocalPosition(this.topRight,this.offset.x+this.width,this.offset.y),this.getLocalPosition(this.bottomLeft,this.offset.x,this.offset.y+this.height),this.getLocalPosition(this.bottomRight,this.offset.x+this.width,this.offset.y+this.height),this._cache.left=c.Math.min(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.right=c.Math.max(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.top=c.Math.min(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this._cache.bottom=c.Math.max(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this.bounds.setTo(this._cache.left,this._cache.top,this._cache.right-this._cache.left,this._cache.bottom-this._cache.top),this.updateFrame=!0,this.inWorld===!1?(this.inWorld=c.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld&&(this._outOfBoundsFired=!1)):(this.inWorld=c.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld===!1&&(this.events.onOutOfBounds.dispatch(this),this._outOfBoundsFired=!0,this.outOfBoundsKill&&this.kill())),this._cache.cameraVisible=c.Rectangle.intersects(this.game.world.camera.screenView,this.bounds,0),this.autoCull&&(this.renderable=this._cache.cameraVisible)},c.Sprite.prototype.getLocalPosition=function(a,b,c){return a.x=(this._cache.a11*this._cache.id*b+-this._cache.a01*this._cache.id*c+(this._cache.a12*this._cache.a01-this._cache.a02*this._cache.a11)*this._cache.id)*this.scale.x+this._cache.a02,a.y=(this._cache.a00*this._cache.id*c+-this._cache.a10*this._cache.id*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.a10)*this._cache.id)*this.scale.y+this._cache.a12,a},c.Sprite.prototype.getLocalUnmodifiedPosition=function(a,b,c){return a.x=this._cache.a11*this._cache.idi*b+-this._cache.i01*this._cache.idi*c+(this._cache.a12*this._cache.i01-this._cache.a02*this._cache.a11)*this._cache.idi+this.anchor.x*this._cache.width,a.y=this._cache.a00*this._cache.idi*c+-this._cache.i10*this._cache.idi*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.i10)*this._cache.idi+this.anchor.y*this._cache.height,a},c.Sprite.prototype.resetCrop=function(){this.crop=new c.Rectangle(0,0,this._cache.width,this._cache.height),this.texture.setFrame(this.crop),this.cropEnabled=!1},c.Sprite.prototype.postUpdate=function(){this.key instanceof c.BitmapData&&this.key._dirty&&this.key.render(),this.exists&&(this.body&&this.body.postUpdate(),this.fixedToCamera?(this._cache.x=this.game.camera.view.x+this.cameraOffset.x,this._cache.y=this.game.camera.view.y+this.cameraOffset.y):(this._cache.x=this.x,this._cache.y=this.y),this.position.x=this._cache.x,this.position.y=this._cache.y)},c.Sprite.prototype.loadTexture=function(a,d){this.key=a,a instanceof c.RenderTexture?this.currentFrame=this.game.cache.getTextureFrame(a.name):a instanceof c.BitmapData?(this.setTexture(a.texture),this.currentFrame=a.textureFrame):a instanceof b.Texture?this.currentFrame=d:(("undefined"==typeof a||this.game.cache.checkImageKey(a)===!1)&&(a="__default",this.key=a),this.game.cache.isSpriteSheet(a)?(this.animations.loadFrameData(this.game.cache.getFrameData(a)),"undefined"!=typeof d&&("string"==typeof d?this.frameName=d:this.frame=d)):(this.currentFrame=this.game.cache.getFrame(a),this.setTexture(b.TextureCache[a])))},c.Sprite.prototype.centerOn=function(a,b){return this.fixedToCamera?(this.cameraOffset.x=a+(this.cameraOffset.x-this.center.x),this.cameraOffset.y=b+(this.cameraOffset.y-this.center.y)):(this.x=a+(this.x-this.center.x),this.y=b+(this.y-this.center.y)),this},c.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},c.Sprite.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},c.Sprite.prototype.destroy=function(){this.filters&&(this.filters=null),this.group&&this.group.remove(this),this.input&&this.input.destroy(),this.events&&this.events.destroy(),this.animations&&this.animations.destroy(),this.body&&this.body.destroy(),this.alive=!1,this.exists=!1,this.visible=!1,this.game=null},c.Sprite.prototype.damage=function(a){return this.alive&&(this.health-=a,this.health<0&&this.kill()),this},c.Sprite.prototype.reset=function(a,b,c){return"undefined"==typeof c&&(c=1),this.x=a,this.y=b,this.world.setTo(a,b),this.position.x=this.x,this.position.y=this.y,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this._outOfBoundsFired=!1,this.health=c,this.body&&this.body.reset(!1),this},c.Sprite.prototype.bringToTop=function(){return this.group?this.group.bringToTop(this):this.game.world.bringToTop(this),this},c.Sprite.prototype.play=function(a,b,c,d){return this.animations?this.animations.play(a,b,c,d):void 0},Object.defineProperty(c.Sprite.prototype,"deltaX",{get:function(){return this.world.x-this._cache.prevX}}),Object.defineProperty(c.Sprite.prototype,"deltaY",{get:function(){return this.world.y-this._cache.prevY}}),Object.defineProperty(c.Sprite.prototype,"angle",{get:function(){return c.Math.wrapAngle(c.Math.radToDeg(this.rotation))},set:function(a){this.rotation=c.Math.degToRad(c.Math.wrapAngle(a))}}),Object.defineProperty(c.Sprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(c.Sprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(c.Sprite.prototype,"inCamera",{get:function(){return this._cache.cameraVisible}}),Object.defineProperty(c.Sprite.prototype,"worldCenterX",{get:function(){return this.game.camera.x+this.center.x}}),Object.defineProperty(c.Sprite.prototype,"worldCenterY",{get:function(){return this.game.camera.y+this.center.y}}),Object.defineProperty(c.Sprite.prototype,"width",{get:function(){return this.scale.x*this.currentFrame.width},set:function(a){this.scale.x=a/this.currentFrame.width,this._cache.scaleX=a/this.currentFrame.width,this._width=a}}),Object.defineProperty(c.Sprite.prototype,"height",{get:function(){return this.scale.y*this.currentFrame.height},set:function(a){this.scale.y=a/this.currentFrame.height,this._cache.scaleY=a/this.currentFrame.height,this._height=a}}),Object.defineProperty(c.Sprite.prototype,"inputEnabled",{get:function(){return this.input.enabled},set:function(a){a?this.input.enabled===!1&&this.input.start():this.input.enabled&&this.input.stop()}}),c.TileSprite=function(a,d,e,f,g,h){d=d||0,e=e||0,f=f||256,g=g||256,h=h||null,c.Sprite.call(this,a,d,e,h),this.texture=b.TextureCache[h],b.TilingSprite.call(this,this.texture,f,g),this.type=c.TILESPRITE,this.tileScale=new c.Point(1,1),this.tilePosition=new c.Point(0,0),this.body.width=f,this.body.height=g
+},c.TileSprite.prototype=c.Utils.extend(!0,b.TilingSprite.prototype,c.Sprite.prototype),c.TileSprite.prototype.constructor=c.TileSprite,Object.defineProperty(c.TileSprite.prototype,"angle",{get:function(){return c.Math.wrapAngle(c.Math.radToDeg(this.rotation))},set:function(a){this.rotation=c.Math.degToRad(c.Math.wrapAngle(a))}}),Object.defineProperty(c.TileSprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(c.TileSprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(c.TileSprite.prototype,"inCamera",{get:function(){return this._cache.cameraVisible}}),Object.defineProperty(c.TileSprite.prototype,"inputEnabled",{get:function(){return this.input.enabled},set:function(a){a?this.input.enabled===!1&&this.input.start():this.input.enabled&&this.input.stop()}}),c.Text=function(a,d,e,f,g){d=d||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=c.TEXT,this._text=f,this._style=g,b.Text.call(this,f,g),this.position.x=this.x=d,this.position.y=this.y=e,this.anchor=new c.Point,this.scale=new c.Point(1,1),this.fixedToCamera=!1,this.cameraOffset=new c.Point(d,e),this._cache={dirty:!1,a00:1,a01:0,a02:d,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y,this.renderable=!0},c.Text.prototype=Object.create(b.Text.prototype),c.Text.prototype.constructor=c.Text,c.Text.prototype.update=function(){this.exists&&(this.fixedToCamera&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y),this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0))},c.Text.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(c.Text.prototype,"angle",{get:function(){return c.Math.radToDeg(this.rotation)},set:function(a){this.rotation=c.Math.degToRad(a)}}),Object.defineProperty(c.Text.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(c.Text.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),Object.defineProperty(c.Text.prototype,"content",{get:function(){return this._text},set:function(a){a!==this._text&&(this._text=a,this.setText(a))}}),Object.defineProperty(c.Text.prototype,"font",{get:function(){return this._style},set:function(a){a!==this._style&&(this._style=a,this.setStyle(a))}}),c.BitmapText=function(a,d,e,f,g){d=d||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=c.BITMAPTEXT,b.BitmapText.call(this,f,g),this.position.x=d,this.position.y=e,this.anchor=new c.Point,this.scale=new c.Point(1,1),this._cache={dirty:!1,a00:1,a01:0,a02:d,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y},c.BitmapText.prototype=Object.create(b.BitmapText.prototype),c.BitmapText.prototype.constructor=c.BitmapText,c.BitmapText.prototype.update=function(){this.exists&&(this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0),this.pivot.x=this.anchor.x*this.width,this.pivot.y=this.anchor.y*this.height)},c.BitmapText.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas&&this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(c.BitmapText.prototype,"angle",{get:function(){return c.Math.radToDeg(this.rotation)},set:function(a){this.rotation=c.Math.degToRad(a)}}),Object.defineProperty(c.BitmapText.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(c.BitmapText.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),c.Button=function(a,b,d,e,f,g,h,i,j,k){b=b||0,d=d||0,e=e||null,f=f||null,g=g||this,c.Sprite.call(this,a,b,d,e,i),this.type=c.BUTTON,this._onOverFrameName=null,this._onOutFrameName=null,this._onDownFrameName=null,this._onUpFrameName=null,this._onOverFrameID=null,this._onOutFrameID=null,this._onDownFrameID=null,this._onUpFrameID=null,this.onOverSound=null,this.onOutSound=null,this.onDownSound=null,this.onUpSound=null,this.onOverSoundMarker="",this.onOutSoundMarker="",this.onDownSoundMarker="",this.onUpSoundMarker="",this.onInputOver=new c.Signal,this.onInputOut=new c.Signal,this.onInputDown=new c.Signal,this.onInputUp=new c.Signal,this.freezeFrames=!1,this.forceOut=!1,this.setFrames(h,i,j,k),null!==f&&this.onInputUp.add(f,g),this.input.start(0,!0),this.events.onInputOver.add(this.onInputOverHandler,this),this.events.onInputOut.add(this.onInputOutHandler,this),this.events.onInputDown.add(this.onInputDownHandler,this),this.events.onInputUp.add(this.onInputUpHandler,this)},c.Button.prototype=Object.create(c.Sprite.prototype),c.Button.prototype=c.Utils.extend(!0,c.Button.prototype,c.Sprite.prototype,b.Sprite.prototype),c.Button.prototype.constructor=c.Button,c.Button.prototype.clearFrames=function(){this._onOverFrameName=null,this._onOverFrameID=null,this._onOutFrameName=null,this._onOutFrameID=null,this._onDownFrameName=null,this._onDownFrameID=null,this._onUpFrameName=null,this._onUpFrameID=null},c.Button.prototype.setFrames=function(a,b,c,d){this.clearFrames(),null!==a&&("string"==typeof a?(this._onOverFrameName=a,this.input.pointerOver()&&(this.frameName=a)):(this._onOverFrameID=a,this.input.pointerOver()&&(this.frame=a))),null!==b&&("string"==typeof b?(this._onOutFrameName=b,this.input.pointerOver()===!1&&(this.frameName=b)):(this._onOutFrameID=b,this.input.pointerOver()===!1&&(this.frame=b))),null!==c&&("string"==typeof c?(this._onDownFrameName=c,this.input.pointerDown()&&(this.frameName=c)):(this._onDownFrameID=c,this.input.pointerDown()&&(this.frame=c))),null!==d&&("string"==typeof d?(this._onUpFrameName=d,this.input.pointerUp()&&(this.frameName=d)):(this._onUpFrameID=d,this.input.pointerUp()&&(this.frame=d)))},c.Button.prototype.setSounds=function(a,b,c,d,e,f,g,h){this.setOverSound(a,b),this.setOutSound(e,f),this.setDownSound(c,d),this.setUpSound(g,h)},c.Button.prototype.setOverSound=function(a,b){this.onOverSound=null,this.onOverSoundMarker="",a instanceof c.Sound&&(this.onOverSound=a),"string"==typeof b&&(this.onOverSoundMarker=b)},c.Button.prototype.setOutSound=function(a,b){this.onOutSound=null,this.onOutSoundMarker="",a instanceof c.Sound&&(this.onOutSound=a),"string"==typeof b&&(this.onOutSoundMarker=b)},c.Button.prototype.setDownSound=function(a,b){this.onDownSound=null,this.onDownSoundMarker="",a instanceof c.Sound&&(this.onDownSound=a),"string"==typeof b&&(this.onDownSoundMarker=b)},c.Button.prototype.setUpSound=function(a,b){this.onUpSound=null,this.onUpSoundMarker="",a instanceof c.Sound&&(this.onUpSound=a),"string"==typeof b&&(this.onUpSoundMarker=b)},c.Button.prototype.onInputOverHandler=function(a,b){this.freezeFrames===!1&&this.setState(1),this.onOverSound&&this.onOverSound.play(this.onOverSoundMarker),this.onInputOver&&this.onInputOver.dispatch(this,b)},c.Button.prototype.onInputOutHandler=function(a,b){this.freezeFrames===!1&&this.setState(2),this.onOutSound&&this.onOutSound.play(this.onOutSoundMarker),this.onInputOut&&this.onInputOut.dispatch(this,b)},c.Button.prototype.onInputDownHandler=function(a,b){this.freezeFrames===!1&&this.setState(3),this.onDownSound&&this.onDownSound.play(this.onDownSoundMarker),this.onInputDown&&this.onInputDown.dispatch(this,b)},c.Button.prototype.onInputUpHandler=function(a,b,c){this.onUpSound&&this.onUpSound.play(this.onUpSoundMarker),this.onInputUp&&this.onInputUp.dispatch(this,b,c),this.freezeFrames||(this.forceOut?this.setState(2):this._onUpFrameName||this._onUpFrameID?this.setState(4):c?this.setState(1):this.setState(2))},c.Button.prototype.setState=function(a){1===a?null!=this._onOverFrameName?this.frameName=this._onOverFrameName:null!=this._onOverFrameID&&(this.frame=this._onOverFrameID):2===a?null!=this._onOutFrameName?this.frameName=this._onOutFrameName:null!=this._onOutFrameID&&(this.frame=this._onOutFrameID):3===a?null!=this._onDownFrameName?this.frameName=this._onDownFrameName:null!=this._onDownFrameID&&(this.frame=this._onDownFrameID):4===a&&(null!=this._onUpFrameName?this.frameName=this._onUpFrameName:null!=this._onUpFrameID&&(this.frame=this._onUpFrameID))},c.Graphics=function(a,d,e){this.game=a,b.Graphics.call(this),this.type=c.GRAPHICS,this.position.x=d,this.position.y=e},c.Graphics.prototype=Object.create(b.Graphics.prototype),c.Graphics.prototype.constructor=c.Graphics,c.Graphics.prototype.destroy=function(){this.clear(),this.group&&this.group.remove(this),this.game=null},c.Graphics.prototype.drawPolygon=function(a){this.moveTo(a.points[0].x,a.points[0].y);for(var b=1;bh;h++)f[h].updateTransform();var j=a.__renderGroup;j?a==j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new b.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},c.RenderTexture.prototype.renderCanvas=function(a,c,d,e){var f=a.children;a.worldTransform=b.mat3.create(),c&&(a.worldTransform[2]=c.x,a.worldTransform[5]=c.y);for(var g=0,h=f.length;h>g;g++)f[g].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a,e),this.renderer.context.setTransform(1,0,0,1,0,0)},c.Canvas={create:function(a,b,c){a=a||256,b=b||256;var d=document.createElement("canvas");return"string"==typeof c&&(d.id=c),d.width=a,d.height=b,d.style.display="block",d},getOffset:function(a,b){b=b||new c.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),b.x=d.left+h-f,b.y=d.top+g-e,b},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}},c.StageScaleMode=function(a,b,d){this.game=a,this.width=b,this.height=d,this.minWidth=null,this.maxWidth=null,this.minHeight=null,this.maxHeight=null,this._startHeight=0,this.forceLandscape=!1,this.forcePortrait=!1,this.incorrectOrientation=!1,this.pageAlignHorizontally=!1,this.pageAlignVertically=!1,this._width=0,this._height=0,this.maxIterations=5,this.orientationSprite=null,this.enterLandscape=new c.Signal,this.enterPortrait=new c.Signal,this.enterIncorrectOrientation=new c.Signal,this.leaveIncorrectOrientation=new c.Signal,this.hasResized=new c.Signal,this.orientation=window.orientation?window.orientation:window.outerWidth>window.outerHeight?90:0,this.scaleFactor=new c.Point(1,1),this.scaleFactorInversed=new c.Point(1,1),this.margin=new c.Point(0,0),this.aspectRatio=0,this.event=null;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)},c.StageScaleMode.EXACT_FIT=0,c.StageScaleMode.NO_SCALE=1,c.StageScaleMode.SHOW_ALL=2,c.StageScaleMode.prototype={startFullScreen:function(a){if(!this.isFullScreen){"undefined"!=typeof a&&c.Canvas.setSmoothingEnabled(this.game.context,a);var b=this.game.canvas;this._width=this.width,this._height=this.height,b.requestFullScreen?b.requestFullScreen():b.mozRequestFullScreen?b.parentNode.mozRequestFullScreen():b.webkitRequestFullScreen&&b.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}},stopFullScreen:function(){document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen()},fullScreenChange:function(a){this.event=a,this.isFullScreen?this.game.stage.fullScreenScaleMode===c.StageScaleMode.EXACT_FIT?(this.game.stage.canvas.style.width="100%",this.game.stage.canvas.style.height="100%",this.setMaximum(),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.game.stage.fullScreenScaleMode===c.StageScaleMode.SHOW_ALL&&(this.game.stage.scale.setShowAll(),this.game.stage.scale.refresh()):(this.game.stage.canvas.style.width=this.game.width+"px",this.game.stage.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)},forceOrientation:function(a,c,d){"undefined"==typeof c&&(c=!1),this.forceLandscape=a,this.forcePortrait=c,"undefined"!=typeof d&&((null==d||this.game.cache.checkImageKey(d)===!1)&&(d="__default"),this.orientationSprite=new b.Sprite(b.TextureCache[d]),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._stage.addChild(this.orientationSprite))},checkOrientationState:function(){this.incorrectOrientation?(this.forceLandscape&&window.innerWidth>window.innerHeight||this.forcePortrait&&window.innerHeight>window.innerWidth)&&(this.game.paused=!1,this.incorrectOrientation=!1,this.leaveIncorrectOrientation.dispatch(),this.orientationSprite&&(this.orientationSprite.visible=!1,this.game.world.visible=!0),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.game.stage.scaleMode!==c.StageScaleMode.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.game.stage.fullScreenScaleMode==c.StageScaleMode.EXACT_FIT?this.setExactFit():this.game.stage.fullScreenScaleMode==c.StageScaleMode.SHOW_ALL&&this.setShowAll():this.game.stage.scaleMode==c.StageScaleMode.EXACT_FIT?this.setExactFit():this.game.stage.scaleMode==c.StageScaleMode.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}},c.StageScaleMode.prototype.constructor=c.StageScaleMode,Object.defineProperty(c.StageScaleMode.prototype,"isFullScreen",{get:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement}}),Object.defineProperty(c.StageScaleMode.prototype,"isPortrait",{get:function(){return 0===this.orientation||180==this.orientation}}),Object.defineProperty(c.StageScaleMode.prototype,"isLandscape",{get:function(){return 90===this.orientation||-90===this.orientation}}),c.Device=function(){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.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._checkAudio(),this._checkBrowser(),this._checkCSS3D(),this._checkDevice(),this._checkFeatures(),this._checkOS()},c.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),(this.windows||this.macOS||this.linux&&this.silk===!1)&&(this.desktop=!0)},_checkFeatures:function(){this.canvas=!!window.CanvasRenderingContext2D;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},_checkBrowser:function(){var a=navigator.userAgent;/Arora/.test(a)?this.arora=!0:/Chrome/.test(a)?this.chrome=!0:/Epiphany/.test(a)?this.epiphany=!0:/Firefox/.test(a)?this.firefox=!0:/Mobile Safari/.test(a)?this.mobileSafari=!0:/MSIE (\d+\.\d+);/.test(a)?(this.ie=!0,this.ieVersion=parseInt(RegExp.$1,10)):/Midori/.test(a)?this.midori=!0:/Opera/.test(a)?this.opera=!0:/Safari/.test(a)?this.safari=!0:/Silk/.test(a)?this.silk=!0:/Trident\/(\d+\.\d+);/.test(a)&&(this.ie=!0,this.trident=!0,this.tridentVersion=parseInt(RegExp.$1,10)),navigator.standalone&&(this.webApp=!0),navigator.isCocoonJS&&(this.cocoonJS=!0),"undefined"!=typeof window.ejecta&&(this.ejecta=!0)},_checkAudio:function(){this.audioData=!!window.Audio,this.webAudio=!(!window.webkitAudioContext&&!window.AudioContext);var a=document.createElement("audio"),b=!1;try{(b=!!a.canPlayType)&&(a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,"")&&(this.ogg=!0),a.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,"")&&(this.opus=!0),a.canPlayType("audio/mpeg;").replace(/^no$/,"")&&(this.mp3=!0),a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,"")&&(this.wav=!0),(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;").replace(/^no$/,""))&&(this.m4a=!0),a.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")&&(this.webm=!0))}catch(c){}},_checkDevice:function(){this.pixelRatio=window.devicePixelRatio||1,this.iPhone=-1!=navigator.userAgent.toLowerCase().indexOf("iphone"),this.iPhone4=2==this.pixelRatio&&this.iPhone,this.iPad=-1!=navigator.userAgent.toLowerCase().indexOf("ipad"),"undefined"!=typeof Int8Array?(this.littleEndian=new Int8Array(new Int16Array([1]).buffer)[0]>0,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}},c.Device.prototype.constructor=c.Device,c.RequestAnimationFrame=function(a){this.game=a,this.isRunning=!1;for(var b=["ms","moz","webkit","o"],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*(0|2097152*this.rnd.apply(this))},real:function(){return this.integer()+this.frac()},integerInRange:function(a,b){return Math.floor(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|4&3*a?(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)}},c.RandomDataGenerator.prototype.constructor=c.RandomDataGenerator,c.Math={PI2:2*Math.PI,fuzzyEqual:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),Math.abs(a-b)a},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;b