phaserjs/phaser-ce

Error calling destroy in objects

Closed this issue · 12 comments

Uncaught TypeError: Cannot read property 'enabled' of undefined

here:
Phaser.Input.callAll = function(handler, pointer) {
var list = this.interactiveItems.list;
var i = list.length;

while (i--)
{
    var item = list[i];

    if (item.enabled) <========================= HERE!!!
    {
        item[handler](pointer);
    }
}

};

when:

calling method destroy in objects;

version: 2.13.0

samme commented

When does it happen?

I have two functions;

  1. create => create a container group and add 5 sprite image;
  2. destroyAll => remove children and container with method destroy;

first: call create();
next: destroyAll();
next: call create(); again;
and now, when I try to call destroyAll again, so happen the error;

samme commented

Can you post your code?

import Sprite from '../com/script4/display/Sprite';
import ImageSuper from '../com/script4/display/ImageSuper';
import SimpleButton from '../com/script4/display/SimpleButton';
import Event from '../com/script4/events/Event';

import EventType from '../enums/EventType';

export default class Menu extends Sprite {

constructor(_loadOptions, _loadGame) {
	super();
	Menu.this = this;

	this.loadOptions = _loadOptions;
	this.loadGame = _loadGame;
	
	var bg = new ImageSuper("bgMenu");
	this.addChild(bg);
	
	var title = new ImageSuper("spriteAll.title");
	title.y = -70;
	this.addChild(title);
	TweenMax.to(title, 2.0, { y:10, repeat:-1, yoyo:true, ease:Linear.easeInOut });
	
	this.btPlay = new SimpleButton("spriteAll.btPlay");
	this.btPlay.name = "play";
	this.btPlay.x = (this.btPlay.width * 0.5) + 21;
	this.btPlay.y = (this.btPlay.height * 0.5) + 378;
	this.addChild(this.btPlay);
	
	this.btOptions = new SimpleButton("spriteAll.btOptions");
	this.btOptions.name = "options";
	this.btOptions.x = (this.btOptions.width * 0.5) + 237;
	this.btOptions.y = (this.btOptions.height * 0.5) + 449;
	this.addChild(this.btOptions);
	
	this.events(EventType.ADD);
}

onClick(e) {
	Menu.this.events(EventType.REMOVE);
	
	switch (e.target.name) {
		case "play":
			Menu.this.loadGame();
			break;
		case "options":
			Menu.this.loadOptions();
			break;
	}
}

events(_type) {
	this.btPlay[_type.name + "EventListener"](Event.TRIGGERED, this.onClick);
	this.btOptions[_type.name + "EventListener"](Event.TRIGGERED, this.onClick);
}

destroy() {
	this.events(EventType.REMOVE);
	super.destroy();
}

}

samme commented

Thanks. Can you post the error trace?

What class do Menu and Sprite extend?

If you're extending a game object, you should avoid overwriting this.events.

VM58121:17334 Uncaught TypeError: Cannot read property 'enabled' of undefined
at Phaser.Input.callAll (eval at module.exports (addScript.js:NaN), :17334:22)
at Phaser.Pointer.stop (eval at module.exports (addScript.js:NaN), :20083:15)
at Phaser.MSPointer.onPointerUp (eval at module.exports (addScript.js:NaN), :18511:37)
at HTMLCanvasElement._onMSPointerUp (eval at module.exports (addScript.js:NaN), :18351:26)

samme commented

I can't reproduce this but I guess I can fix it.

You could add this to troubleshoot:

console.assert(game.input.interactiveItems.list.every(Boolean))
samme commented

I'm going to leave Phaser CE's behavior unchanged (as of v2.13.0) on this unless I can reproduce the issue.

game.input.interactiveItems shouldn't contain any undefined values so it's normal to get an error. Maybe check your remove/destroy code.

I get this same error on 2.13.1 when changing a sprite's inputEnabled to false from true. It's only on one particular button in my code, which has no difference from other buttons. A separate instance of the same button only sometimes triggers the error, so it's pretty random.

It does not happen in 2.12.0 for me.

samme commented

@XWILKINX can you post a code sample?

I have the same error.
The problem is, if I set the button to inputEnabled = true;
But not with every button. Seems to be where the button is in the list.

The interactiveItems changed during the while loop. I deactive 3 Buttons with inputEnabled = true;
But the list starts with all 28 items. The first i loops are correct, then the list changed to 25 items and then, the exception throws, because i is 25 and list[25] doesn't exist anymore.

I think, it's a timing problem.

var list = this.interactiveItems.list;
var i = list.length;

    while (i--)
    {
        var item = list[i];

        if (item.enabled)
        {
            item[handler](pointer);
        }
    }
samme commented

OK, it's worth changing, then.

You can try a workaround by setting input.enabled = false instead.