I'm making a 4 player co-op r-type game, and I'm about to implement the collision detection code. I've read a lot of articles and stuff about how to handle collision detection, but I'm having a hard time figuring out what to go with.
It seems the quad tree is the most common way to go, but in some resources they mention the grid based solution. For having used a grid for detections in a previous game, I'm comfortable with that, but is it actually better than a quad tree ?
I'm not sure which offers best performance, and I've also ran a little benchmark, there is not much difference between both solutions.

Is one better than the other ? or more elegant ? I'm really not sure which one I should use.

1 Answer
1

The right answer depends a little bit on the actual game you're designing, and choosing one over the other is really going to require implementing both and doing profiling to find out which one is more time or space efficient on your specific game.

Grid detection seems to only apply to detecting collisions between moving objects and a static background. The biggest advantage to this is that the static background is represented as a contiguous memory array, and each collision lookup is O(1) with good locality if you need to do multiple reads (because entities cover more than one cell in the grid). The disadvantage, if the static background is large, is that the grid can be rather wasteful of space.

If instead you represent the static background as quadtree, then the cost of individual lookups goes up, but because large blocks of the background take up a small amount of space, the memory requirements go down, and so more of the background can sit in the cache. even if it takes 10 times as many reads to do a lookup in such a structure, if it's all in the cache, it'll still be 10 times faster than a single lookup with a cache miss.

If I were faced with the choice? I'd go with the grid implementation, because it's stupid simple to do, better spend my time on other, more interesting problems. If I notice that my game is running a little slow, I'll do some profiling and see what could use some help. If it looks like the game is spending a lot of time doing collision detection, I'd try another implementation, like a quadtree (after exhausting all easy fixes first), and find out if that helped.

This obviously has performance around O(n^2), with n the number of actors that are currently alive in the game, including bullets and spaceships and aliens. It can also include small static obstacles.

This works fantastically well so long as the number of such items is reasonably small, but starts to look a little poor when there's more than a few hundred objects to check against. 10 objects results in just 100 collision checks, 100 results in 10,000 checks. 1000 results in one million checks.

A spatial index (like quadtrees) can efficiently enumerate the items it collects according to geometric relationships. this would change the collision algorithm to something like this:

The efficiency of this (assuming a uniform distribution of entities): is usually O(n^1.5 log(n)), since the index takes about log(n) comparisons to traverse, there will be about sqrt(n) neighbors to compare, and there are n actors to check. Realistically, though, the number of neighbors is always quite limited, since if a collision does occur, most of the time one of the objects is deleted, or moved away from the collision. thus you get just O(n log(n)). For 10 entities, you do (about) 10 comparisons, for 100, you do 200, for 1000 you do 3000.

A really clever index can even combine the neighbor search with the bulk iteration, and perform a callback on each intersecting entity. This will give a performance of about O(n), since the index is being scanned once rather than queried n times.

I'm not sure I know what you are refering to when you say "static background". What I'm dealing with is basicaly a 2D shooter, so it's collision detection with space ships and aliens, bullets and walls.
–
dotminicDec 10 '10 at 0:41

This might sound stupid but how do I actually use my quadtree to select against which other objects an object should test collisions ? I'm unsure about how this is done. Which brings up a second question. Say I have an object in node that is not a neighbor of another node, but that the object is large enough that it spans a few nodes, how can I check for an actual collision, since I'm guessing the tree might consider it's not close enough to collide with objects in a "far away" node ? Should objects that don't completely fit in a node be kept in the parent node ?
–
dotminicDec 13 '10 at 21:47

2

Quat-tree's are inherintly sub-optimal for overlapping bounding box searches. The best choice for that is usually an R-Tree. For quad-trees, if most objects are roughly point-like, then yes, it's reasonable to keep objects at inner nodes, and perform exact collision testing on a fuzzy neighbor search. If most objects in the index are large and overlap without colliding, A quad tree probably is a poor choice. If you have more technical questions about this, you should consider taking them to stackoverflow.com
–
SingleNegationEliminationDec 13 '10 at 22:16

All this is pretty confusing! thanks for the info.
–
dotminicDec 13 '10 at 22:55