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

Lose "depth" object with instance_deactivate_all and instance_activate_all

globule

Member
Hello,

I am encountering a problem.
I try to pause my game

For that I use instance_deactivate_all and instance_activate_all

But I have the impression that there is a bug in game maker.
Indeed, the depth is not respected and when I reactivate the instances, the background image appears on the sprites.

if (keyboard_check_pressed(ord("P")) && paused==false)
{
instance_deactivate_all(true);
paused=true;
}

if (keyboard_check_pressed(ord("O")) && paused==true)
{

paused=false;
instance_activate_all();
}
 

Geners

Member
This is a known issue within the program. Unless you specifically set the depths to different numbers their order will change so objects at the same depth may layer incorrectly.

I suggest you either set the depths of your objects or use another method to pause your game, for instance you can create a global boolean called "paused" and then check if paused is true before you do anything in the step events of your objects.
 

globule

Member
I am a little surprised by your answer. If this is a known problem why is it not resolved? All games need a paus. Managing all the elements one by one is a huge job if the project is important like mine
 

Geners

Member
I am a little surprised by your answer. If this is a known problem why is it not resolved? All games need a paus. Managing all the elements one by one is a huge job if the project is important like mine
GMS definitely has its flaws.

When you create your object instances use instance_create_depth(); and then just set a varying depth for each object that needs to be layered in a specific way. If you want to keep track of important depths you can make an enum like this

GML:
enum depthSet {
        background = 5,
        foreground = 4,
        effects = 3,
        close = 2,
        closer = 1,
        closest = 0
}

instance_create_depth(x,y,depthSet.foreground,object)
Enums are in the global scope so if you just set this once you should be able to use it any time you create an instance.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
I'm not sure this an "issue" with the program, but rather a known and documented side-effect of using layers to efficiently render items in a room. Instances placed on the SAME layer (or at the same depth) do not have a guaranteed render order, and if you want something to specifically render over something else then you use a different layer, or you use the "depth" variable (which still uses layers, only they are managed by the engine).

Now, if the background image is on a higher depth/layer than the other objects and is then being rendered over everything after a deactivate, then THAT is a bug and you should make a bug report about it, supplying a test project YYZ that shows the issue. But if the background is being drawn by an instance, and that instance is on the same layer as other instances, then it is NOT a bug and simply just the way GM works. Like I said, render order of instances on the same depth/layer is not guaranteed.
 

Tyg

Member
There is another way, i use it on a game with scrollable view cameras and even text messages or enemy fireballs stop in their tracks and continue when unpaused, it works great
i do it with 2 objects pause and unpause, ill explain how i implemented them and show which events to put the code
ill explain a fixed room size and tiled scrollable also

ill refer to level room as the game room to be paused
make a pause room with nothing in it, persistant objects will carry over to the pause room so try not to use them especially like player
make the room size the same as your level room if it is the screen size, if it is bigger for scrolling make the room size the camera or veiwport size

make a pause object and put it in the level room
make an unpause object and put it in the pause room, mine is rm_pause

the pause object
make 3 events create,key press P and key up P ...this is just the way i coded it but try only call it once and not in a step event

** in create event of pause object:
global.Paused = false;
global.Paused_room = room;
global.OldScreen = -1;

** in key press P event: (or any key you want for pausing)
global.Paused = true;
if(!(surface_exists(global.OldScreen)))
{
global.OldScreen = surface_create(camera_get_view_width(view_camera[0]), camera_get_view_height(view_camera[0]));
view_surface_id[0] = global.OldScreen;
}

**in the key up P event
room_goto(rm_pause);

**************************************************
the unpause object
make 4 events create, draw_gui, key press P and key up P

** in create event of unpause object:
view_surface_id[0] = global.OldScreen;

** in key press P event: (or any key you want for unpausing)
global.Paused = false;

**in the key up P event:
surface_free(global.OldScreen);
room_goto(global.Paused_room);

**in the DrawGui event:
if(surface_exists(global.OldScreen))
{
draw_surface_stretched(global.OldScreen, 0, 0, display_get_gui_width(), display_get_gui_height());

// This is all that is really necessary
// Implement anything you want to draw here like so

draw_set_colour(c_yellow);
draw_set_halign(fa_center);
draw_set_valign(fa_top);
draw_text_transformed(display_get_gui_width()/2, display_get_gui_height()/2, string("PAUSED") + "", 4, 4, 0);
}

Thats it, make sure that you put the pause object in the room you want to pause and the unpause object in the pause(rm_pause) room
This way you don't need to deactivate an instance unless it is persistant and visible in multiple rooms or need to check every instance if it is paused enjoy :)
You can also do whatever to the surface in the pause room animate it or use a shader because it will be destroyed when you exit the pause room

