我正在制作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