首页 > 解决方案 > 如何正确地在游戏板上制作鼠标监听器以放置国际象棋

问题描述

我正在做我的暑期项目,这是关于通过实现人工智能算法的黑白棋游戏。通过使用 JavaFX,我在 GUI 构建部分中苦苦挣扎。我在 8x8 棋盘上设置了鼠标单击事件,当用户单击棋盘上的任何块时,棋子将放在指定位置。我在网上找了很久。但是没有用。请帮助或尝试给出一些想法如何实现这一点,即使主窗格出现了,但仍然无法显示。以下是我的代码。setpiece 方法在 ReversiBoard 类中。谢谢。

以下是主要课程

    package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Rectangle2D;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.StrokeType;
import javafx.scene.text.Font;

/**
 * @author Zibo Wang 
 * the main class is the main entrance of the GUI
 *
 */
public class Main extends Application {

    public static ReversiBoard[][] RevBoard = new ReversiBoard[8][8];
    //public static ReversiAI robot = new ReversiAI();
    public static boolean AIPlay = true;
    public static boolean AIPiece = false;
    public static char whoseTurn = ' ';
    public static Circle[][] arrayCircle = new Circle[8][8];
    public static int step = 0;
    public int WIDTH = 65;
    public static TextArea textArea = new TextArea();
    public static Pane mainPane = new Pane();

    @Override
    public void start(Stage primaryStage) {
        try {
            GridPane grid = new GridPane();
//          for (int i = 0; i < 8; i++) {
//              for (int j = 0; j < 8; j++) {
//                  Rectangle rectangle1 = new Rectangle(WIDTH, WIDTH);
//                  rectangle1.setFill(Color.LIGHTGREEN);
//                  rectangle1.setStroke(Color.BLACK);
//                  Rectangle rectangle2 = new Rectangle(WIDTH, WIDTH);
//                  rectangle2.setFill(Color.DARKGREEN);
//                  rectangle2.setStroke(Color.BLACK);
//                  if ((i + j) % 2 == 0) {
//                      grid.add(rectangle1, i, j);
//                  } else {
//                      grid.add(rectangle2, i, j);
//                  }
//              }
//          }
            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                    grid.add(RevBoard[i][j] = new ReversiBoard(i, j), i, j);
            grid.setLayoutX(65);
            grid.setLayoutY(50);

            /*
             * inserting a background image of the GUI
             */
            ImageView selectedImage = new ImageView();
            Image image1 = new Image(test.class.getResourceAsStream("/pictures/Wood_3888x2592.jpg"));
            selectedImage.setImage(image1);
            selectedImage.setFitHeight(650);
            selectedImage.setFitWidth(1060);

            /*
             * drawing a list of buttons, and add them into the VBox, which will be located
             * at the right side of the main pane
             */
            BoardController controller = new BoardController(null, null, null, null);
            VBox vBox = new VBox(50);
            vBox.setPadding(new Insets(20, 20, 625, 625));
            vBox.setLayoutY(150);
            vBox.getChildren().addAll(controller.getBtSet(), controller.getBtStart(), controller.getBtSurrender(),
                    controller.getBtExit());

            /*
             * Drawing a textArea, defining the font size as 16, the max width and the max
             * height, and drop it at the right hand side of the main pane,
             */
            textArea.setWrapText(true);
            textArea.setFont(new Font(15));
            textArea.setMaxWidth(250);
            textArea.setMinHeight(500);
            textArea.setLayoutX(740);
            textArea.setLayoutY(75);
            textArea.setEditable(false);
            textArea.insertText(0, "Press the 'Start Game' button to strat the game!" + '\n' + '\n');

            //recall the five function defined methods from the BoardController class
            controller.settingButton(null);
            controller.startButton(null);
            controller.surrenderButton(null);
            controller.exitButton(null);
            controller.boardReset(null);

            /*
             * set a main pain which is used to contain the all GUI elements
             */
            //Pane mainPane = new Pane();
            //mainPane.getChildren().addAll(selectedImage, grid, vBox, textArea);
            mainPane.getChildren().addAll(grid, vBox, textArea);

            Scene scene = new Scene(mainPane, 1050, 650);
            scene.getStylesheets().add(getClass().getResource("/application/application.css").toExternalForm());
            primaryStage.setTitle("Welcome to AI Reversi");
            primaryStage.setScene(scene);
            primaryStage.show();
            primaryStage.setResizable(false);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }   

    public static void gameStart() {
        textArea.insertText(0, "Game Start!" + '\n' + '\n');
    }

    public static void whiteWin() {
        textArea.insertText(0, "White piece wins!" + '\n' + '\n');
    }

    public static void blackWin() {
        textArea.insertText(0, "Black piece wins!" + '\n' + '\n');
    }

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

}

以下是 BoardController

package application;

import java.io.IOException;
import java.util.Optional;

import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

/**
 * @author Zibo Wang this BoardController class mainly contains all implemented
 *         functions for the buttons
 */
public class BoardController {

