How do I find the right time for rhythm games?

Get help using Construct 2

Post » Sun Apr 06, 2014 7:35 pm

I'm working on a rhythm game, and it functions just like a guitar hero game. I'm using a script like this:

every 0.XX seconds | aspawner spawn note at image point 0


It works, but I need to find out the right times to spawn the note.

For example:

I want the notes to spawn every beat of an 138 bpm song. I take 138/60 to get the beats per second, and end up with 2.3. which is the number of beats per second, right? So how do I set it up to spawn a note every beat?
B
8
S
3
Posts: 48
Reputation: 1,013

Post » Fri May 30, 2014 9:52 pm

You simply need to access the Time and dt values. I'm going to describe this in a general coding fashion here. You basically want to check on each frame if you're hitting a beat or not:

At the start of the gameplay session, you store
Code: Select all
beatsPerMinute = retrieveBpmFromSong(currentSong);
beatsPerSecond = beatsPerMinute/60;
startTIme = Time;
currentTime = startTime;
secondsPerBeat = 1/beatsPerSecond;
lastBeatTime = 0;


On every frame, you want to get your current time, and check if it's approximately a multiple of your bpm. I you have hit a bit in the past secondsPerBeat though, you don't want the game to take it in account again in the next frame:

Code: Select all
currentTime += dt;
if(currentTime - lastBeatTime < secondsPerBeat)
{
if( 0.8 * secondsPerBeat < curentTime % beatsPerSecond < 1.2 * secondsPerBeat)
{
lastBeatTime = currentTime; // you trigger some visual thing, store values, whatever. At least, you know that this frame's timing is a beat. You can check the player's precision against it.
}
}


It's a bit late, I'll try to make something like that directly on construct later!
Cheers,
Nathan
B
77
S
22
G
4
Posts: 311
Reputation: 12,634

Post » Sun Jun 15, 2014 6:53 pm

Oh, that makes sense! I'll play around with the code a bit. Thanks!
B
8
S
3
Posts: 48
Reputation: 1,013

Post » Sat Nov 15, 2014 1:50 am

Can someone make an capx with this logic?
seems kinda advanced, but its exacly what i need!
B
37
S
9
G
8
Posts: 541
Reputation: 8,554

Post » Sat Nov 15, 2014 3:37 am

I'm actually working on a step sequencer. The formula I came up with is:
240/(noteLength*tempo)

noteLength is the denominator of the note, so a 1/4 note would = 4, a 1/2 note would =2...
tempo is bpm
a beat is considered a 1/4 note

So, as per above, 240/(4*138) = 0.435 seconds between notes.

Put another way, to see how long 138 beats take, 138 * 0.0.435 = 60 seconds; that is 138 bpm take 60 seconds to play.

You can use the Timer behaviour to time the beats/notes.
ImageImageImage
B
71
S
21
G
221
Posts: 3,649
Reputation: 124,227

Post » Sat Aug 13, 2016 1:37 pm

blackhornet wrote:I'm actually working on a step sequencer. The formula I came up with is:
240/(noteLength*tempo)

noteLength is the denominator of the note, so a 1/4 note would = 4, a 1/2 note would =2...
tempo is bpm
a beat is considered a 1/4 note

So, as per above, 240/(4*138) = 0.435 seconds between notes.

Put another way, to see how long 138 beats take, 138 * 0.0.435 = 60 seconds; that is 138 bpm take 60 seconds to play.

You can use the Timer behaviour to time the beats/notes.


Did you manage to finish this, @blackhornet ?
B
41
S
12
G
14
Posts: 1,117
Reputation: 11,253

Post » Mon Aug 15, 2016 11:53 am

Valerien wrote:You simply need to access the Time and dt values. I'm going to describe this in a general coding fashion here. You basically want to check on each frame if you're hitting a beat or not:

At the start of the gameplay session, you store
Code: Select all
beatsPerMinute = retrieveBpmFromSong(currentSong);
beatsPerSecond = beatsPerMinute/60;
startTIme = Time;
currentTime = startTime;
secondsPerBeat = 1/beatsPerSecond;
lastBeatTime = 0;


On every frame, you want to get your current time, and check if it's approximately a multiple of your bpm. I you have hit a bit in the past secondsPerBeat though, you don't want the game to take it in account again in the next frame:

Code: Select all
currentTime += dt;
if(currentTime - lastBeatTime < secondsPerBeat)
{
if( 0.8 * secondsPerBeat < curentTime % beatsPerSecond < 1.2 * secondsPerBeat)
{
lastBeatTime = currentTime; // you trigger some visual thing, store values, whatever. At least, you know that this frame's timing is a beat. You can check the player's precision against it.
}
}


It's a bit late, I'll try to make something like that directly on construct later!
Cheers,
Nathan

@Valerien I'd like to use this to sync loops to the nearest 8th note, so you can play a loop or a one-shot and it won't play/start looping until the timer is on an 8th note division, could this be used for doing that?
B
41
S
12
G
14
Posts: 1,117
Reputation: 11,253


Return to How do I....?

Who is online

Users browsing this forum: bluesun66, Kenthria, Malhog, plinkie, Yahoo [Bot] and 1 guest