GMS 2 Object will not properly follow camera, lags behind by a frame

I'm trying to make a small horizontal shmup right now, in the style of Gradius- the camera will move along a track, but the position of the player and their shots will be fixed relative to the screen- so if, for example, the player is 200 pixels away from the left edge of the screen, they'll always appear there, unmoving unless the player makes an input, even as the screen scrolls one pixel to the right every 2 frames.

For some reason, though, I just cannot make this work properly- before, I tried keeping track of when the camera's changed position and added that to the player's position so it'd look as if the player was unmoving but the world moves around them. This worked...until you touched the edge of the screen, then suddenly it all desynced- the frame the camera moved, the player thought it didn't, so the visuals would jitter. Thus, I changed it to where now every frame it's placed at a position relative to the position of the camera, which makes sense...and it jitters every single frame now. I've tried putting that in Step. I've tried Begin Step. I've tried End Step. Nope, it still jitters. I move the camera by letting the engine do that for me- it follows an object that moves on its own- so I've tried changing which of those its movement coded uses- same effect. I just do NOT understand what the hell is going on!

My code is simple: on the player object, every frame I set its X and Y to

GML:
camX += HorzSpeed;
camY += VertSpeed;
x = camera_get_view_x(view_camera[0]) + floor(camX);
y = camera_get_view_y(view_camera[0]) + floor(camY);
camX and camY are the positions from the top-left corner of the camera that the player should sit at. I floor them because I want to use fractional values for slower speeds, but I also want to stick to actual pixels instead of getting into weird subpixel stuff.

The code for positioning the camera object:

Code:
xreal += xspeed;
yreal += yspeed;
x = floor(xreal);
y = floor(yreal);
xreal and yreal are done similarly as camX and camY on the player- used to store fractional values, which are then floored to get the actual x and y position in full pixels. (Typing this, I realize I could probably use frac() somehow to simply remove the decimal value so something like -0.5 won't be floored down to -1, but whatever.)

The speed variables are set by player input only for the player object and are reset after use so no input will always be no movement, and are set by other triggers for the camera and are not reset until changed so the camera keeps moving. The view is set to follow this object, and movement of THAT is smooth- just nothing else. I've even set up a dummy object whose only code is to be 64 pixels from the left of the camera and 128 pixels from the top, and even that jitters around! If I set the camera's speed to a whole number, the jittering is gone, but it still lags behind by a frame, which I do not want. Even changing the Instance Creation Order so the player object is created first changes nothing What am I doing wrong? Is there even a way to fix this? I've been told before when talking about me coding in collisions myself to just enable engine physics so the engine can do that itself, but in this case, is the opposite the best choice- would it be better for me to just manually control the screen scrolling, even though that also means having to manually stop the camera from going out-of-bounds?
 
Last edited:

ophelius

Member
Try putting all the camera code into its own object. The camera should be its own control object.
Only recalculate the camera position in the End Step event of the camera object, so after all the objects have been moved.
I remember having similar problems, this fixed it.

The objects like your player should move by themselves without having to see where the camera is. The camera should position itself based on where the objects are.

Edit: Or in other words, make the camera follow the player, not the player follow the camera
 
Try putting all the camera code into its own object. The camera should be its own control object.
Only recalculate the camera position in the End Step event of the camera object, so after all the objects have been moved.
I remember having similar problems, this fixed it
The camera control is already its own object.

End Step... I actually haven't tried that. Let me check it. Nope, that still makes the sprite jitter. It's still lagging behind by a frame. Right now, the camera is being moved automatically by the engine- all I do is move the object, attach the view to follow it, and the engine does the rest. Would it be best to just manually control the camera, instead of letting the engine do it automatically? I've been avoiding that, since in the past I've had some people tell me to stop trying to do collisions manually when the engine has Physics, so I'm not sure if that's even the "right" or "efficient" option...
 

ophelius

Member
Would it be best to just manually control the camera, instead of letting the engine do it automatically?
Sorry, I assumed you were controlling it manually. Controlling the camera yourself leads to way more flexibility, so yes you should.
Having GM control the camera and you controlling it at the same time might lead to problems. Have one or the other.
 

kburkhart84

Firehammer Games
Wait....if you are not the one controlling it(you say the camera is moved by the engine), then how did you manage to move the controlling code into the End Step? Which is it, are you controlling it or is the engine?

In general, I like to recommend that you control the camera yourself.
 

ophelius

Member
Basically, you want this scenario:

Calculate and move all your objects in the Step events
...
All objects have been updated at this point
...
In the camera's End Step event, position the camera based on where the player is now
 
Last edited:
Wait....if you are not the one controlling it(you say the camera is moved by the engine), then how did you manage to move the controlling code into the End Step? Which is it, are you controlling it or is the engine?

In general, I like to recommend that you control the camera yourself.
I moved the code to move the object the camera follows to the End Step.

Basically, you want this scenario:

Calculate and move all your objects in the Step events
...
All objects have been updated at this point
...
In the camera's End Step event, position the camera based on where the player now is
Alright, thanks for all the advice! I'm not sure doing camera last will work for me with an automatic camera movement, but I'm sure I can figure it all out :)
 

