我正在尝试用Java构建一个简单的游戏。在游戏循环终止之前,直到JTextPanel没有更新的问题,这当然对玩家来说不是一个好的体验。
我不熟悉多线程,但试图解决这个问题。我现在可以在多个线程中运行单独的代码,但是我无法理解如何让线程进行交互。很可能我错过了一些简单的东西,但是我找不到它,所以我把自己放在你的怜悯之中。我挂了一个帖子......
控制器类和主线程。我需要gamePanel和游戏分开运行。我试图在一个单独的线程中运行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();
}
});
}
}
和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
对象,并且UI也需要知道这一点,因为用户所做的更改必须传播到GameData
对象。
在GamePlay
对象中,您可以每隔一秒左右查找GameData
对象的更改。如果有变化而不是你有什么事情要做..
但最好使用类似方法的事件,即Observer Pattern。如果UI进行了更改,则GamePlay
对象将通知GameData
。
此外,当数据发生变化时,也可以通知UI。
这非常清楚地分离了关注点并遵循模型视图控制器模式。
答案 1 :(得分:2)
嗯,在这种情况下,您的MainFrame对象是从swing调度程序线程构造的。正如你所说,你必须在某处开始一个新线程来处理游戏。假设您将在MainFrame对象的实例方法中使用此代码,那将是:
Thread thr = new Thread(this);
thr.start();
然后,每当您的单独游戏线程想要更新ui对象时,它不应该直接执行,而是使用SwingUtilities.invokeLater:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
/* Update the ui element... */
}});
当runnable有时间时,它将在swing调度程序线程中执行。