Check out Rixa’s
- 🕹️ Game Page
- 💾 Project Files
About
Rixa is a retro, top-down shooter inspired by Commando on the C64. This was originally a group project done under the Developer Academy last year. I decided to overhaul it as I recently got some amazing C++ feedback and thought it was a great chance to put it into practise.
This was made using C++ and Sumo Digital’s Playbuffer library.
Refactoring
The original codebase was admittedly very messy — a reason why this project was not previously included in my portfolio. This was due to a number of reasons, but the main one was time constraints.
It was also our introduction to C++ games development, so some fundamental C++ practices were missing. E.G., Heap memory de-allocation, const correctness and others.
If you want to see a side-by-side, check out the last two overhaul commits:
Here are some of the improvements I made to the codebase:
Implementation
-
Projectiles
-
Projectiles
initially didn’t have their own class and were handled by the game object that spawned them. -
Now broken down into
PlayerProjectile
andEnemyProjectile
which inherit from theProjectile
class. -
The
ProjectileManager
is a static class which handles updating all the projectiles. -
Projectiles
have references to the owner that spawns them, which allows me to apply enemy specific attack ranges and damage. This is instead of having theEnemy
andPlayer
manage them directly in order to apply the same.See
RIXA/Source/Manager/ProjectileManager.cpp
See in
RIXA/Source/Actor/
:
-
-
Enemies
-
Broken down into different enemy classes which inherit from the
Enemy
class. -
This is less verbose than the original
switch
statement used to construct different enemies depending on type given to the constructor. -
They are now updated via the
EnemyManager
class, instead of being maintained in collection in theMain.cpp
.See
RIXA/Source/Manager/EnemyManager.cpp
See in
RIXA/Source/Actor/
:
-
-
Player
-
Player
originally was not managed by its own class, but in theMain.cpp
. -
It now inherits from the
Character
class which contains common functions required by both thePlayer
andEnemy
to override.
-
-
Particles
-
Decided to expand the explosion effect functions into it’s own
ParticleManager
system. -
This allows you draw a sprite animation at a given position. After it’s animation finishes, it destroys itself.
-
This is done for the damage and explosion effects in the game.
-
-
GameModes
-
Implemented class-based game states.
-
Helpful for reloading the game, as the
Game.cpp
deconstructor is used to free game-related heap memory.
-
Additions/Balancing
Here are some other additions I made outside of refactoring.
-
Win/Lose States
-
You could only die in the original prototype.
-
Added win state when reaching the end of the level.
-
-
Restart
-
After reaching the win/lose states, you can press space to restart.
-
-
Balancing
- Enemy stats were reworked to make them feel different from each other.
- Enemy bullet sizes now correlate to the amount of damage they deal.
-
Camera Lerping
-
Added lerping to make camera movement more smooth.
-
By far my favourite addition.
-
-
Bullet Animations
-
Enemy bullets now play a despawn animation instead of suddenly dissapearing when out of range or hitting the player.
-
-
Sounds
- Added shooting and hit sounds to make gameplay feel more impactful.
C++ Best Practises
- Replacing Enum DataType w/ Enum Class
- For reasons mentioned in the SFAS Feedback.
- Done for
GameState
andDirection
enums.
- Replacing Pointers
- Most functions or classes assumed the pointers used would not be
null
, so it made sense to swap them out with references where applicable.
- Most functions or classes assumed the pointers used would not be
- De-allocate Heap Memory
- Re-implementation of new
Projectile
andEnemy
classes meant they had to be correctly de-allocated.
- Re-implementation of new
- Const Correctness
- For functions and inputs where applicable.
Structure
-
Separate Functionality
-
The
Main.cpp
originally had over 1000 lines of code and needed some severe refactoring. -
Splitting it out into different classes allowed me to modularize and re-implement components better.
-
Additions: Game Modes, Actor/Enemy/Player/Projectile Classes and their corresponding Manager Classes.
See
Main.cpp
in the intial overhaul commit
-
-
Folder Structure
-
With the addition of more classes, I had to re-organise the file structure to make it more navigable.
See
RIXA/Source/
-
Bugs
- Crashing Issues
- Fixed illegal memory access crashes in the new implementation.
- Tracked Enemy
- Fixed a bug where the ‘Tracked Enemy’ would appear as a giant turret.
Contributions
Thanks to the original team behind Rixa! It was a blast making this with them at the time. It was interesting to see how much I have improved over the monthes since then.
Here are the contributors to the base prototype:
Daniel Vasile
- Sound
Henry Ha
- Gameplay
- Enemy, AI
- Camera
Izzy Cassell
- XML level loader
- Level collisions
- Enemy, AI
Jake White
- Design
- Assets
- Music