java javaFX代写: COMP1040 Assignment 2

COMP1040

Programming Fundamentals

Assignment 2

Prepared by Michael Ulpen

August 2017

CONTENTS

Introduction…………………………………………………………………………………………………………………………………………………… 1 GameEngine ………………………………………………………………………………………………………………………………………………… 1

Provided Classes …………………………………………………………………………………………………………………………………………………….. 1

engine.GameEngine ……………………………………………………………………………………………………………………………….. 1 engine.interfaces.IPaintable……………………………………………………………………………………………………………………… 1 engine.interfaces.IUpdatable ……………………………………………………………………………………………………………………. 2 engine.Game …………………………………………………………………………………………………………………………………………. 2 engine.math.Vector2D …………………………………………………………………………………………………………………………….. 2 engine.math.BoundingBox………………………………………………………………………………………………………………………..2

UML Diagram ……………………………………………………………………………………………………………………………………………………….. 3

EcoSim ………………………………………………………………………………………………………………………………………………………… 4

Provided Classes …………………………………………………………………………………………………………………………………………………….. 4

ecosim.game.Main ………………………………………………………………………………………………………………………………….. 4 ecosim.world.Tile ……………………………………………………………………………………………………………………………………. 4 ecosim.world.GrassTile……………………………………………………………………………………………………………………………. 4 ecosim.world.SandTile …………………………………………………………………………………………………………………………….. 4 ecosim.entity.Entity …………………………………………………………………………………………………………………………………. 4 ecosim.entity.GrassTuft …………………………………………………………………………………………………………………………… 4

Required Classes ……………………………………………………………………………………………………………………………………………………. 5

ecosim.game.EcoSim ……………………………………………………………………………………………………………………………… 5 ecosim.entity.Animal ……………………………………………………………………………………………………………………………….. 5 ecosim.entity.Wombat……………………………………………………………………………………………………………………………… 6 ecosim.entity.Snake…………………………………………………………………………………………………………………………………6 ecosim.exception.OutOfBoundsException …………………………………………………………………………………………………. 7

Source Code Documentation …………………………………………………………………………………………………………………………………… 7 UML Diagram ……………………………………………………………………………………………………………………………………………………….. 8

How To Start ………………………………………………………………………………………………………………………………………………… 9 Additions………………………………………………………………………………………………………………………………………………………. 9 Submission Details……………………………………………………………………………………………………………………………………….10 Extensions and Late Submissions …………………………………………………………………………………………………………………. 10 Academic Misconduct ………………………………………………………………………………………………………………………………….. 11 Marking Criteria……………………………………………………………………………………………………………………………………………11

INTRODUCTION

This document describes Assignment 2 for Programming Fundamentals. The assignment will require you to write classes to represent Animals and Plants in an ecosystem simulator, called EcoSim. This will be a graphical application, utilizing your own classes and code with help from a provided game engine. You will be required to demonstrate the use of arrays, inheritance, polymorphism and exception handling.

This document outlines how to use the game engine. Documentation for the game engine may be found in Javadoc format, written as comments in the source code and organized into html files in the doc folder. This document also provides instructions for how to complete the ecosystem simulator.

This assignment is an individual task that will require an individual submission. You will be required to submit this project in week 12 of the study period. In the case that you do not fully understand the assignment, please ask your lecturer.

GAMEENGINE

The assignment files include a GameEngine which will automatically handle graphics, input and object updates. Part of the assignment is learning how to use the provided GameEngine to create a graphical application. There are many classes in the GameEngine and many methods in those classes. You will need to read the source code documentation to get a full understanding of how to use them.

Provided Classes

The following is a summary of some of the important classes that have been provided…

engine.GameEngine

GameEngine manages a resizable array of IPaintable, IUpdatable and ICollidable objects. It also manages the Keyboard, Mouse, GraphicsWindow and Game objects. All methods in the GameEngine are static, which means they can be accessed from anywhere without constructing a GameEngine object.

