2016-03-07 2 views
0

Я пытаюсь создать простую игру на Java. Исправлена ​​проблема с JTextPanel, которая не обновлялась до тех пор, пока игровой цикл не завершится, что, конечно же, не является хорошим опытом для игрока.Многопоточность без плотно связанных объектов

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

Класс контроллера и основная резьба. Мне нужна игра для игры и игра для запуска отдельно. Я попытался запустить класс Game в отдельном потоке, но код игры не запущен в gamePanel.

Контроллер:

import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 



public class Controller_LetterFall{ 
public static void main(String[] args){ 
    SwingUtilities.invokeLater(new Runnable(){ 
     public void run(){ 
      new MainFrame(); 
     } 
    }); 

    } 
} 

А класса мэйнфреймов. Я пытаюсь запустить gameplay() в новом потоке.

package wordFall; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JTextArea; 

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class MainFrame extends JFrame implements Runnable { 

private GamePlay game; 
private TextPanel gamePanel; 
private Header header; 
private Player player; 
private Dictionary dictionary; 
private GamePlay game; 

public MainFrame(){ 
super("Game"); 
    // Set the size of the frame. 
setSize(400,600); 
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
setVisible(true); 


// Establish default player. 
player = new Player(); 
dictionary = new Dictionary(); 
game = new GamePlay(); 
header = new Header(); 
gamePanel = new TextPanel(); 
add(header, BorderLayout.NORTH); 
add(gamePanel, BorderLayout.CENTER); 

this.game.setBoardInterface( 
     new BoardInterface(){ 
      @Override 
      public void redraw(String text) { 
       gamePanel.appendText(text); 
      } 
     }); 
    } 
    @Override 
    public void run() { 
     game.play(); 
     System.out.println("The game is over."); 
    } 
} 

Любая помощь будет принята с благодарностью.

+0

Я не вижу нитей в вашем примере. –

ответ

2

Вам нужно что-то вроде поточного контейнера данных. Позволяет называть его GameData. Ваш объект GamePlay должен знать, что объект GameData и пользовательский интерфейс должны знать это, а также потому, что изменения, сделанные пользователем, должны распространяться на объект GameData.

В вашем объекте GamePlay вы можете искать изменения объекта GameData каждую секунду или около того. Если есть какие-то изменения, чем вам нужно что-то делать, если нет.

Но лучше было бы использовать такой подход, как подход, например, Observer Pattern. Если изменения вносятся пользовательским интерфейсом, то GamePlay будет уведомлен наблюдаемым объектом GameData. Кроме того, пользовательский интерфейс также может быть уведомлен, когда данные будут изменены.

Это разделяет озабоченность очень четко и следует за образцом модели контроллера модели.

2

Ну, в этом случае ваш объект MainFrame строится из нити диспетчера свинг. Как вы сказали, вы должны начать новый поток где-то, чтобы справиться с игрой. Предполагая, что вы бы этот код в метод экземпляра объекта MainFrame, который был бы:

Thread thr = new Thread(this); 
thr.start(); 

Затем, когда ваша отдельная игра нить хочет обновить объект пользовательского интерфейса, он не должен делать это непосредственно, но использовать SwingUtilities .invokeLater:

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     /* Update the ui element... */ 
}}); 

это работоспособное будет выполнено в свинге диспетчерского потоке, когда у него будет время.

+0

Это будет работать нормально, если обновления не слишком часты и, что более важно, что runnable не имеет каких-либо гонок данных или проблем синхронизации (если он обращается к некоторым полям, измененным в игровом потоке, это быстро вызовет проблемы) , –

+0

Что может быть проблемой в случае слишком частых изменений, зависящих от действий игрового потока? –

+0

Ahh, нажал добавить случайно.Я также собирался сказать, что дело в правильности данных и синхронизации/параллельных коллекций/независимо от того, что необходимо для доступа к общим данным. –

Смежные вопросы