2011-07-06 164 views
0

我用行動腳本3汽車Flash遊戲的工作,我想如果我按「向上」的道路線走得更快鍵盤上,該行是由定時器產生它的延遲是由按下的鍵修改,問題是,如果我讓按鍵按壓的情況下的計時器仍然刷新,並沒有表現出任何分道線,直到我停止按壓。問題在動作腳本計時器延遲3

這裏的按鍵代碼:

if (upPressed) 
{ 
    speed = speed*1.02; 
    timerB.delay = timerB.delay/1.007; 
    timerA.delay = timerA.delay/1.005; 
} 

任何提示嗎?提前致謝。

+0

請張貼更多的代碼,這是不夠的代碼推測什麼的。 – 2011-07-07 01:17:37

回答

0

問題可能是你更改延遲屬性Timer類每次重啓的結果。

從Adobe的文檔:

如果設置在定時器運行延遲時間,計時器會重新啓動相同的repeatCount迭代。

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Timer.html#delay

這基本上意味着重新啓動定時器0,但是記住它已經重複了多少遍。我意識到我的答案越來越長,所以我在底部提供了一些參考。

解決方案:使用flash.utils.getTimer()而不是Timer對象。

http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#getTimer()

的getTimer()函數返回表示自啓動.swf文件的已經過去的毫秒數的整數。如果您每幀檢查一次該數字,您可以看到自上一幀以來經過了多長時間。只需添加每幀通過的毫秒數,直到該數字達到閾值,然後調用畫線功能並重置計數器。

當檢查,看看是否按下鍵減少你的新「myDelay」變量而不是一個Timer.delay屬性的。

var ms:int; 
    var timeStamp:int = flash.utils.getTimer(); 
    var myDelay:Number;  

    onEnterFrame() { 

      // Track how much time has passed since the last frame 
      ms += flash.utils.getTimer() - timeStamp; 

      if (ms > myDelay) 
      { 
       // DRAW THE ROAD LINES 
       drawLines(); 
       // RESET THE COUNTER 
       ms = 0; 
      } 

      //other stuff 

      // Record the timestamp of this frame so you can see the difference next frame 
      timeStamp = flash.utils.getTimer();     
    } 

說明TIMER復位的:

注:我假設你是每秒檢查按鍵。如果要更改計時器的每一幀(例如24次),延遲性,你的計時器發生了超過很少一24次,它就會發出一個事件來調用它的處理器的機會之前,將被重置函數來創建線條。

如果你看看下面的例子,啓動和停止事件是防止它被重置的唯一方法,但即使如此,只有當延遲小於時間時纔會調用定時器事件處理函數在延遲的變化之間。由於平均swf是24fps,這意味着在下一幀再次改變值之前,延遲需要小於41.6毫秒。

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.events.KeyboardEvent; 
    import flash.events.TimerEvent; 
    import flash.utils.Timer; 

    /** 
    * ... 
    * @author 
    */ 
    public class Main extends Sprite 
    { 

     var timer:Timer; 
     var keyPressed:Boolean = false; 

     public function Main():void 
     { 
      if (stage) init(); 
      else addEventListener(Event.ADDED_TO_STAGE, init); 
     } 

     private function init(e:Event = null):void 
     { 
      removeEventListener(Event.ADDED_TO_STAGE, init); 
      timer = new Timer(50); 
      timer.addEventListener(TimerEvent.TIMER, function():void { trace (timer.delay); }); 
      timer.start(); 

      stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown); 
      stage.addEventListener(KeyboardEvent.KEY_UP, keyUp); 

      addEventListener(Event.ENTER_FRAME, onEnterFrame); 

     } 

     function onEnterFrame (e:Event) 
     {     
      if (keyPressed) 
      { 
       timer.stop(); 
       timer.delay -= 1; 
       timer.start(); 
      } 
     } 

     function keyDown (e:KeyboardEvent):void { keyPressed = true; } 


     function keyUp (e:KeyboardEvent):void { keyPressed = false; } 
    } 

} 
+0

+1可靠答案。 – Marty

0

雖然約什的答案似乎準確地描述你的錯誤的根源,應該指出的是,爲您解決問題的正確方法是停止使用定時器完全,並在enterFrame事件處理程序運行所有你的邏輯。

要知道爲什麼這是真的,請回想一下,Flash播放器以給定的幀率運行,並且每幀僅重新繪製一次屏幕。假設您以與幀速率相同的速度運行定時器。這意味着您將在每次屏幕重繪之間獲得一個Timer事件。現在假設你加速了10%的定時器。發生的情況是,定時器事件和幀事件不同步,因此每幀可以獲得一個定時器9幀,而在第十幀定時器將會觸發兩次。你的路線不會移動10%,它以9幀的速度移動,第10個移動速度加倍,這與你想要的完全不同。

解決方法是,不是試圖更頻繁地移動路線,而是希望每幀移動一次,但移動它們的距離更大或更小。正確的方法是在一個EnterFrame處理程序中。

+0

我似乎很困惑...你能否詳細介紹一下EnterFrame的工作原理?也許一個如何添加一條線的例子,然後以兩種不同的速度移動會有幫助......謝謝! – Omega

+0

Flash按照(大部分)固定的時間表重新繪製屏幕,​​並且EnterFrame是每幀調度一次的事件(屏幕重繪)。重要的一點是,改變定時器延遲會影響定時器事件處理程序的調用頻率,但它對屏幕重新繪製的頻率沒有影響。我今天晚些時候會添加示例代碼。現在,下面是關於定時器和幀事件如何工作的所有細節:http://www.craftymind.com/2008/04/18/updated-elastic-racetrack-for-flash-9-and-avm2/ – fenomas

0

EnterFrame是每次視圖刷新(大致)時由Flash運行時觸發的事件。您可以將事件偵聽器添加到您的根顯示對象,並觸發「update()」方法。這將取代你正在做的計時器。

您可以閱讀爲什麼enterFrame事件是在這裏你的遊戲方面比定時器更有用一個詳細的解釋:

http://www.bit-101.com/blog/?p=910