Game apps for smartphones and tablets

Research project PHBern  
HomeStart online editorAndroid TurtlegraphicsPrintJava-Online

Chasing figures


Example 1: A shark chases Nemo

Nemo swims back and forth horizontally. The shark chases Nemo. He moves from cell to cell in direction of the current position of Nemo.With each step, he can choose one of the 8 possible neighbouring cells. The ideal diretion for the chase is determined by the method
getCompassDirectionTo(nemo.getLocation()) . As a parameter, this method receives the position of the chased object. Already when creating the actor shark , the chased object is handed as parameter to r new Shark(nemo).
So that the shark does not instantly catch Nemo, it can move in every fifth simulation cycle only.

Edit this example in the Online Editor

App installieren auf Smartphone oder Tablet

QR-Code

Download sources (AndroidEx12.zip)

 

// AndroidEx12.java

package app.ex12;

import ch.aplu.android.*;

public class AndroidEx12 extends GameGrid 
{
  public AndroidEx12()
  {
    super(8, 8, cellZoom(62), GRAY, "reef",false);
  }

  public void main()
  {
    Fish nemo = new Fish();
    addActor(nemo, new Location(0, 1));
    Shark shark = new Shark(nemo);
    addActor(shark, new Location(7, 7));
    doRun();
  }
}

class Fish extends Actor
{
  public Fish()
  {
    super("nemo");
  }

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

class Shark extends Actor
{
  private Fish nemo;

  public Shark(Fish nemo)
  {
    super(true"shark");
    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();
  }
}

Explanations to the program code:
Shark shark = new Shark(nemo) So that the shark knows whom to chase, he receives the parameter nemo
if (nbCycles % 5 == 0 && !nemo.isRemoved()) The shark only moves in every fifth simulation cycle and only as long as the Nemo is there
getCompassDirectionTo(nemo.getLocation())) With nemo.getLocation(), we get Nemo's current position. With getCompassDirectionTo(), the direction to Nemo is chosen.
setDirection(getLocation().getCompassDirectionTo(nemo.getLocation())) The direction of the shark's current position, not Nemo's is chosen.

 

Example 2: Direct chase. The white ball follows the red ball

Unlike in the previous game, the white ball (ball) moves to the red ball directly (target); that is to say not from cell to cell, but continuously. After the ball has reached the position of the targets, the red ball disappears and appears in a new randomly chosen position. Then the chase begins again.

The white ball's position is calculated dotwise as follows: At the beginning of every chase, the difference of the x-coordinates dx and the difference of the y coordinates dy is calculated. So that the ball is moving at the same speed over large and small distances, we "nominate" the speed components by dividing dx and dy by the distance of the two balls. The speed factor can be adapted randomly. We get the new coordinates x and y by adding the y-coordinate to the current x-coordinate and vy/ vx coordinate respectively

Edit this example in the Online Editor

App installieren auf Smartphone oder Tablet

QR-Code

Download sources (AndroidEx13.zip)

 

// AndroidEx13.java

package app.ex13;

import ch.aplu.android.*;
import android.graphics.Point;

public class AndroidEx13 extends GameGrid
{
  public AndroidEx13()
  {
    super(10, 10, 0, RED, true);
  }

  public void main()
  {
    Target target = new Target();
    addActor(target, new Location(5, 5));
    Ball ball = new Ball(target);
    addActor(ball, new Location(0, 0));
    doRun();
  }
}

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

  public Ball(Target target)
  {
    super("playstone");
    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 Target---------------------------
class Target extends Actor
{
  public Target()
  {
    super(true"ball");
  }
}


Explanations to the program code:
int dx = targetPos.x - getPixelLocation().x
int dy = targetPos.y - getPixelLocation().y   
Calculation of the difference of the x-coordinates of both balls
Calculation of the difference of the y-coordinates of both balls
norm = Math.sqrt(dx * dx + dy *dy); The distance of both balls at the beginning of the chase
vx = speedFactor * dx / norm;
vy = speedFactor * dy / norm;
Calculates the speed components
x += vx;
y += vy;
Calculates the new coordinates
setPixelLocation(new Point((int)x, (int)y)) Sets the white ball on the exact position that is indicated by both calculated pixel coordinates
if (ball.getLocation().equals(getLocation())) Gives back true when both balls are in the same cell