ophelius

Member
I'm not sure doing camera last will work for me with an automatic camera movement, but I'm sure I can figure it all out :)
You need to turn off the automatic camera(Set the Follow Player to nothing).
You should either have GM follow it for you or control it with code. It's best to control it with code
 

kburkhart84

Firehammer Games
I moved the code to move the object the camera follows to the End Step.
The code that moves the camera would need to be moved to EndStep, not the code moving your object itself. What you should probably do is turn off the automatic stuff and code it yourself.
 
You need to turn off the automatic camera(Set the Follow Player to nothing).
You should either have GM follow it for you or control it with code. It's best to control it with code
The code that moves the camera would need to be moved to EndStep, not the code moving your object itself. What you should probably do is turn off the automatic stuff and code it yourself.
Oh, sorry, misspoke there- what I meant was that the camera won't normally follow the player- even with me manually controlling it in an object, it moves independently of player control; wouldn't that mess up with it in End Step, bringing me back to the same issue of the player lagging behind by a frame?
 

Yal

šŸ§ *penguin noises*
GMC Elder
The Step Event happens before automatic movement (hspeed, vspeed, gravity etc) and the End Step event happens after; the reason the "camera lags behind jitter" stuff happens is because moving the camera in normal Step makes you move the camera BEFORE the player's position is updated. Just make sure you apply camera-position updates after the player is moved and it should be fine - either by splitting it up in different parts of the Step event, or the player moving the camera themselves, after their movement logic is done. (Custom movement like changing x/y directly can happen anytime you want)
 

kburkhart84

Firehammer Games
Oh, sorry, misspoke there- what I meant was that the camera won't normally follow the player- even with me manually controlling it in an object, it moves independently of player control; wouldn't that mess up with it in End Step, bringing me back to the same issue of the player lagging behind by a frame?
I'm not clear on your intentions. Is the camera supposed to follow the player or not? Did you set in the room editor properties for the camera to automatically follow the player or not?

It is fine, and quite common, for the camera to move independent of the player. In many games the camera either lags behind, or moves ahead of the player. In platformers, it is typical for the camera to move dfferently on different axes even, with the camera following the player somewhat closely left and right, but being much more hesitant to move up and down. This is so the camera doesn't jerk up and down when the player jumps or goes up stairs, etc...

Typically, these types of things need to be done with your own code controlling the camera. Many people put that on separate objects, which in my opinion is better, as you can better organize things(each object should only handle one thing really). If you have the player itself directly control the camera, then what happens if you design an instance where the player is now some other object? Or if the player dies and you want to show the "after effects" of that? A separate camera object can still reference the player but not be directly controlled by the player object. This also lets you easily pan around the level, say you want to focus on where the boss is and then come back, or something like that.

If you do keep the player object itself controlling the camera, then yes, you could update the camera position right there in the same step event with the player, as long as it is done after updating the position. However, since it is better to do this code in a separate object, you would be better served using the EndStep event as that happens after the player object has done its own movement. If you use the regular step event on the camera object, you have no control over whether it happens before or after the player does its step event.
 
Top