GameGrid: Game programming with Java

Research project PHBern  
HomePrintJava-Online

Chasing actors


Example 1: A shark chases Nemo

Nemo swims back and forth horzintally while the shark chases Nemo. The shark moves from cell to cell, each time adjusting its direction to the position of Nemo. It can move into one of the eight neighbouring cells. The direction to Nemo is set by the method getCompassDirectionTo(nemo.getLocation()). Its parameter is the method which returns the current location of Nemo. Already when initialzing an actor shark, its parameter is set to Nemo: new Shark(nemo).
To slow down the whole chase, the shark only moves each fifth simulation cycle.

 

Run this example

Edit this example in the Online-Editor

 

// JGameEx15.java

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

public class JGameEx15 extends GameGrid
{
  public JGameEx15()
  {
    super(10, 10, 60, Color.red, "sprites/reef.gif");
    Fish nemo = new Fish();
    addActor(nemo, new Location(0, 1));
    Shark shark = new Shark(nemo);
    addActor(shark, new Location(7, 9));
    show();
  }

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

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

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

// ---------------------- class Shark ------------------------------------------
class Shark extends Actor
{
  private Fish nemo;

  public Shark(Fish nemo)
  {
    super(true"sprites/shark.gif");
    this.nemo = nemo;
  }

  public void act()
  {
    if (nbCycles % == && !nemo.isRemoved())
    {
      setDirection(getLocation().getCompassDirectionTo(nemo.getLocation()));
      move();
    }
    Actor aNemo = gameGrid.getOneActorAt(getLocation(), Fish.class);
    if (aNemo != null)
      aNemo.removeSelf();
  }
}

Explaining the program code:
Shark shark = new Shark(nemo) The shark knows which actor to follow by setting it as its parameter, e.g. nemo
if (nbCycles % 5 == 0 && !nemo.isRemoved()) The shark only moves each fifth simulation cycle and stops as soon as it catches Nemo
getCompassDirectionTo(nemo.getLocation())) nemo.getLocation() returns Nemo's current location. getCompassDirectionTo() returns the direction from the shark's position to Nemo
setDirection(getLocation().getCompassDirectionTo(nemo.getLocation())) The direction of the shark is set to the current position of Nemo

Download the program code for local editing: JGameEx15.zip

 

Example 2: Straight chase. The white ball follows the red one

Different to the first example, the white ball moves straight to the red one, without moving from cell to cell. As soon as it reaches the cell of the red ball, the red one disappears and reappears at a new random location. The chase starts again.

The position of the white ball is calculated pixelwise. At the beginning of each step the difference between the x-coordinates dx and the difference between the y-coordinates dy of the two balls are recalculated. This resets the direction of the white ball. To let the white ball move at the same speed for its big and small distances, its speed is "normed" by dividing dx and dy with the distance of the two balls to each other. The speed can be change at random. The new x- and y-coordinates are calculated by adding the vx or vy to the current x- or y-coordinate

Run this example

Edit this example in the Online-Editor

 

// JGameEx16.java

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

public class JGameEx16 extends GameGrid
{
  public JGameEx16()
  {
    super(10, 10, 60, Color.red);
    Target target = new Target();
    addActor(target, new Location(5, 5));
    Ball ball = new Ball(target);
    addActor(ball, new Location(0, 0));
    show();
  }

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

class Ball extends Actor
{
  private Target target;
  private double vx, vy, x, y;
  private final double speedFactor = 10;

  public Ball(Target target)
  {
    super("sprites/playStone_0.png");
    this.target = target;
  }

  public void act()
  {
    moveBall();
    tryToTouch();
  }

  public void moveBall()
  {
    x += vx;
    y += vy;
    setPixelLocation(new Point((int)x, (int)y));
  }

  private void tryToTouch()
  {
    if (target.getLocation().equals(getLocation()))
    {
      target.setLocation(gameGrid.getRandomEmptyLocation());
      setSpeed();
    }
  }

  private void setSpeed()
  {
    Point targetPosition = target.getPixelLocation();
    int dx = targetPosition.x - getPixelLocation().x;
    int dy = targetPosition.y - getPixelLocation().y;
    double norm = Math.sqrt(dx * dx + dy *dy);
    vx = speedFactor * dx / norm;
    vy = speedFactor * dy / norm;
  }

  public void reset()
  {
    x = getPixelLocation().x;
    = getPixelLocation().y;
    setSpeed();
  }
}

// --------------------- class Ball ---------------------------
class Target extends Actor
{
  public Target()
  {
    super(true"sprites/ball.gif");
  }
}

Explaining the program code:
int dx = targetPos.x - getPixelLocation().x
int dy = targetPos.y - getPixelLocation().y   
Calculates the difference of the x-coordinates of the two balls
Calculates the difference of the y-coordinates of the two balls

norm ≅ Math.sqrt(dx * dx + dy * dy)

The distance of the two balls at the start of the chase
vx = speedFactor * dx / norm;
vy = speedFactor * dy / norm;
Calculates the speed
x += vx;
y += vy;
Calculates the new coordinates
setPixelLocation(new Point((int)x, (int)y)) Sets the white ball at the exact position of the calculated pixel coordinates
if (ball.getLocation().equals(getLocation())) Returns true if both balls are inside the same cell

Download the program code for local editing: JGameEx16.zip