Используя JavaFX SplitPane, как вы можете заставить две панели отражать друг друга?

Я разрабатываю 2D-игру, и мне нужно сделать ее многопользовательской с разделенным экраном. Я хочу, чтобы содержимое второй панели прокрутки отражало первую, но содержимое отображается только на второй панели.

package sample;

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.*;
import javafx.scene.layout.Background;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javafx.animation.AnimationTimer;
import javafx.geometry.Point2D;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;

Приложение начинается здесь!

public class Main extends Application {

    // Initialize background media
    private Media media = new Media(new File("/Users/hashimjacobs/IdeaProjects/TankGame/src/sample/sprites/ZHU-Nero-Dreams(Tank Trim).wav").toURI().toString());
    private MediaPlayer mp = new MediaPlayer(media);

    // Horizontal box. Child nodes will be laid out horizontally (side by side)
    private HBox box = new HBox();

    // Two anchor panes for bases of split screens
    private SplitPane splitScreen = new SplitPane();
    private AnchorPane basePane;
    private AnchorPane screen1base;
    private AnchorPane screen2base;
    ScrollPane screen1;
    ScrollPane screen2;
    // Two scroll panes to enable scrolling for each anchor pane
    private AnchorPane base = new AnchorPane();
    private AnchorPane base2 = new AnchorPane();


    // Define dynamic lists necessary for controlling multiple objects on screen
    private List<GameObject> bullets = new ArrayList<>();
    private List<GameObject> enemies = new ArrayList<>();
    private List<Tank> players = new ArrayList<>();
    private List<GameObject> walls = new ArrayList<>();
    private List<GameObject> walls2 = new ArrayList<>();
    private List<PowerUp> powerups = new ArrayList<>();

    // Naming player tanks
    private Tank tank1,tank2;

    // Window height and width
    private static final double H = 864;
    private static final double W = 992;


    /**
     *
     */
    // Plays media
    private static void playMedia(MediaPlayer mp){
        mp.setAutoPlay(true);
        mp.play();
    }

Вот где я считаю, что проблема.