    private Button btSet;
    private Button btStart;
    private Button btSurrender;
    private Button btExit;

    private Alert startConfirmWindow = new Alert(AlertType.CONFIRMATION,
            "The game has not ended yet, are you going to start a new game?");
    private Alert setConfirmWindow = new Alert(AlertType.INFORMATION);
    private Alert surrenderConfirmWindow = new Alert(AlertType.CONFIRMATION, "Are you going to surrender?");
    private Alert exitConfirmWindow = new Alert(AlertType.CONFIRMATION, "Are you going to exit the game?");
    private Alert winnerWindow = new Alert(AlertType.INFORMATION);

    Main method = new Main();

    public BoardController(Button btSet, Button btStart, Button btSurrender, Button btExit) {
        this.btSet = new Button("Setting");
        this.btStart = new Button("Start Game");
        this.btSurrender = new Button("Surrender");
        this.btExit = new Button("Finish Game");
    }

    public Button getBtSet() {
        return btSet;
    }

    public void setBtSet(Button btSet) {
        this.btSet = btSet;
    }

    public Button getBtStart() {
        return btStart;
    }

    public void setBtStart(Button btStart) {
        this.btStart = btStart;
    }

    public Button getBtSurrender() {
        return btSurrender;
    }

    public void setBtSurrender(Button btSurrender) {
        this.btSurrender = btSurrender;
    }

    public Button getBtExit() {
        return btExit;
    }

    public void setBtExit(Button btExit) {
        this.btExit = btExit;
    }

