Assignment 7:
Introduction to Computer Program Design: Assignment 7

Due 15 Dec 7pm
This is a Graded Assignment.
Goals
This assignment is intended to give you experience in writing larger programs:
- with simple event-driven input (mouse, buttons, etc)
- with multiple classes
- that use collections of objects stored in ArrayLists and search for objects and add/remove things in an ArrayList
- that store data to files and read data from files
Resources and links
-
DiskGame.java
and Disk.java
-
FireworksDisplay.java
Do not rename these files. You must use the provided template file and not remove the setupGui
and main
methods.

When you have submitted the files, check that you can read the files listed on the submission page, and complete the submission process.
DiskGame Program (80%)
Description of the game
DiskGame
is a simple game in which the player has to blow up disks spread out over a shooting range.
The game starts with a collection of randomly placed small disks on the upper half of the graphics pane, and a gun at the bottom.
The gun is fixed in the middle of a horizontal line below the shooting range, and shoots in any direction within a 180 degrees radius.
The player fires the gun with the mouse by releasing the mouse within the firing zone, which is limited by an arc surrounding the upper part of the gun. That will give the direction of the shot.
If a shot hits a disk, it will damage it.
If the disk is damaged sufficiently, it will explode and may damage surrounding disks if they are within range.
The player has a limited number of shots, and the goal is to cause the maximum damage.
Each disk can report its score (based on how much damage it received - the greater the damage, the greater the score), and
the score for the game is the sum of the scores for each disk.
The game is over when the player runs out of shots or all the disks have exploded.
Classes
The program consists of two classes
DiskGame
and
Disk
. The
DiskGame
class has an ArrayList which contains the list of all the disks.
User Interface

