如何在Java中实现一个好的游戏菜单?

时间:2011-01-03 22:29:47

标签: java user-interface event-handling menu

我在大学时代开始研究Java游戏已有一段时间了。由于我的职业生涯,在经历了相当多的休息之后,我又回到了它,并意识到代码是多么可怕。我基本上在同一个类文件中有一个GUI和游戏逻辑的“单片主”。我正在尝试做的是抽象并将GUI“组件化”为更小的块。我执行的类扩展了 JFrame ,我在单击按钮时添加和删除面板。实施例

public class GameFrame extends JFrame{
    private JPanel[] _panels = {new MainPanel(), new OptionsPanel(), new DifficultyPanel()};
    private int _currentPanelIndex = 0;
    public GameFrame(){
        ...
        add(_panels[_currentPanelIndex]);
        ...
    }
}

在每个面板类中,我有按钮的私有 ActionListeners 。在 MainPanel 中,我正在获取单例 GameFrame 实例并将当前面板设置为:

class SinglePlayerButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
        GameFrame instance = GameFrame.getInstance();
        JPanel[] panels = instance.getPanels();
        int currentPanelIndex = instance.getCurrentPanelIndex();
        instance.remove(panels[currentPanelIndex]);
        int newPanelIndex;
        for(newPanelIndex = 0; newPanelIndex < panels.length; newPanelIndex++){
            if(panels[newPanelIndex] instanceof DifficultyPanel){
                break;
            }
        }
        instance.add(panels[newPanelIndex]);
    }
}

我不喜欢我课堂上那种深刻的耦合,但我可以忍受它。然而,真正的问题是,当我点击进入游戏的最后一个按钮时,我不能拥有:

public void actionPerformed(ActionEvent e){
    GameFrame.getInstance().startGame();
}

因为这会导致我的游戏在Java Event 线程中运行,从而禁止处理任何其他事件。以前,我有一个忙碌的循环:

...
while(waiting){
    //Do nothing
}
remove(_panels[_currentPanelIndex]);
startGame();
...
...
public void actionPerformed(ActionEvent e){
    waiting = false;
}

让我的 GameFrame 课程知道我点击了播放按钮的最佳方法是什么?我可以从其中一个子面板发送一个事件或消息告诉它启动吗?如果是这样,我如何防止游戏在 Event 线程中运行?我应该在 actionPerformed()方法中处理它并简单地生成一个新线程吗?我宁愿把它放在主线程中。感谢。

2 个答案:

答案 0 :(得分:1)

转到Slick 2D(一个包含大量酷炫内容的轻量级OpenGL 2D游戏开发框架)或Nifty-GUI

Slick还有一些示例和教程,并且易于学习,例如StateBasedGame可以轻松用于实现多个游戏内菜单(例如主菜单,设置菜单,游戏内选项, - 游戏暂停/恢复等。)

答案 1 :(得分:0)

您应该让游戏逻辑在其自己的执行线程上执行,可能是在用户单击按钮时。我不了解你之前使用while(等待)的方法 - 如果你的游戏逻辑做了一些耗时的计算而导致偶数线程无法进行更新,那么仍会产生问题,因为偶数线程在你调用时不会停止执行startGame()。

编辑:

从您粘贴的代码中不清楚GUI更新和游戏逻辑是在单独的执行线程上发生的 - 您可能希望在代码中证明这一点。