Build Your Own World
Mar - May 2024
Designing and developing a 2D tile-based world exploration game, where users can move and interact with objects within the world through an overhead perspective.
Completed through UC Berkeley’s computer science course CS61B Project Partner: AnhThu Bui
Tool / API Used: Java, StdDraw
The Task
As part of a class partner project for my computer science class, we are tasked with designing a 2D tile-based explorable game from scratch. Here are the main project requirements :
the world generated must be sufficiently random and valid (world layout depends on user seed input and must be explorable)
the game must support user WASD movement and allow users to save and load previous games
have a logical game flow that sufficiently challenges the user and allows them to win/lose
Here is a link to the full project description.
The Game Flow Design
-
1. Overall Game Logic
We wanted the user's main objective to retrieve a key located somewhere random in the world, and escape by bringing it to the locked door.
In this process, we designed obstacles by creating enemies that spawn in random locations.
While the user can kill the enemies by pressing k, the enemy can also deal damage to the avatar if it is within a certain range of the enemy.
Click here for the full gameflow design
-
2. Game Initialization Design
Avatar Initialization: the avatar spawns at a random location within the world with a starting health value of 5
Key and Locked Door: Both spawn in random locations, ensuring the key is accessible to the user and the door is not immediately adjacent
Enemies: 8 enemies spawn at random locations, ensuring they are not adjacent to the avatar at the time of spawning, moving randomly across the grid
Hearts: 5 hearts spawn in random locations to restore health.
-
3. Game Mechanics Design
Enemy Interaction: If an enemy comes within a 3-tile radius of the avatar, the avatar loses 2 health points, and that enemy disappears
Attack Mechanism: If the avatar presses 'K' when an enemy is within a 3-tile radius, the enemy is "killed" and disappears without causing harm to the avatar
Health Restoration: The avatar can collect hearts to restore health by 1 point per heart, up to a maximum of 5 points.
Winning: The avatar wins the game by reaching the door with the key and having a health value greater than 0.
World Generation
Expectations:
World must be valid:
Rooms and hallways must be connected
There must not be dead-end hallways
All rooms must be reachable
Rooms must not clip off at edge of the world
World must be sufficiently random:
Number of rooms and hallways is random
Size of rooms and hallways is random
Width and height of each room is random
Our Solution:
We decided to create 3 classes to build a valid and sufficiently random - Room, Hallway and World class. Room and Hallway instances are defined separately in their own class, while World is used to connect them appropriately. Below are the specifics of how we achieved this:
Room.java:
Contains room properties (e.g. position in world, length and width, etc)
Have methods to determine if the room is overlapping or lies on the border of other rooms
Hallway.java:
Have methods to create a hallway between two rooms, including changing the tile type
Checks if the direction of the hallway should be vertical or horizontal
World.java:
Generates a random number of rooms depending on seed input
Generates hallways to connect previously unconnected rooms
Ensures the tiles displayed are correct according to their tile type
Checks that all rooms and hallways are reachable and within bounds of the world
At this point, a valid and sufficiently random world is generated every time, regardless of seed input
The Results: Implementing UI + Game Mechanisms
Now that we had a strong and valid world generated, it was time to implement the details from our game flow idea into our work. Similar to part 1, we decided to create new classes for Avatar and Enemy, with each class containing their respective methods for moving (with WASD), attacking and dealing with damage / health updates.
Then, we moved on to building upon our current World class, where we:
1. Spawn the avatar, enemies, and hearts in valid positions in the world
2. Consistently update the world game state according to avatar and enemy movement
3. Implemented saving, quitting and loading game logic according to user’s keyboard input
4. Display in-game messages depending on user actions (e.g. if the avatar / enemy has dealt damage and current health value)
Thank you for reading!
This video is a demonstration of the final results of our game. The white diamond is the avatar, while blue triangles that move randomly are enemies. In game messages are displayed whenever the avatar deals or receives damage.