ArgumentError:错误#2025修复removeChild

时间:2012-10-20 11:54:40

标签: actionscript-3 removechild

我正在尝试制作太空飞船游戏,当我使用removeChild()方法将弹丸或敌舰移出舞台时,我遇到了问题。

以下是代码的相关部分:

var bulletsArr:Array = new Array();
var eShipsArr:Array = new Array();


for (var c = 0; c < eShipsArr.length; c++){
stage.addChild(eShipsArr[c]);
}
....

stage.addEventListener(KeyboardEvent.KEY_DOWN,shoot);

function shoot (e:KeyboardEvent):void{
if(e.keyCode==17){
    var pj:projectile = new projectile();
    pj.x = SShip.x;
    pj.y = SShip.y;
    stage.addChild(pj);
    bulletsArr.push(pj);
    if(bulletsArr.length >= 10){
       bulletsArr = bulletsArr.slice(1,10);
    }
}
}
stage.addEventListener(Event.ENTER_FRAME,checkHit);

function checkHit (e:Event):void{
for (var d = 0; d < bulletsArr.length; d++){
    for(var f = 0; f < eShipsArr.length; f++){
        if(bulletsArr[d].hitTestObject(eShipsArr[f])){
            trace(bulletsArr[d].parent);
            stage.removeChild(bulletsArr[d]); //ArgumentError: Error #2025!!!!
        }
    }
}
}

removeChild()stage一起使用时,跟踪会返回null。没有它,跟踪返回Stage object。在这两种情况下,同样的错误都会跳跃。

1 个答案:

答案 0 :(得分:0)

您是否正在尝试删除已删除的子项?

您没有从数组中删除它,因此下一个循环或下一个checkHit调用将包括对可能已从阶段中删除的对象的检查。即使对象不在舞台上,hitTestObject检查也会返回true

未经测试(请注意,当删除数组元素时,向后迭代bulletes数组以避免长度问题):

for (var d = bulletsArr.length - 1; d >= 0; d--){
    for(var f = 0; f < eShipsArr.length; f++){
        if(bulletsArr[d].hitTestObject(eShipsArr[f])){
            trace(bulletsArr[d].parent);
            stage.removeChild(bulletsArr[d]); 
            bulletsArr.splice(d, 1); // remove bullet from array
        }
    }
}

编辑:这是一些未经测试的(正确输入的)代码,以防单个子弹可能与两艘或更多船发生碰撞,您需要做的就是移除子弹:

for(var f:Number = 0; f < eShipsArr.length; f ++)
{
    for(var d:Number = bulletsArr.length - 1; d >= 0; d --)
    {
        if(bulletsArr[d].hitTestObject(eShipsArr[f]))
        {
            stage.removeChild(bulletsArr[d]);
            bulletsArr.splice(d, 1);
        }
    }
}

不会再次检查互换的循环,即删除子弹的循环。

如果一颗子弹可能与两艘或多艘船发生碰撞,并且您打算对与子弹发生碰撞的船只做一些事情,那么试试这个:

    for(var d:Number = bulletsArr.length - 1; d >= 0; d --)
    {
        var bullet:DisplayObject = bulletsArr[d];
        var bulletHitSomething:Boolean = false;

        for(var f:Number = 0; f < eShipsArr.length; f ++)
        {
            if(bullet.hitTestObject(eShipsArr[f]))
            {
                if(!bulletHitSomething)
                {
                    bulletHitSomething = true;
                    stage.removeChild(bullet);
                    bulletsArr.splice(d, 1);
                }
                // do other, ship specific stuff here
            }
        }
    }

当前项目符号对象引用存储在一个变量中,所有检查都是使用数组访问对该变量而不是数组中的元素进行的。与数组访问方法不同,它可能访问不存在的索引,这种方式可能连续检查同一子弹应该没问题。另外一个变量存储子弹是否已经击中某个东西,因此它不会再次尝试删除该子弹。