Search code examples
javaslick2d

Having The "Camera" positioning On The Player in Java


So I've been having some trouble with positioning the "camera" on the player since this is my first time trying to accomplish this. Whenever I launch my game and I move my player, the camera doesn't seem to center on the player like I hope it to do and I don't know what is wrong with it. I've tried looking through online resources and checked out many questions on stack overflow but I could not find what I did wrong :/ . I am using Java and using the Slick2D engine. Here are my class files:

Camera.class:

private float offsetMaxX;
private float offsetMaxY;
private float offsetMinX = 0;
private float offsetMinY = 0;
public float camX;
public float camY;

public Camera () {
    super ();
}

public void update (float playerX, float playerY, float mapX, float mapY){
    offsetMaxX = mapX - Main.WIDTH;
    offsetMaxY = mapY - Main.HEIGHT;

    camX = playerX - Main.WIDTH/2;
    camY = playerY - Main.HEIGHT/2;

    if (camX > offsetMaxX) {
        camX = offsetMaxX;
    } else if (camX < offsetMinX) {
        camX = offsetMinX;
    }
    if (camY > offsetMaxY) {
        camY = offsetMaxY;
    } else if (camY < offsetMinY) {
        camY = offsetMinY;
    }
}

public float getCamX() {
    return camX;
}

public float getCamY() {
    return camY;
}

public float getOffsetMaxX() {
    return offsetMaxX;
}

public float getOffsetMaxY() {
    return offsetMaxY;
}

public float getOffsetMinX() {
    return offsetMinX;
}

public float getOffsetMinY() {
    return offsetMinY;
}

public void setOffsetMaxX(float offsetMaxX) {
    this.offsetMaxX = offsetMaxX;
}

public void setOffsetMaxY(float offsetMaxY) {
    this.offsetMaxY = offsetMaxY;
}

public void setOffsetMinX(float offsetMinX) {
    this.offsetMinX = offsetMinX;
}

public void setOffsetMinY(float offsetMinY) {
    this.offsetMinY = offsetMinY;
}

And my Game.class:

// Player variables
public SpriteSheet playerSS = null;
protected InputHandler inputHandler;
public float playerX = Main.WIDTH/2, playerY = Main.HEIGHT/2;
private Animation sprite, runningAnimationLEFT, runningAnimationRIGHT, runningAnimationUP, runningAnimationDOWN;
private Animation standLEFT, standRIGHT, standUP, standDOWN; //THIS IS TO PREVENT ANIMATIONS FROM CONTINUING AFTER THE PLAYER STOPS
private int duration = 300;
public boolean isMoving, isLeft, isRight, isUp, isDown;


//Map
private Image testMap; //This is a test map
private float mapX = 1024, mapY = 1024;

//Camera
public Camera camera;

public Game (int stateID) {}

@Override
public int getID() {
    return Main.game; //GAMESTATE = 1
}

@Override
public void init(GameContainer gameContainer, StateBasedGame stateBasedGame) throws SlickException {
    playerSS = new SpriteSheet("res/characters/player_sprite_sheet.png", 50, 75);
    testMap = new Image ("res/grassMap.png");
    camera = new Camera();

    // ANIMATIONS
    runningAnimationDOWN = new Animation();
    runningAnimationDOWN.setAutoUpdate(true);
    runningAnimationDOWN.addFrame(playerSS.getSprite(1, 0), duration);
    runningAnimationDOWN.addFrame(playerSS.getSprite(0, 0), duration);
    runningAnimationDOWN.addFrame(playerSS.getSprite(2, 0), duration);

    runningAnimationLEFT = new Animation();
    runningAnimationLEFT.setAutoUpdate(true);
    runningAnimationLEFT.addFrame(playerSS.getSprite(1, 1), duration);
    runningAnimationLEFT.addFrame(playerSS.getSprite(0, 1), duration);
    runningAnimationLEFT.addFrame(playerSS.getSprite(2, 1), duration);

    runningAnimationRIGHT = new Animation();
    runningAnimationRIGHT.setAutoUpdate(true);
    runningAnimationRIGHT.addFrame(playerSS.getSprite(1, 2), duration);
    runningAnimationRIGHT.addFrame(playerSS.getSprite(0, 2), duration);
    runningAnimationRIGHT.addFrame(playerSS.getSprite(2, 2), duration);

    runningAnimationUP = new Animation();
    runningAnimationUP.setAutoUpdate(true);
    runningAnimationUP.addFrame(playerSS.getSprite(1, 3), duration);
    runningAnimationUP.addFrame(playerSS.getSprite(0, 3), duration);
    runningAnimationUP.addFrame(playerSS.getSprite(2, 3), duration);

    standDOWN = new Animation();
    standDOWN.setAutoUpdate(true);
    standDOWN.addFrame(playerSS.getSprite(1, 0), duration);

    standLEFT = new Animation();
    standLEFT.setAutoUpdate(true);
    standLEFT.addFrame(playerSS.getSprite(1, 1), duration);

    standRIGHT = new Animation();
    standRIGHT.setAutoUpdate(true);
    standRIGHT.addFrame(playerSS.getSprite(1, 2), duration);

    standUP = new Animation();
    standUP.setAutoUpdate(true);
    standUP.addFrame(playerSS.getSprite(1, 3), duration);

    sprite = standDOWN;
}

