Tutorial 10

MISSING SOME COLLISIONS!?

CollisionManager.java [view online]
This chapter will explain GTGE collision system to check collision between sprites.
Objective : Understand GTGE collision system, types of collision, and how to use it.
collapse/expand

As has been mentioned before, GTGE collision system is checking collision between sprites in a group againsts sprites in another group.

For example :
In shooter game, there are 6 sprite groups : player group, player shot group, enemy group, enemy shot group, asteroid group, and bonus group.
Collision can be checked between : player group <-> enemy, enemy shot, asteroid, and bonus group; while enemy group <-> player and player shot group; etc.

By using collision system based on group like this, managing collision implementation would be much easier. For example in above shooter game example, you could make the collision implementation like this : for player shot group <-> enemy group, set the collided sprite in enemy group to be destroyed (dead / inactive) and set the collided sprite in player shot group to vanish; while for collision between player group <-> bonus group, set player energy, score, or power to increase and set collided bonus to vanish.

Besides of making collision implementation much easier, this kind of collision system also improve readability, improve collision check performance, etc.

The Basic Collision Detection

The foundation of collision system in GTGE is CollisionManager class. The CollisionManager class is the base class of every collision types in GTGE.

How the CollisionManager class works :

  1. Register the two collision groups (groups to check its collision for one another) :
    class :: CollisionManager
    
    Syntax:
       public void setCollisionGroup(SpriteGroup group1,
                                     SpriteGroup group2);
    
    whereas :
    group1 = the first group registered for the collision check
    group2 = the second group registered for the collision check
    
    
    For example:
    register collision check between player shoot group and enemy group
    
       SpriteGroup       PLAYER_SHOT_GROUP,
                         ENEMY_GROUP;
    
       CollisionManager  collisionType;
    
    
       collisionType.setCollisionGroup(PLAYER_SHOT_GROUP, ENEMY_GROUP);
    
  2. Checking for the actual collision :
    How the collision check is delegated to its subclass.
    class :: CollisionManager
    
    Syntax:
       public abstract void checkCollision();
    
    
    For example:
    register and check for collision between player shoot group and enemy group
    
       SpriteGroup       PLAYER_SHOT_GROUP,
                         ENEMY_GROUP;
    
       CollisionManager  collisionType;
    
    
       collisionType.setCollisionGroup(PLAYER_SHOT_GROUP, ENEMY_GROUP);
    
       collisionType.checkCollision();
    

Types of Collision

As has been mentioned above, CollisionManager delegates the collision check to its subclass. For that, GTGE provides five subclass of CollisionManager class (collision types) :

  • BasicCollisionGroup class
    The basic collision type, only check whether collision is occured or not.
  • CollisionGroup class
    Check whether collision is occured or not and provide some information about the collision event, such as side of collision and sprite position before collision occured.
  • PreciseCollisionGroup class
    Sprite position before collision occured is calculated precisely, that way the collided sprites can return right before the collision occured.
  • AdvanceCollisionGroup class
    One-to-many collision type, this type of collision able to check collision between one sprite to many sprites at once accurately, for example in platformer game, this type of collision can calculate collision between player with many blocks.
  • CollisionBounds class
    Check sprite collision with boundary, for example bound sprite movement to the game background, when the sprite to out of bounds boundary, the collision event is fired.

Always use appropriate collision type for optimum and efficient collision check to improve game performance. For example if you only need to check whether collision occured without other collision info (like the collision side or sprite return position), then better use the BasicCollisionGroup collision type.

Collision Implementation

All above collision types send collision event to collided(Sprite s1, Sprite s2) function, where in this function the collision implementation is worked out. Whether the collided sprite is force to stop, or removed from the game, etc.

class :: BasicCollisionGroup

Syntax:
   public abstract void collided(Sprite s1,
                                 Sprite s2);

whereas :
s1 = the collided sprite from group 1
s2 = the collided sprite from group 2

Collision Check Initialization

Tutorial10.java [view online]

In order to initialize and perform collision check, the first thing is create the collision prototype by subclassing appropriate collision type. For example making collision prototype based on BasicCollisionGroup collision type to check collision between player shot group and enemy group :

file :: PlayerShotToEnemyCollision.java

// GTGE
import com.golden.gamedev.object.*;
import com.golden.gamedev.object.collision.*;


