在动作监听器中启动一个游戏

6
我有一个用Java制作的二十一点游戏,我想通过点击按钮来表示游戏的开始。我的所有动作监听器都可以正常工作,但问题是我无法在不完全运行actionPerformed方法的情况下启动游戏。显然,一个在actionPerformed方法中持续运行的函数将有效地禁用我的GUI的其余部分。以下是代码片段....
go.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
                 // START GAME SOMEHOW but must run outside of action listener
        }
    });

游戏启动时会发生什么?它不应该有循环。所有用户操作都应该是事件。 - JB Nizet
我认为一个好的解决方案可能是不启动整个游戏,而只是发牌并返回。然而,我想知道如何从操作监听器中启动程序。我想象这是可能的,但我对Java很新,对整个计算机也不太熟悉。任何提示将不胜感激! :) - Keith Salmon
感谢您的回复,JB。最初我将其初始化为新游戏,它在其构造函数内运行整个过程,因此actionPerformed方法只有一行代码:“game g = new game()”。然而,现在您提到它应该是一个事件,我更加确定我做错了。哈哈 - Keith Salmon
3个回答

7
显然,持续在actionPerformed方法内运行的函数会有效地禁用GUI的其余部分。这是一个有效的观察结论,表明您已经理解了在使用Swing时的基本规则。
您的游戏很可能是事件驱动的(如果我错了,请纠正我),因此按钮执行的操作应该只是将程序设置为等待更多事件的新状态。这并不需要耗费时间,并且通常直接由EDT完成。
当然,如果您想做一个花哨的开始新游戏动画,则需要在单独的线程中执行,这种情况下,您只需从actionPerformed方法内启动动画线程(我建议使用SwingWorker),然后返回即可。
代码实现上,我认为应该像这样:
go.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {

        // Remove the menu components
        someJPanel.removeAll();

        // Show the game table
        someJPanel.add(new GamePanel());

        someJPanel.revalidate();
        someJPanel.repaint();

        // done. Wait for further user actions.
    }
});

我觉得这听起来绝对是我应该做的事情。我要实施这个计划,看看它会带我去哪里。我很惊讶我如此快地得到了这么多回应。我真的很感激大家的帮助!!! - Keith Salmon

1

我相信你想要扩展 javax.swing.SwingWorker

非 UI 启动功能将在 doInBackground 中运行,当它完成以更新 UI 时,done 方法将被调用。

甚至在 javadoc 类描述中有一个示例,可以使用进度条更新启动过程中正在发生的状态。


1

你的游戏应该在自己的线程中启动并管理(很难说),但是为了让你开始,你可以在actionPerformed中启动一个新的“外部”线程,类似于以下内容:

public void actionPerformed(ActionEvent e) {
    Thread thread = new Thread("Game thread") {
        public void run() {
            startGame(); //or however you start your game
        }
    };
    thread.start();
}

除非这是一个以“每秒帧数”为驱动/连续动画的应用程序,否则我认为启动一个运行游戏的单独线程似乎不是一个好主意。actionPerformed 应该只调整用户界面,然后返回并等待进一步的用户操作。 - aioobe
我认为游戏运行时没有返回,听起来对我来说不太像事件驱动。 - Mattias Isegran Bergander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接