@Override
public void update(GameContainer gameContainer, StateBasedGame stateBasedGame, int delta) throws SlickException {
    inputHandler.updateKeyboardRelay(gameContainer);
    isMoving = false;

    if (inputHandler.keyUP) {
        isUp = true;
        isDown = false;
        isLeft = false;
        isRight = false;
        isMoving = true;
        playerY -= delta * 0.1f;
    } else if (inputHandler.keyDOWN) {
        isDown = true;
        isUp = false;
        isLeft = false;
        isRight = false;
        isMoving = true;
        playerY += delta * 0.1f;
    } else if (inputHandler.keyLEFT) {
        isLeft = true;
        isUp = false;
        isDown = false;
        isRight = false;
        isMoving = true;
        playerX -= delta * 0.1f;
    } else if (inputHandler.keyRIGHT) {
        isRight = true;
        isUp = false;
        isDown = false;
        isLeft = false;
        isMoving = true;
        playerX += delta * 0.1f;
    }

    if (isMoving) {
        if (inputHandler.keyUP) {
            sprite = runningAnimationUP;
            sprite.update(delta);
        } else if (inputHandler.keyDOWN) {
            sprite = runningAnimationDOWN;
            sprite.update(delta);
        } else if (inputHandler.keyLEFT) {
            sprite = runningAnimationLEFT;
            sprite.update(delta);
        } else if (inputHandler.keyRIGHT) {
            sprite = runningAnimationRIGHT;
            sprite.update(delta);
        }
    } else {
        if (isDown) {
            sprite = standDOWN;
            sprite.update(delta);
        } else if (isUp) {
            sprite = standUP;
            sprite.update(delta);
        } else if (isLeft) {
            sprite = standLEFT;
            sprite.update(delta);
        } else if (isRight) {
            sprite = standRIGHT;
            sprite.update(delta);
        }
    }

    // Map Boundaries
    if (playerX > mapX) {
        playerX = mapX;
    } else if (playerX < 0) {
        playerX = 0;
    }
    if (playerY > mapY) {
        playerY = mapY;
    } else if (playerY < 0) {
        playerY = 0;
    }

    camera.update(playerX, playerY, mapX, mapY);
}

@Override
public void render(GameContainer gameContainer, StateBasedGame stateBasedGame, Graphics graphics) throws SlickException {
    testMap.draw(mapX - 1024, mapY - 1024);

    graphics.translate(camera.getCamX(), camera.getCamY());
    sprite.draw(playerX, playerY);
    graphics.translate(-camera.getCamX(), -camera.getCamY());

    graphics.drawString("Player X: " + playerX, 400, 400);
    graphics.drawString("Player Y: " + playerY, 400, 415);

}

I feel like there is something specifically wrong in my Camera.class and my update(...) & render(...) methods, but I don't know what.


Solution

  • Here in your camera class in the update method try changing

    camX = playerX - Main.WIDTH/2;
    camY = playerY - Main.HEIGHT/2;
    

    to

    camX = playerX;
    camY = playerY;
    

    tell me if this does not work.