# How do I find the right time for rhythm games?

Get help using Construct 2

### » 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
15
S
5
Posts: 56
Reputation: 1,404

### » 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
80
S
23
G
4
Posts: 311
Reputation: 13,069

### » Sun Jun 15, 2014 6:53 pm

Oh, that makes sense! I'll play around with the code a bit. Thanks!
B
15
S
5
Posts: 56
Reputation: 1,404

### » 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
38
S
10
G
9
Posts: 542
Reputation: 9,181

### » 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.
B
72
S
22
G
288
Posts: 3,862
Reputation: 158,460

### » 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,124
Reputation: 11,286

### » 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,124
Reputation: 11,286