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

Sample World Generation

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.