1

I'm new to LibGDX and I'm trying to make a simple RPG game. I've implemented a basic movement & combat system. Now I would like to add a sidebar with inventory, character information etc. (like in Tibia). Then I would like to add a bottom bar too. However, I don't know how to accomplish that. I've read that adding 2nd stage could be a solution, but I don't know how implement it into my code.

screen how that supposed to look like

Here is my current code with render method:

public class Game extends ApplicationAdapter {

private final static int TURN_DURATION_IN_MILLIS = 2000;

TiledMap tiledMap;
OrthographicCamera gameCamera;
OrthographicCamera guiCamera;
private Map renderer;

Player player;
Monster rat;

private Map.Drawing playerDrawing;
private Map.Drawing ratDrawing;
private SpriteBatch sb;
BitmapFont font;
BitmapFont font2;
Stage stage;
float guiToCameraRatioX;
float guiToCameraRatioY;

long lastTurn;

@Override
public void create() {

    sb = new SpriteBatch();

    tiledMap = new TmxMapLoader().load("map.tmx");
    renderer = new Map(tiledMap, 1 / TILE_CELL_IN_PX, sb);

    gameCamera = new OrthographicCamera(NUMBER_OF_TILES_HORIZONTALLY, NUMBER_OF_TILES_VERTICALLY);
    gameCamera.update();

    guiCamera = new OrthographicCamera(GAME_WINDOW_WIDTH, GAME_WINDOW_HEIGHT);
    guiCamera.update();

    guiToCameraRatioX = guiCamera.viewportWidth / gameCamera.viewportWidth;
    guiToCameraRatioY = guiCamera.viewportHeight / gameCamera.viewportHeight;

    player = new Player();

    playerDrawing = new Map.Drawing(true, null, player.positionX - 0.5f, player.positionY + 0.5f, player.width, player.height, gameCamera, guiCamera);

    player.initHealthPointsBar();
    renderer.addCreature(player);

    stage = new TiledMapStage(tiledMap, player);
    Gdx.input.setInputProcessor(stage);
    stage.getViewport().setCamera(gameCamera);

    rat = new Monster(MonsterType.RAT);
    ratDrawing = new Map.Drawing(false, null, rat.positionX, rat.positionY, rat.width, rat.height, gameCamera, guiCamera);
    renderer.addDrawing(ratDrawing);
    renderer.addDrawing(playerDrawing);

    rat.initHealthPointsBar();
    renderer.addCreature(rat);

    initFont();

}

private void initFont() {
    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("martel.ttf"));
    FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
    parameter.size = 10;
    parameter.color = new Color(0, 0.75f, 0.15f, 1);
    parameter.borderWidth = 1.2f;
    font = generator.generateFont(parameter);
    parameter.size = 12;
    parameter.color = new Color(0.8f, 0.1f, 0.1f, 1);
    font2 = generator.generateFont(parameter);
    generator.dispose();
}

@Override
public void render() {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    float deltaTime = Gdx.graphics.getDeltaTime();

    player.updateState(deltaTime);
    rat.updateState(deltaTime);

    gameCamera.position.set(player.positionX + 0.5f, player.positionY + 0.5f, 0);
    gameCamera.update();

    renderer.setView(gameCamera);

    renderer.render();

    stage.act();

    playerDrawing.x = player.positionX;
    playerDrawing.y = player.positionY;

    ratDrawing.x = rat.positionX;
    ratDrawing.y = rat.positionY;

    //TODO implement real combat system
    if (System.currentTimeMillis() - lastTurn >= TURN_DURATION_IN_MILLIS) {
        lastTurn = System.currentTimeMillis();
        if (rat.state != Creature.State.DEAD && Math.abs(rat.positionX - player.positionX) < 2 && Math.abs(rat.positionY - player.positionY) < 2) {

            player.givenHit = (int) (Math.random() * rat.attack + 1) * 2 - player.defence / 2;
            player.currentHealthPoints -= player.givenHit;

            rat.givenHit = (int) (Math.random() * player.attack + 1) * 2 - rat.defence / 2;
            rat.currentHealthPoints -= rat.givenHit;

            if (rat.currentHealthPoints <= 0) {
                rat.currentHealthPoints = 0;
                rat.state = Creature.State.DEAD;
                rat.moveDestinationX = -1;
                rat.moveDestinationY = -1;
            }
        } else {
            player.givenHit = 0;
            rat.givenHit = 0;
        }
    }

    // used solution below https://stackoverflow.com/questions/20595558/libgdx-sprite-batch-font-bad-scale-rendering
    player.renderPlayer(font, font2, playerDrawing, sb, guiCamera.position.x - (gameCamera.position.x - player.positionX) * guiToCameraRatioX, guiCamera.position.y - (gameCamera.position.y - player.positionY) * guiToCameraRatioY, player.givenHit, System.currentTimeMillis() - lastTurn);
    rat.renderMonster(font, font2, ratDrawing, sb, guiCamera.position.x - (gameCamera.position.x - rat.positionX) * guiToCameraRatioX, guiCamera.position.y - (gameCamera.position.y - rat.positionY) * guiToCameraRatioY, rat.givenHit, System.currentTimeMillis() - lastTurn);
}

@Override
public void dispose() { // SpriteBatches and Textures must always be disposed
    sb.dispose();
}

I appreciate any help :)

gamefreak
  • 11
  • 3

1 Answers1

0

You already have a guiCamera in your Game class. This one can be used to draw the sidebar (or anything else that doesn't move with the rest of the map).
If this camera is already used (e.g. for a menu), you could create a new one, so it can be changed if needed (without changing the menu, or whatever it is used for).

Basically you just need to set the camera's projection matrix to you SpriteBatch (maybe better use a new SpriteBatch for this) and start drawing.

A solution could look like this:

private SpriteBatch sb2; // better use a different sprite batch here (and initialize it in your create method, just like the other one)

// ...

@Override
public void render() {
  // ... other rendering stuff ...

  // set the projection matrix
  sb2.setProjectionMatrix(guiCamera.combined);
  sb2.begin();
  // draw whatever you want on your sidebar to appear
  // all things you draw here will be static on the screen, because the guiCamera doesn't move with the player, but stays in it's position

  // when you are ready drawing, end the SpriteBatch, so everything is actually drawn
}
  sb2.end();
Tobias
  • 2,547
  • 3
  • 14
  • 29