2013-03-08 30 views
1

我創建了一個2D側滾動射擊遊戲,有4種不同類型的敵人和3種不同類型的子彈。我使用工廠類來創建敵人,並在for循環中使用for循環進行命中測試。當一個敵人遇到我的其他敵人死亡時,我因爲某種原因運行我的代碼。有人可以幫助我找到並解決我的問題。AS3生成不同的敵人和子彈hitTest問題

這是敵人的一個類。除了var值不同之外,其他3個是相同的。

package char { 

import flash.display.MovieClip; 
import flash.events.Event; 
import flash.display.Stage; 

public class Enemy1 extends MovieClip { 

    private var _type:String; 
    private var _health:Number; 
    private var _vx:Number; 
    private var _vy:Number; 
    private var _stage:Stage; 

    private static var _instance:Enemy1; 

    public function Enemy1() { 
     init(); 
    } 

    private function init():void { 
     //Vars 
     _vx = -5; 
     _vy = Math.random()*5; 
     _health = 1; 
     _stage = Main.getStage(); 
     _instance = this; 

     //Listeners 
     addEventListener(Event.ADDED_TO_STAGE, onAdded); 
     addEventListener(Event.ENTER_FRAME, enemyLoop); 
     addEventListener(Event.REMOVED_FROM_STAGE, onRemoved); 
    } 

    //When Added 
    private function onAdded(event:Event):void{ 
     //Set position 
     this.x = _stage.stageWidth; 
     this.y = Math.random() * _stage.stageHeight; 
     //trace("Enemy created"); 

     dispatchEvent(new Event("enemyCreated", true)); 
    } 

    //Loop 
    private function enemyLoop(event:Event):void { 
     //Move 
     x += _vx; 
     y += _vy; 

     //Boundaries 
     if (this.y <= 0 + this.height/2){ 
      this.y = this.height/2; 
      _vy *= -1; 
     } 
     if (this.y >= _stage.stageHeight - this.width/2){ 
      this.y = _stage.stageHeight - this.width/2; 
      _vy *= -1; 
     } 

     //Health cheack 
     if (_health <= 0){ 
      if (this.parent) { 
       this.parent.removeChild(this); 
       Main.setScore(10); 
      } 
     } 
     //Leaves screen 
     if (this.x <= -this.width){ 
      if (this.parent) { 
       this.parent.removeChild(this); 
      } 
     } 
    } 

    public function isHit(type:String):void{ 
     //trace(this + " is hit by " + type); 
     if(type == "power"){ 
      _health -= 1; 
      trace(_health); 
     } 
     else if(type == "quick"){ 
      _health -= 1; 
      trace(_health); 
     } 
     else if(type == "strong"){ 
      _health -= 1; 
      trace(_health); 
     } 
    } 

    public function getHealth():Number{ 
     return _health; 
    } 

    public function getEnemy1():Enemy1{ 
     return _instance; 
    } 

    //When Removed 
    private function onRemoved(event:Event):void { 
     removeEventListener(Event.ADDED_TO_STAGE, onAdded); 
     removeEventListener(Event.ENTER_FRAME, enemyLoop); 
     removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved); 
     //trace("enemy removed"); 
    } 
} 

} 

及這裏的檢查所有hitTests

