This project is a 3D maze game built using Three.js. The player navigates through a maze environment, collects crystals, and attempts to reach the exit. The game includes two modes: a collection mode and a challenge mode.
- W / A / S / D: Move the player
- The character automatically rotates to face the direction of movement
There are two possible ways to win:
- Collect Mode
- Collect all crystals in the maze
- Then reach the exit to win
- Challenge Mode
- Ignore crystals
- Reach the exit directly
The mode is selected by walking near the signboards at the start of the maze.
The project uses hierarchical modeling in two ways:
- Each collectible is built using a parent Object3D containing a rotating crystal and an orbiting sphere. The sphere rotates around the crystal using a child object hierarchy.
- The player model is imported from Blender and contains multiple child meshes (hands and legs). These parts are animated independently while remaining attached to the main character.
The scene includes:
- A directional light source
- An ambient light source
These illuminate the maze and provide depth and visibility.
Texture mapping is applied to:
- Walls (brick texture)
- Floor (wood texture)
- Boards (door texture)
Bump mapping is also used to enhance surface detail.
A third-person camera follows the player from behind, allowing the user to observe both the character and the environment.
- Built with Three.js
- Requires a local server to run properly (due to texture loading)
- Textures from Kenney (https://kenney.nl/assets/retro-textures-fantasy)
- Player model created using Blender
- Download all project files to your local machine
- Make sure all related assets (JS, textures, models) are in the correct folders
- Open final_project.html directly in your browser
At the beginning of this project, I decided to design a maze game that includes a collection system. To make the development process more manageable, I broke the project down into several stages.
First, I designed the maze layout using Excel. I created a structure with two possible routes: one path includes collectible crystals, while the other is a more challenging maze without the requirement to collect items. After finalizing the layout, I translated the maze into a JavaScript array format, where different numbers represent different elements (for example, walls and paths).
Next, I used Blender to model a simple player character and exported it as a .glb file. After setting up the HTML file and connecting it with maze.js, I used loops and conditional statements to generate the maze in Three.js.
Once the maze was created, I added the player into the environment and implemented a WASD control system. At this stage, I also set up a third-person camera that follows the player’s position, allowing the user to navigate the maze more easily.
After establishing basic movement, I implemented the crystal collection system and added a HUD to display the player’s progress. I also created a start screen and a win screen to improve the overall user experience. Additionally, I introduced two signboards at the beginning of the maze, allowing the player to choose between the collection route and the challenge route. If the player selects the challenge route, they can reach the goal without collecting all crystals.
Later in development, I realized that I had not yet incorporated hierarchical modeling. To address this, I redesigned the crystal system so that each crystal is part of a parent object, with a smaller sphere orbiting around it. This demonstrates a clear parent-child relationship. I also animated the player’s hands and legs using the hierarchical structure of the imported model.
Finally, I researched and selected appropriate textures to improve the visual quality of the environment. I experimented with adding mouse-based camera control, but found that it made the gameplay more difficult and less intuitive for a maze setting. As a result, I decided to keep the original keyboard-based control system, which provides a smoother and more accessible player experience.
Overall, this project helped me better understand how to combine modeling, animation, interaction, and rendering into a complete interactive 3D application.