我正在使用一些TImage控件並控制它們的位置和角度爲我的Android手機制作Firemonkey中的2D遊戲。就那麼簡單。我試圖用我正常的循環方式,它在Windows中運行良好/無瑕,但在Android上失敗。Android版Firemonkey中的遊戲循環
方法1:「最終少」循環(壞)
我的主要問題是,我想通過使用「最終少循環」,以避免不必要的/意外的行爲,像這樣的,我有調用Application.ProcessMessages()
:
while (Game.IsRunning()) do
begin
{ Update game objects and stuff }
World.Update();
{ Process window messages, or the window will not respond anymore obviously }
Application.ProcessMessages(); { And thats what i want to avoid }
end;
的問題是,作爲即時通訊卡在循環,也要求來處理消息的程序,我可以碰到很多問題,而且我不認爲這是一個很好的辦法。
方法2:TTimer(甚至不想想;-))
由於TTimer在許多方面是可怕的,並不意味着用於這樣的事情,該方法,即我只是把一個TTimer最小間隔下降。此外,我從來沒有嘗試過其他計時器比,但如果有一個真正的遊戲,我會盡量當然:)
方法#3的是:的OnIdle - 我通常如何做到這一點在Windows
在Windows我可以使用Application.OnIdle事件。
procedure GameLoop(Sender: TObject; var Done: Boolean);
begin
{ Update game objects and stuff }
World.Update();
{ Set done to false }
Done := False;
end;
...
Application.OnIdle := GameLoop;
每次應用程序在Windows消息上徘徊時都會調用它。與#1相比,性能似乎相同或更差,整體架構更加可靠,這就是我通常使用這種方法的原因。然而,在Android上,它與TForm.MouseMove結合起來似乎被稱爲不同的。 OnIdle在Windows OnIdle上一直保持正常工作,在Android上,它會在觸摸輸入中調用TForm.MouseMove時延遲/停止(RAD Studio自動將它編譯爲觸摸事件)
但是我可以在MouseMove中自己觸發OnIdle通過調用Application.DoIdle
和「協助」「循環」,我認爲它錯過了被稱爲beimg的事件,但這種方法也非常糟糕,並且在使用觸摸輸入時會帶來不必要的行爲和更糟的性能。
這讓我回到方法#1,它似乎現在在Android上效果最好。有沒有其他的方式來創建一個可靠的方法(像OnIdle這樣一個持續而快速的被稱爲事件)創建這樣一個循環或以任何方式來避免方法#3與MouseMove事件結合所面臨的問題?看起來Android手機沒有足夠強大的功能,足以在格式事件和世界更新旁邊擁有足夠的「空閒時間」
此外,我可以考慮使用線程作爲世界邏輯,並且在它旁邊使用方法# 1在我的主窗體/線程上更新渲染?通過無限循環(使用Application.ProcessMessages())更新表單控件並從另一個處理世界上的線程,對象等獲取所顯示的數據是否安全?
您可以使用匿名線程(與之同步)來實現這一 – nolaspeaker
如果你想避免遊戲循環滯後FireMonkey UI引起那麼你最好的選擇是將所有的遊戲邏輯到輔助線程。但即便如此,如果目標設備只有一個處理核心,這可能會完全解決您的問題。您看到FireMonkey在處理UI消息時非常糟糕/緩慢。作爲一項測試,只需創建一個新的FireMonkey應用程序,並在窗體上放置大約100個面板。然後對其進行編譯並觀察鼠標在您的表單上的移動速度如何會導致CPU使用率顯着上升。 ... – SilverWarior
...這樣的測試是能夠最大限度地利用我的7歲筆記本電腦的CPU使用率,它不僅僅是一些弱電筆記本,因爲我可以在媒體設置上播放Far Cry 3而不會有任何問題。現在我可以想象使用這種情況下FireMonkey在手機上會導致哪種CPU使用率。這就是爲什麼我不考慮使用FireMonkey進行任何遊戲開發。 – SilverWarior