As part of my Games Computing module in university, I designed and developed a 3D platformer game in C++ called Space Escape!
In Space Escape!, the player is a robot lost in outer space. The player must navigate various obstacles and challenges in the environment to get to the rocket and escape back to Earth. The game has multiple levels and collectable items, and the goal for the player is to reach the end of the level without falling into the void.
In this project, I designed, planned and implemented a fully functional game concept within a short timeframe. I gained practical experience in developing an application in C++ and I learnt how to effectively use middleware libraries such as openFrameworks and Open Dynamics Engine to help build an immersive game.
Implementation Details and Challenges
I used C++ to develop the game since it is an efficient compiled language and offers direct memory management, which allows games to run more smoothly. C++ is also widely used in the commercial games industry. Alongside this, I used two C++ middleware libraries to help build the solution:
Open Dynamics Engine (ODE) - ODE is an open-source library which can simulate rigid body dynamics in a 3D environment. I chose this library because it can simulate interactions between 3D objects and offers built-in collision detection and handling, which suits my platformer game genre.
openFrameworks - openFrameworks is a lightweight open-source library that provides an intuitive interface for creative programming in C++. I chose this library because it already implements many core functionalities essential for any game, such as handling the draw loop and key press events, which allows 3D objects to be rendered and animated. Another great feature openFrameworks provides are its lighting functions, which I used in my game to make scenes more cinematic and to enhance the space environment.
Camera System
For the camera system, I decided to use a third-person perspective, as this allows the player to see more of their surroundings and helps them to judge distances better in a 3D environment.
To implement the camera, I used the ofCamera class from openFrameworks to create a camera with a perspective projection. This class contains two useful methods which I used to configure the camera: the setPosition method, which I used to set the camera position behind the player, and the lookAt method, which I used to rotate the camera so that it always looks at the player as they move.
I used three variables: distance from the player, pitch and the angle around the player to calculate the camera’s coordinates relative to the player’s position. I chose this configuration to have more precise control over the camera.
Platform Collision Detection
As Space Escape! is a platformer, the game needs to handle the collisions between the player and the platforms. I implemented this by using ODE to specify box geometry for the player and each platform. I also developed a collision callback which uses methods from ODE to handle the interactions between geometries when they intersect.
Another requirement for this game was to handle moving platforms realistically so that when the player stands on a moving platform, it moves with the platform. To achieve this, I used the geometry identifier in the collision callback function to determine which specific platform the player was standing on. Then, I added the platform’s current velocity to the player to make it appear that the player is ‘glued’ to the platform.
Space Background Effect
To create a space-themed, star-lit background, I developed a particle effect of 1000 multi-coloured vertices on the surface of a sphere centred around the player. I used a Perlin Noise function to coordinate the movement and colour of the points. The sphere follows the player continuously as they move.
To ensure that the points are evenly distributed on the surface of a sphere centred around the player, I used the following equation to normalise a vector of random variables x, y, and z for each point:
// For each vertex: float sqrtCoords = sqrt(x*x + y*y + z*z); x = (x*radius/sqrtCoords) + playerPos.x; y = (y*radius/sqrtCoords) + playerPos.y; z = (z*radius/sqrtCoords) + playerPos.z;
Lighting Effects
Once I finished developing the game's core mechanics, I used some of the lighting capabilities within openFrameworks to make the game more immersive and challenging. For example, I created a spotlight which hovers above the player and follows them as they move to illuminate the player’s immediate surroundings. I also set emissive lighting properties for the platforms to make them glow. I used this feature to make some platforms disappear temporarily to make the final level more challenging.
Demonstration
The following video shows a demonstration of the game, which currently has three levels with an incremental game difficulty:
Summary
Through building this game, I have learnt a lot about working with middleware game components such as a rigid-body physics engine and a graphics library. In addition, I have learnt how to design, plan and develop a 3D game in C++, working to short deadlines.
This project is only a game concept, and while it contains many of the mechanics of a game, it is not a fully-fledged game yet. To make this a complete game, I would add more levels with different projectiles and enemies, to make the game more challenging. I would also add textures to the platforms and other objects to make it more space-themed. Additionally, I would consider adding a timed-scored mode, where procedural generation is applied so that there is one level which continuously generates new platforms, orbs and enemies as the player advances.
Project GitHub Link: github.com/nathanielbrookes/SpaceEscape