gpt4 book ai didi

java - 向 javafx 游戏添加菜单

转载 作者:行者123 更新时间:2023-11-30 07:24:03 26 4
gpt4 key购买 nike

我对 java 和 javafx 还很陌生,我已经创建了一个扫雷游戏。我想添加一个小菜单栏,用户可以在其中选择游戏难度(图 block 数量)。我创建了一个菜单方法,但我不确定将其添加到场景的位置。在我尝试放置菜单方法的每个地方都会出现异常错误。

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Minesweeper extends Application {

private int TILE_SIZE = 50;
private static final int W = 800;
private static final int H = 600;

private int X_TILES = W / TILE_SIZE;
private int Y_TILES = H / TILE_SIZE;
private final String[] gameType = {"Easy", "Medium", "Hard", "Very Hard"};
private String difficulty;

@FXML
private Menu gameMenu;

private Tile[][] grid = new Tile[X_TILES][Y_TILES];
private Scene scene;

public void menu() {
for(String game : gameType){
MenuItem menuItem = new MenuItem(game);
menuItem.setUserData(game);
menuItem.setOnAction((ActionEvent event) -> {
selectGame(event);
});
gameMenu.getItems().add(menuItem);
}
}
private void selectGame(ActionEvent event) {
MenuItem menuItem = (MenuItem)event.getSource();
difficulty = (String)menuItem.getUserData();
switch (difficulty) {
case "Easy":
TILE_SIZE = 200;
break;
case "Medium":
TILE_SIZE = 100;
break;
case "Hard":
TILE_SIZE = 50;
break;
case "Very Hard":
TILE_SIZE = 40;
break;
default:
break;
}
}

private Parent createContent() {
Pane root = new Pane();
root.setPrefSize(W, H);

for (int y = 0; y < Y_TILES; y++) {
for (int x = 0; x < X_TILES; x++) {
Tile tile = new Tile(x, y, Math.random() < 0.2);

grid[x][y] = tile;
root.getChildren().add(tile);
}
}

for (int y = 0; y < Y_TILES; y++) {
for (int x = 0; x < X_TILES; x++) {
Tile tile = grid[x][y];

if (tile.hasBomb)
continue;

long bombs = getNeighbors(tile).stream().filter(t -> t.hasBomb).count();

if (bombs > 0)
tile.text.setText(String.valueOf(bombs));
}
}

return root;
}

private List<Tile> getNeighbors(Tile tile) {
List<Tile> neighbors = new ArrayList<>();

int[] points = new int[] {
-1, -1,
-1, 0,
-1, 1,
0, -1,
0, 1,
1, -1,
1, 0,
1, 1
};

for (int i = 0; i < points.length; i++) {
int dx = points[i];
int dy = points[++i];

int newX = tile.x + dx;
int newY = tile.y + dy;

if (newX >= 0 && newX < X_TILES
&& newY >= 0 && newY < Y_TILES) {
neighbors.add(grid[newX][newY]);
}
}

return neighbors;
}

private class Tile extends StackPane {
private int x, y;
private boolean hasBomb;
private boolean isOpen = false;

private Rectangle border = new Rectangle(TILE_SIZE - 2, TILE_SIZE - 2);
private Text text = new Text();

Alert alert = new Alert(AlertType.CONFIRMATION, "Game Over! Play Again?");

public Tile(int x, int y, boolean hasBomb) {
this.x = x;
this.y = y;
this.hasBomb = hasBomb;

border.setStroke(Color.LIGHTGRAY);

text.setFont(Font.font(18));
text.setText(hasBomb ? "X" : "");
text.setVisible(false);

getChildren().addAll(border, text);

setTranslateX(x * TILE_SIZE);
setTranslateY(y * TILE_SIZE);

setOnMouseClicked(e -> open());
}

public void open() {
if (isOpen)
return;

if (hasBomb) {
Optional<ButtonType> result = alert.showAndWait();
if (result.isPresent() && result.get() == ButtonType.OK) {
scene.setRoot(createContent());
}
return;
}

isOpen = true;
text.setVisible(true);
border.setFill(null);

if (text.getText().isEmpty()) {
getNeighbors(this).forEach(Tile::open);
}

switch (text.getText()) {
case "1":
text.setFill(Color.BLUE);
break;
case "2":
text.setFill(Color.FORESTGREEN);
break;
case "3":
text.setFill(Color.RED);
break;
case "4":
text.setFill(Color.DARKBLUE);
break;
case "5":
text.setFill(Color.MAROON);
break;
case "6":
text.setFill(Color.AQUAMARINE);
break;
case "7":
text.setFill(Color.BLACK);
break;
case "8":
text.setFill(Color.GRAY);
break;
default:
break;
}
}
}

@Override
public void start(Stage stage) throws Exception {
scene = new Scene(createContent());

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

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

最佳答案

您可以这样添加:

public MenuBar menu() {
gameMenu = new Menu("Difficulty");
for(String game : gameType){
MenuItem menuItem = new MenuItem(game);
menuItem.setUserData(game);
menuItem.setOnAction((ActionEvent event) -> {
selectGame(event);
});
gameMenu.getItems().add(menuItem);
}
MenuBar menuBar = new MenuBar(gameMenu);
return menuBar;
}

private Parent createContent() {
VBox root = new VBox();
Pane content = new Pane();
content.setPrefSize(W, H);

for (int y = 0; y < Y_TILES; y++) {
for (int x = 0; x < X_TILES; x++) {
Tile tile = new Tile(x, y, Math.random() < 0.2);

grid[x][y] = tile;
content.getChildren().add(tile);
}
}

for (int y = 0; y < Y_TILES; y++) {
for (int x = 0; x < X_TILES; x++) {
Tile tile = grid[x][y];

if (tile.hasBomb)
continue;

long bombs = getNeighbors(tile).stream().filter(t -> t.hasBomb).count();

if (bombs > 0)
tile.text.setText(String.valueOf(bombs));
}
}
root.getChildren().addAll(menu(), content);

return root;
}

menu 方法中,我创建了 gameMenu 的实例,该实例在您的示例中用 @FXML 进行了注释,因此可能不需要此行。然而,该方法返回一个包含菜单的 MenuBar

然后将该栏作为子元素添加到根元素。我还引入了一个新的布局层 (VBox),其中菜单和原始内容作为子项。

另请参阅this oracle article .

关于java - 向 javafx 游戏添加菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37064607/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com