TouchEvent.TOUCH_BEGIN,onTouchBegin几次重新载入后冻结 [英] TouchEvent.TOUCH_BEGIN, onTouchBegin Freezes after several Reloads

查看:155
本文介绍了TouchEvent.TOUCH_BEGIN,onTouchBegin几次重新载入后冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个Adobe Air AS3 IOS和Android应用程序,其中我有一个在舞台中央的影片剪辑。当你开始触摸这个影片剪辑时,你可以在舞台上移动它。


这就是我所做的:

$ b $ $ $ $ $ $ $ $ $ $ $> Multitouch.inputMode = MultitouchInputMode 。接触点;
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);

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

函数onTouchMove(event:TouchEvent)
{
if(event.touchPointID!= touchMoveID)
{
return;
}
// trace(Moving)
MC_M1.x = event.stageX;
MC_M1.y = event.stageY;

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

$ / code>

当玩家真的失去了游戏时,我实际上在做的是:
$ b

  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的类中。用户松了一口气,他会得到一个重播按钮,当他点击它时,他会回到同一个班级,并使用下面的代码重新加载所有内容:


 函数gotoIntro(event:MouseEvent):void 
{

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






$ b因此,一切都会重新加载,游戏重新开始。我的问题是,当我倾向于重播游戏超过2-3次时,我正面临一个非常奇怪的行为。 MC_M1只是停止听任何触摸事件,但不停地听ENTER_FRAME事件,其中我不断触摸MC_M1,但似乎没有回应。我甚至从我的iPhone远程调试它,第一对重播,我可以看到跟踪(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)

解决方案

我知道这个问题很老,但也许有人仍然在想这里发生了什么(像我一样)
有很多

 函数gotoIntro(event:MouseEvent):void { 
// ...
var reload:introClassToUse = new introClassToUse();
}




  • 如果简单地创建一个实例,那么通常会产生不必要的行为,而且甚至不需要将其分配给变量在这种情况下。

  • 您提到此代码位于 introClassToUse 类中。这基本上意味着你正在创建一个旧的游戏实例,这似乎是完全错误的。



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

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


  • 整个类的结构是怎么样的 - 例如你不能在你的类的范围内放置 MC_M1.addEventListener(Event.ENTER_FRAME,ifHitAct); 显然你有这个功能,我们不知道什么时候和从哪里调用。

  • 您的变量在哪里以及如何声明和分配。很难判断你的 MC_M1 是一个实例还是一个类的属性,是internal / public / private / ...


  • 您是否将图书馆符号链接到您的类,或从 stage 获取它。

  • >

    有很多事情可以给你这样的结果。基于你写的我已经复制了类似于你所描述的行为,但使用鼠标事件和一个虚拟的松散条件。每当你把鼠标放在圣人的右边缘以外时,这个游戏结束,显示重启按钮,如果你点击它(基本上它主要是你的代码),重新开始。它工作正常约10秒,而不是突然你不能移动MC了。框架事件仍在追踪,但触摸/鼠标不是。



    这怎么可能?我怀疑你只能删除某个地方的听众,并且看不见的mc卡在新的。这可能很容易被忽视,特别是如果你使用静态属性。我们甚至不知道你的电影剪辑来自哪里,所以我们只能猜测你的代码正在发生什么,但我试图简单地举例说明这是我做的。问题可能在于一些完全不同的地方,但你可以猜测所有情况。



    项目的文档类 - GameIntro.as

      package 
    {
    import flash.display.Sprite;

    public class GameIntro extends Sprite
    {
    // Document class。这需要用严格模式编译。
    public function GameIntro(){

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

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





    $ b $ p $强> IntroClassToUse.as

     
    {
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    $ b / **
    *您需要在.fla中使用两个mcs -
    * mcFromLibrarySymbol(dragable)和repButton(reapatButton)
    * /
    public class IntroClassToUse extends MovieClip
    {
    var t = 0; //计时器滴答
    var fc:uint = 0; // frame 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();


    内部函数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);


    内部函数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;


    内部函数onReplay(e:MouseEvent):void {
    trace(onReplay);
    repButton.removeEventListener(MouseEvent.CLICK,onReplay);
    repButton.alpha = 0;
    stop();
    新IntroClassToUse();


    内部函数onMDown(e:MouseEvent):void {
    trace(mouseDow);
    GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_MOVE,onMMove);
    GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_UP,onMUp);


    内部函数onMMove(e:MouseEvent):void {
    mc.x = e.stageX;
    mc.y = e.stageY;
    }

    //如果你释放了mc,并且在最后阶段就释放了它,
    内部函数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();


    内部函数onFrame(e:Event):void {
    trace(frames,fc ++);


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

    }


    I am building an Adobe Air AS3 IOS and Android App, in which i have a movie clip in the center of the stage. When you start touching this movie clip, you can move it all around the stage.
    This is how i'm doing so :

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

    When the player actually looses the game, what i am actually doing is the following :

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

    This is all happening in a class called : introClassToUse.
    So when the users looses, he will get a replay button, and when he clicks it, he will go back to the same class and reload everything, using the following code :

    function gotoIntro(event:MouseEvent):void
            {
    
                replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
                replayButToUse.alpha = 0;
                replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
                stop();
                var reload:introClassToUse = new introClassToUse();
    
            }
    

    And so everything loads back up and the game restarts. My problem is, i'm facing a very weird behavior when i tend to replay the game more than 2-3 times. The MC_M1 just stops listening to any touch event, but keeps on listening to ENTER_FRAME events, in which i keep touching the MC_M1 but it seems to not respond to it. I even debugged it remotely from my iPhone, for the first couple of replays, i can see the trace("TouchBegin"); with it's outcome, it was showing me TouchBegin, but after a few replays, the touch events just froze. What am i missing?

    Any help is really appreciated, i'm new in AS3, i need to learn so i could manage more

    Edit 1 :

    I have no code on any frame, i just have lots of AS Classes. The fla file is linked to an AS Class called gameIntro. In this class, i have linked the following :
    - STAGE is an object of type Stage.
    - gameIntro.STAGE = stage
    Later on, when the user clicks a play button, i call the class introClassToUse. This class has all the game functionalities. All the code present above is in introClassToUse. When the user looses and clicks the replay button, he will go to "goToIntro" function, im which i recall the introClassToUse.
    It's all working fine, with several other timers implemented and all, the only problem is that after several replays, the MC_M1 just freezes over I am removing the MC_M1 each time the user looses and re-add them when i call back the introClassToUse, because i tried to use the .visible property, it didn't work at all ( this is why i am using the gameIntro.STAGE.stage.removeChild(MC_M1)

    解决方案

    I know the question is old but maybe someone is still wondering what is going on here (like me). There are lot of problems in you code but I thing the root of your problem starts here:

    function gotoIntro(event:MouseEvent):void{
        //...
        var reload:introClassToUse = new introClassToUse();
    }
    

    • It is usually unwanted behavior if simply creating an instance does more than nothing to your program and you don't even need to assign it to variable in this case.
    • You mentioned this code is located in your introClassToUse class. This basically means that you are creating new instance of your game inside old one and this seem to be completely awry.

    You should consider using only instance properties in your class definition and create new introClassToUse() in external classes;

    You didn't include many important details about your code like

    • How the whole class structures look like - for example you can't place line like MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);in the scope of your class so obviously you have this in some function and we don't know when and from where it is called.

    • Where and how your variables are declared, and assigned. It's hard to tell if your MC_M1 is property of an instance or a class, is it internal/public/private/...

    • Do you link library symbols to your classes or acquire it from stage.

    There could be many things that could give you such result. Based on what you wrote I've reproduced behavior similar to what you've describe but using mouse event and a dummy loose condition. This ends the game each time you drop the mc partially outside right edge of the sage, show restart button and starts again if you click it (basically it's mostly your code). It works fine for about 10s and than suddely you can't move the mc anymore. The frame event is still tracing out but touch/mouse is not.

    How can it be? I suspect that you could remove only listeners somewhere and have invisible mc stuck on the new one. And this could be easy overlooked, especially if you using static properties. Again we don't even know where is your movie clip coming from so we can only guess what is happening whit your code but I've tried to take the example simple this is how I did it. The problem may lay in some completely different place but you can guess for all scenarios.

    Document class of the project - 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;
            }
        }
    
    }
    

    这篇关于TouchEvent.TOUCH_BEGIN,onTouchBegin几次重新载入后冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