GameGrid: Game programming with Java

Research project PHBern  
HomePrintJava-Online

Cat Game

 

The cat can move forward and backward. It can also jump. It can protect itself from the dog by jumping onto the walls. If the cat survives three wall blocks, it can start eating flies. The aim of the game is to eat as many flies as possible.

The game controls are the cursor keys

To jump, hit space


Run this example

 

Edit this example in the Online-Editor

 

 
Program code
// CatGame.java

import ch.aplu.jgamegrid.*;
import ch.aplu.util.*;
import java.util.*;
import java.awt.*;
import java.awt.event.KeyEvent;

public class CatGame extends GameGrid
{
  private final int nbHorzTiles = 30;
  private final int nbVertTiles = 5;
  private final int tileSize = 64;
  private Dog[] dogs = new Dog[2];
  private Cat cat;
  private boolean isFliesEnabled = false;
  private int nbEatenFlies = 0;
  private final String info =
    "Welcome to the Cat Game!\n\n" +
    "The cat wants to move to right where it finds delicious\n" +
    "flies to eat. The dogs are dangerous, so the cat\n" +
    "should keep away from their heads.\n\n" +
    "Use the left and right cursor keys to move the cat,\n" +
    "the space key will make the cat jump.\n\n" +
    "There is only a limited number of flies and the cat\n" +
    "must catch them with his mouth.\n\n" +
    "The aim is to eat as much flies as possible\n" +
    "(the number of eaten flies is shown in the title bar).";

  public CatGame()
  {
    super(6403201null"sprites/clouds.gif"false);
    new ModelessOptionPane(5050, info, null);
    setSimulationPeriod(50);

    GGTileMap tm = createTileMap(nbHorzTiles, nbVertTiles, tileSize, tileSize);
    for (int i = 0; i < nbHorzTiles; i++)
      tm.setImage("sprites/tile_B.gif", i, 4);

    // first bumb at i = 2, 3
    tm.setImage("sprites/tile_G.gif"24);
    tm.setImage("sprites/tile_H.gif"34);

    tm.setImage("sprites/tile_E.gif"23);
    tm.setImage("sprites/tile_F.gif"33);

    // second bumb at i = 10, 11
    tm.setImage("sprites/tile_G.gif"104);
    tm.setImage("sprites/tile_H.gif"114);

    tm.setImage("sprites/tile_C.gif"103);
    tm.setImage("sprites/tile_D.gif"113);

    tm.setImage("sprites/tile_E.gif"102);
    tm.setImage("sprites/tile_F.gif"112);

    // third bumb at i = 20, 21, 22, 23
    tm.setImage("sprites/tile_G.gif"204);
    tm.setImage("sprites/tile_A.gif"214);
    tm.setImage("sprites/tile_A.gif"224);
    tm.setImage("sprites/tile_H.gif"234);

    tm.setImage("sprites/tile_E.gif"203);
    tm.setImage("sprites/tile_G.gif"213);
    tm.setImage("sprites/tile_H.gif"223);
    tm.setImage("sprites/tile_F.gif"233);

    tm.setImage("sprites/tile_E.gif"212);
    tm.setImage("sprites/tile_F.gif"222);

    dogs[0] = new Dog(this);
    dogs[0].addCollisionTile(new Location(33));
    dogs[0].addCollisionTile(new Location(103));
    dogs[0].setCollisionCircle(new Point(22-25)10);
    addActor(dogs[0]new Location(350225));

    dogs[1] = new Dog(this);
    dogs[1].addCollisionTile(new Location(113));
    dogs[1].addCollisionTile(new Location(203));
    dogs[1].setCollisionCircle(new Point(28-16)20);
    addActor(dogs[1]new Location(850220));

    cat = new Cat(this);
    addActor(cat, new Location(30235));
    addKeyListener(cat);
    cat.setCollisionRectangle(new Point(00)3555);

    ArrayList<Location> tiles = new ArrayList<Location>();

    // First bumb
    tiles.add(new Location(23));
    tiles.add(new Location(33));

    // Second bumb
    tiles.add(new Location(103));
    tiles.add(new Location(102));
    tiles.add(new Location(113));
    tiles.add(new Location(112));

    // Third bumb
    tiles.add(new Location(203));
    tiles.add(new Location(212));
    tiles.add(new Location(222));
    tiles.add(new Location(233));

    cat.addCollisionTiles(tiles);
    cat.addCollisionActor(dogs[0]);
    cat.addCollisionActor(dogs[1]);

    show();
    doRun();
    Monitor.putSleep();
    int nbFlies = 0;
    while (nbFlies < 50)
    {
      Location randomLocation =
        new Location((int)(400 + 200 * Math.random())250);
      Fly fly = new Fly(this);
      addActor(fly, randomLocation);
      fly.addCollisionActor(cat);
      delay((long)(200 + 1000 * Math.random()));
      nbFlies++;
    }
  }

