我正在製作Android遊戲。我有點試圖保持遊戲的祕密,所以我不能透露太多,所以請耐心等待。基本上它是實時運行的(所以我將實現一個線程來更新對象的座標),它的風格有點像Duck Hunt;你必須擊中在屏幕上移動的物體。但是,遊戲一直在稍微滯後(運行在三星Galaxy S上,這是高端設備之一),所以我相信我需要使用更好的數據結構。Android遊戲開發:使用哪種數據結構?
基本上我將這些對象存儲在雙向鏈表中而不是數組中,因爲我希望屏幕上的對象的最大數量是動態的。換句話說,我有一個頭部和尾部對象的引用,並且所有的遊戲對象都像典型的鏈表一樣連接。這提供了以下問題:
- 搜索如果一個對象與交叉的給定座標(通過觸摸屏幕)需要O(n)的時間(最壞的情況下),因爲我有從頭部到遍歷到尾,並檢查每個對象的hitbox。
- 兩個對象之間的碰撞檢查需要O(n^2)個時間(再次,最壞的情況),因爲對於每個對象我都要檢查它的hitbox是否與鏈表中所有其他對象相交。
我選擇鏈表的另一個原因是我基本上有兩個鏈表:一個用於活動對象(即屏幕上的對象)和一個用於非活動對象。假設遊戲畫面上最多有8個對象,如果活動鏈表有5個對象,非活動列表將有3個對象。使用兩個鏈表可以使對象變爲非活動狀態時,我可以簡單地將它附加到不活動鏈表上,而不是取消引用它,並等待垃圾回收器回收內存。另外,如果我需要一個新對象,我可以簡單地從非活動鏈接列表中取出一個對象,並將其用於活動鏈接列表中,而不必分配更多內存來創建新對象。我已考慮使用多維數組。這種方法涉及將屏幕劃分爲對象可以躺下的「單元格」。例如,在一個480x800的屏幕上,如果對象的高度和寬度都是80像素,我會將屏幕分成6x10個網格,或者在Java代碼的上下文中,我會製作GameObject [6] [10]。我可以簡單地將對象的座標(在屏幕上)除以80以得到它的索引(在網格上),這也可以提供O(1)插入。這也可以通過座標O(1)進行搜索,因爲我可以用觸摸座標執行相同的操作來檢查相應的索引。
碰撞檢查可能仍然需要O(n^2)時間,因爲我仍然需要經過網格中的每個單元格(儘管這樣我只需要比較最多與我相鄰的8個單元格目前正在檢查)。
但是,網格的想法提出了自己的問題:
- 如果屏幕比其他480x800的分辨率?另外,如果網格不能均勻分成6x10?這可能會使程序更容易出錯。
- 正在使用內存方面昂貴的遊戲對象的網格?考慮到我正在爲移動設備開發,我需要考慮這一點。
所以最終的問題是:我應該使用鏈表,多維數組還是其他我沒有考慮過的東西?
下面是我如何實現碰撞的想法:
更好的碰撞檢測性能private void checkForAllCollisions() {
GameObject obj1 = mHead;
while (obj1 != null) {
GameObject obj2 = obj1.getNext();
while (obj2 != null) {
//getHitBox() returns a Rect object that encompasses the object
Rect.intersects(obj1.getHitBox(), obj2.getHitBox());
//Some collision logic
}
obj1 = obj1.getNext();
}
}
當談到內存時,我更擔心分配新的內存並讓垃圾回收回收內存,這會導致我的應用程序出現打嗝。另外,我對Java的List類不太熟悉,但在查看這些文檔後,它與常規數組有什麼不同? – Dan
當你看到它們時,擔心GC打嗝。 ['List'](http://download.oracle.com/javase/6/docs/api/java/util/List.html)是一個接口。 'LinkedList'和'ArrayList'是該接口的不同實現。已經有很多文檔(** [官方文檔](http://download.oracle.com/javase/tutorial/collections/implementations/list.html)**以及** [SO問題]( http://stackoverflow.com/search?q=%5Bjava%5D+linkedlist+vs+arraylist)**關於差異。 'ArrayList'通常被認爲是通用的'List'實現的選擇。 –
^我第二個這個。如果可以的話,堅持ArrayList通過LinkedList。 – Vinay