迷宫游戏设计

实验要求
1.要求随机生成一个迷宫,并求解迷宫
2.要求游戏支持玩家走迷官,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系统走迷宫珞径要求基于A*算法实现、输出走迷宫都最优路径显示。

设计过程分析

  1. 开始界面点击即可开始游戏 这里是用Java中的JFrame添加了背景和按钮,如何设置按钮监听器即可进入下一个界面。主要代码:

设计背景:

 //不采用任何布局方式
       ct=this.getContentPane();
       this.setLayout(null);

       //设置背景
       bgp=new GamePanel((new ImageIcon("src/images/bj3.png")).getImage());
       bgp.setBounds(0,0,600,500);
       ct.add(bgp);

创建按钮:

  //创建按钮
       jb=new JButton("开始游戏");
       jb.setBounds(220,180,100,80);
       jb.setForeground(Color.BLACK);
       jb.setBackground(Color.lightGray);
       jb.setBorder(null);
       ct.add(jb);

       jb.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
               close();
               new GameStart();
           }
       });


2.进入游戏界面,这里我设计了四个按钮选择迷宫模式有:简单、中等、困难和自定义模式,自定义输入行数和列数即可。如图:

选择游戏难度

    private JButton button1 = new JButton("简单");
    private JButton button2 = new JButton("中等");
    private JButton button3 = new JButton("困难");
    private JButton button4 = new JButton("自定义");
    
    //将选择按钮包含在选择面板上
        JPanel choose = new JPanel();
        choose.setLayout(new GridLayout(2, 2));
        choose.add(button1);
        choose.add(button2);
        choose.add(button3);
        choose.add(button4);
        button1.setBackground(Color.CYAN);
        button2.setBackground(Color.ORANGE);
        button3.setBackground(Color.red);
        button4.setBackground(Color.PINK);

设计监听器进入游戏界面:

//设计监听器
        button1.addActionListener(this);
        button2.addActionListener(this);
        button3.addActionListener(this);
        button4.addActionListener(this);

3.游戏界面设置菜单。
菜单有游戏,编辑和帮助。游戏里设置了开始游戏,返回和退出选项。点击开始游戏玩家即可自己操纵鼠标移动小鸟,返回可返回上一个界面重新选择游戏难度,退出即退出游戏。编辑设有编辑当前迷宫和随机生成迷宫,玩家选择编辑当前迷宫即可在迷宫中把墙打通,随机生成迷宫可生成新的迷宫。帮助里设置了选择最优路径,系统自动生成最优路径,玩家不需要操纵。代码如下:

 // 菜单项
    private JMenuItem m_start = new JMenuItem("开始游戏");
    private JMenuItem m_return = new JMenuItem("返回菜单");
    private JMenuItem m_exit = new JMenuItem("退出游戏");
    private JMenuItem m_selfconfig = new JMenuItem("编辑当前迷宫");
    private JMenuItem m_randommake = new JMenuItem("随机生成迷宫");
    private JMenuItem m_sortpath = new JMenuItem("显示最短路径");

 //菜单
        JMenu game = new JMenu("游戏");
        JMenu edit = new JMenu("编辑");
        JMenu tip = new JMenu("帮助");
        game.add(m_start);
        game.add(m_return);
        game.add(m_exit);
        edit.add(m_selfconfig);
        edit.add(m_randommake);
        tip.add(m_sortpath);

        //菜单栏
        JMenuBar menu = new JMenuBar();
        menu.add(game);
        menu.add(edit);
        menu.add(tip);

设置菜单监听器,点击按钮实现相应的功能。

3.初始化迷宫组件,生成迷宫。迷宫设置为小鸟找食物。

 //初始化迷宫组件,并生成随机路径
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++) {
                tp[i][j] = new Maze();
            }
        Operations.creatMaze();  //深度优先遍历生成至少有一条随机通道的迷宫

        //迷宫地图
        JPanel mazePane = new JPanel();
        mazePane.setLayout(new GridLayout(m, n, 0, 0));
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                mazePane.add(tp[i][j]);
            }
        }

4.生成迷宫,从某一点开始深度优先遍历与它x 、y坐标相差均为偶数的点构成的图,并打通每一步需要通过的墙。算法思想: 将起点作为当前迷宫单元并标记为已访问,当还存在未标记的迷宫单元,进行循环 。
1).如果当前迷宫单元有未被访问过的的相邻的迷宫单元
(1).随机选择一个未访问的相邻迷宫单元
(2).将当前迷宫单元入栈
(3).移除当前迷宫单元与相邻迷宫单元的墙
(4).标记相邻迷宫单元并用它作为当前迷宫单元
2).如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空
(1).栈顶的迷宫单元出栈
(2).令其成为当前迷宫单元
这个算法叫做“深度优先”,简单来说,就是从起点开始走,寻找它的上下左右4个邻居,然后随机一个走,到走不通的时候就返回上一步继续走,直到全部单元都走完。

