Tutorial 9

GROUPING YOUR SPRITES

SpriteGroup.java [view online]
This chapter will explain why sprites need to be group, what the benefit of grouping sprites, and how to group sprites correctly.
Objective : Understand what is, the objective, and how to group sprites.
collapse/expand

In previous chapter (the first approach of sprite management in GTGE) has been explained that every sprites need to be updated, rendered, and attached to a background one by one. This will became troubles and perhaps will be impossible to organize anymore as the number of sprites is increasing greatly.

For example managing nine sprites :

file :: YourGame.java

// JFC
import java.awt.*;

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


public class YourGame extends Game {


    Background  background;
    Sprite      s1, s2, s3, s4, s5,
                s6, s7, s8, s9;


    public void initResources() {
        background = new ColorBackground(Color.BLUE, 1024, 768);

        s1 = new Sprite(getImage("player.png"));
        s2 = new Sprite(getImage("player.png"));
        s3 = new Sprite(getImage("player.png"));
        s4 = new Sprite(getImage("player.png"));
        s5 = new Sprite(getImage("player.png"));
        s6 = new Sprite(getImage("player.png"));
        s7 = new Sprite(getImage("player.png"));
        s8 = new Sprite(getImage("player.png"));
        s9 = new Sprite(getImage("player.png"));

        s1.setBackground(background);
        s2.setBackground(background);
        s3.setBackground(background);
        s4.setBackground(background);
        s5.setBackground(background);
        s6.setBackground(background);
        s7.setBackground(background);
        s8.setBackground(background);
        s9.setBackground(background);
    }


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

        s1.update(elapsedTime);
        s2.update(elapsedTime);
        s3.update(elapsedTime);
        s4.update(elapsedTime);
        s5.update(elapsedTime);
        s6.update(elapsedTime);
        s7.update(elapsedTime);
        s8.update(elapsedTime);
        s9.update(elapsedTime);
    }


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

        s1.render(g);
        s2.render(g);
        s3.render(g);
        s4.render(g);
        s5.render(g);
        s6.render(g);
        s7.render(g);
        s8.render(g);
        s9.render(g);
    }


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

}

For nine sprites that can be categorized as a very small amount of sprites for a game, the management is quite difficult. You probably think why not just use array in there, it's possible, but how if the sprites need to be removed or if there is a new sprite to be added? Adding and removing array elements is a difficult task, beside that there is also the problem of determining the sprite location within the array.

Because of that, GTGE offers the next sprite management : grouping all sprites into groups, and those groups that will automatically attach all its sprite member to a background, updating, and rendering all sprites in the group.

This group in GTGE is represented by SpriteGroup class, which in essence is actually a dynamic resizeable array.
sprite group diagram

SpriteGroup Initialization

SpriteGroup initialization is similar like in sprite, the group need to be attached to a background, updated and rendered to the screen :

class :: SpriteGroup

Syntax:
   public SpriteGroup(String name);
   public void setBackground(Background backgr);
   public void update(long elapsedTime);
   public void render(Graphics2D g);

whereas :
name        = the name of the group, only for group identifier
backgr      = the background where all the sprites in the group will be attached on
elapsedTime = time elapsed since last updated
              this value is taken from Game class
g           = graphics object where the game is rendered

Adding Sprite Into a Group

Newly created SpriteGroup is always empty. To add new sprite to the group use SpriteGroup.add(Sprite) :

class :: SpriteGroup

Syntax:
   public void add(Sprite member);

whereas :
member = sprite to be added into the group

Above example (managing nine sprites) when changed to use SpriteGroup class will became :
Tutorial9_1.java [view online]

file :: YourGame.java

// JFC
import java.awt.*;

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


public class YourGame extends Game {


    Background   background;
    SpriteGroup  PLAYER_GROUP; // we use sprite group's variable name
                               // in UPPERCASE


