我正在尝试制作太空飞船游戏,当我使用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
。在这两种情况下,同样的错误都会跳跃。
答案 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
}
}
}
当前项目符号对象引用存储在一个变量中,所有检查都是使用数组访问对该变量而不是数组中的元素进行的。与数组访问方法不同,它可能访问不存在的索引,这种方式可能连续检查同一子弹应该没问题。另外一个变量存储子弹是否已经击中某个东西,因此它不会再次尝试删除该子弹。