First off, don't use alarms for this (as convenient as they are). If the game lags for some reason the music will be off with your alarm triggers because alarms are based off of your frame-rate and audio is based off of real time. For example, you might have a song with 120bpm. Let's say you have your alarm going off every 30 frames in a 60fps game (so twice a second). Should the game lag to 30fps for a beat, that alarm will take an entire second instead of half a second to execute and thus every beat afterwards will be off by half a second.
Use delta time. GameMaker has a built-in variable called "delta_time" which is the length of time since the last frame (in micro-seconds, so 1/1000000th of a second). Instead of alarms you could keep a timer that starts at 0 at audio start and increments by delta_time every frame to keep track of timing that way. In the above example you would simple execute a beat every 500000 micro seconds instead of every 30 frames. This way it is based on your system clock so lag won't throw off your game logic.
So, let's say you want a beat every 500000 micro seconds and you have a variable called `song_timer` that is incremented by delta_time every frame. How do you know when it has been 500000 micro seconds? Well, if you 'reset' the value every 500000 micro seconds it will be a new beat every time the value is 0. So something like this:
Code:
song_timer += delta_time; // Add number of micro-seconds between frames
song_timer %= 500000; // Wrap around value 500000
Now, this won't work because the value will rarely be EXACTLY 0, you might be off by some number of micro-seconds. So when checking for user input, let's add an 'error' threshold where they only need to be within a certain range. Let's say 1/10th of a second, so 100000 microseconds. It might look like this:
Code:
song_time += delta_time;
song_timer %= 500000;
// Check for user input:
var threshold = 100000; // Number of micro-seconds we can be off by
if (keyboard_check_pressed(vk_up)){
if (song_timer < threshold or (500000 - song_timer) < threshold){
// They hit the beat on time!
}
else{
// They were off beat
}
}
Does that make sense?
For the actual visual representation, it should technically be separate from your actual input detection. They shouldn't effect each-other. However, the logic for drawing the sprite should be similar. In your video you have notes circling around the player and the bottom one gets hit on the beat. That is as easy as this:
Code:
var cx = 512; // Some point to circle around
var cy = 512;
var offset = 0; // Degrees offset from the beat (0 = bottom on beat, 180 = top on beat)
var distance = 128; // Number of pixels away from center
draw_sprite(sprite_index, image_index, cx + lengthdir_x(distance, 360 / 500000 * song_timer + offset), cy + lengthdir_y(distance, 360 / 500000 * song_timer + offset));
With an offset of 0 this will draw the sprite at the bottom of your center point (in the given video this would be the character) right on the beat. For the other notes you would just increment the offset some amount for each to get the swirling circle.
I have to be somewhere in 5 so I'm out, but if you have questions I'll come back and check afterwards.
EDIT:
In regards the comment about GameMaker's capability, they don't know what they are talking about. GameMaker is perfectly capable (and easily so) of doing something like this. I made my own rhythm game engine years back and it took less than a day to implement the underlying timing system.