The following is a list of the most important static methods in the GameEngine:

  •   GameEngine.loadGame(Game g)
    Calls that game’s load method and makes the window visible. It then starts the GameEngine update and paint loops.
  •   GameEngine.add(Object o)
    If the object is an IPaintable, ICollidable and/or IUpdatable, it will be added to the GameEngine’s array and will automatically be painted and updated.
  •   GameEngine.addToBackground(IPaintable p)
    If the object is an IPaintable, ICollidable and/or IUpdatable, it will be added to the GameEngine’s background and will automatically be updated and painted behind other IPaintables.
  •   GameEngine.remove(Object o)
    If the object has been added to the GameEngine it will be removed.
  •   GameEngine.getGameObjs()
    Returns all game objects in the GameEngine’s array.
  •   GameEngine.getGameObjs(String classPath)
    Returns all objects in the GameEngine’s array that are instances of the argument classPath. The classPath must be fully qualified, including the package path. For example, getGameObjs(“ecosim.entity.Wombat”) will return all the Wombat objects in the GameEngine.

    engine.interfaces.IPaintable

    The IPaintable interface has one method, paint(Graphics g). The Entity and Tile classes implement IPaintable and already have a suitable paint method.

1 of 11

engine.interfaces.IUpdatable

The IUpdatable interface has one method, update(long millisElapsed). Entity implements the IUpdatable interface and you will have to write your own update method. This method will be called automatically by the GameEngine 60 times per second.

engine.Game

Game is an abstract class including the following abstract methods:

  •   loadKeyFunctions()
    Creates executable functions and binds them to Keyboard keys.
  •   loadMouseFunctions()
    Creates executable functions and binds them to Mouse buttons.
  •   loadImages()
    Calls ImageLibrary.load(String alias, String imagePath) for each image in the assets folder.
  •   getWinWidth()
    Returns the width of the game window.
  •   getWinHeight()
    Returns the height of the game window.
  •   update(long millisElapsed)
    Updates the state of the game. Any code that should be executed 60 times a second should be added here.

    The above methods will have to be implemented in any class that derives from Game. Game has one non static method, load(), which will automatically call loadImages(), loadMouseFunctions() and loadKeyFunctions().

    engine.math.Vector2D

    A Vector2D contains x and y coordinates. It can be interpreted as a point in space or a direction with an origin. The Vector2D contains the following methods:

  •   add(Vector2D other)
    Adds the argument x to this x and the argument y to this y.
  •   subtract(Vector2D other)
    Subtracts the argument x from this x and the argument y from this y.
  •   scale(float scale)
    Multiplies both the x and y by the argument scale.
  •   normalize()
    Divides the x and y components by the Vector’s length. The result is a Vector with a length of 1, also known as a unit vector.
  •   distance(Vector2D other)
    Returns the distance between this Vector and the argument Vector.

    engine.math.BoundingBox

    A BoundingBox contains a position, as a Vector2D, and a width and height. The position is the top left point of the box. It contains the following methods:

  •   move(Vector2D movement)
    Adds the argument vector to this object’s position.
  •   distance(BoundingBox other)
    Returns the distance between this BoundingBox’s position and the argument’s position.
  •   contains(Vector2D point)
    Returns true if the given point is inside this BoundingBox.
  •   intersects(BoundingBox other)
    Returns true if any corner point in the argument is inside this BoundingBox.

2 of 11

UML Diagram

The following UML diagram is a summary of most of the classes and methods in the engine package.

You will need to read the source code documentation to get a full understanding of each class and the methods therein.

Note that any underlined methods are static and any methods in italics are abstract.

Note that this diagram does not follow the rules of UML exactly. If you are confused by the diagram please ask your lecturer.

3 of 11

ECOSIM

EcoSim attempts to simulate the relationship between predators and prey in the environment. Each animal will have to find food to survive. If they survive for long enough they will reproduce to create more animals. Some animals eat other animals. Some animals eat plants. In this assignment our animals will be wombats and snakes. The snakes will eat the wombats, the wombats will eat grass. The wombats will breed faster than the snakes but will have to eat more to stay alive.

You will need to complete the ecosim package and add its game objects to the GameEngine. In this assignment, you will have to define five classes. You will need to define the Animal, Wombat and Snake classes. You will also need to define the EcoSim and OutOfBoundsException classes. You have been provided some complete classes to get you started. These include Main, Entity, GrassTuft, Tile, SandTile and GrassTile.

Provided Classes