if you can't get it to work i can put the 2 objects in a dropbox
 
Last edited:

Yal

šŸ§ *penguin noises*
GMC Elder
There's another problem with your code that you might wanna be aware of for the future: instance_activate_all / instance_deactivate_all doesn't take effect until the next step (or rather, instances are moved from the "active" and "inactive" list between steps), so be careful if you're e.g. planning to read data from newly activated instances.
 

globule

Member
Thanks, The problem with using the technique which consists in not being able to execute the code "step" if a variable pause = true is that the animations which use "speed" and "direction" continue to execute.

I finally managed to pause by specifying the depth for each object and using the following code. It seems to be working very well.
** Create : **
paused_=false;
pause_sprite_=noone;


** Draw GUI : **
if paused_
{
draw_sprite_ext(pause_sprite_,0,0,0,1,1,0,c_white,1);
}

** Event Press P : **
if not paused_
{

paused_=true;
if sprite_exists(pause_sprite_) sprite_delete(pause_sprite_);

pause_sprite_=sprite_create_from_surface(application_surface,0,0,1366,768,false,true,0,0);
instance_deactivate_all(true);
}
else
{
paused_=false;
instance_activate_all();
}
 

globule

Member
>> if you can't get it to work i can put the 2 objects in a dropbox
Yes please, i want to try your technique



There is another way, i use it on a game with scrollable view cameras and even text messages or enemy fireballs stop in their tracks and continue when unpaused, it works great
i do it with 2 objects pause and unpause, ill explain how i implemented them and show which events to put the code
ill explain a fixed room size and tiled scrollable also

ill refer to level room as the game room to be paused
make a pause room with nothing in it, persistant objects will carry over to the pause room so try not to use them especially like player
make the room size the same as your level room if it is the screen size, if it is bigger for scrolling make the room size the camera or veiwport size

make a pause object and put it in the level room
make an unpause object and put it in the pause room, mine is rm_pause

the pause object
make 3 events create,key press P and key up P ...this is just the way i coded it but try only call it once and not in a step event

** in create event of pause object:
global.Paused = false;
global.Paused_room = room;
global.OldScreen = -1;

** in key press P event: (or any key you want for pausing)
global.Paused = true;
if(!(surface_exists(global.OldScreen)))
{
global.OldScreen = surface_create(camera_get_view_width(view_camera[0]), camera_get_view_height(view_camera[0]));
view_surface_id[0] = global.OldScreen;
}

**in the key up P event
room_goto(rm_pause);

**************************************************
the unpause object
make 4 events create, draw_gui, key press P and key up P

** in create event of unpause object:
view_surface_id[0] = global.OldScreen;

** in key press P event: (or any key you want for unpausing)
global.Paused = false;

**in the key up P event:
surface_free(global.OldScreen);
room_goto(global.Paused_room);

**in the DrawGui event:
if(surface_exists(global.OldScreen))
{
draw_surface_stretched(global.OldScreen, 0, 0, display_get_gui_width(), display_get_gui_height());

// This is all that is really necessary
// Implement anything you want to draw here like so

draw_set_colour(c_yellow);
draw_set_halign(fa_center);
draw_set_valign(fa_top);
draw_text_transformed(display_get_gui_width()/2, display_get_gui_height()/2, string("PAUSED") + "", 4, 4, 0);
}

Thats it, make sure that you put the pause object in the room you want to pause and the unpause object in the pause(rm_pause) room
This way you don't need to deactivate an instance unless it is persistant and visible in multiple rooms or need to check every instance if it is paused enjoy :)
You can also do whatever to the surface in the pause room animate it or use a shader because it will be destroyed when you exit the pause room

if you can't get it to work i can put the 2 objects in a dropbox
 
Last edited by a moderator:

Tyg

Member
no ...the room just takes a snaphot of the viewcamera surface so it grabs everything then it goes to the pause room, then the snapshot is displayed so all the events in the previous room are just suspended, and it looks like the room is frozen
then the unpause destroys the snapshot surface and returns to the room it was called from and the objects continue where they left off because they were not reset or deactivated

Here is the awesome demo i promised
P to pause, arrow keys move, right mouse fire weapon, some graphics are just placeholders so please don't use in your projects
all you need to pause your project is the game room containing a pause object and a pause room containing an unpause object
in the objects invisible folder you can turn the visibility off on the objects, they are just visible for level development, like solid walls, info zones
the only 2 problems i have and will try to fix, is with some objects that define their own depth in a create event, and text alignment if it is not set in the draw event
both can be easily solved

 
Last edited:
Top