Games - deteccao de colisao

Top  Previous  Next

Method of implementing simple collision detection for games using bounding boxes. 

Answer:

 

 

It's not uncommon that collision detection in games is one of the most called functions. There are several ways of doing collision detection and this article describes a method for 2D games using bounding boxes. 

 

Perfect collision detection down to the pixel is of course what (theoretically) is the best. However, checking each pixel against each other for all objects every frame in a game is slow, very slow. So a simplier way is needed, this is where bounding boxes comes in. 

 

Imagine that you draw a rectangle, like a frame, around an object (the player spaceship for examle). Then do the same thing for all the other objects in the game. Now calculate if these rectangles intercept each other to determine a collision, instead of checking each pixels. This method is much faster, not as precise, but usually exact enough. 

 

+------------+ 

|      XX    | 

|    XXXXXX  | 

|XXXXXXXXXXXX| 

|    XXXXXX+-|----------+ 

|      XX  |X|XX    XXXX| 

+------------+ XX  XX   | 

           |    XXXX    | 

           |   XX  XX   | 

           |XXXX    XXXX| 

           +------------+ 

 

A problem is that sometimes a collision is detected when visually it seems like the object didn't touch. This usually occurs when any of the objects is shaped like a sphere. To compensate this we use an offset when checking if the bounding boxes intercept. By making the bounding boxes slightly smaller than the object itself, detection usually seems accurate enough. As mentioned before, we sacrifice precision for speed, but this is a way to compensate the precision to make it "feel" more exact. 

 

Here is the function which does the real collision detection of two objects. In this example the player's coordinates are x1 and y1, while the enemy's are x2 and y2. The offset used is 4 pixels. 

 

function CheckCollision(x1, y1, x2, y2: integer): boolean; 

const 

  OFFSET_X = 4

  OFFSET_Y = 4

begin 

  Result := True; 

 

  if (y1 + PLAYER_HEIGHT - (OFFSET_Y * 2) < y2 + OFFSET_Y) or 

     (y1 + OFFSET_Y > y2 + ENEMY_HEIGHT - (OFFSET_Y * 2)) or 

     (x1 + PLAYER_WIDTH - (OFFSET_X * 2) < x2 + OFFSET_X) or 

     (x1 + OFFSET_X > x2 + ENEMY_WIDTH - (OFFSET_X * 2)) then 

      Result := False; 

end

 

As an example, the above function may be used in a loop like this to check the player against multiple enemies: 

 

  for i := 0 to Length(Enemy) - 1 do 

    if CheckCollision(Player.x, Player.y, Enemy[i].x, Enemy[i].y) then 

      GameOver; 

 

Bottom line is that usually it's enough if it "looks" real, and less important that it "is" real. It's a balance between how exact we want it, and how fast we need it to perform. 

 

This article was aimed towards beginners wanting get into game programming, I'll hope it was helpful.