Extreme Zoom with gamecam - Libgdx

左心房为你撑大大i 提交于 2019-12-26 03:14:10

问题


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.


回答1:


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



回答2:


The camera takes in two variables: the width and height of the world. That's an important keyword here, as it defines the rendered size of the world. If the width and height of the camera is 300x300, that means there's 300x300 units visible on the screen, even if the screen is 1920x1080.

When you do:

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

You set the width and height of the camera to a given value.

The second you apply it:

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

the batch you use to render uses the projection matrix of the camera, meaning it converts screen coordinates to world coordinates based on the width and height of what's visible at once. For an instance 300x300.

If you think the world is too small (meaning what you render shows up as too big) you can of course zoom out by adding a scale factor, but you can also increase the width and height of the camera. I have no clue what you set the width and height to, but if you increase the width and height it'll probably work.

And as I already mentioned, the world coordinates can be different from the screen coordinates.



来源:https://stackoverflow.com/questions/47120722/extreme-zoom-with-gamecam-libgdx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!