2013-03-08 1 views
1

Я создаю 2-й боковой прокручивающий шутер с 4 различными типами врагов и 3 разных типами пуль. Я использую фабричный класс для создания врагов и цикла for внутри цикла for, чтобы выполнить тестирование на удар. Когда я запускаю свой код по какой-то причине, когда один из врагов попадает, некоторые из моих других врагов умирают. Может кто-то, пожалуйста, помогите мне найти и исправить мою проблему.AS3 Генерация differnet Враги и пули hitTest Problems

Вот один из классов Enemy. Остальные 3 идентичны, за исключением разных значений var.

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

Трудно с уверенностью сказать, что это будет легко подтвердить с помощью пошагового кода в отладчике.

Но мне кажется подозрительным то, что вы повторяете массивы врагов/пуль, а в середине этого вы удаляете элементы из массива и уменьшаете счетные переменные. Как правило, когда вам нужно перебирать что-то и потенциально удалять элементы из того, что вы повторяете, вы должны сделать эту итерацию в обратном порядке. Таким образом, изменение длины и содержимого массива в середине цикла безвредно.

+0

Изменение моей петли в обратном направлении - это именно то, что мне нужно. Спасибо. Я чувствую, что много раз буду использовать эту полезную технику в своем программировании. – Cxsquared

Смежные вопросы