phaser-rails 2.4.4.1 → 2.4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Phaser - http://phaser.io
9
9
  *
10
- * v2.4.4 "Amador" - Built: Thu Oct 15 2015 11:52:26
10
+ * v2.4.5 "Sienda" - Built: Wed Feb 17 2016 13:36:26
11
11
  *
12
12
  * By Richard Davey http://www.photonstorm.com @photonstorm
13
13
  *
@@ -14411,17 +14411,21 @@ PIXI.DisplayObject.prototype._generateCachedSprite = function()
14411
14411
 
14412
14412
  var bounds = this.getLocalBounds();
14413
14413
 
14414
+ // Round it off and force non-zero dimensions
14415
+ bounds.width = Math.max(1, Math.ceil(bounds.width));
14416
+ bounds.height = Math.max(1, Math.ceil(bounds.height));
14417
+
14414
14418
  this.updateTransform();
14415
14419
 
14416
14420
  if (!this._cachedSprite)
14417
14421
  {
14418
- var renderTexture = new PIXI.RenderTexture(bounds.width | 1, bounds.height | 1);
14422
+ var renderTexture = new PIXI.RenderTexture(bounds.width, bounds.height);
14419
14423
  this._cachedSprite = new PIXI.Sprite(renderTexture);
14420
14424
  this._cachedSprite.worldTransform = this.worldTransform;
14421
14425
  }
14422
14426
  else
14423
14427
  {
14424
- this._cachedSprite.texture.resize(bounds.width | 1, bounds.height | 1);
14428
+ this._cachedSprite.texture.resize(bounds.width, bounds.height);
14425
14429
  }
14426
14430
 
14427
14431
  // Remove filters
@@ -14434,8 +14438,8 @@ PIXI.DisplayObject.prototype._generateCachedSprite = function()
14434
14438
  PIXI.DisplayObject._tempMatrix.ty = -bounds.y;
14435
14439
 
14436
14440
  this._cachedSprite.texture.render(this, PIXI.DisplayObject._tempMatrix, true);
14437
- this._cachedSprite.anchor.x = -( bounds.x / bounds.width );
14438
- this._cachedSprite.anchor.y = -( bounds.y / bounds.height );
14441
+ this._cachedSprite.anchor.x = -(bounds.x / bounds.width);
14442
+ this._cachedSprite.anchor.y = -(bounds.y / bounds.height);
14439
14443
 
14440
14444
  this._filters = tempFilters;
14441
14445
 
@@ -15207,6 +15211,8 @@ PIXI.Sprite.prototype.setTexture = function(texture, destroyBase)
15207
15211
  this.texture.baseTexture.destroy();
15208
15212
  }
15209
15213
 
15214
+ // Over-ridden by loadTexture as needed
15215
+ this.texture.baseTexture.skipRender = false;
15210
15216
  this.texture = texture;
15211
15217
  this.texture.valid = true;
15212
15218
  };
@@ -17570,12 +17576,15 @@ PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession)
17570
17576
  {
17571
17577
  var gl = renderSession.gl;
17572
17578
 
17573
- if(maskData.dirty)
17579
+ if (maskData.dirty)
17574
17580
  {
17575
17581
  PIXI.WebGLGraphics.updateGraphics(maskData, gl);
17576
17582
  }
17577
17583
 
17578
- if(!maskData._webGL[gl.id].data.length)return;
17584
+ if (maskData._webGL[gl.id] === undefined || maskData._webGL[gl.id].data === undefined || maskData._webGL[gl.id].data.length === 0)
17585
+ {
17586
+ return;
17587
+ }
17579
17588
 
17580
17589
  renderSession.stencilManager.pushStencil(maskData, maskData._webGL[gl.id].data[0], renderSession);
17581
17590
  };
@@ -17590,7 +17599,14 @@ PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession)
17590
17599
  PIXI.WebGLMaskManager.prototype.popMask = function(maskData, renderSession)
17591
17600
  {
17592
17601
  var gl = this.gl;
17602
+
17603
+ if (maskData._webGL[gl.id] === undefined || maskData._webGL[gl.id].data === undefined || maskData._webGL[gl.id].data.length === 0)
17604
+ {
17605
+ return;
17606
+ }
17607
+
17593
17608
  renderSession.stencilManager.popStencil(maskData, maskData._webGL[gl.id].data[0], renderSession);
17609
+
17594
17610
  };
17595
17611
 
17596
17612
  /**
@@ -18600,7 +18616,14 @@ PIXI.WebGLSpriteBatch.prototype.flush = function()
18600
18616
  blendSwap = currentBlendMode !== nextBlendMode;
18601
18617
  shaderSwap = currentShader !== nextShader; // should I use _UIDS???
18602
18618
 
18603
- if ((currentBaseTexture !== nextTexture && !nextTexture.skipRender) || blendSwap || shaderSwap)
18619
+ var skip = nextTexture.skipRender;
18620
+
18621
+ if (skip && sprite.children.length > 0)
18622
+ {
18623
+ skip = false;
18624
+ }
18625
+
18626
+ if ((currentBaseTexture !== nextTexture && !skip) || blendSwap || shaderSwap)
18604
18627
  {
18605
18628
  this.renderBatch(currentBaseTexture, batchSize, start);
18606
18629
 
@@ -19236,7 +19259,14 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
19236
19259
  var offset = this.renderSession.offset;
19237
19260
 
19238
19261
  filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds();
19239
-
19262
+
19263
+ // >>> modify by nextht
19264
+ filterBlock._previous_stencil_mgr = this.renderSession.stencilManager;
19265
+ this.renderSession.stencilManager = new PIXI.WebGLStencilManager();
19266
+ this.renderSession.stencilManager.setContext(gl);
19267
+ gl.disable(gl.STENCIL_TEST);
19268
+ // <<< modify by nextht
19269
+
19240
19270
  // filter program
19241
19271
  // OPTIMISATION - the first filter is free if its a simple color change?
19242
19272
  this.filterStack.push(filterBlock);
@@ -19249,11 +19279,11 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
19249
19279
  var texture = this.texturePool.pop();
19250
19280
  if(!texture)
19251
19281
  {
19252
- texture = new PIXI.FilterTexture(this.gl, this.width, this.height);
19282
+ texture = new PIXI.FilterTexture(this.gl, this.width * this.renderSession.resolution, this.height * this.renderSession.resolution);
19253
19283
  }
19254
19284
  else
19255
19285
  {
19256
- texture.resize(this.width, this.height);
19286
+ texture.resize(this.width * this.renderSession.resolution, this.height * this.renderSession.resolution);
19257
19287
  }
19258
19288
 
19259
19289
  gl.bindTexture(gl.TEXTURE_2D, texture.texture);
@@ -19276,7 +19306,7 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
19276
19306
  gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer);
19277
19307
 
19278
19308
  // set view port
19279
- gl.viewport(0, 0, filterArea.width, filterArea.height);
19309
+ gl.viewport(0, 0, filterArea.width * this.renderSession.resolution, filterArea.height * this.renderSession.resolution);
19280
19310
 
19281
19311
  projection.x = filterArea.width/2;
19282
19312
  projection.y = -filterArea.height/2;
@@ -19314,7 +19344,7 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
19314
19344
 
19315
19345
  if(filterBlock.filterPasses.length > 1)
19316
19346
  {
19317
- gl.viewport(0, 0, filterArea.width, filterArea.height);
19347
+ gl.viewport(0, 0, filterArea.width * this.renderSession.resolution, filterArea.height * this.renderSession.resolution);
19318
19348
 
19319
19349
  gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
19320
19350
 
@@ -19343,8 +19373,8 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
19343
19373
 
19344
19374
  var inputTexture = texture;
19345
19375
  var outputTexture = this.texturePool.pop();
19346
- if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width, this.height);
19347
- outputTexture.resize(this.width, this.height);
19376
+ if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width * this.renderSession.resolution, this.height * this.renderSession.resolution);
19377
+ outputTexture.resize(this.width * this.renderSession.resolution, this.height * this.renderSession.resolution);
19348
19378
 
19349
19379
  // need to clear this FBO as it may have some left over elements from a previous filter.
19350
19380
  gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
@@ -19461,6 +19491,20 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
19461
19491
  gl.activeTexture(gl.TEXTURE0);
19462
19492
  gl.bindTexture(gl.TEXTURE_2D, texture.texture);
19463
19493
 
19494
+ // >>> modify by nextht
19495
+ if (this.renderSession.stencilManager) {
19496
+ this.renderSession.stencilManager.destroy();
19497
+ }
19498
+ this.renderSession.stencilManager = filterBlock._previous_stencil_mgr;
19499
+ filterBlock._previous_stencil_mgr = null;
19500
+ if (this.renderSession.stencilManager.count > 0) {
19501
+ gl.enable(gl.STENCIL_TEST);
19502
+ }
19503
+ else {
19504
+ gl.disable(gl.STENCIL_TEST);
19505
+ }
19506
+ // <<< modify by nextht
19507
+
19464
19508
  // apply!
19465
19509
  this.applyFilterPass(filter, filterArea, sizeX, sizeY);
19466
19510
 
@@ -20516,11 +20560,11 @@ PIXI.BaseTexture.prototype.destroy = function()
20516
20560
 
20517
20561
  if (!navigator.isCocoonJS) this.source.src = '';
20518
20562
  }
20519
- else if (this.source && this.source._pixiId)
20563
+ else if (this.source)
20520
20564
  {
20521
20565
  PIXI.CanvasPool.removeByCanvas(this.source);
20522
20566
 
20523
- delete PIXI.BaseTextureCache[this.source._pixiId];
20567
+ delete PIXI.BaseTextureCache[this.source];
20524
20568
  }
20525
20569
 
20526
20570
  this.source = null;
@@ -20591,7 +20635,7 @@ PIXI.BaseTexture.prototype.unloadFromGPU = function()
20591
20635
  * @param imageUrl {String} The image url of the texture
20592
20636
  * @param crossorigin {Boolean}
20593
20637
  * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values
20594
- * @return BaseTexture
20638
+ * @return {BaseTexture}
20595
20639
  */
20596
20640
  PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode)
20597
20641
  {
@@ -20632,7 +20676,7 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode)
20632
20676
  * @method fromCanvas
20633
20677
  * @param canvas {Canvas} The canvas element source of the texture
20634
20678
  * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values
20635
- * @return BaseTexture
20679
+ * @return {BaseTexture}
20636
20680
  */
20637
20681
  PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode)
20638
20682
  {
@@ -20924,7 +20968,7 @@ PIXI.Texture.prototype._updateUvs = function()
20924
20968
  * @param imageUrl {String} The image url of the texture
20925
20969
  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
20926
20970
  * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values
20927
- * @return Texture
20971
+ * @return {Texture}
20928
20972
  */
20929
20973
  PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode)
20930
20974
  {
@@ -20946,7 +20990,7 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode)
20946
20990
  * @static
20947
20991
  * @method fromFrame
20948
20992
  * @param frameId {String} The frame id of the texture
20949
- * @return Texture
20993
+ * @return {Texture}
20950
20994
  */
20951
20995
  PIXI.Texture.fromFrame = function(frameId)
