Как ждать, пока задача не будет завершена, а затем продолжить в потоке отправки событий? - PullRequest
1 голос
/ 12 января 2011

У меня есть программа, игра с графическим интерфейсом, созданным с помощью Swing.

Графический интерфейс состоит из моего собственного класса, который наследует JFrame и содержит JPanel с CardLayout, который имеет несколько JPanel в качестве карт.

На одной из этих панелей есть кнопка, которая запускает игру, и вид игры расположен на одной из карточек (объект-конструктор, который имеет свой собственный класс, который наследует JPanel, добавляется к карточке в конструкторе JFrame).

Теперь пролог:

Я нажимаю кнопку JButton и перехожу к потоку диспетчеризации событий, чтобы выполнить метод actionPerformed.

В этом методе я сначала переключаюсь на карту, которая содержит панель просмотра, затем создаю экземпляр уровня, на котором я собираюсь играть, и игрового движка (который создается в соответствии с уровнем). Затем я вызываю repaint для объекта просмотра (который должен закончиться при рисовании игры в окне приложения), а затем я вызываю объект игрового движка, чтобы запустить игровой цикл.

Моя проблема:

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

Итак, я вычитал, что, поскольку в Java все происходит не в том порядке, в котором оно написано, игровой цикл начинает выполняться ДО того, как другие операции в методе actionperformed были завершены.

Вот соответствующий фрагмент из метода actionperformed кортти = карточка кентта = уровень valikkopaneeli = панель с раскладкой карт aloitusnappula = кнопка, которая запускает игру Пели = класс, который я сделал, который наследует JFrame

if (e.getSource() == aloitusnappula) {

CardLayout kortti = (CardLayout) valikkopaneeli.getLayout (); Kentta kentta = новая Кентта ("testikentta.txt"); kortti.show (валиккопанеэли, "пели"); Peli.this.pack (); Peli.this.setVisible (истина); aloita (kentta); }

и вот фрагмент метода алоита (кентта):

public void aloita(Kentta kentta) {
 moottori = new Pelimoottori(Peli.this, kentta);
 nakyma.repaint();
 moottori.peliLooppi();
}

где Pelimoottori = класс Game Engine накима = вид объекта peliLooppi () = метод в классе Game Engine, запускающий игровой цикл

Если бы я удалил вызов moottori.peliLooppi () из метода aloita, представление игры показывалось бы нормально.

Я пытался гуглить некоторые ответы, и самое далекое, что у меня есть, это как-то делать это с SwingWorker, но почему-то это не похоже на хороший способ делать то, что я хочу.

Есть предложения?

Ответы [ 2 ]

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

Когда я удаляю фрагмент кода, который запускает игровой цикл, вид игры отображается на экране нормально

Похоже, вы, вероятно, используете цикл while с Thread.sleep.

Лучше всего использовать Swing Timer для планирования "зацикливания" вашей игры.

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

Полагаю, вы запускаете цикл двигателя внутри EDT. Если так, то это ПЛОХО.

Из edt вызовите другой поток и управляйте вашим движком из этого нового потока. Для обновления графического интерфейса, вызовите edt с SwingUtilities.invokeLater .

Или лучше использовать SwingWorker .

Чтобы прочитать хорошую документацию по английскому языку о долгосрочной работе на качелях, см. Параллельность в Swing . Не используйте Thread.sleep.

...