Java Swing JFrame 为游戏启动另一个 JFrame
Java Swing JFrame launch another JFrame for game
我正在使用 Java 开发一个小游戏。我的应用程序有一个主 JFrame,它可以通过单击 JButton 创建另一个 Window(游戏 window)。
我已经单独测试了我的游戏window,一切正常。
这是我的游戏 window 构造函数:
public GameWindow(final GameController controller)
{
super("Boulder Dash Game");
this.controller = controller;
this.controller.registerObserver(getCurrentFrame());
this.gamePanel = new GamePanel(controller);
this.frameWidth = controller.getColumns() * 16;
this.frameHeight = controller.getRows() * 16 + 76;
getContentPane().add(gamePanel, BorderLayout.CENTER);
setSize(frameWidth, frameHeight);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
controller.startGame();
}
controller.startGame() 方法启动游戏循环。
当我直接从我的 main.
启动这个 window 时,游戏循环工作正常
现在,我想从我的主框架启动这个游戏Window框架。
这是我的主框架的代码:
playButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final @Nullable ActionEvent e)
{
String selectedItem = (String) levelsComboBox.getSelectedItem();
assert selectedItem != null;
controller.lauchGame(selectedItem);
}
});
controller.launchGame(String selectedItem) 是一种用于加载游戏关卡和启动游戏的方法window。
这是代码
public void lauchGame(final String levelQueried)
{
assert levelQueried != null;
Level level = LevelRepository.load(levelQueried);
assert level != null;
GameController controller = new GameController(model);
GameWindow view = new GameWindow(controller);
}
我的问题是,当我从另一个 JFrame 启动游戏Window 时,上面没有任何元素。如果我不在构造函数中启动游戏循环,我的游戏 windows 似乎已正确初始化(内容、关闭操作退出...)。但是当我启动 gameloop 时,我只有一个没有内容的空 JFrame(大小正确)。当我尝试退出框架时,我不能...
这是我的游戏循环代码:
public void start() throws InterruptedException // Game loop method
{
boolean updateGame = true;
while ( !isFinish() ) {
// We update the elements only 1 round of 2
if ( updateGame ) {
updateExitState();
getPlayField().updateMoovableEntities();
updateGame = false;
} else {
updateGame = true;
}
Thread.sleep(100);
// Animate the sprite at every round
setChanged();
notifyObservers(); // inform that a repaint is necessary
}
LOGGER.debug("The game loop for the current level is now finished.");
}
在控制台上,我可以看到游戏循环正在播放并且更新方法被正确调用...但是 paintComponent 从未被调用...所以我的框架上没有任何内容!
我对这个问题没有任何想法...有人可以帮我吗?
编辑:
谢谢你的回答。我已经使用
修改了我的游戏 Window 的构造函数
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
controller.startGame();
}
});
好多了,现在我的框架已经正确初始化了。但现在还有另一个问题,监听器不再可用……我根本无法与我的框架进行交互(无法退出,或执行任何其他操作……)。怎么了?
您通过 运行 在其上设置 while (true)
循环来完全冻结 Swing 事件线程(EDT 或事件分派线程)。不要那样做。相反,要么 运行 你的 while 循环在后台线程中,要么使用 Swing Timer 来驱动你的游戏循环。阅读本网站上的 Concurrency in Swing for more on this. Also, please read The Use of Multiple JFrames 个问题。
请注意,当您(错误地)在 main 方法中启动 GUI 和游戏循环时,您的游戏循环 运行 在主线程中而不是 Swing 事件线程中,因此在这种情况下您的游戏可行,但这不是一个好的解决方案,因为主 GUI 也是从 Swing 事件线程启动的,这可能导致间歇性的难以调试的线程错误。
我正在使用 Java 开发一个小游戏。我的应用程序有一个主 JFrame,它可以通过单击 JButton 创建另一个 Window(游戏 window)。 我已经单独测试了我的游戏window,一切正常。
这是我的游戏 window 构造函数:
public GameWindow(final GameController controller)
{
super("Boulder Dash Game");
this.controller = controller;
this.controller.registerObserver(getCurrentFrame());
this.gamePanel = new GamePanel(controller);
this.frameWidth = controller.getColumns() * 16;
this.frameHeight = controller.getRows() * 16 + 76;
getContentPane().add(gamePanel, BorderLayout.CENTER);
setSize(frameWidth, frameHeight);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
controller.startGame();
}
controller.startGame() 方法启动游戏循环。 当我直接从我的 main.
启动这个 window 时,游戏循环工作正常现在,我想从我的主框架启动这个游戏Window框架。 这是我的主框架的代码:
playButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final @Nullable ActionEvent e)
{
String selectedItem = (String) levelsComboBox.getSelectedItem();
assert selectedItem != null;
controller.lauchGame(selectedItem);
}
});
controller.launchGame(String selectedItem) 是一种用于加载游戏关卡和启动游戏的方法window。 这是代码
public void lauchGame(final String levelQueried)
{
assert levelQueried != null;
Level level = LevelRepository.load(levelQueried);
assert level != null;
GameController controller = new GameController(model);
GameWindow view = new GameWindow(controller);
}
我的问题是,当我从另一个 JFrame 启动游戏Window 时,上面没有任何元素。如果我不在构造函数中启动游戏循环,我的游戏 windows 似乎已正确初始化(内容、关闭操作退出...)。但是当我启动 gameloop 时,我只有一个没有内容的空 JFrame(大小正确)。当我尝试退出框架时,我不能...
这是我的游戏循环代码:
public void start() throws InterruptedException // Game loop method
{
boolean updateGame = true;
while ( !isFinish() ) {
// We update the elements only 1 round of 2
if ( updateGame ) {
updateExitState();
getPlayField().updateMoovableEntities();
updateGame = false;
} else {
updateGame = true;
}
Thread.sleep(100);
// Animate the sprite at every round
setChanged();
notifyObservers(); // inform that a repaint is necessary
}
LOGGER.debug("The game loop for the current level is now finished.");
}
在控制台上,我可以看到游戏循环正在播放并且更新方法被正确调用...但是 paintComponent 从未被调用...所以我的框架上没有任何内容!
我对这个问题没有任何想法...有人可以帮我吗?
编辑:
谢谢你的回答。我已经使用
修改了我的游戏 Window 的构造函数javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
controller.startGame();
}
});
好多了,现在我的框架已经正确初始化了。但现在还有另一个问题,监听器不再可用……我根本无法与我的框架进行交互(无法退出,或执行任何其他操作……)。怎么了?
您通过 运行 在其上设置 while (true)
循环来完全冻结 Swing 事件线程(EDT 或事件分派线程)。不要那样做。相反,要么 运行 你的 while 循环在后台线程中,要么使用 Swing Timer 来驱动你的游戏循环。阅读本网站上的 Concurrency in Swing for more on this. Also, please read The Use of Multiple JFrames 个问题。
请注意,当您(错误地)在 main 方法中启动 GUI 和游戏循环时,您的游戏循环 运行 在主线程中而不是 Swing 事件线程中,因此在这种情况下您的游戏可行,但这不是一个好的解决方案,因为主 GUI 也是从 Swing 事件线程启动的,这可能导致间歇性的难以调试的线程错误。