TouchEvent.TOUCH_BEGIN,onTouchBegin在几次重载之后冻结

Eli*_*hme 7 air flash actionscript-3

我正在构建一个Adobe Air AS3 IOS和Android App,其中我在舞台中央有一个影片剪辑.当您开始触摸此影片剪辑时,您可以在舞台上移动它.
这就是我这样做的方式:

            Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
            MC_M1.alpha = 1;
            MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);
            MC_M1.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
            MC_M1.x = 0.516 * gameIntro.stageWidthToUse;
            MC_M1.y = 0.75 * gameIntro.stageHeightToUse;
            MC_M1.height = 0.2 * gameIntro.stageHeightToUse;
            MC_M1.width = MC_M1.height / 1.4;
            gameIntro.STAGE.stage.addChildAt(MC_M1,1);

function onTouchBegin(event:TouchEvent)
        {
            trace("TouchBegin");
            if (touchMoveID != 0)
            {
                trace("It Did Not");
                return;
            }
            touchMoveID = event.touchPointID;

            gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
            gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
        }
        function onTouchMove(event:TouchEvent)
        {
            if (event.touchPointID != touchMoveID)
            {
                return;
            }
            //trace("Moving")
            MC_M1.x = event.stageX;
            MC_M1.y = event.stageY;
        }
        function onTouchEnd(event:TouchEvent)
        {
            if (event.touchPointID != touchMoveID)
            {
                return;
            }
            //trace("Ending");
            touchMoveID = 0;
            gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
            gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
        }
Run Code Online (Sandbox Code Playgroud)

当玩家实际上失去游戏时,我实际做的是以下内容:

MC_M1.removeEventListener(Event.ENTER_FRAME , ifHitAct);
MC_M1.removeEventListener(TouchEvent.TOUCH_BEGIN , onTouchBegin);
gameIntro.STAGE.stage.removeChild(MC_M1);
MC_M1.alpha = 0;
isDead = 1;
replayButToUse.x = 0.127 * gameIntro.stageWidthToUse;
replayButToUse.y = 0.91 * gameIntro.stageHeightToUse;
replayButToUse.addEventListener(MouseEvent.CLICK, gotoIntro);
Run Code Online (Sandbox Code Playgroud)

这一切都发生在一个名为:introClassToUse的类中.
因此,当用户失去时,他将获得一个重播按钮,当他点击它时,他将返回同一个类并重新加载所有内容,使用以下代码:

function gotoIntro(event:MouseEvent):void
        {

            replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
            replayButToUse.alpha = 0;
            replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
            stop();
            var reload:introClassToUse = new introClassToUse();

        }
Run Code Online (Sandbox Code Playgroud)

所以一切都加载回来,游戏重新开始.我的问题是,当我倾向于重播游戏超过2-3次时,我面临一种非常奇怪的行为.MC_M1只是停止收听任何触摸事件,但继续收听ENTER_FRAME事件,我继续触摸MC_M1,但它似乎没有响应它.我甚至从我的iPhone远程调试它,对于前几次重放,我可以看到trace("TouchBegin");它的结果,它向我展示了TouchBegin,但经过几次重放之后,触摸事件就冻结了.我错过了什么?

任何帮助真的很感激,我是AS3的新手,我需要学习,所以我可以管理更多

编辑1:

我没有任何框架的代码,我只有很多AS类.fla文件链接到名为gameIntro的AS类.在这个类中,我链接了以下内容:
- STAGE是Stage类型的对象.
- gameIntro.STAGE = stage
稍后,当用户点击播放按钮时,我会调用类introClassToUse.这个类具有所有游戏功能.上面的所有代码都在introClassToUse中.当用户松开并点击重播按钮时,他将转到"goToIntro"功能,即我记得introClassToUse.
这一切都运行良好,其他几个计时器实现了,唯一的问题是,经过几次重放后,MC_M1只是冻结我每次用户松开时都会移除MC_M1并在我回调introClassToUse时重新添加它们,因为我试图使用.visible属性,它根本不起作用(这就是我使用gameIntro.STAGE.stage.removeChild(MC_M1)的原因

Paw*_*sos 1

我知道这个问题已经很老了,但也许有人仍然想知道这里发生了什么(就像我一样)。您的代码中有很多问题,但我认为问题的根源从这里开始:

function gotoIntro(event:MouseEvent):void{
    //...
    var reload:introClassToUse = new introClassToUse();
}
Run Code Online (Sandbox Code Playgroud)
  • 如果简单地创建一个实例对您的程序没有任何作用,并且在这种情况下您甚至不需要将其分配给变量,那么这通常是不需要的行为。
  • 您提到此代码位于您的introClassToUse班级中。这基本上意味着您正在旧游戏中创建游戏的新实例,这似乎完全错误。

您应该考虑在类定义中仅使用实例属性并new introClassToUse() 在外部类中创建;

您没有包含有关代码的许多重要细节,例如

  • 整个类的结构是什么样的 - 例如,你不能像MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);在类的范围内放置 line 一样,所以显然你在某个函数中有这个,我们不知道它何时何地被调用。

  • 变量在何处以及如何声明和分配。很难判断您的MC_M1属性是实例还是类的属性,是内部/公共/私有/...

  • 您是否将库符号链接到您的类或从stage.

