How do I make something wait a certain amount of time before executing?

I am relatively new to Gamemaker, and I am having a problem that I can't figure out how to fix... Although I am sure the solution is very simple. So, what I have as of now is a player, (obj_player_ship), and when that player collides with obj_bullet_powerup, obj_player_ship is replaced with obj_rapid_fire. Which is basically the player ship but it fires super quickly. So, I want, after about say, 10 seconds, obj_rapid_fire to be replaced by obj_player_ship. But I can't figure out how to make it wait a certain amount of time. Anyways, I know how to use Alarms (sort of), and I'm sure I need to use one of them to do this, but I don't know what code I need to use. Here is the code I have so far to do all of this (this is a collision event BTW):
1.png
That isn't really much, but it's all there is as of now. I assume I need to make an alarm in obj_rapid_fire, then do something in the step event to make the alarm go off and destroy obj_rapid_fire, and create obj_player_ship where it was. But I don't know exactly what code I need to put to do that. I did make it at one point wait a split second and then do it, but when I tried making the number higher to make it wait longer, it just never changed back.
 

MVPBiggles

Member
Here's the manual page for alarms.

Alarms go down every step, so they'll go off on their own, at which point they will trigger the code in the alarm's respective event.

I don't know why changing the number of the alarm didn't change anything, because I can't see the code that updated the alarm. However, if you update the alarm in an event that occurs every frame, like the step event, then the alarm will never go down, because you'll be resetting it every frame.
 

nicolask

Member
Check the manual page for alarms

Be careful to not set the alarm/timer every step without a check, because if you do it will never go down. If you're doing it in a event that happens every frame like a Step or Draw event, do a simple check like

GML:
if alarm[0] == -1
{
    alarm[0] = 600;
}
Switch 600 for the amount of time you want. Just put this code in the step event of obj_rapid_fire, and in the alarm[0] event put the code that switches it into obj_player_ship.
 

chamaeleon

Member
Also keep in mind alarms will only count down, and execute the alarm event code when the countdown is done, as long as the instance counting down exists. If it is destroyed before the alarm gets to execute it will not execute the code.
 

Joe Ellis

Member
An alternative to using alarms (which ends up pretty much the same in code) is to make a variable "timer" set it to n time, then in the step event do:

GML:
if !--timer
{do_thing()}
It's basically asking if timer = 0 or less, as in it's ran out of time, do thing. The -- function is a good neat way of subtracting 1 from a variable.
So if you put -- before a variable it'll subtract 1 from it, same with ++, as you can imagine that adds 1. It doesn't really change anything, it just sometimes makes the code tidier and easier to look at. Of course you can instead do: variable += 1\-=1 on the line before. But sometimes if you want to pack something in one line the ++/-- are useful.
I prefer to use timer variables instead of the alarms cus they're controlled by the step event, whereas the alarms are a separate event, so if you wanted to pause the instance with something like:

GML:
if hurt
{
image_alpha = !image_alpha //make it flash
return false //end the event here, so none of the below code is run
}

///The rest of the player code is cancelled because it's hurt and can't move
If you used alarms they'd still count down and run whatever's in them and you might not want it to while the player is hurt or something.
So with timer variables you can choose exactly when they count down and do stuff

The alternative if you wanted to use alarms would be: "alarm[n] += 1" to make it cancel the countdown of that step, but it's just annoying.
It's just what I prefer though, it's up to you.. I just prefer to have more control over stuff rather than compromising and hatefully living with built in features haha
(hateful is such a strong word, maybe regretful or uncomfortable is more realistic)
 
Last edited:

TheouAegis

Member
GML:
with instance_create_layer(x,y,"Instances",obj_rapid_fire) {
    alarm[11] = room_speed * 10;
}
Inside obj_rapid_fire's Alarm 11 event:
GML:
instance_create_layer(obj_player_ship);
instance_destroy();
Although, you could be using instance_change() instead of destroying and creating instances. But sometimes that can cause other sorts of problems for rookies. I'll still toss out that suggestion, though.
 
Alright, I fixed it. IDK how I didn't think of doing that before... What I did was created an Alarm[1], put the code I wanted it to execute when the alarm went off inside of it, and then put the timer in the create event. I should have thought of that... Well, I knew it would be a simple fix. The code I used was this:

Inside Alarm1:
instance_create_layer(x,y,"Instances", obj_player_ship)
instance_destroy()

Inside Create event:
alarm[1] = 600

The 600 makes it wait 10 seconds since it is a 60 FPS game. That is the same code I had put in before, but I had put it in the Step event. And it had been waiting a split second when I had put alarm[1] = 1, but when I raised the number any it didn't work.
Anyways, thanks!
 

Yal

šŸ§ *penguin noises*
GMC Elder
Alright, I fixed it. IDK how I didn't think of doing that before... What I did was created an Alarm[1], put the code I wanted it to execute when the alarm went off inside of it, and then put the timer in the create event. I should have thought of that... Well, I knew it would be a simple fix. The code I used was this:

Inside Alarm1:
instance_create_layer(x,y,"Instances", obj_player_ship)
instance_destroy()

Inside Create event:
alarm[1] = 600

The 600 makes it wait 10 seconds since it is a 60 FPS game. That is the same code I had put in before, but I had put it in the Step event. And it had been waiting a split second when I had put alarm[1] = 1, but when I raised the number any it didn't work.
Anyways, thanks!
Since you're starting with alarm 1 instead of alarm 0, just figured I should point out that every object has their own alarms; you don't need to worry about using different alarms for different objects.

Also, a big source of alarm code not working is accidentally resetting the alarms every step, so they never get a chance to count down - I think this is why setting the alarm to 1 step worked (because they could down in increments of 1 step) but anything higher didn't (it would keep getting reset to the full countdown every step and never getting a chance to trigger)
(Sometimes you might want to INTENTIONALLY reset alarms like this, though - for instance triggering an idle animation if the player doesn't press any button for 5 seconds; every button check would reset the timer that starts the idle animation)
 
" Since you're starting with alarm 1 instead of alarm 0, just figured I should point out that every object has their own alarms; you don't need to worry about using different alarms for different objects. "
I did start with Alarm 0 for something else inside of that object already. That's why I used alarm 1. Thanks anyway.
 
Top