The following classes have been provided for you…

ecosim.game.Main

Main is the starting point of the program. It constructs an EcoSim object and adds it to the GameEngine. Execute the main method in the Main class to start the EcoSim application.

ecosim.world.Tile

Tile contains a BoundingBox and a BufferedImage. Tile implements IPaintable so it has a paint method which will paint its image to its bounding box position. Tiles will be created and arranged into a grid. This will act as a background image and determine the area in which the Wombats and Snakes are allowed to move. Once added to the GameEngine, using GameEngine.addToBackground(tile), it will automatically be painted to the screen and will appear behind images added on top of it. It also contains the constants Tile.WIDTH and Tile.HEIGHT which should be used as the width and height of every Tile.

ecosim.world.GrassTile

GrassTile extends from Tile. GrassTufts are only allowed to be created in the same position as a GrassTile. GrassTiles should be added to the GameEngine background.

ecosim.world.SandTile

SandTile extends from Tile. A GrassTuft should never be allowed to grow on top of a SandTile. SandTiles should also be added to the GameEngine background.

ecosim.entity.Entity

Entity is the base class of Animal and GrassTuft. An Entity has a bounding box, a target position, an image and an alive status. The bounding box determines the Entity’s position and size. Entity implements IPaintable and consequently, has a paint method which will paint the Entity’s image to the screen at its position. It implements IUpdatable so it has an abstract update method, which should be overridden in its derived classes to determine how the Entity acts and how it moves. In general, the Entity will move towards its target position over time. It has a die method which, when called, will set alive to false and automatically remove the Entity from the GameEngine. Once removed from the GameEngine, an Entity will not be updated or painted to the screen.

Any class extending from Entity can be added to the GameEngine using GameEngine.add(entity). This will paint it on top of objects added to the background.

ecosim.entity.GrassTuft

GrassTuft extends from Entity and, as a result, has an image, bounding box, and alive status. It will be painted to the screen at its bounding box position. It can die, just like any Entity. It also has an update method, but the update method is empty. Wombats will find GrassTuft objects, move to their location and eat them. If a GrassTuft is eaten by a Wombat, the GrassTuft will die and be removed from the GameEngine.

4 of 11

Required Classes

The following classes will need to be written by you…

ecosim.game.EcoSim

EcoSim extends from the abstract class engine.Game. It must implement the abstract methods loadKeyFunctions(), loadMouseFunctions(), loadImages(), getWinWidth(), getWinHeight() and update(long millisElapsed). Most of these methods have been written for you. The class contains a gridWidth, gridHeight, timer and 2 dimensional array of Tiles. The gridWidth and gridHeight determine the length of the tile array. The timer will be used in the update method.

Complete the EcoSim constructor to save the arguments gridWidth and gridHeight to instance variables. Initialize the length of the tile array to gridHeight arrays of gridWidth length each. Implement the getWinWidth method to return gridWidth multiplied by the Tile width. Implement the getWinHeight method to return gridHeight multiplied by the Tile height.

The EcoSim load method should call super.load(). This will automatically call the loadKeyFunctions(), loadMouseFunctions() and loadImages() methods. After calling super.load(), you will need to create a two dimensional array of Tiles and add each to the GameEngine background. You will need a nested for loop to place the tiles at intervals of Tile.WIDTH along the x coordinate and intervals of Tile.HEIGHT along the y coordinate.

While creating your tiles, generate a random number and use it to ensure that approximately 80% of the Tiles are GrassTiles and 20% of the Tiles are SandTiles. If it is a GrassTile, generate another random number and use it to ensure that 50% of the time, you create a GrassTuft object and add it to the GameEngine at the same position as the GrassTile. Generate another random number and use it to ensure that about 20% of the time, you add a Wombat at the same position as the Tile and 10% of the time, you add a Snake. There should be about half as many Snakes as Wombats.

The EcoSim update method should add a GrassTuft object to the GameEngine background every 1000 milliseconds. Add the millisElapsed argument to the timer instance variable. If the timer is greater than 1000 add a GrassTuft object in the same position as a random GrassTile that does not already have a GrassTuft in the same position. You can access the GrassTuft objects from the GameEngine using GameEngine.getGameObjs(“ecosim.entity.GrassTuft”). This will return an Object array. You can type cast each item from the array to a GrassTuft and check its position is not the same as the GrassTile you have selected. If none of the GrassTufts are in its position, create the GrassTuft here. If a GrassTuft was successfully created, reset the timer back to zero.

