Search code examples
game-maker

How can I make my text box follow the GUI


I have a text box element in game on my gui which is loaded in after the user enters the room.

goto_room = asset_get_index(target_room);
room_goto(goto_room);

//Initiate a player object on this room
with(instance_create(target_x, target_y, obj_Player)) {
     name = other.name;
}
with(instance_create(15, window_get_height()-15, txt_ChatBox)) {
     image_xscale = string_width("g") * 99;
}

the object hierarchy is: txt_ChatBox>gui_textBox_base>ui_focus_base>ui_base

this is the draw event where everything happens

Draw GUI:
/// Draws the text box
if not uiVisible exit;  //if not visible, don't draw it!

x = view_xview[0] + 15;
y = (view_hview[0] - 15) + view_yview[0];

if isFocused {
    draw_rectangle(posX, posY, posX + (16 * image_xscale), posY + (16 * image_yscale), 2);
}

if(string_length(text) > 0 || isFocused) {
    draw_text(posX + 3, posY, string(text));
} else {
    draw_text(posX + 3, posY, string(placeholder));
}

In game it works but it also adds part of it to the map like this enter image description here

EDIT: something new I have found is that the one on the map is the physical instance of the control but all the drawing for text happens in the drawGUI call. I.e. the on click handler that give it focus only works on the on map one.

I made the map/physical one move at the start of the drawGUI to where I wanted it to be but it was off from the gui one by a bit during scrolling which could be smoothed out but I don't think that is the right answer (see updated code above).

I have a feeling I need to say please be part of the view rather than part of the map right??


Solution

  • To draw something fixed on the screen, you have two common options:

    The Draw Event

    This Event will draw Sprites, Pixels, Lines, etc within the Room. In order to make this appear in the same place, you'll need to offset whatever you're drawing with view_xview and view_yview. Note that both of these are arrays, so you should use whichever view you're using for your main display. If that made no sense to you, then just use view_xview[0] and view_yview[0].

    This approach has some drawbacks. If you scale or rotate the view, whatever you've drawn will scale and rotate too. Seeing as that's probably not what you want, then I recommend the other approach.

    The Draw GUI Event

    Rather than drawing within the Room, this Event will draw on the screen. As such, you should use coordinates that match this. To determine the width and height of your display, use the display_get_width() and display_get_height() methods.

    This is by far the preferred method, as you'll be drawing to the screen, rather than within the room. This method also supports view scaling and rotation, as you're drawing to the screen directly.