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

(SOLVED) Struggle with surfaces: newbie question

C

candlelight2007

Guest
I'm working on a simple "pause" feature where on a key pressed a snapshot of the current screen/room (using surface) would be shown with some stuff drawn on top ("game paused" message, etc.). Then on the "unpause" trigger, the surface would be released and the game would resume. All seems to be working great, except when the surface is released, I lose all control of all existing objects in the room. They become non responsive. I am new to surfaces, I admit, so to create one I followed the manual 's article on view_surface_id almost to the letter. Anyone can point me in the right direction?

Here are the snippets: I use obj_freeze object to control the actions. I commented out activate/deactivate statements to make debugging easier.

on Create:
-----------
GML:
roomIsFrozen = false;
room_snapshot = -1; // surface we will be using to create a snapshot of the screen
On Key Pressed:
------------------
GML:
if roomIsFrozen != true {    //
    roomIsFrozen = true;    // freeze
    if !surface_exists(room_snapshot) {
        room_snapshot = surface_create(CAM_WIDTH, CAM_HEIGHT); // CAM_WIDTH and CAM _HEIGHT are macros I used for simplicity
        view_surface_id[0] = room_snapshot;
    }
        
    // deactivate all layers except Settings layer
    //instance_deactivate_all(true);

} else {
    roomIsFrozen = false;    // unfreeze

    surface_free(room_snapshot);

    // re-activate layers
    //instance_activate_all();
}

on Draw GUI:
--------
GML:
if roomIsFrozen == true {

    if surface_exists(room_snapshot) {
        draw_surface_stretched(room_snapshot, 0, 0, CAM_WIDTH, CAM_HEIGHT)
    }

    // draw semitransparent veil
    draw_set_alpha(0.5);
    draw_set_color(c_dkgrey);
    draw_rectangle(CAM_X, CAM_Y, CAM_X + CAM_WIDTH, CAM_Y + CAM_HEIGHT, false);

    draw_set_alpha(1); // reset alpha

    draw_set_colour(c_yellow);
    draw_set_halign(fa_center);
    draw_set_valign(fa_top);
    //draw_text_transformed(CAM_CENTER_X, CAM_CENTER_Y, string("FROZEN") + "", 4, 4, 0);
    draw_text_transformed(CAM_CENTER_X, CAM_CENTER_Y, string("FROZEN") + "", 4, 4, 0);

}
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
IIRC, just set view_surface_id to -1 and it'll reset the view again.

However, I honestly don't think this is the best way to do what you want to do... I think you'd be better drawing the application surface to the "snapshot" surface then simply drawing that. The application_surface is the sort of "canvas" surface that GameMaker draws to every step automatically and it can be used to do exactly what you are doing here. SO, you'd create the snapshot surface, then call surface_set_target() on it, draw the app surface to the freeze surface, then reset the target. After that you simply draw the freeze surface in the GUI event as you're doing now. Hope that makes sense, but if you want a more guided example, then let me know!

Oh, and don't forget to call surface_free() when you no longer need the "snapshot" surface to prevent memory leaks!

PS: some sauce...
(application_surface)

PPS: Unrelated comment... Just read our PM conversation from before... Yes, using with(all) will indeed target EVERY active instance in the room, including the one calling the function. :)
 
C

candlelight2007

Guest
IIRC, just set view_surface_id to -1 and it'll reset the view again.
Aaahh!! Genius! đź‘Ť I knew there was something very very simple. See, that's where the experience comes in! I spent hours trying to figure it out. :oops: Phew!

However, I honestly don't think this is the best way to do what you want to do... I think you'd be better drawing the application surface to the "snapshot" surface then simply drawing that. The application_surface is the sort of "canvas" surface that GameMaker draws to every step automatically and it can be used to do exactly what you are doing here. SO, you'd create the snapshot surface, then call surface_set_target() on it, draw the app surface to the freeze surface, then reset the target. After that you simply draw the freeze surface in the GUI event as you're doing now. Hope that makes sense, but if you want a more guided example, then let me know!
Now that's a good pointer! I like it! I'll give it a try. Much appreciated!
 
C

candlelight2007

Guest
I used the "set view_surface_id to -1" trick and things began to work. :) However, I noticed a peculiar thing (peculiar to me anyway) - when the surface is on, it effectively blocks all the other objects in the room. Even without deactivating anything! I'm curious if it is some sort of a side effect or is it by design? Can someone explain?

EDIT: nevermind, there must be something in the code of that one particular room, that blocks them. :) I'll check.

EDIT 2: Ok, I eventually decided to try @Nocturne's suggestion and use application_surface instead and the glitch I mentioned above went away! All is running actually much smoother! This indeed seems to be a superior approach. Thanks again!
 
Last edited by a moderator:
Top