Objectives include:
In this project you will write a program for a simple game. Project 3 will be a more sophisticated version of this game.
In this game there will be a runner and a chaser. The computer will control the chaser, which should always move toward the runner. The user (you) will control the runner by keyboard input. The goal is to keep away from the chaser for a short amount of time.
This project will involve graphics and animation. Here an example of playing the game. The user is controlling the movement of the runner, the green square.
Below is an initial, incomplete class for you to start with. It contains an incomplet main method.
import java.util.*;
import java.awt.*;
public class SurvivorI {
public static void main(String[] args) {
// Create DrawingPanel and draw a box in the panel.
// The box is a square of this size.
int boxSize = 760;
DrawingPanel panel = new DrawingPanel(800, 800);
Graphics g = panel.getGraphics();
g.fillRect(10, 10, 10, 780);
g.fillRect(10, 10, 780, 10);
g.fillRect(780, 10, 10, 780);
g.fillRect(10, 780, 780, 10);
// Initialize positions of runner and chaser.
Point runner = new Point(200, 400);
Point chaser = new Point(600, 400);
// Variable for input from user to move runner.
char keyInput = ' ';
// The program should wait sleepTime ms between moves.
int sleepTime = 100;
// The runner should move moveSize (or zero) pixels each time step.
// The chaser should move moveSize - 1 pixels each time step.
int moveSize = 10;
// Display players using Color.GREEN and Color.RED (or whatever colors you want).
displayPlayers(panel, runner, chaser);
// Wait one second before start of game.
panel.sleep(1000);
// NEED TO PUT SOME OF THESE STATEMENTS IN A FOR LOOP
// Erase players from the panel using Color.WHITE.
erasePlayers(panel, runner, chaser);
// Get input from user if any.
char newKeyInput = panel.getKeyChar();
if (newKeyInput == 'w' || newKeyInput == 'a' || newKeyInput == 's' || newKeyInput == 'd') {
keyInput = newKeyInput;
}
// Move the players according to parameters.
movePlayers(runner, chaser, keyInput, boxSize, moveSize);
// Display players using Color.GREEN and Color.RED (or whatever colors you want).
displayPlayers(panel, runner, chaser);
// Game is over if the chaser catches up to the runner.
if (collision(runner, chaser)) {
System.out.println("YOU LOST!!!");
}
// Wait sleepTime ms between moves.
panel.sleep(sleepTime);
// NEED AN IF STATEMENT TO DETERMINE WHEN TO PRINT THIS.
System.out.println("YOU WON!!!");
}
}
The program uses a DrawingPanel to show the runner and chaser and the box that confines them.
A Point is a convenient way to store a pair of values X and Y. For example, runner.getX() is initially equal to 200, and runner.getY() is initially equal to 400. The other method you will need to use is translate, for example, runner.translate(1,-1) would add 1 to the X value and subtract 1 from the Y value. The program also uses a Point to store the coordinates of the chaser.
The runner should be controlled using the WASD keys on the keyboard. 'w' means go up. 'a' means go left. 's' means go down. 'd' means go right. The last 'w', 'a', 's', or 'd' character is stored in keyInput.
To control the rate of animation, the program needs to wait between moves (a time step). The variable sleepTime indicates how long to wait. Waiting 100 milliseconds each time step is not short enough for smooth animation, but should be good for debugging.
The moveSize variable indicates how many pixels the runner moves each time step. The chaser needs to move slightly slower, otherwise the chaser can easily corner the runner.
The displayPlayers method should draw the runner and the chaser on the panel.
public static void displayPlayers(DrawingPanel panel, Point runner, Point chaser)
displayPlayers should use the getGraphics method of DrawingPanel and the setColor and fillRect methods of Graphics. The runner should be a 10x10 filled rectangle using Color.GREEN. The chaser should be a 10x10 filled rectangle using Color.RED. You can choose different colors if you like.
The erasePlayers method should erase the runner and the chaser on the panel. This is in preparation for drawing the runner and chaser in new positions.
public static void erasePlayers(DrawingPanel panel, Point runner, Point chaser)
displayPlayers should use the getGraphics method of DrawingPanel and the setColor and fillRect methods of Graphics. The runner should be erased with a 10x10 filled rectangle using Color.WHITE. The chaser should be erased with a 10x10 filled rectangle using Color.WHITE. It might be interesting to choose different light colors to show the paths of the runner and chaser.
The movePlayers method is the most important and most involved method of the game.
public static void movePlayers(Point runner, Point chaser, char keyInput, int boxSize, int moveSize)
A move by the runner means using the translate to change either the x or y coordinate of the runner, but not both. A single move of moveSize pixels must be one of:
The runner's move is determined by keyInput as described above. The runner should not be allowed to go into the box boundary; in this case, the runner should not move at all. It is recommended that you define two additional methods: a method that determines whether a move is legal and another that performs the runner's move if it is legal.
A move by the chaser means using the translate method to change the x or y coordinate of the chaser, but not both. A single move of moveSize - 1 pixels must be up, down, left, or right. For example, chaser.translate(0, -(moveSize - 1)) would move the chaser up. The move of the chaser is determined by choosing the move (out of the four possible moves) that gets the chaser chosest to the runner. The chaser should not be allowed to go into the box boundary; in this case, the chaser should not move at all. It is recommended that you define two additional methods: one for determining the distance between two points and another for performing the move using the distance method and the legal method described above.
The distance between two Points point1 and point2 is:
the square root of ( ( point1.getX() - point2.getX()) 2 + ( point1.getY() - point2.getY()) 2 )
The collision method determines whether the chaser has caught up to the runner.
public static boolean collision(Point runner, Point chaser)
This method should return true if the two players touch or intersect each other, if runner.getX() is close enough to chaser.getX(), and if runner.getY() is close enough to chaser.getY().
The main method need a for loop that runs the game for 300 time steps. However, if a collision occurs, use a break statement to end the loop early.
The main method currently has fixed values for boxSize, moveSize, and sleepTime. The user should be asked for these values using a single prompt.
Enter the box size, move size, and sleep time: 760 10 100
If the user enters a 0 or negative number, use the default value for that variable. Other magic numbers in the main method might need to replaced with appropriate expressions to take the user's inputs into account.
Add a statement at beginning printing (with appropriate substitutions):
Project 2 written by YOUR NAME
Initially define stubs for the methods you need to code. Compiling and running should show a window with a box that has a 10 pixel boundary
Define the displayPlayers and erasePlayers methods. erasePlayers should be about the same code as displayPlayers expect that erasePlayers uses Color.WHITE. Compiling and running should show a small green box and small red box at the specified positions.
Write code for the main method and movePlayers method so that the user can control the motion of the runner. Leave the code for the chaser for later.
Write the code for the collision method so it returns true if the runner collides with the chaser. This method should also return true if the runner "sideswipes" the chaser. Add a break statement to the if block so that the loop ends. Add a boolean variable and an if statement to ensure that YOU WON!!! is not printed out after YOU LOST!!!.
Write code in the movePlayers method to control the movement of the chaser. It will be better to make this a separate method called by movePlayers.
Modify the main method so that the user can enter the values of boxSize, moveSize and sleepTime on a single line. If a zero or negative number is entered, set the corresponding variable to its default value, that is, the ones shown in the main method above. Obviously, the size of the box should depend on boxSize, but the size of the panel and the initial positions of the runner and chaser should also depend on boxSize.