package screen { 

import flash.display.MovieClip; 
import flash.events.Event; 
import com.greensock.TweenLite; 
import com.greensock.easing.*; 
import char.Player; 
import char.EnemyFactory; 


public class Level1 extends MovieClip { 
    //Consts 
    private const ENEMY_CHANCE:Number = 0.025; 

    //Vars 
    private var _player:Player; 
    private var _enemyBudget:Number = 20; 
    private static var _bullets:Array = []; 
    private static var _enemies:Array = []; 

    public function Level1() { 
     init(); 
    } 

    private function init():void { 
     //Vars 
     this.alpha = 0; 
     _enemyBudget = 20; 

     //Event listeners 
     addEventListener(Event.ENTER_FRAME, levelLoop); 
     addEventListener(Event.ADDED_TO_STAGE, onAdded); 
     addEventListener(Event.REMOVED_FROM_STAGE, onRemoved); 

     //Add This 
     Main.getInstance().addChild(this); 
    } 

    private function onAdded(event:Event):void { 
     TweenLite.to(this, 0.5, {alpha:1}); 
     _player = new Player(); 
     trace("Level 1 reaady"); 
    } 

    private function levelLoop(event:Event):void{ 
     //Health bar 
     _healthBar.scaleX = Main.getPlayerHealth()/100; 

     //enemy creation 
     if(_enemyBudget <= 20 && _enemyBudget > 10){ 
      if (ENEMY_CHANCE > Math.random()){ 
       var randomEnemy:Number = Math.random()* 1.2; 
       //trace(randomEnemy); 
       if(randomEnemy <= 0.5){ 
        //trace("Enemy 1"); 
        var enemy1:MovieClip = char.EnemyFactory.makeEnemy("weak"); 
        Main.getInstance().addChild(enemy1); 
        _enemyBudget -= 1; 
       } 
       else if(randomEnemy > 0.5 && randomEnemy <= 0.8){ 
        //trace("Enemy 2"); 
        var enemy2:MovieClip = char.EnemyFactory.makeEnemy("quick"); 
        Main.getInstance().addChild(enemy2); 
        _enemyBudget -= 3; 
       } 
       else if(randomEnemy > 0.8 && randomEnemy <= 1){ 
        //trace("Enemy 3"); 
        var enemy3:MovieClip = char.EnemyFactory.makeEnemy("strong"); 
        Main.getInstance().addChild(enemy3); 
        _enemyBudget -= 3; 
       } 
       else if(randomEnemy > 1 && randomEnemy <= 1.2){ 
        //trace("Enemy 4"); 
        var enemy4:MovieClip = char.EnemyFactory.makeEnemy("power"); 
        Main.getInstance().addChild(enemy4); 
        _enemyBudget -= 4; 
       } 
      } 
     } 

     else if(_enemyBudget <= 10 && _enemyBudget > 0){ 
      if (ENEMY_CHANCE > Math.random()){ 
       var randomEnemy:Number = Math.random(); 
       if(randomEnemy <= 0.5){ 
        //trace("Enemy 1"); 
        var enemy1:MovieClip = char.EnemyFactory.makeEnemy("weak"); 
        Main.getInstance().addChild(enemy1); 
        _enemyBudget -= 1; 
       } 
       else if(randomEnemy > 0.5 && randomEnemy <= 0.8){ 
        //trace("Enemy 2"); 
        var enemy2:MovieClip = char.EnemyFactory.makeEnemy("quick"); 
        Main.getInstance().addChild(enemy2); 
        _enemyBudget -= 3; 
       } 
       else if(randomEnemy > 0.8 && randomEnemy <= 1){ 
        //trace("Enemy 3"); 
        var enemy3:MovieClip = char.EnemyFactory.makeEnemy("strong"); 
        Main.getInstance().addChild(enemy3); 
        _enemyBudget -= 3; 
       } 
      } 
     } 

     else if(_enemyBudget <= 0){ 
      if(_enemies == []){ 
       trace("Game End"); 
      } 
     } 

     if(Main.getPlayerHealth() <= 0){ 
      trace("Player Dead. End Game"); 
     } 

     for (var i:int = 0; i < _enemies.length; i++){ 
      for(var j:int = 0; j < _bullets.length; j++){ 
       if(_bullets[j] != null && _enemies[i] != null){ 
        //Check if bullet hits enemy 
        if(_bullets[j].hitTestObject(_enemies[i])){ 
         //removes bullet 
         if (_bullets[j].parent) { 
          _bullets[j].parent.removeChild(_bullets[j]); 
         } 

         //Tells enemy he's hit 
         if(_enemies[i] != null){ 
          _enemies[i].isHit(_bullets[j].getType()); 
         } 

         //Checks enemy health 
         if(_enemies[i].getHealth() <= 0){ 
          if(_enemies[i] == null){ 
           _enemies.splice(i, 1); 
           i--; 
          } 
         } 

         //Removes bullet from array 
         if(_bullets[j] == null){ 
          _bullets.splice(j, 1); 
          j--; 
         } 
        } 

        //Check if player hit 
        if(_enemies[i] != null && _player != null){ 
         if(_enemies[i].hitTestObject(_player)){ 
          if (_enemies[i].parent) { 
           _enemies[i].parent.removeChild(_enemies[i]); 
           Main.setPlayerHealth(-10); 
          } 
         } 

         if(_enemies[i] == null){ 
          _enemies.splice(i, 1); 
          i--; 
         } 
        } 
       } 
      } 
     } 
    } 

    private function onRemoved(event:Event):void{ 
     removeEventListener(Event.ENTER_FRAME, levelLoop); 
     removeEventListener(Event.ADDED_TO_STAGE, onAdded); 
     removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved); 
    } 

    //Get instance 
    public static function addBullet(bullet:MovieClip):void { 
     _bullets.push(MovieClip(bullet)); 
    } 

    public static function addEnemy(enemy:MovieClip):void{ 
     _enemies.push(MovieClip(enemy)); 
     //trace(enemy + " was added to enemy array."); 
    } 
} 

} 

而這裏的子彈類返回的它的類型裏面的功能我的主類。

public function getType():String{ 
     return TYPE; 
    } 

回答

2

很難肯定地說,通過在調試器中逐步驗證代碼很容易確認。

但是對我來說看起來很可疑的是你正在迭代敵人/子彈數組,並且在這樣做的過程中,你會從數組中刪除元素並減少計數器變量。通常,當你需要迭代某些東西並且可能從你正在迭代的東西中移除元素時,你應該以向後的方式做迭代。這樣改變循環中間數組的長度和內容是無害的。

for (var i:int = enemeies.length -1; i >= 0; i--) 
{ 
    // do your stuff and remove elements from the 
    // enemies array at will ... just splice the current 
    // element at index i out here, don't decrement i as 
    // you've done in your code above it will get decremented 
    // by the for loop 
} 
+0

改變我的循環向後走正是我所需要的。謝謝。我覺得我會在編程中多次使用這種有用的技巧。 – Cxsquared 2013-03-09 21:51:34