I thought we could all share thoughts on how to make a rhythm-based game work as good as possible. I don't know if there's any interest but I'm almost done with one, so I can at least share my experiences so that if anyone is hesitant to make a rhythm-based game they can get a head start.
First off, we check the timing of the song in question. In this example we'll be working with a 115BPM song. Let's say we want to time each beat of that song; this would be every 0.521739 seconds.
So we store that in a float called BPM# = 0.5217. We initiate a float called beatTimer# at BPM# because we want to start with a beat. Also this is all ran at 60fps or less, of course precision would increase with more FPS but this is supposed to run on android-devices.
I've done four tests on how to hit that timing right every beat, I've stored 50 beat-times in an array and printed the results in a text-file for each test. In every one I increase beatTimer# by frameTime# (stores getFrameTime()) each frame.
Test One - The simple (and ineffective as you'll see) way:
if beatTimer# => BPM#
beatTimer# = 0.0000
Do-everything-you-want-happening-on-a-beat()
endIf
Results:
Goal: 0.521700
Average: 0.534519
Diff:
0.012819
This of course doesn't work. It overreaches BPM# every time, naturally.
Test 2 - Check if last beatTimer# overreached and adjust:
if beatTimer# => BPM# - (frameTime# * lastFrameFast#)
if beatTimer# > BPM# then lastFrameFast# = 0.5
if beatTimer# < BPM# then lastFrameFast# = 0.0
beatTimer# = 0.0000
Do-everything-you-want-happening-on-a-beat()
endIf
Result:
Goal: 0.521700
Average: 0.526174
Diff:
0.004474
Not too bad. Could probably work with this. However over time this would get more and more of beat (by 0.0044 seconds/beat)
Test 3 - Store the difference and adjust:
if beatTimer# => BPM# + difference#
difference# = difference# + (BPM# - beatTimer#)
beatTimer# = 0.0000
Do-everything-you-want-happening-on-a-beat()
endIf
Result:
Goal: 0.521700
Average: 0.521989
Diff:
0.000289
Better! And more on point, this would get better or at least not worse the longer the game runs.
Test 4 - A mix of 2 and 3:
if beatTimer# => BPM# - (frameTime# * lastFrameFast#) + difference#
if beatTimer# > BPM# then lastFrameFast# = 0.5
if beatTimer# < BPM# then lastFrameFast# = 0.0
difference# = difference# + (BPM# - beatTimer#)
beatTimer# = 0.0000
Do-everything-you-want-happening-on-a-beat()
Result:
Goal: 0.521700
Average: 0.521574
Diff:
-0.000126
Quite acceptable I would say. Even the music-man I work with was satisfied
Edit: I just let test 4 run for 500 beats, just over 4 minutes, and the results are very good:
Goal: 0.521739
Average: 0.521725
Diff:
-0.000014
So there you have it. Please fill in if you have a better way of doing this or you if you have any questions at all.
lil*****willy
My hovercraft is full of eels