Actionscript 3.0 Splice/RemoveChild问题

问题描述:

我有岩石和敌人忍者离开屏幕。忍者一旦遭到手里剑的击中就应该消失,然而他们正在接受两次命中消失,尽管手中的每一次都会消失。代码对于shurikens和敌人忍者几乎是相同的,但是忍者似乎不能正常工作。我也偶尔忍受忍者卡在屏幕上的任何地方,手中穿过它。Actionscript 3.0 Splice/RemoveChild问题

//If a rock moves off the screen, it is spliced. 
    if (rock[j].x <= -301){ 
     removeChild(rock[j]); 
     rock.splice(j, 1); 
     rockNum--; 
    } 
} 

for (var q=shurikens.length - 1; q >= 0; q--){ 
    for (var w=enemy.length - 1; w >= 0; w--){ 
     //If the shurikens hit the ninjas. 
     if ((shurikens[q]).hitTestObject(enemy[w])){ 
      removeChild(enemy[w]); 
      enemy.splice(w, 1); 
      ninjaNum--; 
      removeChild(shurikens[q]); 
      shurikens.splice(q, 1); 
      break; 
     } 
    } 
} 

}

+0

你可以用两个忍者手里剑 - 检查如果一个带有索引“q”的手里剑同时击中两个忍者会发生什么。你会得到索引'q + 1'拼接出来的手里剑,而不是从屏幕上移除。为了解决这个问题,当你发现一个给定的手里剑时,你需要立即停止外圈。 – Vesper

如何解决你的代码,并给你一些性能提示:

这段代码是非常“虫友”:要修改阵列的“长度”属性在依赖于相同属性的for/in循环中,这实际上不是明智的做法。 的方式我会做:

// Create an array where to store colliding ninjas and shurikens 
    var depleted:Array = []; 
    // Create local references to make code more readable and fast (querying arrays all the time is slow). 
    var ninja:DisplayObject; 
    var shuriken:DisplayObject; 
    // Loop in shurikens (no need to check if shurikens have been depleted, since you query only once each of them 
    for (var q:int=shurikens.length - 1; q >= 0; q--){ 
     shuriken = shurikens[q]; // Assign a shuriken to our variable so you avoid to call further shurikens[q]; 
     for (var w:int=enemy.length - 1; w >= 0; w--){ // Loop in ninjas 
      ninja = enemy[w]; // Assign ninja 
      //If the shurikens hit the ninjas. (only if ninjas have not yet been removed) 
      // This is the core of our improvement, before calling hitTest that is slow, you first check that ninjas have not already been killed 
      if (depleted.indexOf(ninja) == -1 && 
shuriken.hitTestObject(ninja)){ 
       // It's a hit with a live ninja. I just add both objects to depleted list. 
       depleted.push(ninja); 
       depleted.push(shuriken); 
       break; // Breaking the loop, makes sure shuriken cannot hit 2 ninjas 
      } 
     } 
    } 
// Then, you loop in the list of killed ninjas and depleted shurikens, and remove them from arrays and display list 
for each (var depletedObj:DisplayObject in depleted) { 
    // First remove object from the relevant array 
    if (shurikens.indexOf(depletedObj) != -1) shurikens.splice(shurikens.indexOf(depletedObj), 1); // If it was in the shurikens array remove from there 
    else if (enemy.indexOf(depletedObj) != -1) enemy.splice(enemy.indexOf(depletedObj), 1); // If it was in the ninjas array remove from there 
    // The do all necessary stuff to remove object from DisplayList (end eventually add it to an object pooling list) 
    removeChild(depletedObj); 
} 
ninjaNum = enemy.length; // Update number of ninjas 

另一个提示,如果你对每一帧的循环运行它,如果你把忍者和shurikens在2个不同的DisplayObjectContainer,可以先则hitTest的2个大容器,和一旦碰撞,你可以运行循环来检查碰撞。另外,在/ in循环的数字中,声明变量始终为:int。键入变量使访问速度快于无类型变量。你当然可以改进这个代码,使其更快,即:为shurikens和ninjas添加一个“alive = true”属性,所以你不需要查询第三个数组等。