  public void setFliesEnabled(boolean enabled)
  {
    isFliesEnabled = true;
    Monitor.wakeUp();
    cat.setCollisionCircle(new Point(16-15)5);
  }

  public boolean isFliesEnabled()
  {
    return isFliesEnabled;
  }

  public void increaseEatenFlies()
  {
    nbEatenFlies++;
    setTitle("Flies eaten: " + nbEatenFlies);
  }

  public Dog[] getDogs()
  {
    return dogs;
  }

  public Cat getCat()
  {
    return cat;
  }

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

// --------------------- class Cat ----------------------------------------
class Cat extends Actor
  implements GGKeyListener, GGTileCollisionListener, GGActorCollisionListener
{
  private Location location;
  private boolean downward = false;
  private boolean forward = false;
  private boolean backward = false;
  private boolean onTop = false;
  private CatGame cg;
  private int tmX = 0;
  private int tmY = 0;

  public Cat(CatGame cg)
  {
    super("sprites/cat.gif"2);
    this.cg = cg;
    location = getLocationStart();
    addTileCollisionListener(this);
  }

  public void act()
  {
    // -------- Move cat ----------
    if (downward && !onTop)
    {
      location.y += 5;
      if (location.y == 235)
        downward = false;
      setLocation(location);
    }
    if (forward)
    {
      forward = false;
      location.x += 10;
      setLocation(location);
    }
    if (backward)
    {
      backward = false;
      location.x -= 10;
      if (cg.isFliesEnabled())
        location.x = Math.max(380, location.x);  // inhibit to go back
      setLocation(location);
    }
    onTop = false;

    // -------- Move tile map and background image ------------
    if (cg.isFliesEnabled())  // Inhibit movement of map
      return;
    GGTileMap tm = cg.getTileMap();
    Dog[] dogs = cg.getDogs();
    location = getLocation();
    if (location.x > 400)
    {
      // Move tile map
      tmX -= 5;
      if (tmX < -1280)
        tmX = -1280;
      else
      {
        location.x = 400;
        setLocation(location);
        tm.setPosition(new Point(tmX, tmY));
        cg.setBgImagePos(new Point(tmX, 0));
        dogs[0].setX(dogs[0].getX() - 5);
        dogs[1].setX(dogs[1].getX() - 5);
      }

    }
    if (location.x < 300)
    {
      // Move tile map
      tmX += 5;
      if (tmX > 0)
        tmX = 0;
      else
      {
        location.x = 300;
        setLocation(location);
        tm.setPosition(new Point(tmX, tmY));
        gameGrid.setBgImagePos(new Point(tmX, 0));
        dogs[0].setX(dogs[0].getX() + 5);
        dogs[1].setX(dogs[1].getX() + 5);
      }
    }
    if (tmX < -1180)
      cg.setFliesEnabled(true);

  }

  public boolean keyPressed(KeyEvent evt)
  {
    switch (evt.getKeyCode())
    {
      case KeyEvent.VK_SPACE:
        if (downward && !onTop)
          return true;
        location = getLocation();
        location.y = 50;
        setLocation(location);
        downward = true;
        break;
      case KeyEvent.VK_LEFT:
        location = getLocation();
        setHorzMirror(true);
        backward = true;
        break;
      case KeyEvent.VK_RIGHT:
        location = getLocation();
        if (location.x > 600)
          return true;
        setHorzMirror(false);
        forward = true;
        break;
    }
    return true;
  }

  public boolean keyReleased(KeyEvent evt)
  {
    return true;
  }

  // Called after act()
  public int collide(Actor actor, Location location)
  {
    int a = 10;  // distance to jump back
    // First bumb
    if (location.equals(new Location(23)))
      walk(-a, 170);
    if (location.equals(new Location(33)))
      walk(a, 170);

    // Second bumb
    if (location.equals(new Location(103)) ||
      location.equals(new Location(102)))
      walk(-a, 110);
    if (location.equals(new Location(113)) ||
      location.equals(new Location(112)))
      walk(a, 110);

    // Third bumb lower part
    if (location.equals(new Location(203)))
      walk(-a, 170);
    if (location.equals(new Location(233)))
      walk(a, 170);

    // Third bumb upper part
    if (location.equals(new Location(212)))
      walk(-a, 110);
    if (location.equals(new Location(222)))
      walk(a, 110);

    // Home
    if (location.equals(new Location(293)) ||
      location.equals(new Location(292)))
      walk(-5110);
    if (location.equals(new Location(293)) ||
      location.equals(new Location(112)))
      walk(5110);

    return 0;
  }

  private void walk(int distance, int height)
  {
    if (getLocation().y > height)
      setX(getX() + distance);
    else
      onTop = true;
  }

  public int collide(Actor a1, Actor a2)
  {
    cg.addActor(new Actor("sprites/happydog.gif")getLocation());
    a1.removeSelf();
    a2.removeSelf();
    return 0;
  }
}

// ------------------------- class Dog --------------------------------------
class Dog extends Actor
{
  private CatGame cg;
  private int skipAct = 0;
  private static int nbDogs = 0;

