【问题标题】:Java Swing 2D Game - EventQueue stops firing after CardLayout switchJava Swing 2D游戏-CardLayout切换后EventQueue停止触发
【发布时间】:2023-04-02 20:44:01
【问题描述】:

我们想为我们的 2D 游戏添加一个菜单。

到目前为止,我们的游戏循环在主线程上运行,而来自 Swing 的 EventQueue 正在处理我们游戏的关键输入。现在,由于我们要添加菜单,我们不再可以简单地从我们的 main 方法启动游戏循环。

问题:我们不知道如何以EventQueue 不断收到KeyEvents 的方式启动游戏循环。

我们的菜单如下:

startGameButton.addActionListener(new ActionListener() {

    @Override
        public void actionPerformed(ActionEvent e) {
            CardLayout cl = (CardLayout)Menu.this.getParent().getLayout();
            cl.show(Menu.this.getParent(), "Game");
        }
    });

因此,单击startGameButton 会从JFrame 中删除菜单并显示游戏本身,但游戏被冻结,因为我们不再从主线程启动游戏循环。我们认为它就在这里,我们需要开始游戏循环。

所以我们创建了一个新的Thread,它将运行我们的游戏循环以防止我们的 UI 冻结:

startGameButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            CardLayout cl = (CardLayout)Menu.this.getParent().getLayout();
            cl.show(Menu.this.getParent(), "Game");

            Thread gameThread = new Thread(new Runnable() {

                @Override
                public void run() {
                    while (true) {
                        game.update();
                        game.repaint();
                        Thread.sleep(10);
                    }
                }
            });
            gameThread.start();
        }
    });

这很完美,游戏出现了,它正在运行……但是:我们的KeyEvents 不再开火了。不知何故,EventQueue 不再接收击键,我们不知道为什么。

在 main 方法中使用完全相同的代码(创建 Thread 并启动它)而不使用 CardLayout 菜单可以正常工作,也可以得到 KeyEvents。所以我们认为问题出在使用CardLayout 的某个地方,但我们不知道它到底是什么。

【问题讨论】:

  • @D-Klotz 谢谢,我会尝试一下,如果该解决方案适合我,请告诉您。
  • @D-Klotz 遗憾的是,使用输入映射并不能解决我的问题,在点击 startGameButton 之后,KeyListener 的游戏 JPanel 仍然没有触发它的事件。
  • 也许您需要发布您是如何实现输入映射的。创建一个显示问题的独立代码示例?通常当我这样做时,我会发现问题......
  • 问题既不是输入映射的实现也不是 KeyListener 本身,它只是一个焦点问题。因为点击startGameButton 将焦点从游戏的JPanel 移开。现在已经解决了。

标签: java swing user-interface cardlayout


【解决方案1】:

感谢 D-Klotz 对输入映射问题的评论。尽管这不是解决我问题的正确方法,但它让我注意到了一些事情:

当从 JFrame 切换到另一个窗口然后返回时,KeyListener 再次正常工作。所以actionPerformed 方法中唯一缺少的代码行是:

game.requestFocus();

像魅力一样工作。再次感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多