部分代码如下:

//深度优先遍历生成至少有一条随机通道的迷宫
    public static void creatMaze() {
        m = map.m;
        n = map.n;
        //遍历前初始化工作
        isBeVisit = new boolean[m * n];
        for (int i = 0; i < m * n; i++) isBeVisit[i] = false;      //是否已被访问

        //迷宫初始化
        for (int i = 0; i < m; i++) {                  //防止发生两边上全为墙的情况
            map.tp[i][0].change(Math.random() * 3 > 1 ? 0 : 1);
            map.tp[i][n - 1].change(Math.random() * 3 > 1 ? 0 : 1);
        }
        for (int i = 0; i < n; i++) {
            map.tp[0][i].change(Math.random() * 3 > 1 ? 0 : 1);
            map.tp[m - 1][i].change(Math.random() * 3 > 1 ? 0 : 1);
        }
        for (int i = 1; i < m - 1; i++)
            for (int j = 1; j < n - 1; j++)
                map.tp[i][j].change(0);  //内部的位置初始化全为墙

        m_startx =  (int) (Math.random() * m / 2);
        m_starty = (int)  (Math.random() * n / 2);    //随机生成小鸟位置

        //从小鸟位置开始深度优先遍历与它x 、y坐标相差均为偶数的点构成的图
        DFS(m_startx * n + m_starty);

        //这一步在 tp[m-2][n-2]与小鸟位置x 、y坐标相差均为偶数时非常重要,保证有到达食物的路径
        if (Math.random() * 2 > 1)
            map.tp[m - 2][n - 1].change(1);
        else
            map.tp[m - 1][n - 2].change(1);    //两者只要有一个为路即可,故随机取其一

        //小鸟和食物的位置作另作处理
        map.tp[m_startx][m_starty].change(2);  //小鸟
        map.tp[m - 1][n - 1].change(3);            //食物

        changeable_key = false;  //键盘不可控制小鸟移动
        m_currex = m_startx;
        m_currey = m_starty;  //开始新游戏前小鸟当前位置与开始位置相等
        restart = false;
    }

5.最优路径选择,部分代码:

 //利用已生成的路径深度图,找到从小鸟和食物之间的最短路径
        int[] path = new int[m * n];                    //用于存放最短路径的数组
        int currePoint = m_startx * n + m_starty;         //当前访问点,初始值为小鸟位置
        int depth = depthGraph[currePoint];         //小鸟位置的路径深度值
        int step = depth - 1;                     //当前要查找的路径深度
        while (step > 0) {
            currex = currePoint / n;
            currey = currePoint % n;
            if (currey + 1 < n && depthGraph[currePoint + 1] == step) {
                currePoint += 1;
            } else if (currex + 1 < m && depthGraph[currePoint + n] == step) {
                currePoint += n;
            } else if (currey - 1 >= 0 && depthGraph[currePoint - 1] == step) {
                currePoint -= 1;
            } else if (currex - 1 >= 0 && depthGraph[currePoint - n] == step) {
                currePoint -= n;
            }
            path[step--] = currePoint;
        }
        int s;         //临时存放位置
        for (int i = 1; i < depth; i++) {
            s = path[i];
            map.tp[s / n][s % n].change(2);   //显示最短路径
        }

        restart = true;                //可开始新游戏

    }

6.迷宫生成完成,如图所示:
开始游戏界面:
控制鼠标可·移动小鸟,快帮助小鸟找到食物吧
系统推荐最优路径界面
最优路径显示
玩家走迷宫显示路径界面:玩家走迷宫

7.2021/12/16
个人小结:在做这个项目的过程中,首先为了美观想把按钮设成透明,在参考了好多网上的资料也没成功就放弃了。其次在生成迷宫的过程中,刚开始在设置和生成随机数时出现了不少问题,比如随机数会一直生成等,在多次测试后,总算生成成功了。然后在实现最优路径的选择时,也把我难到了,在参考老师PPT上的A*算法的那个网站才写出来了。最后,这个迷宫也有许多不足之处,比如功能不够完善,还没有显示小鸟走过的路径,我本来考虑加一个定时器,每走一步刷新界面,保留上一个页面,可能是我设置的方式不对吧,它还是没有显示,我打算在考虑一下别的思路。然后在添加一些别的功能,比如设置时间限制和背景音乐等。
2021/12/17
经过更改和调试,玩家走迷宫的走过的路径也显示了。如上图所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值