AS3 更新变量报告 Null.. 在一个模式中

AS3 Update Variable Reports Null.. in a pattern

我正在 AS3 中制作 space 游戏 - 我有一个名为 EnemyShip 的敌人 class。

我已经注册了 Event.ENTER_FRAME 并且它工作正常 - 问题是我的变量,Array 类型的 rowXY,在一个模式中报告空值和非空值。

我怎样才能避免这种情况发生(或者在 Flash Professional 中是否有更简单的方法来设置船舶动画?)。

模式如下:

敌舰:

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class EnemyShip extends Sprite
    {
        internal var id:int;
        internal var rowOrder:int;
        internal var rowXY:Array;
        private var dirUp:Boolean = false;

        public function EnemyShip()
        {
            // add event listeners
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

            addEventListener(Event.ENTER_FRAME, update);    
        }

        private function update(e:Event):void
        {
            moveUpAndDown();

            trace(rowXY);

            function moveUpAndDown():void
            {
                if (dirUp)
                    y -= C.ENEMY_SPEED;
                else
                    y += C.ENEMY_SPEED;
            }
        }

        private function onAddedToStage(e:Event):void
        {
            // get row XY
            if (rowOrder == 1)
                rowXY = C.ENEMY_ROW_1;

            if (rowOrder == 2)
                rowXY = C.ENEMY_ROW_2;

            if (rowOrder == 3)
                rowXY = C.ENEMY_ROW_3;

            // set XY position
            x = rowXY[0];
            y = rowXY[1];

            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

        }

        internal function destroy():void
        {
            rowOrder = null;
            rowXY = null;

            // remove event listeners
            removeEventListener(Event.ENTER_FRAME, update);

            // remove from display list
            parent.removeChild(this);

        }

    }

}

C.as(常量):

package
{
    // C stands for constants

    public class C
    {
        // ship constants
        public static const FIRE_DELAY:int = 500; // milliseconds

        // laser constants
        public static const LASER_SPEED:int = 30;
        public static const POINTS_KILL:int = 10;

        // mcScore constants
        public static const SCORE_LOC_X:Number = 345;
        public static const SCORE_LOC_Y:Number = -120;

        // enemy ship constants
        public static const ENEMY_ROW_1:Array = [485, -45];
        public static const ENEMY_ROW_2:Array = [485, 25];
        public static const ENEMY_ROW_3:Array = [485, 95];
        public static const ENEMY_SPEED:int = 5; // 5 pixels
        public static const ENEMY_Y_MIN:int = -10;
        public static const ENEMY_Y_MAX:int = 10;
    }

}

如果您尝试使用 Flash Professional 制作动画,我会利用其内置 Motion Tween feature. You could also animate the ship in your code by taking advantage of the Tween class.

我重现了你使用这个 for 循环的行为(你可以通过实例化 3 个对象并将另外 3 个对象直接插入舞台来获得相同的结果):

for(var i:int = 1; i < 7; i++){
    var enemy:EnemyShip = new EnemyShip();
        enemy.rowOrder = i;
    addChild(enemy);
}

在这里我们可以很清楚地看到 i 是 4、5 或 6,rowOrder 将是 null,这也会为所有实例触发一些 #1009 错误此行中的 rowOrder 大于 3 :

x = rowXY[0];

因此,为了避免这种情况,您可以将 rowOrder 的值限制在 1 到 3 之间,例如:

enemy.rowOrder = 1 + int(Math.random()*3);

您还可以在 EnemyShip class 本身中设置该值。

...

希望能帮到你。

解决方案

据我所知,事件 Event.ENTER_FRAME 仅传递给舞台上的对象,但事实并非如此。

问题出在我的 EnemyShip class' 构造方法中 - ENTER_FRAME 事件正在被舞台上和舞台下的实例侦听 - 舞台下的实例尚未分配一个 rowXY(这发生在 ADDED_TO_STAGE 事件中)。

旧代码:

新代码:

那么这里有什么教训呢?
Event.ENTER_FRAME 无论对象是否显示都会发生。

在您发布的屏幕截图中,您有以下代码:

if(rowOrder > 3)
    rowOrder = 0;

但是当您在 onAddedToStage() 中检查 rowOrder 时,您没有 0 的情况 - 只有 1、2 或 3。因此 rowXY 永远不会在 rowOrder 是 0.

要么更改该代码以将 rowOrder 设置为 1 而不是 0,或者将您的其他代码更改为零索引。