Jawaban yang tepat tergantung sedikit pada permainan yang sebenarnya Anda rancang, dan memilih satu di antara yang lain benar-benar akan membutuhkan penerapan keduanya dan melakukan profil untuk mengetahui mana yang lebih efisien waktu atau ruang pada gim spesifik Anda.
Deteksi kisi tampaknya hanya berlaku untuk mendeteksi tabrakan antara objek bergerak dan latar belakang statis. Keuntungan terbesar untuk ini adalah bahwa latar belakang statis direpresentasikan sebagai susunan memori yang berdekatan, dan setiap pencarian tabrakan adalah O (1) dengan lokalitas yang baik jika Anda perlu melakukan banyak pembacaan (karena entitas mencakup lebih dari satu sel dalam grid). Kerugiannya, jika latar belakang statisnya besar, adalah bahwa kisi-kisi bisa agak boros ruang.
Jika sebaliknya Anda mewakili latar belakang statis sebagai quadtree, maka biaya pencarian individu naik, tetapi karena blok besar latar belakang memakan sedikit ruang, persyaratan memori turun, dan lebih banyak latar belakang dapat duduk di cache. bahkan jika dibutuhkan 10 kali lebih banyak membaca untuk melakukan pencarian dalam struktur seperti itu, jika semuanya ada dalam cache, itu akan tetap 10 kali lebih cepat daripada pencarian tunggal dengan cache miss.
Jika saya dihadapkan dengan pilihan? Saya akan pergi dengan implementasi grid, karena itu bodoh untuk dilakukan, lebih baik menghabiskan waktu saya pada masalah lain yang lebih menarik. Jika saya perhatikan bahwa permainan saya berjalan agak lambat, saya akan melakukan beberapa profil dan melihat apa yang bisa menggunakan bantuan. Jika sepertinya game menghabiskan banyak waktu melakukan deteksi tabrakan, saya akan mencoba implementasi lain, seperti quadtree (setelah menghabiskan semua perbaikan mudah terlebih dahulu), dan mencari tahu apakah itu membantu.
Sunting: Saya belum mendapatkan petunjuk bagaimana pendeteksian tabrakan kisi berhubungan dengan pendeteksian tabrakan beberapa entitas seluler, tetapi sebaliknya, saya akan menjawab bagaimana indeks spasial (Quadtree) meningkatkan kinerja pendeteksian melalui solusi berulang. Solusi naif (dan biasanya sangat baik-baik saja) terlihat seperti ini:
foreach actor in actorList:
foreach target in actorList:
if (actor != target) and actor.boundingbox intersects target.boundingbox:
actor.doCollision(target)
Ini jelas memiliki kinerja sekitar O (n ^ 2), dengan jumlah aktor yang saat ini hidup dalam permainan, termasuk peluru dan pesawat ruang angkasa dan alien. Itu juga dapat mencakup hambatan statis kecil.
Ini bekerja dengan sangat baik selama jumlah item tersebut cukup kecil, tetapi mulai terlihat sedikit buruk ketika ada lebih dari beberapa ratus objek yang perlu diperiksa. 10 objek menghasilkan hanya 100 cek benturan, 100 hasil dalam 10.000 cek. 1000 hasil dalam satu juta cek.
Indeks spasial (seperti quadtrees) dapat secara efisien menyebutkan item yang dikumpulkan sesuai dengan hubungan geometris. ini akan mengubah algoritme tabrakan menjadi seperti ini:
foreach actor in actorList:
foreach target in actorIndex.neighbors(actor.boundingbox):
if (actor != target) and actor.boundingbox intersects target.boundingbox:
actor.doCollision(target)
Efisiensi ini (dengan asumsi distribusi entitas yang seragam): biasanya O (n ^ 1,5 log (n)), karena indeks membutuhkan sekitar log (n) perbandingan untuk dilintasi, akan ada sekitar sqrt (n) tetangga untuk membandingkan , dan ada n aktor untuk diperiksa. Namun, secara realistis, jumlah tetangga selalu sangat terbatas, karena jika tabrakan terjadi, sebagian besar waktu salah satu objek dihapus, atau menjauh dari tabrakan. dengan demikian Anda mendapatkan hanya O (n log (n)). Untuk 10 entitas, Anda melakukan 10 perbandingan, untuk 100, Anda melakukan 200, untuk 1000 Anda melakukan 3000.
Indeks yang sangat pintar bahkan dapat menggabungkan pencarian tetangga dengan iterasi massal, dan melakukan panggilan balik pada setiap entitas yang berpotongan. Ini akan memberikan kinerja sekitar O (n), karena indeks sedang dipindai sekali daripada ditanya n kali.