cykod / Quintus

HTML5 Game Engine
http://html5quintus.com
GNU General Public License v2.0
1.41k stars 401 forks source link

Removing a sprite and inserting it back #131

Open rohitj opened 10 years ago

rohitj commented 10 years ago

I am working on something where I add a sprite, then on a user action, I remove the sprite, and then I add it back based on user action. (And this can be repeated a few times). It worked the first time, and after that, it wouldn't work. It turns out that the problem was that in the destroy function, the first line is:

if(this.isDestroyed) { return; }

I could not find a reason why this line exists. If I comment out this like, things seem to be working fine for me. If it makes sense to others, perhaps, we should remove this line.

nicholas-quirk commented 10 years ago

How are you reviving the Sprite? The destroy function will return undefined regardless, so that line of code as the first statement is preventing the destroy() call from executing code on a previously destroyed target.

rohitj commented 10 years ago

I am reviving it by just inserting it again in the stage.

A crude code would look like this:

var s = new Q.Sprite({.....}); // A container actually, not a sprite stage.insert(s); s.destroy(); stage.insert(); s.destroy(); stage.insert();

If I remove that line, this code works just fine. Otherwise, it wouldn't work fine.

viki53 commented 10 years ago

Then you're doing it wrong. Instead of destroying your sprite, just remove it from the stage: stage.remove(s).

See quintus_scenes.js

rohitj commented 10 years ago

What happens when I have a container instead of a sprite? Basically, I have a container with a bunch of things, and I want to remove it from stage and then insert it back a few times. The container also has Touch enabled. I used remove before, and it doesn't work as desired.

viki53 commented 10 years ago

A container is a Sprite, so it should work too. Try again and if it still won't work, show us your code.

rohitj commented 10 years ago

I checked the code. It seems that if remove() is called, destroy() will be called eventually (in the step function). So, the issue remains the same, that is that if a sprite is removed, (and hence destroyed), the next time we try to do that, destroy() will have no effect.

cykod commented 10 years ago

The isDestroyed is in there so if destroy is called multiple times it doesn't blow up - what's the goal of the removing and adding the object back in?

Removing the object does a lot of extra work - it removes it from lists, triggers events, unbinds events/etc - we could probably add in a a lightweight remove that just removes it from the scenegraph and leaves the rest of the stuff intact.

But - I wonder if just setting type=0 and hiding the object wouldn't achieve the same thing with less work.