AS3生成不同的敌人和子弹hotTest问题

时间:2013-03-08 14:53:59

标签: actionscript-3 flash instance creation hittest

我正在创建一个2d侧滚动射击游戏,有4种不同类型的敌人和3种不同类型的子弹。我正在使用工厂类来创建敌人,并在for循环中使用for循环来进行命中测试。当我出于某种原因运行我的代码时,当一个敌人被击中时,我的其他一些敌人会死亡。有人可以帮我找到并解决我的问题。

这是Enemy课程之一。除了具有不同的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.");
    }
}

}

这里是Bullet类中返回它的类型的函数。

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

1 个答案:

答案 0 :(得分: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
}