【Java程序设计实验大作业】游戏开发:设计一个迷宫逃脱小游戏

引言:为什么选择迷宫逃脱?

迷宫逃脱是一个经典的游戏类型,非常适合 Java 初学者入门。它不仅能够锻炼你的编程逻辑思维,还能让你接触到图形界面开发、用户交互以及线程编程等核心技术。本文将手把手教你如何用 Java 设计一个简单的迷宫逃脱游戏,并实现以下功能:

  1. 迷宫生成:随机生成一个迷宫结构。
  2. 玩家移动:通过键盘控制玩家移动。
  3. 迷宫显示:使用图形界面显示迷宫和玩家位置。
  4. 路径搜索:使用深度优先搜索(DFS)算法自动寻找迷宫出口。

一、游戏设计思路

1.1 游戏模块分解

  1. 迷宫生成模块:随机生成迷宫的墙壁和道路。
  2. 玩家控制模块:通过键盘事件控制玩家移动。
  3. 迷宫显示模块:使用 JavaFX 或 Swing 绘制迷宫界面。
  4. 路径搜索模块:使用 DFS 算法自动寻找迷宫出口。

1.2 游戏流程

  1. 初始化迷宫:随机生成迷宫结构。
  2. 显示迷宫:在图形界面上绘制迷宫和玩家位置。
  3. 玩家移动:通过键盘事件控制玩家移动。
  4. 路径搜索:按下特定按键(如空格键)启动 DFS 算法,显示路径。
  5. 获胜判定:玩家到达迷宫出口时提示胜利。

二、核心功能实现

2.1 迷宫生成

迷宫生成是游戏的核心部分。我们将使用一个二维数组表示迷宫,0 表示可以通过的道路,1 表示墙壁。

代码实现:迷宫生成类
import java.util.Random; 
 
public class MazeGenerator {
    private int rows;
    private int cols;
    private int[][] maze;
 
    public MazeGenerator(int rows, int cols) {
        this.rows  = rows;
        this.cols  = cols;
        this.maze  = new int[rows][cols];
        initializeMaze();
    }
 
    // 初始化迷宫 
    private void initializeMaze() {
        // 初始化所有格子为道路(0)
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                maze[i][j] = 0;
            }
        }
 
        // 随机设置墙壁(1)
        Random random = new Random();
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (random.nextDouble()  < 0.3) { // 30% 的概率设置为墙壁 
                    maze[i][j] = 1;
                }
            }
        }
 
        // 确保起点和终点是道路 
        maze[0][0] = 0;
        maze[rows - 1][cols - 1] = 0;
    }
 
    // 获取迷宫数据 
    public int[][] getMaze() {
        return maze;
    }
 
    // 检查位置是否为道路 
    public boolean isRoad(int x, int y) {
        return maze[x][y] == 0;
    }
}

2.2 玩家移动控制

为了实现玩家移动,我们需要监听页面的键盘事件。这里使用 JavaFX 的 KeyEvent 来处理用户输入。

代码实现:移动控制类
import javafx.scene.input.KeyEvent; 
 
public class PlayerController {
    private int playerX;
    private int playerY;
    private MazeGenerator maze;
 
    public PlayerController(MazeGenerator maze) {
        this.maze  = maze;
        this.playerX  = 0;
        this.playerY  = 0;
    }
 
    // 处理键盘事件 
    public void handleKeyPress(KeyEvent event) {
        switch (event.getCode())  {
            case UP:
                movePlayer(-1, 0);
                break;
            case DOWN:
                movePlayer(1, 0);
                break;
            case LEFT:
                movePlayer(0, -1);
                break;
            case RIGHT:
                movePlayer(0, 1);
                break;
            default:
                break;
        }
    }
 
    // 移动玩家 
    private void movePlayer(int dx, int dy) {
        int newX = playerX + dx;
        int newY = playerY + dy;
 
        // 检查新位置是否合法 
        if (newX >= 0 && newX < maze.getRows()  &&
            newY >= 0 && newY < maze.getCols()  &&
            maze.isRoad(newX,  newY)) {
 
            playerX = newX;
            playerY = newY;
 
            // 检查是否到达终点 
            if (playerX == maze.getRows()  - 1 && playerY == maze.getCols()  - 1) {
                System.out.println("Congratulations!  You escaped the maze!");
            }
        }
    }
 
    // 获取玩家位置 
    public int getPlayerX() {
        return playerX;
    }
 
    public int getPlayerY() {
        return playerY;
    }
}

2.3 迷宫显示

为了显示迷宫,我们使用 JavaFX 的 Canvas 组件来绘制图形。

代码实现:迷宫显示类
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.paint.Color; 
 
public class MazeDisplay {
    private Canvas canvas;
    private GraphicsContext gc;
    private MazeGenerator maze;
    private PlayerController player;
 
    public MazeDisplay(Canvas canvas, MazeGenerator maze, PlayerController player) {
        this.canvas  = canvas;
        this.gc  = canvas.getGraphicsContext2D(); 
        this.maze  = maze;
        this.player  = player;
    }
 
