AS3 - 数组对象仍在更新?

Posted

技术标签:

【中文标题】AS3 - 数组对象仍在更新?【英文标题】:AS3 - Array Object still being updated? 【发布时间】:2012-11-06 17:03:53 【问题描述】:

所以在我的游戏中,我使用了一系列敌人来跟踪它们并更新它们等等 - 当玩家撞到敌人时,它的游戏然而,但是如果玩家射出击中敌人的子弹敌人被删除。好吧,这应该是发生了什么,但是当子弹是敌人时它会删除它但由于某种原因该对象仍在更新并且仍然可以撞到玩家身上?

我该如何阻止这种情况?

这是我在激光类中用于检查碰撞的代码

private function loop(e:Event) : void

    //move bullet up
    y -= bulletSpeed;

    if (y < 0)
    
        removeSelf();
    

    for (var i:int = 0; i < AvoiderGame.enemyArray.length; i++)
    
        if (hitTestObject(AvoiderGame.enemyArray[i]))
        
            AvoiderGame.enemyArray[i].takeHit();
            removeSelf();
        
    

这是我在敌人类中的所有代码。

package 


import flash.display.MovieClip;
import flash.display.Stage;

public class Enemy extends MovieClip

    private var stageRef:Stage;

    public function Enemy(startX:Number, startY:Number, stageRef:Stage)
    
        this.stageRef = stageRef;
        x = startX;
        y = startY;
           
    public function moveDown():void
    
        y = y + (1 + (10 - 1) * Math.random());
        switch(Math.round(1 + (2 - 1) * Math.random()))
        
            case 1: x = x + (1 + (10 - 1) * Math.random());
                    break;
            case 2: x = x - (1 + (10 - 1) * Math.random());
                    break;
        ;
    

    public function StayOnScreen():void
    
        if  (x <= 0)
        
            x = 0;
        
        else if (x >= stageRef.stageWidth)
        
            x = stageRef.stageWidth;
        
        else
        
            x = x;
        
    

    private function removeSelf() : void
    
        if (stageRef.contains(this))
        
            this.parent.removeChild(this);
            delete AvoiderGame.enemyArray[this];
        

    

    public function takeHit() : void
    
        removeSelf();
    
    

这是我在主游戏中的所有代码。

package

import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import com.freeactionscript.CollisionTest;
import flash.display.Stage;
import flashx.textLayout.formats.BackgroundColor;

public class AvoiderGame extends MovieClip

    public static var enemyArray:Array;
    public var enemy:Enemy
    public var Background:gameBackground;

    public var avatar:Avatar;
    public var gameTimer:Timer;

    private var _collisionTest:CollisionTest;
    private var numStars:int = 80;

    private var fireTimer:Timer; //causes delay between fires
    private var canFire:Boolean = true; //can you fire a laser

    public function AvoiderGame()
    
        Background = new gameBackground();
        addChild(Background);

        enemyArray = new Array();
        var enemy = new Enemy(Math.round(1 + (500 - 1) * Math.random()), - 2, stage);
        enemyArray.push(enemy);
        addChild(enemy);

        avatar = new Avatar(stage);
        addChild(avatar);

        avatar.x = stage.stageWidth / 2;
        avatar.y = stage.stageHeight / 2;

        for (var i:int = 0; i < numStars; i++)
        
            stage.addChildAt(new Star(stage), 1);
        

        _collisionTest = new CollisionTest();

        gameTimer = new Timer(25);
        gameTimer.addEventListener(TimerEvent.TIMER, onTick);
        gameTimer.start();

        fireTimer = new Timer(300, 1);
        fireTimer.addEventListener(TimerEvent.TIMER, fireTimerHandler, false, 0, true);
        fireTimer.start();

    

    public function onTick(timerEvent:TimerEvent):void 
    
        if (Math.random() < 0.1)
        
            var enemy = new Enemy(Math.round(1 + (500 - 1) * Math.random()), - 28, stage);
            enemyArray.push(enemy);
            addChild(enemy);
        

        avatar.UpdateAvatar(canFire);
        if (canFire == true)
        
            canFire = false;
            fireTimer.start();
        
        avatar.StayOnScreen();

        for each (var enemy:Enemy in enemyArray)
        
            enemy.moveDown();
            enemy.StayOnScreen();
            if (_collisionTest.complex(enemy, avatar)) 
            
                gameTimer.stop();
            
        
    
    private function fireTimerHandler(e:TimerEvent) : void
    
        //timer ran, we can fire again.
        canFire = true;
    

我知道我可能会在使用 removeSelf() 函数的敌人类中出错,但我将如何解决这个问题?

如果你不想要我的意思是 - 在我的网站上有一个可玩的游戏示例,使用空间射击会摧毁敌人,但它仍然会在游戏中?

http://dynamite-andy.co.uk/projects/free-time/as3-avoider-game/

【问题讨论】:

【参考方案1】:

问题似乎出在removeSelf() 方法中的这一行:

delete AvoiderGame.enemyArray[this];

要从Array 中删除某些内容,您必须使用修改数组的Array class methods 而不是delete 关键字。

[编辑] 在这种情况下,您可以使用splice(),将敌人从阵列中移除:

var enemyIndex:int = this.parent.getChildIndex(this);
this.parent.removeChild(this);
AvoiderGame.enemyArray.splice(enemyIndex, 1);

【讨论】:

这仍然使我提到的那个错误变得不可见并且仍然能够崩溃到播放器中:(。我现在在拍摄时出现以下错误。TypeError:错误#1009:无法访问空对象引用的属性或方法。在 Enemy/removeSelf() 在 Enemy/takeHit() 在 Laser/loop() 糟糕:我在建议的代码中出错(试图在删除子索引后获取子索引)。尝试在拨打removeChild() 之前拨打getChildIndex() 消除了错误,但幽灵动作仍然存在,嗯。 尝试在更改敌人数组之前/之后添加一些跟踪语句:trace('array length: ', AvoiderGame.enemyArray.length); 然后在控制台上查看此输出。这样你就可以看到什么时候从数组中添加/删除东西,并希望找出问题。 实际上避免依赖 childIndex 作为数组中的位置 - 例如,您不能确定不会交换子项,而是使用 indexOf(this) 来查找位置或简单循环。

以上是关于AS3 - 数组对象仍在更新?的主要内容,如果未能解决你的问题,请参考以下文章

按住 AS3 键防止鼠标更新

关闭窗口后方法仍在运行

AS3:mouseX 在鼠标移动之前不会更新

如何使用 AS3 更新我的外部 XML 文件?

为什么当我更新二维数组时会出现“错误#1010”

PHP无法取消设置对象内的数组元素