Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

Gorilla-Game

Zwei Gorillas bewerfen sich gegenseitig mit Bananen. Dies ist aber nicht so einfach wie es scheint, denn auch der Wind muss berücksichtigt werden. Die Windrichtung und die Windstärke ist aus der Stellung der Fahne (oben Mitte) ersichtlich.

Vor jedem Wurf wird in einer Dialogbox nach dem Wurfwinkel und der Wurfgeschwindigkeit gefragt. Die Wurfbahn wird dann (mehr oder weniger) nach physikalischen Gesetzen berechnet.

 

 

Das Hintergrundbild können Sie selbst hinzufügen. Speichern Sie dazu die Datei TownBig.png unter <userHome>\gamegrid\sprites (TownBig.zip)

Programmcode für lokale Bearbeitung herunterladen: GorillaGame.zip

Programmcode:

// GorillaGame.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import java.awt.Point;
import javax.swing.JOptionPane;

public class GorillaGame extends GameGrid
{
  private WindSock ws = new WindSock();
  private Location[] gorillaLoc =
  {
    new Location(35, 565), new Location(1165, 565)
  };
  private Location[] bananaLunchLoc =
  {
    new Location(70, 535), new Location(1130, 535)
  };
  private Location[] youWinLoc =
  {
    new Location(100, 500), new Location(1100, 500)
  };
  private Gorilla[] players = new Gorilla[2];
  private int currentPlayer = 0;
  private Actor youWin = new Actor("sprites/you_win.gif");
  private boolean gameOver;

  public GorillaGame()
  {
    super(1200, 600, 1, nullnullfalse);
    //super(1200, 600, 1, null, "sprites/townBig.jpg", false);
    setBgColor(35, 186, 255);
    setSimulationPeriod(30);
    addActor(ws, new Location(nbHorzCells / 2, 40));
    for (int = 0; i < 2; i++)
    {
      players[i] = new Gorilla(thisbananaLunchLoc[i], i);
      players[i].addActorCollisionListener(players[i]);
      addActor(players[i], gorillaLoc[i]);
    }
    show();
    doRun();
    while (true)
    {
      ws.setRandomWind();
      players[currentPlayer].lunchBanana();
      while (!getActors(Banana.class).isEmpty())
      {
        if (gameOver)
        {
          addActor(youWin, youWinLoc[currentPlayer]);
          setTitle("Game finished! New game starts in 5 seconds.");
          refresh(); //should not be needed
          delay(5000);
          reset();
        }
        // wait for banana to hit floor or gorilla
      }

      currentPlayer = (currentPlayer + 1) % 2;
    }
  }

  public WindSock getWindSock()
  {
    return ws;
  }

  public Gorilla getEnemyGorilla(int player)
  {
    int enemyNb = (player + 1) % 2;
    return players[enemyNb];
  }

  public void reset()
  {
    removeActors(Banana.class);
    removeActor(youWin);
    getBg().clear();
    gameOver = false;
  }

  public void setGorillaTitle(boolean isRightGorilla)
  {
    if (isRightGorilla)
      setTitle("Gorilla on the right is throwing!");
    else
      setTitle("Gorilla on the left is throwing!");
  }

  public void gorillaWasHit()
  {
    gameOver = true;
  }

  public static void main(String[] args)
  {
    new GorillaGame();
  }
}
// ----------------class Gorilla
class Gorilla extends Actor
{
  private Location lunchLoc;
  private GorillaGame gg;
  private int ownPlayerNb;

  public Gorilla(GorillaGame gg, Location bananaLunchLoc, int playerNb)
  {
    super("sprites/gorilla.png"2);
    this.lunchLoc = bananaLunchLoc;
    this.gg = gg;
    this.ownPlayerNb = playerNb;
    setCollisionCircle(new Point(0, 0), 29);
  }

  public void reset()
  {
    if (isRightGorilla())
      setHorzMirror(true);
  }

  public void lunchBanana()
  {
    gg.setGorillaTitle(isRightGorilla());
    show(1); //show throwing sprite
    double angle = 0, speed = 0;
    while (angle <= || angle >= Math.PI / 2)
      angle = Math.toRadians(requestNumber("Angle (between 0 and 90): "));
    while (speed <= || speed >= 200)
      speed = requestNumber("Speed (between 0 and 200): ");
    double vx = Math.cos(angle) * speed;
    double vy = Math.sin(angle) * speed;
    if (isRightGorilla())
      vx = -vx;
    Banana = new Banana(gg, vx, -vy);
    b.addActorCollisionListener(b);
    b.addCollisionActor(gg.getEnemyGorilla(ownPlayerNb));
    gg.addActor(b, lunchLoc);
    show(0);
  }

  private boolean isRightGorilla()
  {
    return ownPlayerNb == 1;
  }

  private double requestNumber(String prompt)
  {
    double number = 0;
    Boolean invalidEntry = true;
    while (invalidEntry)
    {
      try
      {
        String entry = JOptionPane.showInputDialog(nullprompt, "",
          JOptionPane.PLAIN_MESSAGE);
        number = Double.parseDouble(entry);
        invalidEntry = false;
      }
      catch (NumberFormatException e)
      {
        System.out.println("Entry was not valid!");
      }
      catch (NullPointerException e)
      {
        gg.setTitle("Quiting Game");
        delay(2000);
        System.exit(0);
      }
    }
    return number;
  }
}
// ----------------class Banana -----------------------
class Banana extends Actor
{
  private GorillaGame gg;
  private double vx, vy, x, y;
  private final double speedFactor = 0.1;

  public Banana(GorillaGame gg, double vx, double vy)
  {
    super(true"sprites/banana_0.png");
    this.gg = gg;
    this.vx = vx;
    this.vy = vy;
  }

  public void reset()
  {
    x = getX();
    y = getY();
  }

  /**
   * Banana collides with Gorilla -> current Player wins!
   */
  public int collide(Actor a1, Actor a2)
  {
    gg.gorillaWasHit();
    setActEnabled(false);
    return 0;
  }

  public void act()
  {
    vy = vy + 9.81 * speedFactor;
    vx = vx + gg.getWindSock().getWind() * speedFactor;
    x = + vx * speedFactor;
    y = + vy * speedFactor;
    gg.getBg().drawPoint(new Point((int)x, (int)y));
    setLocation(new Location((int)x, (int)y));
    //that doesn't make much sense physically but looks cool:
    turn(Math.sqrt(vx * vx + vy * vy) * speedFactor * 2);
    if (getY() > gg.getNbVertCells())
      removeSelf();
  }
}
// -------------------class WindSock----------------
class WindSock extends Actor
{
  private static int nrWindStates = 6;
  private int currentWind;

  public WindSock()
  {
    super("sprites/windsock.png"nrWindStates);
  }

  public void setRandomWind()
  {
    //get a number between -5 and 5:
    currentWind = (int)(Math.random() * ((nrWindStates - 1) * 2)) - nrWindStates + 1;
    if (currentWind > 0)
    {
      setHorzMirror(true);
      show(currentWind);
    }
    else
    {
      setHorzMirror(false);
      show(-currentWind);
    }
  }

  public int getWind()
  {
    return currentWind;
  }
}