David
David

Reputation: 3105

LibGDX moving camera

I'm currently working at small platformer game and I have problems with my camera movement. First of all my screen dimensions 900x400 when my character y position is bigger than my screen size I want to change camera positon. Here's how I update my camera

    public void updateCamera(){
            leftButton.x = player1.getHitBox().x - 380;
            spriteLeftButton.setPosition(leftButton.x, 20);

            rightButton.x = player1.getHitBox().x - 280;
            spriteRightButton.setPosition(rightButton.x, 20);

            jumpButton.x = player1.getHitBox().x + 312;
            spriteJumpButton.setPosition(jumpButton.x, 20);

            camera.position.x = player1.getHitBox().x;

        if(player1.getHitBox().getY() > Gdx.graphics.getHeight()){ // update camera 
            updateCameraY = true;
        }else{
            updateCameraY = false;
        }
        if(updateCameraY){
            camera.position.y = player1.getHitBox().y;

        }else{
            camera.position.y = 200;
        }
            camera.update();
        }

also I have controlls for android devices, so here's a few pictures from my game enter image description here enter image description here enter image description here so when my character's y position is higher I got some strange results. My controlls disapear.

Upvotes: 1

Views: 1408

Answers (3)

Zohaib Amir
Zohaib Amir

Reputation: 3562

There are two ways to achieve this. Easier method is to use project() method in camera class which will convert your world/camera coordinates to screen coordinates. But this method takes Vector3 as a parameter so you will have to put the UI coordinates into a Vector3 object and then pass it to project(). Heres an example:

    Vector3 camCoords = new Vector3(posX, posY, 0);

posX and posY are x and y coordinates of your button/gui element. since we are dealing with 2d only, so the last paramter-z must be zero. Now we can get screen coordinates:

    Vector3 screenCoords = camera.project(camCoords);
    buttonX = screenCoords.x;
    buttonY = screenCoords.y;

Now if you will draw the element at "buttonX" and "buttonY", element will always be on the screen.

If you don't want to use above method:

You can calculate the the position of your element with respect to the camera position, without using the above method. All you have to do is that you have to position your elements with respect to camera instead of your standard coordinates. Heres some simple maths to convert your standard coordinates to camera coordinates.

Suppose posX and posY are x and y coordinates of your gui element. Now you have to calculate the exact position of your camera:

    float cameraX = camera.position.x;
    float cameraY = camera.position.x - (camera.viewportHeight/2);

position is a Vector3 in Camera class. camera.y would return a value in middle of the screen but we have to get the bottom of the camera so we will subtract half the viewport to do that. Now all you have to do is to add these values to your element coordinates:

    float newPosX = posX + cameraX;
    float newPosY = posY + cameraY;

Now draw your element at this newPosX and newPosY and it will always stick to its position.

Upvotes: 1

Fish
Fish

Reputation: 1697

The fact that your titles and buttons are moving away is because they are set to a static position

One quick way to solve this problem is to get the camera position and then place the images and words according to the camera position

A better way to achieve this is to use Buttons First declare skins You need to lean how to create a .json file and a texture Atlas here is a good tutorial

I'll make an example for your "Deaths "Label

private Stage stage = new Stage(); private Skin skin = new Skin(Gdx.files.internal("UI/uiskins.json"), new TextureAtlas(Gdx.files.internal("UI/uiskins.atlas"))); private Label label = new Label("Deaths", skin); private Table table = new Table();

In the show() Section you need to know how tables work Here

table.center().top();
table.add(label).row();
table.setFillParent(true);

stage.addActor(table);

Gdx.input.setInputProcessor(stage);`

//And finally add this to where you want to update the death score
label.setText("Deaths: " + String.valueOf(yourDeathVariable));

Hope you enjoy :)

Upvotes: 1

Patman
Patman

Reputation: 217

It's good to render you game with 2 cameras.

  1. One is used to render game objects, it zooms, moves rotates etc.
  2. Second is used to render you game controls, score etc.
  3. The fact that you can use pixel perfect rendering for your gui is one of the advantages of this approach.

Quick sample:

gameBatch.setProjectionMatrix(gameCamera.combined);
gameBatch.begin();
sprite.draw(gameBatch);
gameBatch.end();
guiBatch.setProjectionMatrix(controlsCamera.combined);
guiBatch.begin();
sprite.draw(guiBatch);
guiBatch.end();

Upvotes: 2

Related Questions