LibGDX multiple cameras

949 Views Asked by At

So, I am working with LiBGDX and Box2D, using the PixelsPerMeter conversion, and I have a camera that follows the player around, but when I turn debug mode on I need to be able to draw a font with the fps on screen, so I always can see it in the corner. The problem is that when I try to scale the BitmapFont down, so it looks normal, cause everything else is scaled down, because of the Box2D. I found something that said something about using multiple cameras, so I don't have to scale the font down, but it didn't have any documentation. I tried to figure how to do it, but with no luck. How should I draw the font to the screen?

Here is my game state in which I tried the multiple cameras:

package com.platformer.gamestates;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.platformer.Entities.Player;
import com.platformer.game.Game;
import com.platformer.generation.MenuTiles;
import com.platformer.generation.TiledMaps;
import com.platformer.managers.GameContacts;
import com.platformer.managers.GameStateManager;

import static com.platformer.managers.B2DVars.PPM;

public class MenuState extends GameState {

    World world;
    Box2DDebugRenderer debugRenderer;

    Texture close, far, house;

    BitmapFont font;
    OrthographicCamera fontCam;

    public static Player player;
    MenuTiles menuTiles;

    SpriteBatch batch;

    float camx,camy;

    float lerp=0.1f,lerpy=0.2f;

    GameContacts gameContacts;


    public MenuState(GameStateManager gsm){
        super(gsm);
    }


    public  void init(){

        close=new Texture(Gdx.files.internal("menu_backgrounds/background_close.png"));
        far=new Texture(Gdx.files.internal("menu_backgrounds/background_far.png"));
        house=new Texture(Gdx.files.internal("menu_backgrounds/house_selected.png"));

        batch=new SpriteBatch();

        font=new BitmapFont();

        fontCam=new OrthographicCamera();
        fontCam.setToOrtho(false,Game.WIDTH,Game.HEIGHT);
        fontCam.position.set(Game.WIDTH/2/PPM,Game.HEIGHT/2/PPM,0);

        world=new World(new Vector2(0,-9.81f),true);
        world.setVelocityThreshold(0);
        gameContacts=new GameContacts();
        world.setContactListener(gameContacts);
        debugRenderer=new Box2DDebugRenderer();

        player=new Player(world,960/2,49+20);
        menuTiles=new MenuTiles(world);

    }
    public  void update(float dt){

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

        player.update(dt,gameContacts);

        if(player.shouldPlay){gsm.setState(GameStateManager.PLAY);dispose();}

        camx+=(player.x-camx)*lerp;
        camy+=(player.y-camy)*lerpy;

    }

    public  void draw(OrthographicCamera camera){

        camera.position.x=Math.min(Math.max(camx,Game.WIDTH/2/PPM),(MenuTiles.levelWidth/PPM)-(Game.WIDTH/2/PPM));
        camera.position.y=Math.min(Math.max(camy,Game.HEIGHT/2/PPM),(MenuTiles.levelHeight/PPM)-(Game.HEIGHT/2/PPM));

        batch.begin();
        batch.draw(far, 0, 0, 960 / PPM, 720 / PPM);
        batch.draw(close,0,0,960/PPM,720/PPM);
        batch.end();

        //draw map
        menuTiles.draw(camera);

        batch.begin();
        if(gameContacts.isOnHouse())batch.draw(house,192/PPM,48/PPM,2*MenuTiles.tileSize/PPM,2*MenuTiles.tileSize/PPM);
        batch.end();

        //draw player
        player.draw(batch);

        if(player.DebugOn){
            debugRenderer.render(world, camera.combined);
            batch.setProjectionMatrix(fontCam.combined);
            batch.begin();
            font.draw(batch,"fps",0,0);
            batch.end();
            System.out.println(Gdx.graphics.getFramesPerSecond()+" fps");
        }

        camera.update();
        batch.setProjectionMatrix(camera.combined);

    }

    public  void handleInput(){}

    public  void dispose(){

        menuTiles.dispose();
        close.dispose();
        far.dispose();
        house.dispose();

    }
}
1

There are 1 best solutions below

2
On BEST ANSWER

I don't think you want to divide by PPM in this line...

fontCam.position.set(Game.WIDTH/2/PPM,Game.HEIGHT/2/PPM,0);

I'm assuming the Game.WIDHT and HEIGHT are in pixels (this is not clear from your code snippet). If that's not teh case, then you should include the divide by PPM into this line...

fontCam.setToOrtho(false,Game.WIDTH,Game.HEIGHT);

At present it's not being consistently applied.

Also, you need to call fontcam.update() after setting its position.

Additionally: This is not to do with your question per se, but I'm not sure why you have the following lines at the end of teh render. I would place them right after I've changed the position of the standard camera.

camera.update();
batch.setProjectionMatrix(camera.combined);