在flash中删除未命名的生成实例(as3)

时间:2015-10-09 19:08:01

标签: actionscript-3 flash flash-cc

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

我尝试了Timeout或普通计时器之类的东西,但我仍然无法与他们交谈。

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
}

有人能帮助我吗?

2 个答案:

答案 0 :(得分:0)

我会给你两个选择。

<强> 1。 (Easy-ish方式) - 使用动态属性和数组(或向量)

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

var items:Array = [];

然后,当你生成项目时,将它们添加到数组/向量中,并给它们一个化妆属性,让它称之为持续时间,它将存储当前时间加上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。创建一个完成所有工作的基类

执行此操作的最佳方法是为希望持续特定持续时间的所有对象创建基类。

您可以在.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);
        }
    }
}

扩展此基类的任何内容都会在添加到显示器2秒后自行终止。

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

enter image description here

当然还有其他方法可以实现这一点,你也可以对我所展示的两种方法进行组合,因为只有一个计时器比每个有自己计时器运行的项目更有效。

第3。使用setTimeout(不理想)

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

plane = new Plane();
setTimeout(kill, 2000, plane);
function kill(itemToKill:DisplayObject):void {
    removeChild(itemToKill);
}

答案 1 :(得分:0)

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

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();
    }
    ...

还有一件事:既然你在每个spawn调用上创建一个新的计时器,你应该停止它并在一个处理程序中循环,或者更好地使用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);

希望这有帮助