java游戏编程案例
[Please read all 3 pages of this document first]
COSC1519 Introduction To Programming java游戏编程案例
Assignment 2: Investigative Debugging/Development of a Partially Complete Java Application 案例java游戏编程
[spec 2019.04.08; check for updates]
[The penalties for breaching academic integrity are severe – they include charges of academic misconduct, 案例java游戏编程 cancellation of results and exclusion from your course – Please see Academic Integrity page for further info – Do not even show your code to other students]
Important:
First, watch the video of the gameplay. You are awarded marks for concisely and sensibly demonstrating/ concepts covered in class materials for meeting every requirement in that video and in this specification document. If something is written, there are marks associated with it. Official clarifications will only be made via the relevant forums in Canvas→Discussions.java游戏编程案例
1. Background and basics:
You are employed as a programmer by a game developer and, being a fan of programming, you are excited to give your new job your 100% or more. You learn that your first task on the job is to revive a game project named ‘AVIANIGHTMARE’ that has been abandoned by your predecessor who mysteriously disappeared without a trace.java游戏编程案例
java游戏编程案例java游戏编程案例[Box art of game]
The game was written in Java and was made up of several classes and image files. Many of the source code files for these classes are now missing and you will need to examine what ever that is left of the code (see section 4 of this document) to reconstruct the missing classes and complete the game as originally intended by the company. You must not alter the provided code in any way (not even image paths) unless you want a significant salary cut (a.k.a. a loss of marks). Thankfully, your predecessor made the short video of the gameplay before they disappeared and you can see how the game was intended to operate.java游戏编程案例
Although this is an assignment, you must consider yourself as a professional programmer and Daryl and Gayan as your employers. It is expected that you will need to independently investigate things such as what types of data some of the provided methods might need, etc. in the Java API Specification and other resources. As it is the case with real-world projects, not everything will be clear at various stages and you are expected to seek clarifications from Daryl or Gayan via the relevant Canvas→Discussion forums. Consider going to the consultation, remedial sessions and mentoring (see Canvas→Announcements for details).java游戏编程案例
2. Requirements, guidelines and tips:
Start off by creating a new Eclipse project for your assignment and add the two classes provided in this document (see section 5) in to separate class files. You must never change even a single line of code in the GameManager.java or the Goal.java. If you do, it is considered altering the assignment requirements/tasks and will result in your submission being rejected for equitable marking (zero marks).java游戏编程案例
Errors are like good friends; they tell you what needs to be fixed. After #1 above, on a need to have basis, add the necessary code to yourEclipse project java游戏编程案例 so that you will not get syntax errors (red dots) manifest in the The code that you produce on your own will involve creating new classes, constructors, methods, object properties, etc. by following the good OO design and coding practices explained further below.
When you place the cursor/mouse pointer over a red underline of an error, Eclipse usually has good recommendations for corrections but as the programmer, you must exercise your judgment and make sure the corrections are consistent with the assignment requirements. The Goal class is provided for further guidance on how to write your part of the code but you must not simply add everything in the Goal class to the other classes you create (i.e. must add code only on a need to have basis).java游戏编程案例
Once you fix the syntax errors, run the program. It will then produce run-time errors in a format similar to the following hypothetical errormessage:
Exception in thread “main” java.lang.NullPointerException at GameManager.updateCanvas(GameManager.java:105) at GameManager.(GameManager.java:84)
at GameManager.main(GameManager.java:33)
You must then proceed to the first line number indicated in the run-time error message (e.g. 105 in the above example but your numbers and specifics might be different) and see what you need to implement next to get the program to work. Repeat this process until all issues are resolved and there are not more red dots. Remember to refer to the video of how the game is required to function and match the provided Goal.java when required.java游戏编程案例
You must extract the image files provided in the zip file under Canvas→Assignments→Assignment 2 and copy them to your Eclipse project folder (not in ‘src’). In the various ImageIO.read… statements, only the file name must be mentioned (like how it is currently done in Goal.java) so that your code will work on any computer. Your code must not have folder java游戏编程案例
The code that you write must follow the following good object oriented design practices:
Every method must have exactly one return statement and this must be the last statement in the
All classes must have object member variables and they must be explicitly private and non-static.There should be no = (equals) signs where member variables are All member variables must be explicitly initialised in the constructor. Whenever a method refers to a member variable, it should use this. (i.e. “this dot”, e.g. this.x).
Aside from the main method in the GameManager, there should be no other main
Allmethods that the student must write must be explicitly public and not Student’s code must no have any methods not required by the GameManager.java游戏编程案例
In addition to the above, the code that you write must follow good codingpractices:
Your code must be formatted consistently and follow common conventions demonstrated inOracle Java Tutorials. g. use Eclipse→Source menu→Format.
Names of identifiers that you can choose must follow common conventions demonstrated inOracle Java API specification
Write plain-English comments next to important variables and at the start ofblocks and explain their intended purpose in the program. You must not have any question text, unused code within your .java files even if they are inside comments. The submitted version should be a final product.
Explain in your comments what other options would have been possible (e.g. with variables, discuss which data typeyou used and what else might have been possible/impossible. With blocks, what alternative orderings may have been possible, etc.) Do not assume that the reader can figure these
If you have any unresolved bugs, you must document these in the approximate locations they originate within your If you do not have bugs, you must explicitly say that there are none. Note: Being able to recognise bugs is a good thing.
Do not use break, continue, static, exit… and similar statements. Code must have good variableand identifier names, comments and presentation (source menu→format).
Ifyour code has run-time issues or if it cannot be compiled (has red dots anywhere) for any delivery, you will receive a 50% penalty for that
Follow the example of Goal.java when writing your code but some changes will be necessary as needed by the rest of the requirements in this document.
At all times, you must follow java游戏编程案例 good coding practices and aim to make your code efficient.
When in doubt, you are required to ask either Daryl or Gayan via the relevant Canvas→Discussions forums. Clarifications will not be made via email as it is not
3. Deliveries and submissions:
Your “employer” requires you to perform two deliveries of your work. There are three important dates/actions to remember.
Delivery 1 (3.75 marks): Submit all .java files that you created for A2 except for java and Goal.
java via Canvas→Assignments→Assignment 2 then demo the whole set of files during your allocated practical in week 10, using your own computers. java游戏编程案例 For this delivery, you are only required to eliminate red dots shown by Eclipse. There is no need to implement any further behaviours or fix run-timeissues.
Delivery 2 (6.25 marks): Submit a fully complete set of files except for java and Goal.
Java by Sunday of week 11 (before Monday of week 12).via Canvas→Assignments→.Assignment 2 and then demo the work that you have done after delivery 1, during your allocated practical in week 12. java游戏编程案例 Note: Your GameManager.java and Goal.java will be replaced for marking. The marks breakdown for delivery 2 is asfollows:
5 marks for work done since delivery 1 (code must be submitted via Canvas→Assignments→Assingnment2)
75 marks for demonstrating all of the concepts required after delivery 1,during the week 12 demo in the allocated prac.
Notes: A submission with no demonstration will not attract marks. It is fine if files are automatically renamed by Canvas.
If you wish to organise special consideration, please follow the instructions below: https://www.rmit.edu.au/students/student-essentials/assessment-and-exams/assessment/special-consideration
4. Existing code that you must use without making changes:
For your convenience, the GameManager.java and Goal.java files can be found under Canvas→Assignments→Assignment 2. You must not modify these files (must not even add package fields). As a risk minimisation measure, periodically replace your GameManager.java and Goal.java code with the code that is provided.
JAVA code
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.Font;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class GameManager extends JFrame implements KeyListener {
private int canvasWidth;
private int canvasHeight;
private int borderLeft;
private int borderTop;
private BufferedImage canvas;
private Stage stage;
private Enemy[] enemies;
private Player player;
private Goal goal;
private Graphics gameGraphics;
private Graphics canvasGraphics;
private int numEnemies;
private boolean continueGame;
public static void main(String[] args) {
// During development, you can adjust the values provided in the brackets below
// as needed. However, your code must work with different/valid combinations
// of values.
int choice;
do{
GameManager managerObj = new GameManager(1920, 1080);
choice=JOptionPane.showConfirmDialog(null,"Play again?", "", JOptionPane.OK_CANCEL_OPTION);
}while(choice==JOptionPane.OK_OPTION);
System.exit(0);
}
public GameManager(int preferredWidth, int preferredHeight) {
int maxEnemies;
try{
maxEnemies=Integer.parseInt(JOptionPane.showInputDialog("How many enemies? (Default is 5)"));
if (maxEnemies<0) maxEnemies=5; } catch (Exception e){ maxEnemies=5; } this.borderLeft = getInsets().left; this.borderTop = getInsets().top; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); if (screenSize.width < preferredWidth) this.canvasWidth = screenSize.width - getInsets().left - getInsets().right; else this.canvasWidth = preferredWidth - getInsets().left - getInsets().right; if (screenSize.height < preferredHeight) this.canvasHeight = screenSize.height - getInsets().top - getInsets().bottom; else this.canvasHeight = preferredHeight - getInsets().top - getInsets().bottom; setSize(this.canvasWidth, this.canvasHeight); setResizable(false); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); addKeyListener(this); Random rng = new Random(); this.canvas = new BufferedImage(this.canvasWidth, this.canvasHeight, BufferedImage.TYPE_INT_RGB); // Create a Stage object to hold the background images this.stage = new Stage(); // Create a Goal object with its initial x and y coordinates this.goal = new Goal((Math.abs(rng.nextInt()) % (this.canvasWidth)), (Math.abs(rng.nextInt()) % this.canvasHeight)); // Create a Player object with its initial x and y coordinates this.player = new Player((Math.abs(rng.nextInt()) % (this.canvasWidth)), (Math.abs(rng.nextInt()) % this.canvasHeight)); // Create the Enemy objects, each with a reference to this (GameManager) object // and their initial x and y coordinates. this.numEnemies = maxEnemies; this.enemies = new Enemy[this.numEnemies]; for (int i = 0; i < this.numEnemies; i++) { this.enemies[i] = new Enemy(this, Math.abs(rng.nextInt()) % (this.canvasWidth), Math.abs(rng.nextInt()) % this.canvasHeight); } this.gameGraphics = getGraphics(); this.canvasGraphics = this.canvas.getGraphics(); this.continueGame = true; long gameStartTime=System.nanoTime(); while (this.continueGame) { updateCanvas(); } this.stage.setGameOverBackground(); double gameTime=(System.nanoTime()-gameStartTime)/1000000000.0; updateCanvas(); this.gameGraphics.setFont(new Font(this.gameGraphics.getFont().getFontName(), Font.PLAIN, 50)); if (gameTime<1) this.gameGraphics.drawString("Oops! Better luck next time...", this.canvasWidth/3, this.canvasHeight/2 - 50); else this.gameGraphics.drawString("You survived " + String.format("%.1f", gameTime)+ " seconds with "+this.numEnemies+" enemies!", this.canvasWidth/4, this.canvasHeight/2 - 50); return; } public void updateCanvas() { long start = System.nanoTime(); this.goal.performAction(); // If the player is alive, this should move the player in the direction of the // key that has been pressed // Note: See keyPressed and keyReleased methods in the GameManager class. this.player.performAction(); // If the enemy is alive, the enemy must move towards the Player. The Player object // is obtained via the GameManager object that is given at the time of creating an Enemy // object. // Note: The amount that the enemy moves by must be much smaller than that of // the player above or else the game becomes too hard to play. for (int i = 0; i < this.numEnemies; i++) { this.enemies[i].performAction(); } if ((Math.abs(this.goal.getX() - this.player.getX()) < (this.goal.getCurrentImage().getWidth() / 2)) && (Math.abs(this.goal.getY() - this.player.getY()) < (this.goal.getCurrentImage().getWidth() / 2))) { for (int i = 0; i < this.numEnemies; i++) { // Sets the image of the enemy to the "dead" image and sets its status to // indicate dead this.enemies[i].die(); } // Sets the background of the stage to the finished game background. this.stage.setGameOverBackground(); this.continueGame = false; } // If an enemy is close to the player or the goal, the player and goal die int j = 0; while (j < this.numEnemies) { if ((Math.abs(this.player.getX() - this.enemies[j].getX()) < (this.player.getCurrentImage().getWidth() / 2)) && (Math.abs(this.player.getY() - this.enemies[j].getY()) < (this.player.getCurrentImage().getWidth() / 2))) { this.player.die(); this.goal.die(); this.stage.setGameOverBackground(); j = this.numEnemies; this.continueGame = false; } else if ((Math.abs(this.goal.getX() - this.enemies[j].getX()) < (this.goal.getCurrentImage().getWidth() / 2)) && (Math.abs(this.goal.getY() - this.enemies[j].getY()) < (this.goal.getCurrentImage().getWidth() / 2))) { this.player.die(); this.goal.die(); this.stage.setGameOverBackground(); j = this.numEnemies; this.continueGame = false; } j++; } try { // Draw stage this.canvasGraphics.drawImage(stage.getCurrentImage(), 0, 0, null); // Draw goal this.canvasGraphics.drawImage(this.goal.getCurrentImage(), this.goal.getX() - (this.goal.getCurrentImage().getWidth() / 2), this.goal.getY() - (this.goal.getCurrentImage().getHeight() / 2), null); // Draw player this.canvasGraphics.drawImage(player.getCurrentImage(), this.player.getX() - (this.player.getCurrentImage().getWidth() / 2), this.player.getY() - (this.player.getCurrentImage().getHeight() / 2), null); // Draw enemies for (int i = 0; i < this.numEnemies; i++) { this.canvasGraphics.drawImage(this.enemies[i].getCurrentImage(), this.enemies[i].getX() - (this.enemies[i].getCurrentImage().getWidth() / 2), this.enemies[i].getY() - (this.enemies[i].getCurrentImage().getHeight() / 2), null); } } catch (Exception e) { System.err.println(e.getMessage()); } // Draw everything. this.gameGraphics.drawImage(this.canvas, this.borderLeft, this.borderTop, this); long end = System.nanoTime(); this.gameGraphics.setFont(new Font(this.gameGraphics.getFont().getFontName(), Font.PLAIN, 15)); this.gameGraphics.drawString("FPS: " + String.format("%2d", (int) (1000000000.0 / (end - start))), this.borderLeft + 50, this.borderTop + 75); return; } public Player getPlayer() { return this.player; } public void keyPressed(KeyEvent ke) { // Below, the setKey method is used to tell the Player object which key is // currently pressed. // The Player object must keep track of the pressed key and use it for // determining the direction // to move. // Important: The setKey method in Player must not move the Player. if (ke.getKeyCode() == KeyEvent.VK_LEFT) this.player.setKey('L', true); if (ke.getKeyCode() == KeyEvent.VK_RIGHT) this.player.setKey('R', true); if (ke.getKeyCode() == KeyEvent.VK_UP) this.player.setKey('U', true); if (ke.getKeyCode() == KeyEvent.VK_DOWN) this.player.setKey('D', true); if (ke.getKeyCode() == KeyEvent.VK_ESCAPE) this.continueGame = false; return; } @Override public void keyReleased(KeyEvent ke) { // Below, the setKey method is used to tell the Player object which key is // currently released. // The Player object must keep track of the pressed key and use it for // determining the direction // to move. // Important: The setKey method in Player must not move the Player. if (ke.getKeyCode() == KeyEvent.VK_LEFT) this.player.setKey('L', false); if (ke.getKeyCode() == KeyEvent.VK_RIGHT) this.player.setKey('R', false); if (ke.getKeyCode() == KeyEvent.VK_UP) this.player.setKey('U', false); if (ke.getKeyCode() == KeyEvent.VK_DOWN) this.player.setKey('D', false); return; } @Override public void keyTyped(KeyEvent ke) { return; } }
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.*;
public class Goal {
private int x;
private int y;
private BufferedImage imageCurrent;
private BufferedImage imageRunning;
private BufferedImage imageOver;
private int stepSize;
private Random rng; // Tip: Code that students write must not use randomness
public Goal(int x, int y) {
try {
this.imageRunning = ImageIO.read(new File("goal-alive.png"));
this.imageOver = ImageIO.read(new File("goal-dead.png"));
} catch (IOException e) {
e.printStackTrace();
}
this.x=x;
this.y=y;
this.stepSize=10;
this.rng=new Random(x+y); // Tip: Code that students write (elsewhere) must not use any randomness.
this.imageCurrent = this.imageRunning;
return;
}
public void performAction() {
// The code below shows how the Goal can be moved by manipulating its x and y coordinates.
// Tip: Code that students write (elsewhere) must not use any randomness.
this.x+= this.rng.nextInt()%stepSize;
this.y+= this.rng.nextInt()%stepSize;
return;
}
public int getX() {
return this.x;
}
public BufferedImage getCurrentImage() {
return this.imageCurrent;
}
public void die() {
this.imageCurrent = this.imageOver;
return;
}
public int getY() {
return this.y;
}
}
java游戏编程案例 AVIANIGHTMARE案例
2020-02-08