20952
20996
  {
@@ -20962,7 +21006,7 @@ PIXI.Texture.fromFrame = function(frameId)
20962
21006
  * @method fromCanvas
20963
21007
  * @param canvas {Canvas} The canvas element source of the texture
20964
21008
  * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values
20965
- * @return Texture
21009
+ * @return {Texture}
20966
21010
  */
20967
21011
  PIXI.Texture.fromCanvas = function(canvas, scaleMode)
20968
21012
  {
@@ -22247,7 +22291,7 @@ PIXI.TilingSprite.prototype.setTexture = function(texture)
22247
22291
  */
22248
22292
  PIXI.TilingSprite.prototype._renderWebGL = function(renderSession)
22249
22293
  {
22250
- if (this.visible === false || this.alpha === 0)
22294
+ if (!this.visible || !this.renderable || this.alpha === 0)
22251
22295
  {
22252
22296
  return;
22253
22297
  }
@@ -22315,7 +22359,7 @@ PIXI.TilingSprite.prototype._renderWebGL = function(renderSession)
22315
22359
  */
22316
22360
  PIXI.TilingSprite.prototype._renderCanvas = function(renderSession)
22317
22361
  {
22318
- if (this.visible === false || this.alpha === 0)
22362
+ if (!this.visible || !this.renderable || this.alpha === 0)
22319
22363
  {
22320
22364
  return;
22321
22365
  }
@@ -22437,6 +22481,8 @@ PIXI.TilingSprite.prototype.generateTilingTexture = function(forcePowerOfTwo, re
22437
22481
  var texture = this.texture;
22438
22482
  var frame = texture.frame;
22439
22483
 
22484
+ console.log('generateTilingTexture', texture, frame);
22485
+
22440
22486
  var targetWidth = this._frame.sourceSizeW;
22441
22487
  var targetHeight = this._frame.sourceSizeH;
22442
22488
 
@@ -22685,7 +22731,7 @@ var Phaser = Phaser || {
22685
22731
  * @constant
22686
22732
  * @type {string}
22687
22733
  */
22688
- VERSION: '2.4.4',
22734
+ VERSION: '2.4.5',
22689
22735
 
22690
22736
  /**
22691
22737
  * An array of Phaser game instances.
@@ -22960,6 +23006,13 @@ var Phaser = Phaser || {
22960
23006
  */
22961
23007
  VIDEO: 28,
22962
23008
 
23009
+ /**
23010
+ * Game Object type.
23011
+ * @constant
23012
+ * @type {integer}
23013
+ */
23014
+ PENDING_ATLAS: -1,
23015
+
22963
23016
  /**
22964
23017
  * Various blend modes supported by Pixi.
22965
23018
  *
@@ -23264,7 +23317,7 @@ Phaser.Utils = {
23264
23317
  * Returns true or false based on the chance value (default 50%). For example if you wanted a player to have a 30% chance
23265
23318
  * of getting a bonus, call chanceRoll(30) - true means the chance passed, false means it failed.
23266
23319
  *
23267
- * @method Phaser.Math#chanceRoll
23320
+ * @method Phaser.Utils#chanceRoll
23268
23321
  * @param {number} chance - The chance of receiving the value. A number between 0 and 100 (effectively 0% to 100%).
23269
23322
  * @return {boolean} True if the roll passed, or false otherwise.
23270
23323
  */
@@ -24625,6 +24678,8 @@ Phaser.Line.prototype = {
24625
24678
  * Rotation takes place around the coordinates given.
24626
24679
  *
24627
24680
  * @method Phaser.Line#rotateAround
24681
+ * @param {number} x - The x coordinate to offset the rotation from.
24682
+ * @param {number} y - The y coordinate to offset the rotation from.
24628
24683
  * @param {number} angle - The angle in radians (unless asDegrees is true) to rotate the line by.
24629
24684
  * @param {boolean} [asDegrees=false] - Is the given angle in radians (false) or degrees (true)?
24630
24685
  * @return {Phaser.Line} This line object
@@ -28176,28 +28231,28 @@ Phaser.Camera.prototype = {
28176
28231
  this.atLimit.y = false;
28177
28232
 
28178
28233
  // Make sure we didn't go outside the cameras bounds
28179
- if (this.view.x <= this.bounds.x)
28234
+ if (this.view.x <= this.bounds.x * this.scale.x)
28180
28235
  {
28181
28236
  this.atLimit.x = true;
28182
- this.view.x = this.bounds.x;
28237
+ this.view.x = this.bounds.x * this.scale.x;
28183
28238
  }
28184
28239
 
28185
- if (this.view.right >= this.bounds.right)
28240
+ if (this.view.right >= this.bounds.right * this.scale.x)
28186
28241
  {
28187
28242
  this.atLimit.x = true;
28188
- this.view.x = this.bounds.right - this.width;
28243
+ this.view.x = (this.bounds.right * this.scale.x) - this.width;
28189
28244
  }
28190
28245
 
28191
- if (this.view.y <= this.bounds.top)
28246
+ if (this.view.y <= this.bounds.top * this.scale.y)
28192
28247
  {
28193
28248
  this.atLimit.y = true;
28194
- this.view.y = this.bounds.top;
28249
+ this.view.y = this.bounds.top * this.scale.y;
28195
28250
  }
28196
28251
 
28197
- if (this.view.bottom >= this.bounds.bottom)
28252
+ if (this.view.bottom >= this.bounds.bottom * this.scale.y)
28198
28253
  {
28199
28254
  this.atLimit.y = true;
28200
- this.view.y = this.bounds.bottom - this.height;
28255
+ this.view.y = (this.bounds.bottom * this.scale.y) - this.height;
28201
28256
  }
28202
28257
 
28203
28258
  },
@@ -28516,7 +28571,7 @@ Phaser.State.prototype = {
28516
28571
  /**
28517
28572
  * The update method is left empty for your own use.
28518
28573
  * It is called during the core game loop AFTER debug, physics, plugins and the Stage have had their preUpdate methods called.
28519
- * If is called BEFORE Stage, Tweens, Sounds, Input, Physics, Particles and Plugins have had their postUpdate methods called.
28574
+ * It is called BEFORE Stage, Tweens, Sounds, Input, Physics, Particles and Plugins have had their postUpdate methods called.
28520
28575
  *
28521
28576
  * @method Phaser.State#update
28522
28577
  */
@@ -29018,20 +29073,15 @@ Phaser.StateManager.prototype = {
29018
29073
 
29019
29074
  if (this.states[key])
29020
29075
  {
29021
- var valid = false;
29022
-
29023
29076
  if (this.states[key]['preload'] || this.states[key]['create'] || this.states[key]['update'] || this.states[key]['render'])
29024
29077
  {
29025
- valid = true;
29078
+ return true;
29026
29079
  }
29027
-
29028
- if (valid === false)
29080
+ else
29029
29081
  {
29030
29082
  console.warn("Invalid Phaser State object given. Must contain at least a one of the required functions: preload, create, update or render");
29031
29083
  return false;
29032
29084
  }
29033
-
29034
- return true;
29035
29085
  }
29036
29086
  else
29037
29087
  {
@@ -29162,7 +29212,7 @@ Phaser.StateManager.prototype = {
29162
29212
  * Gets the current State.
29163
29213
  *
29164
29214
  * @method Phaser.StateManager#getCurrentState
29165
- * @return Phaser.State
29215
+ * @return {Phaser.State}
29166
29216
  * @public
29167
29217
  */
29168
29218
  getCurrentState: function() {
@@ -29175,6 +29225,12 @@ Phaser.StateManager.prototype = {
29175
29225
  */
29176
29226
  loadComplete: function () {
29177
29227
 
29228
+ // Make sure to do load-update one last time before state is set to _created
29229
+ if (this._created === false && this.onLoadUpdateCallback)
29230
+ {
29231
+ this.onLoadUpdateCallback.call(this.callbackContext, this.game);
29232
+ }
29233
+
29178
29234
  if (this._created === false && this.onCreateCallback)
29179
29235
  {
29180
29236
  this._created = true;
@@ -30045,6 +30101,9 @@ Phaser.SignalBinding.prototype.constructor = Phaser.SignalBinding;
30045
30101
  /**
30046
30102
  * This is a base Filter class to use for any Phaser filter development.
30047
30103
  *
30104
+ * The vast majority of filters (including all of those that ship with Phaser) use fragment shaders, and
30105
+ * therefore only work in WebGL and are not supported by Canvas at all.
30106
+ *
30048
30107
  * @class Phaser.Filter
30049
30108
  * @constructor
30050
30109
  * @param {Phaser.Game} game - A reference to the currently running game.
@@ -30723,7 +30782,12 @@ Phaser.Stage = function (game) {
30723
30782
  this.name = '_stage_root';
30724
30783
 
30725
30784
  /**
30726
- * @property {boolean} disableVisibilityChange - By default if the browser tab loses focus the game will pause. You can stop that behaviour by setting this property to true.
30785
+ * By default if the browser tab loses focus the game will pause.
30786
+ * You can stop that behavior by setting this property to true.
30787
+ * Note that the browser can still elect to pause your game if it wishes to do so,
30788
+ * for example swapping to another browser tab. This will cause the RAF callback to halt,
30789
+ * effectively pausing your game, even though no in-game pause event is triggered if you enable this property.
30790
+ * @property {boolean} disableVisibilityChange
30727
30791
  * @default
30728
30792
  */
30729
30793
  this.disableVisibilityChange = false;
@@ -31399,10 +31463,15 @@ Phaser.Group.prototype.add = function (child, silent) {
31399
31463
 
31400
31464
  if (child.parent !== this)
31401
31465
  {
31402
- this.addChild(child);
31466
+ if (child.body)
31467
+ {
31468
+ child.parent.removeFromHash(child);
31469
+ }
31403
31470
 
31404
31471
  child.z = this.children.length;
31405
31472
 
31473
+ this.addChild(child);
31474
+
31406
31475
  if (this.enableBody && child.body === null)
31407
31476
  {
31408
31477
  this.game.physics.enable(child, this.physicsBodyType);
@@ -31525,6 +31594,11 @@ Phaser.Group.prototype.addAt = function (child, index, silent) {
31525
31594
 
31526
31595
  if (child.parent !== this)
31527
31596
  {
31597
+ if (child.body)
31598
+ {
31599
+ child.parent.removeFromHash(child);
31600
+ }
31601
+
31528
31602
  this.addChildAt(child, index);
31529
31603
 
31530
31604
  this.updateZ();
@@ -31596,10 +31670,10 @@ Phaser.Group.prototype.create = function (x, y, key, frame, exists) {
31596
31670
  child.visible = exists;
31597
31671
  child.alive = exists;
31598
31672
 
31599
- this.addChild(child);
31600
-
31601
31673
  child.z = this.children.length;
31602
31674
 
31675
+ this.addChild(child);
31676
+
31603
31677
  if (this.enableBody)
31604
31678
  {
31605
31679
  this.game.physics.enable(child, this.physicsBodyType, this.enableBodyDebug);
@@ -31875,7 +31949,7 @@ Phaser.Group.prototype.xy = function (index, x, y) {
31875
31949
  /**
31876
31950
  * Reverses all children in this group.
31877
31951
  *
31878
- * This operaation applies only to immediate children and does not propagate to subgroups.
31952
+ * This operation applies only to immediate children and does not propagate to subgroups.
31879
31953
  *
31880
31954
  * @method Phaser.Group#reverse
31881
31955
  */
@@ -32696,8 +32770,12 @@ Phaser.Group.prototype.forEachDead = function (callback, callbackContext) {
32696
32770
  * Sort the children in the group according to a particular key and ordering.
32697
32771
  *
32698
32772
  * Call this function to sort the group according to a particular key value and order.
32773
+ *
32699
32774
  * For example to depth sort Sprites for Zelda-style game you might call `group.sort('y', Phaser.Group.SORT_ASCENDING)` at the bottom of your `State.update()`.
32700
32775
  *
32776
+ * Internally this uses a standard JavaScript Array sort, so everything that applies there also applies here, including
32777
+ * alphabetical sorting, mixing strings and numbers, and Unicode sorting. See MDN for more details.
32778
+ *
32701
32779
  * @method Phaser.Group#sort
32702
32780
  * @param {string} [key='z'] - The name of the property to sort on. Defaults to the objects z-depth value.
32703
32781
  * @param {integer} [order=Phaser.Group.SORT_ASCENDING] - Order ascending ({@link Phaser.Group.SORT_ASCENDING SORT_ASCENDING}) or descending ({@link Phaser.Group.SORT_DESCENDING SORT_DESCENDING}).
@@ -34251,12 +34329,12 @@ Phaser.Game.prototype = {
34251
34329
  this.parent = config['parent'];
34252
34330
  }
34253
34331
 
34254
- if (config['transparent'])
34332
+ if (config['transparent'] !== undefined)
34255
34333
  {
34256
34334
  this.transparent = config['transparent'];
34257
34335
  }
34258
34336
 
34259
- if (config['antialias'])
34337
+ if (config['antialias'] !== undefined)
34260
34338
  {
34261
34339
  this.antialias = config['antialias'];
34262
34340
  }
@@ -34266,7 +34344,7 @@ Phaser.Game.prototype = {
34266
34344
  this.resolution = config['resolution'];
34267
34345
  }
34268
34346
 
34269
- if (config['preserveDrawingBuffer'])
34347
+ if (config['preserveDrawingBuffer'] !== undefined)
34270
34348
  {
34271
34349
  this.preserveDrawingBuffer = config['preserveDrawingBuffer'];
34272
34350
  }
@@ -36283,6 +36361,10 @@ Phaser.Mouse.prototype = {
36283
36361
  return _this.onMouseUpGlobal(event);
36284
36362
  };
36285
36363
 
36364
+ this._onMouseOutGlobal = function (event) {
36365
+ return _this.onMouseOutGlobal(event);
36366
+ };
36367
+
36286
36368
  this._onMouseOut = function (event) {
36287
36369
  return _this.onMouseOut(event);
36288
36370
  };
@@ -36304,6 +36386,7 @@ Phaser.Mouse.prototype = {
36304
36386
  if (!this.game.device.cocoonJS)
36305
36387
  {
36306
36388
  window.addEventListener('mouseup', this._onMouseUpGlobal, true);
36389
+ window.addEventListener('mouseout', this._onMouseOutGlobal, true);
36307
36390
  canvas.addEventListener('mouseover', this._onMouseOver, true);
36308
36391
  canvas.addEventListener('mouseout', this._onMouseOut, true);
36309
36392
  }
@@ -36438,6 +36521,42 @@ Phaser.Mouse.prototype = {
36438
36521
 
36439
36522
  },
36440
36523
 
36524
+ /**
36525
+ * The internal method that handles the mouse out event from the window.
36526
+ *
36527
+ * @method Phaser.Mouse#onMouseOutGlobal
36528
+ * @param {MouseEvent} event - The native event from the browser. This gets stored in Mouse.event.
36529
+ */
36530
+ onMouseOutGlobal: function (event) {
36531
+
36532
+ this.event = event;
36533
+
36534
+ if (this.capture)
36535
+ {
36536
+ event.preventDefault();
36537
+ }
36538
+
36539
+ this.input.mousePointer.withinGame = false;
36540
+
36541
+ if (!this.input.enabled || !this.enabled)
36542
+ {
36543
+ return;
36544
+ }
36545
+
36546
+ // If we get a mouseout event from the window then basically
36547
+ // something serious has gone down, usually along the lines of
36548
+ // the browser opening a context-menu or similar.
36549
+ // On OS X Chrome especially this is bad news, as it blocks
36550
+ // us then getting a mouseup event, so we need to force that through.
36551
+ //
36552
+ // No matter what, we must cancel the left and right buttons
36553
+
36554
+ this.input.mousePointer.stop(event);
36555
+ this.input.mousePointer.leftButton.stop(event);
36556
+ this.input.mousePointer.rightButton.stop(event);
36557
+
36558
+ },
36559
+
36441
36560
  /**
36442
36561
  * The internal method that handles the mouse out event from the browser.
36443
36562
  *
@@ -38042,10 +38161,12 @@ Phaser.Pointer.prototype = {
38042
38161
  }
38043
38162
 
38044
38163
  // On OS X (and other devices with trackpads) you have to press CTRL + the pad
38045
- // to initiate a right-click event, so we'll check for that here
38164
+ // to initiate a right-click event, so we'll check for that here ONLY if
38165
+ // event.buttons = 1 (i.e. they only have a 1 button mouse or trackpad)
38046
38166
 
38047
- if (event.ctrlKey && this.leftButton.isDown)
38167
+ if (event.buttons === 1 && event.ctrlKey && this.leftButton.isDown)
38048
38168
  {
38169
+ this.leftButton.stop(event);
38049
38170
  this.rightButton.start(event);
38050
38171
  }
38051
38172
 
@@ -39353,14 +39474,6 @@ Phaser.InputHandler = function (sprite) {
39353
39474
  */
39354
39475
  this.boundsSprite = null;
39355
39476
 
39356
- /**
39357
- * If this object is set to consume the pointer event then it will stop all propagation from this object on.
39358
- * For example if you had a stack of 6 sprites with the same priority IDs and one consumed the event, none of the others would receive it.
39359
- * @property {boolean} consumePointerEvent
39360
- * @default
39361
- */
39362
- this.consumePointerEvent = false;
39363
-
39364
39477
  /**
39365
39478
  * @property {boolean} scaleLayer - EXPERIMENTAL: Please do not use this property unless you know what it does. Likely to change in the future.
39366
39479
  */
@@ -39774,6 +39887,8 @@ Phaser.InputHandler.prototype = {
39774
39887
  return true;
39775
39888
  }
39776
39889
  }
39890
+
39891
+ return false;
39777
39892
  }
39778
39893
  else
39779
39894
  {
@@ -40063,6 +40178,8 @@ Phaser.InputHandler.prototype = {
40063
40178
 
40064
40179
  if (data.isOver === false || pointer.dirty)
40065
40180
  {
40181
+ var sendEvent = (data.isOver === false);
40182
+
40066
40183
  data.isOver = true;
40067
40184
  data.isOut = false;
40068
40185
  data.timeOver = this.game.time.time;
@@ -40075,7 +40192,7 @@ Phaser.InputHandler.prototype = {
40075
40192
  this._setHandCursor = true;
40076
40193
  }
40077
40194
 
40078
- if (this.sprite && this.sprite.events)
40195
+ if (sendEvent && this.sprite && this.sprite.events)
40079
40196
  {
40080
40197
  this.sprite.events.onInputOver$dispatch(this.sprite, pointer);
40081
40198
  }
@@ -40165,9 +40282,6 @@ Phaser.InputHandler.prototype = {
40165
40282
  }
40166
40283
  }
40167
40284
 
40168
- // Consume the event?
40169
- return this.consumePointerEvent;
40170
-
40171
40285
  },
40172
40286
 
40173
40287
  /**
@@ -40234,7 +40348,7 @@ Phaser.InputHandler.prototype = {
40234
40348
  * @param {Phaser.Pointer} pointer
40235
40349
  * @return {boolean}
40236
40350
  */
40237
- updateDrag: function (pointer) {
40351
+ updateDrag: function (pointer, fromStart) {
40238
40352
 
40239
40353
  if (pointer.isUp)
40240
40354
  {
@@ -40242,6 +40356,11 @@ Phaser.InputHandler.prototype = {
40242
40356
  return false;
40243
40357
  }
40244
40358
 
40359
+ if (fromStart === undefined)
40360
+ {
40361
+ fromStart = false;
40362
+ }
40363
+
40245
40364
  var px = this.globalToLocalX(pointer.x) + this._dragPoint.x + this.dragOffset.x;
40246
40365
  var py = this.globalToLocalY(pointer.y) + this._dragPoint.y + this.dragOffset.y;
40247
40366
 
@@ -40304,7 +40423,7 @@ Phaser.InputHandler.prototype = {
40304
40423
  }
40305
40424
  }
40306
40425
 
40307
- this.sprite.events.onDragUpdate.dispatch(this.sprite, pointer, px, py, this.snapPoint);
40426
+ this.sprite.events.onDragUpdate.dispatch(this.sprite, pointer, px, py, this.snapPoint, fromStart);
40308
40427
 
40309
40428
  return true;
40310
40429
 
@@ -40528,7 +40647,7 @@ Phaser.InputHandler.prototype = {
40528
40647
  this._dragPoint.setTo(this.sprite.x - this.globalToLocalX(pointer.x), this.sprite.y - this.globalToLocalY(pointer.y));
40529
40648
  }
40530
40649
 
40531
- this.updateDrag(pointer);
40650
+ this.updateDrag(pointer, true);
40532
40651
 
40533
40652
  if (this.bringToTop)
40534
40653
  {
@@ -41593,8 +41712,9 @@ Phaser.SinglePad.prototype = {
41593
41712
  this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback;
41594
41713
  this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback;
41595
41714
  this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback;
41596
- }
41597
41715
 
41716
+ this.callbackContext = context;
41717
+ }
41598
41718
  },
41599
41719
 
41600
41720
  /**
@@ -41816,6 +41936,11 @@ Phaser.SinglePad.prototype = {
41816
41936
  */
41817
41937
  processButtonDown: function (buttonCode, value) {
41818
41938
 
41939
+ if (this._buttons[buttonCode])
41940
+ {
41941
+ this._buttons[buttonCode].start(null, value);
41942
+ }
41943
+
41819
41944
  if (this._padParent.onDownCallback)
41820
41945
  {
41821
41946
  this._padParent.onDownCallback.call(this._padParent.callbackContext, buttonCode, value, this.index);
@@ -41826,11 +41951,6 @@ Phaser.SinglePad.prototype = {
41826
41951
  this.onDownCallback.call(this.callbackContext, buttonCode, value);
41827
41952
  }
41828
41953
 
41829
- if (this._buttons[buttonCode])
41830
- {
41831
- this._buttons[buttonCode].start(null, value);
41832
- }
41833
-
41834
41954
  },
41835
41955
 
41836
41956
  /**
@@ -44129,14 +44249,19 @@ Phaser.Component.Destroy.prototype = {
44129
44249
  *
44130
44250
  * If this Game Object has the Events component it will also dispatch the `onDestroy` event.
44131
44251
  *
44252
+ * You can optionally also destroy the BaseTexture this Game Object is using. Be careful if you've
44253
+ * more than one Game Object sharing the same BaseTexture.
44254
+ *
44132
44255
  * @method
44133
44256
  * @param {boolean} [destroyChildren=true] - Should every child of this object have its destroy method called as well?
44257
+ * @param {boolean} [destroyTexture=false] - Destroy the BaseTexture this Game Object is using? Note that if another Game Object is sharing the same BaseTexture it will invalidate it.
44134
44258
  */
44135
- destroy: function (destroyChildren) {
44259
+ destroy: function (destroyChildren, destroyTexture) {
44136
44260
 
44137
44261
  if (this.game === null || this.destroyPhase) { return; }
44138
44262
 
44139
44263
  if (destroyChildren === undefined) { destroyChildren = true; }
44264
+ if (destroyTexture === undefined) { destroyTexture = false; }
44140
44265
 
44141
44266
  this.destroyPhase = true;
44142
44267
 
@@ -44243,6 +44368,12 @@ Phaser.Component.Destroy.prototype = {
44243
44368
 
44244
44369
  this._destroyCachedSprite();
44245
44370
 
44371
+ // Texture?
44372
+ if (destroyTexture)
44373
+ {
44374
+ this.texture.destroy(true);
44375
+ }
44376
+
44246
44377
  this.destroyPhase = false;
44247
44378
  this.pendingDestroy = false;
44248
44379
 
@@ -44578,7 +44709,7 @@ Phaser.Component.Health.prototype = {
44578
44709
  * @param {number} amount - The amount to subtract from the current `health` value.
44579
44710
  * @return {Phaser.Sprite} This instance.
44580
44711
  */
44581
- damage: function(amount) {
44712
+ damage: function (amount) {
44582
44713
 
44583
44714
  if (this.alive)
44584
44715
  {
@@ -44594,6 +44725,27 @@ Phaser.Component.Health.prototype = {
44594
44725
 
44595
44726
  },
44596
44727
 
44728
+ /**
44729
+ * Sets the health property of the Game Object to the given amount.
44730
+ * Will never exceed the `maxHealth` value.
44731
+ *
44732
+ * @member
44733
+ * @param {number} amount - The amount to set the `health` value to. The total will never exceed `maxHealth`.
44734
+ * @return {Phaser.Sprite} This instance.
44735
+ */
44736
+ setHealth: function (amount) {
44737
+
44738
+ this.health = amount;
44739
+
44740
+ if (this.health > this.maxHealth)
44741
+ {
44742
+ this.health = this.maxHealth;
44743
+ }
44744
+
44745
+ return this;
44746
+
44747
+ },
44748
+
44597
44749
  /**
44598
44750
  * Heal the Game Object. This adds the given amount of health to the `health` property.
44599
44751
  *
@@ -44601,7 +44753,7 @@ Phaser.Component.Health.prototype = {
44601
44753
  * @param {number} amount - The amount to add to the current `health` value. The total will never exceed `maxHealth`.
44602
44754
  * @return {Phaser.Sprite} This instance.
44603
44755
  */
44604
- heal: function(amount) {
44756
+ heal: function (amount) {
44605
44757
 
44606
44758
  if (this.alive)
44607
44759
  {
@@ -44928,20 +45080,20 @@ Phaser.Component.LifeSpan.prototype = {
44928
45080
  * It will dispatch the `onRevived` event. Listen to `events.onRevived` for the signal.
44929
45081
  *
44930
45082
  * @method
44931
- * @param {number} [health=1] - The health to give the Game Object. Only set if the GameObject has the Health component.
45083
+ * @param {number} [health=100] - The health to give the Game Object. Only set if the GameObject has the Health component.
44932
45084
  * @return {PIXI.DisplayObject} This instance.
44933
45085
  */
44934
45086
  revive: function (health) {
44935
45087
 
44936
- if (health === undefined) { health = 1; }
45088
+ if (health === undefined) { health = 100; }
44937
45089
 
44938
45090
  this.alive = true;
44939
45091
  this.exists = true;
44940
45092
  this.visible = true;
44941
45093
 
44942
- if (typeof this.heal === 'function')
45094
+ if (typeof this.setHealth === 'function')
44943
45095
  {
44944
- this.heal(health);
45096
+ this.setHealth(health);
44945
45097
  }
44946
45098
 
44947
45099
  if (this.events)
@@ -45019,6 +45171,13 @@ Phaser.Component.LoadTexture.prototype = {
45019
45171
  *
45020
45172
  * Calling this method causes a WebGL texture update, so use sparingly or in low-intensity portions of your game, or if you know the new texture is already on the GPU.
45021
45173
  *
45174
+ * You can use the new const `Phaser.PENDING_ATLAS` as the texture key for any sprite.
45175
+ * Doing this then sets the key to be the `frame` argument (the frame is set to zero).
45176
+ *
45177
+ * This allows you to create sprites using `load.image` during development, and then change them
45178
+ * to use a Texture Atlas later in development by simply searching your code for 'PENDING_ATLAS'
45179
+ * and swapping it to be the key of the atlas data.
45180
+ *
45022
45181
  * @method
45023
45182
  * @param {string|Phaser.RenderTexture|Phaser.BitmapData|Phaser.Video|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData, Video or PIXI.Texture.
45024
45183
  * @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
@@ -45026,7 +45185,15 @@ Phaser.Component.LoadTexture.prototype = {
45026
45185
  */
45027
45186
  loadTexture: function (key, frame, stopAnimation) {
45028
45187
 
45029
- frame = frame || 0;
45188
+ if (key === Phaser.PENDING_ATLAS)
45189
+ {
45190
+ key = frame;
45191
+ frame = 0;
45192
+ }
45193
+ else
45194
+ {
45195
+ frame = frame || 0;
45196
+ }
45030
45197
 
45031
45198
  if ((stopAnimation || stopAnimation === undefined) && this.animations)
45032
45199
  {
@@ -45078,6 +45245,15 @@ Phaser.Component.LoadTexture.prototype = {
45078
45245
  this.key = img.key;
45079
45246
  this.setTexture(new PIXI.Texture(img.base));
45080
45247
 
45248
+ if (key === '__default')
45249
+ {
45250
+ this.texture.baseTexture.skipRender = true;
45251
+ }
45252
+ else
45253
+ {
45254
+ this.texture.baseTexture.skipRender = false;
45255
+ }
45256
+
45081
45257
  setFrame = !this.animations.loadFrameData(img.frameData, frame);
45082
45258
  }
45083
45259
 
@@ -47544,7 +47720,7 @@ Phaser.SpriteBatch = function (game, parent, name, addToStage) {
47544
47720
 
47545
47721
  };
47546
47722
 
47547
- Phaser.SpriteBatch.prototype = Phaser.Utils.extend(true, Phaser.SpriteBatch.prototype, Phaser.Group.prototype, PIXI.SpriteBatch.prototype);
47723
+ Phaser.SpriteBatch.prototype = Phaser.Utils.extend(true, Phaser.SpriteBatch.prototype, PIXI.SpriteBatch.prototype, Phaser.Group.prototype);
47548
47724
 
47549
47725
  Phaser.SpriteBatch.prototype.constructor = Phaser.SpriteBatch;
47550
47726
 
@@ -47595,7 +47771,6 @@ Phaser.BitmapData = function (game, key, width, height) {
47595
47771
  * @property {HTMLCanvasElement} canvas - The canvas to which this BitmapData draws.
47596
47772
  * @default
47597
47773
  */
47598
- // this.canvas = Phaser.Canvas.create(width, height, '', true);
47599
47774
  this.canvas = PIXI.CanvasPool.create(this, width, height);
47600
47775
 
47601
47776
  /**
@@ -47763,10 +47938,10 @@ Phaser.BitmapData = function (game, key, width, height) {
47763
47938
  this._circle = new Phaser.Circle();
47764
47939
 
47765
47940
  /**
47766
- * @property {HTMLCanvasElement} _swapCanvas - A swap canvas.
47941
+ * @property {HTMLCanvasElement} _swapCanvas - A swap canvas. Used by moveH and moveV, created in those methods.
47767
47942
  * @private
47768
47943
  */
47769
- this._swapCanvas = PIXI.CanvasPool.create(this, width, height);
47944
+ this._swapCanvas = undefined;
47770
47945
 
47771
47946
  };
47772
47947
 
@@ -47813,6 +47988,11 @@ Phaser.BitmapData.prototype = {
47813
47988
 
47814
47989
  if (wrap === undefined) { wrap = true; }
47815
47990
 
47991
+ if (this._swapCanvas === undefined)
47992
+ {
47993
+ this._swapCanvas = PIXI.CanvasPool.create(this, this.width, this.height);
47994
+ }
47995
+
47816
47996
  var c = this._swapCanvas;
47817
47997
  var ctx = c.getContext('2d');
47818
47998
  var h = this.height;
@@ -47871,6 +48051,11 @@ Phaser.BitmapData.prototype = {
47871
48051
 
47872
48052
  if (wrap === undefined) { wrap = true; }
47873
48053
 
48054
+ if (this._swapCanvas === undefined)
48055
+ {
48056
+ this._swapCanvas = PIXI.CanvasPool.create(this, this.width, this.height);
48057
+ }
48058
+
47874
48059
  var c = this._swapCanvas;
47875
48060
  var ctx = c.getContext('2d');
47876
48061
  var w = this.width;
@@ -47991,6 +48176,9 @@ Phaser.BitmapData.prototype = {
47991
48176
  * You can optionally define the area to clear.
47992
48177
  * If the arguments are left empty it will clear the entire canvas.
47993
48178
  *
48179
+ * You may need to call BitmapData.update after this in order to clear out the pixel data,
48180
+ * but Phaser will not do this automatically for you.
48181
+ *
47994
48182
  * @method Phaser.BitmapData#clear
47995
48183
  * @param {number} [x=0] - The x coordinate of the top-left of the area to clear.
47996
48184
  * @param {number} [y=0] - The y coordinate of the top-left of the area to clear.
@@ -48007,8 +48195,6 @@ Phaser.BitmapData.prototype = {
48007
48195
 
48008
48196
  this.context.clearRect(x, y, width, height);
48009
48197
 
48010
- this.update();
48011
-
48012
48198
  this.dirty = true;
48013
48199
 
48014
48200
  return this;
@@ -48077,6 +48263,8 @@ Phaser.BitmapData.prototype = {
48077
48263
  * Resizes the BitmapData. This changes the size of the underlying canvas and refreshes the buffer.
48078
48264
  *
48079
48265
  * @method Phaser.BitmapData#resize
48266
+ * @param {integer} width - The new width of the BitmapData.
48267
+ * @param {integer} height - The new height of the BitmapData.
48080
48268
  * @return {Phaser.BitmapData} This BitmapData object for method chaining.
48081
48269
  */
48082
48270
  resize: function (width, height) {
@@ -48089,8 +48277,11 @@ Phaser.BitmapData.prototype = {
48089
48277
  this.canvas.width = width;
48090
48278
  this.canvas.height = height;
48091
48279
 
48092
- this._swapCanvas.width = width;
48093
- this._swapCanvas.height = height;
48280
+ if (this._swapCanvas !== undefined)
48281
+ {
48282
+ this._swapCanvas.width = width;
48283
+ this._swapCanvas.height = height;
48284
+ }
48094
48285
 
48095
48286
  this.baseTexture.width = width;
48096
48287
  this.baseTexture.height = height;
@@ -48117,6 +48308,8 @@ Phaser.BitmapData.prototype = {
48117
48308
  * It then re-builds the ArrayBuffer, the data Uint8ClampedArray reference and the pixels Int32Array.
48118
48309
  * If not given the dimensions defaults to the full size of the context.
48119
48310
  *
48311
+ * Warning: This is a very expensive operation, so use it sparingly.
48312
+ *
48120
48313
  * @method Phaser.BitmapData#update
48121
48314
  * @param {number} [x=0] - The x coordinate of the top-left of the image data area to grab from.
48122
48315
  * @param {number} [y=0] - The y coordinate of the top-left of the image data area to grab from.
@@ -48329,12 +48522,12 @@ Phaser.BitmapData.prototype = {
48329
48522
  * @return {Phaser.BitmapData} This BitmapData object for method chaining.
48330
48523
  */
48331
48524
  setHSL: function (h, s, l, region) {
48525
+
48526
+ var bHaveH = h || h === 0;
48527
+ var bHaveS = s || s === 0;
48528
+ var bHaveL = l || l === 0;
48332
48529
 
48333
- if (h === undefined || h === null) { h = false; }
48334
- if (s === undefined || s === null) { s = false; }
48335
- if (l === undefined || l === null) { l = false; }
48336
-
48337
- if (!h && !s && !l)
48530
+ if (!bHaveH && !bHaveS && !bHaveL)
48338
48531
  {
48339
48532
  return;
48340
48533
  }
@@ -48352,17 +48545,17 @@ Phaser.BitmapData.prototype = {
48352
48545
  {
48353
48546
  Phaser.Color.unpackPixel(this.getPixel32(x, y), pixel, true);
48354
48547
 
48355
- if (h)
48548
+ if (bHaveH)
48356
48549
  {
48357
48550
  pixel.h = h;
48358
48551
  }
48359
48552
 
48360
- if (s)
48553
+ if (bHaveS)
48361
48554
  {
48362
48555
  pixel.s = s;
48363
48556
  }
48364
48557
 
48365
- if (l)
48558
+ if (bHaveL)
48366
48559
  {
48367
48560
  pixel.l = l;
48368
48561
  }
@@ -48422,12 +48615,12 @@ Phaser.BitmapData.prototype = {
48422
48615
 
48423
48616
  if (s)
48424
48617
  {
48425
- pixel.s = this.game.math.limitValue(pixel.s + s, 0, 1);
48618
+ pixel.s = this.game.math.clamp(pixel.s + s, 0, 1);
48426
48619
  }
48427
48620
 
48428
48621
  if (l)
48429
48622
  {
48430
- pixel.l = this.game.math.limitValue(pixel.l + l, 0, 1);
48623
+ pixel.l = this.game.math.clamp(pixel.l + l, 0, 1);
48431
48624
  }
48432
48625
 
48433
48626
  Phaser.Color.HSLtoRGB(pixel.h, pixel.s, pixel.l, pixel);
@@ -48960,7 +49153,7 @@ Phaser.BitmapData.prototype = {
48960
49153
 
48961
49154
  /**
48962
49155
  * Draws the immediate children of a Phaser.Group to this BitmapData.
48963
- * Children are only drawn if they have their `exists` property set to `true`.
49156
+ * Children are only drawn if they have their `exists` property set to `true` and have image based Textures.
48964
49157
  * The children will be drawn at their `x` and `y` world space coordinates. If this is outside the bounds of the BitmapData they won't be drawn.
48965
49158
  * When drawing it will take into account the child's rotation, scale and alpha values.
48966
49159
  * No iteration takes place. Groups nested inside other Groups will not be iterated through.
@@ -48975,13 +49168,38 @@ Phaser.BitmapData.prototype = {
48975
49168
 
48976
49169
  if (group.total > 0)
48977
49170
  {
48978
- group.forEachExists(this.copy, this, null, null, null, null, null, null, null, null, null, null, null, null, null, null, blendMode, roundPx);
49171
+ group.forEachExists(this.drawGroupProxy, this, blendMode, roundPx);
48979
49172
  }
48980
49173
 
48981
49174
  return this;
48982
49175
 
48983
49176
  },
48984
49177
 
49178
+ /**
49179
+ * A proxy for drawGroup that handles child iteration for more complex Game Objects.
49180
+ *
49181
+ * @method Phaser.BitmapData#drawGroupProxy
49182
+ * @private
49183
+ * @param {Phaser.Sprite|Phaser.Image|Phaser.BitmapText} child - The child to draw.
49184
+ * @param {string} [blendMode=null] - The composite blend mode that will be used when drawing. The default is no blend mode at all. This is a Canvas globalCompositeOperation value such as 'lighter' or 'xor'.
49185
+ * @param {boolean} [roundPx=false] - Should the x and y values be rounded to integers before drawing? This prevents anti-aliasing in some instances.
49186
+ */
49187
+ drawGroupProxy: function (child, blendMode, roundPx) {
49188
+
49189
+ if (child.type === Phaser.EMITTER || child.type === Phaser.BITMAPTEXT)
49190
+ {
49191
+ for (var i = 0; i < child.children.length; i++)
49192
+ {
49193
+ this.copy(child.children[i], null, null, null, null, null, null, null, null, null, null, null, null, null, null, blendMode, roundPx);
49194
+ }
49195
+ }
49196
+ else
49197
+ {
49198
+ this.copy(child, null, null, null, null, null, null, null, null, null, null, null, null, null, null, blendMode, roundPx);
49199
+ }
49200
+
49201
+ },
49202
+
48985
49203
  /**
48986
49204
  * Draws the Game Object or Group to this BitmapData and then recursively iterates through all of its children.
48987
49205
  *
@@ -50172,9 +50390,10 @@ PIXI.Graphics.prototype.arcTo = function(x1, y1, x2, y2, radius)
50172
50390
  * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)
50173
50391
  * @param endAngle {Number} The ending angle, in radians
50174
50392
  * @param anticlockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.
50393
+ * @param segments {Number} Optional. The number of segments to use when calculating the arc. The default is 40. If you need more fidelity use a higher number.
50175
50394
  * @return {Graphics}
50176
50395
  */
50177
- PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, anticlockwise)
50396
+ PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, anticlockwise, segments)
50178
50397
  {
50179
50398
  // If we do this we can never draw a full circle
50180
50399
  if (startAngle === endAngle)
@@ -50183,6 +50402,7 @@ PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, ant
50183
50402
  }
50184
50403
 
50185
50404
  if (anticlockwise === undefined) { anticlockwise = false; }
50405
+ if (segments === undefined) { segments = 40; }
50186
50406
 
50187
50407
  if (!anticlockwise && endAngle <= startAngle)
50188
50408
  {
@@ -50194,7 +50414,7 @@ PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, ant
50194
50414
  }
50195
50415
 
50196
50416
  var sweep = anticlockwise ? (startAngle - endAngle) * -1 : (endAngle - startAngle);
50197
- var segs = Math.ceil(Math.abs(sweep) / (Math.PI * 2)) * 40;
50417
+ var segs = Math.ceil(Math.abs(sweep) / (Math.PI * 2)) * segments;
50198
50418
 
50199
50419
  // Sweep check - moved here because we don't want to do the moveTo below if the arc fails
50200
50420
  if (sweep === 0)
@@ -50410,19 +50630,26 @@ PIXI.Graphics.prototype.clear = function()
50410
50630
  * This can be quite useful if your geometry is complicated and needs to be reused multiple times.
50411
50631
  *
50412
50632
  * @method generateTexture
50413
- * @param resolution {Number} The resolution of the texture being generated
50414
- * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts
50633
+ * @param [resolution=1] {Number} The resolution of the texture being generated
50634
+ * @param [scaleMode=0] {Number} Should be one of the PIXI.scaleMode consts
50635
+ * @param [padding=0] {Number} Add optional extra padding to the generated texture (default 0)
50415
50636
  * @return {Texture} a texture of the graphics object
50416
50637
  */
50417
- PIXI.Graphics.prototype.generateTexture = function(resolution, scaleMode)
50638
+ PIXI.Graphics.prototype.generateTexture = function(resolution, scaleMode, padding)
50418
50639
  {
50419
- resolution = resolution || 1;
50640
+ if (resolution === undefined) { resolution = 1; }
50641
+ if (scaleMode === undefined) { scaleMode = PIXI.scaleModes.DEFAULT; }
50642
+ if (padding === undefined) { padding = 0; }
50420
50643
 
50421
50644
  var bounds = this.getBounds();
50645
+
50646
+ bounds.width += padding;
50647
+ bounds.height += padding;
50422
50648
 
50423
50649
  var canvasBuffer = new PIXI.CanvasBuffer(bounds.width * resolution, bounds.height * resolution);
50424
50650
 
50425
50651
  var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas, scaleMode);
50652
+
50426
50653
  texture.baseTexture.resolution = resolution;
50427
50654
 
50428
50655
  canvasBuffer.context.scale(resolution, resolution);
@@ -50972,9 +51199,11 @@ Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", {
50972
51199
  else
50973
51200
  {
50974
51201
  this.destroyCachedSprite();
50975
- this.dirty = true;
50976
51202
  }
50977
51203
 
51204
+ this.dirty = true;
51205
+ this.webGLDirty = true;
51206
+
50978
51207
  }
50979
51208
  });
50980
51209
 
@@ -51257,6 +51486,631 @@ PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
51257
51486
  return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) === sign;
51258
51487
  };
51259
51488
 
51489
+ /*
51490
+ Copyright (c) 2016, Mapbox
51491
+
51492
+ Permission to use, copy, modify, and/or distribute this software for any purpose
51493
+ with or without fee is hereby granted, provided that the above copyright notice
51494
+ and this permission notice appear in all copies.
51495
+
51496
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
51497
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
51498
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
51499
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
51500
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
51501
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
51502
+ THIS SOFTWARE.
51503
+ */
51504
+
51505
+ /**
51506
+ * @class EarCut
51507
+ */
51508
+ PIXI.EarCut = {};
51509
+
51510
+ PIXI.EarCut.Triangulate = function (data, holeIndices, dim) {
51511
+
51512
+ dim = dim || 2;
51513
+
51514
+ var hasHoles = holeIndices && holeIndices.length,
51515
+ outerLen = hasHoles ? holeIndices[0] * dim : data.length,
51516
+ outerNode = PIXI.EarCut.linkedList(data, 0, outerLen, dim, true),
51517
+ triangles = [];
51518
+
51519
+ if (!outerNode) return triangles;
51520
+
51521
+ var minX, minY, maxX, maxY, x, y, size;
51522
+
51523
+ if (hasHoles) outerNode = PIXI.EarCut.eliminateHoles(data, holeIndices, outerNode, dim);
51524
+
51525
+ // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
51526
+ if (data.length > 80 * dim) {
51527
+ minX = maxX = data[0];
51528
+ minY = maxY = data[1];
51529
+
51530
+ for (var i = dim; i < outerLen; i += dim) {
51531
+ x = data[i];
51532
+ y = data[i + 1];
51533
+ if (x < minX) minX = x;
51534
+ if (y < minY) minY = y;
51535
+ if (x > maxX) maxX = x;
51536
+ if (y > maxY) maxY = y;
51537
+ }
51538
+
51539
+ // minX, minY and size are later used to transform coords into integers for z-order calculation
51540
+ size = Math.max(maxX - minX, maxY - minY);
51541
+ }
51542
+
51543
+ PIXI.EarCut.earcutLinked(outerNode, triangles, dim, minX, minY, size);
51544
+
51545
+ return triangles;
51546
+ }
51547
+
51548
+ // create a circular doubly linked list from polygon points in the specified winding order
51549
+
51550
+ PIXI.EarCut.linkedList = function (data, start, end, dim, clockwise) {
51551
+ var sum = 0,
51552
+ i, j, last;
51553
+
51554
+ // calculate original winding order of a polygon ring
51555
+ for (i = start, j = end - dim; i < end; i += dim) {
51556
+ sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
51557
+ j = i;
51558
+ }
51559
+
51560
+ // link points into circular doubly-linked list in the specified winding order
51561
+ if (clockwise === (sum > 0)) {
51562
+ for (i = start; i < end; i += dim) last = PIXI.EarCut.insertNode(i, data[i], data[i + 1], last);
51563
+ } else {
51564
+ for (i = end - dim; i >= start; i -= dim) last = PIXI.EarCut.insertNode(i, data[i], data[i + 1], last);
51565
+ }
51566
+
51567
+ return last;
51568
+ }
51569
+
51570
+ // eliminate colinear or duplicate points
51571
+
51572
+ PIXI.EarCut.filterPoints = function (start, end) {
51573
+ if (!start) return start;
51574
+ if (!end) end = start;
51575
+
51576
+ var p = start,
51577
+ again;
51578
+ do {
51579
+ again = false;
51580
+
51581
+ if (!p.steiner && (PIXI.EarCut.equals(p, p.next) || PIXI.EarCut.area(p.prev, p, p.next) === 0)) {
51582
+ PIXI.EarCut.removeNode(p);
51583
+ p = end = p.prev;
51584
+ if (p === p.next) return null;
51585
+ again = true;
51586
+
51587
+ } else {
51588
+ p = p.next;
51589
+ }
51590
+ } while (again || p !== end);
51591
+
51592
+ return end;
51593
+ }
51594
+
51595
+ // main ear slicing loop which triangulates a polygon (given as a linked list)
51596
+
51597
+ PIXI.EarCut.earcutLinked = function (ear, triangles, dim, minX, minY, size, pass) {
51598
+ if (!ear) return;
51599
+
51600
+ // interlink polygon nodes in z-order
51601
+ if (!pass && size) PIXI.EarCut.indexCurve(ear, minX, minY, size);
51602
+
51603
+ var stop = ear,
51604
+ prev, next;
51605
+
51606
+ // iterate through ears, slicing them one by one
51607
+ while (ear.prev !== ear.next) {
51608
+ prev = ear.prev;
51609
+ next = ear.next;
51610
+
51611
+ if (size ? PIXI.EarCut.isEarHashed(ear, minX, minY, size) : PIXI.EarCut.isEar(ear)) {
51612
+ // cut off the triangle
51613
+ triangles.push(prev.i / dim);
51614
+ triangles.push(ear.i / dim);
51615
+ triangles.push(next.i / dim);
51616
+
51617
+ PIXI.EarCut.removeNode(ear);
51618
+
51619
+ // skipping the next vertice leads to less sliver triangles
51620
+ ear = next.next;
51621
+ stop = next.next;
51622
+
51623
+ continue;
51624
+ }
51625
+
51626
+ ear = next;
51627
+
51628
+ // if we looped through the whole remaining polygon and can't find any more ears
51629
+ if (ear === stop) {
51630
+ // try filtering points and slicing again
51631
+ if (!pass) {
51632
+ PIXI.EarCut.earcutLinked(PIXI.EarCut.filterPoints(ear), triangles, dim, minX, minY, size, 1);
51633
+
51634
+ // if this didn't work, try curing all small self-intersections locally
51635
+ } else if (pass === 1) {
51636
+ ear = PIXI.EarCut.cureLocalIntersections(ear, triangles, dim);
51637
+ PIXI.EarCut.earcutLinked(ear, triangles, dim, minX, minY, size, 2);
51638
+
51639
+ // as a last resort, try splitting the remaining polygon into two
51640
+ } else if (pass === 2) {
51641
+ PIXI.EarCut.splitEarcut(ear, triangles, dim, minX, minY, size);
51642
+ }
51643
+
51644
+ break;
51645
+ }
51646
+ }
51647
+ }
51648
+
51649
+ // check whether a polygon node forms a valid ear with adjacent nodes
51650
+
51651
+ PIXI.EarCut.isEar = function (ear) {
51652
+ var a = ear.prev,
51653
+ b = ear,
51654
+ c = ear.next;
51655
+
51656
+ if (PIXI.EarCut.area(a, b, c) >= 0) return false; // reflex, can't be an ear
51657
+
51658
+ // now make sure we don't have other points inside the potential ear
51659
+ var p = ear.next.next;
51660
+
51661
+ while (p !== ear.prev) {
51662
+ if (PIXI.EarCut.pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
51663
+ PIXI.EarCut.area(p.prev, p, p.next) >= 0) return false;
51664
+ p = p.next;
51665
+ }
51666
+
51667
+ return true;
51668
+ }
51669
+
51670
+ PIXI.EarCut.isEarHashed = function (ear, minX, minY, size) {
51671
+ var a = ear.prev,
51672
+ b = ear,
51673
+ c = ear.next;
51674
+
51675
+ if (PIXI.EarCut.area(a, b, c) >= 0) return false; // reflex, can't be an ear
51676
+
51677
+ // triangle bbox; min & max are calculated like this for speed
51678
+ var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
51679
+ minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
51680
+ maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
51681
+ maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);
51682
+
51683
+ // z-order range for the current triangle bbox;
51684
+ var minZ = PIXI.EarCut.zOrder(minTX, minTY, minX, minY, size),
51685
+ maxZ = PIXI.EarCut.zOrder(maxTX, maxTY, minX, minY, size);
51686
+
51687
+ // first look for points inside the triangle in increasing z-order
51688
+ var p = ear.nextZ;
51689
+
51690
+ while (p && p.z <= maxZ) {
51691
+ if (p !== ear.prev && p !== ear.next &&
51692
+ PIXI.EarCut.pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
51693
+ PIXI.EarCut.area(p.prev, p, p.next) >= 0) return false;
51694
+ p = p.nextZ;
51695
+ }
51696
+
51697
+ // then look for points in decreasing z-order
51698
+ p = ear.prevZ;
51699
+
51700
+ while (p && p.z >= minZ) {
51701
+ if (p !== ear.prev && p !== ear.next &&
51702
+ PIXI.EarCut.pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
51703
+ PIXI.EarCut.area(p.prev, p, p.next) >= 0) return false;
51704
+ p = p.prevZ;
51705
+ }
51706
+
51707
+ return true;
51708
+ }
51709
+
51710
+ // go through all polygon nodes and cure small local self-intersections
51711
+
51712
+ PIXI.EarCut.cureLocalIntersections = function (start, triangles, dim) {
51713
+ var p = start;
51714
+ do {
51715
+ var a = p.prev,
51716
+ b = p.next.next;
51717
+
51718
+ // a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2])
51719
+ if (PIXI.EarCut.intersects(a, p, p.next, b) && PIXI.EarCut.locallyInside(a, b) && PIXI.EarCut.locallyInside(b, a)) {
51720
+
51721
+ triangles.push(a.i / dim);
51722
+ triangles.push(p.i / dim);
51723
+ triangles.push(b.i / dim);
51724
+
51725
+ // remove two nodes involved
51726
+ PIXI.EarCut.removeNode(p);
51727
+ PIXI.EarCut.removeNode(p.next);
51728
+
51729
+ p = start = b;
51730
+ }
51731
+ p = p.next;
51732
+ } while (p !== start);
51733
+
51734
+ return p;
51735
+ }
51736
+
51737
+ // try splitting polygon into two and triangulate them independently
51738
+
51739
+ PIXI.EarCut.splitEarcut = function (start, triangles, dim, minX, minY, size) {
51740
+ // look for a valid diagonal that divides the polygon into two
51741
+ var a = start;
51742
+ do {
51743
+ var b = a.next.next;
51744
+ while (b !== a.prev) {
51745
+ if (a.i !== b.i && PIXI.EarCut.isValidDiagonal(a, b)) {
51746
+ // split the polygon in two by the diagonal
51747
+ var c = PIXI.EarCut.splitPolygon(a, b);
51748
+
51749
+ // filter colinear points around the cuts
51750
+ a = PIXI.EarCut.filterPoints(a, a.next);
51751
+ c = PIXI.EarCut.filterPoints(c, c.next);
51752
+
51753
+ // run earcut on each half
51754
+ PIXI.EarCut.earcutLinked(a, triangles, dim, minX, minY, size);
51755
+ PIXI.EarCut.earcutLinked(c, triangles, dim, minX, minY, size);
51756
+ return;
51757
+ }
51758
+ b = b.next;
51759
+ }
51760
+ a = a.next;
51761
+ } while (a !== start);
51762
+ }
51763
+
51764
+ // link every hole into the outer loop, producing a single-ring polygon without holes
51765
+
51766
+ PIXI.EarCut.eliminateHoles = function (data, holeIndices, outerNode, dim) {
51767
+ var queue = [],
51768
+ i, len, start, end, list;
51769
+
51770
+ for (i = 0, len = holeIndices.length; i < len; i++) {
51771
+ start = holeIndices[i] * dim;
51772
+ end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
51773
+ list = PIXI.EarCut.linkedList(data, start, end, dim, false);
51774
+ if (list === list.next) list.steiner = true;
51775
+ queue.push(PIXI.EarCut.getLeftmost(list));
51776
+ }
51777
+
51778
+ queue.sort(compareX);
51779
+
51780
+ // process holes from left to right
51781
+ for (i = 0; i < queue.length; i++) {
51782
+ PIXI.EarCut.eliminateHole(queue[i], outerNode);
51783
+ outerNode = PIXI.EarCut.filterPoints(outerNode, outerNode.next);
51784
+ }
51785
+
51786
+ return outerNode;
51787
+ }
51788
+
51789
+ PIXI.EarCut.compareX = function (a, b) {
51790
+ return a.x - b.x;
51791
+ }
51792
+
51793
+ // find a bridge between vertices that connects hole with an outer ring and and link it
51794
+
51795
+ PIXI.EarCut.eliminateHole = function (hole, outerNode) {
51796
+ outerNode = PIXI.EarCut.findHoleBridge(hole, outerNode);
51797
+ if (outerNode) {
51798
+ var b = PIXI.EarCut.splitPolygon(outerNode, hole);
51799
+ PIXI.EarCut.filterPoints(b, b.next);
51800
+ }
51801
+ }
51802
+
51803
+ // David Eberly's algorithm for finding a bridge between hole and outer polygon
51804
+
51805
+ PIXI.EarCut.findHoleBridge = function (hole, outerNode) {
51806
+ var p = outerNode,
51807
+ hx = hole.x,
51808
+ hy = hole.y,
51809
+ qx = -Infinity,
51810
+ m;
51811
+
51812
+ // find a segment intersected by a ray from the hole's leftmost point to the left;
51813
+ // segment's endpoint with lesser x will be potential connection point
51814
+ do {
51815
+ if (hy <= p.y && hy >= p.next.y) {
51816
+ var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
51817
+ if (x <= hx && x > qx) {
51818
+ qx = x;
51819
+ m = p.x < p.next.x ? p : p.next;
51820
+ }
51821
+ }
51822
+ p = p.next;
51823
+ } while (p !== outerNode);
51824
+
51825
+ if (!m) return null;
51826
+
51827
+ if (hole.x === m.x) return m.prev; // hole touches outer segment; pick lower endpoint
51828
+
51829
+ // look for points inside the triangle of hole point, segment intersection and endpoint;
51830
+ // if there are no points found, we have a valid connection;
51831
+ // otherwise choose the point of the minimum angle with the ray as connection point
51832
+
51833
+ var stop = m,
51834
+ tanMin = Infinity,
51835
+ tan;
51836
+
51837
+ p = m.next;
51838
+
51839
+ while (p !== stop) {
51840
+ if (hx >= p.x && p.x >= m.x &&
51841
+ PIXI.EarCut.pointInTriangle(hy < m.y ? hx : qx, hy, m.x, m.y, hy < m.y ? qx : hx, hy, p.x, p.y)) {
51842
+
51843
+ tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
51844
+
51845
+ if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && PIXI.EarCut.locallyInside(p, hole)) {
51846
+ m = p;
51847
+ tanMin = tan;
51848
+ }
51849
+ }
51850
+
51851
+ p = p.next;
51852
+ }
51853
+
51854
+ return m;
51855
+ }
51856
+
51857
+ // interlink polygon nodes in z-order
51858
+
51859
+ PIXI.EarCut.indexCurve = function (start, minX, minY, size) {
51860
+ var p = start;
51861
+ do {
51862
+ if (p.z === null) p.z = PIXI.EarCut.zOrder(p.x, p.y, minX, minY, size);
51863
+ p.prevZ = p.prev;
51864
+ p.nextZ = p.next;
51865
+ p = p.next;
51866
+ } while (p !== start);
51867
+
51868
+ p.prevZ.nextZ = null;
51869
+ p.prevZ = null;
51870
+
51871
+ PIXI.EarCut.sortLinked(p);
51872
+ }
51873
+
51874
+ // Simon Tatham's linked list merge sort algorithm
51875
+ // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
51876
+
51877
+ PIXI.EarCut.sortLinked = function (list) {
51878
+ var i, p, q, e, tail, numMerges, pSize, qSize,
51879
+ inSize = 1;
51880
+
51881
+ do {
51882
+ p = list;
51883
+ list = null;
51884
+ tail = null;
51885
+ numMerges = 0;
51886
+
51887
+ while (p) {
51888
+ numMerges++;
51889
+ q = p;
51890
+ pSize = 0;
51891
+ for (i = 0; i < inSize; i++) {
51892
+ pSize++;
51893
+ q = q.nextZ;
51894
+ if (!q) break;
51895
+ }
51896
+
51897
+ qSize = inSize;
51898
+
51899
+ while (pSize > 0 || (qSize > 0 && q)) {
51900
+
51901
+ if (pSize === 0) {
51902
+ e = q;
51903
+ q = q.nextZ;
51904
+ qSize--;
51905
+ } else if (qSize === 0 || !q) {
51906
+ e = p;
51907
+ p = p.nextZ;
51908
+ pSize--;
51909
+ } else if (p.z <= q.z) {
51910
+ e = p;
51911
+ p = p.nextZ;
51912
+ pSize--;
51913
+ } else {
51914
+ e = q;
51915
+ q = q.nextZ;
51916
+ qSize--;
51917
+ }
51918
+
51919
+ if (tail) tail.nextZ = e;
51920
+ else list = e;
51921
+
51922
+ e.prevZ = tail;
51923
+ tail = e;
51924
+ }
51925
+
51926
+ p = q;
51927
+ }
51928
+
51929
+ tail.nextZ = null;
51930
+ inSize *= 2;
51931
+
51932
+ } while (numMerges > 1);
51933
+
51934
+ return list;
51935
+ }
51936
+
51937
+ // z-order of a point given coords and size of the data bounding box
51938
+
51939
+ PIXI.EarCut.zOrder = function (x, y, minX, minY, size) {
51940
+ // coords are transformed into non-negative 15-bit integer range
51941
+ x = 32767 * (x - minX) / size;
51942
+ y = 32767 * (y - minY) / size;
51943
+
51944
+ x = (x | (x << 8)) & 0x00FF00FF;
51945
+ x = (x | (x << 4)) & 0x0F0F0F0F;
51946
+ x = (x | (x << 2)) & 0x33333333;
51947
+ x = (x | (x << 1)) & 0x55555555;
51948
+
51949
+ y = (y | (y << 8)) & 0x00FF00FF;
51950
+ y = (y | (y << 4)) & 0x0F0F0F0F;
51951
+ y = (y | (y << 2)) & 0x33333333;
51952
+ y = (y | (y << 1)) & 0x55555555;
51953
+
51954
+ return x | (y << 1);
51955
+ }
51956
+
51957
+ // find the leftmost node of a polygon ring
51958
+
51959
+ PIXI.EarCut.getLeftmost = function (start) {
51960
+ var p = start,
51961
+ leftmost = start;
51962
+ do {
51963
+ if (p.x < leftmost.x) leftmost = p;
51964
+ p = p.next;
51965
+ } while (p !== start);
51966
+
51967
+ return leftmost;
51968
+ }
51969
+
51970
+ // check if a point lies within a convex triangle
51971
+
51972
+ PIXI.EarCut.pointInTriangle = function (ax, ay, bx, by, cx, cy, px, py) {
51973
+ return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
51974
+ (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
51975
+ (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
51976
+ }
51977
+
51978
+ // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
51979
+
51980
+ PIXI.EarCut.isValidDiagonal = function (a, b) {
51981
+ return PIXI.EarCut.equals(a, b) || a.next.i !== b.i && a.prev.i !== b.i && !PIXI.EarCut.intersectsPolygon(a, b) &&
51982
+ PIXI.EarCut.locallyInside(a, b) && PIXI.EarCut.locallyInside(b, a) && PIXI.EarCut.middleInside(a, b);
51983
+ }
51984
+
51985
+ // signed area of a triangle
51986
+
51987
+ PIXI.EarCut.area = function (p, q, r) {
51988
+ return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
51989
+ }
51990
+
51991
+ // check if two points are equal
51992
+
51993
+ PIXI.EarCut.equals = function (p1, p2) {
51994
+ return p1.x === p2.x && p1.y === p2.y;
51995
+ }
51996
+
51997
+ // check if two segments intersect
51998
+
51999
+ PIXI.EarCut.intersects = function (p1, q1, p2, q2) {
52000
+ return PIXI.EarCut.area(p1, q1, p2) > 0 !== PIXI.EarCut.area(p1, q1, q2) > 0 &&
52001
+ PIXI.EarCut.area(p2, q2, p1) > 0 !== PIXI.EarCut.area(p2, q2, q1) > 0;
52002
+ }
52003
+
52004
+ // check if a polygon diagonal intersects any polygon segments
52005
+
52006
+ PIXI.EarCut.intersectsPolygon = function (a, b) {
52007
+ var p = a;
52008
+ do {
52009
+ if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
52010
+ PIXI.EarCut.intersects(p, p.next, a, b)) return true;
52011
+ p = p.next;
52012
+ } while (p !== a);
52013
+
52014
+ return false;
52015
+ }
52016
+
52017
+ // check if a polygon diagonal is locally inside the polygon
52018
+
52019
+ PIXI.EarCut.locallyInside = function (a, b) {
52020
+ return PIXI.EarCut.area(a.prev, a, a.next) < 0 ?
52021
+ PIXI.EarCut.area(a, b, a.next) >= 0 && PIXI.EarCut.area(a, a.prev, b) >= 0 :
52022
+ PIXI.EarCut.area(a, b, a.prev) < 0 || PIXI.EarCut.area(a, a.next, b) < 0;
52023
+ }
52024
+
52025
+ // check if the middle point of a polygon diagonal is inside the polygon
52026
+
52027
+ PIXI.EarCut.middleInside = function (a, b) {
52028
+ var p = a,
52029
+ inside = false,
52030
+ px = (a.x + b.x) / 2,
52031
+ py = (a.y + b.y) / 2;
52032
+ do {
52033
+ if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
52034
+ inside = !inside;
52035
+ p = p.next;
52036
+ } while (p !== a);
52037
+
52038
+ return inside;
52039
+ }
52040
+
52041
+ // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
52042
+ // if one belongs to the outer ring and another to a hole, it merges it into a single ring
52043
+
52044
+ PIXI.EarCut.splitPolygon = function (a, b) {
52045
+ var a2 = new PIXI.EarCut.Node(a.i, a.x, a.y),
52046
+ b2 = new PIXI.EarCut.Node(b.i, b.x, b.y),
52047
+ an = a.next,
52048
+ bp = b.prev;
52049
+
52050
+ a.next = b;
52051
+ b.prev = a;
52052
+
52053
+ a2.next = an;
52054
+ an.prev = a2;
52055
+
52056
+ b2.next = a2;
52057
+ a2.prev = b2;
52058
+
52059
+ bp.next = b2;
52060
+ b2.prev = bp;
52061
+
52062
+ return b2;
52063
+ }
52064
+
52065
+ // create a node and optionally link it with previous one (in a circular doubly linked list)
52066
+
52067
+ PIXI.EarCut.insertNode = function (i, x, y, last) {
52068
+ var p = new PIXI.EarCut.Node(i, x, y);
52069
+
52070
+ if (!last) {
52071
+ p.prev = p;
52072
+ p.next = p;
52073
+
52074
+ } else {
52075
+ p.next = last.next;
52076
+ p.prev = last;
52077
+ last.next.prev = p;
52078
+ last.next = p;
52079
+ }
52080
+ return p;
52081
+ }
52082
+
52083
+ PIXI.EarCut.removeNode = function (p) {
52084
+ p.next.prev = p.prev;
52085
+ p.prev.next = p.next;
52086
+
52087
+ if (p.prevZ) p.prevZ.nextZ = p.nextZ;
52088
+ if (p.nextZ) p.nextZ.prevZ = p.prevZ;
52089
+ }
52090
+
52091
+ PIXI.EarCut.Node = function (i, x, y) {
52092
+ // vertice index in coordinates array
52093
+ this.i = i;
52094
+
52095
+ // vertex coordinates
52096
+ this.x = x;
52097
+ this.y = y;
52098
+
52099
+ // previous and next vertice nodes in a polygon ring
52100
+ this.prev = null;
52101
+ this.next = null;
52102
+
52103
+ // z-order curve value
52104
+ this.z = null;
52105
+
52106
+ // previous and next nodes in z-order
52107
+ this.prevZ = null;
52108
+ this.nextZ = null;
52109
+
52110
+ // indicates whether this is a steiner point
52111
+ this.steiner = false;
52112
+ }
52113
+
51260
52114
  /**
51261
52115
  * @author Mat Groves http://matgroves.com/ @Doormat23
51262
52116
  */
@@ -51272,6 +52126,13 @@ PIXI.WebGLGraphics = function()
51272
52126
  {
51273
52127
  };
51274
52128
 
52129
+ /**
52130
+ * The number of points beyond which Pixi swaps to using the Stencil Buffer to render the Graphics.
52131
+ *
52132
+ * @type {number}
52133
+ */
52134
+ PIXI.WebGLGraphics.stencilBufferLimit = 6;
52135
+
51275
52136
  /**
51276
52137
  * Renders the graphics object
51277
52138
  *
@@ -51406,9 +52267,9 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics, gl)
51406
52267
  // MAKE SURE WE HAVE THE CORRECT TYPE..
51407
52268
  if(data.fill)
51408
52269
  {
51409
- if(data.points.length >= 6)
52270
+ if(data.points.length >= PIXI.WebGLGraphics.stencilBufferLimit)
51410
52271
  {
51411
- if(data.points.length < 6 * 2)
52272
+ if(data.points.length < PIXI.WebGLGraphics.stencilBufferLimit * 2)
51412
52273
  {
51413
52274
  webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0);
51414
52275
 
@@ -51533,7 +52394,7 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
51533
52394
  var verts = webGLData.points;
51534
52395
  var indices = webGLData.indices;
51535
52396
 
51536
- var vertPos = verts.length/6;
52397
+ var vertPos = verts.length / 6;
51537
52398
 
51538
52399
  // start
51539
52400
  verts.push(x, y);
@@ -51549,10 +52410,10 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
51549
52410
  verts.push(r, g, b, alpha);
51550
52411
 
51551
52412
  // insert 2 dead triangles..
51552
- indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3);
52413
+ indices.push(vertPos, vertPos, vertPos + 1, vertPos + 2, vertPos + 3, vertPos + 3);
51553
52414
  }
51554
52415
 
51555
- if(graphicsData.lineWidth)
52416
+ if (graphicsData.lineWidth)
51556
52417
  {
51557
52418
  var tempPoints = graphicsData.points;
51558
52419
 
@@ -51606,13 +52467,12 @@ PIXI.WebGLGraphics.buildRoundedRectangle = function(graphicsData, webGLData)
51606
52467
  var verts = webGLData.points;
51607
52468
  var indices = webGLData.indices;
51608
52469
 
51609
- var vecPos = verts.length/6;
52470
+ var vecPos = verts.length / 6;
51610
52471
 
51611
- var triangles = PIXI.PolyK.Triangulate(recPoints);
52472
+ var triangles = PIXI.EarCut.Triangulate(recPoints, null, 2);
51612
52473
 
51613
- //
51614
-
51615
52474
  var i = 0;
52475
+
51616
52476
  for (i = 0; i < triangles.length; i+=3)
51617
52477
  {
51618
52478
  indices.push(triangles[i] + vecPos);
@@ -51739,7 +52599,7 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
51739
52599
  var verts = webGLData.points;
51740
52600
  var indices = webGLData.indices;
51741
52601
 
51742
- var vecPos = verts.length/6;
52602
+ var vecPos = verts.length / 6;
51743
52603
 
51744
52604
  indices.push(vecPos);
51745
52605
 
@@ -52076,7 +52936,7 @@ PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData)
52076
52936
  var g = color[1] * alpha;
52077
52937
  var b = color[2] * alpha;
52078
52938
 
52079
- var triangles = PIXI.PolyK.Triangulate(points);
52939
+ var triangles = PIXI.EarCut.Triangulate(points, null, 2);
52080
52940
 
52081
52941
  if(!triangles)return false;
52082
52942
 
@@ -52903,7 +53763,7 @@ Phaser.Text = function (game, x, y, text, style) {
52903
53763
  text = text.toString();
52904
53764
  }
52905
53765
 
52906
- style = style || {};
53766
+ style = Phaser.Utils.extend({}, style);
52907
53767
 
52908
53768
  /**
52909
53769
  * @property {number} type - The const type of this object.
@@ -52970,6 +53830,19 @@ Phaser.Text = function (game, x, y, text, style) {
52970
53830
  */
52971
53831
  this.autoRound = false;
52972
53832
 
53833
+ /**
53834
+ * Will this Text object use Basic or Advanced Word Wrapping?
53835
+ *
53836
+ * Advanced wrapping breaks long words if they are the first of a line, and repeats the process as necessary.
53837
+ * White space is condensed (e.g., consecutive spaces are replaced with one).
53838
+ * Lines are trimmed of white space before processing.
53839
+ *
53840
+ * It throws an error if wordWrapWidth is less than a single character.
53841
+ * @property {boolean} useAdvancedWrap
53842
+ * @default
53843
+ */
53844
+ this.useAdvancedWrap = false;
53845
+
52973
53846
  /**
52974
53847
  * @property {number} _res - Internal canvas resolution var.
52975
53848
  * @private
@@ -53279,8 +54152,7 @@ Phaser.Text.prototype.updateText = function () {
53279
54152
  // Adjust for line spacing
53280
54153
  if (lineSpacing !== 0)
53281
54154
  {
53282
- var diff = lineSpacing * (lines.length - 1);
53283
- height += diff;
54155
+ height += lineSpacing * lines.length;
53284
54156
  }
53285
54157
 
53286
54158
  this.canvas.height = height * this._res;
@@ -53658,6 +54530,28 @@ Phaser.Text.prototype.addFontWeight = function (weight, position) {
53658
54530
 
53659
54531
  };
53660
54532
 
54533
+ /**
54534
+ * Runs the given text through the Text.runWordWrap function and returns
54535
+ * the results as an array, where each element of the array corresponds to a wrapped
54536
+ * line of text.
54537
+ *
54538
+ * Useful if you wish to control pagination on long pieces of content.
54539
+ *
54540
+ * @method Phaser.Text#precalculateWordWrap
54541
+ * @param {string} text - The text for which the wrapping will be calculated.
54542
+ * @return {array} An array of strings with the pieces of wrapped text.
54543
+ */
54544
+ Phaser.Text.prototype.precalculateWordWrap = function (text) {
54545
+
54546
+ this.texture.baseTexture.resolution = this._res;
54547
+ this.context.font = this.style.font;
54548
+
54549
+ var wrappedLines = this.runWordWrap(text);
54550
+
54551
+ return wrappedLines.split(/(?:\r\n|\r|\n)/);
54552
+
54553
+ };
54554
+
53661
54555
  /**
53662
54556
  * Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal bounds.
53663
54557
  *
@@ -53667,6 +54561,150 @@ Phaser.Text.prototype.addFontWeight = function (weight, position) {
53667
54561
  */
53668
54562
  Phaser.Text.prototype.runWordWrap = function (text) {
53669
54563
 
54564
+ if (this.useAdvancedWrap)
54565
+ {
54566
+ return this.advancedWordWrap(text);
54567
+ }
54568
+ else
54569
+ {
54570
+ return this.basicWordWrap(text);
54571
+ }
54572
+
54573
+ };
54574
+
54575
+ /**
54576
+ * Advanced wrapping algorithm that will wrap words as the line grows longer than its horizontal bounds.
54577
+ * White space is condensed (e.g., consecutive spaces are replaced with one).
54578
+ * Lines are trimmed of white space before processing.
54579
+ * Throws an error if the user was smart enough to specify a wordWrapWidth less than a single character.
54580
+ *
54581
+ * @method Phaser.Text#advancedWordWrap
54582
+ * @param {string} text - The text to perform word wrap detection against.
54583
+ * @private
54584
+ */
54585
+ Phaser.Text.prototype.advancedWordWrap = function (text) {
54586
+
54587
+ var context = this.context;
54588
+ var wordWrapWidth = this.style.wordWrapWidth;
54589
+
54590
+ var output = '';
54591
+
54592
+ // (1) condense whitespace
54593
+ // (2) split into lines
54594
+ var lines = text
54595
+ .replace(/ +/gi, ' ')
54596
+ .split(/\r?\n/gi);
54597
+
54598
+ var linesCount = lines.length;
54599
+
54600
+ for (var i = 0; i < linesCount; i++)
54601
+ {
54602
+ var line = lines[i];
54603
+ var out = '';
54604
+
54605
+ // trim whitespace
54606
+ line = line.replace(/^ *|\s*$/gi, '');
54607
+
54608
+ // if entire line is less than wordWrapWidth
54609
+ // append the entire line and exit early
54610
+ var lineWidth = context.measureText(line).width;
54611
+
54612
+ if (lineWidth < wordWrapWidth)
54613
+ {
54614
+ output += line + '\n';
54615
+ continue;
54616
+ }
54617
+
54618
+ // otherwise, calculate new lines
54619
+ var currentLineWidth = wordWrapWidth;
54620
+
54621
+ // split into words
54622
+ var words = line.split(' ');
54623
+
54624
+ for (var j = 0; j < words.length; j++)
54625
+ {
54626
+ var word = words[j];
54627
+ var wordWithSpace = word + ' ';
54628
+ var wordWidth = context.measureText(wordWithSpace).width;
54629
+
54630
+ if (wordWidth > currentLineWidth)
54631
+ {
54632
+ // break word
54633
+ if (j === 0)
54634
+ {
54635
+ // shave off letters from word until it's small enough
54636
+ var newWord = wordWithSpace;
54637
+
54638
+ while (newWord.length)
54639
+ {
54640
+ newWord = newWord.slice(0, -1);
54641
+ wordWidth = context.measureText(newWord).width;
54642
+
54643
+ if (wordWidth <= currentLineWidth)
54644
+ {
54645
+ break;
54646
+ }
54647
+ }
54648
+
54649
+ // if wordWrapWidth is too small for even a single
54650
+ // letter, shame user failure with a fatal error
54651
+ if (!newWord.length)
54652
+ {
54653
+ throw new Error('This text\'s wordWrapWidth setting is less than a single character!');
54654
+ }
54655
+
54656
+ // replace current word in array with remainder
54657
+ var secondPart = word.substr(newWord.length);
54658
+
54659
+ words[j] = secondPart;
54660
+
54661
+ // append first piece to output
54662
+ out += newWord;
54663
+ }
54664
+
54665
+ // if existing word length is 0, don't include it
54666
+ var offset = (words[j].length) ? j : j + 1;
54667
+
54668
+ // collapse rest of sentence
54669
+ var remainder = words.slice(offset).join(' ')
54670
+ // remove any trailing white space
54671
+ .replace(/[ \n]*$/gi, '');
54672
+
54673
+ // prepend remainder to next line
54674
+ lines[i + 1] = remainder + ' ' + (lines[i + 1] || '');
54675
+ linesCount = lines.length;
54676
+
54677
+ break; // processing on this line
54678
+
54679
+ // append word with space to output
54680
+ }
54681
+ else
54682
+ {
54683
+ out += wordWithSpace;
54684
+ currentLineWidth -= wordWidth;
54685
+ }
54686
+ }
54687
+
54688
+ // append processed line to output
54689
+ output += out.replace(/[ \n]*$/gi, '') + '\n';
54690
+ }
54691
+
54692
+ // trim the end of the string
54693
+ output = output.replace(/[\s|\n]*$/gi, '');
54694
+
54695
+ return output;
54696
+
54697
+ };
54698
+
54699
+ /**
54700
+ * Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal bounds.
54701
+ *
54702
+ * @method Phaser.Text#basicWordWrap
54703
+ * @param {string} text - The text to perform word wrap detection against.
54704
+ * @private
54705
+ */
54706
+ Phaser.Text.prototype.basicWordWrap = function (text) {
54707
+
53670
54708
  var result = '';
53671
54709
  var lines = text.split('\n');
53672
54710
 
@@ -55100,10 +56138,12 @@ Phaser.BitmapText.prototype.scanLine = function (data, scale, text) {
55100
56138
 
55101
56139
  var c = 0;
55102
56140
 
55103
- if (!charData)
56141
+ // If the character data isn't found in the data array
56142
+ // then we replace it with a blank space
56143
+ if (charData === undefined)
55104
56144
  {
55105
- // Skip a character not found in the font data
55106
- continue;
56145
+ charCode = 32;
56146
+ charData = data.chars[charCode];
55107
56147
  }
55108
56148
 
55109
56149
  // Adjust for kerning from previous character to this one
@@ -55123,11 +56163,11 @@ Phaser.BitmapText.prototype.scanLine = function (data, scale, text) {
55123
56163
  }
55124
56164
  else
55125
56165
  {
55126
- w += charData.xAdvance * scale;
56166
+ w += (charData.xAdvance + kerning) * scale;
55127
56167
 
55128
- chars.push(x + (charData.xOffset * scale));
56168
+ chars.push(x + (charData.xOffset + kerning) * scale);
55129
56169
 
55130
- x += charData.xAdvance * scale;
56170
+ x += (charData.xAdvance + kerning) * scale;
55131
56171
 
55132
56172
  prevCharCode = charCode;
55133
56173
  }
@@ -55138,6 +56178,58 @@ Phaser.BitmapText.prototype.scanLine = function (data, scale, text) {
55138
56178
 
55139
56179
  };
55140
56180
 
56181
+ /**
56182
+ * Given a text string this will scan each character in the string to ensure it exists
56183
+ * in the BitmapText font data. If it doesn't the character is removed, or replaced with the `replace` argument.
56184
+ *
56185
+ * If no font data has been loaded at all this returns an empty string, as nothing can be rendered.
56186
+ *
56187
+ * @method Phaser.BitmapText.prototype.cleanText
56188
+ * @param {string} text - The text to parse.
56189
+ * @param {string} [replace=''] - The replacement string for any missing characters.
56190
+ * @return {string} The cleaned text string.
56191
+ */
56192
+ Phaser.BitmapText.prototype.cleanText = function (text, replace) {
56193
+
56194
+ if (replace === undefined)
56195
+ {
56196
+ replace = '';
56197
+ }
56198
+
56199
+ var data = this._data.font;
56200
+
56201
+ if (!data)
56202
+ {
56203
+ return '';
56204
+ }
56205
+
56206
+ var re = /\r\n|\n\r|\n|\r/g;
56207
+ var lines = text.replace(re, "\n").split("\n");
56208
+
56209
+ for (var i = 0; i < lines.length; i++)
56210
+ {
56211
+ var output = '';
56212
+ var line = lines[i];
56213
+
56214
+ for (var c = 0; c < line.length; c++)
56215
+ {
56216
+ if (data.chars[line.charCodeAt(c)])
56217
+ {
56218
+ output = output.concat(line[c]);
56219
+ }
56220
+ else
56221
+ {
56222
+ output = output.concat(replace);
56223
+ }
56224
+ }
56225
+
56226
+ lines[i] = output;
56227
+ }
56228
+
56229
+ return lines.join("\n");
56230
+
56231
+ };
56232
+
55141
56233
  /**
55142
56234
  * Renders text and updates it when needed.
55143
56235
  *
@@ -55205,6 +56297,12 @@ Phaser.BitmapText.prototype.updateText = function () {
55205
56297
  var charCode = line.text.charCodeAt(c);
55206
56298
  var charData = data.chars[charCode];
55207
56299
 
56300
+ if (charData === undefined)
56301
+ {
56302
+ charCode = 32;
56303
+ charData = data.chars[charCode];
56304
+ }
56305
+
55208
56306
  var g = this._glyphs[t];
55209
56307
 
55210
56308
  if (g)
@@ -56068,7 +57166,7 @@ Object.defineProperty(Phaser.RetroFont.prototype, "text", {
56068
57166
 
56069
57167
  /**
56070
57168
  * @name Phaser.RetroFont#smoothed
56071
- * @property {string} text - Set this value to update the text in this sprite. Carriage returns are automatically stripped out if multiLine is false. Text is converted to upper case if autoUpperCase is true.
57169
+ * @property {boolean} smoothed - Sets if the stamp is smoothed or not.
56072
57170
  */
56073
57171
  Object.defineProperty(Phaser.RetroFont.prototype, "smoothed", {
56074
57172
 
@@ -56220,7 +57318,7 @@ Phaser.Rope.prototype.update = function() {
56220
57318
  * @memberof Phaser.Rope
56221
57319
  * @param {number} x - The x coordinate (in world space) to position the Sprite at.
56222
57320
  * @param {number} y - The y coordinate (in world space) to position the Sprite at.
56223
- * @return (Phaser.Rope) This instance.
57321
+ * @return {Phaser.Rope} This instance.
56224
57322
  */
56225
57323
  Phaser.Rope.prototype.reset = function(x, y) {
56226
57324
 
@@ -56499,7 +57597,7 @@ Phaser.TileSprite.prototype.destroy = function(destroyChildren) {
56499
57597
  * @memberof Phaser.TileSprite
56500
57598
  * @param {number} x - The x coordinate (in world space) to position the Sprite at.
56501
57599
  * @param {number} y - The y coordinate (in world space) to position the Sprite at.
56502
- * @return (Phaser.TileSprite) This instance.
57600
+ * @return {Phaser.TileSprite} This instance.
56503
57601
  */
56504
57602
  Phaser.TileSprite.prototype.reset = function(x, y) {
56505
57603
 
@@ -56824,6 +57922,12 @@ Phaser.Device = function () {
56824
57922
  */
56825
57923
  this.tridentVersion = 0;
56826
57924
 
57925
+ /**
57926
+ * @property {boolean} edge - Set to true if running in Microsoft Edge browser.
57927
+ * @default
57928
+ */
57929
+ this.edge = false;
57930
+
56827
57931
  /**
56828
57932
  * @property {boolean} mobileSafari - Set to true if running in Mobile Safari.
56829
57933
  * @default
@@ -56848,6 +57952,12 @@ Phaser.Device = function () {
56848
57952
  */
56849
57953
  this.safari = false;
56850
57954
 
57955
+ /**
57956
+ * @property {number} safariVersion - If running in Safari this will contain the major version number.
57957
+ * @default
57958
+ */
57959
+ this.safariVersion = 0;
57960
+
56851
57961
  /**
56852
57962
  * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView
56853
57963
  * @default
@@ -56911,6 +58021,12 @@ Phaser.Device = function () {
56911
58021
  */
56912
58022
  this.webm = false;
56913
58023
 
58024
+ /**
58025
+ * @property {boolean} dolby - Can this device play EC-3 Dolby Digital Plus files?
58026
+ * @default
58027
+ */
58028
+ this.dolby = false;
58029
+
56914
58030
  // Video
56915
58031
 
56916
58032
  /**
@@ -57379,6 +58495,10 @@ Phaser.Device._initialize = function () {
57379
58495
  {
57380
58496
  device.arora = true;
57381
58497
  }
58498
+ else if (/Edge\/\d+/.test(ua))
58499
+ {
58500
+ device.edge = true;
58501
+ }
57382
58502
  else if (/Chrome\/(\d+)/.test(ua) && !device.windowsPhone)
57383
58503
  {
57384
58504
  device.chrome = true;
@@ -57410,9 +58530,14 @@ Phaser.Device._initialize = function () {
57410
58530
  {
57411
58531
  device.opera = true;
57412
58532
  }
57413
- else if (/Safari/.test(ua) && !device.windowsPhone)
58533
+ else if (/Safari\/(\d+)/.test(ua) && !device.windowsPhone)
57414
58534
  {
57415
58535
  device.safari = true;
58536
+
58537
+ if (/Version\/(\d+)\./.test(ua))
58538
+ {
58539
+ device.safariVersion = parseInt(RegExp.$1, 10);
58540
+ }
57416
58541
  }
57417
58542
  else if (/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/.test(ua))
57418
58543
  {
@@ -57565,6 +58690,27 @@ Phaser.Device._initialize = function () {
57565
58690
  {
57566
58691
  device.webm = true;
57567
58692
  }
58693
+
58694
+ if (audioElement.canPlayType('audio/mp4;codecs="ec-3"') !== '')
58695
+ {
58696
+ if (device.edge)
58697
+ {
58698
+ device.dolby = true;
58699
+ }
58700
+ else if (device.safari && device.safariVersion >= 9)
58701
+ {
58702
+ if (/Mac OS X (\d+)_(\d+)/.test(navigator.userAgent))
58703
+ {
58704
+ var major = parseInt(RegExp.$1, 10);
58705
+ var minor = parseInt(RegExp.$2, 10);
58706
+
58707
+ if ((major === 10 && minor >= 11) || major > 10)
58708
+ {
58709
+ device.dolby = true;
58710
+ }
58711
+ }
58712
+ }
58713
+ }
57568
58714
  }
57569
58715
  } catch (e) {
57570
58716
  }
@@ -57702,9 +58848,9 @@ Phaser.Device._initialize = function () {
57702
58848
 
57703
58849
  // Run the checks
57704
58850
  _checkOS();
58851
+ _checkBrowser();
57705
58852
  _checkAudio();
57706
58853
  _checkVideo();
57707
- _checkBrowser();
57708
58854
  _checkCSS3D();
57709
58855
  _checkDevice();
57710
58856
  _checkFeatures();
@@ -57747,6 +58893,10 @@ Phaser.Device.canPlayAudio = function (type) {
57747
58893
  {
57748
58894
  return true;
57749
58895
  }
58896
+ else if (type === 'mp4' && this.dolby)
58897
+ {
58898
+ return true;
58899
+ }
57750
58900
 
57751
58901
  return false;
57752
58902
 
@@ -60729,13 +61879,13 @@ Phaser.Tween = function (target, game, manager) {
60729
61879
  * Is this Tween frame or time based? A frame based tween will use the physics elapsed timer when updating. This means
60730
61880
  * it will retain the same consistent frame rate, regardless of the speed of the device. The duration value given should
60731
61881
  * be given in frames.
60732
- *
61882
+ *
60733
61883
  * If the Tween uses a time based update (which is the default) then the duration is given in milliseconds.
60734
61884
  * In this situation a 2000ms tween will last exactly 2 seconds, regardless of the device and how many visual updates the tween
60735
61885
  * has actually been through. For very short tweens you may wish to experiment with a frame based update instead.
60736
61886
  *
60737
61887
  * The default value is whatever you've set in TweenManager.frameBased.
60738
- *
61888
+ *
60739
61889
  * @property {boolean} frameBased
60740
61890
  * @default
60741
61891
  */
@@ -60789,7 +61939,7 @@ Phaser.Tween.prototype = {
60789
61939
  * @param {function|string} [ease=null] - Easing function. If not set it will default to Phaser.Easing.Default, which is Phaser.Easing.Linear.None by default but can be over-ridden.
60790
61940
  * @param {boolean} [autoStart=false] - Set to `true` to allow this tween to start automatically. Otherwise call Tween.start().
60791
61941
  * @param {number} [delay=0] - Delay before this tween will start in milliseconds. Defaults to 0, no delay.
60792
- * @param {number} [repeat=0] - Should the tween automatically restart once complete? If you want it to run forever set as -1. This only effects this induvidual tween, not any chained tweens.
61942
+ * @param {number} [repeat=0] - Should the tween automatically restart once complete? If you want it to run forever set as -1. This only effects this individual tween, not any chained tweens.
60793
61943
  * @param {boolean} [yoyo=false] - A tween that yoyos will reverse itself and play backwards automatically. A yoyo'd tween doesn't fire the Tween.onComplete event, so listen for Tween.onLoop instead.
60794
61944
  * @return {Phaser.Tween} This Tween object.
60795
61945
  */
@@ -60836,7 +61986,7 @@ Phaser.Tween.prototype = {
60836
61986
  * @param {function|string} [ease=null] - Easing function. If not set it will default to Phaser.Easing.Default, which is Phaser.Easing.Linear.None by default but can be over-ridden.
60837
61987
  * @param {boolean} [autoStart=false] - Set to `true` to allow this tween to start automatically. Otherwise call Tween.start().
60838
61988
  * @param {number} [delay=0] - Delay before this tween will start in milliseconds. Defaults to 0, no delay.
60839
- * @param {number} [repeat=0] - Should the tween automatically restart once complete? If you want it to run forever set as -1. This only effects this induvidual tween, not any chained tweens.
61989
+ * @param {number} [repeat=0] - Should the tween automatically restart once complete? If you want it to run forever set as -1. This only effects this individual tween, not any chained tweens.
60840
61990
  * @param {boolean} [yoyo=false] - A tween that yoyos will reverse itself and play backwards automatically. A yoyo'd tween doesn't fire the Tween.onComplete event, so listen for Tween.onLoop instead.
60841
61991
  * @return {Phaser.Tween} This Tween object.
60842
61992
  */
@@ -60948,6 +62098,7 @@ Phaser.Tween.prototype = {
60948
62098
  if (complete)
60949
62099
  {
60950
62100
  this.onComplete.dispatch(this.target, this);
62101
+ this._hasStarted = false;
60951
62102
 
60952
62103
  if (this.chainedTween)
60953
62104
  {
@@ -61353,7 +62504,14 @@ Phaser.Tween.prototype = {
61353
62504
  }
61354
62505
  else if (status === Phaser.TweenData.LOOPED)
61355
62506
  {
61356
- this.onLoop.dispatch(this.target, this);
62507
+ if (this.repeatCounter === -1)
62508
+ {
62509
+ this.onLoop.dispatch(this.target, this);
62510
+ }
62511
+ else
62512
+ {
62513
+ this.onRepeat.dispatch(this.target, this);
62514
+ }
61357
62515
  return true;
61358
62516
  }
61359
62517
  else if (status === Phaser.TweenData.COMPLETE)
@@ -61388,7 +62546,7 @@ Phaser.Tween.prototype = {
61388
62546
  if (this.repeatCounter === -1)
61389
62547
  {
61390
62548
  this.timeline[this.current].start();
61391
- this.onRepeat.dispatch(this.target, this);
62549
+ this.onLoop.dispatch(this.target, this);
61392
62550
  return true;
61393
62551
  }
61394
62552
  else if (this.repeatCounter > 0)
@@ -61404,6 +62562,7 @@ Phaser.Tween.prototype = {
61404
62562
  // No more repeats and no more children, so we're done
61405
62563
  this.isRunning = false;
61406
62564
  this.onComplete.dispatch(this.target, this);
62565
+ this._hasStarted = false;
61407
62566
 
61408
62567
  if (this.chainedTween)
61409
62568
  {
@@ -62001,6 +63160,15 @@ Phaser.TweenData.prototype = {
62001
63160
  // We're already in reverse mode, which means the yoyo has finished and there's no repeats, so end
62002
63161
  if (this.inReverse && this.repeatCounter === 0)
62003
63162
  {
63163
+ // Restore the properties
63164
+ for (var property in this.vStartCache)
63165
+ {
63166
+ this.vStart[property] = this.vStartCache[property];
63167
+ this.vEnd[property] = this.vEndCache[property];
63168
+ }
63169
+
63170
+ this.inReverse = false;
63171
+
62004
63172
  return Phaser.TweenData.COMPLETE;
62005
63173
  }
62006
63174
 
@@ -64420,20 +65588,9 @@ Phaser.AnimationManager.prototype = {
64420
65588
 
64421
65589
  if (resetFrame === undefined) { resetFrame = false; }
64422
65590
 
64423
- if (typeof name === 'string')
65591
+ if (this.currentAnim && (typeof name !== 'string' || name === this.currentAnim.name))
64424
65592
  {
64425
- if (this._anims[name])
64426
- {
64427
- this.currentAnim = this._anims[name];
64428
- this.currentAnim.stop(resetFrame);
64429
- }
64430
- }
64431
- else
64432
- {
64433
- if (this.currentAnim)
64434
- {
64435
- this.currentAnim.stop(resetFrame);
64436
- }
65593
+ this.currentAnim.stop(resetFrame);
64437
65594
  }
64438
65595
 
64439
65596
  },
@@ -64710,7 +65867,6 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frameName', {
64710
65867
  * @param {number[]|string[]} frames - An array of numbers or strings indicating which frames to play in which order.
64711
65868
  * @param {number} [frameRate=60] - The speed at which the animation should play. The speed is given in frames per second.
64712
65869
  * @param {boolean} [loop=false] - Whether or not the animation is looped or just plays once.
64713
- * @param {boolean} loop - Should this animation loop when it reaches the end or play through once.
64714
65870
  */
64715
65871
  Phaser.Animation = function (game, parent, name, frameData, frames, frameRate, loop) {
64716
65872
 
@@ -64825,6 +65981,9 @@ Phaser.Animation = function (game, parent, name, frameData, frames, frameRate, l
64825
65981
  /**
64826
65982
  * This event is dispatched when the Animation changes frame.
64827
65983
  * By default this event is disabled due to its intensive nature. Enable it with: `Animation.enableUpdate = true`.
65984
+ * Note that the event is only dispatched with the current frame. In a low-FPS environment Animations
65985
+ * will automatically frame-skip to try and claw back time, so do not base your code on expecting to
65986
+ * receive a perfectly sequential set of frames from this event.
64828
65987
  * @property {Phaser.Signal|null} onUpdate
64829
65988
  * @default
64830
65989
  */
@@ -65973,7 +67132,7 @@ Phaser.FrameData.prototype = {
65973
67132
  for (var i = 0; i < frames.length; i++)
65974
67133
  {
65975
67134
  // Does the frames array contain names or indexes?
65976
- if (useNumericIndex)
67135
+ if (useNumericIndex && this._frames[frames[i]])
65977
67136
  {
65978
67137
  output.push(this._frames[frames[i]].index);
65979
67138
  }
@@ -68281,9 +69440,9 @@ Phaser.Cache.prototype = {
68281
69440
  */
68282
69441
  clearGLTextures: function () {
68283
69442
 
68284
- for (var key in this.cache.image)
69443
+ for (var key in this._cache.image)
68285
69444
  {
68286
- this.cache.image[key].base._glTextures = [];
69445
+ this._cache.image[key].base._glTextures = [];
68287
69446
  }
68288
69447
 
68289
69448
  },
@@ -68543,7 +69702,7 @@ Phaser.Loader = function (game) {
68543
69702
  *
68544
69703
  * To disable all parallel downloads this must be set to false prior to any resource being loaded.
68545
69704
  *
68546
- * @property {integer} enableParallel
69705
+ * @property {boolean} enableParallel
68547
69706
  */
68548
69707
  this.enableParallel = true;
68549
69708
 
@@ -69017,7 +70176,7 @@ Phaser.Loader.prototype = {
69017
70176
 
69018
70177
  if (!file || (!file.loaded && !file.loading && file.type !== 'packfile'))
69019
70178
  {
69020
- this._fileList.splice(i, 1, pack);
70179
+ this._fileList.splice(i, 0, pack);
69021
70180
  this._totalPackCount++;
69022
70181
  break;
69023
70182
  }
@@ -69392,7 +70551,7 @@ Phaser.Loader.prototype = {
69392
70551
  * Audio files can't be played until they are decoded and, if specified, this enables immediate decoding. Decoding is a non-blocking async process, however it consumes huge amounts of CPU time on mobiles especially.
69393
70552
  * @return {Phaser.Loader} This Loader instance.
69394
70553
  */
69395
- audiosprite: function(key, urls, jsonURL, jsonData, autoDecode) {
70554
+ audioSprite: function (key, urls, jsonURL, jsonData, autoDecode) {
69396
70555
 
69397
70556
  if (this.game.sound.noAudio)
69398
70557
  {
@@ -69427,6 +70586,23 @@ Phaser.Loader.prototype = {
69427
70586
 
69428
70587
  },
69429
70588
 
70589
+ /**
70590
+ * A legacy alias for Loader.audioSprite. Please see that method for documentation.
70591
+ *
70592
+ * @method Phaser.Loader#audiosprite
70593
+ * @param {string} key - Unique asset key of the audio file.
70594
+ * @param {Array|string} urls - An array containing the URLs of the audio files, i.e.: [ 'audiosprite.mp3', 'audiosprite.ogg', 'audiosprite.m4a' ] or a single string containing just one URL.
70595
+ * @param {string} [jsonURL=null] - The URL of the audiosprite configuration JSON object. If you wish to pass the data directly set this parameter to null.
70596
+ * @param {string|object} [jsonData=null] - A JSON object or string containing the audiosprite configuration data. This is ignored if jsonURL is not null.
70597
+ * @param {boolean} [autoDecode=true] - When using Web Audio the audio files can either be decoded at load time or run-time.
70598
+ * Audio files can't be played until they are decoded and, if specified, this enables immediate decoding. Decoding is a non-blocking async process, however it consumes huge amounts of CPU time on mobiles especially.
70599
+ * @return {Phaser.Loader} This Loader instance.
70600
+ */
70601
+ audiosprite: function (key, urls, jsonURL, jsonData, autoDecode) {
70602
+
70603
+ return this.audioSprite(key, urls, jsonURL, jsonData, autoDecode);
70604
+
70605
+ },
69430
70606
 
69431
70607
  /**
69432
70608
  * Adds a video file to the current load queue.
@@ -70243,10 +71419,10 @@ Phaser.Loader.prototype = {
70243
71419
 
70244
71420
  this.onLoadComplete.dispatch();
70245
71421
 
70246
- this.reset();
70247
-
70248
71422
  this.game.state.loadComplete();
70249
71423
 
71424
+ this.reset();
71425
+
70250
71426
  },
70251
71427
 
70252
71428
  /**
@@ -70668,9 +71844,12 @@ Phaser.Loader.prototype = {
70668
71844
  xhr.onload = function () {
70669
71845
 
70670
71846
  try {
70671
-
70672
- return onload.call(_this, file, xhr);
70673
-
71847
+ if (xhr.readyState == 4 && xhr.status >= 400 && xhr.status <= 599) { // Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called.
71848
+ return onerror.call(_this, file, xhr);
71849
+ }
71850
+ else {
71851
+ return onload.call(_this, file, xhr);
71852
+ }
70674
71853
  } catch (e) {
70675
71854
 
70676
71855
  // If this was the last file in the queue and an error is thrown in the create method
@@ -70779,6 +71958,12 @@ Phaser.Loader.prototype = {
70779
71958
 
70780
71959
  xhr.onload = function () {
70781
71960
  try {
71961
+ if (xhr.readyState == 4 && xhr.status >= 400 && xhr.status <= 599) { // Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called.
71962
+ return onerror.call(_this, file, xhr);
71963
+ }
71964
+ else {
71965
+ return onload.call(_this, file, xhr);
71966
+ }
70782
71967
  return onload.call(_this, file, xhr);
70783
71968
  } catch (e) {
70784
71969
  _this.asyncComplete(file, e.message || 'Exception');
@@ -70815,8 +72000,8 @@ Phaser.Loader.prototype = {
70815
72000
 
70816
72001
  if (url.uri) // {uri: .., type: ..} pair
70817
72002
  {
70818
- url = url.uri;
70819
72003
  videoType = url.type;
72004
+ url = url.uri;
70820
72005
  }
70821
72006
  else
70822
72007
  {
@@ -70838,7 +72023,7 @@ Phaser.Loader.prototype = {
70838
72023
 
70839
72024
  if (this.game.device.canPlayVideo(videoType))
70840
72025
  {
70841
- return urls[i];
72026
+ return url;
70842
72027
  }
70843
72028
  }
70844
72029
 
@@ -70870,8 +72055,8 @@ Phaser.Loader.prototype = {
70870
72055
 
70871
72056
  if (url.uri) // {uri: .., type: ..} pair
70872
72057
  {
70873
- url = url.uri;
70874
72058
  audioType = url.type;
72059
+ url = url.uri;
70875
72060
  }
70876
72061
  else
70877
72062
  {
@@ -70893,7 +72078,7 @@ Phaser.Loader.prototype = {
70893
72078
 
70894
72079
  if (this.game.device.canPlayAudio(audioType))
70895
72080
  {
70896
- return urls[i];
72081
+ return url;
70897
72082
  }
70898
72083
  }
70899
72084
 
@@ -71198,7 +72383,7 @@ Phaser.Loader.prototype = {
71198
72383
  /**
71199
72384
  * Parses string data as XML.
71200
72385
  *
71201
- * @method parseXml
72386
+ * @method Phaser.Loader#parseXml
71202
72387
  * @private
71203
72388
  * @param {string} data - The XML text to parse
71204
72389
  * @return {?XMLDocument} Returns the xml document, or null if such could not parsed to a valid document.
@@ -72055,6 +73240,7 @@ Phaser.Sound.prototype = {
72055
73240
 
72056
73241
  this._sound.onended = null;
72057
73242
  this.isPlaying = false;
73243
+ this.currentTime = this.durationMS;
72058
73244
  this.stop();
72059
73245
 
72060
73246
  },
@@ -72172,15 +73358,6 @@ Phaser.Sound.prototype = {
72172
73358
  {
72173
73359
  if (this.usingWebAudio)
72174
73360
  {
72175
- if (this.externalNode)
72176
- {
72177
- this._sound.disconnect(this.externalNode);
72178
- }
72179
- else
72180
- {
72181
- this._sound.disconnect(this.gainNode);
72182
- }
72183
-
72184
73361
  if (this._sound.stop === undefined)
72185
73362
  {
72186
73363
  this._sound.noteOff(0);
@@ -72193,6 +73370,15 @@ Phaser.Sound.prototype = {
72193
73370
  catch (e) {
72194
73371
  }
72195
73372
  }
73373
+
73374
+ if (this.externalNode)
73375
+ {
73376
+ this._sound.disconnect(this.externalNode);
73377
+ }
73378
+ else
73379
+ {
73380
+ this._sound.disconnect(this.gainNode);
73381
+ }
72196
73382
  }
72197
73383
  else if (this.usingAudioTag)
72198
73384
  {
@@ -72505,15 +73691,6 @@ Phaser.Sound.prototype = {
72505
73691
  {
72506
73692
  if (this.usingWebAudio)
72507
73693
  {
72508
- if (this.externalNode)
72509
- {
72510
- this._sound.disconnect(this.externalNode);
72511
- }
72512
- else
72513
- {
72514
- this._sound.disconnect(this.gainNode);
72515
- }
72516
-
72517
73694
  if (this._sound.stop === undefined)
72518
73695
  {
72519
73696
  this._sound.noteOff(0);
@@ -72528,6 +73705,15 @@ Phaser.Sound.prototype = {
72528
73705
  // Thanks Android 4.4
72529
73706
  }
72530
73707
  }
73708
+
73709
+ if (this.externalNode)
73710
+ {
73711
+ this._sound.disconnect(this.externalNode);
73712
+ }
73713
+ else
73714
+ {
73715
+ this._sound.disconnect(this.gainNode);
73716
+ }
72531
73717
  }
72532
73718
  else if (this.usingAudioTag)
72533
73719
  {
@@ -72538,22 +73724,23 @@ Phaser.Sound.prototype = {
72538
73724
 
72539
73725
  this.pendingPlayback = false;
72540
73726
  this.isPlaying = false;
72541
- var prevMarker = this.currentMarker;
72542
73727
 
72543
- if (this.currentMarker !== '')
73728
+ if (!this.paused)
72544
73729
  {
72545
- this.onMarkerComplete.dispatch(this.currentMarker, this);
72546
- }
73730
+ var prevMarker = this.currentMarker;
72547
73731
 
72548
- this.currentMarker = '';
73732
+ if (this.currentMarker !== '')
73733
+ {
73734
+ this.onMarkerComplete.dispatch(this.currentMarker, this);
73735
+ }
72549
73736
 
72550
- if (this.fadeTween !== null)
72551
- {
72552
- this.fadeTween.stop();
72553
- }
73737
+ this.currentMarker = '';
73738
+
73739
+ if (this.fadeTween !== null)
73740
+ {
73741
+ this.fadeTween.stop();
73742
+ }
72554
73743
 
72555
- if (!this.paused)
72556
- {
72557
73744
  this.onStop.dispatch(this, prevMarker);
72558
73745
  }
72559
73746
 
@@ -73075,6 +74262,11 @@ Phaser.SoundManager.prototype = {
73075
74262
  */
73076
74263
  setTouchLock: function () {
73077
74264
 
74265
+ if (this.noAudio || (window['PhaserGlobal'] && window['PhaserGlobal'].disableAudio === true))
74266
+ {
74267
+ return;
74268
+ }
74269
+
73078
74270
  if (this.game.device.iOSVersion > 8)
73079
74271
  {
73080
74272
  this.game.input.touch.addTouchLockCallback(this.unlock, this, true);
@@ -73535,6 +74727,8 @@ Phaser.SoundManager.prototype = {
73535
74727
 
73536
74728
  this.onSoundDecode.dispose();
73537
74729
 
74730
+ this.context.close();
74731
+
73538
74732
  if (this.context && window['PhaserGlobal'])
73539
74733
  {
73540
74734
  // Store this in the PhaserGlobal window var, if set, to allow for re-use if the game is created again without the page refreshing
@@ -74017,7 +75211,7 @@ Phaser.ScaleManager = function (game, width, height) {
74017
75211
  *
74018
75212
  * @protected
74019
75213
  *
74020
- * @property {boolean} [supportsFullscreen=(auto)] - True only if fullscreen support will be used. (Changing to fullscreen still might not work.)
75214
+ * @property {boolean} [supportsFullScreen=(auto)] - True only if fullscreen support will be used. (Changing to fullscreen still might not work.)
74021
75215
  *
74022
75216
  * @property {boolean} [orientationFallback=(auto)] - See {@link Phaser.DOM.getScreenOrientation}.
74023
75217
  *
@@ -74365,7 +75559,7 @@ Phaser.ScaleManager.prototype = {
74365
75559
 
74366
75560
  this._booted = true;
74367
75561
 
74368
- if (this._pendingScaleMode)
75562
+ if (this._pendingScaleMode !== null)
74369
75563
  {
74370
75564
  this.scaleMode = this._pendingScaleMode;
74371
75565
  this._pendingScaleMode = null;
@@ -74382,7 +75576,7 @@ Phaser.ScaleManager.prototype = {
74382
75576
  */
74383
75577
  parseConfig: function (config) {
74384
75578
 
74385
- if (config['scaleMode'])
75579
+ if (config['scaleMode'] !== undefined)
74386
75580
  {
74387
75581
  if (this._booted)
74388
75582
  {
@@ -74394,7 +75588,7 @@ Phaser.ScaleManager.prototype = {
74394
75588
  }
74395
75589
  }
74396
75590
 
74397
- if (config['fullScreenScaleMode'])
75591
+ if (config['fullScreenScaleMode'] !== undefined)
74398
75592
  {
74399
75593
  this.fullScreenScaleMode = config['fullScreenScaleMode'];
74400
75594
  }
@@ -74485,6 +75679,9 @@ Phaser.ScaleManager.prototype = {
74485
75679
  newHeight = rect.height * this.parentScaleFactor.y;
74486
75680
  }
74487
75681
 
75682
+ newWidth = Math.floor(newWidth);
75683
+ newHeight = Math.floor(newHeight);
75684
+
74488
75685
  this._gameSize.setTo(0, 0, newWidth, newHeight);
74489
75686
 
74490
75687
  this.updateDimensions(newWidth, newHeight, false);
@@ -79136,7 +80333,7 @@ Phaser.Color = {
79136
80333
  },
79137
80334
 
79138
80335
  /**
79139
- * Takes a color object and updates the rgba property.
80336
+ * Takes a color object and updates the rgba, color and color32 properties.
79140
80337
  *
79141
80338
  * @method Phaser.Color.updateColor
79142
80339
  * @static
@@ -79147,7 +80344,7 @@ Phaser.Color = {
79147
80344
 
79148
80345
  out.rgba = 'rgba(' + out.r.toString() + ',' + out.g.toString() + ',' + out.b.toString() + ',' + out.a.toString() + ')';
79149
80346
  out.color = Phaser.Color.getColor(out.r, out.g, out.b);
79150
- out.color32 = Phaser.Color.getColor32(out.a, out.r, out.g, out.b);
80347
+ out.color32 = Phaser.Color.getColor32(out.a * 255, out.r, out.g, out.b);
79151
80348
 
79152
80349
  return out;
79153
80350
 
@@ -80844,7 +82041,7 @@ Phaser.Physics.Arcade.prototype = {
80844
82041
  * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.TilemapLayer|array} object1 - The first object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.TilemapLayer.
80845
82042
  * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.TilemapLayer|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.TilemapLayer.
80846
82043
  * @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, unless you are colliding Group vs. Sprite, in which case Sprite will always be the first parameter.
80847
- * @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.
82044
+ * @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, unless you are colliding Group vs. Sprite, in which case Sprite will always be the first parameter.
80848
82045
  * @param {object} [callbackContext] - The context in which to run the callbacks.
80849
82046
  * @return {boolean} True if a collision occurred otherwise false.
80850
82047
  */
@@ -82154,6 +83351,26 @@ Phaser.Physics.Arcade.prototype = {
82154
83351
 
82155
83352
  return Math.atan2(dy, dx);
82156
83353
 
83354
+ },
83355
+
83356
+ /**
83357
+ * Find the angle in radians between a display object (like a Sprite) and a Pointer,
83358
+ * taking their x/y and center into account relative to the world.
83359
+ *
83360
+ * @method Phaser.Physics.Arcade#worldAngleToPointer
83361
+ * @param {any} displayObject - The DisplayObjerct to test from.
83362
+ * @param {Phaser.Pointer} [pointer] - The Phaser.Pointer to test to. If none is given then Input.activePointer is used.
83363
+ * @return {number} The angle in radians between displayObject.world.x/y to Pointer.worldX / worldY
83364
+ */
83365
+ worldAngleToPointer: function (displayObject, pointer) {
83366
+
83367
+ pointer = pointer || this.game.input.activePointer;
83368
+
83369
+ var dx = pointer.worldX - displayObject.world.x;
83370
+ var dy = pointer.worldY - displayObject.world.y;
83371
+
83372
+ return Math.atan2(dy, dx);
83373
+
82157
83374
  }
82158
83375
 
82159
83376
  };
@@ -82865,6 +84082,16 @@ Phaser.Physics.Arcade.Body.prototype = {
82865
84082
  onFloor: function () {
82866
84083
  return this.blocked.down;
82867
84084
  },
84085
+
84086
+ /**
84087
+ * Returns true if the top of this Body is in contact with either the world bounds or a tile.
84088
+ *
84089
+ * @method Phaser.Physics.Arcade.Body#onTop
84090
+ * @return {boolean} True if in contact with either the world bounds or a tile.
84091
+ */
84092
+ onCeiling: function(){
84093
+ return this.blocked.up;
84094
+ },
82868
84095
 
82869
84096
  /**
82870
84097
  * Returns true if either side of this Body is in contact with either the world bounds or a tile.
@@ -86501,7 +87728,7 @@ Phaser.Physics.P2.Body.prototype = {
86501
87728
  * period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity.
86502
87729
  *
86503
87730
  * @method Phaser.Physics.P2.Body#applyImpulseLocal
86504
- * @param {Float32Array|Array} impulse - The impulse vector to add, oriented in world space.
87731
+ * @param {Float32Array|Array} impulse - The impulse vector to add, oriented in local space.
86505
87732
  * @param {number} localX - A local point on the body.
86506
87733
  * @param {number} localY - A local point on the body.
86507
87734
  */
@@ -89653,8 +90880,8 @@ Phaser.Tilemap.prototype = {
89653
90880
  * You can also pass in a BitmapData which can be used instead of an Image.
89654
90881
  * @param {number} [tileWidth=32] - The width of the tiles in the Tileset Image. If not given it will default to the map.tileWidth value, if that isn't set then 32.
89655
90882
  * @param {number} [tileHeight=32] - The height of the tiles in the Tileset Image. If not given it will default to the map.tileHeight value, if that isn't set then 32.
89656
- * @param {number} [tileMargin=0] - The width of the tiles in the Tileset Image. If not given it will default to the map.tileWidth value.
89657
- * @param {number} [tileSpacing=0] - The height of the tiles in the Tileset Image. If not given it will default to the map.tileHeight value.
90883
+ * @param {number} [tileMargin=0] - The width of the tiles in the Tileset Image.
90884
+ * @param {number} [tileSpacing=0] - The height of the tiles in the Tileset Image.
89658
90885
  * @param {number} [gid=0] - If adding multiple tilesets to a blank/dynamic map, specify the starting GID the set will use here.
89659
90886
  * @return {Phaser.Tileset} Returns the Tileset object that was created or updated, or null if it failed.
89660
90887
  */
@@ -89704,7 +90931,7 @@ Phaser.Tilemap.prototype = {
89704
90931
 
89705
90932
  if (idx === null && this.format === Phaser.Tilemap.TILED_JSON)
89706
90933
  {
89707
- console.warn('Phaser.Tilemap.addTilesetImage: No data found in the JSON matching the tileset name: "' + key + '"');
90934
+ console.warn('Phaser.Tilemap.addTilesetImage: No data found in the JSON matching the tileset name: "' + tileset + '"');
89708
90935
  return null;
89709
90936
  }
89710
90937
 
@@ -90133,19 +91360,6 @@ Phaser.Tilemap.prototype = {
90133
91360
 
90134
91361
  },
90135
91362
 
90136
- /**
90137
- * Gets the object index based on its name.
90138
- *
90139
- * @method Phaser.Tilemap#getObjectIndex
90140
- * @param {string} name - The name of the object to get.
90141
- * @return {number} The index of the object in this tilemap, or null if not found.
90142
- */
90143
- getObjectIndex: function (name) {
90144
-
90145
- return this.getIndex(this.objects, name);
90146
-
90147
- },
90148
-
90149
91363
  /**
90150
91364
  * 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.
90151
91365
  * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it.
@@ -90619,9 +91833,10 @@ Phaser.Tilemap.prototype = {
90619
91833
  hasTile: function (x, y, layer) {
90620
91834
 
90621
91835
  layer = this.getLayer(layer);
90622
-
91836
+ if (this.layers[layer].data[y] === undefined || this.layers[layer].data[y][x] === undefined) {
91837
+ return false;
91838
+ }
90623
91839
  return (this.layers[layer].data[y][x].index > -1);
90624
-
90625
91840
  },
90626
91841
 
90627
91842
  /**
@@ -91995,7 +93210,7 @@ Phaser.TilemapLayer.prototype.resetTilesetCache = function () {
91995
93210
  };
91996
93211
 
91997
93212
  /**
91998
- * This method will set the scale of the tilemap as well as update the underlying block data of this layer
93213
+ * This method will set the scale of the tilemap as well as update the underlying block data of this layer.
91999
93214
  *
92000
93215
  * @method Phaser.TilemapLayer#setScale
92001
93216
  * @param {number} [xScale=1] - The scale factor along the X-plane
@@ -92700,6 +93915,7 @@ Phaser.TilemapParser = {
92700
93915
  * Parses a CSV file into valid map data.
92701
93916
  *
92702
93917
  * @method Phaser.TilemapParser.parseCSV
93918
+ * @param {string} key - The name you want to give the map data.
92703
93919
  * @param {string} data - The CSV file data.
92704
93920
  * @param {number} [tileWidth=32] - The pixel width of a single map tile. If using CSV data you must specify this. Not required if using Tiled map data.
92705
93921
  * @param {number} [tileHeight=32] - The pixel height of a single map tile. If using CSV data you must specify this. Not required if using Tiled map data.
@@ -92863,11 +94079,11 @@ Phaser.TilemapParser = {
92863
94079
  var bytes = new Array( len );
92864
94080
  // Interpret binaryString as an array of bytes representing
92865
94081
  // little-endian encoded uint32 values.
92866
- for (var i = 0; i < len; i+=4) {
92867
- bytes[i/4] = (binaryString.charCodeAt(i) |
92868
- binaryString.charCodeAt(i+1) << 8 |
92869
- binaryString.charCodeAt(i+2) << 16 |
92870
- binaryString.charCodeAt(i+3) << 24) >>> 0;
94082
+ for (var j = 0; j < len; j+=4) {
94083
+ bytes[j/4] = (binaryString.charCodeAt(j) |
94084
+ binaryString.charCodeAt(j+1) << 8 |
94085
+ binaryString.charCodeAt(j+2) << 16 |
94086
+ binaryString.charCodeAt(j+3) << 24) >>> 0;
92871
94087
  }
92872
94088
  curl.data = bytes;
92873
94089
  }
@@ -93068,10 +94284,10 @@ Phaser.TilemapParser = {
93068
94284
  {
93069
94285
  var newCollection = new Phaser.ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties);
93070
94286
 
93071
- for (var i in set.tiles)
94287
+ for (var ti in set.tiles)
93072
94288
  {
93073
- var image = set.tiles[i].image;
93074
- var gid = set.firstgid + parseInt(i, 10);
94289
+ var image = set.tiles[ti].image;
94290
+ var gid = set.firstgid + parseInt(ti, 10);
93075
94291
  newCollection.addImage(gid, image);
93076
94292
  }
93077
94293
 
@@ -93715,7 +94931,7 @@ Phaser.Particle.prototype.setScaleData = function(data) {
93715
94931
  * @param {number} x - The x coordinate (in world space) to position the Particle at.
93716
94932
  * @param {number} y - The y coordinate (in world space) to position the Particle at.
93717
94933
  * @param {number} [health=1] - The health to give the Particle.
93718
- * @return (Phaser.Particle) This instance.
94934
+ * @return {Phaser.Particle} This instance.
93719
94935
  */
93720
94936
  Phaser.Particle.prototype.reset = function(x, y, health) {
93721
94937
 
@@ -94234,6 +95450,7 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
94234
95450
  * Call this function to turn off all the particles and the emitter.
94235
95451
  *
94236
95452
  * @method Phaser.Particles.Arcade.Emitter#kill
95453
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94237
95454
  */
94238
95455
  Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
94239
95456
 
@@ -94241,18 +95458,23 @@ Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
94241
95458
  this.alive = false;
94242
95459
  this.exists = false;
94243
95460
 
95461
+ return this;
95462
+
94244
95463
  };
94245
95464
 
94246
95465
  /**
94247
95466
  * Handy for bringing game objects "back to life". Just sets alive and exists back to true.
94248
95467
  *
94249
95468
  * @method Phaser.Particles.Arcade.Emitter#revive
95469
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94250
95470
  */
94251
95471
  Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
94252
95472
 
94253
95473
  this.alive = true;
94254
95474
  this.exists = true;
94255
95475
 
95476
+ return this;
95477
+
94256
95478
  };
94257
95479
 
94258
95480
  /**
@@ -94261,6 +95483,7 @@ Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
94261
95483
  * @method Phaser.Particles.Arcade.Emitter#explode
94262
95484
  * @param {number} [lifespan=0] - How long each particle lives once emitted in ms. 0 = forever.
94263
95485
  * @param {number} [quantity=0] - How many particles to launch.
95486
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94264
95487
  */
94265
95488
  Phaser.Particles.Arcade.Emitter.prototype.explode = function (lifespan, quantity) {
94266
95489
 
@@ -94268,6 +95491,8 @@ Phaser.Particles.Arcade.Emitter.prototype.explode = function (lifespan, quantity
94268
95491
 
94269
95492
  this.start(true, lifespan, 0, quantity, false);
94270
95493
 
95494
+ return this;
95495
+
94271
95496
  };
94272
95497
 
94273
95498
  /**
@@ -94283,6 +95508,7 @@ Phaser.Particles.Arcade.Emitter.prototype.explode = function (lifespan, quantity
94283
95508
  * @param {number} [quantity=1] - How many particles to launch each time the frequency is met. Can never be > Emitter.maxParticles.
94284
95509
  * @param {number} [total=-1] - How many particles to launch in total. If -1 it will carry on indefinitely.
94285
95510
  * @param {boolean} [immediate=true] - Should the flow start immediately (true) or wait until the first frequency event? (false)
95511
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94286
95512
  */
94287
95513
  Phaser.Particles.Arcade.Emitter.prototype.flow = function (lifespan, frequency, quantity, total, immediate) {
94288
95514
 
@@ -94312,6 +95538,8 @@ Phaser.Particles.Arcade.Emitter.prototype.flow = function (lifespan, frequency,
94312
95538
  this.start(false, lifespan, frequency, quantity);
94313
95539
  }
94314
95540
 
95541
+ return this;
95542
+
94315
95543
  };
94316
95544
 
94317
95545
  /**
@@ -94323,6 +95551,7 @@ Phaser.Particles.Arcade.Emitter.prototype.flow = function (lifespan, frequency,
94323
95551
  * @param {number} [frequency=250] - Ignored if Explode is set to true. Frequency is how often to emit 1 particle. Value given in ms.
94324
95552
  * @param {number} [quantity=0] - How many particles to launch. 0 = "all of the particles" which will keep emitting until Emitter.maxParticles is reached.
94325
95553
  * @param {number} [forceQuantity=false] - If `true` and creating a particle flow, the quantity emitted will be forced to the be quantity given in this call. This can never exceed Emitter.maxParticles.
95554
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94326
95555
  */
94327
95556
  Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, frequency, quantity, forceQuantity) {
94328
95557
 
@@ -94359,6 +95588,8 @@ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, f
94359
95588
  this._timer = this.game.time.time + frequency * this.game.time.slowMotion;
94360
95589
  }
94361
95590
 
95591
+ return this;
95592
+
94362
95593
  };
94363
95594
 
94364
95595
  /**
@@ -94508,12 +95739,15 @@ Phaser.Particles.Arcade.Emitter.prototype.destroy = function () {
94508
95739
  * @method Phaser.Particles.Arcade.Emitter#setSize
94509
95740
  * @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions).
94510
95741
  * @param {number} height - The desired height of the emitter.
95742
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94511
95743
  */
94512
95744
  Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) {
94513
95745
 
94514
95746
  this.area.width = width;
94515
95747
  this.area.height = height;
94516
95748
 
95749
+ return this;
95750
+
94517
95751
  };
94518
95752
 
94519
95753
  /**
@@ -94521,6 +95755,7 @@ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) {
94521
95755
  * @method Phaser.Particles.Arcade.Emitter#setXSpeed
94522
95756
  * @param {number} [min=0] - The minimum value for this range.
94523
95757
  * @param {number} [max=0] - The maximum value for this range.
95758
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94524
95759
  */
94525
95760
  Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
94526
95761
 
@@ -94530,6 +95765,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
94530
95765
  this.minParticleSpeed.x = min;
94531
95766
  this.maxParticleSpeed.x = max;
94532
95767
 
95768
+ return this;
95769
+
94533
95770
  };
94534
95771
 
94535
95772
  /**
@@ -94537,6 +95774,7 @@ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
94537
95774
  * @method Phaser.Particles.Arcade.Emitter#setYSpeed
94538
95775
  * @param {number} [min=0] - The minimum value for this range.
94539
95776
  * @param {number} [max=0] - The maximum value for this range.
95777
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94540
95778
  */
94541
95779
  Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
94542
95780
 
@@ -94546,6 +95784,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
94546
95784
  this.minParticleSpeed.y = min;
94547
95785
  this.maxParticleSpeed.y = max;
94548
95786
 
95787
+ return this;
95788
+
94549
95789
  };
94550
95790
 
94551
95791
  /**
@@ -94554,6 +95794,7 @@ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
94554
95794
  * @method Phaser.Particles.Arcade.Emitter#setRotation
94555
95795
  * @param {number} [min=0] - The minimum value for this range.
94556
95796
  * @param {number} [max=0] - The maximum value for this range.
95797
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94557
95798
  */
94558
95799
  Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
94559
95800
 
@@ -94563,6 +95804,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
94563
95804
  this.minRotation = min;
94564
95805
  this.maxRotation = max;
94565
95806
 
95807
+ return this;
95808
+
94566
95809
  };
94567
95810
 
94568
95811
  /**
@@ -94576,6 +95819,7 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
94576
95819
  * @param {number} [rate=0] - The rate (in ms) at which the particles will change in alpha from min to max, or set to zero to pick a random alpha between the two.
94577
95820
  * @param {function} [ease=Phaser.Easing.Linear.None] - If you've set a rate > 0 this is the easing formula applied between the min and max values.
94578
95821
  * @param {boolean} [yoyo=false] - If you've set a rate > 0 you can set if the ease will yoyo or not (i.e. ease back to its original values)
95822
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94579
95823
  */
94580
95824
  Phaser.Particles.Arcade.Emitter.prototype.setAlpha = function (min, max, rate, ease, yoyo) {
94581
95825
 
@@ -94602,6 +95846,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setAlpha = function (min, max, rate, e
94602
95846
  this.autoAlpha = true;
94603
95847
  }
94604
95848
 
95849
+ return this;
95850
+
94605
95851
  };
94606
95852
 
94607
95853
  /**
@@ -94617,6 +95863,7 @@ Phaser.Particles.Arcade.Emitter.prototype.setAlpha = function (min, max, rate, e
94617
95863
  * @param {number} [rate=0] - The rate (in ms) at which the particles will change in scale from min to max, or set to zero to pick a random size between the two.
94618
95864
  * @param {function} [ease=Phaser.Easing.Linear.None] - If you've set a rate > 0 this is the easing formula applied between the min and max values.
94619
95865
  * @param {boolean} [yoyo=false] - If you've set a rate > 0 you can set if the ease will yoyo or not (i.e. ease back to its original values)
95866
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94620
95867
  */
94621
95868
  Phaser.Particles.Arcade.Emitter.prototype.setScale = function (minX, maxX, minY, maxY, rate, ease, yoyo) {
94622
95869
 
@@ -94650,6 +95897,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setScale = function (minX, maxX, minY,
94650
95897
  this.autoScale = true;
94651
95898
  }
94652
95899
 
95900
+ return this;
95901
+
94653
95902
  };
94654
95903
 
94655
95904
  /**
@@ -94658,6 +95907,7 @@ Phaser.Particles.Arcade.Emitter.prototype.setScale = function (minX, maxX, minY,
94658
95907
  *
94659
95908
  * @method Phaser.Particles.Arcade.Emitter#at
94660
95909
  * @param {object|Phaser.Sprite|Phaser.Image|Phaser.TileSprite|Phaser.Text|PIXI.DisplayObject} object - The object that you wish to match the center with.
95910
+ * @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
94661
95911
  */
94662
95912
  Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
94663
95913
 
@@ -94672,6 +95922,8 @@ Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
94672
95922
  this.emitY = object.world.y + (object.anchor.y * object.height);
94673
95923
  }
94674
95924
 
95925
+ return this;
95926
+
94675
95927
  };
94676
95928
 
94677
95929
  /**
@@ -94997,6 +96249,18 @@ Phaser.Video = function (game, key, url) {
94997
96249
  */
94998
96250
  this._autoplay = false;
94999
96251
 
96252
+ /**
96253
+ * @property {function} _endCallback - The addEventListener ended function.
96254
+ * @private
96255
+ */
96256
+ this._endCallback = null;
96257
+
96258
+ /**
96259
+ * @property {function} _playCallback - The addEventListener playing function.
96260
+ * @private
96261
+ */
96262
+ this._playCallback = null;
96263
+
95000
96264
  if (key && this.game.cache.checkVideoKey(key))
95001
96265
  {
95002
96266
  var _video = this.game.cache.getVideo(key);
@@ -95436,7 +96700,9 @@ Phaser.Video.prototype = {
95436
96700
  this.game.onPause.add(this.setPause, this);
95437
96701
  this.game.onResume.add(this.setResume, this);
95438
96702
 
95439
- this.video.addEventListener('ended', this.complete.bind(this), true);
96703
+ this._endCallback = this.complete.bind(this);
96704
+
96705
+ this.video.addEventListener('ended', this._endCallback, true);
95440
96706
 
95441
96707
  if (loop)
95442
96708
  {
@@ -95466,7 +96732,8 @@ Phaser.Video.prototype = {
95466
96732
  }
95467
96733
  else
95468
96734
  {
95469
- this.video.addEventListener('playing', this.playHandler.bind(this), true);
96735
+ this._playCallback = this.playHandler.bind(this);
96736
+ this.video.addEventListener('playing', this._playCallback, true);
95470
96737
  }
95471
96738
  }
95472
96739
 
@@ -95487,7 +96754,7 @@ Phaser.Video.prototype = {
95487
96754
  */
95488
96755
  playHandler: function () {
95489
96756
 
95490
- this.video.removeEventListener('playing', this.playHandler.bind(this));
96757
+ this.video.removeEventListener('playing', this._playCallback, true);
95491
96758
 
95492
96759
  this.updateTexture();
95493
96760
 
@@ -95546,8 +96813,8 @@ Phaser.Video.prototype = {
95546
96813
  }
95547
96814
  else
95548
96815
  {
95549
- this.video.removeEventListener('ended', this.complete.bind(this), true);
95550
- this.video.removeEventListener('playing', this.playHandler.bind(this), true);
96816
+ this.video.removeEventListener('ended', this._endCallback, true);
96817
+ this.video.removeEventListener('playing', this._playCallback, true);
95551
96818
 
95552
96819
  if (this.touchLocked)
95553
96820
  {
@@ -95927,7 +97194,7 @@ Phaser.Video.prototype = {
95927
97194
  };
95928
97195
 
95929
97196
  /**
95930
- * @memberof Phaser.Video
97197
+ * @name Phaser.Video#currentTime
95931
97198
  * @property {number} currentTime - The current time of the video in seconds. If set the video will attempt to seek to that point in time.
95932
97199
  */
95933
97200
  Object.defineProperty(Phaser.Video.prototype, "currentTime", {
@@ -95947,7 +97214,7 @@ Object.defineProperty(Phaser.Video.prototype, "currentTime", {
95947
97214
  });
95948
97215
 
95949
97216
  /**
95950
- * @memberof Phaser.Video
97217
+ * @name Phaser.Video#duration
95951
97218
  * @property {number} duration - The duration of the video in seconds.
95952
97219
  * @readOnly
95953
97220
  */
@@ -95962,7 +97229,7 @@ Object.defineProperty(Phaser.Video.prototype, "duration", {
95962
97229
  });
95963
97230
 
95964
97231
  /**
95965
- * @memberof Phaser.Video
97232
+ * @name Phaser.Video#progress
95966
97233
  * @property {number} progress - The progress of this video. This is a value between 0 and 1, where 0 is the start and 1 is the end of the video.
95967
97234
  * @readOnly
95968
97235
  */