ecosim.entity.Animal

Animal is an abstract class that extends from Entity. It has energy, breedTime, maxBreedTime, speed and a timer. The energy starts at a high number but, if it reaches zero, the Animal will die. The breedTime will start at maxBreedTime and when it reaches zero, the Animal will breed to create a copy of itself and add it to the GameEngine. The breedTime will then be reset to maxBreedTime. The speed determines how far the Animal can move each step. The timer will add up towards 1000. Every time it reaches 1000, it will decrease the energy by 1 and decrease the breedTime by 1. The timer should then be reset to zero.

You will need to complete the constructor, provide getters and setters and implement the update method. In the constructor, initialize the instance variables to the given arguments and initialize the timer to zero. Also call the abstract selectTarget method. Add getters and setters for each of the variables except for the timer. Ensure that the setters only change the variables if the argument is greater than or equal to zero.

The Animal update method should add the millisElapsed to the timer. If the timer is greater than 1000, the timer should reset to zero and the energy and the breedTime should decrease by one. If the energy is zero or less, the animal should call the die() method. Otherwise, if the breedTime is less than or equal to zero, the Animal should call the breed method and add the result to the GameEngine. If the Animal is still alive, the animal should move towards its target position.

5 of 11

The Vector math for moving the Animal is provided below:

Vector2D direction = target.clone().subtract(this.getPosition()); direction.normalize().scale(this.speed); this.getBounds().move(direction);

These diagrams demonstrate how the above Vector mathematics works:

ecosim.entity.Wombat

Wombat will extend from Animal and have an instance variable, called targetGrass, containing a GrassTuft target. By default this GrassTuft should be null. The Wombat constructor will have to send its position and its default image, energy, breed steps and movement speed to the super constructor. You can set your energy to 10, breedSteps to 18 and speed to 1. The Wombat will need to implement the breed method and selectTarget method. It will also need to override the update method.

The breed method should return a Wombat at the same position as the calling object. The update method should call super.update(). Provided the Wombat is not dead, it should then find the distance between its position and its target vector. If it is less than half the width of a tile, then the Wombat has reached its destination. It should set target to null. If the Wombat has a target GrassTuft, and it is within a half Tile width of that object, the Wombat should add 10 to its energy, call the target grass’ die method and set its target grass variable to null. It should then call the selectTarget method.

The selectTarget method will check to see if the Wombat’s energy is lower than 10 and if it is, the Wombat should find the closest GrassTuft object and set a reference to that GrassTuft’s position as the Wombat’s target. The GrassTuft should also be saved as the Wombat’s targetGrass. If the Wombat does not have a targetGrass and it does not have a target, you should generate a new target at a random position between 0 and 150 pixels away from the Wombat’s current position. If the new target’s x or y coordinate is less than zero or its x coordinate is greater than the Game’s pixel width or its y coordinate is greater than the Game’s pixel height, you should throw an OutOfBoundsException. If an OutOfBoundsException is caught, the target vector should be constrained to between 0 and the Game’s width along the x and between 0 and the Game’s height along the y.

ecosim.entity.Snake

Snake will extend from Animal and have an instance variable for moveSpeed, attackSpeed and a targetWombat containing a reference to a Wombat. The Snake constructor will have to send its position and its default image, energy, breed steps and movement speed to the super constructor. You can set the energy to 16, breedSteps to 32 and speed to 0.6. Set the attack speed to 1.1 and the move speed to 0.6. You will need to implement the breed method and selectTarget method and override the update method.

Figure 2: Use subtract to get position of GrassTuft relative to Wombat.

Figure 1: Position of Wombat and GrassTuft relative to (0, 0).

6 of 11

Figure 3: Use normalize() to scale the Vector to length 1. Use scale() to multiply the length by speed. Move the Wombat by the result.

