GameGrid: Game programming with Java

Research project PHBern  
HomePrintJava-Online

Collisions inside the grid


Interactions between actors play an important role in game programming. JGameGrid implements collisions in two ways:

The second collision implementation will be discussed in Exact collision identification.

With grid collisions, the method getActorsAt() returns all actors in one cell as an ArrayList. The list can be limited to an actor typ, by defining its class name. If there is only one or no actor in one cell, the simplified method getOneActorAt() is used. It returns an actor refernce or null.

Example 1: Fish eats alga

With the help of the method getRandomEmptyLocation() , 10 actors from the class Alga are set to random empty locations. By clicking on the Reset button, additional alga can be added to the grid.

The fish swims around inside the grid an eats all alga. Inside the method tryToEat() the JGameGird method getOneActorAt(getLocation(), Alga.class) checks if there is an actor of the class Alga in the fish's current cell. If there is alga, the fish opens its mouth and the alga is removed from the grid by calling the method actor.removeSelf().

Only after a few seconds, the whole grid is cleaned of alga.

 

Run this example

Edit this example in the Online-Editor

 
// JGameEx12.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;

public class JGameEx12 extends GameGrid
{
  public JGameEx12()
  {
    super(10, 10, 60, Color.red, "sprites/reef.gif");
    addActor(new EatingFish(), new Location(0, 0));
    for (int = 0; i < 10; i++)
      addActor(new Alga(), getRandomEmptyLocation());
    show();
  }
  
  public static void main(String[] args)
  {
    new JGameEx12();
  }
}

// --------------------- class EatingFish ---------------------
class EatingFish extends Actor
{
  public EatingFish()
  {
    super("sprites/fish.gif"2);
  }

  public void act()
  {
    move();
    tryToEat();
    if (getX() == 9)
    {
      turn(90);
      setHorzMirror(true);
    }
    if (getX() == 0)
    {
      turn(270);
      setHorzMirror(false);
    }
  }

  private void tryToEat()
  {
    show(0);
    Actor actor = gameGrid.getOneActorAt(getLocation(), Alga.class);
    if (actor != null)
    {
      actor.hide();
      show(1);
    }
  }
}

// --------------------- class Alga ---------------------------
class Alga extends Actor
{

  public Alga()
  {
    super("sprites/alga.gif");
  }
}

Explaining the program code:
reset() The method reset() is called if the button Reset is pressed. After each click ten new alga are set inside the grid
tryToEat() Checks if there is an alga inside the fish's current cell. The fish opens its mouth and the alga is removed from the grid
getOneActorAt(getLocation(), Alga.class) Returns a reference of Alga or null
if (actor != null) The condition is satisfied, if there is an Alga inside the cell
actor.hide() The actor is hidden, but stays inside the grid and can be reactivated by calling reset()
actor.removeSelf() Can be used instead of hide(). But with this method the actor is removed from the grid

 

 

Example 2: Nemo has to avoid the crab

Nemo swims back and forth while the crab suddenly appears at a location with a random x-coordinate and starts moving up and down. To be able to observe several collisons at once, the crab stays for 5 simulation cycles in the cell with the y-coordinate of Nemo. If a collision happens, Nemo turns around and swims away in the opposite direction.

The method getOneActorAt(getNextMoveLocation(), Crab.class) checks if there is a crab inside the cell which Nemo will move to next. It is important that the crab moves first, because Nemo needs to check afterwards if it can move into the next cell or not. In other words, the method act() of the crab needs to be called before the act() of Nemo. By default the act() method of the actor which is added last to the game grid is called first. Therefore the crab must be added after Nemo (the act-order can be changed with the method setActOrder()).

 

Run this example

Edit this example in the Online-Editor

 

// JGameEx14.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;

public class JGameEx14 extends GameGrid
{
  public JGameEx14()
  {
    super(10, 10, 60, Color.red, "sprites/reef.gif");
    addActor(new Fish(), new Location(1, 4));
    addActor(new Crab(), new Location(5, 7));
    show();
  }

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

// ----------------------- class Fish ---------------------------------------

class Fish extends Actor
{
  public Fish()
  {
    super("sprites/sNemo.gif");
  }

  public void act()
  {

    Actor actor = gameGrid.getOneActorAt(getNextMoveLocation(), Crab.class);
    if (actor != null || isNearBorder())
    {
      turn(180);
      setHorzMirror(!isHorzMirror());
    }
    move();
  }

  public void reset()
  {
    setHorzMirror(false);
  }
}

// ---------------------- class Crab ------------------------------------------

class Crab extends Actor
{
  public Crab()
  {
    super("sprites/crab.gif");
  }

  public void act()
  {
    if (getY() == && getNbCycles() % != 0)
       return;
    move();
    if (getY() == 2)
      turn(180);
    if (getY() == 7)
    {
      turn(180);
      setX((int)(5 * Math.random()) + 3);
    }
  }

  public void reset()
  {
    setDirection(Location.NORTH);
  }
}

Explaining the program code:
Actor actor = 
getOneActorAt(nextMoveLocation, Crab.class)
If there is an object of the class Crab inside the next cell, Nemo has to turn around
if (getY() == 4 && getNbCycles() % 5 != 0)
return
If the crab's y-coordinate is 4, the program checkes if the number of simulation cycles can be divided by 5. This allows the crab to stay inside the same cell for 5 cycles
setX((int)(5 * Math.random()) + 3) The x-coordinate is set to a random number between 3 and 7