Building a Rhythm Game in C
This is the rhythm game I made as a first-year term project.
Making the game itself didn’t take long, but I remember struggling to get the notes in sync.
How to Play
Use the D, F, J, K keys to hit notes.
If you hit a note precisely, the judgment is Excellent. If you hit slightly late, the judgment is Good.
Hitting notes consecutively builds a combo.
Your score increases based on combo and judgment. The scoring formula is:
| |
In the settings menu you can toggle two options:
Turning on Note Recording Mode enables an editor mode.
The music plays but no notes fall. While the song is playing, your key inputs are saved as notes to a file namednote.txt.Turning on Debug Mode enables debugging.
You can check the screen refresh delay.
Explanation
The simple text animation at the start is implemented with a
forloop.
I store the text in a 2Dchararray and repeatedly print and erase one line at a time.When a song is selected, the program reads a text file containing the notes into a
charbuffer.0means no note,1means a note exists.The music is played using the
PlaySoundfunction.Notes are rendered by changing the console text color and printing spaces so they look like rhythm-game notes.
I change text color withSetConsoleTextAttribute.The per-frame delay is matched to the song’s BPM.
Because notes must be drawn quickly, delay variance is inevitable.
I measure time at the start and end of each loop and adjust the delay to keep it uniform.Using a variation of double buffering, I clear only the regions where the front and back buffers differ (with spaces) and then draw.
Key input is read with
GetAsyncKeyState.
For multithreading I use_beginthreadex, which allows multiple keys to be registered simultaneously.When a note reaches the judgment line, I compare the screen buffer with the current key state to determine the judgment.
By comparing the states of the front and back buffers, I distinguish hold notes from tap notes.
If you press exactly on time, it’s Excellent. If you press early, it’s Good. If you miss, it’s Miss.
Akey_statevariable prevents holding a key to farm points.During gameplay the counts of Excellent, Good, and Miss are recorded.
A rank is assigned based on their ratios.
When the game ends it shows the judgments and draws a graph so you can see your performance at a glance.
