Search code examples
javaandroidlibgdx

Extreme Zoom with gamecam - Libgdx


Hi guys i'm quite new to libgdx I tried to make the camera follow the player. Trying to do so i read online that i had to add this line of code.

game.getBatch().setProjectionMatrix(gamecam.combined);

By doing so i noticed that my game was really zoomed i tried to dezoom it but i was not able to make it work. Do you guys have any suggestion? This is my GameScreen where i render the player.

`public class GameScreen implements Screen {

private Logang game;

//basic playscreen variables
private OrthographicCamera gamecam;
private Viewport gamePort;

//Box2d variables
private World world;
private Box2DDebugRenderer b2dr;

boolean drawn = true;
private Player p;
private int pX = 100, pY = 300;

public GameScreen(Logang game) {

    this.game = game;
    //create cam used to follow mario through cam world
    gamecam = new OrthographicCamera(Logang.GWIDTH, Logang.GHEIGHT);
    gamecam.update();

    //create our Box2D world, setting no gravity in X, -10 gravity in Y, and allow bodies to sleep
    world = new World(new Vector2(0, Logang.GRAVITY), true);
    //allows for debug lines of our box2d world.
    b2dr = new Box2DDebugRenderer();


    //create a FitViewport to maintain virtual aspect ratio despite screen size
    gamePort = new ScalingViewport(Scaling.fill, Logang.GWIDTH / Logang.PPM, Logang.GHEIGHT / Logang.PPM, gamecam);

    p = new Player(new Sprite(new Texture("badlogic.jpg")), world, pX, pY, 1);

    //initially set our gamcam to be centered correctly at the start of of map
    //gamecam.position.set(gamePort.getWorldWidth() / 2, gamePort.getWorldHeight() / 2, 0);

    line();
}


@Override
public void show() {

}

public void update(float dt) {
    //handle user input first
    p.update(dt);
    //update our gamecam with correct coordinates after changes
    /*gamecam.position.set(p.getSprite().getX(),0,0);
    gamecam.update();*/
}


@Override
public void render(float delta) {
    //separate our update logic from render
    update(delta);

    //Clear the game screen with Black
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    world.step(1f / 60f, 6, 2);

    gamecam.position.set(p.getSprite().getX(), p.getSprite().getY(), 0); // x and y could be changed by Keyboard input for example

    //gamecam.position.set(p.getSprite().getX(), p.getSprite().getY(), 0);
    gamecam.update();

    game.getBatch().setProjectionMatrix(gamecam.combined);

    //renderer our Box2DDebugLines
    b2dr.render(world, gamecam.combined);

    System.out.println("Player x: " + p.getSprite().getX() + " Camera X: " + gamecam.position.x + " Body X: " + p.getBody().getPosition().x);
    //System.out.println("Player y: " + p.getSprite().getY() + " Camera Y: " + gamecam.position.y + " Body Y: " + p.getBody().getPosition().y);


    game.getBatch().begin();


    if (p.getBody() != null)
        p.render(game.getBatch());

    EntityManager.renderTerra(game.getBatch(), delta);


    game.getBatch().end();

}

public void line() {
    Texture tmp = new Texture("dirt.png");
    tmp.setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
    for (int i = 0; i < 10; i++) {
        EntityManager.add(new Ground(new Sprite(tmp), world, i * Logang.TILE, 0, 2));
    }
    //EntityManager.changeSize(Logang.TILE * 5,Logang.TILE);
}

@Override
public void resize(int width, int height) {
    //updated our game viewport
    gamePort.update(width, height);
}

public World getWorld() {
    return world;
}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    world.dispose();
    b2dr.dispose();
}`

And this is my Entity class which is extended by the Player which i empty for now` public abstract class Entity {

private World world;
private Sprite sprite;
private Body body;
private int tipo;

public Entity(Sprite sprite, World world, int x, int y, int tipo){
    this.sprite = sprite;
    this.world = world;
    getSprite().setPosition(x, y);
    getSprite().setSize(Logang.TILE, Logang.TILE);
    define(tipo);
    this.tipo = tipo;
}

public abstract void update(float dt);

public void define(int tipo){
    BodyDef bdef = new BodyDef();
    bdef.position.set((getSprite().getX() + getSprite().getWidth() / 2) / Logang.PPM, (getSprite().getY() + getSprite().getHeight() / 2) / Logang.PPM);
    switch(tipo){
        case 1: {
            bdef.type = BodyDef.BodyType.DynamicBody;
            break;
        }
        case 2:{
            bdef.type = BodyDef.BodyType.StaticBody;
            break;
        }
        case 3:{
            bdef.type = BodyDef.BodyType.DynamicBody;
            break;
        }

    }

    body = world.createBody(bdef);

    FixtureDef fdef = new FixtureDef();
    PolygonShape shape = new PolygonShape();
    shape.setAsBox(getSprite().getWidth() / Logang.PPM / 2, getSprite().getHeight() / Logang.PPM / 2);


    fdef.shape = shape;
    body.createFixture(fdef);
    body.setUserData(this);

    shape.dispose();
}

public void render(SpriteBatch batch){
    if(tipo != 2) {
        float posX = getBody().getPosition().x * Logang.PPM;
        float posY = getBody().getPosition().y * Logang.PPM;

        getSprite().setPosition(posX - getSprite().getWidth() / 2, posY - getSprite().getHeight() / 2);

    }
    getSprite().draw(batch);
}

public Sprite getSprite() {
    return sprite;
}

public void setSprite(Sprite sprite) {
    this.sprite = sprite;
}

public Body getBody() {
    return body;
}

public void setBody(Body body) {
    this.body = body;
}`

If I remove that line at the start the game sizes are good but my camera doesn't follow my player.

Thanks for the answer and sorry if the question was not well asked.


Solution

  • 1) If your viewport dimensions divided by Logang.PPM then all Textures size should be also divided by Logang.PPM.

    Logang.TILE should be float and divided by Logang.PPM

    Player sprite also should be resized**.

    2) To follow player try dividing gamecam resolution by Logang.PPM.

    Initialize it like this:

    gamecam = new OrthographicCamera(Logang.GWIDTH / Logang.PPM, Logang.GHEIGHT / Logang.PPM);
    

    UPD: I found issue, it was in player render method:

    float posX = getBody().getPosition().x; // delete  * Logang.PPM
    float posY = getBody().getPosition().y; // delete  * Logang.PPM