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 :
- 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);
- 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); } }