GameMaker Need help drawing objects with GUI Layers within a script

G

Gullgum

Guest
Hello!

I have an object that is drawing a textbox in a 'Draw GUI' event. In this event, I have a script that draws scrolling text inside the textbox. I need to draw an object on top of this box because when I use the draw_sprite function it messes up the animation on the sprite.

The problem is that the object needs to be created from within the script. Every time I try to make the object appear in front of the textbox, it just ends up behind it instead. I have tried setting a Draw GUI End event for the object with the draw_self(); function, manually setting the depth etc. but nothing so far has worked.

I'm still learning this software, so any ideas would be much appreciated!
 

samspade

Member
Hello!

I have an object that is drawing a textbox in a 'Draw GUI' event. In this event, I have a script that draws scrolling text inside the textbox. I need to draw an object on top of this box because when I use the draw_sprite function it messes up the animation on the sprite.

The problem is that the object needs to be created from within the script. Every time I try to make the object appear in front of the textbox, it just ends up behind it instead. I have tried setting a Draw GUI End event for the object with the draw_self(); function, manually setting the depth etc. but nothing so far has worked.

I'm still learning this software, so any ideas would be much appreciated!
Not quiet sure I understand the question. draw_sprite doesn't mess up animation. It doesn't animate at all. None of the draw functions do. All of the draw functions, including draw self, and no draw function which is basically draw self, work exactly like draw_sprite. They use the built in variables (in the case of draw self) or variables you provide (which could be built in variables). Built in variables are being changed automatically by GM and if you provide your own variables you'd have to change those manually. So if you use a draw function and it looks odd, it means that you need to revisit the variables you are providing that function (or that are being provided by default) and think about how they work in the context of that draw event.

Also, there is no way that something drawn in the Draw End GUI event can appear behind something drawn in the Draw GUI event that I know of. If this appears to be happening, it likely means that the draw end GUI event isn't firing (or is but is doing something you don't expect) and that a normal draw event is also firing.

I would show your code and maybe try to break the problem down a little more and explain more precisely what is wrong.
 
G

Gullgum

Guest
Thanks for responding

I want an animated sprite to appear on my textbox, which I'm guessing doesn't work with draw_sprite. Instead, I've set it to create an instance where I need it to go. The object has an empty draw event, and a Draw GUI End event with draw_self(); inside, but appears behind the rest of the textbox.

This is the code for my textbox, which holds the script I was talking about earlier and is in a Draw GUI event:
Code:
get_input();

var text = ds_list_create();
for (var i = 0; i < array_length_1d(message); i++){
    ds_list_add(text, message[i]);
}

if obj_player.y > signY {
    textboxY = 30;
}else textboxY = 575;
draw_set_color($bdc6c6);
draw_roundrect(95,textboxY,930,textboxY + 160,0);
draw_set_color(c_black);
draw_roundrect(95,textboxY,930,textboxY+160,1);
draw_roundrect(99,textboxY + 4,926,textboxY + 156,1)
draw_set_color($4f336b);
draw_roundrect(100,textboxY + 5,925,textboxY + 155,0);
draw_set_color(c_white);
draw_set_font(fnt_text);
draw_set_halign(fa_left);
var key_advance = action;
var key_skip = skipKey;
draw_text_scrolling(130, textboxY + 20,text,40,770,1,6,key_advance,key_skip,doFace,sound,speaker,script);
The instance for my sprite, which is defined in the 'doFace' variable, is being created within that draw_text_scrolling script.

Code:
if currentText!=undefined{
    if doFace != undefined{
        var facexPos = (camera_get_view_x(view_camera[0]) + xpos);
        var faceyPos = (camera_get_view_y(view_camera[0]) + ypos);
        if !instance_exists(obj_textface){         
            tFace = instance_create_depth(facexPos,faceyPos + 100,0,obj_textface);
        }

        tFace.sprite_index = doFace;
    }
}
But the instance appears behind the rectangle that was drawn in the textbox Draw GUI event.

Hopefully this makes more sense
 

samspade

Member
Short version, right now I think your problem is the following.
  1. You need to disable the automatic drawing of obj_textface. You can do this by adding an empty draw event to that object. You should do a simple test to make sure this is working by adding an instance of obj_textface to some room in the room editor and checking to make sure it isn't visible.
  2. Don't add the view coordinates to facex and facey pos. Just use the normal xpos and ypos instead.

Edit: Longer explanation.

As I said in my first post, it is actually impossible (as far as I know) for anything in the Draw End GUI Event to be draw behind the Draw GUI Event. So if you see something, that isn't it. Also, I know this is kind of basic, but 'animation' is a process of drawing consecutive, static, images to the screen. GM by default updates certain variables, such as image_index, and by default uses these variables to choose which static image is shown on the screen. You can use draw_sprite to draw an animated sprite you just need to manually update the values (image index) since GM isn't doing it for you.

Given all of this, it sounds like you have a normal draw event that is running automatically (which GM does by default) that is drawing the sprite using the normal draw event (again run by default) at its room coordinates.

Which is the second point, the GUI system uses a different coordinate system than the normal room system. But draw self uses the room coordinates. So you appear to be using a view. The GUI coordinate system is always 0, 0 at the top left. This is why you don't need to (and arn't) adding view position variables to the rest of your draw GUI code - because that is static. But when you use draw self you are telling GM to draw the sprite on the GUI layer using the room coordinates. So if you want your sprite to be at 100, 100 in GUI space, but you're using the its room x and y which is 100 + the view x/y position it's going to be drawn somewhere else - likely not even in the view at all if your room is large, so you aren't seeing it.

So the solution is to disable the automatic drawing of the sprite using room coordinates and then draw the sprite at the correct GUI coordinates (which again don't and shouldn't take into account the view position).
 
Last edited:
G

Gullgum

Guest
I tried placing obj_textface in the room and it didn't appear, so I don't think there's an automatic draw event going on. I already had a blank Draw event.
 
Top