在 flash (as3) 中杀死未命名的生成实例

kill unnamed generated instances after time in flash (as3)

我正在制作一个小游戏,在其中生成实例,我希望它们在两秒后被杀死。 我遇到的问题 运行 是实例有一个生成的名称,我不知道在它们生成后如何与它们交谈。

我试过超时或普通定时器之类的东西,但我仍然无法与他们交谈。

function spawn(): void {
    if (Math.floor(Math.random() * 70) == 0) {
        plane = new Plane();
        plane.x = Math.random() * (stage.stageWidth - 100) + 50;
        plane.y = Math.random() * (stage.stageHeight - 100) + 20;
        plane.addEventListener(MouseEvent.CLICK, shoot);
        var killtimer: Timer = new Timer(2000);
        killtimer.addEventListener(TimerEvent.TIMER, timerListener);
        //setTimeout(kill, 2000);
        addChild(plane);
        killtimer.start();
    }

    if (Math.floor(Math.random() * 30) == 0) {
        bird = new Bird();
        bird.x = Math.random() * (stage.stageWidth - 100) + 50;
        bird.y = Math.random() * (stage.stageHeight - 100) + 20;
        bird.addEventListener(MouseEvent.CLICK, shoot);
        //setTimeout(kill, 2000);
        addChild(bird);
    }

    if (Math.floor(Math.random() * 300) == 0) {
        g_bird = new Golden_bird();
        g_bird.x = Math.random() * (stage.stageWidth - 100) + 50;
        g_bird.y = Math.random() * (stage.stageHeight - 100) + 20;
        g_bird.addEventListener(MouseEvent.CLICK, shoot);
        //setTimeout(kill, 2000);
        addChild(g_bird);
    }
}

function timerListener(e: TimerEvent): void {
    trace("Killtimer: " + flash.utils.getQualifiedClassName(e.currentTarget));
    e.currentTarget.parent.removeChild(e.currentTarget);  <- Problem e is the timer, not the instance
}

有人可以帮我吗?

我给你两个选择。

1. (简单的方法)- 使用动态属性和数组(或向量)

创建一个数组或向量来保存所有生成的项目。

var items:Array = [];

然后,当你生成你的物品时,将它们添加到 array/vector,并给它们一个弥补的 属性,我们称之为持续时间,它将存储当前时间加 2 秒:

plane = new Plane();
items.push(plane);
plane.duration = flash.utils.getTimer() + 2000; //this is when the item expires and can be removed

然后,制作一个每秒滴答 10 次(或您想要的任何时间)的主计时器

var mainTimer:Timer = new Timer(100);
mainTimer.addEventListener(TimerEvent.TIMER, timerListener);
mainTimer.start();

或者取而代之的是,您可以聆听每一帧:(更准确,但性能较差)

this.addEventListener(Event.ENTER_FRAME, timerListener);

在计时器滴答处理程序(或输入帧处理程序)中,检查每个项目的持续时间并查看是否需要将其删除:

function timerListener(e:Event):void {
    //get the current time
    var time:Number = flash.utils.getTimer();

    //iterate backwards through all the items
    for(var i:int=items.length-1;i--){
        //if the current time is the same or greater
        if(items[i]).time >= time){
            removeChild(items[i]); //remove it from the screen
            items.splice(i,0); //delete it from the array
        }
    }
}

2。创建一个完成所有工作的基础 class

最好的方法是为所有您希望持续特定时间的对象创建一个基础class。

您可以在 .fla 旁边创建一个名为 MyBaseClass.as 的文件。在该文件中,您可以执行如下操作:

package {
    import flash.display.Sprite;
    import flash.utils.Timer;
    import flash.events.Event;
    import flash.events.TimerEvent;

    public class MyBaseClass extends Sprite {
        private var timer:Timer = new Timer(2000,1);

        public function MyBaseClass():void {
            this.addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true);      timer.addEventListener(TimerEvent.TIMER, kill,false,0,true);
        }

        private function addedToStage(e:Event):void {
            timer.start();
        }

        private function kill(e:Event):void {
            if(parent) parent.removeChild(this);
        }
    }
}

任何扩展此基础 class 的东西都会在添加到显示中 2 秒后自行终止。

要扩展它,请右键单击库中的资源(在 FlashPro 中),然后在 "export for actionscript" 设置中,将 MyBaseClass 放在基础 class 文本字段中。


当然还有其他方法可以做到这一点,你也可以结合我展示的两种方法,因为只有一个计时器比每个项目都有自己的计时器更有效运行.

3。使用setTimeout(不理想)

如果只想了解如何使用 setTimeout,这将是正确的用法:

plane = new Plane();
setTimeout(kill, 2000, plane);

function kill(itemToKill:DisplayObject):void {
    removeChild(itemToKill);
}

另一种变体是创建闭包作为事件监听器,它将包含一个平面的值,并且在被触发后将自身作为事件监听器移除,并移除平面。就像这样:

function getKillFn(plane:Plane):Function {
    return function handler(event:TimerEvent):void {
        Timer(event.currentTarget).removeEventListener(TimerEvent.TIMER, handler);
        plane.parent.removeChild(plane);
    }
}

因此,您只需更改代码即可替换此行:

killtimer.addEventListener(TimerEvent.TIMER, timerListener);

这个:

killtimer.addEventListener(TimerEvent.TIMER, getKillFn(plane));

或者您甚至可以就地创建此函数(在 spawn 函数中):

function spawn(): void {
    if (Math.floor(Math.random() * 70) == 0) {
        plane = new Plane();
        plane.x = Math.random() * (stage.stageWidth - 100) + 50;
        plane.y = Math.random() * (stage.stageHeight - 100) + 20;
        plane.addEventListener(MouseEvent.CLICK, shoot);
        var killtimer: Timer = new Timer(2000);

        function killPlane(event:TimerEvent):void {
            killTimer.removeEventListener(TimerEvent.TIMER, killPlane);
            plane.parent.removeChild(plane);
        }

        killtimer.addEventListener(TimerEvent.TIMER, killPlane);
        //setTimeout(kill, 2000);
        addChild(plane);
        killtimer.start();
    }
    ...

还有一件事:因为你在每次生成调用时都创建了一个新的计时器,你应该停止它并在处理程序中回收,或者更好地使用 TimerEvent.COMPLETE,让它自动停止:

var killtimer: Timer = new Timer(2000, 1);

function killPlane(event:TimerEvent):void {
    killTimer.removeEventListener(TimerEvent.COMPLETE, killPlane);
    killTimer = null;
    plane.parent.removeChild(plane);
}

killtimer.addEventListener(TimerEvent.COMPLETE, killPlane);

希望这会有所帮助