1

4 種類の敵と 3 種類の弾丸を使用する 2D 横スクロール シューティング ゲームを作成しています。ファクトリ クラスを使用して敵を作成し、for ループ内に for ループを使用してヒット テストを行います。なんらかの理由でコードを実行すると、ある敵が攻撃を受けて他の敵が死亡します。誰かが私の問題を見つけて修正するのを手伝ってくれませんか.

これは、敵のクラスの 1 つです。他の 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.");
    }
}

}

そして、これがBulletクラス内の関数で、型を返します。

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

1 に答える 1

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
}
于 2013-03-08T19:47:09.823 に答える