可能有很多事情可以给你这样的结果。根据您所写的内容,我重现了与您所描述的类似的行为,但使用了鼠标事件和虚拟松散条件。每次您将 mc 部分放在圣人右边缘之外时,都会结束游戏,显示重新启动按钮,如果单击它则重新开始(基本上主要是您的代码)。它工作正常大约 10 秒,然后突然你不能再移动 mc 了。框架事件仍在追踪,但触摸/鼠标则没有。

怎么会这样?我怀疑你可以只删除某处的侦听器,然后将隐形的 mc 卡在新侦听器上。这很容易被忽视,特别是如果您使用静态属性。同样,我们甚至不知道您的影片剪辑来自哪里,因此我们只能猜测您的代码发生了什么,但我尝试简单地举个例子,这就是我的做法。问题可能出在某个完全不同的地方,但您可以猜测所有情况。

项目的文档类 - GameIntro.as

package 
{
    import flash.display.Sprite;

    public class GameIntro extends Sprite 
    {
        //Document class. this need to be compiled with strict mode off.
        public function GameIntro() {

            GameIntro.STAGE = stage;
            GameIntro.stageWidthToUse = stage.stageWidth;
            GameIntro.stageHeightToUse = stage.stageHeight;

            var intro:IntroClassToUse = new IntroClassToUse();
            stage.addChild(intro);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

IntroClassToUse.as

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

    /**
     * You need to have library symbol linked to this class in .fla with two mcs - 
     * mcFromLibrarySymbol (dragable) and repButton (reapatButton)
     */
    public class IntroClassToUse  extends MovieClip
    {
        var t = 0; //timer ticks
        var fc:uint = 0; //frames counter
        var isDead = 0;
        var mc;
        static var repButton;
        var logicContex:Timer = new Timer(30);

        public function IntroClassToUse() {
            trace("toUse", GameIntro.stageWidthToUse);
            mc = mcFromLibrarySymbol;
            if(!repButton) repButton = repButtonX;
            logicContex.addEventListener(TimerEvent.TIMER, logicInterval);
            logicContex.start();
            init();
        }

        internal function init() {
            trace("init");
            mc.alpha = 1;
            mc.addEventListener(Event.ENTER_FRAME, onFrame);
            mc.addEventListener(MouseEvent.MOUSE_DOWN, onMDown);
            mc.x = 0.516 * GameIntro.stageWidthToUse;
            mc.y = 0.75 * GameIntro.stageHeightToUse;
            mc.height = 0.2 * GameIntro.stageHeightToUse;
            mc.width = mc.height / 1.4;
            GameIntro.STAGE.stage.addChildAt(mc, 1);
        }

        internal function onLoose() {
            trace("onLoose");
            mc.removeEventListener(Event.ENTER_FRAME , onFrame);
            mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
            GameIntro.STAGE.stage.removeChild(mc);
            mc.alpha = 0;
            isDead = 1;
            repButton.x = 0.127 * GameIntro.stageWidthToUse;
            repButton.y = 0.91 * GameIntro.stageHeightToUse;
            repButton.addEventListener(MouseEvent.CLICK, onReplay);
            repButton.alpha = 1;
        }

        internal function onReplay(e:MouseEvent):void {
            trace("onReplay");
            repButton.removeEventListener(MouseEvent.CLICK, onReplay);
            repButton.alpha = 0;
            stop();
            new IntroClassToUse();
        }

        internal function onMDown(e:MouseEvent):void {
            trace("mouseDow");
            GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMMove);
            GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_UP, onMUp);
        }       

        internal function onMMove(e:MouseEvent):void {
            mc.x = e.stageX;
            mc.y = e.stageY;    
        }

        //you loose the game if you release you mc with part of it over rigth stage edge.
        internal function onMUp(e:MouseEvent):void {
            trace("mouseUp");
            GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMMove);
            GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_UP, onMUp);
            trace("Stage:", GameIntro.STAGE.numChildren);
            if (mc.x + mc.width > GameIntro.STAGE.stageWidth) onLoose();
        }

        internal function onFrame(e:Event):void {
            trace("frames", fc++);
        }

        internal function logicInterval(e:TimerEvent):void {
            if (t++ < 300 || !isDead) return;
            init();
            mc.alpha = 0;
            mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
            isDead = 0;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)