    /*
     * this method defines the implemented function of the setting button
     */
    public void settingButton(ActionEvent event) throws IOException {

        // game setting button function
        btSet.setOnAction(e -> {
            if (Main.whoseTurn == ' ') {
                Stage settingStage = new Stage();
                Pane settingPane = new Pane();

                // group1 is responsible to radio button 1 and 2
                ToggleGroup group1 = new ToggleGroup();
                // group2 is responsible to the option1 label
                ToggleGroup group2 = new ToggleGroup();
                ToggleGroup group3 = new ToggleGroup();

                Label option1 = new Label("Game Battle Mode");
                Label option2 = new Label("AI Battle Setting");
                Label option3 = new Label("Game Difficulty");
                option1.setStyle("-fx-font-size: 16px");
                option1.setLayoutX(30);
                option1.setLayoutY(15);
                option2.setStyle("-fx-font-size: 16px");
                option2.setLayoutX(30);
                option2.setLayoutY(100);
                option3.setStyle("-fx-font-size: 16px");
                option3.setLayoutX(30);
                option3.setLayoutY(190);

                // adding the radio buttons on the new stage, the following part is for the
                // "Game Battle Mode" setting
                // default selection is set for the AI Battle
                RadioButton radio1 = new RadioButton("AI Battle");
                RadioButton radio2 = new RadioButton("Players Battle");
                radio1.setLayoutX(50);
                radio1.setLayoutY(50);
                radio2.setLayoutX(200);
                radio2.setLayoutY(50);
                // adding the radio1 and radio2 buttons into the toggle group1
                radio1.setToggleGroup(group1);
                radio2.setToggleGroup(group1);
                radio1.setSelected(true);
                Line divLine1 = new Line(0, 80, 350, 80);
                divLine1.setStrokeWidth(2f);

                // adding the radio buttons on the new stage, the following part is for the "AI
                // Battle Mode" setting
                // default selection is set for the PC side takes the white chess piece
                RadioButton radio3 = new RadioButton("PC - White piece");
                RadioButton radio4 = new RadioButton("PC - Black piece");
                radio3.setLayoutX(50);
                radio3.setLayoutY(130);
                radio4.setLayoutX(200);
                radio4.setLayoutY(130);
                radio3.setToggleGroup(group2);
                radio4.setToggleGroup(group2);
                radio3.setSelected(true);
                Line divLine2 = new Line(0, 165, 350, 165);
                divLine2.setStrokeWidth(2f);

                // adding the radio buttons on the new stage, the following part is for the
                // "Game Difficulty" setting
                RadioButton radio5 = new RadioButton("Simple");
                RadioButton radio6 = new RadioButton("Regular");
                RadioButton radio7 = new RadioButton("Complex");
                radio5.setLayoutX(50);
                radio5.setLayoutY(220);
                radio6.setLayoutX(200);
                radio6.setLayoutY(220);
                radio7.setLayoutX(50);
                radio7.setLayoutY(250);
                radio5.setToggleGroup(group3);
                radio6.setSelected(true);
                radio6.setToggleGroup(group3);
                radio7.setToggleGroup(group3);
                Line divLine3 = new Line(0, 280, 350, 280);
                divLine3.setStrokeWidth(2f);

                // inserting an background image of the selection window
                ImageView bgImage = new ImageView();
                Image image1 = new Image(test.class
                        .getResourceAsStream("/pictures/chessboard-perspective-background-vector_57911-3.jpg"));
                bgImage.setImage(image1);
                bgImage.setFitHeight(400);
                bgImage.setFitWidth(350);
                bgImage.setLayoutX(0);
                bgImage.setLayoutY(60);

                // adding two buttons at the bottom of the setting pane
                // close button is used to close the window, confirm button is used to confirm
                // all player's selection
                Button cancelBt = new Button("Cancel");
                Button confirmBt = new Button("Confirm");
                cancelBt.setLayoutX(90);
                cancelBt.setLayoutY(315);
                confirmBt.setLayoutX(190);
                confirmBt.setLayoutY(315);

                // defining function of the cancel button, which enable user to close the
                // setting board
                cancelBt.setOnAction(event2 -> {
                    settingStage.close();
                });

                // defining function of the confirm button, clicking the button to change the
                // game parameters
                confirmBt.setOnAction(event3 -> {
                    if (radio1.isSelected() == true) {
                        Main.AIPlay = true;
                        radio1.setSelected(true);
                    } else if (radio2.isSelected() == true) {
                        Main.AIPlay = false;
                        radio2.setSelected(true);
                    }
                    if (radio3.isSelected() == true) {
                        Main.AIPiece = true;
                        radio3.setSelected(true);
                    } else if (radio4.isSelected() == true) {
                        Main.AIPiece = false;
                        radio4.setSelected(true);
                    }
                    settingStage.close();
                });

                settingPane.getChildren().addAll(bgImage, option1, radio1, radio2, divLine1, option2, radio3, radio4,
                        divLine2, option3, radio5, radio6, radio7, divLine3, cancelBt, confirmBt);
                Scene scene = new Scene(settingPane, 350, 400);
                settingStage.setScene(scene);
                settingStage.setTitle("Game Setting");
                settingStage.show();
                settingStage.setResizable(false);
            } else {
                setConfirmWindow.setHeaderText(null);
                setConfirmWindow.setContentText("Please finsih this game first, then doing the game setting change");
                setConfirmWindow.showAndWait();
            }

        });
    }

