diff --git a/README.md b/README.md index 29201852..b35e939c 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ Bug Fixes: * Tilemap had the wrong @method signatures so most were missing from the docs. * Fixed bug where changing State would cause the camera to not reset if it was following an object. * Tile had 2 properties (callback and callbackContext) that were never assigned, updated to use the proper names (thanks ratkingsimon) - +* Issue 382: Error when using InputHandler#onInputUp & sprite destroys itself during the event. You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md diff --git a/examples/wip/destroy.js b/examples/wip/destroy.js index 698e0a4b..63088547 100644 --- a/examples/wip/destroy.js +++ b/examples/wip/destroy.js @@ -14,14 +14,16 @@ var p; function create() { - game.stage.backgroundColor = '#ff5500'; + // game.stage.backgroundColor = '#ff5500'; - game.renderer.useFillRect = false; + // game.renderer.useFillRect = false; sprite = game.add.sprite(0.5, 0, 'pic'); - sprite2 = game.add.sprite(0, 300, 'pic'); + // sprite2 = game.add.sprite(0, 300, 'pic'); - game.input.onDown.add(tint, this); + sprite.inputEnabled = true; + sprite.events.onInputDown.add(tint, this); + sprite.events.onInputUp.add(wibble, this); // game.add.tween(sprite).to({y: 500}, 3000, Phaser.Easing.Linear.None, true); @@ -37,6 +39,12 @@ function tint() { } +function wibble() { + + console.log(sprite); + +} + function update() { diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index e99e207a..7739fbab 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -491,11 +491,6 @@ Phaser.Sprite.prototype.destroy = function() { this.parent.remove(this); } - if (this.events) - { - this.events.destroy(); - } - if (this.input) { this.input.destroy(); @@ -511,6 +506,11 @@ Phaser.Sprite.prototype.destroy = function() { this.body.destroy(); } + if (this.events) + { + this.events.destroy(); + } + this.alive = false; this.exists = false; this.visible = false; diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js index c36b07e3..3957a14f 100644 --- a/src/input/InputHandler.js +++ b/src/input/InputHandler.js @@ -145,11 +145,15 @@ Phaser.InputHandler = function (sprite) { this.consumePointerEvent = false; /** - * @property {Phaser.Point} _tempPoint - Description. + * @property {Phaser.Point} _tempPoint - Internal cache var. * @private */ this._tempPoint = new Phaser.Point(); + /** + * @property {array} _pointerData - Internal cache var. + * @private + */ this._pointerData = []; this._pointerData.push({ @@ -290,10 +294,12 @@ Phaser.InputHandler.prototype = { this.game.input.interactiveItems.remove(this); - this.stop(); - + this._pointerData.length = 0; + this.boundsRect = null; + this.boundsSprite = null; this.sprite = null; } + }, /** @@ -549,10 +555,17 @@ Phaser.InputHandler.prototype = { /** * Update. * @method Phaser.InputHandler#update + * @protected * @param {Phaser.Pointer} pointer */ update: function (pointer) { + if (this.sprite === null) + { + // Abort. We've been destroyed. + return; + } + if (this.enabled === false || this.sprite.visible === false || (this.sprite.group && this.sprite.group.visible === false)) { this._pointerOutHandler(pointer); @@ -587,6 +600,12 @@ Phaser.InputHandler.prototype = { */ _pointerOverHandler: function (pointer) { + if (this.sprite === null) + { + // Abort. We've been destroyed. + return; + } + if (this._pointerData[pointer.id].isOver === false) { this._pointerData[pointer.id].isOver = true; @@ -602,6 +621,7 @@ Phaser.InputHandler.prototype = { this.sprite.events.onInputOver.dispatch(this.sprite, pointer); } + }, /** @@ -612,6 +632,12 @@ Phaser.InputHandler.prototype = { */ _pointerOutHandler: function (pointer) { + if (this.sprite === null) + { + // Abort. We've been destroyed. + return; + } + this._pointerData[pointer.id].isOver = false; this._pointerData[pointer.id].isOut = true; this._pointerData[pointer.id].timeOut = this.game.time.now; @@ -636,6 +662,12 @@ Phaser.InputHandler.prototype = { */ _touchedHandler: function (pointer) { + if (this.sprite === null) + { + // Abort. We've been destroyed. + return; + } + if (this._pointerData[pointer.id].isDown === false && this._pointerData[pointer.id].isOver === true) { this._pointerData[pointer.id].isDown = true; @@ -668,6 +700,12 @@ Phaser.InputHandler.prototype = { */ _releasedHandler: function (pointer) { + if (this.sprite === null) + { + // Abort. We've been destroyed. + return; + } + // If was previously touched by this Pointer, check if still is AND still over this item if (this._pointerData[pointer.id].isDown && pointer.isUp) { diff --git a/src/input/Pointer.js b/src/input/Pointer.js index 56fc31bb..da895c38 100644 --- a/src/input/Pointer.js +++ b/src/input/Pointer.js @@ -386,7 +386,7 @@ Phaser.Pointer.prototype = { while (currentNode != null) } - if (this._highestRenderObject == null) + if (this._highestRenderObject === null) { // The pointer isn't currently over anything, check if we've got a lingering previous target if (this.targetObject) @@ -398,7 +398,7 @@ Phaser.Pointer.prototype = { } else { - if (this.targetObject == null) + if (this.targetObject === null) { // And now set the new one // console.log('And now set the new one'); @@ -409,7 +409,7 @@ Phaser.Pointer.prototype = { { // We've got a target from the last update // console.log("We've got a target from the last update"); - if (this.targetObject == this._highestRenderObject) + if (this.targetObject === this._highestRenderObject) { // Same target as before, so update it // console.log("Same target as before, so update it");