• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

GMS 2 Alarm Not Counting [SOLVED]

I'm trying to make an animation play after the player's HP runs out and before the player restarts the level. But even though I have an alarm set, the player restarts right after the HP runs out, not giving the animation time to play and bypassing the alarm. Here is the code I'm using. Is there something I'm missing? My game is set at 60 FPS so, I've set it for about 4 seconds to wait for. By the way, "s_player_game_over" is the animation that's supposed to play. Not the game over screen.
Code:
if global.player_HP <= 0 && !invincible_ && global.player_lives >= 0 {
    
    create_animation_effect(s_player_game_over, x, y, 10, true);   
    alarm[3] = 240;   
    instance_destroy();
    global.player_lives -= 1;
    ini_load("save_data.ini");
}
 
You destroy the instance immediately. The alarm can't count if there is no instance.
What I'm trying to do is, play animation, count 4 seconds then destroy.

Since I have the alarm first, I thought it would wait until the alarm is over. How else could I do it?
 
Put this code IN the alarm event:
Code:
instance_destroy();
global.player_lives -= 1;
ini_load("save_data.ini");
An alarm doesn't "hold" on the line of code that sets the alarm until the alarm is over...The rest of the code after you set the alarm will still run like normal (as in, in the same frame). The only thing the alarm does is make it so that the actual Alarm Event will run IT'S code when the alarm timer has hit 0.

EDIT: Oh, also, you need to have a trigger that will stop this:
Code:
if global.player_HP <= 0 && !invincible_ && global.player_lives >= 0 {  
   create_animation_effect(s_player_game_over, x, y, 10, true);   
   alarm[3] = 240;   
}
From running more than once, otherwise you'll just be setting alarm[3] to 240 every step and it will never count down. One way to do this is:
Code:
if (global.player_HP <= 0 && !invincible_ && global.player_lives >= 0 && alarm[3] < 0) {
   create_animation_effect(s_player_game_over, x, y, 10, true);   
   alarm[3] = 240;   
}
 
Last edited:

TheouAegis

Member
Or just set the player to invincible, since that's one of the conditions. lol I'm guessing one of the other alarms is reserved for clearing invincible state.
 
Put this code IN the alarm event:
Code:
instance_destroy();
global.player_lives -= 1;
ini_load("save_data.ini");
An alarm doesn't "hold" on the line of code that sets the alarm until the alarm is over...The rest of the code after you set the alarm will still run like normal (as in, in the same frame). The only thing the alarm does is make it so that the actual Alarm Event will run IT'S code when the alarm timer has hit 0.

EDIT: Oh, also, you need to have a trigger that will stop this:
Code:
if global.player_HP <= 0 && !invincible_ && global.player_lives >= 0 { 
   create_animation_effect(s_player_game_over, x, y, 10, true);  
   alarm[3] = 240;  
}
From running more than once, otherwise you'll just be setting alarm[3] to 240 every step and it will never count down. One way to do this is:
Code:
if (global.player_HP <= 0 && !invincible_ && global.player_lives >= 0 && alarm[3] < 0) {
   create_animation_effect(s_player_game_over, x, y, 10, true);  
   alarm[3] = 240;  
}
Thanks, I seem to have it working now. It goes really fast though. But I think some small changes and it should work!

Your above code did work like I would like it to, but the player didn't get destroyed and the animation played anyway. I've tried adding the code in the alarm event but didn't seem to work before.

Here's what worked if it will help anyone:

Code for the Player Step Event
Code:
if global.player_HP <= 0 && !invincible_ && global.player_lives >= 0 {
    
    instance_destroy();
    create_animation_effect(s_player_game_over, x, y, 10, true);   
    alarm[3] = 240;  
}
Code for the Alarm Event
Code:
global.player_lives -= 1;
ini_load("save_data.ini");
 
Look at my edit in my original post or follow what TheouAegis suggested.

EDIT: You haven't done it correctly. instance_destroy() needs to be in the alarm, not in the Step Event. If you destroy the player object, the alarm gets deleted as well, so it will never trigger.
 

TheouAegis

Member
Like, seriously. If the alarm counts down even after instance_destroy() is called, that's a BUG in GM. There's no way that was put in intentionally as it runs counter to 10 years of GM coding.
 
Look at my edit in my original post or follow what TheouAegis suggested.

EDIT: You haven't done it correctly. instance_destroy() needs to be in the alarm, not in the Step Event. If you destroy the player object, the alarm gets deleted as well, so it will never trigger.
Like, seriously. If the alarm counts down even after instance_destroy() is called, that's a BUG in GM. There's no way that was put in intentionally as it runs counter to 10 years of GM coding.
For some reason now it works almost exactly as I want it too.
 
I think what is happening though, is the o_player is getting destroyed and I'm creating a new sprite animation at the player's position (which is not the player object anymore) then when the alarm is over the rest of the code runs.
 
No that is not what's happening. That's not how GM works. If you destroy an instance, all of that instance's code stops running. Including alarms, etc. Something else is going on. Move the instance destroy to the alarm event like we have told you.
 
Whenever I put code in the alarm[3] event that code for some reason gets ignored. But after changing the code and adding more conditions, it seems to be working better now.
 
Ok, this time I actually have it working the way I wanted it too.
Instead of destroying the player object, I just made it not visible while the animation played then it goes to the game over room.
Here is the code that I used:
Code:
if global.player_HP <= 0 && !invincible_ && global.player_lives == 0 {
        
    global.player_lives -= 1;
    invincible_ = true;
    visible = false;
    create_animation_effect(s_player_game_over, x, y, 2, true);
    alarm[3] = global.one_second * 2;
}

// Lives

if global.player_lives < 0 && alarm[3] < 0 {
    room_goto(r_game_over);
}
 
Top