Search code examples
actionscript-3instancedestroyremovechild

Completely remove unnamed instance from stage and group


So I have a bunch of instances of a movie clip "fruit". They are all unnamed.

I added them in a mother movie clip named "fruitGroup".

What the code is supposed to do is when any fruit instance is clicked, play its animation, and destroy it forever.

It works well, until your mouse is over the coords of the previously destroyed fruit. The fruit pops back into existence!

fruitGroup.addEventListener(MouseEvent.MOUSE_OVER,fruitOver);
fruitGroup.addEventListener(MouseEvent.CLICK,fruitclick);
fruitGroup.mouseEnabled = false;

function fruitOver(e:MouseEvent)
{
    e.target.play();

}
function fruitclick(e:MouseEvent)
{
    e.target.gotoAndPlay(82);
    if (e.target._currentframe==100)
    {
        e.target.removeChild(e.target);
    }

}

EDIT: I didn't really clarify my setup. Apart from the fruitGroup and my CLICK listener, there are 2 more things to my setup. The base symbol has 100 frames. 1-81 are a wiggle animation played on mouseover, 82-100 are a fade-out animation played on click. Maybe the destruction should happen INSIDE of the base symbol at frame 100?


Solution

  • You should do two things. First, you have to add an Event.ENTER_FRAME listener to the one of your fruits that was clicked, in order to make it handle the event when its currentFrame will become 100, and second, to remove your fruit that's playing you have to do this:

    e.target.parent.removeChild(e.target);
    e.target.removeEventListener(Event.ENTER_FRAME,yourFunction);
    

    Note the parent in reference, you have to check if there is a parent, or you'll run into issues.

    Edit: Okay, let me clarify the answer. You retain your MouseEvent.CLICK listener, but make it like this:

    fruitGroup.addEventListener(MouseEvent.CLICK,fruitclick);
    function fruitclick(e:MouseEvent)
    {
        if (e.target is Fruit) {
            e.target.gotoAndPlay(82);
            if (!e.target.hasEventListener(Event.ENTER_FRAME)) 
                e.target.addEventListener(Event.ENTER_FRAME,endPlay);
        }
    }
    

    Then you add an ENTER_FRAME listener like this:

    function endPlay(e:Event):void 
    {
        if (e.target._currentframe==100)
        {
            e.target.parent.removeChild(e.target);
            e.target.removeEventListener(Event.ENTER_FRAME,endPlay);
        }
    }
    

    This code can still reside on the main timeline, or it can be in any class that has access to fruitGroup to initiate listening for clicks.

    How does this work: When you click on a fruit, the function fruitClick is called, with the event's target set to the clicked fruit. We now have the reference there - good, now we assign it a listener and make it play the animation you want. The listener activates each frame with event's target being the very same fruit, and once its currentFrame reaches 100, we call its parent to release the fruit off itself (it'll most likely be fruitGroup, but if not, this won't give an error), and remove the now-obsolete listener.