Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flash 为什么我的事件侦听器会多次触发?_Flash_Actionscript 3_Events - Fatal编程技术网

Flash 为什么我的事件侦听器会多次触发?

Flash 为什么我的事件侦听器会多次触发?,flash,actionscript-3,events,Flash,Actionscript 3,Events,在我的Flash项目中,我有一个有两个关键帧的movieclip。两个帧各包含一个电影剪辑 第1帧-着陆 第2帧-游戏 应用程序的流程很简单: 用户到达登录页(第1帧) 用户点击“开始游戏”按钮 用户被带到游戏页面(第2帧) 游戏结束后,用户可以按“再次播放”按钮,返回到步骤1 Landing和Gamemovieclips都链接到定义事件侦听器的单独类。问题是,当我在玩游戏后返回步骤1时,游戏事件侦听器会为各自的事件触发两次。如果我第三次执行这个过程,事件侦听器会为每个事件触发三次。这一直在发生

在我的Flash项目中,我有一个有两个关键帧的movieclip。两个帧各包含一个电影剪辑

第1帧-
着陆

第2帧-
游戏

应用程序的流程很简单:

  • 用户到达登录页(第1帧)
  • 用户点击“开始游戏”按钮
  • 用户被带到游戏页面(第2帧)
  • 游戏结束后,用户可以按“再次播放”按钮,返回到步骤1
  • Landing
    Game
    movieclips都链接到定义事件侦听器的单独类。问题是,当我在玩游戏后返回步骤1时,
    游戏
    事件侦听器会为各自的事件触发两次。如果我第三次执行这个过程,事件侦听器会为每个事件触发三次。这一直在发生,因此如果我循环应用程序流7次,事件侦听器将触发7次。我不明白为什么会发生这种情况,因为在第1帧上,
    Game
    movieclip(我假设它的相关类实例)不存在——但我显然遗漏了一些东西

    我在其他项目中也遇到过这个问题,并尝试通过首先检查事件侦听器是否存在并仅定义它们(如果不存在)来解决它,但我最终得到了意想不到的结果,并没有真正解决问题


    我需要确保事件侦听器只触发一次。如有任何建议和见解,将不胜感激,谢谢

    如果在同一层上有两个具有不同剪辑的帧,则每次该帧“进入”时,都会创建该剪辑。当它“离开”时,夹子被移除,但它仍然会被保留在周围,不会被垃圾收集。因此,下一次帧进入不同的剪辑时,它将“创建”并获得自己的侦听器。最好的办法是在更改帧时删除侦听器。我通常通过在每堂课中为
    事件设置一个监听器来解决这类问题。如果它被删除,那么您将清理剩余的侦听器

    您可能还想尝试“弱侦听器”:

    “true”使链接“弱”,因此,如果删除了对象,垃圾收集器可以将其拾取。不过,我不会完全依赖这个。最好手动删除引用,以便您可以确定


    这个答案当然假设了很多。如果您发布代码/屏幕截图/FLA以更好地进行诊断,这将很有帮助。

    如果您在同一层上有两个具有不同剪辑的帧,则每次该帧“进入”时,都会创建该剪辑。当它“离开”时,夹子被移除,但它仍然会被保留在周围,不会被垃圾收集。因此,下一次帧进入不同的剪辑时,它将“创建”并获得自己的侦听器。最好的办法是在更改帧时删除侦听器。我通常通过在每堂课中为
    事件设置一个监听器来解决这类问题。如果它被删除,那么您将清理剩余的侦听器

    您可能还想尝试“弱侦听器”:

    “true”使链接“弱”,因此,如果删除了对象,垃圾收集器可以将其拾取。不过,我不会完全依赖这个。最好手动删除引用,以便您可以确定


    这个答案当然假设了很多。如果你发布代码/屏幕截图/flas以更好地诊断,这会很有帮助。

    如果你没有看到代码,也不知道你在听什么事件以及是谁/什么触发了这些事件,就很难确定

    但是,我的猜测是,电影嘴唇没有被收集(这不一定是内存泄漏!),因此,它们仍然活着。可以说,您应该有一个方法将它们设置为“空闲”状态。也就是说,删除侦听器、停止计时器等。这样做的目的是将对象置于不运行任何代码的状态

    movieclips和其他显示对象的一种简单方法(通常已经足够好了)是侦听添加到\u阶段和从\u阶段事件中删除的\u。这里的想法是,当你的对象被添加到舞台上时,它会“激活”,在你的情况下,当你到达游戏类的第2帧时;当它被移除时,即当您返回到第1帧时,它将“停用”

    大致如下:

    public class Game extends MovieClip {
    
        private var _timer:Timer;
    
        public function Game() {
            addEventListener(Event.ADDED_TO_STAGE,init);
            addEventListener(Event.REMOVED_FROM_STAGE,destroy);
        }
    
        private function init():void {
            //  your init code goes here
            //  just an example:
            _timer = new Timer(33);
            _timer.addEventListener(TimerEvent.TIMER,mainLoop);
            _timer.start();
            trace("init");
        }
    
        private function destroy():void {
            _timer.stop();
            _timer.removeEventListener(TimerEvent.TIMER,mainLoop);
            trace("destroy");
        }
    
        private function mainLoop(e:TimerEvent):void {
            //  code for main loop here...
            trace("mainLoop");
        }
    }
    
    检查痕迹,看它是否工作正常。您应该看到“init”被跟踪出来,然后是“mainLoop”,只要您停留在第2帧,当您返回到第1帧时是“destroy”。“mainLoop”此时应停止跟踪


    除此之外,您可能还需要检查是否存在内存泄漏(事实上,您有7个实例并不一定意味着您有泄漏;但在某些情况下,如果GC运行,至少应该释放其中的一些;如果从未发生过这种情况,这是泄漏的症状;尝试强制GC查看活动实例的数量是否减少;如果没有,则很可能有泄漏).

    如果看不到代码,也不知道您在监听什么事件以及是谁/什么触发了这些事件,就很难确定

    但是,我的猜测是,movieclips没有被收集(这不一定是内存泄漏!),因此,它们仍然处于活动状态。您可能应该有一种方法将它们设置为“空闲”也就是说,删除侦听器、停止计时器等。这样做的目的是将对象置于不运行任何代码的状态

    movieclips和其他显示对象的一种简单方法(通常已经足够好了)是监听添加到\u STAGE和从\u STAGE事件中删除的\u。这里的想法是,对象在添加到STAGE时“激活”,在您的情况下,当您到达游戏类的第2帧时;它“停用”当它被移除时,也就是说,当您返回到第1帧时

    大致如下:

    public class Game extends MovieClip {
    
        private var _timer:Timer;
    
        public function Game() {
            addEventListener(Event.ADDED_TO_STAGE,init);
            addEventListener(Event.REMOVED_FROM_STAGE,destroy);
        }
    
        private function init():void {
            //  your init code goes here
            //  just an example:
            _timer = new Timer(33);
            _timer.addEventListener(TimerEvent.TIMER,mainLoop);
            _timer.start();
            trace("init");
        }
    
        private function destroy():void {
            _timer.stop();
            _timer.removeEventListener(TimerEvent.TIMER,mainLoop);
            trace("destroy");
        }
    
        private function mainLoop(e:TimerEvent):void {
            //  code for main loop here...
            trace("mainLoop");
        }
    }
    
    检查跟踪,看看它是否工作正常。你应该看到“init”跟踪出来,t