2011-12-11 1 views
0

レーザーが敵に当たったときにレーザーと敵を取り除きたいのですが、 私のループは何とかインデックスの外側を検索してプログラムをクラッシュさせます。私は間違って何をしていますか?それを反復処理しながら、配列の要素を削除する私がヒットした子どもを取り除きたいのですが、インデックスがオフのようです

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.events.MouseEvent; 
    import flash.events.TimerEvent; 
    import flash.geom.Rectangle; 
    import flash.ui.Mouse; 
    import flash.utils.Timer; 

    [SWF(width = 500, height = 500, frameRate = 25, backgroundColor = 0x000000)] 

    public class Main extends Sprite 
    { 
     private var craft:Craft = new Craft(); 
     private var laser:Laser; 
     private var laserCollection:Vector.<Laser> = new Vector.<Laser>; 
     private var laserSpeed:Number = 5; 

     private var newEnemyTimer:Timer = new Timer(2000); 
     private var enemy:Enemy; 
     private var enemyCollection:Vector.<Enemy> = new Vector.<Enemy>; 
     private var enemySpeed:Number = 5; 

     public function Main() 
     { 
      addChild(craft); 
      //Create a bounding box for the draggable area. 
      var rect:Rectangle = new Rectangle(12, 460, 476, 0); 
      //If you set startDrags first parameter, LockCenter to true, you don't have to explicitly set the targets position to the mouses position. 
      craft.startDrag(true, rect); 
      Mouse.hide(); 

      newEnemyTimer.start(); 
      newEnemyTimer.addEventListener(TimerEvent.TIMER, newEnemy); 

      stage.addEventListener(MouseEvent.CLICK, shoot); 

      addEventListener(Event.ENTER_FRAME, update); 
     } 

     private function update(e:Event):void 
     { 
      updateLasers(); 
      updateEnemies(); 
      checkForHit(); 

      trace("lasers:" + laserCollection.length + ", enemies:" + enemyCollection.length); 
     } 

     private function checkForHit():void 
     { 
      if (laserCollection.length > 0) 
      { 
       for (var i:int = 0; i < laserCollection.length; i++) 
       { 
        for (var j:int = 0; j < enemyCollection.length; j++) 
        { 
         if (laserCollection[i].hitTestObject(enemyCollection[j])) 
         { 
          removeChild(laserCollection[i]); 
          laserCollection.splice(i, 1); 

          removeChild(enemyCollection[j]); 
          enemyCollection.splice(j, 1); 

          //The program crashes here because the index is outside the reach, 
          //i.e if I have 8 laser beams out and only 3 enemies, it tries to remove enemy[8] 
          // I THINK??? 
         } 
        } 
       } 
      } 
     } 

     private function updateLasers():void 
     { 
      if (laserCollection.length > 0) 
      { 
       for (var i:int = 0; i < laserCollection.length; i++) 
       { 
        if (laserCollection[i].y > 10) 
        { 
         laserCollection[i].y -= laserSpeed; 
         laserCollection[i].alpha -= 0.01; 
        } 
        else 
        { 
         //Can the problem be that I also remove the laser here? 
         //It seem to crash even if I hit an enemy at the bottom of the stage so shouldn't be. 
        removeChild(laserCollection[i]); 
        laserCollection.splice(i, 1); 
        } 
       } 
      } 
     } 

     private function updateEnemies():void 
     { 
      if (enemyCollection.length > 0) 
      { 
       for (var i:int = 0; i < enemyCollection.length; i++) 
       { 
        if (enemyCollection[i].y < 500) 
        { 
         enemyCollection[i].y += enemyCollection[i].getSpeed(); 
        } 
        else 
        { 
         enemyCollection[i].y = -20; 
         enemyCollection[i].setSpeed(); 
         enemyCollection[i].x = Math.random() * stage.stageWidth; 
        } 
       } 
      } 
     } 

     private function newEnemy(e:TimerEvent):void 
     { 
      enemy = new Enemy(); 
      addChild(enemy); 
      enemy.x = Math.random() * stage.stageWidth; 
      enemy.y = -30; 
      enemyCollection.push(enemy); 
     } 

     private function shoot(e:MouseEvent):void 
     { 
      laser = new Laser(); 
      addChild(laser); 
      laserCollection.push(laser); 
      laser.x = craft.x; 
      laser.y = craft.y; 
     } 
    } 
} 

答えて

0

は問題があった:あなたはarray[i]にある要素を削除する時には、次の要素が上に移動します。エレメントを削除した直後の同じサイクルには、まだarray[i]のエレメントがあります。次のループサイクルが始まると、iがインクリメントされ、要素をスキップしました。

2つの解決策:

  • デクリメントカウンター(あなたのケースでは、両方のij)あなたは要素を削除した場合。
  • ループが後方にあるので、まだチェックされていない要素のインデックスは変更されません。

もう一つ:コレクションが空の場合、ループはとにかく実行されませんようif (laserCollection.length > 0)などのチェックはここでは必要ありません。

+0

インデックス0の要素を常に削除するとどうなりますか? – AsTheWormTurns

+0

@AsTheWormTurnsもし彼が 'array [0]'を削除し、 'i'を減少させると' -1'になります。ループが継続すると、再び「0」にインクリメントされるため、常に正しい範囲に収まります。それを減らした直後にインデックスを使用しない限り、大丈夫です。 – Kapep

関連する問題