public class PlayerShotToEnemyCollision extends BasicCollisionGroup {

   public void collided(Sprite s1, Sprite s2) {
      // s1 = player shot sprite
      // s2 = enemy sprite

      // we make both of sprites to vanish!
      s1.setActive(false);
      s2.setActive(false);
   }

}

Above code is only the collision prototype/blue print, in order to check the collision, create a new object based on the prototype and register the collision groups into it :

   SpriteGroup       PLAYER_SHOT_GROUP,
                     ENEMY_GROUP;

   CollisionManager  collisionType;


   collisionType = new PlayerShotToEnemyCollision();

   collisionType.setCollisionGroup(PLAYER_SHOT_GROUP, ENEMY_GROUP);

   collisionType.checkCollision();

To use other collision type, for example CollisionGroup, only need to change the BasicCollisionGroup to CollisionGroup. To see all functions the collision type provided (for example function to get the collided side), please see the collision type API documentation.

Pixel Perfect Collision

BasicCollisionGroup class and its subclass support for pixel perfect collision. To use it simply set pixelPerfectCollision variable to true :

class :: BasicCollisionGroup

Syntax:
    boolean pixelPerfectCollision;


For example:
turn on pixel perfect collision for
collision between player and enemy in above example

   BasicCollisionGroup collisionType = new PlayerShotToEnemyCollision();
   collisionType.pixelPerfectCollision = true;

Full Example

A complete example of how to use GTGE collision system using the most basic collision type (BasicCollisionGroup class) where pixel perfect collision is turned on :

file :: YourGame.java

// JFC
import java.awt.*;

// GTGE
import com.golden.gamedev.*;
import com.golden.gamedev.object.*;
import com.golden.gamedev.object.background.*;
import com.golden.gamedev.object.collision.*;


public class YourGame extends Game {


    Background   background;

    SpriteGroup  PLAYER_SHOT_GROUP,
    SpriteGroup  ENEMY_GROUP;

    CollisionManager collisionType;


    public void initResources() {
        background = new ColorBackground(Color.BLUE, 640, 480);

        PLAYER_SHOT_GROUP = new SpriteGroup("Player Shot Group");
        ENEMY_GROUP = new SpriteGroup("Enemy Group");

        collisionType = new PlayerShotToEnemyCollision();
        collisionType.setCollisionGroup(PLAYER_SHOT_GROUP, ENEMY_GROUP);
    }


    public void update(long elapsedTime) {
        background.update(elapsedTime);

        PLAYER_SHOT_GROUP.update(elapsedTime);
        ENEMY_GROUP.update(elapsedTime);

        collisionType.checkCollision();
    }


    public void render(Graphics2D g) {
        background.render(g);

        PLAYER_SHOT_GROUP.render(g);
        ENEMY_GROUP.render(g);
    }


    public static void main(String[] args) {
        GameLoader game = new GameLoader();
        game.setup(new YourGame(), new Dimension(640,480), false);
        game.start();
    }

}

class PlayerShotToEnemyCollision extends BasicCollisionGroup {

    public PlayerShotToEnemyCollision() {
	pixelPerfectCollision = true;
    }

    public void collided(Sprite s1, Sprite s2) {
        // s1 = player shot sprite
        // s2 = enemy sprite

        // make both sprites to vanish!
        s1.setActive(false);
        s2.setActive(false);
    }

}


Summary :

  • The collision system in GTGE is checking collision between members of two sprite groups.
  • CollisionManager class is the base GTGE collision system, where its main task is registering the collision groups using setCollisionGroup(SpriteGroup, SpriteGroup), and checking the actual collision using checkCollision().
  • There are 5 collision types in GTGE (subclass of CollisionManager class) : BasicCollisionGroup, CollisionGroup, PreciseCollisionGroup, AdvanceCollisionGroup, dan CollisionBounds. Always use appropriate collision type for optimum collision check to improve game performance.
  • To initialize collision detection, subclass the appropriate collision type, instantiate new object based on the class, register the collision groups into it, and check for collision by calling checkCollision() function.
  • To turn on pixel perfect collision, simply set pixelPerfectCollision variable to true.

Reference : CollisionManager class, BasicCollisionGroup class, com.golden.gamedev.object.collision package

Copyright © 2003-2005 Golden T Studios. All rights reserved. Use is subject to license terms.
GoldenStudios.or.id
Page 10 of 12