用java完成一个可调难度大小的有动画的迷宫鼠,打出一个完整的程序
时间: 2023-11-28 15:49:12 浏览: 65
以下是一个基于JavaFX的简单迷宫鼠游戏实现,其中包含有动画效果和可调节难度大小的功能。
```java
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MazeMouseGame extends Application {
private static final int TILE_SIZE = 20;
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private static final Color WALL_COLOR = Color.BLACK;
private static final Color PATH_COLOR = Color.WHITE;
private static final Color MOUSE_COLOR = Color.BLUE;
private static final Color GOAL_COLOR = Color.RED;
private int mazeWidth = 40;
private int mazeHeight = 30;
private int difficulty = 1;
private int mazeSeed = new Random().nextInt();
private SimpleIntegerProperty playerX = new SimpleIntegerProperty(0);
private SimpleIntegerProperty playerY = new SimpleIntegerProperty(0);
private List<Rectangle> walls = new ArrayList<>();
@Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, WIDTH, HEIGHT);
Button restartButton = new Button("Restart");
restartButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
restartGame();
}
});
root.add(restartButton, 0, 0);
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1000 / difficulty), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
movePlayer();
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case UP:
if (playerY.get() > 0 && !isWall(playerX.get(), playerY.get() - 1)) {
playerY.set(playerY.get() - 1);
}
break;
case DOWN:
if (playerY.get() < mazeHeight - 1 && !isWall(playerX.get(), playerY.get() + 1)) {
playerY.set(playerY.get() + 1);
}
break;
case LEFT:
if (playerX.get() > 0 && !isWall(playerX.get() - 1, playerY.get())) {
playerX.set(playerX.get() - 1);
}
break;
case RIGHT:
if (playerX.get() < mazeWidth - 1 && !isWall(playerX.get() + 1, playerY.get())) {
playerX.set(playerX.get() + 1);
}
break;
}
}
});
restartGame();
primaryStage.setTitle("Maze Mouse Game");
primaryStage.setScene(scene);
primaryStage.show();
}
private void restartGame() {
walls.clear();
playerX.set(0);
playerY.set(0);
GridPane root = (GridPane) SceneHelper.getScene().getRoot();
root.getChildren().removeIf(node -> node instanceof Rectangle);
generateMaze();
Rectangle goal = new Rectangle(TILE_SIZE, TILE_SIZE, GOAL_COLOR);
GridPane.setColumnIndex(goal, mazeWidth - 1);
GridPane.setRowIndex(goal, mazeHeight - 1);
root.getChildren().add(goal);
GridPane.setColumnIndex(goal, mazeWidth - 1);
GridPane.setRowIndex(goal, mazeHeight - 1);
}
private void movePlayer() {
GridPane root = (GridPane) SceneHelper.getScene().getRoot();
Rectangle player = new Rectangle(TILE_SIZE, TILE_SIZE, MOUSE_COLOR);
GridPane.setColumnIndex(player, playerX.get());
GridPane.setRowIndex(player, playerY.get());
root.getChildren().removeIf(node -> node.getFill().equals(MOUSE_COLOR));
root.getChildren().add(player);
if (playerX.get() == mazeWidth - 1 && playerY.get() == mazeHeight - 1) {
restartGame();
}
}
private boolean isWall(int x, int y) {
return walls.stream()
.anyMatch(wall -> GridPane.getColumnIndex(wall) == x && GridPane.getRowIndex(wall) == y);
}
private void generateMaze() {
MazeGenerator mazeGenerator = new MazeGenerator(mazeWidth, mazeHeight);
boolean[][] maze = mazeGenerator.generateMaze(mazeSeed);
GridPane root = (GridPane) SceneHelper.getScene().getRoot();
for (int y = 0; y < mazeHeight; y++) {
for (int x = 0; x < mazeWidth; x++) {
Rectangle tile;
if (maze[x][y]) {
tile = new Rectangle(TILE_SIZE, TILE_SIZE, PATH_COLOR);
} else {
tile = new Rectangle(TILE_SIZE, TILE_SIZE, WALL_COLOR);
walls.add(tile);
}
GridPane.setColumnIndex(tile, x);
GridPane.setRowIndex(tile, y);
root.getChildren().add(tile);
}
}
}
public static void main(String[] args) {
launch(args);
}
private class MazeGenerator {
private int width;
private int height;
private int[][] maze;
public MazeGenerator(int width, int height) {
this.width = width;
this.height = height;
this.maze = new int[width][height];
}
public boolean[][] generateMaze(int seed) {
Random random = new Random(seed);
boolean[][] result = new boolean[width][height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
result[x][y] = true;
}
}
maze[0][0] = 1;
while (!isFullyConnected()) {
int x = 1 + random.nextInt(width - 2);
int y = 1 + random.nextInt(height - 2);
if (maze[x][y] == 0) {
if (random.nextBoolean()) {
if (maze[x - 1][y] == 1) {
maze[x][y] = 1;
result[x][y] = false;
} else if (maze[x + 1][y] == 1) {
maze[x][y] = 1;
result[x][y] = false;
}
} else {
if (maze[x][y - 1] == 1) {
maze[x][y] = 1;
result[x][y] = false;
} else if (maze[x][y + 1] == 1) {
maze[x][y] = 1;
result[x][y] = false;
}
}
}
}
return result;
}
private boolean isFullyConnected() {
int[][] visited = new int[width][height];
int color = 1;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (maze[x][y] == 1 && visited[x][y] == 0) {
color++;
floodFill(x, y, color, visited);
}
}
}
return color == 2;
}
private void floodFill(int x, int y, int color, int[][] visited) {
if (x < 0 || x >= width || y < 0 || y >= height || maze[x][y] == 0 || visited[x][y] != 0) {
return;
}
visited[x][y] = color;
floodFill(x - 1, y, color, visited);
floodFill(x + 1, y, color, visited);
floodFill(x, y - 1, color, visited);
floodFill(x, y + 1, color, visited);
}
}
private static class SceneHelper {
private static Scene scene;
public static Scene getScene() {
return scene;
}
public static void setScene(Scene scene) {
SceneHelper.scene = scene;
}
}
}
```
这个程序实现了一个迷宫鼠游戏,包含以下主要功能:
- 可调节难度大小:可以通过设置 `difficulty` 变量来增加或减少鼠标的移动速度,从而控制游戏难度。
- 有动画效果:通过使用 JavaFX 提供的 `Timeline` 类和 `KeyFrame` 类实现了鼠标的动画效果。
- 可以生成不同的迷宫:通过使用一个简单的迷宫生成器,可以生成不同的迷宫并在屏幕上显示出来。
在程序中,我们使用了一个简单的迷宫生成器来生成迷宫。该迷宫生成器使用随机算法来生成迷宫,并返回一个二维布尔数组,其中 `true` 表示路径,`false` 表示墙壁。然后,我们通过将每个布尔值映射到一个矩形上来在屏幕上显示迷宫。
然后,我们使用 `Timeline` 类和 `KeyFrame` 类来实现鼠标的动画效果。在 `Timeline` 中,我们使用 `Duration.millis(1000 / difficulty)` 来设置动画的速度。在 `KeyFrame` 中,我们使用 `EventHandler<ActionEvent>` 来处理每一帧的动画效果。
最后,我们通过监听 `Scene` 上的按键事件来实现鼠标的移动。在事件处理程序中,我们可以检查当前的位置是否为墙壁,并根据按键来移动鼠标。
在 `restartGame()` 方法中,我们重新生成迷宫、移动鼠标和清除旧的矩形,然后在屏幕上显示新的矩形。
总的来说,这个程序是一个简单的迷宫鼠游戏实现,包含有动画效果和可调节难度大小的功能。
阅读全文