  public Dog(CatGame cg)
  {
    super("sprites/dog" + nbDogs + ".gif");
    nbDogs++;
    this.cg = cg;
  }

  public void act()
  {
    move(3);
    if (skipAct > 0)
    {
      skipAct--;
      return;
    }
    /*
    // If dog sees the cat, he turns toward the cat
    int dist = getX() - cg.getCat().getX();
    if (dist > 0 && cg.getCat().getY() == 235)
      turnLeft();
    else
      turnRight();
     */
  }

  public int collide(Actor actor, Location location)
  {
    if (location.equals(new Location(33)) ||
      location.equals(new Location(113)))
      turnRight();
    if (location.equals(new Location(103)) ||
      location.equals(new Location(203)))
     turnLeft();
    skipAct = 80;
    return 0;
  }

  private void turnRight()
  {
    setDirection(0);
    setHorzMirror(false);
  }

  private void turnLeft()
  {
    setDirection(180);
    setHorzMirror(true);
  }
}

// ----------------------- class Fly --------------------------------------
class Fly extends Actor
{
  private CatGame cg;

  public Fly(CatGame cg)
  {
    super(true"sprites/fly1.gif");
    this.cg = cg;
  }

  public void act()
  {
    setDirection(225 + 90 * Math.random());
    move();
    if (getY() < 10)
      removeSelf();
  }

  public int collide(Actor a1, final Actor a2)
  {
    cg.increaseEatenFlies();
    a2.setVisible(1true);
    cg.refresh();
    new Thread()
    {
      public void run()
      {
        delay(400);
        a2.setVisible(0true);
      }
    }.start();
    removeSelf();
    return 0;
  }
}