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

如何在俄罗斯轮盘赌Swing程序中使用Swing Timer实现暂停效果?

解决Swing Timer在俄罗斯轮盘赌游戏中的使用问题

我太懂你这种困扰了——之前用Thread.sleep()的时候,界面直接卡死,图片根本来不及显示,对吧?这是因为Swing是单线程UI模型,所有界面更新都在事件调度线程(EDT)里完成,Thread.sleep()会阻塞EDT,导致界面完全没法刷新,自然看不到图片。

Swing Timer就是为这种场景设计的:它在EDT里调度任务,不会阻塞界面,还能精准控制延迟时间。下面我给你重构代码,解决这个问题:

核心思路

原来的for循环会瞬间跑完所有轮次,中间的图片根本没机会显示。我们需要把游戏拆成分阶段执行,用Timer来触发每一轮的逻辑,每轮存活后等待几秒再进入下一轮。

修改后的完整代码

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicInteger;

public class YourGameClass implements ActionListener { // 假设你的类实现了ActionListener
    private JFrame frame;
    private JLabel label1, label2;

    @Override
    public void actionPerformed(ActionEvent e) {
        PanelCasino panel = (PanelCasino) e.getSource(); // 修正获取panel的方式,根据你的实际情况调整
        frame = new JFrame();
        
        // 1. 提前生成子弹的固定位置(俄罗斯轮盘的子弹位置是固定的,不是每轮随机)
        final int bulletPosition = (int)(Math.random() * 6 + 1);
        // 2. 用原子整数跟踪当前轮次(lambda里需要线程安全的变量)
        AtomicInteger currentRound = new AtomicInteger(0);
        
        // 3. 封装每一轮的配置,避免重复的if-else
        record RoundConfig(
                int randomRangeMax,   // 本轮随机数的最大值
                boolean isOtherPlayer,// 本轮轮到对方还是自己
                String aliveImage,    // 存活时显示的图片
                String deadImage,     // 死亡时显示的图片
                String aliveText,     // 存活时的文本
                String deadText,      // 死亡时的文本
                int betChange         // 输赢对应的赌注变化(+赢,-输)
        ) {}

        // 定义6轮游戏的配置
        RoundConfig[] rounds = {
            new RoundConfig(6, true, "gun1.jpg", "gun3.jpg", "The other player lives...", "The other player got sprayed up!", panel.bet),
            new RoundConfig(5, false, "gun2.jpg", "gun4.jpg", "You live...", "You got sprayed up! Rip!", -panel.bet),
            new RoundConfig(4, true, "gun1.jpg", "gun3.jpg", "The other player lives...", "The other player got sprayed up!", panel.bet),
            new RoundConfig(3, false, "gun2.jpg", "gun4.jpg", "You live...", "You got sprayed up! Rip!", -panel.bet),
            new RoundConfig(2, true, "gun1.jpg", "gun3.jpg", "The other player lives...", "The other player got sprayed up!", panel.bet),
            new RoundConfig(1, false, null, "gun4.jpg", null, "You got sprayed up! Rip!", -panel.bet) // 最后一轮必中
        };
        
        // 4. 创建Swing Timer,每2秒触发一次下一轮(可根据需求调整延迟时间,单位毫秒)
        Timer gameTimer = new Timer(2000, null);
        gameTimer.addActionListener(timerEvent -> {
            int current = currentRound.getAndIncrement();
            if (current >= rounds.length) {
                gameTimer.stop(); // 所有轮次结束,停止计时器
                return;
            }

            RoundConfig currentConfig = rounds[current];
            int randomNum = (int)(Math.random() * currentConfig.randomRangeMax + 1);

            // 判断本轮是否命中子弹
            boolean isHit = (current == 5) || (bulletPosition == randomNum);
            if (isHit) {
                // 死亡逻辑:显示死亡图片和文本,更新赌注,停止游戏
                label2.setIcon(new ImageIcon(currentConfig.deadImage));
                label1.setText(currentConfig.deadText);
                panel.total += currentConfig.betChange;
                gameTimer.stop();
            } else {
                // 存活逻辑:显示存活图片和文本,等待Timer触发下一轮
                label2.setIcon(new ImageIcon(currentConfig.aliveImage));
                label1.setText(currentConfig.aliveText);
            }

            // 更新界面显示
            panel.label3.setText(String.valueOf(panel.total));
            panel.revalidate();
            panel.repaint(); // 强制刷新界面,确保图片和文本及时显示
        });

        // 第一轮立即执行,不需要等待延迟
        gameTimer.setInitialDelay(0);
        gameTimer.start();
    }
}

关键细节说明

  1. 固定子弹位置:原来的代码每轮都生成新的num,这不符合俄罗斯轮盘的逻辑——子弹位置是固定的,每次只是随机选择发射位置,所以我们提前生成bulletPosition,整个游戏过程中保持不变。
  2. 轮次配置封装:用record把每轮的参数打包,避免了大量重复的if-else,代码更易维护。
  3. Timer的工作方式:Timer的actionPerformed方法在EDT中执行,所以所有UI更新都是安全的,不会出现线程问题。
  4. 延迟控制:设置2000毫秒(2秒)的延迟,你可以根据需要调整这个数值,比如改成1500就是1.5秒。
  5. 界面刷新:每次更新后调用repaint()确保界面及时刷新,避免图片或文本不显示的问题。

额外注意事项

  • 确保图片路径正确:如果图片放在项目的资源文件夹里,可能需要用getClass().getResource("gun1.jpg")来获取路径,避免找不到图片的问题。
  • 避免重复启动Timer:如果用户多次点击按钮,要确保之前的Timer已经停止,不然会出现多个Timer同时运行的混乱情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:15:46