Downloadable
Controls:
Exit: ESC or click on X
Move Rocket: Arrow Keys
Shoot: Space
* If you want to run source files instead of executables, please download Dong Wang's ColliderBuilder.exe as well or you won't be able to run BuildFakeRaidenAssets and generate .bcollider files, or you can download my binary files.
Introduction
Inspired by the arcade game Raiden, Fake Raiden is also a shooter, in which players control a rocket to avoid enemies' attack and try to shoot down all enemies on screen. The rocket has cooldown time, so it can't shoot nonstop. Each round consists of several small fights and a boss fight. The boss has more bullets, less cooldown time, and receives less damage. Both enemies and the rocket have HP. When the HP of the rocket reaches zero, the game is over, or else players can keep playing the game. As the game progresses, it becomes more challenging. More normal enemies will be spawned in, and there will be more small fights before players meet the boss.
Since my engine project is an audio system, I wanted to add some sound effects in addition to background music. Considering the physics system was not very complicated, I thought of Raiden, which had simple mechanics.
Here's a short video of the gameplay:
Engine Projects
The background music and the shooting sound were added using my audio system. One thing I'm glad that I have done is that the interfaces don't rely on states. Therefore you can call them anywhere and anytime. However, I regret that I chose to load everything all at once instead of loading chunks. Currently, loading all music at the start of the game takes more time than I thought it would take. I should have tried streaming music.
Dong also has a clear project structure. Most interfaces are easy to use, but I had to copy some of his GameObject and RigidbodyState codes into mine, which caused some errors at first. I also had to add some more parameters to OnCollision and OnTrigger functions to get some information about the other collider. I think having both OnCollision and OnTrigger events like Unity is a smart move. It can deal with most situations, but I also added something like channels to filter collisions. I've been using a counter and a boolean variable to prevent events from getting triggered each frame. In my opinion, it would be better to separate the start and the end of the collision from OnCollision.
Summary
Among all things I learned this semester, there are two that interested me the most. One is platform-specific code, and the other is separating assets from code.
I have never dealt with or even thought about platform-specific code before, mainly because we are all working with Windows and the same libraries. However, in real projects, we might need to deal with platforms other than windows. We should first try our best to merge code if it appears on all platforms. Using macros, we can easily group small differences, and by creating different files for different platforms, we can deal with big differences. It is also a good method if multiple teams develop the same project. Though engine developers know they are using different platforms, we should be aware that engineers who use the library should never notice these differences, thus designing good interfaces becomes really important.
Separating assets helps to modify assets without rebuilding the whole project. This semester, we also built binary files instead of using human-readable files directly. I didn't fully understand why saving loading time was vital until I started working on the final project. As was mentioned, yes, it took much time to load audio files.
I studied software engineering for four years, and my teachers kept telling me architecture was IMPORTANT. Sometimes, how convenient these game engines can be makes me forget about that, but I start to have that feeling again when developing game engines. A good design should let you add new code instead of modifying existing code. It should also be easy to understand and use. Take my audio system as an example. At first, I had more than ten interfaces in my cMusic class. While I was integrating them into my game, I noticed though they were only responsible for one task, some tasks were actually relevant. I needed to call two or three functions to complete one single task. Later, I added some parameters to my interfaces and reduced the number of interfaces. The class then looked much more straightforward and easier to understand.
Comments