使用Java写迷宫之迷宫的升华(三)

使用Java写迷宫之迷宫的升华

本文介绍

之前的文章讲述了如何将前面建立的生成迷宫、解决迷宫更好的连接起来,使其更美观。(里面有一些println语句,是我在测试和修bug时使用的,有些没有删除,请见谅)

初始化界面

在这里插入图片描述使页面在窗口的中间位置显示,并添加按钮,供玩家选择,添加关闭按钮的监听,添加页面Icon。

void initPanel () {
        JFrame newJFrame = new JFrame();
        int side = 30;
        int width;
        int height;
        //任务栏高度
        double task = 30;
        double a = Toolkit.getDefaultToolkit().getScreenSize().getWidth() - task;
        double b = Toolkit.getDefaultToolkit().getScreenSize().getHeight() - task;
        //添加画布
        if (setting == null) {
            //这里的6弥补一点宽度
            width = widthCount * side + 6;
            //这里创建的窗口高度需要加1,也需要留一点位置给按钮
            height = heightCount * side + side * 1;
            newJFrame.add(new MyPanel(widthCount, heightCount, DFSMethod, newJFrame));
            newJFrame.setBounds((int)(a/2) - width/2,(int)(b/2) - height/2,
                    width,
                    height);
        } else {
            width = setting.getWidth() * side + 6;
            height = setting.getHeight() * side + side * 1;
            newJFrame.add(new MyPanel(setting.getWidth(), setting.getHeight(), setting.getModel(), newJFrame));
            newJFrame.setBounds((int)(a/2) - width/2,(int)(b/2) - height/2,
                    width,
                    height);
        }
        this.setVisible(false);
        newJFrame.setVisible(true);
        newJFrame.setResizable(false);
        newJFrame.setTitle("小蝌蚪找妈妈迷宫");
        ImageIcon img = new ImageIcon("src\\images\\mazeIcon.jpg");
        newJFrame.setIconImage(img.getImage());
        newJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

设置页面

在这里插入图片描述
默认开始参数:
设置长为23,宽为23,深度优先遍历产生地图

public Setting (MazeFrame mazeFrame) {
        this.mazeFrame = mazeFrame;
        int labelX = 10, labelY = 10, labelW = 70, fieldX = 80, fieldY = 10, fieldW = 240, height = 30, hSpace = 35;
        int frameW = 350, frameH = 230, btnW = 120;
        double a = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        double b = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
        frame.setLocation(new Point((int) (a / 2) - 150, (int) (b / 2) - 150));// 设定窗口出现位置
        frame.setSize(frameW, frameH);// 设定窗口大小
        frame.setContentPane(tabPane);// 设置布局
        labelWidth.setBounds(labelX, labelY, labelW, height);
        labelHeight.setBounds(labelX, labelY = labelY + hSpace, labelW, height);
        label2.setBounds(labelX, labelY = labelY + hSpace, labelW, height);
        fieldWidth.setBounds(fieldX, fieldY, fieldW, height);
        fieldHeight.setBounds(fieldX, fieldY = fieldY + hSpace, fieldW, height);
        comboBox.setBounds(fieldX, fieldY = fieldY + hSpace, fieldW, height);
        button.setBounds((frameW-btnW)/2, fieldY = fieldY + hSpace, btnW, height);
        button.addActionListener(this);
        comboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String value = comboBox.getSelectedItem().toString();
                    if ("DFS生成算法".equals(value)) {
                        model = DFSMethod;
                    } else {
                        model = BFSMethod;
                    }
                    System.out.println(value);
                }
            }
        });
        _ONE.add(labelWidth);
        _ONE.add(labelHeight);
        _ONE.add(label2);
        _ONE.add(fieldWidth);
        _ONE.add(fieldHeight);
        _ONE.add(comboBox);
        _ONE.add(button);
        frame.setVisible(true);// 窗口可见
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        tabPane.add("难度设置", _ONE);
        fieldWidth.setText("23");
        fieldHeight.setText("23");
    }

上面是初始化设置的页面展示,因为我是从fieldWidth和fieldHeight中读取数据的,在刚初始化就设定为23,就设定好默认结果了。如果想改变,只需要键盘在文本框中输入就行了。
在这里插入图片描述# 对宽度和高度的限制

我们知道,如果用户输入了一个很大的数,因为地图会根据长宽生成不一样的大小,就会把整个窗口占满,如果输入了一个很小的数,地图就会不好玩。我测试了一下我电脑的大小,将长度设定在7至31范围内,将宽度设定在7至53范围内。以及我们发现,因为生成迷宫需要的长和宽都是奇数,如果用户输入偶数,也会对那个数进行修改(就是调用setText方法改宽和高)。具体代码如下:

在这里插入图片描述
按下确定后:
在这里插入图片描述在这里插入图片描述
然后进入游戏界面:
在这里插入图片描述

