• 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] Button objects lagging behind camera

So I've been looking into how to fix this issue since it seems to be a common one and the only solutions that I've consistently seen are related to the end step event of the object being drawn. The buttons snap into place once I stop moving the camera, but it looks very jarring while in motion. I'm not sure what I'm missing, but any help would be appreciated.

Button end step event
Code:
view_xview = camera_get_view_x(view_camera[0]);
view_yview = camera_get_view_y(view_camera[0]);

x = view_xview + screenX;
y = view_yview + screenY;
Camera step event in case this is the problem
Code:
x = clamp(x, 0 + (width / 2), room_width - (width / 2));
y = clamp(y, 0 + (height / 2), room_height - (height  /2));

var vm = matrix_build_lookat(x, y, -10, x, y, 0, 0, 1, 0);
camera_set_view_mat(camera, vm);
As a note, I am pretty much brand new to working with cameras other than the tutorials I've watched and messing around I've done, so my understanding is fairly limited.
 
Last edited:

jo-thijs

Member
So I've been looking into how to fix this issue since it seems to be a common one and the only solutions that I've consistently seen are related to the end step event of the object being drawn. The buttons snap into place once I stop moving the camera, but it looks very jarring while in motion. I'm not sure what I'm missing, but any help would be appreciated.

Button end step event
Code:
view_xview = camera_get_view_x(view_camera[0]);
view_yview = camera_get_view_y(view_camera[0]);

x = view_xview + screenX;
y = view_yview + screenY;
Camera step event in case this is the problem
Code:
x = clamp(x, 0 + (width / 2), room_width - (width / 2));
y = clamp(y, 0 + (height / 2), room_height - (height  /2));

var vm = matrix_build_lookat(x, y, -10, x, y, 0, 0, 1, 0);
camera_set_view_mat(camera, vm);
As a note, I am pretty much brand new to working with cameras other than the tutorials I've watched and messing around I've done, so my understanding is fairly limited.
You've not shown the code that makes the camera move.
I suppose movement happens after the step event, but that would make it so the view lags behind, not the buttons.
Have you set the view to follow certain objects / targets or do you have some camera code elsewhere that is performed after the end step event?

Either way, you should draw buttons in a different way.
Because buttons remain stationary in view, you should draw them in the draw GUI event, which is exactly meant for these kind of things.
This will automatically solve your issue.
 
You've not shown the code that makes the camera move.
I suppose movement happens after the step event, but that would make it so the view lags behind, not the buttons.
Have you set the view to follow certain objects / targets or do you have some camera code elsewhere that is performed after the end step event?

Either way, you should draw buttons in a different way.
Because buttons remain stationary in view, you should draw them in the draw GUI event, which is exactly meant for these kind of things.
This will automatically solve your issue.

Ah, I believe that would be in my create event then. I have my camera move whenever my cursor reaches the edge of the screen.
Code:
camera = camera_create();
var vm = matrix_build_lookat(x, y, -10, x, y, 0, 0, 1, 0);
var pm = matrix_build_projection_ortho(512, 512, 1, 10000);

camera_set_view_mat(camera, vm);
camera_set_proj_mat(camera, pm);

width = view_wport[0];
height = view_hport[0];

view_camera[0] = camera_create_view(0, 0, 512, 512, 0, oCursor, -1, -1, 32, 32);
In most cases I would agree with you on using the draw GUI event, but in the case of the buttons I used for my actors' abilities, the number of buttons that they have is dynamic, as the actors have different abilities and I also create actors on the fly during the game itself, so I found it easier to just calculate the size of the button bar and center it so that it will stay locked to the center of the camera regardless of how many I have. I've had a trickier time accomplishing this with a draw GUI event. Considering my cursor is also drawn as a non-GUI and it is currently able to interact with the button and function as intended, I am hesitant to complicate things by moving away from that. I will try reconfiguring everything with the button as a GUI though and see if I can get it to work correctly that way.
 
Last edited:

jo-thijs

Member
Ah, I believe that would be in my create event then. I have my camera move whenever my cursor reaches the edge of the screen.
Code:
camera = camera_create();
var vm = matrix_build_lookat(x, y, -10, x, y, 0, 0, 1, 0);
var pm = matrix_build_projection_ortho(512, 512, 1, 10000);

camera_set_view_mat(camera, vm);
camera_set_proj_mat(camera, pm);

width = view_wport[0];
height = view_hport[0];

view_camera[0] = camera_create_view(0, 0, 512, 512, 0, oCursor, -1, -1, 32, 32);
In most cases I would agree with you on using the draw GUI event, but in the case of the buttons I used for my actors' abilities, the number of buttons that they have is dynamic, as the actors have different abilities and I also create actors on the fly during the game itself, so I found it easier to just calculate the size of the button bar and center it so that it will stay locked to the center of the camera regardless of how many I have. I've had a trickier time accomplishing this with a draw GUI event. Considering my cursor is also drawn as a non-GUI and it is currently able to interact with the button and function as intended, I am hesitant to complicate things by moving away from that. I will try reconfiguring everything with the button as a GUI though and see if I can get it to work correctly that way.
That may be the cause.
I believe the view is updated after the end step event to follow an object.
If you manually make the view follow the cursor in the step event, it should be fixed.