The breed method should return a Snake at the same position as the calling object. The update method should call super.update(). Provided the Snake is not dead, it should set its speed to its moveSpeed. If its targetWombat is not null and the targetWombat is alive, if the distance to the Wombat is less than half a Tile width, then the Snake should gain the energy of the Wombat, the Wombat should die and the targetWombat should be set to null. Otherwise, if the distance from the Snake to the Wombat is less than 3 Tile widths, set the Snake’s speed to its attackSpeed, so it can chase down the Wombat. It should then call the selectTarget method.

The selectTarget method will check to see if the Snake’s energy is lower than 8 and if it is, the Snake should find the closest Wombat object and set a reference to that Wombat’s position as the Snake’s target. The Wombat should also be saved as the Snake’s targetWombat. If the Snake does not have a targetWombat and it does not have a target, you should generate a new target at a random position between 0 and 150 pixels away from the Snake’s current position. If the new target’s x or y coordinate is less than zero or its x coordinate is greater than the Game’s pixel width or its y coordinate is greater than the Game’s pixel height, you should throw an OutOfBoundsException. If an OutOfBoundsException is caught, the target vector should be constrained to between 0 and the Game’s width along the x and between 0 and the Game’s height along the y.

ecosim.exception.OutOfBoundsException

The OutOfBoundsException class should extend from Exception. It should have a private final instance variable called badPosition that contains a Vector2D. The class will need a constructor that takes a Vector2D parameter and saves it in the instance variable. It should also call super with the default error message, “Out of bounds: ” + badPosition. Provide a getter method to return the badPosition.

Source Code Documentation

You will be required to include source code documentation for each of the methods you write. You must place a comment between /** and */ on the line above each of the methods you write. Describe in detail what the method does, what parameters are required and what value is returned.
An example of a doc string for the EcoSim getWinWidth method is as follows:

/**
* Return the total screen width of the Game, which should be
* the number of horizontal Tiles multiplied by the tile width. * @return gridWidth multiplied by default Tile width.
*/

public int getWinWidth() {
return this.gridWidth * Tile.WIDTH;

}

7 of 11

UML Diagram

The following UML diagram is a summary of all classes in the ecosim package. Your goal in this assignment is to implement the UML Diagram in code. The classes marked in blue contain the methods you will neeed to implement. Note that any underlined methods are static and any methods in italics are abstract.

8 of 11

HOW TO START

The following are a few things you can do to test that the GameEngine works:

  •   Implement any unimplemented methods to remove all the compile errors.
  •   In the EcoSim load method, under super.load() call GameEngine.add(new Wombat(200, 300)). This should put

    a Wombat on the screen. Change the numbers to change the Wombat’s position.

  •   If your window is too small, return a number from the EcoSim getWinHeight() and getWinWidth() method.

    Maybe return 600 from the getWinWidth() and return 400 from getWinHeight().

  •   In the Wombat update method call this.getBounds().move(1, 0). This should cause the Wombat to move 1

    pixel to the right 60 times per second. Try changing the numbers to see what causes it to move in different

    directions.

  •   Press the tilde button ( ~ ). This should set the GameEngine debugging state to true. You should be able to see

    a BoundingBox drawn around the Wombat. Normally this would show the movement vector as an arrow, but you will have to follow the specifications above to get that to work. You can also try pressing the space key to pause the program.

  •   You may like to open the GameEngine, BoundingBox and Vector2D classes to read their code. You may also like to read the documentation in the doc folder. This should give you further understanding of how the GameEngine works.
  •   Once you are feeling confident return to the EcoSim Required Classes section and follow the instructions to complete the assignment.

    ADDITIONS

    The EcoSim and GameEngine are extendable. For full marks you must implement at least one of the following additions. Please only attempt these once you have completed all other requirements. If you submit an unfinished addition, please ensure that your code still compiles without errors.

    •   Another Animal: Implement a predator of Snakes or another predator of GrassTufts. The new Animal must have a new image.
    •   Animation: Implement sprite animations. In the assets/images folder, there is a second image for both Wombat and Snake. Cycle between the first and second image every 500 milliseconds to create a walk cycle.
    •   Obstacle: Implement a new Tile that Animals cannot stand on or move through. Water or Bush tiles might be appropriate. These Tiles will need new images.
    •   Wombat Artificial Intelligence: Wombats should try to move away from any nearby Snakes, unless they are hungry and the Snake has gotten in the way of their food.
    •   Collisions: Implement the ICollidable interface for Snakes and Wombats so that Snakes do not pass through other Snakes and Wombats do not pass through other Wombats.
    •   Realistic Breeding: Implement the ICollidable interface for Animals so that Animals can only breed when their breedTimer is less than or equal to zero and they have collided with another object of the same class.
    •   Sound: Add a sound system and sound files to the EcoSim, so that Snakes and Wombats make sounds whenever they eat, breed or die.
    •   Paused Label: Display a label saying PAUSED at the center of the screen whenever the GameEngine is paused.
    •   Other: If you would like to make an addition not listed above, please discuss it with your lecturer.