    // Creates all static content to be displayed on both screens
    private Parent createContent(){

        base.setPrefSize(W,H);
        base.setMaxSize(W,H);
        base2.setPrefSize(W,H);
        base2.setMaxSize(W,H);

        box.setPrefSize(W,H);
        BackgroundImage bi = new BackgroundImage(new Image("sample/sprites/grass_5.png",W,H,false,true),BackgroundRepeat.REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
                BackgroundSize.DEFAULT);
        base.setBackground(new Background(bi));
        base2.setBackground(new Background(bi));

        /**
        Set up viewports for scroll panes. This way, the players can be centered on their respective screens as they scroll around the map.
        * */


        /**
         * buildMap lays out all walls, pentagon, and tanks on top of the background
         *
         * **/
        buildMap();
        initPlayers();

        // Add labels to health bar
        Text player1 = new Text(10,15,"Player 1"); player1.setFont(Font.font("Ariel",FontWeight.BOLD,20)); player1.setFill(Color.DARKVIOLET);
        Text player1lives = new Text(10,55,"Lives: " + tank1.getLives()); player1lives.setFont(Font.font("Times New Roman", FontWeight.EXTRA_BOLD,15));player1lives.setFill(Color.WHITE);
        Text player2 = new Text(870,15,"Player 2"); player2.setFont(Font.font("Ariel",FontWeight.BOLD,20)); player2.setFill(Color.DARKVIOLET);
        Text player2lives = new Text(870,55,"Lives: " + tank2.getLives()); player2lives.setFont(Font.font("Times New Roman", FontWeight.EXTRA_BOLD,15));player2lives.setFill(Color.WHITE);

Я думал, что должен добавить каждый узел к каждой области прокрутки, с которой я начал экспериментировать ниже.

        base.getChildren().add(player1); base.getChildren().add(player2);
        base.getChildren().add(player1lives); base.getChildren().add(player2lives);
        base2.getChildren().add(player1); base2.getChildren().add(player2);
        base2.getChildren().add(player1lives); base2.getChildren().add(player2lives);
        addGameObject(tank1.getHealthBar(),10,20); addGameObject(tank2.getHealthBar(),870,20);

После создания двух разных панелей привязки, base и base2, я наконец-то увидел фон, отображаемый на обеих панелях.

        screen1 = new ScrollPane(base);
        screen2 = new ScrollPane(base2);

Высота обеих панелей по-прежнему не распространяется на нижний край окна.

        // Set layout of each screen
        screen1.setPrefSize(W/2,H/2);
        screen2.setMaxSize(W/2,H/2);
        screen1.setPrefViewportWidth(W/2); screen1.setPrefViewportHeight(H);
        screen2.setPrefViewportWidth(W/2); screen2.setPrefViewportHeight(H);
        screen1.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); screen1.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        screen2.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); screen2.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

        screen1base = new AnchorPane(screen1);
        screen2base = new AnchorPane(screen2);

        screen1base.setPrefSize(W/2,H);
        screen2base.setPrefSize(W/2,H);
        splitScreen.getItems().addAll(screen1base,screen2base);

        basePane = new AnchorPane(splitScreen);

        // Game Loop
        AnimationTimer timer = new AnimationTimer() {
            //@Override
            public void handle(long now){
                onUpdate();
            }
        };
        timer.start();

        return basePane;
    }




    // Updates the board by eliminating any dead objects due to collision and also adds enemies to the board at random
    private void onUpdate(){

        // Bullet collision
        for (GameObject bullet : bullets) {
            for (GameObject enemy : enemies) {
                if (bullet.isColliding(enemy)) {
                    bullet.setDead(true);
                    enemy.setDead(true);
                    base.getChildren().removeAll(bullet.getView(), enemy.getView());
                    base2.getChildren().removeAll(bullet.getView(), enemy.getView());
                }
            }
            for (GameObject wall : walls){
                if (bullet.isColliding(wall)){
                    bullet.setDead(true);
                    if (wall.getClass().isInstance(new BreakableWall(null))){
                        double newHealth = wall.getHealth() - 1;
                        if(newHealth == 0) {
                            wall.setDead(true);
                            base.getChildren().remove(wall.getView());
                            base2.getChildren().remove(wall.getView());

                            playMedia(new MediaPlayer(new Media(new File("/Users/hashimjacobs/IdeaProjects/TankGame/src/sample/sprites/Wet Fart Squish-SoundBible.com-332766022.wav").toURI().toString())));
                        }
                        else {
                            wall.setHealth(newHealth);
                        }
                    }
                    base.getChildren().remove(bullet.getView());
                    base2.getChildren().remove(bullet.getView());
                }
            }
            for (Tank tank : players){
                if (bullet.isColliding(tank)){
                    bullet.setDead(true);
                    double newHealth = tank.getHealth()-10;
                    tank.getHealthBar().setBar(newHealth);
                    if(newHealth==0){
                        tank.setLives(tank.getLives()-1);
                        if (tank.getLives() == 0){
                            tank.setDead(true);
                            playMedia(new MediaPlayer(new Media(new File("/Users/hashimjacobs/IdeaProjects/TankGame/src/sample/sprites/TITANIC-FLUTE-FAIL-Sound-Effect-Best-Sound-Effects-TV.wav").toURI().toString())));
                            base.getChildren().remove(tank.getView());
                            base2.getChildren().remove(tank.getView());
                            Text theEnd = new Text(base.getPrefWidth()/2,base.getPrefHeight()/2,"You is Dead...");
                            theEnd.setFont(Font.font("Comic Sans",FontWeight.EXTRA_BOLD,40));
                            base.getChildren().add(theEnd);
                        }
                        else {
                            resetPlayer(tank);
                        }
                    }
                }
            }
            for (GameObject bull : bullets){
                if (bullet.isColliding(bull)){
                    bullet.setDead(true); bull.setDead(true);
                    base.getChildren().remove(bull.getView());
                    base2.getChildren().remove(bull.getView());
                }
            }
        }
        // handle tank collision
        for (GameObject tank : players){
            for (GameObject wall : walls){
                if (tank.isColliding(wall)){
                    tank.setVelocity(tank.getFormerVelocity());
                    tank.setVelocity(new Point2D(0,0));
                }
            }

        }

        bullets.removeIf(GameObject::isDead);
        enemies.removeIf(GameObject::isDead);
        walls.removeIf(GameObject::isDead);



        bullets.forEach(GameObject::update);
        enemies.forEach(GameObject::update);
        walls.forEach(GameObject::update);

        for (GameObject tank : players) {
            tank.update();
        }


    }

    @Override
    public void start(Stage primaryStage) {

        // Background Music
        playMedia(mp);

        Scene scene = new Scene(createContent(),992,864, Color.GREEN);

        primaryStage.setTitle("Ratchet Tank Pew Pew");
        primaryStage.setScene(scene);
        primaryStage.setResizable(false);

        // Movement Controls
        primaryStage.getScene().setOnKeyPressed((KeyEvent e) -> {
                tank1.setFormerVelocity(tank1.getVelocity());
                tank2.setFormerVelocity(tank2.getVelocity());
                if (e.getCode() == KeyCode.UP) {
                    tank2.moveForwards();
                }
                if (e.getCode() == KeyCode.DOWN){
                    tank2.moveBackwards();
                }
                if (e.getCode() == KeyCode.LEFT) {
                    tank2.rotateLeft();
                }
                if (e.getCode() == KeyCode.RIGHT) {
                    tank2.rotateRight();
                }

                if (e.getCode() == KeyCode.W) {
                   tank1.moveForwards();
                }
                if (e.getCode() == KeyCode.S){
                    tank1.moveBackwards();

                }
                if (e.getCode() == KeyCode.A) {
                    tank1.rotateLeft();

                }
                if (e.getCode() == KeyCode.D){
                    tank1.rotateRight();

                }



                if (e.getCode() == KeyCode.COMMA) {
                    Bullet bullet = new Bullet(new ImageView(new Image("sample/sprites/pewpew.png", 20, 20, true, true)));
                    shoot(tank2,bullet,tank2.getRVelocity());
                    playMedia(new MediaPlayer(new Media(new File("/Users/hashimjacobs/IdeaProjects/TankGame/src/sample/sprites/shottyToDaBody.wav").toURI().toString())));
                }
                if (e.getCode() == KeyCode.SHIFT) {
                    Bullet bullet = new Bullet(new ImageView(new Image("sample/sprites/pewpew.png", 20, 20, true, true)));
                    shoot(tank1,bullet,tank1.getRVelocity());
                    playMedia(new MediaPlayer(new Media(new File("/Users/hashimjacobs/IdeaProjects/TankGame/src/sample/sprites/shottyToDaBody.wav").toURI().toString())));
                }
        });

        primaryStage.getScene().setOnKeyReleased((KeyEvent e) -> {
            if (e.getCode() == KeyCode.LEFT)
                tank2.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.RIGHT)
                tank2.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.A)
                tank1.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.D)
                tank1.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.W)
                tank1.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.S)
                tank1.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.UP)
                tank2.setVelocity(new Point2D(0,0));
            if (e.getCode() == KeyCode.DOWN)
                tank2.setVelocity(new Point2D(0,0));
        });



        // Movement Controls END

        primaryStage.show();
    }


    // Instantiates player tank objects, set initial velocity, and add to map
    private void initPlayers() {
        tank1 = new Tank(new ImageView(new Image("sample/sprites/sickTank.png", 80, 80, true, false)));
        tank2 = new Tank(new ImageView(new Image("sample/sprites/sickTank2.png", 80, 80, true, false)));
        tank1.setVelocity(new Point2D(0,0));
        tank2.setVelocity(new Point2D(0,0));
        players.add(tank1);
        players.add(tank2);
        tank1.setInitPos(300,400);
        tank2.setInitPos(650,400);
        addGameObject(tank1, tank1.getInitX(),tank1.getInitY());
        addGameObject(tank2, tank2.getInitX(),tank2.getInitY());
    }

    private void resetPlayer(Tank tank){
        base.getChildren().remove(tank.getView());
        base2.getChildren().remove(tank.getView());
        tank.getView().setTranslateX(tank.getInitX());
        tank.getView().setTranslateY(tank.getInitY());
    }


    // Adds a bullet object to the scene
    protected void shoot(Tank tank,GameObject bullet, Point2D point){
        bullets.add(bullet);
        if (tank.getVelocity() == tank.getFormerVelocity()) {
            bullet.setVelocity(tank.getVelocity());
            addGameObject(bullet,tank.getView().getTranslateX(),tank.getView().getTranslateY());
            bullet.moveForwards();
        }
        else {
            bullet.setVelocity(new Point2D(tank.getView().getTranslateX(),tank.getView().getTranslateY()).normalize().multiply(3));
            addGameObject(bullet,tank.getView().getTranslateX(),tank.getView().getTranslateY());
        }
    }

    // Adds an enemy to the scene
    private void spawnEnemy(){
        Enemy enemy = new Enemy(new ImageView(new Image("sample/sprites/aNuttaSickTank.png",30,30,true,true)));
        enemies.add(enemy);

        if (Math.random()+1 < .001){
        addGameObject(enemy, base.getPrefWidth(), 864);

        }
    }


    // Adds a game object to the scene
    private Node addGameObject(GameObject object, double x, double y) {
        object.getView().setTranslateX(x);
        object.getView().setTranslateY(y);
        return object.getView();
        //base.getChildren().add(object.getView());
        //base2.getChildren().add(object.getView());
    }

    // Sets walls and 'Nexus'
    private void buildMap(){
        int map[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
                1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                1,0,0,0,1,1,1,1,0,0,1,0,0,0,0,2,2,2,2,2,0,0,1,1,1,0,0,1,1,1,1,
                1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,6,1,
                1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,
                1,0,0,0,1,0,0,2,2,1,1,1,1,1,1,1,1,0,0,0,0,2,2,2,2,0,0,1,0,0,1,
                0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,
                0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,
                0,0,0,0,1,0,0,1,0,0,2,2,2,2,2,2,2,0,0,1,0,0,0,0,1,0,0,2,0,0,1,
                1,0,0,0,1,0,0,1,0,0,2,3,0,0,0,0,2,0,0,1,0,0,0,0,1,0,0,2,0,0,1,
                1,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                1,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                1,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                0,0,0,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                0,0,0,0,2,0,0,1,0,0,2,2,2,2,2,2,2,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,
                1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,
                1,0,0,0,1,2,2,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,
                1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,2,2,1,0,0,1,
                1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,
                1,0,0,0,1,0,0,1,1,1,1,1,1,1,1,2,2,2,1,1,0,0,2,1,1,0,0,1,4,0,1,
                1,0,0,0,1,0,0,1,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,
                1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,
                1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

        // Loops through map array to add walls and 'Nexus' to scene
        for (int i = 0;i<31;i++){
            for (int j = i; j<837;j+=31){
                int index = map[j];
                int x_pixel = i*32;
                int y_pixel = (j/31)*32;
                switch (index) {
                    case 1: Wall unwall = new UnbreakableWall(new ImageView(new Image("sample/sprites/unbreakablewall.jpg",32,32,false,true)));
                        Wall unwall2 = new UnbreakableWall(new ImageView(new Image("sample/sprites/unbreakablewall.jpg",32,32,false,true)));
                        walls.add(unwall);
                        walls2.add(unwall2);

                        base.getChildren().add(addGameObject(unwall,x_pixel,y_pixel));
                        base2.getChildren().add(addGameObject(unwall2,x_pixel,y_pixel));
                        break;
                    case 2:
                        Wall wall = new BreakableWall(new ImageView(new Image("sample/sprites/breakablewall.jpg",32,32,false,true)));
                        walls.add(wall);
                        addGameObject(wall,x_pixel,y_pixel);
                        break;
                    case 3:
                        Pentagon pentagon = new Pentagon(new ImageView(new Image("sample/sprites/PentagonUpgrade.png",100,100,true,true)));
                        addGameObject(pentagon,x_pixel,y_pixel);
                        break;
                    case 4:
                        PowerUp missile = new PowerUp(new ImageView(new Image("sample/sprites/missile.png",40,40,false,true)));
                        powerups.add(missile);
                        addGameObject(missile,x_pixel,y_pixel);
                        break;
                    case 5:
                        PowerUp shield = new PowerUp(new ImageView(new Image("sample/sprites/shield.png",40,40,false,true)));
                        powerups.add(shield);
                        addGameObject(shield,x_pixel,y_pixel);
                        break;
                    case 6:
                        PowerUp crack = new PowerUp(new ImageView(new Image("sample/sprites/redbull.png",50,50,true,true)));
                        powerups.add(crack);
                        addGameObject(crack,x_pixel,y_pixel);
                        break;
                }
            }

        }
    }




    public static void main(String[] args) {
        launch(args);
    }
}

0 ответов

Другие вопросы по тегам