I don't see how having a dynamic amount of buttons makes using the GUI event more difficult.
Having the cursor drawn in a normal draw event does make for an issue, but then again, you could draw the cursor in the GUI event instead.
Anyway, with the solution proposed above, you won't have to use the GUI event.
 

Rob

Member
Even if the cursor is drawn in the normal draw event, if it's based off the mouse coordinates he can just check with device_mouse_x_to_gui etc, no?

Personally I'd also prefer/recommend using the GUI to draw buttons. Drawing a dynamic amount of buttons is easy when you know how and I prefer to just deal with the GUI than extra objects.
 

jo-thijs

Member
Even if the cursor is drawn in the normal draw event, if it's based off the mouse coordinates he can just check with device_mouse_x_to_gui etc, no?

Personally I'd also prefer/recommend using the GUI to draw buttons. Drawing a dynamic amount of buttons is easy when you know how and I prefer to just deal with the GUI than extra objects.
The issue with drawing the cursor in a normal draw event and buttons in a GUI event is that the normal draw event occurs before the GUI event and the cursor will appear below the buttons.
 
  • Like
Reactions: Rob
N

NoFontNL

Guest
THIS IS FOR GMS1.4, NOT FOR GMS2, YOU MIGHT NEED TO CHANGE VALUES UP A BIT, IF USING FOR GMS2.
I found this problem also very irritating, drawing the objects to the screen with the draw GUI event is an option, but then you need to manually check if your mouse is clicking on that area, and if you want the buttons to move (for example if you want to hide the GUI with a smooth animation, it becomes much harder.)

I've read a thread earlier and found something very useful. If you put this code (button) in the Draw Begin event, you'll find the buttons not lagging behind:
Code:
/// Create event
xpos=0; // X position, relative to view_xview;
ypos=0;// Y position, relative to view_yview;

xoffset=0; /
yoffset=0;

/// Draw Begin event
x=view_xview+xpos+xoffset
y=view_yview+ypos+yoffset
xoffset and yoffset are used to move the button if needed.
GMS2 uses the camera in the middle of the screen, so you might want to change stuff up a bit.
 
M

Matt Hawkins

Guest
Put the button's movement code in an end step event and they wont lag.
 

jo-thijs

Member
THIS IS FOR GMS1.4, NOT FOR GMS2, YOU MIGHT NEED TO CHANGE VALUES UP A BIT, IF USING FOR GMS2.
I found this problem also very irritating, drawing the objects to the screen with the draw GUI event is an option, but then you need to manually check if your mouse is clicking on that area, and if you want the buttons to move (for example if you want to hide the GUI with a smooth animation, it becomes much harder.)

I've read a thread earlier and found something very useful. If you put this code (button) in the Draw Begin event, you'll find the buttons not lagging behind:
Code:
/// Create event
xpos=0; // X position, relative to view_xview;
ypos=0;// Y position, relative to view_yview;

xoffset=0; /
yoffset=0;

/// Draw Begin event
x=view_xview+xpos+xoffset
y=view_yview+ypos+yoffset
xoffset and yoffset are used to move the button if needed.
GMS2 uses the camera in the middle of the screen, so you might want to change stuff up a bit.
This solution is equally good as my non-gui solution.
The GUI solution is still better (for example, this solution would slightly mismatch the collision box with the drawn button position while the camera is moving).

Put the button's movement code in an end step event and they wont lag.
Not quite.
The issue is that the buttons are moved too early.
Moving them even earlier won't solve things.
 
THIS IS FOR GMS1.4, NOT FOR GMS2, YOU MIGHT NEED TO CHANGE VALUES UP A BIT, IF USING FOR GMS2.
I found this problem also very irritating, drawing the objects to the screen with the draw GUI event is an option, but then you need to manually check if your mouse is clicking on that area, and if you want the buttons to move (for example if you want to hide the GUI with a smooth animation, it becomes much harder.)

I've read a thread earlier and found something very useful. If you put this code (button) in the Draw Begin event, you'll find the buttons not lagging behind:
Code:
/// Create event
xpos=0; // X position, relative to view_xview;
ypos=0;// Y position, relative to view_yview;

xoffset=0; /
yoffset=0;

/// Draw Begin event
x=view_xview+xpos+xoffset
y=view_yview+ypos+yoffset
xoffset and yoffset are used to move the button if needed.
GMS2 uses the camera in the middle of the screen, so you might want to change stuff up a bit.
Worked like a charm, thanks!
 
Top