9 of 11

SUBMISSION DETAILS

You are required to submit an electronic copy of your program via Moodle. Make sure your eclipse project is included in a zip file (WinZip). The zip file should be called yourId.zip. For example: bonjy1207.zip. Ensure that your files are named correctly (as per instructions outlined in this document).

All Java files that you submit must include the following comments.

     /**
     / File: fileName.java
     / Author: your name
     / Id: your id
     / Version: 1.0 today’s date
     / Description: Assignment 2 - ....
     / This is my own work as defined by the SAIBT
     / Academic Misconduct policy.
     */

This is to acknowledge this is your own individual work.
Assignments that do not contain these details may not be marked.
Work that has not been correctly submitted to Moodle will not be marked.
It is expected that students will make copies of all assignments and be able to provide these if required.

EXTENSIONS AND LATE SUBMISSIONS
There will be no extensions/late submissions for this course without one of the following exceptions:

  1. A medical certificate is provided that has the timing and duration of the illness and an opinion on how much the student’s ability to perform has been compromised by the illness. Please note if this information is not provided the medical certificate WILL NOT BE ACCEPTED. Late assessment items will not be accepted unless a medical certificate is presented to the Course Coordinator. The certificate must be produced as soon as possible and must cover the dates during which the assessment was to be attempted. In the case where you have a valid medical certificate, the due date will be extended by the number of days stated on the certificate up to five working days.
  2. A SAIBT councillor contacts the Course Coordinator on your behalf requesting an extension. Normally you would use this if you have events outside your control adversely affecting your course work.
  3. Unexpected work commitments. In this case, you will need to attach a letter from your work supervisor with your application stating the impact on your ability to complete your assessment.
  4. Military obligations with proof.

Applications for extensions must be lodged with the Course Coordinator before the due date of the assignment.

Note: Equipment failure, loss of data, ‘Heavy work commitments’ or late starting of the course are not sufficient grounds for an extension.

10 of 11

ACADEMIC MISCONDUCT

Students are reminded that they should be aware of the academic misconduct guidelines available from the SAIBT website.

Deliberate academic misconduct such as plagiarism is subject to penalties. Information about Academic integrity can be found in the “Policies and Procedures” section of the SAIBT website.

MARKING CRITERIA

Assessment feedback

Programming Fundamentals (COMP1040) Assignment 2 – Weighting: 20%

NAME:

MAX MARK

MARK

COMMENT

ECOSIM: Constructor(3), load(7), update(10)

20

ANIMAL: Constructor(2), update(10), getters and setters(8)

20

WOMBAT: Constructor(3), update(5), selectTarget(5), findGrass(7)

20

SNAKE: Constructor(3), update(5), selectTarget(5), findWombat(7)

20

OUTOFBOUNDSEXCEPTION: Constructor(3), getter(2), Exception Handling(5)

10

STYLE: Doc comments (5)

5

ADDITIONS*: Animation (10), extra animal(10), obstacle(10), Wombat A.I.(10), collisions(10), breeding(10), sound(10), paused label(10), other…

5 ~ 20

TOTAL

100 MARKS

*Note that the maximum marks without additions is 95%. An addition must be made for full marks. Additions may recover lost marks up to a maximum of 20.

Possible deductions:

  •   Programming style: -10 marks for poor or no commenting, poor variable names, poor indentation, use

    of break and continue etc.

  •   Submitted incorrectly: -20 marks if assignment is submitted incorrectly.

11 of 11