0

我遇到了一个非常具有挑战性的问题,我很想得到一些支持。这是场景:

主 Game 类实例化 Level1 类,负责通过嵌套的 For 循环生成敌人并将它们推送到数组中。然后它检查 Bullet 和 Enemy 之间的碰撞,如果发现碰撞,它会调用 Enemy 类中的一个方法,从数组中删除 removeChild 和 Splice 本身。

问题是它对最初的几个敌人有效,然后它会选择错误的敌人来摧毁,并完全停止发挥作用。我尝试使用 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()[]在将事件侦听器添加到Main对象之前或在将其分配到的任何位置初始化它们,或者检查类似if (!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 回答
0

我终于找到了问题,我很愚蠢:我只是在 Enemy 类中打错了 Die 函数:

我写了 :splice(Game.level1.enemies_arr.indexOf(enemyHit,1)) 而不是 splice(Game.level1.enemies_arr.indexOf(enemyHit),1)

无论如何,通过尝试修复此错误,我学到了很多想法。谢谢

于 2013-10-15T11:03:34.137 回答