Skip to content

Commit 6225bb0

Browse files
committed
Animation - guard around destroy
- Allows sprites (and/or the animation) to be destroyed from within the onUpdate, onLoop, or onComplete events
1 parent cb9ef4f commit 6225bb0

1 file changed

Lines changed: 52 additions & 62 deletions

File tree

src/animation/Animation.js

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,7 @@ Phaser.Animation.prototype = {
192192
this._timeNextFrame = this.game.time.time + this.delay;
193193

194194
this._frameIndex = 0;
195-
196-
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
197-
198-
this._parent.setFrame(this.currentFrame);
199-
200-
// TODO: Double check if required
201-
if (this._parent.__tilePattern)
202-
{
203-
this._parent.__tilePattern = false;
204-
this._parent.tilingTexture = false;
205-
}
195+
this.updateCurrentFrame(false);
206196

207197
this._parent.events.onAnimationStart$dispatch(this._parent, this);
208198

@@ -391,6 +381,7 @@ Phaser.Animation.prototype = {
391381
{
392382
if (this.loop)
393383
{
384+
// Update current state before event callback
394385
this._frameIndex %= this._frames.length;
395386
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
396387
this.loopCount++;
@@ -403,29 +394,56 @@ Phaser.Animation.prototype = {
403394
}
404395
}
405396

406-
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
397+
return this.updateCurrentFrame(true);
407398

408-
if (this.currentFrame)
409-
{
410-
this._parent.setFrame(this.currentFrame);
399+
}
411400

412-
if (this._parent.__tilePattern)
413-
{
414-
this._parent.__tilePattern = false;
415-
this._parent.tilingTexture = false;
416-
}
401+
return false;
417402

418-
if (this.onUpdate)
419-
{
420-
this.onUpdate.dispatch(this, this.currentFrame);
421-
}
403+
},
404+
405+
/**
406+
* Changes the currentFrame per the _frameIndex, updates the display state,
407+
* and triggers the update signal.
408+
*
409+
* Returns true if the current frame update was 'successful', false otherwise.
410+
*
411+
* @method Phaser.Animation#updateCurrentFrame
412+
* @param {bool} signalUpdate - If true th onUpdate signal will be triggered.
413+
* @private
414+
*/
415+
updateCurrentFrame: function (signalUpdate) {
416+
417+
if (!this._frameData)
418+
{
419+
// The animation is already destroyed, probably from a callback
420+
return false;
421+
}
422+
423+
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
424+
425+
if (this.currentFrame)
426+
{
427+
this._parent.setFrame(this.currentFrame);
428+
429+
if (this._parent.__tilePattern)
430+
{
431+
this._parent.__tilePattern = false;
432+
this._parent.tilingTexture = false;
422433
}
434+
}
423435

436+
if (this.onUpdate && signalUpdate)
437+
{
438+
this.onUpdate.dispatch(this, this.currentFrame);
439+
// False if the animation was destroyed from within a callback
440+
return !!this._frameData;
441+
}
442+
else
443+
{
424444
return true;
425445
}
426446

427-
return false;
428-
429447
},
430448

431449
/**
@@ -455,24 +473,7 @@ Phaser.Animation.prototype = {
455473
if (frame !== this._frameIndex)
456474
{
457475
this._frameIndex = frame;
458-
459-
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
460-
461-
if (this.currentFrame)
462-
{
463-
this._parent.setFrame(this.currentFrame);
464-
465-
if (this._parent.__tilePattern)
466-
{
467-
this._parent.__tilePattern = false;
468-
this._parent.tilingTexture = false;
469-
}
470-
}
471-
472-
if (this.onUpdate)
473-
{
474-
this.onUpdate.dispatch(this, this.currentFrame);
475-
}
476+
this.updateCurrentFrame(true);
476477
}
477478

478479
},
@@ -504,24 +505,7 @@ Phaser.Animation.prototype = {
504505
if (frame !== this._frameIndex)
505506
{
506507
this._frameIndex = frame;
507-
508-
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
509-
510-
if (this.currentFrame)
511-
{
512-
this._parent.setFrame(this.currentFrame);
513-
514-
if (this._parent.__tilePattern)
515-
{
516-
this._parent.__tilePattern = false;
517-
this._parent.tilingTexture = false;
518-
}
519-
}
520-
521-
if (this.onUpdate)
522-
{
523-
this.onUpdate.dispatch(this, this.currentFrame);
524-
}
508+
this.updateCurrentFrame(true);
525509
}
526510

527511
},
@@ -546,6 +530,12 @@ Phaser.Animation.prototype = {
546530
*/
547531
destroy: function () {
548532

533+
if (!this._frameData)
534+
{
535+
// Already destroyed
536+
return;
537+
}
538+
549539
this.game.onPause.remove(this.onPause, this);
550540
this.game.onResume.remove(this.onResume, this);
551541

0 commit comments

Comments
 (0)