The user interface of
DiskGame
has two sliders: one to set the number of disks in the next game, and the other one to set up the number of shots the player can fire in the next game. It has 4 buttons:
- the Restart button should start a new game;
- the Load game will load a previously saved game;
- the Save game will save a game to be carried on later;
- the Quit button will exit.
The program also listens to mouse events, and responds when the mouse is released.
The
Disk
class is written for you, and you do not need to change it for the Core.
Make sure you read it carefully so that you know what methods you
can call on a Disk object.
Instructions and Tips
- You must use the constants defined in
DiskGame
.
- You must make use of the methods implemented in the
Disk
class. Do not duplicate code.
Core (70% of DiskGame)
Some of the code is provided; you will need to read and understand
it. In particular, note the fields storing the disks, the gun position, the number of shots remaining, and the current score.
We strongly advise you to build your program in stages, testing each stage and getting it working before progressing to the next stage!
The following steps are one way of constructing your program in stages. You
don't need to follow them, but it may be helpful to you. They give one way of
breaking the program into stages, each of which results in a working (though
limited) program.
- Stage 1. GUI Setup: Set up the user interface by completing the
setupGUI()
method, so that it:
- adds two sliders to set the number of disks and initial shots. They should call
setNumDisks
and setNumShots
methods, accordingly.
- adds a Restart button that calls the
startGame
method.
- sets up the mouse listener.
- Stage 2. Basic Initialisation: Initialise the game by creating disks with random positions, setting the total number of disks, and initial shots.
- Define the
setNumDisks(double value)
method so that it sets the total number of disks in the game.
Hint: Make variable types compatible by using type casting when setting the number of disks.
- Define the
setNumShots(double value)
method so that it sets the initial number of shots for the player.
Hint: Make variable types compatible by using type casting when setting the number of shots.
- Define the
initialiseDisks()
method so that it creates a new list of Disks at random positions within the shooting range.
Note that it is okay for the core if some of the Disks are initially touching or overlapping.
- Stage 3. Redrawing the Game Interface: Keep the display updated during the game.
- Complete the
redraw()
method so that it also redraws all the Disks in the ArrayList.
- Stage 4. Mouse Interaction and Shooting: Implement mouse interactions, allowing the player to click and shoot.
- Define the
doMouse(String action, double x, double y)
method so that it responds to mouse releases. It must
- check whether there is any remaining shot (if not, the game is over)
- then, if the mouse is released within the firing zone, it shoots by calling the
fireShot()
method.
Hint: you can use the isWithinFiringZone()
method to check if the given point was within the firing zone.
- The
fireShot(double x, double y)
method is the core of the game. Complete it so that it:
- moves the shot up the screen from the gun, 1 unit at a time, until it either goes off the screen or hits a disk. (Written for you)
- checks whether the shot hits a disk (use
getHitDisk()
method). If it does:
- it damages the disk,
- If the disk is broken, it should explode and damage any other disks within range ( use
damageNeighbours()
method).
- it exits the loop.
- Define the
getHitDisk(double shotX, double shotY)
method so that it returns the disk that has been hit by the shot, if any. The method returns null otherwise.
Hint: You use the isOn
method of the Disk
class.
- Define the
damageNeighbours(Disk disk)
method so that it inflicts damage on all the neighbours of the given disk.
- Stage 5. Game State and Scoring: Manage the game state by checking if all disks have exploded.
- Define the
haveAllDisksExploded()
method so that it returns true
if all the disks are exploded, false
otherwise.
- Define the
updateScore()
method so that it iterates through disks and adds up the scores. It also prints the current score.
Note there are many useful methods in the
Disk
class. Make sure
you use them rather than duplicating their code.
Completion (20% of DiskGame)
- Stage 6. Extend the
Disk
class:
- The second constructor in the
Disk
class should take x and y coordinates and an initial damage level.
- The
toString
method should return a string representation of the disk attributes such as coordinates and damage.
- Stage 7. Improve GUI Setup:
- Add two buttons for "save" and "load" that call
saveGame
method and loadGame
method.
- Stage 8. File Handling:
- Define the
saveGame()
method so that it
- asks the user to select a file and save the current game to the selected file.
- saves at least the score, the number of remaining shots, all the disk attributes such as their coordinates and damage.
Hint: You can use toString()
method.
- Define the
loadGame()
method so that it
- asks the user to select a file for loading a saved game.
- reads all game attributes and recreate the game. (It must mirror what was saved in the
saveGame()
method)
- Stage 9. Improve Initialisation:
- Extend the
initialiseDisks()
method. The core version of the game sometimes starts with overlapping Disks. Fix this so that it is guaranteed that all of the Disks are separated at the start.
- Stage 10. Improve Redrawing the Game Interface:
- Extend the
redraw()
method so that it also displays the remaining number of shots(e.g. as a pile of little squares).
Challenge (10% of DiskGame)
- If you explode a disk and it damages other disks, the core does not check whether they should be exploded (which might damage further disks, ...). Make the program do this properly, propagating the damage and exploding broken disks.
Fireworks Display (20%)
The
FireworksDisplay.java
program has
waves of fireworks that all go up together. The GUI has
a slider to set the number of fireworks in the next wave.
You will need to complete
- the
setWaveSize
method, to change the number of fireworks that should be made in the next wave. The slider provides the value for this.
- the
runDisplay
method, which should repeatedly send up waves of fireworks. It has a variable containing an ArrayList of the Firework
objects in the current wave. This involves:
- Creating and initialising an ArrayList to store
Firework
objects for the current wave.
- Updating the state of each firework in the ArrayList using its
step()
method.
- Removing fireworks from the ArrayList after they are finished (
isFinished(
method).
Watch the demo video to make sure you know what the program should do.
The
Firework
class is written for you. You are not allowed to modify it. The
Firework
class has a constructor and three
methods you can call:
-
new
Firework()
to create a new random firework
-
void step()
to make the firework take one more step
-
boolean isFinished()
to check if the firework has finished
-
void draw()
to display the firework on the screen
You are not permitted to modify Firework.java
.
Core (70% of FireworksDisplay)
- Complete the
setWaveSize
method.
- One Wave: Intialise the ArrayList with a collection of
Firework
objects and repeatedly make them step and remove any fireworks that have finished.
Completion (20% of FireworksDisplay)
- Multiple Waves: In addition to the Core, extend the
runDisplay
to check each time around the loop if the fireworks have all finished, and if so, make a new wave of fireworks.
Challenge (10% of FireworksDisplay)
- Nicer Fireworks: The fireworks given are boring - they just draw expanding coloured circles. Make the fireworks explode in a more realistic way, with a collection of "sparks" that expand outwards in a cloud.