Play a different sound for each instance of object, not at the same time

The user rearranges music notes (“note bricks”) into a sequence and then clicks a ‘play’ button to hear the notes in order.

But I can’t for work out how to stop GDevelop from playing all the notes at the same time. There needs to be a wait in between each note, in the order in which the user has arranged them.

If this was Java, I’d propably use a switch case and a for loop.

I tried using an array too (e.g. NotesToPlay[E,C,F,G,G]) but that didn’t help.

I guess I could add a hidden object that moves from left to right and, upon collision with each ‘note brick’, triggers the corresponding sound to play.

Any suggestions? Thanks

Finally solved the problem by creating a custom extension/function that plays the corresponding note passed to it. Then I simply run through an array of note letters to play.

image

I would want to improve this by storing the array index and the time delay as variables. Then:

repeat VariableChildCount(NotesToPlay) times
   | wait noteDelay seconds
   | play note: NotesToPlay[noteIndex]

This way you can adjust the speed of playback, and have a flexible array size.

An object that moves across the notes would be pretty cool too, although you could run into issues with collision accuracy (especially at high speeds).

1 Like

I like the idea of an object that is tweened from left to right. You could use a collision with a trigger once. It would give a nice visual feedback as well.

1 Like

Thanks, but how does the noteIndex value increase by 1, in your example, without using something like noteIndex add 1 into the repeat function?

e.g.

However, this still doesn’t work. All the notes play at once. I can’t work out how to get the wait command to work in a for/repeat loop.

Crap, you’re right, this doesn’t work because the Wait instruction doesn’t hold up the rest of the loop.

You would have to multiply the wait time by the index number + 1. So it would be, Wait 0.3 * (NoteIndex + 1) seconds.

Another way to do it would be if the delay was a variable, just add 0.3 to the variable on each iteration. And yes, you need to increment the NoteIndex manually, I was just too lazy to type that part :stuck_out_tongue:

Also, playing the note should happen after the Wait action, while changing variables relevant to the next loop iteration should happen before. Wait can be confusing because it only delays the next actions and sub-events. It doesn’t delay any events (or loop iterations) that are not indented after the Wait. For this reason I often initialize index variables at -1

declare noteIndex = -1
   repeat
      <no conditions>    | change noteIndex: add 1
                         | wait 0.3 * (noteIndex + 1) seconds
                         | play note
1 Like

Brilliant, thank you! I’ll try this, and I’m realising now that wait is more complicated that I first assumed! :grinning: