Java实现经典游戏复杂迷宫

目录
  • 前言
  • 主要设计
  • 功能截图
  • 代码实现
  • 总结

前言

人类建造迷宫已有5000年的历史。在世界的不同文化发展时期,这些奇特的建筑物始终吸引人们沿着弯弯曲曲、困难重重的小路吃力地行走,寻找真相。迷宫类小游戏应运而生。在游戏中,迷宫被表现为冒险舞台里,藏有各式各样奇妙与谜题或宝藏的危险区域。型态有洞窟、人工建筑物、怪物巢穴、密林或山路等。迷宫内有恶徒或凶猛的生物(真实存在或想像物体都有)徘徊,其中可能会有陷阱、不明设施、遗迹等。

《复杂迷宫》游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

主要需求

方向键控制移动,角色走出迷宫,游戏胜利。增加游戏难度和增加随机地图。

主要设计

1、构建游戏地图面板

2、设定迷宫地图,包含可走的通道,不可走的墙体,还有出口位置

3、键盘的上下左右按键,来控制角色的移动

4、角色移动的算法,通道可走,遇到墙体不可走

5、走到终点,有成功通关的提示。

6、增加游戏的难度选择,难度1,难度2和难度3

7、每次生成的地图是随机的

8、地图大小可选择,迷宫的长在10-45之间,宽在10-90之间

9、增加撞墙的音乐效果

功能截图

游戏开始页面

生成难度1,10*10的迷宫地图

随机地图:生成难度1,10*10的迷宫地图

生成难度2,30*30的迷宫地图

生成难度3,90*45的迷宫地图

成功过关-效果

代码实现

窗口布局

public class StartView extends JFrame {
    public StartView() {
        this.setTitle("复杂迷宫");
        this.setSize(240, 265);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setResizable(false);
        initialize();
        this.setVisible(true);
    }