    public void initResources() {
        background = new ColorBackground(Color.BLUE, 1024, 768);

        PLAYER_GROUP = new SpriteGroup("Player Group");
        PLAYER_GROUP.setBackground(background);

        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
        PLAYER_GROUP.add(new Sprite(getImage("player.png")));
    }


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

        PLAYER_GROUP.update(elapsedTime);
    }


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

        PLAYER_GROUP.render(g);
    }


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

}
By using SpriteGroup, managing many sprites can be done easily. No need for holding sprite object reference anymore, attaching the sprite to a background one by one, updating, and rendering each sprite.

Removing Sprite From A Group

Tutorial9_2.java [view online]

To remove a sprite from its group simply set sprite active state to false by using Sprite.setActive(false).

class :: Sprite

Syntax:
   public void setActive(boolean b);

whereas :
b = active state of the sprite, false makes the sprite inactive (dead)
    inactive sprite will be removed from its group
adding/removing sprite to/from a sprite group

How To Group Sprites Correctly

There is one important thing that requires attention when grouping sprites, sprite group is also be used in GTGE collision detection. Collision system in GTGE is checking collision between sprites in two groups. Therefore before grouping sprites, you need to see which sprites that need to be in separate groups so the collision detection can be used efficiently.

For example in shooter game, you could make 6 groups as followed : player, player shot, enemy, enemy shot, asteroid, and bonus. Then you can make collision system easily like this : player <-> enemy, enemy shot, asteroid, and bonus; while enemy <-> player and player shot; etc.

Other Important Notice

What you need to pay attention in this second approach of GTGE sprite management is each group still need to be attached with the desired background, updated, and rendered one by one.

file :: YourGame.java

// JFC
import java.awt.*;

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


public class YourGame extends Game {


    Background   background;
    SpriteGroup  PLAYER_GROUP, PLAYER_SHOT_GROUP,
                 ENEMY_GROUP, ENEMY_SHOT_GROUP,
                 ASTEROID_GROUP, BONUS_GROUP;


    public void initResources() {
        background = new ColorBackground(Color.BLUE, 1024, 768);

        PLAYER_GROUP      = new SpriteGroup("Player Group");
        PLAYER_SHOT_GROUP = new SpriteGroup("Player Shot Group");
        ENEMY_GROUP       = new SpriteGroup("Enemy Group");
        ENEMY_SHOT_GROUP  = new SpriteGroup("Enemy Shot Group");
        ASTEROID_GROUP    = new SpriteGroup("Asteroid Group");
        BONUS_GROUP       = new SpriteGroup("Bonus Group");

        PLAYER_GROUP.setBackground(background);
        PLAYER_SHOT_GROUP.setBackground(background);
        ENEMY_GROUP.setBackground(background);
        ENEMY_SHOT_GROUP.setBackground(background);
        ASTEROID_GROUP.setBackground(background);
        BONUS_GROUP.setBackground(background);
    }


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

        PLAYER_GROUP.update(elapsedTime);
        PLAYER_SHOT_GROUP.update(elapsedTime);
        ENEMY_GROUP.update(elapsedTime);
        ENEMY_SHOT_GROUP.update(elapsedTime);
        ASTEROID_GROUP.update(elapsedTime);
        BONUS_GROUP.update(elapsedTime);
    }


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

        PLAYER_GROUP.render(g);
        PLAYER_SHOT_GROUP.render(g);
        ENEMY_GROUP.render(g);
        ENEMY_SHOT_GROUP.render(g);
        ASTEROID_GROUP.render(g);
        BONUS_GROUP.render(g);
    }


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

}

Summary :

  • To grouping sprites use SpriteGroup class.
  • The purpose of grouping sprites is for easier managing many sprites by automate sprite attachment to a background, updating, and rendering each sprite.
  • To add a sprite into a group use SpriteGroup.add(Sprite).
  • To remove a sprite from its group, set the active state of the sprite to false, Sprite.setActive(false).

Reference : SpriteGroup class, Sprite class

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