You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java游戏开发:JOptionPane弹窗打开时如何暂停当前线程?

嘿,这个需求其实很好实现,核心就是让游戏循环在弹窗弹出时暂停,等用户操作完弹窗再恢复(或者退出)。我给你梳理下具体步骤和代码调整方案:

1. 先准备线程安全的暂停标记

首先,我们需要一个线程可见的暂停开关,用来控制游戏循环的运行状态。用volatile修饰可以保证多线程之间的变量可见性,避免出现线程缓存导致的逻辑错误:

// 定义在游戏类中的成员变量
private volatile boolean isGamePaused = false;
// 如果你的游戏循环是单独的线程,也要把它作为成员变量保存
private Thread gameLoopThread;
2. 改造游戏循环线程

如果你的游戏是在单独的线程里跑循环(这是推荐的做法,避免阻塞UI线程),需要在循环里加入暂停检查逻辑,当标记为暂停时,让线程进入等待状态:

// 初始化并启动游戏循环线程
gameLoopThread = new Thread(() -> {
    while (!Thread.currentThread().isInterrupted()) {
        // 循环检查是否暂停,若暂停则进入等待
        while (isGamePaused) {
            synchronized (this) {
                try {
                    wait(); // 线程进入等待,直到被唤醒
                } catch (InterruptedException e) {
                    // 如果线程被中断,直接退出循环
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        // 游戏核心逻辑:更新状态 + 渲染画面
        updateGameState(); // 比如角色移动、碰撞检测等
        renderGame();       // 绘制游戏画面

        // 控制帧率,比如每秒60帧,约16ms一帧
        try {
            Thread.sleep(16);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            break;
        }
    }
});
gameLoopThread.start();
3. 在弹窗触发时控制游戏暂停/恢复

接下来修改你的windowClosing方法,在弹出JOptionPane之前先暂停游戏,等用户做出选择后再处理:

window.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent event) {
        // 第一步:暂停游戏
        isGamePaused = true;

        // 第二步:弹出确认弹窗(模态对话框,会阻塞当前UI线程)
        int dialogResult = JOptionPane.showConfirmDialog(
                null,
                "Would You Like to exit this game? Your progress will not be saved!",
                "Warning",
                JOptionPane.YES_NO_OPTION
        );

        // 第三步:根据用户选择处理
        if (dialogResult == JOptionPane.YES_OPTION) {
            // 用户选择退出:终止游戏线程,关闭窗口
            gameLoopThread.interrupt();
            window.dispose();
            System.exit(0);
        } else {
            // 用户选择返回:恢复游戏运行
            synchronized (this) {
                isGamePaused = false;
                notifyAll(); // 唤醒等待的游戏循环线程
            }
        }
    }
});
额外注意事项
  • 如果你的游戏是直接在主线程运行的(不推荐,会导致UI卡顿),那JOptionPane本身是模态对话框,会自动阻塞主线程,游戏自然就暂停了,但这种方式体验很差,建议尽快改成单独的游戏循环线程。
  • wait()和notifyAll()必须在同步块中调用,确保线程安全,避免出现线程状态异常。
  • volatile关键字不能少,否则游戏循环线程可能无法及时感知到isGamePaused的变化。

内容的提问来源于stack exchange,提问作者Danedesta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:53:51