JGameGrid
 
 

The source code of all examples is included in the JGameGrid distribution.

Ex04: Colliding Actors in Cells

Like in everyday life the interaction between actors plays an important role. Therefore collision detection is a major theme in gaming software. The subject is not trivial because of performance issues: it would be a simple concept to detect collisions between two images be checking, if non-transparent pixels of each images overlays. Unfortunately this is a very time consuming task, because each pixel has to be checked in real time. For two sprite images each 50x50 wide over 6 million checks are required. More effective procedure must be developed to speed-up collision detection in real time. JGameGrid includes some rather sophisticated support for collision detection.

When actors fills up grid cells almost completely, the collision can be detected simply by checking cell locations. The GameGrid class has a palette of appropriate methods to do this: getActorsAt() returns all actors or all actors at a specified location in a ArrayList of actors. You may restrict this list to the actors of a given class by specifying the class type.

In the following example a bear walks through the grid and eats all leaves found on his way. Because in this example a cell is either empty or contains a leaf, we use getOneActorAt() that returns the first (and only) actor found at a specified location or null, if the location is empty. First comes the application class that creates the game grid and adds a bear an 10 leaves at random grid locations. This is particularly simple by using getRandomEmptyLocation():

import ch.aplu.jgamegrid.*;

public
 class Ex04 extends GameGrid
{
  
public Ex04()
  
{
    
super(10, 10, 60, java.awt.Color.red);
    
addActor(new Bear(Class.leaf), new Location(0, 0));
    
for (int i = 0; i < 10; i++)
      
addActor(new Leaf(), getRandomEmptyLocation());
    
show();
  
}

  
public static void main(String[] args)
  
{
    
new Ex04();
  
}
}

We are now happy to create a animal class Bear by choosing the appearance and the behavior a bear. The appearance is given by the sprite image, the behavior by coding the method act(). Because we will use the Bear class in other examples, we pass the class literal of the collision class to the constructor and save it into a instance variable. This is the usual way how to make a class a bit more universal. In this example we use isMoveValid() to check whether the bear is at the border, it returns false, if the next move would be outside the visible grid. (In JGameGrid cell locations may be outside the visible grid and the cell indices in the full integer range, also negative.) To avoid global flags we use the mirror property as indicator if we move to the right or the left. The return value of getOneActorAt() is null or a leaf. In the latter case we remove the leaf from the game grid by calling hide(). Unfortunately it's not really eaten and the bear remains hungry.

import ch.aplu.jgamegrid.*;

public
 class Bear extends Actor
{
  
private Class clazz;

  
public Bear(Class clazz)
  
{
    
super("sprites/bear.gif");
    
this.clazz = clazz;
  
}

  
public void act()
  
{
    
if (isMoveValid())
      
move();
    
else
    
{
      
if (isHorzMirror())  // at left border
      
{
        
setHorzMirror(false);
        
turn(270);
        
move();
        
turn(270);
      
}
      
else // at right border
      
{
        
setHorzMirror(true);
        
turn(90);
        
move();
        
turn(90);
      
}
    
}
    
tryToEat();
  
}

  
private void tryToEat()
  
{
    Actor actor 
=
      
gameGrid.getOneActorAt(getLocation(), clazz);
    
if (actor!= null)
      actor.
hide();
  
}
}

The Leaf class is declared because we need the class literal Leaf.class.

import ch.aplu.jgamegrid.*;

public
 class Leaf extends Actor
{
  
public Leaf()
  
{
    
super("sprites/leaf.gif");
  
}
}

Execute the program locally using WebStart.

When we click Reset most of the initial properties of an actor such as starting location, direction and the mirror state are automatically restored. If you must reinitialize your own instance variables, you can override Actor's reset() (or register a GGResetListener).

jgamegridtut23

 

You can easily implement a more intelligent animal feeding scenario where the animal, a hamster, finds hazelnuts following your own clever search strategy despite some rock obstacles.

jgamegridtut22

Execute the program locally using WebStart.

 

If you do not want the title bar nor the surrounding borders, you can remove it by using a special GameGrid constructor . An exit button is added to terminate the application (the navigation area is hidden too).

jgamegridtut24

Execute the program locally using WebStart.