2009-11-22 100 views
3

我有一個帶有TTimer(timAnimateDataChange)的TFrame(fraDisplay)。計時器用於控制小動畫。在含有所述幀的形式我想有做了這樣的方法:我該如何等待TTimer完成?

procedure TForm.DoStuff; 
begin 
    DoSomeLogicStuff; 
    fraDisplay.AnimateResult; 
    WaitForAnimationToFinish; 
    DoSomeOtherLogicStuff; 
    fraDisplay.AnimateEndResult; 
    WaitForAnimationToFinish; 
    fraDisplay.Finalize; 
end; 

的動畫是基本上重繪一個TImage32的,由計時器計時。計時器在完成時將自動禁用它,並且該框架具有一個名爲AnimationRunning的布爾屬性,當動畫完成時它將被設置爲false。

沒有任何線程或類似的東西來使事情複雜化或有所幫助。

問題是,我該如何實現WaitForAnimationToFinish方法?

(順便說一句,這不是一個很好的解決方案:

procedure TForm.WaitForAnimationToFinish; 
begin 
    repeat 
    Application.ProcessMessages; 
    until not fraDisplay.AnimationRunning; 
end; 

,因爲儘管該方法可以運行:-( 計時器不會閃光)

回答

2

Smasher's suggestion可以使用Delphi 2009的匿名方法實現。

procedure TForm.DoStuff; 
begin 
    DoSomeLogicStuff; 
    fraDisplay.AnimateResult.OnFinished := 
    procedure (Sender: TObject) 
    begin 
     DoSomeOtherLogicStuff; 
     fraDisplay.AnimateEndResult.OnFinished := 
     procedure (Sender: TObject) 
     begin 
      fraDisplay.Finalize; 
     end; 
     fraDisplay.AnimateEndResult; 
    end; 
    fraDisplay.AnimateResult; 
end; 

BTW:實際上,WaitForAnimationToFinish會讓OnTimer觸發,因爲它使用調用ProcessMessages時調度的窗口消息。但無論如何這是一個壞主意,因爲它使用大量的CPU而不需要它。

+0

聽起來像一個很好的建議。不幸的是,我仍然在2007年:-(無論如何,還有幾個月的時間) – 2009-11-22 19:19:04

+0

這也適用於沒有匿名方法,只需要多一點代碼:) – 2009-11-22 19:21:20

1

當計時器自行禁用和設置AnimationRunning變量爲False,您可以直接調用下一步應該執行的方法。

+0

我不知道下一個應該調用哪個方法。有幾種方法需要暫停並等待動畫完成。 – 2009-11-22 19:11:17

0

那麼你的計時器正在做什麼是很長的,大約幾秒?無論如何,這種長時間運行的活動不應該在主GUI循環中執行。也不應該等待這樣的:

當你等待動畫完成(如果可以的話),你的應用程序的其餘部分將表現得像死程序,即它不會以任何方式響應GUI,包括調整大小,重新繪製,使用X等關閉。

解決方法是將您的DoStuff方法分解爲兩個;一個啓動定時器活動,另一個在定時器結束時執行。爲了完成後者,該計時器應該在說再見之前調用你的第二種方法。

拉爾斯做了一個很棒的工作,考慮這本書去與他的電影:)

+0

不是非常冗長。一秒左右。這實際上是壟斷的一個小實施。動畫就像動畫模具卷,移動令牌等。沒有花哨的圖形,只有文字和畫布上的彩色矩形,但是一定數量的動畫使遊戲感覺更好。 我有一個名爲TGame的對象,它有一個名爲FDisplay的屬性,這是我提到的框架。該框架具有諸如AnimateDieRoll和MoveToken的方法。 – 2009-11-22 19:40:13

0

使AnimateResults採取參數的方法被調用時,它完成。

1

斯洛文尼亞的一位斯德哥爾摩的程序員寫了你正在尋找的代碼 - Active Sleep