0
votes

I'm making a game as a project for school and have recently encountered a little problem in as3. I'm making a game where you are maneuvering ship avoiding asteroids, and just added the function so that when you hit an asteroid your ship is removed from the stage via stage.removeChild. Everything is fine until you actually hit something, then this error comes up(and I mean alot, like it keeps repeating itself for as long as the game is on):

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at Function/com.asgamer.basics1:Engine/private:loop/com.asgamer.basics1:krash()[C:\Users\nti\Desktop\Ship game\com\asgamer\basics1\Engine.as:54]

Here's the code(I marked out line 54):

 package com.asgamer.basics1
{
    import flash.display.MovieClip;
    import flash.display.Stage;
    import flash.events.Event; 

    public class Engine extends MovieClip
    {


    private var numStars:int = 80;

    private var enemyList:Array = new Array();

    private var ourShip:Ship;

    public function Engine() : void
    {

        ourShip = new Ship(stage);
        stage.addChild(ourShip);

        ourShip.x = stage.stageWidth / 2;
        ourShip.y = stage.stageHeight / 2;

        for (var i:int = 0; i < numStars; i++)
        {
            stage.addChildAt(new Star(stage), stage.getChildIndex(ourShip));
        }


        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);


    }


    private function loop(e:Event) : void
    {

        if (Math.floor(Math.random() * 14) == 5)
        {

            var enemy:Asteroid = new Asteroid(stage);

            enemy.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy, false, 0, true);

            enemyList.push(enemy);

            stage.addChild(enemy);

            stage.addEventListener(Event.ENTER_FRAME, krash);
            function krash(e:Event):void{
                if (enemy.hitTestObject(ourShip)==true){
                    stage.removeChild(ourShip); <-------------------------- LINE 54

                }
            }

        }
    }


    private function removeEnemy(e:Event)
    {
        enemyList.splice(enemyList.indexOf(e.currentTarget), 1);
    }




}

}

Please do remember that I'm sort of a beginner to coding, which would explain other possible "faults" in the code. :)

2

2 Answers

1
votes

The problem is, as was mentioned a while ago, is that you don't clean up your ourShip after actually removing it from stage. See, once you call stage.removeChild() the ship is no longer on stage, but collision check still goes because you didn't remove the enter frame listener. You should add the remove listener statement to the code branch where you remove the ship.

        stage.addEventListener(Event.ENTER_FRAME, krash);
        ... // other code
        function krash(e:Event):void{
            for each (var enemy in enemyList)
              if (enemy.hitTestObject(ourShip)==true){
                stage.removeChild(ourShip); 
                stage.removeEventListener(Event.ENTER_FRAME, krash); // THIS line
            }
        }

EDIT: first, move the addEventListener(Event.ENTER_FRAME, krash) line to the point where you add a loop listener, because you don't want to have more than a single one of these, and second, make a complete loop for hitTestObject versus enemyList. The code above is updated.

Note: Some validity checks may need to be present in the listener code, for example, if ourShip is already removed you might just return from the event listener function, or skip the hit test checks. This will also help you once you'll start advancing to a single master enter frame listener - it's generally faster having one function as event listener than many for the same event, and also helps you consolidate every bit of code you want to be executed in response for a particular event in one place, instead of searching where did you place that statement that bugs out. This also helps to not fiddle with adding/removing listeners on a regular basis, although sometimes playing with listeners can do you better.

0
votes

Problem is caused by the fact that you're trying remove ourShip from the stage several times. More precisely on each Event.ENTER_FRAME event.