2010-03-13 104 views
5

情況:模擬環境中有幾個實體,它具有稱爲「滴答」的人造時間概念,它與實時無關。每個實體輪流移動,但有些實體比其他實體更快。這通過延遲表示,以蜱形式表示。因此,實體A可能有10的延遲,和B 25在這種情況下,輪候次序會去:支持最終幻想ATB風格隊列的數據結構? (延遲隊列)

A A B A A

我不知道用什麼樣的數據結構。起初我會自動想到「優先排隊」,但延誤與「當前時間」有關,這使事情變得複雜。此外,將會有更多延遲的實體,並且不能不肯定該計劃將運行數百萬次。當延遲本身保持相對較小並且不增加時,內部計數器越來越高,似乎很愚蠢。

那麼你會如何解決這個問題?

回答

4

您的實體存儲在一個堆和組通過他們自己的時間留給等待。移動旁邊的實體組將位於堆頂部。你只需要更新這些實體。當他們剩下的時間等於0時,將其從堆中移除。將下一組實體放在堆頂部,同時減少等待的時間,等待上一次移動之前剛過的時間。

例如:

你的堆具有3個節點(A,B和C)中,頂節點是A和兩個實體均具有5蜱剩餘。 childern分別有10個和12個滴答。

  • 在時間t = 5您移動在節點時段的甲
  • 刪除從堆
  • 乙移動到堆的頂部的所有實體10-5 = 5蜱剩餘然後
  • 重複。
+1

如果不是通過排序堆由「時間在此實體將未來採取行動」,「等待時間」你爲了它,那麼你不必遞減「等待時間」每個實體的。 – 2010-03-13 04:51:16

+0

當你計數時,如果超過Int或Int64的限制(如果你的戰鬥長時間運行),你可能不得不考慮滾動。 – vfilby 2010-03-13 05:02:16

+0

我的意思是直到下一個動作的時間,但是等待的時間少於打字。 – BeWarned 2010-03-13 05:07:29

0

選項#1:輪詢

我可能會建立一個控制器,可以發現所有的不同實體的延遲和保持蜱,其餘爲每個實體。控制器會循環通過滴答,並且在每次滴答時都會減少滴答 - 剩餘的所有遊戲實體。

一旦實體滴答 - 剩餘值達到零,您知道它輪到他們了,要麼由處理滴答的心跳方法控制,要麼由您調用的方法控制。

選項#2活動

這樣想的UI模式,接口不不斷查詢按鈕查看被點擊時它。相反,當按鈕通過事件點擊時,讓按鈕通知用戶界面。讓您的實體(或EntityBattleContext)在事件準備就緒時觸發事件。您必須以某種方式處理您的遊戲時間,因爲它不是基於真實世界的時間,您可能需要讓所有實體偵聽GameTick事件,並且當它們接收該事件時更新它們的intells TicksRemaining變量。

在遵循事件驅動路線之前,請確保輪詢路線不起作用。記住基本規則總是優化後,因爲更多的時候你不需要優化。

+0

似乎可行,但如果有大量實體可能有點慢? – ZoFreX 2010-03-13 04:17:03

+1

那麼,我想如果你有很多實體你不想使用輪詢系統。而是設置一個事件,每個實體在準備就緒時觸發。這樣你的控制器只需要接收器事件就可以這樣處理實體。 – vfilby 2010-03-13 04:25:44

+0

這兩種方法都非常有效,因爲您逐步完成每個打勾。通常在這種性質的模擬中,你可以跳過沒有發生任何事情而不是通過它們增加的時間上的巨大差距。 – ZoFreX 2010-03-13 14:03:36

0

如果我們假設您的實體正在觀察或觀察模擬時間,它們可以分別實現一個接口,使它們跟蹤ticks left並提供一種方法來獲取特定實體的剩餘滴答數。在每次打勾時,該實體將其ticks left減1。

然後,您可以保留這些實體的排序集隊列(因爲每個實體將在隊列中只有一次),根據get ticks left排序,以便第0個實體是下一個要移動的實體,而第N個實體是「最慢的」實體。

當實體的get ticks left方法爲0時,它將從排序後的集合中移除,ticks left定時器將重置,並將其重新插入排序後的集合中。

1

在你看來,我認爲「下一個是什麼?」的概念。比「直到下一次行動多久」更重要。在這種情況下,可以通過「下一步」或最低數量的報價來排序您的隊列。當然,插入按照適當的順序輸入,並且改變的條目(「加速」法術)從隊列中移除,改變,然後適當地重新輸入。

然後,你只是彈出下一個作業從隊列中。無論它有多少刻度,都必須是「經過時間」。在隊列中進行傳遞,將每個條目的剩餘字段按照剛剛發現的數量減少。

這有跟蹤的剩餘時間概念的優勢,但也不必觸發事件或執行任何其他代碼,通過當沒有要採取的行動去蜱。你可以負擔得起,因爲與實時無關。只有「下一步?」和「需要多長時間才能到達?」。

+0

你是對的,「接下來是什麼?」是重要的概念。只要事件按照正確的順序處理,什麼時間或什麼時間直到下一個動作完全不需要。 我不知道遞減隊列中的一切......可能有相當多的,我想它要快。不過,如果我沒有找到更好的方法,那可能就是我要做的。 – ZoFreX 2010-03-13 14:02:16

0

看看Java的DelayQueue是如何實現的。

+0

全球的時間概念,每個元素知道什麼時候到期,並公開對getDelay和的compareTo相對時間。這仍然會遇到溢出問題。 – ZoFreX 2010-03-13 14:00:32