Как реализовать хорошее игровое меню на Java? - PullRequest
2 голосов
/ 04 января 2011

Я какое-то время работал над Java-игрой, которую начал еще в студенческие годы. После значительных перерывов, связанных с моей профессиональной карьерой, я вернулся к этому и понял, насколько ужасен код. У меня в основном был «монолитный основной» с графическим интерфейсом и игровой логикой в ​​одном файле классов. То, что я пытаюсь сделать, это абстрагировать и «разбить» GUI на более мелкие куски. Мой исполняемый класс расширяет JFrame , который я добавляю и удаляю панели в / из при нажатии кнопок. Ex.

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 я получаю экземпляр singleton 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:

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

Как лучше всего сообщить классу GameFrame , что я нажал кнопку воспроизведения? Могу ли я отправить ему событие или сообщение с одной из его подпанелей с указанием запустить его, и если да, как я могу предотвратить запуск игры в потоке Event ? Должен ли я обработать это в методе actionPerformed () и просто создать новый поток? Я бы предпочел оставить это в главной теме. Спасибо.

Ответы [ 2 ]

1 голос
/ 04 января 2011

Go для Slick 2D (облегченная среда разработки игр OpenGL 2D с множеством интересных вещей) или Nifty-GUI .

Slick также имеет несколько примеров и учебных пособий и прост в освоении, например, StateBasedGame может быть легко использован для реализации нескольких игровых меню (таких как главное меню, меню настроек, внутриигровые настройки, внутриигровые игры). пауза / возобновление и т. д.)

0 голосов
/ 04 января 2011

Вы должны иметь игровую логику, выполняющуюся в своем собственном потоке выполнения, возможно, когда пользователь нажимает кнопку.Я не понимаю ваш предыдущий подход с while (wait) - это все равно создало бы проблемы, если бы ваша игровая логика выполняла некоторые трудоемкие вычисления, которые не позволяли четному потоку выполнять обновления, потому что четный поток не прекращает выполняться при вызове startGame ().

РЕДАКТИРОВАТЬ:

Из вставленного вами кода не ясно, что обновления графического интерфейса и логика игры происходят в отдельных потоках выполнения - вы можете захотеть продемонстрировать это в своем коде.

...