Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

First of all, I've only been writing my own game logic for a short while, so I apologize if this might seem straight forward.

I've been reading a lot about quad trees and grid based collision detection. I understand the logic - basically don't check for collision unless objects are near basically. But it never is mentioned how the actually execute this.

I have a couple of possibile methods in my head but am not sure which is best

General collision test - no optimisation

for(var i:int = 0; i < objects.length; i++){
        //find object A
        var objectA = objects[i];

        for(var j:int = i + 1; j < objects.length; j++){
            //find object B
            var objectB = objects[j];

            if(objectA.collidesWith(objectB){

               //handle collision logic
              }
        }

store neighbours (method 1) But what if we want to optimise the collisions to only check objects that are near. Do we still run through all the objects, or do we create an array with near objects to check through?

var objects:Array = new Array();
    var neighbours:Array = new Array();

    for(var i:int = 0; i < objects.length; i++){
        //find object A
        var objectA = objects[i];

        for(var j:int = i + 1; j < objects.length; j++){
            //find object B
            var objectB = objects[j];

            if(objectA.isNear(objectB){

               neighbours.push(objectA, objectB);
              }
        }

    }

    //somewhere else
    for(i:int = 0; i < neighbours.length; i++){
        //only check neighbours

        for(j:int = i + 1; j < neighbours.length; j++){

            if(objectA.collidesWith(objectB){

               //handle collision logic
              }
        }
    }

loop all objects but only check neighbours for collision (method 3) The other possibillity is that we still loop through everything but check if the objects are near before testing the collision.

for(var i:int = 0; i < objects.length; i++){
        //find object A
        var objectA = objects[i];

        for(var j:int = i + 1; j < objects.length; j++){
            //find object B
            var objectB = objects[j];

            if(objectA.isNear(objectB){
               //they are near - check collision!
               if(objectA.collidesWith(objectB){

               //handle collision logic
              }
            }
        }

    }

Store objects in tile data (method 3) Using a tile based sytem allow for another option; Store the objects that are on a specific tile in the tile data itself. Check to see on which tile the object is the surrounding tiles contain any objects it could collide with:

var ObjectA;

for(var i:int = 0; i < 4; i ++){
//check 4 surrounding tiles from object A

   if(Object.currentTile + surroundingTile[i] CONTAINS collidable object){
   //check collision!
    if(objectA.collidesWith(surroundingTile.object){

    //handle collision logic
     }

}
}

I always try to look at the real world as an example. If I wanted to compare items with the same colour it would seem illogical to check every entire item even if they don't match colour (Method 2, check each item). I would probably collect the items with the same colour (objects that are near each other) and check those (method 1), instead of checking everything.

This isn't an appropiate comparison since the items in collision checking are constantly moving so the order gets mixed up. That whats confusing me.

Would it be more efficient to check each item, thus removing the strain of keep generating an array of neighbours.

Or is it more efficient to find neighbours thus not having to loop through so many objects to check the collision?

Keep changing the data on each tile seems very intensive aswell, so i'm not sure if that a good idea..

I've been thinking of a tower defense game where the tower needs to detect objects if objects are in range before it shoots at it. And it just seems silly to check all items while at some times there won't be any objects near at all.

I apologize for the long post, always having trouble explaining myself!

share|improve this question
    
what language is this? Javascript? –  Kyle C Mar 26 '11 at 21:55
2  
Actionscript 3, but the language is pretty irrelevent. Just want to found out whats the best way to handle and structure this :) –  omgnoseat Mar 28 '11 at 10:54
add comment

1 Answer

up vote 8 down vote accepted

You need to reduce the count of actual collision checks. Yeah obvious I know. So lets elaborate on this:

Your first collision check algorithm without any optimization: how many checks will it do in one run? If n is the count of objects, this will be around n*(n-1) checks. For a lot of objects (>100) this will be horribly slow.

Your neighbor checking method will not be much faster. If your objects aren't static and move around a lot, you will need to build these neighbors list for each object everytime in your game loop. This is actually worse than the first algorithm since you're doing n*(n-1) to build the neighbour list and then check for each object if it collides with one of its neighbours.

You need to partition your game space. Lets say your game space is 400x400 pixels wide. Your can partition this into 4 sub-space each 200x200 in size and check for each object into which of the sub-spaces it belongs (one object can be inside more than one sub-space). Then you will only need to check if the objects in each subspace collides with other object in the same sub-space.

So the runtime cost will be: n for building the 4 sub-space list + (n/4)*((n-1)/4) which is a lot better than the previous runtime cost. This can be cut down further by making the sub-spaces smaller (e.g. 50x50).

So our algorithm now looks something like this:

for each (object in objects)
  check into which subspace the object belongs

for each (subspace in subspaces)
  for each (object in subspace)
    check object for collision with other objects in same subspace

This is somewhat similar to your tile data idea. But the subspaces do not need to be the same size as the tiles.

We can do one last step to optimize this further using a quadtree. Let k be the count of subspaces. To build the spaces object lists we are doing k*n checks, leading to a lot of checks if your game world gets large.

To cut this cost down we use a quadtree. A quadtree is another way to partition our game space. Instead of dividing our 400x400 space into 64 50x50 subspaces and checking for each object in which of the 64 subspaces it currently is, the game space is divide into 4 subspaces half the size of the game space (200x200), which in turn are divide into smaller subspaces (100x100), which in turn are divided again into 50x50 subspaces. This is our quadtree.

Now if we want to know into which 50x50 subspace an object belongs we check into which of the 200x200 subspaces it belongs. Then we go one level deeper in our quadtree and check against the 4 100x100 subspaces which are inside the 200x200 subspace we just found. This is repeated until we know into which 50x50 subspace the object belongs. So how many checks were now necessary? 4 for each level of the the quadtree (Remember an object can be on the edge of two subspaces). So we need 4*3 checks to assign an object to the correct 50x50 subspace. A lot better than 64 checks.

So our quadtree algorithm needs 4*3*n checks to build the subspace lists and then something like k*(n/k) checks to check the collisions of each object.

share|improve this answer
    
Thats a very clear and understandable awnser, thanks alot! How is it handled on which subspace an object is? Is the subspace handeled as an object, where the object on it are saved as arrays and checked against each other? Or do you just check on which subspace it is by checking the X and Y inside the main loop? Seems like building and changing arrays all the time is pretty inefficient. So I want to be sure that I use the appropriate method :) I can also see a problem occurring when objects are varying in size. I guess the smallest subspace should be about as big as the biggest object? –  omgnoseat Mar 28 '11 at 10:53
    
I'm glad to help :) A subspace would be an object which maintains the 4 subspaces it contains. The smallest subspace is different since it does not contain anymore subspaces, but a list of your objects. Considering the update cost: the subspace tree is built once at game start. In each loop of the main loop the objects lists in the smallest subspaces is cleared and filled again. So only list add/remove is necessary. No arrays need to be changed. The smallest subspace should be large enough to contain several game objects. How large depends on your game and can be tweaked later. –  Stephen Apr 2 '11 at 16:20
    
Thanks, forgot that the we will also be checking collisions between the actual objects in the smallest subspace, makes sense that it should be able to hold multiple objects now. I've started on a test and it's coming along nicely. The biggest trouble I'm having is detecting in which subspace an objects belongs. I keep looping through subspaces childs X and Y values, is this an appropiate method? –  omgnoseat Apr 4 '11 at 1:17
    
How do you handle objects that extend into more than one subspace (i.e. whose location is on or near a boundary)? –  mghicks Oct 26 '11 at 13:47
    
Simple: I don't. Objects can be part of multiple subspaces, if they are on the boundary of each subspace. So one object can be part of up to 4 subspaces. But this is the minority. –  Stephen Nov 27 '11 at 10:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.