Project 2, Semester 2, 2022
Please read the complete specification before starting on the project, because there are important instructions through to the end!
In this project, you will create a fantasy role-playing game called ShadowDimension in the Java programming language, continuing from your work in Project 1. We will provide a full working solution for Project 1; you may use all or part of it, provided you add a comment explaining where you found the code at the top of each file that uses the sample code.
You may use any platform and tools you wish to develop the game, but we recommend using IntelliJ IDEA for Java development as this is what we will support in class.
There are two parts to this project, with different submission dates. The first task, Project 2A, requires that you produce a class design demonstrating how you plan to implement the game. This should be submitted in the form of a UML diagram showing all the classes you plan to im- plement, the relationships (e.g. inheritance and associations) between them, and their attributes, as well as their primary public methods.
The second task, Project 2B, is to complete the implementation of the game as described in the rest of this specification. You do not need to strictly follow your class design from Project 2A; you will likely find ways to improve the design as you implement it. Submission will be via GitLab and you must make at least 5 commits throughout your project.
“A dark evil has arrived in your hometown. A group of government scientists have opened a gate in their laboratory to another dimension called the Over Under. The Over Under is ruled by Navec (an evil creature of immense power) and his henchmen are called demons. The scientists thought they could control these creatures but alas they failed and are being held captive in the Over Under. Navec has created sinkholes that will destroy the lab and is planning on eventually destroying your world.
The player’s name is Fae, the daughter of one of the scientists. In order to save your father and your town, you need to avoid the sinkholes, find the gate in the lab and defeat Navec & his demons in the Over Under...”
The game features two levels : Level 0 is in the lab and Level 1 is in the Over Under. In Level 0, the player will be able to control Fae who has to move around the walls and avoid any sinkholes that are in the lab. If the player falls into a sinkhole, the player will lose health points. To finish the level, the player has to get to the gate, located in the bottom right of the window. If the player’s health reduces to 0, the game ends. You have already implemented Level 0 in Project 1 (the only change required is to the winning message screen which is explained later).
The Game Engine
The Basic Academic Game Engine Library (Bagel) is a game engine that you will use to develop your game. You can find the documentation for Bagel here.
Every coordinate on the screen is described by an (x,y) pair. (0,0) represents the top-left of the screen, and coordinates increase towards the bottom-right. Each of these coordinates is called a pixel. The Bagel Point class encapsulates this.
Bagel will refresh the program’s logic at the same refresh rate as your monitor. Each time, the screen will be cleared to a blank state and all of the graphics are drawn again. Each of these steps is called a frame. Every time a frame is to be rendered, the update() method in ShadowDimension is called. It is in this method that you are expected to update the state of the game.
Our game will have two levels, each with messages that would be rendered at the start and end of the level.
Window and Background
In Level 0, the background (background0.png) should be rendered on the screen to completely fill up your window throughout the game. In Level 1, the image background1.png should be used for the background. The default window size should be 1024 * 768 pixels.
All messages should be rendered with the font provided in res folder, in size 75 (unless otherwise specified). All messages should be centered both horizontally and vertically (unless otherwise specified).
When the game is run, Level 0 should start with a title message that reads SHADOW DIMENSION should be rendered in the font provided. The bottom left corner of this message should be located at (260, 250).
Additionally, an instruction message consisting of 2 lines:
PRESS SPACE TO START
USE ARROW KEYS TO FIND GATE
should be rendered below the title message, in the font provided, in size 40. The bottom left of the first line in the message should be calculated as follows: the x-coordinate should be increased by 90 pixels and the y-coordinate should be increased by 190 pixels.
All the actors will be defined in a world file, describing the types and their positions in the window. The world file for Level 0 is level0.csv and Level 1 is level1.csv. Both world files will contain the level bounds at the end of each file. A world file is a comma-separated value (CSV) file with rows in the following format:
You must actually load both files—copying and pasting the data, for example, is not allowed. Note: You can assume that the player is always the first entry in both files, the Level 0 world file will have a maximum of 60 entries and the Level 1 world file will have a maximum of 29 entries.
This is a rectangular perimeter that represents the edges of the level, which will be provided in the level’s CSV file (TopLeft for the top-left (x, y) coordinate of the perimeter, BottomRight for the bottom-right). You can assume that all entities provided will have a starting location within
For enemies, they should simply start moving in the opposite direction if they collide with the level bounds (e.g. if they were moving up when they reached the top edge, they should start moving down after the collision).
For Level 0, once the player reaches the gate, this is the end of the level. To reach the gate, the player’s x coordinate must be greater than or equal to 950 and the y coordinate must be greater
than or equal to 670. A winning message that reads LEVEL COMPLETE! should be rendered as described earlier in the Level Messages section. Note that nothing else (not even the background) must be displayed in the window at this time and this message should be rendered for 3 seconds before displaying the start screen for Level 1.
On either level, while there is no win, the game will continue running until it ends. As described earlier, the game can only end if the player’s health points reduce to 0. A message of GAME OVER! should be rendered as described in the Level Messages section. Note that nothing else (not even the background) must be displayed in the window at this time, and there’s no need to terminate the game window while this is being displayed.
The Game Entities
All game entities have an associated image (or multiple!) and a starting location (x, y) on the map which are defined in the CSV files provided to you. Remember that you can assume the provided images are rectangles and make use of the Rectangle class in Bagel; the provided (x, y) coordinates for a given entity should be the top left of each image.
In our game, the player is represented by Fae. The game should display some information about her current state, as described below.
The player is controlled by the four arrow keys and can move continuously in one of four directions (left, right, up, down) by 2 pixels per frame whenever an arrow key is held down.
These are entities that can attack the player. But, as described previously, the player can fight back against them, so they can die and disappear from the screen. Note that enemies are allowed to overlap with each other as well as the player during movement.
Demons feature in Level 1. Demons can be of two types (passive or aggressive) which is set randomly at creation. Passive demons are stationary and aggressive demons can move in one of four directions (left, right, up and down), randomly selected upon creation, at a random speed between 0.2 to 0.7 pixels per frame. If an aggressive demon collides with a sinkhole, tree or reaches the level boundary, it will rebound and move in the opposite direction. A demon has 2 states which determine its behavior: ATTACK and INVINCIBLE.
A demon starts with 40 health points and its current health value is dis- played as a percentage using the same calculation logic explained above for the player. This health bar is rendered on top of the demon’s image at (x, y - 6) where (x, y) is the top left of the image, as shown here. The font size should be 15 and the color logic is the same as explained above for the player. If a demon’s health points reduce to 0 or less, they will die and disappear from the screen.
Fire is shot by a demon or Navec as described earlier. The fire gets rendered if the player enters an enemy’s range and will be rendered from one of four points of the demon’s image (top-left, bottom-left, top-right or bottom-right). This is chosen based on how close the centre of the player’s image is to the centre of the enemy’s image (Remember that the given coordinates in the CSV are for the top-left of each image).
These are entities placed throughout the level that do not move, at locations specified by the level CSV file. These may apply some effect on the moving entities that collide with them, and may need to disappear at some point (i.e. the game should stop rendering and updating them).
Figure 10: Wall
A wall is a stationary object that features in Level 0, shown by wall.png. The player shouldn’t be able to overlap with or move through the walls, i.e. the player must move the player around any areas on the level where blocks are being rendered. A wall has no damage points and cannot in- flict damage on the player.
A tree has the image tree.png and is only featured in Level 1. Like the wall, the player shouldn’t be able to overlap with or move through the trees, i.e. the player must move around any areas on the level where trees are being rendered. This rule also applies to any moving enemies that may collide with a tree (they should move in the opposite direction upon collision).
A sinkhole is a stationary object that features in both levels and is shown by
sinkhole.png. Each sinkhole has a damage points value of 30. The sinkhole
should behave similar to a wall and prevent the player from moving through it. If the player falls into (i.e. collides) with a sinkhole, it will inflict damage on the player (according to its damage points value). After collision, the sinkhole will disappear from the screen and the player should be able to move through the area it was placed at before.
effect on the player
faeLeft.png (IDLE & INVINCIBLE, moving left), faeRight.png(IDLE & INVINCIBLE, moving right), faeAttackLeft.png (ATTACK & INVINCIBLE, moving left), faeAttackRight.png (ATTACK & INVINCIBLE, moving right)
Demon (station- ary & aggres- sive)
demonLeft.png (ATTACK, moving left), demonRight.png (ATTACK, moving right), demonInvinci- bleLeft.png (INVINCIBLE, moving left), demonInvincib- leRight.png (INVINCIBLE, moving right)
Random value between 0.2 to 0.7 (for aggressive demons)
When the player enters its attack range, it shoots fire
navecLeft.png (ATTACK, moving left), navecRight.png (ATTACK, moving right), navecInvincibleLeft.png (INVINCIBLE, moving left), navecInvincib- leRight.png (INVINCIBLE, moving right)
Random value between 0.2 to 0.7
When the player enters its attack range, it fires it shoots fire
Sinkhole inflicts 30 damage points on Fae. Fae’s current health: 70/100 Fae inflicts 20 damage points on Demon. Demon’s current health: 20/40 Navec inflicts 20 damage points on Fae. Fae’s current health: 50/100