2016-08-16 53 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; 
     } 
    } 

}