    /*
     * this method defines the implemented function of the start button
     */
    public void startButton(ActionEvent event) {
        btStart.setOnAction(e -> {
            if (Main.whoseTurn == ' ') {
                startConfirmWindow.setTitle("Game Start!");
                startConfirmWindow.setHeaderText(null);
                Optional<ButtonType> result = startConfirmWindow.showAndWait();
                if (result.isPresent() && result.get() == ButtonType.OK)
                    boardReset(event);
            } else {
                boardReset(event);
            }

        });
    }

    /*
     * this method defines the implemented function of the surrender button
     */
    public void surrenderButton(ActionEvent event) {
        btSurrender.setOnAction(e -> {
            surrenderConfirmWindow.setTitle("Surrender");
            surrenderConfirmWindow.setHeaderText(null);
            // if the player takes the black piece, surrender window shows the white piece
            // wins
            if (Main.whoseTurn == 'B') {
                Optional<ButtonType> computerWin = surrenderConfirmWindow.showAndWait();
                if (computerWin.isPresent() && computerWin.get() == ButtonType.OK) {
                    Main.textArea.insertText(0, "White piece wins!" + '\n' + '\n');
                    Main.whiteWin();
                    winnerWindow.setContentText("White piece wins!!!");
                    winnerWindow.setHeaderText(null);
                    winnerWindow.showAndWait();
                }
            } else if (Main.whoseTurn == 'W') {
                Optional<ButtonType> computerWin = surrenderConfirmWindow.showAndWait();
                if (computerWin.isPresent() && computerWin.get() == ButtonType.OK) {
                    Main.textArea.insertText(0, "Black piece wins!" + '\n' + '\n');
                    Main.blackWin();
                    winnerWindow.setContentText("Black piece wins!!!");
                    winnerWindow.setHeaderText(null);
                    winnerWindow.showAndWait();
                }
            }
        });
    }

    /*
     * this method defines the implemented function of the exit button
     */
    public void exitButton(ActionEvent event) {
        btExit.setOnAction(e -> {
            exitConfirmWindow.setTitle("Exit the Othello");
            exitConfirmWindow.setHeaderText(null);

            Optional<ButtonType> result = exitConfirmWindow.showAndWait();
            // press the confirm button to exit the whole system
            if (result.isPresent() && result.get() == ButtonType.OK) {
                System.exit(1);
            }
        });
    }

    /*
     * this method defines the function to reset the whole Reversi board
     */
    public void boardReset(ActionEvent event) {
        Main.gameStart();
        for (int i = 0; i < 8; i++)
            for (int j = 0; j < 8; j++) {
                Main.RevBoard[i][j].getChildren().remove(Main.arrayCircle[i][j]);
                Main.RevBoard[i][j].piece = ' ';
            }
        Main.whoseTurn = ' ';
        Main.step = 0;

        //if the game is in AI battle mode, computer will pre-place four (2 for each colour)
        //at the middle section of the Reversi board
        if (Main.AIPiece == true) {
            Main.RevBoard[3][3].setPiece(Main.whoseTurn, 3, 3, true);
            Main.RevBoard[4][3].setPiece(Main.whoseTurn, 4, 3, true);
            Main.RevBoard[3][4].setPiece(Main.whoseTurn, 3, 4, true);
            Main.RevBoard[4][3].setPiece(Main.whoseTurn, 4, 3, true);
            Main.whoseTurn = 'W';
        }
    }
}

以下是 MyPiece 类

package application;

import javafx.application.Application;
import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

public class MyPiece extends Circle {

    MyPiece(){      

    }

    //setting the radius, colour and shadow effect for the piece
    MyPiece(int radius, Color color){
        super.setRadius(radius);
        super.setStroke(color);
        super.setFill(color);
        DropShadow ds = new DropShadow();
        ds.setOffsetX(3.0);
        super.setEffect(ds);
    }

}

package application;

import java.util.List;

import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

下面是 ReversiBoard 类,鼠标点击事件在这里定义

public class ReversiBoard extends Pane {

