Andrew
Andrew

Reputation: 1109

LibGDX camera smooth translation

How can I lerp (linear interpolate) the camera of top view game which has follow on player so it doesn't tremble as it gets close to the target. This is the code I use for camera translation:

//Creating a vector 3 which represents the target location (my player)
Vector3 target = new Vector3(
(float)player.getPosition().x*map.getTileWidth()+(float)map.getTileWidth()/2, 
(float)player.getPosition().y*map.getTileHeight()+(float)map.getTileHeight()/2, 
0);
//Creating vector 3 which gets camera position
Vector3 cameraPosition = camera.position;
//Interpolating (lerping) vector 
cameraPosition.lerp(target, 0.1f);
//Updating camera and setting it for batch
camera.position.set(cameraPosition);        
camera.update();
batch.setProjectionMatrix(camera.combined);

I think I did this right but the alpha value might be too small, yet again if i make it bigger then camera moves too fast and other issues appear. Can i make the trembling stop with this alpha value (in my example alpha is 0.1f)?

Upvotes: 4

Views: 4864

Answers (3)

Madmenyo
Madmenyo

Reputation: 8584

What you did wrong is cameraPosition.lerp(target, 0.1f); since this applies the lerp immediately to the camera position and so the next time you call it the cameraPosition is not the same anymore and thus you are lerping between different values as the previous iteration.

What you can do is storing the begin position when starting to lerp.

//call once when you want to move
private void move()
{
  beginPosition = cameraPosition.cpy(); 
  //make sure you copy so it's not a reference of cameraPosition.
  lerpAlpha = 0;
}

public update()
{
  //..
  //Calculate lerp alpha
  lerpAlpha += .1;
  //..
  camera.position.set(beginposition.cpy().lerp(target, lerpAlpha), 0);
  //Copy again so it does not change.
  //..
}

Whenever you get strange results using Vectors it is 99% of the time because you did not copy the Vector and applying methods directly to it since it uses a chaining pattern (it alters the given object and returns it).

Upvotes: 1

Manuel Mejias
Manuel Mejias

Reputation: 326

So i tried for libgdx and it worked just fine, only change scale for scl function in Vector3 and speed for the delta

 public void updateCam(float delta,float Xtaget, float Ytarget) {

        //Creating a vector 3 which represents the target location myplayer)
        Vector3 target = new Vector3(Xtaget,Ytarget,0); 
        //Change speed to your need
        final float speed=delta,ispeed=1.0f-speed;
        //The result is roughly: old_position*0.9 + target * 0.1
        Vector3 cameraPosition = camBox2D.position;
        cameraPosition.scl(ispeed);
        target.scl(speed);
        cameraPosition.add(target);
        camBox2D.position.set(cameraPosition);
}

Upvotes: 4

Mr. Developerdude
Mr. Developerdude

Reputation: 9698

I think that you don't want linear interpolation, but something like this (not tested, and the vector operations should be considered pseudo-code at best):

//Change speed to your need
final float speed=0.1f,ispeed=1.0f-speed;
//The result is roughly: old_position*0.9 + target * 0.1
cameraPosition.scale(ispeed);
target.scale(speed);
cameraPosition.add(target);

camera.position.set(cameraPosition);

Upvotes: 4

Related Questions