邪丶魔狱 2022-04-30 21:04 采纳率: 0%
浏览 32
已结题

在paint方法中调用自定义的方格打开方法,方格无法再点击后立刻打开

问题遇到的现象和发生背景

最近用Java写了一个扫雷游戏,写到后面发现点击方格无法立即将方格打开,需要在点击方格后,再点击任务栏中的程序图标,将其隐藏并再次打开才能使其生效,求解决方法和问题原因

问题相关代码,请勿粘贴截图
public class MineSweeping extends JFrame {
    /** 启动扫雷游戏 */
    public void launch() {

        MineSweeping mineSweeping = new MineSweeping();

        mineSweeping.setVisible(true) /* 设置窗口大小可调整 */;
        mineSweeping.setSize(width, height) /* 设置窗口大小 */;
        mineSweeping.setTitle("扫雷") /* 设置窗口标题 */;
        mineSweeping.setLocationRelativeTo(null) /* 设置窗口居中显示 */;
        /*
         * 设置窗口关闭方式
         *   1. DO_NOTHING_ON_CLOSE 不执行任何操作
         *   2. HIDE_ON_CLOSE 默认关闭操作,不会释放内存,只隐藏界面,调用setVisible(false)
         *   3. DISPOSE_ON_CLOSE 隐藏并释放窗体,调用dispose(),当最后一个窗口被释放后,程序也随之结束
         *   4. EXIT_ON_CLOSE 直接关闭应用程序,调用System.exit(0)
         */
        mineSweeping.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        /* 鼠标监听事件
         *    MouseAdapter用于接收鼠标事件的抽象适配类
         *      mouseClicked: 鼠标点击事件
         *      mousePressed: 鼠标按下事件
         *      mouseReleased: 鼠标释放事件
         *      mouseEntered: 鼠标进入事件
         *      mouseExited: 鼠标退出事件
         *      mouseWheelMoved: 鼠标滚轮移动事件
         *      mouseDragged: 鼠标拖动事件
         *      mouseMoved: 鼠标移动事件
         */
        mineSweeping.addMouseListener(new MouseAdapter() {
            /* 鼠标点击事件
             *    MouseEvent.BUTTON1: 左键被使用
             *    MouseEvent.BUTTON2: 滚轮被使用
             *    MouseEvent.BUTTON3: 右键被使用
             */
            @Override
            public void mouseClicked(MouseEvent e) {

                super.mouseClicked(e);

                switch (Map.GAME_STATE) {

                    case 0:

                        Mouse.X = e.getX();
                        Mouse.Y = e.getY();

                        /* 当前事件若为左键点击事件,则运行左键单击按钮的方法 */
                        if (MouseEvent.BUTTON1 == e.getButton()) Mouse.leftClickState = true;
                        /* 判断当前事件是否为右键点击事件 */
                        if (MouseEvent.BUTTON3 == e.getButton()) Mouse.rightClickState = true;

                    case 1:

                    case -1:

                        /* 重置游戏 */
                        if (MouseEvent.BUTTON1 == e.getButton()) {
                            if (e.getX() >= Map.OFFSET + Map.SQUARE_SIDE_LENGTH * (Map.X - 1) / 2 &&
                                    e.getX() <= Map.OFFSET + Map.SQUARE_SIDE_LENGTH * (Map.X - 1) / 2 + Map.SQUARE_SIDE_LENGTH &&
                                    e.getY() >= Map.OFFSET * 3 / 2 &&
                                    e.getY() <= Map.OFFSET * 3 / 2 + Map.SQUARE_SIDE_LENGTH) {

                                Mouse.leftClickState = false;

                                Mouse.rightClickState = false;

                                MapBottom.resetTheUnderlyingMap();

                                MapTop.resetTopLevelMap();

                            }
                        }

                        Map.GAME_STATE = 0 /* 重置游戏状态 */;

                        break;

                    default:
                }
            }
        });

        /* 不停绘制地图 */
        while (WindowConstants.DISPOSE_ON_CLOSE != mineSweeping.getDefaultCloseOperation()) {
            repaint();
            /* 睡眠40毫秒 */
            try {
                Thread.sleep(40);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 绘制扫雷地图
     * @param g 画图工具
     */
    @Override
    public void paint(Graphics g) {

        /* 通过将顶层地图与底层地图绘制到一个新的画布中来解决窗体组件闪动问题 */
        Image image = this.createImage(width, height);

        Graphics graphics = image.getGraphics() /* 获取画笔 */;

        graphics.setColor(new Color(181, 181, 181)) /* 设置背景颜色 */;
        graphics.fillRect(0,0,width, height) /* 填充整个画布 */;

        MapBottom.drawABottomMap(graphics) /* 将底层地图绘制到新画布中 */;
        MapTop.drawATopLevelMap(graphics) /* 将顶层地图绘制到新画布中 */;

        g.drawImage(image, 0,0,null) /* 将新生成的图片绘制到画布中 */;

    }
}
public class MapTop {
    /**
     * 画扫雷顶层地图
     * @param g 画笔对象
     */
    public static void drawATopLevelMap(Graphics g) {

        MapTop.gridOpen();

        for (int i = 0; i < Map.X; i++) {
            for (int j = 0; j < Map.Y; j++) {
                switch (MapTop.DATA_TOP_LAYER[i][j]) {
                    case 0:
                        g.drawImage(TOPICON,
                                Map.OFFSET + i * Map.SQUARE_SIDE_LENGTH + 1,
                                3 * Map.OFFSET + j * Map.SQUARE_SIDE_LENGTH + 1,
                                Map.SQUARE_SIDE_LENGTH -2,
                                Map.SQUARE_SIDE_LENGTH -2,
                                null);
                        break;
                    case 1:
                        g.drawImage(FLAG_ICON,
                                Map.OFFSET + i * Map.SQUARE_SIDE_LENGTH + 1,
                                3 * Map.OFFSET + j * Map.SQUARE_SIDE_LENGTH + 1,
                                Map.SQUARE_SIDE_LENGTH -2,
                                Map.SQUARE_SIDE_LENGTH -2,
                                null);
                        break;
                    case 2:
                        g.drawImage(DEBUG_BOMB_ICON,
                                Map.OFFSET + i * Map.SQUARE_SIDE_LENGTH + 1,
                                3 * Map.OFFSET + j * Map.SQUARE_SIDE_LENGTH + 1,
                                Map.SQUARE_SIDE_LENGTH -2,
                                Map.SQUARE_SIDE_LENGTH -2,
                                null);
                    default:
                }
            }
        }
    }

    /** 打开方格 */
    private static void gridOpen() {

        int x = 0,
                y = 0;

        if (Mouse.X > Map.OFFSET && Mouse.Y > 3 * Map.OFFSET) {
            x = (Mouse.X - Map.OFFSET) / Map.SQUARE_SIDE_LENGTH;
            y = (Mouse.Y - Map.OFFSET * 3) / Map.SQUARE_SIDE_LENGTH;
        }

        if (0 <= x && Map.X >= x && 0 <= y && Map.Y >= y) {

            if (Mouse.leftClickState) {

                if (MapTop.DATA_TOP_LAYER[x][y] == 0) MapTop.DATA_TOP_LAYER[x][y] = -1 /* 将未打开的方格打开 */;

                MapTop.openBlankSquare(x, y);

                Mouse.leftClickState = false;

            }

            if (Mouse.rightClickState) {

                switch (MapTop.DATA_TOP_LAYER[x][y]) {
                    case -1:
                        openSquaresByNumbers(x, y);
                        break;
                    case 0:
                        MapTop.DATA_TOP_LAYER[x][y] = 1 /* 未插旗则插旗 */;
                        break;
                    case 1:
                        MapTop.DATA_TOP_LAYER[x][y] = 0 /* 已插旗则取消插旗 */;
                        break;
                    default:
                }

                Mouse.rightClickState = false;

            }
        }

        if (triggerBomb()) {
            showAllBombs();
            Map.GAME_STATE = -1;
        }

        if (successfullyDefusedTheBomb()) {
            Map.GAME_STATE = 1;
        }
    }
}
运行结果及报错内容

没有任何报错内容

我想要达到的结果

使其能够在被点击后立即打开,不在需要频繁的点击任务栏图标打开

  • 写回答

2条回答 默认 最新

  • 歇歇 2022-04-30 21:55
    关注

    你录一段视频吧

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月1日
  • 创建了问题 4月30日

悬赏问题

  • ¥15 matlab答疑 关于海上风电的爬坡事件检测
  • ¥88 python部署量化回测异常问题
  • ¥30 酬劳2w元求合作写文章
  • ¥15 在现有系统基础上增加功能
  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