private void startPanel() {

        String widthValue = fieldWidth.getText();
        String HeightValue = fieldHeight.getText();
        try {
            widthCount = Integer.parseInt(widthValue);
            if (widthCount > 53) {
                JOptionPane.showMessageDialog(comboBox,"宽度过长,已经帮您修改为53","警告",JOptionPane.WARNING_MESSAGE);
                widthCount = 53;
                fieldWidth.setText("53");
            }
            if (widthCount < 7) {
                JOptionPane.showMessageDialog(comboBox,"宽度过短,已经帮您修改为7","警告",JOptionPane.WARNING_MESSAGE);
                widthCount = 7;
                fieldWidth.setText("7");
            }
            if (widthCount % 2 != 1) {
                JOptionPane.showMessageDialog(comboBox,"宽度需要是奇数哦,已经帮您修改数值为" + (widthCount+1),
                        "警告",JOptionPane.WARNING_MESSAGE);
                widthCount += 1;
                fieldWidth.setText(String.valueOf(widthCount));
            }
            System.out.println("宽度"  + widthCount);
        } catch (NumberFormatException numberFormatException) {
            JOptionPane.showMessageDialog(comboBox,"宽度输入格式不正确!","警告",JOptionPane.WARNING_MESSAGE);
        }
        try {
            heightCount = Integer.parseInt(HeightValue);
            heightCount = (heightCount % 2 == 1) ? heightCount : heightCount + 1;
            if (heightCount > 31) {
                JOptionPane.showMessageDialog(comboBox,"长度过长,已经帮您修改为31","警告",JOptionPane.WARNING_MESSAGE);
                heightCount = 31;
                fieldHeight.setText("31");
            }
            if (heightCount < 7) {
                JOptionPane.showMessageDialog(comboBox,"长度过短,已经帮您修改为7","警告",JOptionPane.WARNING_MESSAGE);
                heightCount = 7;
                fieldHeight.setText("7");
            }
            if (heightCount % 2 != 1) {
                JOptionPane.showMessageDialog(comboBox,"长度需要是奇数哦,已经帮您修改数值为" + (heightCount+1),
                        "警告",JOptionPane.WARNING_MESSAGE);
                heightCount += 1;
                fieldHeight.setText(String.valueOf(heightCount));
            }
            System.out.println("高度" + heightCount);
        } catch (NumberFormatException numberFormatException) {
            JOptionPane.showMessageDialog(comboBox,"长度输入格式不正确!","警告",JOptionPane.WARNING_MESSAGE);
        }

        //new SelectTableToGenerageDialog();触发下一个弹框
        frame.dispose();//关闭弹框
    }

电脑帮玩

发现仔细的小伙伴以及看到那个按钮了,只要按下那个按钮,电脑会自动帮您走完全部过程,但是只能在起始点才能按,否则会出现这个情况。

具体的代码如下:

void initButton() {
        ansButton = new JButton("开启自动寻路");
        ansButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (go && !buttonOpen) {
                    JOptionPane.showMessageDialog(null,
                            "您已经开始,所以无法再帮您寻找通路了",
                            "警告",JOptionPane.WARNING_MESSAGE);
                    return;
                }
                buttonOpen = !buttonOpen;
                if (!buttonOpen) {
                    ansButton.setText("开启自动寻路");
                } else {
                    ansButton.setText("关闭自动寻路");
                    go = true;
                }
                map = mapForComputer;
                Thread thread = new Thread(new LookWay());
                thread.start();
            }
        });
        ansButton.setVisible(true);
        ansButton.setFocusable(false);
    }

首先说明的是,如果想要点击按钮,然后还想要关闭按钮,需要用到多线程的技术。
我建立了一个内部类,好共用变量。

class LookWay extends Thread {
        @Override
        public void run() {

            while (!isSucceed && buttonOpen) {
                //todo
                int[][] xy = getSELFxy();
                int selfX = xy[0][0];
                int selfY = xy[0][1];
                moveDirect(selfX, selfY);
                //System.out.println(selfX + " " + selfY);
                //printMap();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

每个0.1秒执行一次moveDirect方法,这个方法会找到之前传过来的map,与此同时也有一份ansMap,在这里保存了需要的答案,在之前的文章中,介绍了答案的位置是6,所以那个方法仅仅只是遍历四周,然后找到6,执行移动方法即可。(goUp之类的方法在上一个文章中写明,如果需要,请您返回看一下)

private void moveDirect(int x, int y) {
            for (int i = 0; i < 4; i++) {
                if (map[x + dir[i][0]][y + dir[i][1]] == ANS
                        || map[x + dir[i][0]][y + dir[i][1]] == END) {
                    if (i == 0) {
                        goUp();
                        System.out.println(i);
                        return;
                    } else if (i == 1) {
                        goDown();
                        System.out.println(i);
                        return;
                    } else if (i == 2) {
                        goLeft();
                        System.out.println(i);
                        return;
                    } else if (i == 3) {

                        goRight();
                        System.out.println(i);
                        return;
                    }
                }
            }
        }
    }

在这里插入图片描述当然,如果您想中途暂停,也是可以的,但是暂停以后就无法再使用按钮了。
在起始点点击后的情况:
在这里插入图片描述点击后想再打开:
在这里插入图片描述还有一些细节就请您继续探索啦!如果大佬们能够提出宝贵意见或者进行功能的完善的话,我将感激涕零!

代码地址:
百度网盘地址:

链接:https://pan.baidu.com/s/1YTArg_iub13-qiKqF2e4ig
提取码:xiga

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值