• 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!

How to make objects wait in line and perform events only after the one before?

So basically, my strategy game has quite a bunch of announcements appearing to the player in the middle of gameplay, be it 'you captured this city' or 'this guy has died here or there'. They don't pause the game, just read on the screen awhile before disappearing. But if there happens to be a lot going on and the game would f.ex. throw 5 announcements on top of each other, how do i make them kinda stack - that is, the newer announcement-objects would only show up (perform their Draw-events, basically) after the one before has disappeared?
 

JackTurbo

Member
Where ever you currently tell the game to create the pop up dont, instead stick it into a ds_queue.

Then have a Gui object that if the queue isnt empty displays the current ds_queue_head value for x number of frames before running ds_queue_dequeue.

This should mean it will now show the next value if there is one.


Here's a pretty rough over view of how I would do it. I've not tested this so it might need some tweaking...

Somewhere you want to create the queue (a control object of some sort would make sense) but you only want to do this once. Also don't forget to destroy the queue when you're finished with it! Like when the level is over or what ever.
Code:
//create the queue and store its id in a global variable for ease
global.notificationQueue = ds_queue_create();
Then where ever you're currently creating your notification pop up instead do something like.
Code:
//add your notification to the queue
ds_queue_enqueue(global.notificationQueue, "your notification here");
Then create an object to display the notification
create event
Code:
showingNotification = false;
//This is a boolean instance variable we'll use in the draw event to know if we should show a notification or not

alarm[0] = 5;
//this is the timer for the alarm that will decide if we should show a notification or not
Alarm[0]
Code:
if(showingNotification){ //are we currently showing a notification?
    ds_queue_dequeue(global.notificationQueue); //if yes then dequeue that notification
    showingNotification = false; //and set this variable to false as we are no longer showing that notification
}else{ //if we're not showing a notification
    if(!ds_queue_empty(global.notificationQueue)){ //then lets check if there is one in the queue to show
        showingNotification = true;   //if there is one then lets show it
    }
}

//now lets reset the timer for the notification
if(showingNotification == false){
    alarm[0] = 5; //how long to wait between subsequent notifications and how frequently to check for notifications (so that there is a small pause between them to make it more noticeable to player)
}else{
    alarm = 30; //how long to show notification for in frames
}
draw_event
Code:
if(showNotification == true){ //if we should show a notification then do the drawing, if not then dont
    //draw any backgrounds for the pop ups or what ever here
    draw_text(x, y, ds_queue_head(global.notificationQueue)); //Now draw the value of the current head of the queue
}
 
Last edited:

NightFrost

Member
The problem with showing one notification at a time is how they start stacking up in the queue. This is not a problem if you're not expecting many notifications at a time, but if you are and they can be time-critical, you need to code a system that can draw multiple of them at a time. For that you'de need to use a ds list instead as queues are "pop it out and its gone" type of thing. In pseudocode the display logic would go something like this (not tested):
Code:
CREATE
set notification timer to zero

STEP
is the notification ds list empty?
    YES: do nothing
    NO:
        loop through the ds list and show five or ds_list_size (whichever is lower) amount of list entries (or more or less depending how many you want to show on screen at a time)
        increase notification timer by one
        is notification timer at five seconds (room_speed * 5)? (set any time you want for alerts to remain on screen)
        NO: do nothing
        YES:
            remove notification ds list entry at position zero
            set notification timer to zero
 
oh wow. thanks for replies guys. never used this ds_queue Action before, so there's some getting used to for me to do here. i've never utilized any of these ds_something codes, but i'll go and give your suggestions a try... thanks again
 

TheouAegis

Member
Wouldn't need a list, but you would need an extra variable to hold the string that gets pulled off the queue. However, since a ds_list is essentially a queue, a list would be more efficient.
 
Wouldn't need a list, but you would need an extra variable to hold the string that gets pulled off the queue. However, since a ds_list is essentially a queue, a list would be more efficient.
thanks 4 reply, i tried with ds_queue tentatively since i only got ur comment afterwards, seems to work fine for now but lots of ppl have been praising ds_list so i'm sure to give it a shot as well later
 
