I have a side scroller game made in OpenGL, and I'm trying to center the player in the viewport when he moves. I know how to do it:

cameraX = Width / 2 / TileSize - playerPosX
cameraY = Height / 2 / TileSize - playerPosY

However, I have a problem. The player and "camera" move, but the player moves faster than the "camera" scrolls. So, the player can actually move out of the screen.

Some code, this is how I translate the camera:

public Camera(){

public void update(Player p){
    glTranslatef(-p.getPos().x - Main.WIDTH / 64 / 2, -p.getPos().y - Main.HEIGHT / 64 / 2, 1);

Here's how I move the player:

public void update(){
        this.move(MOVESPEED, 0);

        this.move(-MOVESPEED, 0);

The move method:

public void move(float x, float y){
    this.getPos().set(this.getPos().x + x, this.getPos().y + y);

And then after I move the player, I update the player's geometry, which shouldn't matter.

What am I doing wrong here, this seems like such a simple problem, yet it doesn't work!

  • \$\begingroup\$ What does glTranslatef do? \$\endgroup\$ – ThorinII Nov 7 '13 at 23:06
  • \$\begingroup\$ Are you translating on the projection matrix? \$\endgroup\$ – nejinx Nov 8 '13 at 0:12

is your player's coordinates in screen coordinates or does your 'world' use a separate coordinate system? You'll need to convert between world coordinates and screen coordinates to do the calculations for translation.

  • \$\begingroup\$ I already do that, as you can see in my code... \$\endgroup\$ – opiop65 Nov 7 '13 at 11:16

The solution is simple. You just translate the camera to the position in the center of the player. If the stored player position is in the center of the player sprite then cameraPosition = playerPosition. If it is in the left bottom of the player sprite then cameraPosition = playerPosition + playerSize/2.0.
One important thing is to first update the player position and then the camera position, otherwise your camera will lag one update behind.

  • \$\begingroup\$ I understand that, and its what I'm doing right now, but as I said, its scrolling slower than the player. The player can escape the screen. \$\endgroup\$ – opiop65 Nov 7 '13 at 13:20
  • \$\begingroup\$ With the way i suggest, the camera will be fixed on the player position (no scrolling involved). You should check the order of the positions updates. Also, maybe your are doing some transformation to the geometry of the player, other than the translation, that is probably changing the position of the geometry. \$\endgroup\$ – Anastasios G Nov 8 '13 at 7:12

As Anastasios said, if your Camera update function is called first and the player Move function after, the camera will follow the previous position of the player, and it will look as the Player go faster than the camera.

And what are Main.Width, 64 and Width? You never use cameraX and cameraY ?

If you want your player to constantly be in the center a easier way is :

glTranslate(playerPos.x, playerPos.y) //Camera translate
//draw your level
glPushMatrix(); //save where you where
glLoadIdentity() //Reset the translate to (0,0) (I'm not sure, but I think it'll affect the camera translate, that would be a big problem)
//Draw your Player
glPopMatrix() // return to the camera translation.

I did not tested this code, but I think that you'll understand what I plan to do.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.