Question: Lab 9 Lab 9 is for partially implementing this game. The goal of Lab 9 is to implement the game with a user-specifed number of
Lab 9
Lab 9 is for partially implementing this game.
The goal of Lab 9 is to implement the game with a user-specifed number of zombies. Lab 9 does not require a chaser. Lab 9 also does not require user-specified values for box size, move size, and sleep time. You may implement these elements in Lab 9 if you wish, but credit for them will be given in your Project 3 score.
Lab 9 should prompt the user for the number of zombies as follows:
Enter the number of zombies: 10
Suppose this value is stored in numZombies. Then your program will need to create an array of Points:
Point[] zombies = new Point[numZombies];
Each element of the array needs to initialized to a Point object. If i is an int that is greater or equal to 0, and is less than numZombies, then the following initializes the array at index i to a Point with coordinates X=600 and Y=400:
zombies[i] = new Point(600,400);
This needs to be done for every value of i from 0 to numZombies-1.
Rather than putting each zombie at the same location, the coordinates should be random. The X and Y coordinates for each zombie should be random values between 30 and 770.
In the starter code, the variable zombie appears in the while loop and in methods. Because there are numZombies zombies, each of these appearances need to be replaced with a loop over the zombies array:
for (int i = 0; i < numZombies; i++) {
Point zombie = zombies[i];
// do stuff to zombie
}
In Lab 9, a collision between the runner and any zombie should result in setting gameOver to true. In Project 3, we will worry about making sure that all the zombies are eliminated before the game is over.
As in Project 2, this game will have a runner and a chaser. The new element in this game is that the game will include zombies. A zombie moves in a random walk (see Lab 7). The object of the game is for the runner to eliminate all the zombies (by colliding with them) and to avoid being caught by the chaser. The runner wins when all the zombies are eliminated. The runner loses if the chaser catches the runner before all the zombies have been eliminated.
Running the starter code for SurvivorII.java shows how the game works with one zombie and no chaser. Note that you also need DrawingPanel.java for this project. Also note that the game does not start until the user has entered a move.
Base code for lab 9:
import java.util.*; import java.awt.*; public class SurvivorII { public static final int PLAYER_SIZE = 10; public static void main(String[] args) { // Create DrawingPanel and draw a box in the panel. int boxSize = 760; DrawingPanel panel = new DrawingPanel(boxSize + 40, boxSize + 40); Graphics g = panel.getGraphics(); g.fillRect(10, 10, 10, boxSize + 20); g.fillRect(10, 10, boxSize + 20, 10); g.fillRect(boxSize + 20, 10, 10, boxSize + 20); g.fillRect(10, boxSize + 20, boxSize + 20, 10); // Initialize positions of runner, chasers, and zombies. Random random = new Random(); Point runner = new Point(200, 400); Point chaser = new Point(300, 300); Point zombie; do { zombie = new Point(random.nextInt(760) + 20, random.nextInt(760) + 20); } while (legal(zombie, 0, 0, boxSize) && collision(runner, zombie)); // Need boolean to keep track of whether zombie is caught boolean eliminated = false; // 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 and Color.BLUE (or whatever colors you want). displayPlayers(panel, runner, chaser, zombie); // Wait one second before start of game. panel.sleep(1000); // Wait until a character is entered keyInput = panel.getKeyChar(); while (keyInput == 0) { keyInput = panel.getKeyChar(); } // use a boolean to indicate when the game is lost boolean lost = false; boolean gameOver = false; while (!gameOver) { // Erase players from the panel using Color.WHITE. erasePlayers(panel, runner, chaser, zombie); // 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, zombie, eliminated, keyInput, boxSize, moveSize); // Display players using Color.GREEN and Color.RED (or whatever colors you want). displayPlayers(panel, runner, chaser, zombie); // Game is over if the runner collides with chaser or zombie. if (collision(runner, chaser)) { System.out.println("YOU LOST!!!"); lost = true; break; } if (collision(runner, zombie)) { eliminated = true; gameOver = true; } if (lost) break; // Wait sleepTime ms between moves. panel.sleep(sleepTime); } if (! lost) { System.out.println("YOU WON!!!"); } } public static void displayPlayers(DrawingPanel panel, Point runner, Point chaser, Point zombie) { Graphics g = panel.getGraphics(); g.setColor(Color.GREEN); g.fillRect((int)runner.getX() - PLAYER_SIZE / 2, (int)runner.getY() - PLAYER_SIZE / 2, PLAYER_SIZE, PLAYER_SIZE); g.setColor(Color.BLUE); g.fillRect((int)zombie.getX() - PLAYER_SIZE / 2, (int)zombie.getY() - PLAYER_SIZE / 2, PLAYER_SIZE, PLAYER_SIZE); } public static void erasePlayers(DrawingPanel panel, Point runner, Point chaser, Point zombie) { Graphics g = panel.getGraphics(); g.setColor(Color.WHITE); // erase runner g.fillRect((int)runner.getX() - PLAYER_SIZE / 2, (int)runner.getY() - PLAYER_SIZE / 2, PLAYER_SIZE, PLAYER_SIZE); // erase zombie g.fillRect((int)zombie.getX() - PLAYER_SIZE / 2, (int)zombie.getY() - PLAYER_SIZE / 2, PLAYER_SIZE, PLAYER_SIZE); } public static void movePlayers(Point runner, Point chaser, Point zombie, boolean eliminated, char keyInput, int boxSize, int moveSize) { moveZombie(zombie, eliminated, boxSize, moveSize); processKeyInput(runner, keyInput, boxSize, moveSize); } public static boolean legal(Point p, int dx, int dy, int boxSize) { return p.getX() + dx + PLAYER_SIZE / 2 < 780 && p.getX() + dx - PLAYER_SIZE / 2 > 20 && p.getY() + dy + PLAYER_SIZE / 2 < 780 && p.getY() + dy - PLAYER_SIZE / 2 > 20; } public static double distance(Point p1, Point p2) { return Math.sqrt( (p1.getX()- p2.getX()) * (p1.getX() - p2.getX()) + (p1.getY() - p2.getY()) * (p1.getY() - p2.getY()) ); } public static double distance(Point p1, Point p2, int dx, int dy) { return Math.sqrt( (p1.getX()- p2.getX() - dx) * (p1.getX() - p2.getX() - dx) + (p1.getY() - p2.getY() - dy) * (p1.getY() - p2.getY() - dy) ); } public static void moveZombie(Point zombie, boolean eliminated, int boxSize, int moveSize) { int[] dxs = { 0, 0, moveSize, -moveSize }; int[] dys = { moveSize, -moveSize, 0, 0 }; Random random = new Random(); if (! eliminated) { int di = random.nextInt(4); int dx = dxs[di]; int dy = dys[di]; if (legal(zombie, dx, dy, boxSize)) { zombie.translate(dx, dy); } } } public static void moveChaser(Point runner, Point chaser, Point zombie, boolean eliminated, int boxSize, int moveSize) { } public static void processKeyInput(Point runner, char keyInput, int boxSize, int moveSize) { int[] dxs = { 0, 0, moveSize, -moveSize }; int[] dys = { moveSize, -moveSize, 0, 0 }; char[] keys = { 's', 'w', 'd', 'a' }; for (int i = 0; i < dxs.length; i++) { int dx = dxs[i]; int dy = dys[i]; char key = keys[i]; if (keyInput == key && legal(runner, dx, dy, boxSize)) { runner.translate(dx, dy); } } } public static boolean collision(Point runner, Point chaser) { return Math.max( Math.abs(runner.getX() - chaser.getX()), Math.abs(runner.getY() - chaser.getY())) <= PLAYER_SIZE; } }
drawing panel code:
/* Stuart Reges and Marty Stepp February 24, 2007 Changes by Tom Bylander in 2010 (no anti-alias, repaint on sleep) Changes by Tom Bylander in 2012 (track mouse clicks and movement) Changes by Tom Bylander in 2013 (fix bug in tracking mouse clicks) Changes by S. Robbins in 2014 (getters for width and height) Changes by S. Robbins in 2014 (addKeyListener added) Changes by S. Robbins in 2014 (catch exception on default close so that it works in an applet) Changes by S. Robbins in 2015 (buffer key events) Changes by S. Robbins in 2015 (show mouse status by default is off) The DrawingPanel class provides a simple interface for drawing persistent images using a Graphics object. An internal BufferedImage object is used to keep track of what has been drawn. A client of the class simply constructs a DrawingPanel of a particular size and then draws on it with the Graphics object, setting the background color if they so choose. To ensure that the image is always displayed, a timer calls repaint at regular intervals. */ import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import javax.swing.event.*; import java.util.ArrayList; public class DrawingPanel implements ActionListener { private static final String versionMessage = "Drawing Panel version 1.1, January 25, 2015"; private static final int DELAY = 100; // delay between repaints in millis private static final boolean PRETTY = false; // true to anti-alias private static boolean showStatus = false; private static final int MAX_KEY_BUF_SIZE = 10; private int width, height; // dimensions of window frame private JFrame frame; // overall window frame private JPanel panel; // overall drawing surface private BufferedImage image; // remembers drawing commands private Graphics2D g2; // graphics context for painting private JLabel statusBar; // status bar showing mouse position private volatile MouseEvent click; // stores the last mouse click private volatile boolean pressed; // true if the mouse is pressed private volatile MouseEvent move; // stores the position of the mouse private ArrayList keys; // construct a drawing panel of given width and height enclosed in a window public DrawingPanel(int width, int height) { this.width = width; this.height = height; keys = new ArrayList(); image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); statusBar = new JLabel(" "); statusBar.setBorder(BorderFactory.createLineBorder(Color.BLACK)); statusBar.setText(versionMessage); panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)); panel.setBackground(Color.WHITE); panel.setPreferredSize(new Dimension(width, height)); panel.add(new JLabel(new ImageIcon(image))); click = null; move = null; pressed = false; // listen to mouse movement MouseInputAdapter listener = new MouseInputAdapter() { public void mouseMoved(MouseEvent e) { pressed = false; move = e; if (showStatus) statusBar.setText("moved (" + e.getX() + ", " + e.getY() + ")"); } public void mousePressed(MouseEvent e) { pressed = true; move = e; if (showStatus) statusBar.setText("pressed (" + e.getX() + ", " + e.getY() + ")"); } public void mouseDragged(MouseEvent e) { pressed = true; move = e; if (showStatus) statusBar.setText("dragged (" + e.getX() + ", " + e.getY() + ")"); } public void mouseReleased(MouseEvent e) { click = e; pressed = false; if (showStatus) statusBar.setText("released (" + e.getX() + ", " + e.getY() + ")"); } public void mouseEntered(MouseEvent e) { // System.out.println("mouse entered"); panel.requestFocus(); } }; panel.addMouseListener(listener); panel.addMouseMotionListener(listener); new DrawingPanelKeyListener(); g2 = (Graphics2D)image.getGraphics(); g2.setColor(Color.BLACK); if (PRETTY) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke(new BasicStroke(1.1f)); } frame = new JFrame("Drawing Panel"); frame.setResizable(false); try { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // so that this works in an applet } catch (Exception e) {} frame.getContentPane().add(panel); frame.getContentPane().add(statusBar, "South"); frame.pack(); frame.setVisible(true); toFront(); frame.requestFocus(); // repaint timer so that the screen will update new Timer(DELAY, this).start(); } public void showMouseStatus(boolean f) { showStatus = f; } public void addKeyListener(KeyListener listener) { panel.addKeyListener(listener); panel.requestFocus(); } // used for an internal timer that keeps repainting public void actionPerformed(ActionEvent e) { panel.repaint(); } // obtain the Graphics object to draw on the panel public Graphics2D getGraphics() { return g2; } // set the background color of the drawing panel public void setBackground(Color c) { panel.setBackground(c); } // show or hide the drawing panel on the screen public void setVisible(boolean visible) { frame.setVisible(visible); } // makes the program pause for the given amount of time, // allowing for animation public void sleep(int millis) { panel.repaint(); try { Thread.sleep(millis); } catch (InterruptedException e) {} } // close the drawing panel public void close() { frame.dispose(); } // makes drawing panel become the frontmost window on the screen public void toFront() { frame.toFront(); } // return panel width public int getWidth() { return width; } // return panel height public int getHeight() { return height; } // return the X position of the mouse or -1 public int getMouseX() { if (move == null) { return -1; } else { return move.getX(); } } // return the Y position of the mouse or -1 public int getMouseY() { if (move == null) { return -1; } else { return move.getY(); } } // return the X position of the last click or -1 public int getClickX() { if (click == null) { return -1; } else { return click.getX(); } } // return the Y position of the last click or -1 public int getClickY() { if (click == null) { return -1; } else { return click.getY(); } } // return true if a mouse button is pressed public boolean mousePressed() { return pressed; } public synchronized int getKeyCode() { if (keys.size() == 0) return 0; return keys.remove(0).keyCode; } public synchronized char getKeyChar() { if (keys.size() == 0) return 0; return keys.remove(0).keyChar; } public synchronized int getKeysSize() { return keys.size(); } private synchronized void insertKeyData(char c, int code) { keys.add(new KeyInfo(c,code)); if (keys.size() > MAX_KEY_BUF_SIZE) { keys.remove(0); // System.out.println("Dropped key"); } } private class KeyInfo { public int keyCode; public char keyChar; public KeyInfo(char keyChar, int keyCode) { this.keyCode = keyCode; this.keyChar = keyChar; } } private class DrawingPanelKeyListener implements KeyListener { int repeatCount = 0; public DrawingPanelKeyListener() { panel.addKeyListener(this); panel.requestFocus(); } public void keyPressed(KeyEvent event) { // System.out.println("key pressed"); repeatCount++; if ((repeatCount == 1) || (getKeysSize() < 2)) insertKeyData(event.getKeyChar(),event.getKeyCode()); } public void keyTyped(KeyEvent event) { } public void keyReleased(KeyEvent event) { repeatCount = 0; } } } Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