Where ever you currently tell the game to create the pop up dont, instead stick it into a ds_queue.

Then have a Gui object that if the queue isnt empty displays the current ds_queue_head value for x number of frames before running ds_queue_dequeue.

This should mean it will now show the next value if there is one.


Here's a pretty rough over view of how I would do it. I've not tested this so it might need some tweaking...

Somewhere you want to create the queue (a control object of some sort would make sense) but you only want to do this once. Also don't forget to destroy the queue when you're finished with it! Like when the level is over or what ever.
Code:
//create the queue and store its id in a global variable for ease
global.notificationQueue = ds_queue_create();
Then where ever you're currently creating your notification pop up instead do something like.
Code:
//add your notification to the queue
ds_queue_enqueue(global.notificationQueue, "your notification here");
Then create an object to display the notification
create event
Code:
showingNotification = false;
//This is a boolean instance variable we'll use in the draw event to know if we should show a notification or not

alarm[0] = 5;
//this is the timer for the alarm that will decide if we should show a notification or not
Alarm[0]
Code:
if(showingNotification){ //are we currently showing a notification?
    ds_queue_dequeue(global.notificationQueue); //if yes then dequeue that notification
    showingNotification = false; //and set this variable to false as we are no longer showing that notification
}else{ //if we're not showing a notification
    if(!ds_queue_empty(global.notificationQueue)){ //then lets check if there is one in the queue to show
        showingNotification = true;   //if there is one then lets show it
    }
}

//now lets reset the timer for the notification
if(showingNotification == false){
    alarm[0] = 5; //how long to wait between subsequent notifications and how frequently to check for notifications (so that there is a small pause between them to make it more noticeable to player)
}else{
    alarm = 30; //how long to show notification for in frames
}
draw_event
Code:
if(showNotification == true){ //if we should show a notification then do the drawing, if not then dont
    //draw any backgrounds for the pop ups or what ever here
    draw_text(x, y, ds_queue_head(global.notificationQueue)); //Now draw the value of the current head of the queue
}
Works like a charm for now, only obscurity i can think of is where to place the code to destroy the queue. Since the game basically takes place on a massive room (and Persistent one), do i need to destroy the queue every time the players visits another room, or if f.ex. the player returns to main menu?
 

NightFrost

Member
As long as you can avoid accidentally recreating it and/or losing the pointer to the DS, you don't really need to ever destroy it. For example if you just create it at game start and store the pointer in some global, there's no pressing need to destroy it. The memory leak problem with DSes comes from accidentally creating them again and again in instance create events or function calls or such, losing the pointers to the old ones and leaving them hanging in the memory.
 
As long as you can avoid accidentally recreating it and/or losing the pointer to the DS, you don't really need to ever destroy it. For example if you just create it at game start and store the pointer in some global, there's no pressing need to destroy it. The memory leak problem with DSes comes from accidentally creating them again and again in instance create events or function calls or such, losing the pointers to the old ones and leaving them hanging in the memory.
Aight got it, i already noticed an issue, when i tried destroying the queue upon f.ex. returning to main menu or leaving the main room altogether, there was strange lagging in the game, the FPS started doing drops occasionally. dunno but i linked it to the fact that i was just testing destroying the ds_queue. Atm, the game is set to not destroy it and now it works fine.
 
K

kevins_office

Guest
If the ds_queue is an instance variable in an object, and you are using that objects draw event, so its basically a self contained system, then just put the ds_queue_destroy() in the Clean Up Event. Then its self managed, because if you change rooms, or go to a menu that ends up destroying that object, then the queue gets cleaned up with it.
 
If the ds_queue is an instance variable in an object, and you are using that objects draw event, so its basically a self contained system, then just put the ds_queue_destroy() in the Clean Up Event. Then its self managed, because if you change rooms, or go to a menu that ends up destroying that object, then the queue gets cleaned up with it.
alright, thanks 4 sharing ur expertise!
 
Top