• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Wait Frames Script?

S

Shadowblitz16

Guest
is it possible to use ds_maps or ds_lists to make a timer call function?
something like...
Code:
var frame = wait_frames(4) // creates a timer and returns its current index
if (frame == 4) // if frame has ended and is about to get deleted in the ds_list or ds_map
{
    //do something
}
 

Hyomoto

Member
I have to admit, I came up with a few examples but the more I read your question the more confused I am about what you want to accomplish. So, I'm going to try to explain a bit about different types of timing and perhaps these will help you find a solution you are working for. A timer is really nothing more than a variable that counts down, or up, and you check it when it reaches a certain point. Since timing is very important in gaming, there are plenty of ways to not just use timers in your games, but also different ways to handle timing in general. Take for example:

Code:
timer += 1; if timer == 60 { timer = 0 }
Here's a timer that loops. The benefits here is that if you need something to happen every X frames, you can simply check for it:

Code:
if timer == 4 { do stuff }
In this case it will just continue looping forever, and the best part is any number of things could use this timer. Then again, as in your example, often you only need a timer that 'goes off' once and then is no longer used. When that's the case, your timer probably looks more like:

Code:
if timer > -1 { timer -= 0 }
Now we just check if it's run out:

Code:
if timer == 0 { do stuff }
So, in your case however you seem to want to create timers on the fly. That is to say, you have no idea how many timers you need. Well, while I really have trouble seeing a situation where this would be the best option, you could use a ds_map to keep track of timers and create and delete them as needed.

Code:
timers = ds_map_create(); timerID = 0
Code:
/// id wait_frames(x)
var _id = timerID++;

timers[? _id ] = argument0;

return _id;
Code:
var _nextTimer = ds_map_find_first( timers ), _thisTimer;

repeat ( ds_map_size( timers ) ) {
    _thisTimer = _nextTimer; _nextTimer = ds_map_find_next( timer, _thisTimer );
    timers[? _thisTimer ] -= 1;

    if timers[? _thisTimer ] == -1 { ds_map_delete( timers, _thisTimer ) }

}
What this code does is create timers on demand and give them a lifespan of whatever you specified, then returns the id of the timer created. You can use that id to check whether or not the timer has expired. I tried to match the outcome with your example, but it is a bit strange and I couldn't get it to work quite the way you asked with any simplicity. So, in this case you'd have to check if timers[? frame ] == 0 to figure out if your timer 'went off' (rather than frame == 4, that line confuses me thoroughly), though other than that the timers count down and are deleted without any further input once created so it's quite simple. I honestly can't imagine a situation where this would be super useful but the idea is functional, so let me explain it:

The first block of code is a creation event of some kind, we're simply creating a ds_map to hold the timers ( maps consist of key and value pairs, or as we are using them id and timer value pairs ). The next block of code is your 'wait_frames' function, which will take the value you give it, create a new timer in 'timers' (our ds_map) and return the id of that timer. The way this works is as I said, a ds_map is a key and value pair, the key can be whatever you want but it's what you use to reference that particular value. We need to make sure each timer is assigned a unique ID so that we don't accidentally overwrite any timers. So, it sets the var _id to _timerID++ (what this is doing is setting _id to _timerID, and then incrementing _timerID by 1, ensuring each id is 1 higher than the last used), then 'creates' a new timer by adding a new key and value pair to our timer's map.

Last is the step event. The issue with ds_maps is that because we reference values by key and value pairs we cannot simply sequentially loop through the list. This means we have to search for each entry in the list, reduce it, destroy it if it's no longer needed, and move onto the next timer. So, the first thing I do is set _nextTimer to be the first 'found' value in timers. I also create another local variable, _thisTimer. The purpose for doing so is as I delete timers, it's no longer possible to use them as a search point (because they no longer exist), so before I do anything with a timer I make sure to find the next one in the list. Then, I need a loop to check each timer. I use a repeat for this because I know how many timers I need to search by checking my map size. At no time will I need to search more or less, so it works perfectly for this. Next I set _thisTimer to match _nextTimer, and then set _nextTimer to find the next entry in timers. Finally, I reduce the timer by 1, and check if it has run out. If it has, ( it is = -1, which means last turn it was 0 ), I delete it from timers because it's no longer needed.

Now, this is a bit of an overengineered solution as chances are there are simpler ways to handle timers in your game. Of course the joy of programming can often be finding a silly solution, or in this case a really abstract one. It does have benefits, I wouldn't just give you some silly code, in that it is possible to simply create timers on the fly without having to assign them to anything specific. So if you need a really ambiguous timer solution, there you have it. Rather than a direct solution, more importantly I hope this gives you some ideas or helps you understand some different ways to look at a problem and find a solution that suits it! Have fun, and keep coding!
 
Last edited:
S

Shadowblitz16

Guest
thankyou I was thinking of being able to use in within statements so that it wait a specific number of frame when reached.
anyways I think I can do it now thankyou for your help
 
Top