0

私は非常に挑戦的なものに遭遇したので、何らかのサポートを得たいと思っています. シナリオは次のとおりです。

メインの Game クラスは、ネストされた For ループを介して敵をスポーンし、それらを配列にプッシュする担当の Level1 クラスをインスタンス化します。次に、Bullet と Enemy の間の衝突をチェックし、衝突が見つかった場合は、配列から removeChild と Splice 自体を削除する Enemy クラスのメソッドを呼び出します。

問題は、最初の数人の敵に対して機能し、その後、破壊する敵を間違って選択し、完全に機能を停止することです. indexOf を使用して正しいオブジェクトを参照していることを確認しようとしましたが、役に立ちませんでした。Pslice と removeChild は別のオブジェクトを指していると思います。

この混乱は、removeChild と splice を Game クラスから Enmy クラスに移動したときに発生しました。

進行中の作業へのリンク: https://dl.dropboxusercontent.com/s/69hcmzygnkx7h1e/space_shooter.swf

これについて何か助けてほしい。ありがとうございました !!!

メインクラス: Game.AS

package 
{
    import flash.display.MovieClip;

    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.text.*;
    import flash.geom.Point;

    public class Game extends MovieClip
    {
        public var _instance : Game;
        public var player:Player;
        public  static var level1:Level1;
        public var bullet:Bullet;
        private var bullets_arr:Array;
        var fire_on : Boolean;
        var fire_counter : int;

        public function Game()
        {

            level1=new Level1(this.stage);
            player = new Player  ;
            addChild(player);
            player.y = 600;
            bullets_arr = [];
            addEventListener(Event.ENTER_FRAME,Main);
            stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
        }

        function mouseDownHandler($e:MouseEvent):void
        {
            fire_on = true;
        }

        function mouseUpHandler($e:MouseEvent):void
        {
            fire_on = false;
            fire_counter = 0;
        }

        function fire():void
        {
            bullet = new Bullet  ;
            addChild(bullet);
            bullet.x = player.x;
            bullet.y = player.y - 32;
            bullets_arr.push(bullet);
        }

        public function Main(e: Event):void
        {

            player.x = mouseX;

            if (bullets_arr)
            {
                for (var m:int = 0; m < bullets_arr.length; m++)
                {
                    bullets_arr[m].y -=  20;

                    if(Game.level1.enemies_arr)
                    {   
                        for (var n:int = 0; n < Game.level1.enemies_arr.length; n++)
                        {
                            if (Game.level1.enemies_arr[n].hitTestObject(bullets_arr[m]))
                            {
                                if(bullets_arr[m].parent)
                                {
                                    bullets_arr[m].parent.removeChild(bullets_arr[m]);
                                    bullets_arr.splice(bullets_arr[m],1);
                                    Game.level1.enemies_arr[n].Damage(10, Game.level1.enemies_arr[n]);
                                }
                            }
                        }
                    }
                }
            }

            if(fire_on)
            {
                fire_counter++;
                if(fire_counter == 01)
                {
                    fire();
                }
                else if(fire_counter >2)
                {
                    fire_counter =0;
                }
            }
        }
    }
}

Level1.as は、敵がスポーンされ、アレイにプッシュされる場所です。

  package 
{

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

public class Level1 extends MovieClip
{
    var i:int;
    var j:int;
    var frame :int;
    public var enemy:Enemy;
    public var enemies_arr:Array;

    public function Level1(target:Stage) 
    {
        frame = 0;
        enemies_arr = [];

        for (var i:int = 0; i < 5; i++)
        {
            for (var j:int = 0; j < 3; j++)
            {
                enemy = new Enemy;
                enemy.x = j*100 + 260;
                enemy.y = i*40 - 150;
                target.addChild(enemy);
                enemies_arr.push(enemy);
                trace(enemy.parent);
            }
        }
    }
}
}

Enemy クラス Enemy.AS

package
{
    import flash.display.MovieClip;

    public class Enemy extends MovieClip
    {
        var Health : int;

        function Enemy()
        {
            Health =2;
        }
        public function Damage(Damage:int, enemyHit:Enemy)
        {
            Health -= Damage;
            if (Health <1)
            {
                Die(enemyHit);
            }
        }
        private function Die(enemyHit:Enemy)
        {       
            if(enemyHit.parent)
            {
                this.parent.removeChild(this);
                Game.level1.enemies_arr.splice(Game.level1.enemies_arr.indexOf(enemyHit,1));
            } 
        }
    }
}
4

2 に答える 2

0

Game.level1.enemies_arr両方とbullets_arr後方にトラバースする必要があります。ポイントは、splice()配列を短くし、結合された要素よりも大きい位置にある要素をより小さなインデックスにシフトし、ループ カウンターが自動的に調整されないことです。エラーはかなり一般的ですが、見過ごされがちです。また、最後の弾丸が敵に命中するbullets_arrと、アレイから抜け出すことができ、1009 エラーが発生します。bullets_arr

ちょっとしたコツ:ループ内の配列の存在と、フレームに入ったリスナー内での別の配列の存在をチェックしています。実際には、少なくともイベントリスナーをオブジェクトに追加する前に、new Array()またはこれが割り当てられている場所でそれらを初期化するか、または同様にチェックしてそのままにしておく必要があるため、配列の存在を1回チェックする必要があります。[]Mainif (!bullets_arr) bullets_arr=new Array();

public function Main(e: Event):void
{
    player.x = mouseX;
    if (!bullets_arr) bullets_arr=new Array();
    if (!Game.level1.enemies_arr) throw new Error('Hey programmer, initialize your arrays!'); 
    // ^ bad practice to throw exceptions in listeners, but if you get one, you've coded something wrongly.
    for (var m:int=bullets_arr.length-1;m>=0;m--) {
        var bm:Bullet=bullets_arr[m]; // TODO fix type
        // the local variable is a cleaner and faster approach
        bm.y-=20;
        for (var n:int=Game.level1.enemies_arr.length-1;n>=0;n--) {
           if (!bm) break; // bullet was destroyed, why checking more enemies vs that?
           if (Game.level1.enemies_arr[n].hitTestObject(bm)) {
              bm.parent.removeChild(bm);
              bullets_arr.splice(m,1); // splice is done by index, not by object
              bm=null; // oops, missed this. The bullet hit something and is now lost
              // so we null the local var, so we can break out the loop.
              Game.level1.enemies_arr[n].Damage(10, Game.level1.enemies_arr[n]);
           }
        }
     }
    // rest of your code follows here
}
于 2013-10-13T15:34:26.593 に答える