TouchEvent.TOUCH_BEGIN,onTouchBegin在多次重新加载后冻结

时间:2016-08-16 17:19:52

标签: actionscript-3 flash air

我正在构建一个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);
        }

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

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);

这一切都发生在一个名为: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();

        }

所以一切都重新开始,游戏重新启动。我的问题是,当我倾向于重播游戏超过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)

1 个答案:

答案 0 :(得分:1)

我知道这个问题很老但也许有人仍在想这里发生了什么(像我一样)。 您的代码中存在很多问题,但问题的根源在于:

function gotoIntro(event:MouseEvent):void{
    //...
    var reload:introClassToUse = new introClassToUse();
}
  • 如果只是创建一个实例对您的程序执行的操作不是什么,而且在这种情况下您甚至不需要将其分配给变量,那么这通常是不受欢迎的行为。
  • 您提到此代码位于您的introClassToUse课程中。这基本上意味着你在旧的游戏中创建了一个新的游戏实例,这似乎完全没错。

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

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

  • 整个班级结构的样子 - 例如,你不能将MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);这样的行放在你班级的范围内,所以很明显你在某些功能中有这个,我们不会这样做。知道何时以及何时被呼叫。

  • 声明和分配变量的位置和方式。很难判断您的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);
        }

    }
}

<强> 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;
        }
    }

}