我正在做我的暑期项目,该项目是通过实施AI算法进行的黑白棋游戏。我很苦苦使用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() {
}
}