2016-08-16 55 views
7

我正在构建一个Adobe Air AS3 IOS和Android应用程序,其中我在舞台中央有一个影片剪辑。当你开始触摸这个影片剪辑时,你可以在舞台上移动它。
这是如何我这样做:
TouchEvent.TOUCH_BEGIN,onTouchBegin几次重新载入后冻结

  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

除非你正在做的事情我不明白,我认为你应该做事情不同。使用可见来显示和隐藏剪辑,因此您不必添加和删除剪辑和侦听器 - 如果visible = false没有触摸事件。舞台上应该有一套主要的触摸事件来运行一切。为剪辑分配开始和结束触摸事件,以便简单了解它们何时被触摸。所以舞台touch_move监听器只是检查MC_M1是否被触摸。通过这种方式,应用中的所有内容都共享一组触摸事件,而不必添加和删除剪辑和侦听器。合理? – moot

+0

我试过了..我仍然得到相同的结果..你认为发生了什么 –

+0

如果你改变触摸鼠标事件和在台式计算机上测试它是否被复制? – www0z0k

回答

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

}