访问数组中的对象时AS3不匹配

时间:2013-10-13 15:14:49

标签: arrays actionscript-3 flash game-engine removechild

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

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

事情是它适用于前几个敌人,然后它将挑选错误的敌人来摧毁,并完全停止运作。 我尝试使用indexOf来确保我指的是正确的对象,但无济于事。 我认为Pslice和removeChild指向不同的对象。

当我将removeChild和splice从Game Class移动到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 class 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));
            } 
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您应该向后遍历Game.level1.enemies_arrbullets_arr。重点是,splice()缩短了数组,将位于比拼接位置更大位置的元素转移到较小的索引,并且不会自动调整循环计数器。错误很常见,但经常被忽视。此外,使用bullets_arr,如果bullets_arr中的最后一颗子弹击中敌人,你可以离开阵列导致1009错误。

一个小的挑剔:你正在循环中检查数组的存在,并且在输入帧监听器中检查另一个数组的存在。事实上,在将事件监听器添加到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
}

答案 1 :(得分:0)

我终于找到了问题,这对我来说非常愚蠢: 我只是错误地输入了Enemy类中的Die函数:

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

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