Remove Child and AS3 2025 Error

2020-02-16 02:53发布

问题:

Trying to remove a bullet from an array and cannot seem to get rid of this error.

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at Template/gameLoop()

I am trying to remove the bullet from the array if it is hit or if it goes past a certain x value.

for (var oo:int=0;oo<bArray2.length;oo++)
    {
        bullet2=bArray2[oo];
        if(bullet2.x<500 && bullet2!=null && bArray2[oo]!=null) 
            {
                bullet2.x += 3;  
            } 
            else 
            {
                removeChild(bullet2);
                bArray2.splice(oo, 1);

            }


                if(boss.hitTestObject(bArray2[oo])&& bArray2[oo]!=null && boss!=null) 
                {

                    removeChild(bArray2[oo]);
                    bLives-=1;
                    bArray2[oo]=null;
                    bArray2.splice(oo, 1);


                }//end if


    }

回答1:

Take a look on the definition of removeChild() :

Removes the specified child DisplayObject instance from the child list of the DisplayObjectContainer instance.

So to get that function executed successfully, it should be executed on the DisplayObjectContainer parent of the child ( DisplayObject ) which we will remove, but if we are outside this parent, the compiler will take the current DisplayObjectContainer as the parent, take this example to understand more :

trace(this);    // gives : [object MainTimeline]

var parent_1:MovieClip = new MovieClip()
    addChild(parent_1);             
    // add the parent_1 to the MainTimeline

var child_1:MovieClip = new MovieClip()
    addChild(child_1);              
    // add the child_1 to the MainTimeline

var child_2:MovieClip = new MovieClip()
    parent_1.addChild(child_2);     
    // add the child_2 to parent_1 which is a child of the MainTimeline         

removeChild(child_1);               
// remove child_1 from the MainTimeline : OK

try {
    removeChild(child_2);           
    // remove child_2 from the MainTimeline : ERROR
} catch(e:*){
    trace(e);                       
    // gives : ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
}

Here we know that child_2 is not a child of the MainTimeline and that's why we got the Error #2025 because the supplied DisplayObject ( child_2 ) is not a child of the caller ( the MainTimeline ).

So to remove the child_2 MovieClip, we have to call removeChild() from it's parent which is parent_1 :

parent_1.removeChild(child_2); // OK

And to simplify or if we don't know it's parent, you can write it :

child_2.parent.removeChild(child_2);

Hope that can help.



回答2:

Try this

for (var index:int= bArray2.length - 1; index >= 0; --index) {
    bullet2 = bArray2[index];

    // you don't even need this check 
    // if you are not setting elements to null in the array
    if (!bullet2) {
        bArray2.splice(index, 1);
        continue;
    }

    // move the bullet
    if (bullet2.x < 500) {
        bullet2.x += 3;  
    } 

    // if the bullet hit the boss or is out of screen remove it
    if((boss && boss.hitTestObject(bullet2)) || bullet2.x > 500) {
        if (this.contains(bullet2)) {  
            removeChild(bullet2);
        }
        bLives -= 1;
        bArray2.splice(index, 1);
    }
}

Iterating over an array from front to back and removing elements will shrink the array and on the next iteration you will skip elements. It is better to iterate from the back to front and remove.

Also it is a good idea to check if a DisplayObjectContainer actually contains the element you are removing before calling removeChild.