    // 绘制迷宫 
    public void drawMaze() {
        gc.setFill(Color.WHITE); 
        gc.fillRect(0,  0, canvas.getWidth(),  canvas.getHeight()); 
 
        // 计算每个格子的宽度和高度 
        double cellWidth = canvas.getWidth()  / maze.getCols(); 
        double cellHeight = canvas.getHeight()  / maze.getRows(); 
 
        // 绘制墙壁 
        for (int i = 0; i < maze.getRows();  i++) {
            for (int j = 0; j < maze.getCols();  j++) {
                if (maze.isRoad(i,  j)) {
                    continue;
                }
                gc.setFill(Color.BLACK); 
                gc.fillRect(j  * cellWidth, i * cellHeight, cellWidth, cellHeight);
            }
        }
 
        // 绘制玩家 
        gc.setFill(Color.RED); 
        double playerX = player.getPlayerY()  * cellWidth;
        double playerY = player.getPlayerX()  * cellHeight;
        gc.fillRect(playerX,  playerY, cellWidth, cellHeight);
    }
}

2.4 路径搜索(DFS)

为了实现路径搜索,我们需要一个独立的线程来执行 DFS 算法,避免阻塞主线程。

代码实现:路径搜索类
import java.util.ArrayList; 
import java.util.List; 
 
public class PathFinder extends Thread {
    private MazeGenerator maze;
    private PlayerController player;
    private List<int[]> path;
 
    public PathFinder(MazeGenerator maze, PlayerController player) {
        this.maze  = maze;
        this.player  = player;
        this.path  = new ArrayList<>();
    }
 
    @Override 
    public void run() {
        boolean[][] visited = new boolean[maze.getRows()][maze.getCols()];
        findPath(0, 0, visited);
        displayPath();
    }
 
    // DFS 寻找路径 
    private boolean findPath(int x, int y, boolean[][] visited) {
        if (x == maze.getRows()  - 1 && y == maze.getCols()  - 1) {
            path.add(new  int[]{x, y});
            return true;
        }
 
        visited[x][y] = true;
        path.add(new  int[]{x, y});
 
        // 定义四个方向:上、下、左、右 
        int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        for (int[] dir : directions) {
            int newX = x + dir[0];
            int newY = y + dir[1];
 
            if (newX >= 0 && newX < maze.getRows()  &&
                newY >= 0 && newY < maze.getCols()  &&
                !visited[newX][newY] &&
                maze.isRoad(newX,  newY)) {
 
                if (findPath(newX, newY, visited)) {
                    return true;
                }
            }
        }
 
        path.remove(path.size()  - 1);
        return false;
    }
 
    // 显示路径 
    private void displayPath() {
        if (!path.isEmpty())  {
            System.out.println("Path  found:");
            for (int[] point : path) {
                System.out.println("("  + point[0] + ", " + point[1] + ")");
            }
        } else {
            System.out.println("No  path exists.");
        }
    }
}

三、完整代码整合

主程序类
import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.input.KeyEvent; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
 
public class MazeGame extends Application {
    private MazeGenerator maze;
    private PlayerController player;
    private MazeDisplay display;
    private PathFinder pathFinder;
 
    @Override 
    public void start(Stage primaryStage) {
        // 初始化迷宫 
        maze = new MazeGenerator(10, 10);
        player = new PlayerController(maze);
        Canvas canvas = new Canvas(800, 600);
        display = new MazeDisplay(canvas, maze, player);
 
        // 设置场景 
        Scene scene = new Scene(new VBox(canvas));
        primaryStage.setTitle("Maze  Game");
        primaryStage.setScene(scene); 
        primaryStage.show(); 
 
        // 注册键盘事件 
        scene.setOnKeyPressed(this::handleKeyPress); 
 
        // 初始化路径搜索线程 
        pathFinder = new PathFinder(maze, player);
    }
 
    // 处理键盘事件 
    private void handleKeyPress(KeyEvent event) {
        player.handleKeyPress(event); 
 
        // 按下空格键启动路径搜索 
        if (event.getCode().toString().equals("SPACE"))  {
            pathFinder.start(); 
        }
 
        // 更新显示 
        display.drawMaze(); 
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

四、总结与扩展

4.1 总结

通过这篇文章,你已经学会了如何用 Java 设计一个简单的迷宫逃脱游戏。我们实现了以下功能:

  1. 随机迷宫生成:使用二维数组表示迷宫结构。
  2. 玩家控制:通过键盘事件控制玩家移动。
  3. 图形显示:使用 JavaFX 绘制迷宫和玩家位置。
  4. 路径搜索:使用 DFS 算法自动寻找迷宫出口,并通过线程实现异步搜索。

4.2 扩展建议

  1. 增加计时器:记录玩家完成迷宫的时间。
  2. 增加声音效果:在玩家移动或获胜时播放音效。
  3. 增加难度选择:提供不同大小的迷宫或不同的墙壁密度。
  4. 优化图形界面:添加按钮、菜单栏等控件,使界面更加友好。

五、结语

希望这篇文章能帮助你入门 Java 游戏开发!如果你有任何问题或想看到更多实战案例,请在评论区留言!我会逐一回复并分享更多技巧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leaton Lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值