Javafx having pane follow game character

1.2k views Asked by At

I'm attempting to create a simple RPG game using javafx. So far, I've gotten my character to show up on screen, move around, and not bump into obstacles. I've accomplished this by use of a Board class, which acts as a grid:

public class TestBoard extends Pane{

    public static final int TILE_SIZE = 40;
    public static final int X_DIM_TILES = 10;
    public static final int Y_DIM_TILES = 10;
    private Image TREE = new Image(Game.class.getResource("tree.png").toString());
    private Image GRASS = new Image(Game.class.getResource("grasssquare.png").toString());
    private Character character;
    private GameTile[][] tiles = new GameTile[X_DIM_TILES][Y_DIM_TILES];
    public TestBoard(){

        this.setPrefWidth(TILE_SIZE * X_DIM_TILES);
        this.setPrefHeight(TILE_SIZE * Y_DIM_TILES);
        setUpScreen();
        character = new Character(this);
        addCharacter();
    }
    public boolean checkTile(double x, double y){
        return (x < X_DIM_TILES && x >= 0 && y < Y_DIM_TILES && y >= 0 && tiles[(int)x][(int)y].getPassable());
    }
    public Character getCharacter(){
        return character;
    }
    public void addCharacter(){
        character.setLocation(4, 4);

    }
    public GameTile getTile(int x, int y){
        return tiles[x][y];
    }
    public void setUpScreen(){
        for (int i = 0; i < X_DIM_TILES; i++){
            for (int j = 0; j < Y_DIM_TILES; j++){
                addTile(i, j, GRASS, true);
            }
        }
        for (int j = 1; j < Y_DIM_TILES-1; j++){
            addTile(1, j, TREE, false);
        }
    }
    public void addTile(int xCord, int yCord, Image image, boolean passable){
        SceneryTile tile = new SceneryTile(this, image, passable);
        tile.setLocation(xCord, yCord);
        tiles[xCord][yCord] = tile; 
    }
}

Basically, this class holds a collection of GameTiles and has the Character object. It works fine the way it's set up, but I want the screen to only show my main character without the entire screen showing, like real RPGs do. Right now, the whole level screen appears. I want to be able to have the screen move with my character and not reveal the entire screen.

public void start(Stage primaryStage) throws Exception {
    board = new TestBoard();
    testManager = new TestManager(this, board);
    Scene scene = new Scene(board);
    primaryStage.setScene(scene);
    primaryStage.show();
    setUpAnimation();
    setUpKeyPresses();
}

How the screen appears

If more documentation is needed, please let me know! Thanks.

1

There are 1 answers

2
fabian On BEST ANSWER

If you want to load the whole level at the same time, you could put the background and the character in a Group. Whenever the character moves, you adjust it's translate property. The translate property of the whole group is adjusted too, but in the opposite direction. Make sure that the Group is not managed, otherwise the parent will take it's size into account when determining it's own size.

The following example shows a simple example only allowing to move left and right with a circle as character and a rectangle filled with a gradient as background:

@Override
public void start(Stage primaryStage) {
    Circle character = new Circle(100, 100, 20, Color.RED);
    Rectangle background = new Rectangle(2000, 200, new LinearGradient(0, 0, 100, 0, false, CycleMethod.REPEAT, new Stop(0, Color.WHITE), new Stop(100, Color.BLUE)));
    Group group = new Group(background, character);
    group.setManaged(false);

    Pane root = new Pane(group);
    root.setPrefSize(200, 200);

    Scene scene = new Scene(root);
    scene.setOnKeyPressed(evt -> {
        double direction = -1;
        switch (evt.getCode()) {
            case RIGHT:
                direction = 1;
            case LEFT:
                double delta = direction * 10;
                character.setTranslateX(character.getTranslateX() + delta);
                group.setTranslateX(group.getTranslateX() - delta);
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}