    //B means black piece, W means white piece
    public char piece = 'B';
    public int playerStep;//used to count the piece steps
    private Alert gameWinner = new Alert(AlertType.INFORMATION);
    private MyPiece circle = null;
    //private Media moveSong = new Media(getClass().getClassLoader().getResource("put.mp3").toString());
    //private Media winSong = new Media(getClass().getClassLoader().getResource("win.wav").toString());

    public ReversiBoard () {

    }

    public ReversiBoard(int x, int y) {
        setStyle("-fx-border-color:black");
        this.setPrefSize(65, 65);
        this.setOnMouseClicked(e -> {
            handleMouseClick(x, y);
        });
    }

    public void handleMouseClick(int x, int y) { 

//      if (piece == ' ' && Main.whoseTurn != ' ' && Main.AIPlay == false) {
            setPiece(Main.whoseTurn, x, y,true);
//          //Main.textArea.insertText(0, "Evaluate:" + Main.robot.Evaluate(x, y, Main.whoseTurn) + " ");
//          
//          if (judge(Main.whoseTurn, x, y) == true)
//              printWinner();
//          else
//              Main.whoseTurn = (Main.whoseTurn == 'B') ? 'W' : 'B';
////            MediaPlayer mediaPlayer = new MediaPlayer(moveSong);
////            mediaPlayer.setVolume(50);
////            mediaPlayer.play();
//      }

        //if AI is true, it is in the AI battle mode
//      if (piece == ' ' && Main.whoseTurn != ' ' && Main.AIPlay == true) {
//          if (Main.whoseTurn == ' ') {
//              setPiece(Main.whoseTurn, x, y,true);
                //Main.textArea.insertText(0, "Evaluate:" + Main.robot.Evaluate(x, y, Main.whoseTurn) + " ");
//              if (judge(Main.whoseTurn, x, y) == true)
//                  printWinner();
//              else
//                  Main.whoseTurn = (Main.whoseTurn == 'B') ? 'W' : 'B';
//              MediaPlayer mediaPlayer = new MediaPlayer(moveSong);
//              mediaPlayer.setVolume(50);
//              mediaPlayer.play();
//          }
//          //若whoseTurn不为空 即未分出胜负,则执行搜索函数,根据人下的子,搜索AI的下一步落子
//          if (Main.whoseTurn != ' ')
//              Main.robot.search(x,y);         
//      }
    }

    public void setPiece(char c, int x, int y, boolean flag) {
        piece = c;
        MyPiece circle = null;
        int row = x + 1;
        int column = y + 1;
        Main.step++;
        Main.RevBoard[x][y].playerStep = Main.step;
        if (piece == 'B') {
            circle = new MyPiece(30, Color.BLACK);
            //output the accurate piece positions in the text area
            if(flag==true)
            Main.textArea.insertText(0, "step:" + Main.step + " black piece:column" + column + ",row" + row + '\n' + '\n');
        } else if (piece == 'W') {
            circle = new MyPiece(30, Color.WHITE);
            if(flag==true)
            Main.textArea.insertText(0, "step:" + Main.step + " white piece:column" + column + ",row" + row + '\n' + '\n');
        }
         //bind the piece at the centre of each block
        circle.centerXProperty().bind(Main.RevBoard[x][y].widthProperty().divide(2));
        circle.centerYProperty().bind(Main.RevBoard[x][y].heightProperty().divide(2));
        Main.RevBoard[x][y].getChildren().add(circle);
        Main.RevBoard[x][y].piece = c;
        Main.arrayCircle[x][y] = circle;
    }

    public boolean judge (char whoseTurn, int x, int y) {
        return false;

    }

    public int checkCount(char whoseTurn, int x, int y, int xChange, int yChange) {
        return yChange;

    }

    public void printWinner() {

    }

}

标签: javajavafx

解决方案


推荐阅读