    private void initialize() {
        JPanel contentPane = new JPanel();
        this.setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel widthLabel = new JLabel("迷宫长度:");
        JLabel heightLabel = new JLabel("迷宫高度:");
        JLabel levelLabel = new JLabel("难度:");
        JTextField widthText = new JTextField();
        JTextField heightText = new JTextField();
        JRadioButton level1 = new JRadioButton("1");
        JRadioButton level2 = new JRadioButton("2");
        JRadioButton level3 = new JRadioButton("3");
        ButtonGroup levelGroup = new ButtonGroup();
        levelGroup.add(level1);
        levelGroup.add(level2);
        levelGroup.add(level3);
        JButton run = new JButton("生成迷宫");

        // 设定标签位置
        widthLabel.setBounds(20, 20, 100, 30);
        heightLabel.setBounds(20, 70, 110, 30);
        widthText.setBounds(120, 20, 70, 30);
        heightText.setBounds(120, 70, 70, 30);
        levelLabel.setBounds(20, 120, 60, 30);
        level1.setBounds(80, 120, 50, 30);
        level2.setBounds(130, 120, 50, 30);
        level3.setBounds(180, 120, 50, 30);
        run.setBounds(55, 170, 120, 30);

        // 限制输入框只接收数字
        widthText.setDocument(new NumberTextField());
        heightText.setDocument(new NumberTextField());

        // 改变字体
        Font font = new Font("楷体", Font.PLAIN, 17);
        widthLabel.setFont(font);
        heightLabel.setFont(font);
        widthText.setFont(font);
        heightText.setFont(font);
        levelLabel.setFont(font);
        level1.setFont(font);
        level2.setFont(font);
        level3.setFont(font);
        run.setFont(font);

        // 取消按钮选中边框
        level1.setFocusPainted(false);
        level2.setFocusPainted(false);
        level3.setFocusPainted(false);

        // 默认选择难度3
        level3.setSelected(true);

        contentPane.add(widthLabel);
        contentPane.add(heightLabel);
        contentPane.add(widthText);
        contentPane.add(heightText);
        contentPane.add(levelLabel);
        contentPane.add(level1);
        contentPane.add(level2);
        contentPane.add(level3);
        contentPane.add(run);

        // 生成迷宫监听器
        run.addActionListener(e -> {
            // 建议宽在10-90,长在10-45之间
            if (widthText.getText().equals("")) {
                JOptionPane.showMessageDialog(null, "长度不能为空!", "提示", JOptionPane.INFORMATION_MESSAGE);
            } else if (heightText.getText().equals("")) {
                JOptionPane.showMessageDialog(null, "高度不能为空!", "提示", JOptionPane.INFORMATION_MESSAGE);
            } else {
                int width = Integer.parseInt(widthText.getText());
                int height = Integer.parseInt(heightText.getText());
                if (width >= 10 && width <= 90 && height >= 10 && height <= 45) {
                    int level = level1.isSelected() ? 1 : level2.isSelected() ? 2 : 3;
                    MazeModel maze = new MazeModel(width, height, level);
                    this.dispose();
                    maze.draw();
                } else {
                    JOptionPane.showMessageDialog(null, "迷宫的长必须在10-45之间,宽必须在10-90之间,请检查输入是否有误!", "错误输入", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        // 添加回车键入监听器
        KeyAdapter enterAdapter = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    run.doClick();   // 回车即生成迷宫
                }
            }
        };
        widthText.addKeyListener(enterAdapter);
        heightText.addKeyListener(enterAdapter);
    }

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

迷宫的数学模型

public class MazeModel {
    private int width;
    private int height;
    private ArrayList<MazePoint> mazePoints;

    /**
     * 迷宫的构造方法
     *
     * @param width  迷宫的宽度
     * @param height 迷宫的
     * @param level  1 -> 递归分割算法生成迷宫,2 -> 递归回溯算法生成迷宫,3 -> 普里姆算法生成迷宫
     */
    public MazeModel(int width, int height, int level) {
        super();
        this.width = width;
        this.height = height;
        switch (level) {
            case 1 : this.mazePoints = recursiveDivision();
            case 2 : this.mazePoints = recursiveBacktracker();
            case 3 : this.mazePoints = prim();
        }
    }

    /**
     * 递归回溯生成迷宫
     *
     * @return 生成的迷宫的单元格集合
     */
    private ArrayList<MazePoint> recursiveBacktracker() {
        ArrayList<MazePoint> maze = new ArrayList<>();
        // 初始化所以单元格都被强包围
        for (int h = 0; h < height; h++) {
            for (int w = 0; w < width; w++) {
                MazePoint point = new MazePoint(w, h, true);
                maze.add(point);
            }
        }
        // 建立一个存放操作单元格的栈
        Stack<MazePoint> stack = new Stack<>();
        // 选择(0,0)点作为起始点,开始打通迷宫
        stack.push(maze.get(0));
        maze.get(0).visited = true;

        Random random = new Random();
        int x;   // 操作单元格的横坐标
        int y;   // 操作单元格的纵坐标
        int direction;   // 方向
        while (!stack.empty()) {
            // 选择栈顶元素作为当前操作数
            MazePoint operatingPoint = stack.peek();
            x = operatingPoint.getX();
            y = operatingPoint.getY();

            direction = random.nextInt(4);
            MazePoint adjacency;

            switch (direction) {

                case 0: // 左边
                    if ((x - 1) >= 0) {   // 判断左边是否为边缘
                        adjacency = maze.get(x - 1 + y * width);   // 判断左边单元格是否被访问过
                        if (!adjacency.visited) {
                            operatingPoint.setLeft(0);   // 打通操作单元格的左墙,和左边单元格的右墙
                            adjacency.setRight(0);
                            stack.push(adjacency);    // 将左墙入栈,作为下次循环的操作单元格
                            adjacency.visited = true;    // 将左边的单元格设置为访问过了
                            x--;   // 改变操作单元格的坐标,方便后面判断当前单元格四周是否都访问过
                        }
                    }
                    break;
                case 1: // 右边
                    // 注释参照case0
                    if ((x + 1) < width) {
                        adjacency = maze.get(x + 1 + y * width);
                        if (!adjacency.visited) {
                            operatingPoint.setRight(0);
                            adjacency.setLeft(0);
                            stack.push(adjacency);
                            adjacency.visited = true;
                            x++;
                        }
                    }
                    break;
                case 2: // 上边
                    // 注释参照case0
                    if ((y - 1) >= 0) {
                        adjacency = maze.get(x + (y - 1) * width);
                        if (!adjacency.visited) {
                            operatingPoint.setUp(0);
                            adjacency.setDown(0);
                            stack.push(adjacency);
                            adjacency.visited = true;
                            y--;
                        }
                    }
                    break;
                case 3: // 下边
                    // 注释参照case0
                    if ((y + 1) < height) {
                        adjacency = maze.get(x + (y + 1) * width);
                        if (!adjacency.visited) {
                            operatingPoint.setDown(0);
                            adjacency.setUp(0);
                            stack.push(adjacency);
                            adjacency.visited = true;
                            y++;
                        }
                    }
                    break;
            }

            // 若操作单元格四周都被访问过,将该单元格出栈。
            if ((x - 1 < 0 || maze.get(x - 1 + y * width).visited)
                    && (x + 1 >= width || maze.get(x + 1 + y * width).visited)
                    && (y - 1 < 0 || maze.get(x + (y - 1) * width).visited)
                    && (y + 1 >= height || maze.get(x + (y + 1) * width).visited)) {
                stack.pop();
            }
        }

        maze.get(0).setLeft(0);    // 左上角开墙作为入口
        maze.get(width * height - 1).setRight(0);    // 右下角开墙作为出口
        return maze;
    }

    /**
     * 分割迷宫区域
     *
     * @param maze  单元格集合
     * @param right 区域的宽
     * @param top   区域的高
     */
    private void divide(ArrayList<MazePoint> maze, int left, int right, int top, int down) {
        if (right - left > 0 && top - down > 0) {
            // 在区域中心”十“字筑墙
            for (int x = left, y = (top - down) / 2 + down; x <= right; x++) {
                maze.get(x + y * this.width).setDown(1);
                maze.get(x + (y + 1) * this.width).setUp(1);
            }
            for (int x = (right - left) / 2 + left, y = down; y <= top; y++) {
                maze.get(x + y * this.width).setRight(1);
                maze.get(x + 1 + y * this.width).setLeft(1);
            }

            // 在“十”字墙中选其中三个方向拆一面墙
            Random random = new Random();
            int direction = random.nextInt(4);
            int x = (right - left) / 2 + left;
            int y = (top - down) / 2 + down;
            int tempX;
            int tempY;
            if (direction != 0) {    // 打通一面左边的墙
                if (x - left > left) {
                    tempX = random.nextInt(x - left + 1) + left;
                } else {
                    tempX = left;
                }
                tempY = y;
                maze.get(tempX + tempY * this.width).setDown(0);
                maze.get(tempX + (tempY + 1) * this.width).setUp(0);
            }
            if (direction != 1) {    // 打通一面右边的墙
                if (right - (x + 1) > x + 1) {
                    tempX = random.nextInt(right - (x + 1) + 1) + x + 1;
                } else {
                    tempX = x + 1;
                }
                tempY = y;
                maze.get(tempX + tempY * this.width).setDown(0);
                maze.get(tempX + (tempY + 1) * this.width).setUp(0);
            }
            if (direction != 2) {    // 打通一面上面的墙
                tempX = x;
                if (y - down > down) {
                    tempY = random.nextInt(y - down + 1) + down;
                } else {
                    tempY = down;
                }
                maze.get(tempX + tempY * this.width).setRight(0);
                maze.get(tempX + 1 + tempY * this.width).setLeft(0);
            }
            if (direction != 3) {    // 打通一面下面的墙
                tempX = x;
                if (top - (y + 1) > y + 1) {
                    tempY = random.nextInt(top - (y + 1) + 1) + y + 1;
                } else {
                    tempY = y + 1;
                }
                maze.get(tempX + tempY * this.width).setRight(0);
                maze.get(tempX + 1 + tempY * this.width).setLeft(0);
            }

            maze.stream().limit(this.width).forEach(m -> m.setUp(1));
            maze.stream().skip((this.height - 1) * this.width).forEach(m -> m.setDown(1));
            maze.stream().filter(m -> m.getX() == 0).forEach(m -> m.setLeft(1));
            maze.stream().filter(m -> m.getX() == width - 1).forEach(m -> m.setRight(1));
            divide(maze, left, (right - left) / 2 + left, (top - down) / 2 + down, down);
            divide(maze, left, (right - left) / 2 + left, top, (top - down) / 2 + down + 1);
            divide(maze, (right - left) / 2 + left + 1, right, (top - down) / 2 + down, down);
            divide(maze, (right - left) / 2 + left + 1, right, top, (top - down) / 2 + down + 1);
        }
    }

    /**
     * 递归分割生成迷宫
     *
     * @return 生成的迷宫的单元格集合
     */
    private ArrayList<MazePoint> recursiveDivision() {
        // 初始化迷宫的所有单元格
        ArrayList<MazePoint> maze = new ArrayList<>();
        for (int h = 0; h < height; h++) {
            for (int w = 0; w < width; w++) {
                MazePoint point = new MazePoint(w, h);
                maze.add(point);
            }
        }
        divide(maze, 0, width - 1, height - 1, 0);  // 递归分割迷宫

        maze.get(0).setLeft(0);    // 左上角开墙作为入口
        maze.get(width * height - 1).setRight(0);    // 右下角开墙作为出口
        return maze;
    }

    private ArrayList<MazePoint> prim() {
        ArrayList<MazePoint> mazePoints = new ArrayList<>();
        PrimMaze primMaze = new PrimMaze(width * 2 + 1, height * 2 + 1);
        int[][] tempMaze = primMaze.getMaze();
        for (int i = 0; i < tempMaze.length; i++) {
            for (int j = 0; j < tempMaze[i].length; j++) {
                if (i % 2 != 0 && j % 2 != 0) {
                    MazePoint mazePoint = new MazePoint(i / 2, j / 2);
                    if (tempMaze[i - 1][j] == 10) {
                        mazePoint.setLeft(1);
                    }
                    if (tempMaze[i + 1][j] == 10) {
                        mazePoint.setRight(1);
                    }
                    if (tempMaze[i][j - 1] == 11) {
                        mazePoint.setUp(1);
                    }
                    if (tempMaze[i][j + 1] == 11) {
                        mazePoint.setDown(1);
                    }
                    mazePoints.add(mazePoint);
                }
            }
        }
        mazePoints.get(0).setLeft(0);    // 左上角开墙作为入口
        mazePoints.get(width * height - 1).setRight(0);    // 右下角开墙作为出口
        return mazePoints;
    }

    public void draw() {
        new PlayView(mazePoints);
    }

}

普里姆算法

class PrimMaze {
    private int[][] maze;

    public int[][] getMaze() {
        return maze;
    }

    PrimMaze(int row, int column) {
        int row1 = row / 2;
        int column1 = column / 2;
        maze = new int[row1 * 2 + 1][column1 * 2 + 1];
        for (int x = 0; x < row1 * 2 + 1; x++)            //初始化迷宫
        {
            for (int y = 0; y < column1 * 2 + 1; y++) {
                if (x == 0 || x == row1 * 2) {
                    maze[x][y] = -1;
                }
                if (y == 0 || y == column1 * 2) {
                    maze[x][y] = -1;
                }
            }
        }
        for (int x = 1; x < row1 * 2; x++) {
            for (int y = 1; y < column1 * 2; y++) {
                if (x % 2 == 1 || y % 2 == 1) {
                    maze[x][y] = 0;
                }
                if (x % 2 == 0 || y % 2 == 0) {
                    maze[x][y] = 1;
                }
            }
        }

        ArrayList<int[]> list = new ArrayList<>();            //记录已连通的"路"的坐标的集合
        int[] coordinate = new int[2];        //记录未访问的点坐标
        int x = 1, y = 1;        //设置起点位置
        coordinate[0] = coordinate[1] = 1;
        list.add(coordinate);        //将起点加入已经连通的路集合

        //x,y表示当前访问坐标
        while (list.size() < row1 * column1)            //当所有点都已访问完时结束
        {
            boolean flag1;        //标识坐标是否已经被访问
            int[] record = {-1, -1, -1, -1};        //用于记录四周未被访问的方位,0代表上,1代表下,2代表左,3代表右

            if (x - 2 > 0)            //判断当前位置上方是否有路
            {
                int[] a = new int[2];
                a[0] = x - 2;
                a[1] = y;
                flag1 = judge(a, list);        //判断上方是否已经被访问
                if (flag1) {
                    record[0] = 0;
                }
            }
            if (x + 2 < row1 * 2)        //判断当前位置下方是否有路
            {
                int[] a = new int[2];
                a[0] = x + 2;
                a[1] = y;
                flag1 = judge(a, list);        //判断下方是否已经被访问
                if (flag1) {
                    record[1] = 1;
                }
            }
            if (y - 2 > 0)        //判断当前位置左方是否有路
            {
                int[] a = new int[2];
                a[0] = x;
                a[1] = y - 2;
                flag1 = judge(a, list);        //判断左方是否已经被访问
                if (flag1) {
                    record[2] = 2;
                }
            }
            if (y + 2 < column1 * 2)        //判断当前位置右方是否有路
            {
                int[] a = new int[2];
                a[0] = x;
                a[1] = y + 2;
                flag1 = judge(a, list);        //判断右方是否已经被访问
                if (flag1) {
                    record[3] = 3;
                }
            }

            boolean flag2 = false;            //flag2标识四周是否有未访问过的路
            for (int i = 0; i < 4; i++)        //判断当前位置的四个方位是否有未访问过的路
            {
                if (record[i] == i) {
                    flag2 = true;        //如果有未访问过的路,跳出循环
                    break;
                }
            }

            int r = new Random().nextInt(4);
            while (record[r] == r) {
                r = new Random().nextInt(4);
            }

            while (record[r] != r && flag2)            //当方位标识错误且当前位置四周有未访问过的点时继续随机获取一个新的方位标识,直到标识正确
            {
                r = new Random().nextInt(4);        //随机选取一个可以符合条件的墙并将其敲碎
                if (record[r] == r)        //当标识正确时,敲碎两点之间的墙
                {
                    if (r == 0) {       //当上方有未访问过的点时,敲碎上方的墙
                        maze[x - 1][y] = 0;
                    }
                    if (r == 1) {        //当下方有未访问过的点时,敲碎下方的墙
                        maze[x + 1][y] = 0;
                    }
                    if (r == 2) {         //当左方有未访问过的点时,敲碎左方的墙
                        maze[x][y - 1] = 0;
                    }
                    if (r == 3) {       //当右方有未访问过的点时,敲碎右方的墙
                        maze[x][y + 1] = 0;
                    }
                }
            }

            //将与当前坐标之间的墙被敲碎的路的坐标从未被访问的集合中移出
            if (r == 0 && flag2)        //如果敲碎的是上方的墙,则将上方的路加入到已连通的路集合
            {
                int[] b = new int[2];
                b[0] = x - 2;
                b[1] = y;
                if (judge(b, list)) {
                    list.add(b);
                }
            }
            if (r == 1 && flag2)        //如果敲碎的是下方的墙,则将下方的路加入到已连通的路集合
            {
                int[] b = new int[2];
                b[0] = x + 2;
                b[1] = y;
                if (judge(b, list)) {
                    list.add(b);
                }
            }
            if (r == 2 && flag2)        //如果敲碎的是左方的墙,则将左方的路加入到已连通的路集合
            {
                int[] b = new int[2];
                b[0] = x;
                b[1] = y - 2;
                if (judge(b, list)) {
                    list.add(b);
                }
            }
            if (r == 3 && flag2)        //如果敲碎的是右方的墙,则将右方的路加入到已连通的路集合
            {
                int[] b = new int[2];
                b[0] = x;
                b[1] = y + 2;
                if (judge(b, list)) {
                    list.add(b);
                }
            }

            int i = new Random().nextInt(list.size());            //随机选取一个被连通的路坐标
            x = list.get(i)[0];                //获取路坐标
            y = list.get(i)[1];
        }

        for (int r = 0; r < maze.length; r++)//将方格墙转为线条墙,10表示横,11表示竖
        {
            for (int c = 0; c < maze[r].length; c++) {
                if (r % 2 == 0 && c % 2 == 1) {
                    if (maze[r][c] != 0) {
                        maze[r][c] = 10;
                    }
                }
                if (r % 2 == 1 && c % 2 == 0) {
                    if (maze[r][c] != 0) {
                        maze[r][c] = 11;
                    }
                }
            }
        }

    }

    boolean judge(int[] coordinate, ArrayList<int[]> list)            //判断路是否已经加入通路集合,已加入则返回false
    {
        boolean flag = true;
        for (int[] ints : list) {
            if (coordinate[0] == ints[0] && coordinate[1] == ints[1])            //若已访问点集合中含有该位置的坐标,表示该位置已访问过,不用重复加入该位置的坐标
            {
                flag = false;
                break;
            }
        }
        return flag;
    }
}

总结

通过此次的《复杂迷宫》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。

java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。

以上就是Java实现经典游戏复杂迷宫的详细内容,更多关于Java迷宫游戏的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java实现的迷宫游戏

    完整项目地址: https://github.com/richenyunqi/Maze-game 软件总体框架 该软件主要分为如下三个模块: 参数设置模块 按钮功能模块按钮功能模块 迷宫主界面模块迷宫主界面模块 软件各模块介绍 参数设置模块 1.迷宫大小相关参数: ROWS(即迷宫行数,默认设置为奇数,最小值为11,最大值为99,默认值为11): COLS(即迷宫列数,默认设置为奇数,最小值为11,最大值为99,默认值为11): Lattice's width(即组成迷宫的格子的宽度,迷宫格子默

  • java实现单词搜索迷宫游戏

    本文实例讲述了java实现单词搜索迷宫游戏.分享给大家供大家参考.具体分析如下: 我们在杂志上,经常能够看到找单词的小游戏,在一个二维表格中,存在各种字母,我们可以从八个方向找单词.这个用计算机处理十分方便,但是,算法的好坏很重要,因为要是用蛮力算法实现,那么耗费的时间是不可想象的. 这是数据结构与问题求解Java语言描述一书中给的实现思路 完整代码如下,注释写的很明白了 import java.io.BufferedReader; import java.io.FileReader; impo

  • Java递归实现迷宫游戏

    目录 1.问题由来 2.问题的描述 3.思路分析 4.代码实现 5.结果输出 1.问题由来 迷宫实验是取自心理学的一个古典实验.在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒中设置了许多墙,对行进方向形成了多处阻挡.盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口.对同一只老鼠重复进行上述实验,一直到老鼠从入口到出口,而不走错一步.老鼠经多次试验终于得到它学习走迷宫的路线. 2.问题的描述 有一个迷宫地图,有一些可达的位置,也有一些不可达的位置(障碍.墙壁.边界)

  • Java小项目之迷宫游戏的实现方法

    项目要求: 一个网格迷宫由n行n列的单元格组成,每个大院个要么是空地(用0表示),要么是障碍物(用1表示),你的任务是找一条从起点到终点的移动序列,其中只能上下左右移动到相邻单元格.任何时候都不能在有障碍物的单元格中,也不能走到迷宫之外,起点为左上角和终点右下角. 项目功能: 解决迷宫路径查找问题,寻找一条从左上角迷宫入口到右下角迷宫出口的一条有效路径,0代表可走,1代表能走,找到请输出最终的迷宫和路径信息,找不到请输出不存在有效路径. 思路: 1.定义一个迷宫节点类型(MazeNode)的二维

  • 老程序员教你一天时间完成Java迷宫小游戏

    目录 效果图 实现思路 迷宫算法(网上参考的) 相关图示说明 代码实现 创建窗口 创建菜单及菜单选项 绘制迷宫的每个单元 计算并打通迷宫 绘制起点终点 加入键盘移动监听 收尾 总结 效果图 实现思路 1.创建运行窗口. 2.创建菜单. 3.绘制迷宫的每个单元. 4.通过算法计算迷宫路径,并打通路径,形成迷宫. 5.绘制起点终点. 6.添加键盘事件控制起点方块移动. 7.收尾. 迷宫算法(网上参考的) 1.将起点作为当前迷宫单元并标记为已访问 2.当还存在未标记的迷宫单元,进行循环 1).如果当前

  • Java编写迷宫小游戏

    缘起: 去年(大三上学期)比较喜欢写小游戏,于是想试着写个迷宫试一下. 程序效果: 按下空格显示路径: 思考过程: 迷宫由一个一个格子组成,要求从入口到出口只有一条路径. 想了一下各种数据结构,似乎树是比较合适的,从根节点到每一个子节点都只有一条路径.假设入口是根节点,出口是树中某个子节点,那么,从根节点到该子节点的路径肯定是唯一的. 所以如果能构造一棵树把所有的格子都覆盖到,也就能够做出一个迷宫了. 另外还要求树的父节点和子节点必须是界面上相邻的格子. 在界面显示时,父节点和子节点之间共用的边

  • Java实现经典游戏复杂迷宫

    目录 前言 主要设计 功能截图 代码实现 总结 前言 人类建造迷宫已有5000年的历史.在世界的不同文化发展时期,这些奇特的建筑物始终吸引人们沿着弯弯曲曲.困难重重的小路吃力地行走,寻找真相.迷宫类小游戏应运而生.在游戏中,迷宫被表现为冒险舞台里,藏有各式各样奇妙与谜题或宝藏的危险区域.型态有洞窟.人工建筑物.怪物巢穴.密林或山路等.迷宫内有恶徒或凶猛的生物(真实存在或想像物体都有)徘徊,其中可能会有陷阱.不明设施.遗迹等. <复杂迷宫>游戏是用java语言实现,采用了swing技术进行了界面

  • JAVA实现经典游戏坦克大战的示例代码

    目录 前言 主要设计 功能截图 代码实现 总结 前言 小时候大家都玩过坦克大战吧,熟悉的旋律和丰富的关卡陪伴了我们一整个寒暑假,还记得传说中的经典坦克大战 吗?那些怀旧的记忆,伴随着我们一起走过来的经典坦克大战,刚开始那战战兢兢,屡屡被敌人坦克击毁的情景历历在目.现在好了,再也不用担心敌人坦克了,可 以横冲直撞,横扫敌人坦克了.快哉!!! <坦克大战>游戏以坦克战斗为主题,用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 可以生成不同的地图,消灭地

  • Java实现经典游戏飞机大战-I的示例代码

    目录 前言 主要设计 功能截图 代码实现 启动类 核心类 核心算法 总结 前言 <飞机大战-I>是一款融合了街机.竞技等多种元素的经典射击手游.华丽精致的游戏画面,超炫带感的技能特效,超火爆画面让你肾上腺素爆棚,给你带来全方位震撼感受,体验飞行战斗的无限乐趣. 游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 玩家控制一台战斗机,以消灭所有的敌机为胜利,有些敌机会掉落装备,不可错过哦 主要设计 1. 用Swing库做可视化界面 2.鼠标控制战

  • Java实现经典游戏2048的示例代码

    目录 前言 主要设计 功能截图 代码实现 界面布局类 业务逻辑类 总结 前言 2014年Gabriele Cirulli利用周末的时间写2048这个游戏的程序,仅仅只是好玩而已.他想用一种不同的视觉展现效果和更快速的动画来创造属于自己的游戏版本. 游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 每次控制所有方块向同一个方向运动,两个相同数字的方块撞在一起之后合并成为他们的和,每次操作之后会在空白的方格处随机生成一个2或者4,最终得到一个“20

  • Java实现经典游戏推箱子的示例代码

    目录 前言 主要设计 功能截图 代码实现 核心类 声音播放类 总结 前言 <推箱子>推箱子是一个古老的游戏,目的是在训练你的逻辑思考能力.在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务. 游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 控制搬运工上下左右移动,来将箱子推到指定地点 主要设计 1.游戏面板生成显示

  • Java实现经典游戏Flappy Bird的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏启动类 核心类 工具类 总结 前言 <布谷鸟闯关-简单版>是一个基于java的布谷鸟闯关游戏,摁上键控制鸟的位置穿过管道间的缝隙,需要做碰撞检测,监听键盘事件,背景图片的切换,障碍物管道产生时y轴上需要随机位置. 主要设计 设计游戏界面,用swing实现 设计背景 设计移动墙 设计布谷鸟 设计障碍物 设计背景音乐和音效 由几个关键的布尔类型变量start,crash,over是产生键键盘事件时用来控制界面显示的弹框的 操作:空格键开始游戏,ente

  • Java实现经典游戏黄金矿工的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏核心类 钩子类 总结 前言 <黄金矿工>游戏是一个经典的抓金子小游戏,它可以锻炼人的反应能力..该游戏中,可以通过“挖矿”获得积分,游戏道具:有3瓶药水,在回收绳子抓金子的时候速度稍快点. 主要设计 设计游戏界面,用swing实现 随机创建金块算法 随机创建石块算法 计时系统设计 积分系统设计 设置鼠标事件,鼠标左键出钩子:鼠标右键开始游戏,确认吃药水等功能. 功能截图 游戏开始: 抓金子 代码实现 游戏核心类 public class GameW

  • Java实现经典游戏打砖块游戏的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏核心类 小球类 砖块类 总结 前言 <JAVA打砖块>游戏是自制的游戏.玩家操作一根萤幕上水平的“棒子”,让一颗不断弹来弹去的“球”在撞击作为过关目标消去的“砖块”的途中不会落到萤幕底下. 主要设计 设计游戏界面,用swing实现 设计砖块,砖块类, 设计小球,满屏乱跑的小球类,负责打碎砖块 设计棒子,左右移动的木头板类 球碰到砖块.棒子与底下以外的三边会反弹,落到底下会失去一颗球,把砖块全部消去就可以破关. 小球碰到砖块的回调算法设计 小球碰到棒

  • Java实现经典游戏超级玛丽的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏主界面 马里奥 小怪 总结 前言 在你的童年记忆里,是否有一个蹦跳.顶蘑菇的小人? 如果你回忆起了它,你定然会觉得现在它幼稚.无聊,画面不漂亮,游戏不精彩……但请你记住:这才是真正的游戏,它给了你无限的欢乐! 马里奥是靠吃蘑菇成长,闻名世界的超级巨星.特征是大鼻子.头戴帽子.身穿背带工作服.还留着胡子. 如此经典的游戏,你怎么能错过,快来玩玩吧. <超级玛丽>游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想.

  • Java实现经典游戏泡泡堂的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏启动类 核心监听类 核心线程类 总结 前言 <泡泡堂I>是一个基于java的自制游戏,游戏设计为双人pk积分赛模式,在这个模式里面,玩家只要率先达到一定分数既可以赢得比赛.玩家可以通过炸箱子可以得到少量的分数,也可以通过炸掉对手然后戳破包围对手的水泡得到大量分数.而玩家如果被泡泡爆炸击中,会被泡泡包裹一段时间,在这段时间内不可以移动和放泡泡,需要等时间过去或者被对手戳破水泡才能获得自由.但如果玩家被自己放的泡泡炸中,会扣一定的分数. 主要设计 设计

随机推荐