Legacy GM [SOLVED] Make draw event of runtime-created object run

D

Dainess

Guest
Hello! My first post here.

I'm going through the Quad Break tutorial to learn the ropes, and I'm making some changes where I see fit.

I have an object_pause with a keyboard pressed <Space> event where I spawn an object_toogleoptions to allow the player to change a few things while the game is paused. I'm doing this because these menus have essentially the same layout and behavior, and I thought this was more efficient than rewriting everything in object_pause. It works as intended so far, but I needed to make a workaround.

The press<Space> code of object_pause:

Code:
paused = !paused;
if paused
{
    sprite = sprite_create_from_surface(application_surface,0,0,room_width,room_height,
    false,false,0,0);
    instance_deactivate_all(true);
    
    exitButton = instance_create(32,352,object_exit);
    backButton = instance_create(32,416,object_back);
    pauseMenu = instance_create(0,0,object_toggleoptions);

}
else
{
    instance_activate_all();
    draw_set_font(font_gui);
    if sprite_exists(sprite)
    {
        sprite_delete(sprite);
    }
    if instance_exists(pauseMenu)
    {
        instance_destroy(pauseMenu);
    }
    if instance_exists(exitButton)
    {
        instance_destroy(exitButton);
    }
    if instance_exists(backButton)
    {
        instance_destroy(backButton);
    }
}
The create event and the step event of object_toogleoptions work fine, but the draw event and draw gui do not appear to be working. Right now in the draw gui of object_pause I rewrote the relevant code to make my pause options screen work as I want it to (nothing relevant in the draw event of object_toogleoptions), but I think this isn't the best option. I tried using event_perform and event_perform_object to "force" the draw event of object_toogleoptions, but didn't have any luck.

The Draw GUI code of object_pause:

Code:
if paused
{
    draw_set_color(c_black);
    
    thick = 3;
    for (i = 0; i < thick; i++)
    {
        draw_rectangle(348 - i, 338 - i, room_width - 17 + i, 463 + i, true);
    }
    draw_text(360,340, "RETURN");
    draw_text(360,400, "TO GAME");
    draw_sprite(sprite_pause, 0, 544, 96);
    
    //the rewritten code from object_toogleoptions starts here
    
    draw_sprite(sprite_exit, 0, 32, 416);
    draw_sprite(sprite_back, 0, 32, 352);
    
    box_x = 90;
    box_y = 32;
    draw_sprite(sprite_box, 0, box_x - 70, box_y);
    draw_sprite(sprite_box, 0, box_x - 70, box_y + 90);
    draw_sprite(sprite_box, 0, box_x - 70, box_y + 180);
    draw_text(box_x, box_y , "Music");
    draw_text(box_x, box_y + 90, "SFX");
    draw_text(box_x, box_y + 180, "Fullscreen");
    
    if global.music
    {
        draw_sprite(sprite_x, 0, box_x - 67, box_y + 5);
    }
    if global.sfx
    {
        draw_sprite(sprite_x, 0, box_x - 67, box_y + 95);
    }
    if window_get_fullscreen()
    {
        draw_sprite(sprite_x, 0, box_x - 67, box_y + 185);
    } */
}
The Draw GUI code of object_toogleoptions:

Code:
{
        draw_text(box_x, box_y , "Music");
        draw_text(box_x, box_y + 90, "SFX");
        draw_text(box_x, box_y + 180, "Fullscreen");
        
        if global.music
        {
            draw_sprite(sprite_x, 0, box_x - 67, box_y + 5);
        }
        
        if global.sfx
        {
            draw_sprite(sprite_x, 0, box_x - 67, box_y + 95);
        }
        
        if window_get_fullscreen()
        {
            draw_sprite(sprite_x, 0, box_x - 67, box_y + 185);
        }
        
        draw_text(box_x, box_y + 270, "Reset Save");
        for (i = 0; i < thickness; i++)
        {
            draw_rectangle(box_x - 10 - i, box_y + 265 - i,
            box_x + 10 + string_width("Reset Save") + i,
            box_y + 280 + string_height("Reset Save") + i, true);
        }
    }
I don't think this is how it's supposed to work - I know draw functions only work as intended in draw events, and I'm creating these instances outside the draw event (as I understand is the right way to do it). But once they are independent instances in the room, their respective draw and draw gui events should run as normal, shouldn't they?

Is there a way to make these draw events run? If not, rewriting the relevant things to draw in the object_pause draw event is the best implementation?

I'm running GMS 1.4.1804 on Windows 10.

Thanks for your attention!
 

Relic

Member
No issues jump out at me. Things to check:

1) box_x and box_y are set correctly
2) object_toggleoptions is set to visible in IDE and/or not set visible to false in code.
 
D

Dainess

Guest
I found out what was happening!

In the Draw GUI code of object_toogleoptions, there's a if room == room_options before the brackets, which caused the issue. I thought the post was already too long and did not want to post all of the event's code to not make it even longer, but I see now this was a mistake. I changed that and the draw gui event started working as intended.

But the objects spawned (such as object_box, object_exit, and object_back) still weren't appearing. I paid no mind to the draw gui of object_toggleoptions for I had tried before spawning only a visible object in the object_pause event and not seeing it. So I knew this room == room_options fluke wasn't the problem to begin with.

So I tried adding a draw gui event in the objects themselves:

Code:
if instance_exists(object_pause) 
{
     draw_self();
}
And this solved it. As far as I can tell, when you spawn an instance of a object from code and not from inserting the object in the room framework, the draw default thing does not appear to trigger. I don't know if this is a bug, or an intended feature, if my assumption is correct, but that's how it's behaving for me in this specific occurrence.

Thanks @Relic for you attention.
 

Relic

Member
You have taken a snapshot of the game when you copy the application surface. I don’t see it in your code but if you are drawing this somewhere in the GUI draw event then it will draw over everything drawn in the normal draw event, including those new buttons.
 
P

ParodyKnaveBob

Guest
Howdy, Dainess, and welcome to the GMC, $:^ J

But once they are independent instances in the room, their respective draw and draw gui events should run as normal, shouldn't they?
As far as I can tell, when you spawn an instance of a object from code and not from inserting the object in the room framework, the draw default thing does not appear to trigger.
Without shenanigans, an instance does default draw whether it was created via room editor or coded command. However, your issue appears you were relying on the new instances' default Draw Event which happens before the Draw GUI event, which of course means they immediately get covered up by the paused surface.

I'm running GMS 1.4.1804 on Windows 10.
Just curious, why not move to the final GMS 1.4.9999? $:^ ]
 
D

Dainess

Guest
You have taken a snapshot of the game when you copy the application surface. I don’t see it in your code but if you are drawing this somewhere in the GUI draw event then it will draw over everything drawn in the normal draw event, including those new buttons.
I'm drawing it in the Draw Event of object_pause. I did try later to draw to the "pause screen" using the Draw Event of objects to no avail, until I realized the problem as you pointed out.

@ParodyKnaveBob Yes, now that you've mentioned it, I realize I've been spawning new objects during normal gameplay all he time without needing the draw_self() command. But seeing how I'd like to keep the snapshot as it is now, using the Draw GUI event to draw these buttons is working fine.

Thanks again for the replies :)
 
Top