如何在JPanel中快速更新图形



我目前正在用Java制作一款2D回合制战略游戏。在开发的这个阶段,我正在测试不同种类的人工智能。

AI通过将x和y变量发送到一个名为gameRoop的函数来与游戏交互,该函数通常由mouseClicked函数调用。这使他们能够直接模仿人类用户,这使得他们与游戏的互动变得更加容易。下面是我的一些代码的概述:

paintComponent() {
drawTiles();
drawUnits();
if(unitSelected && gameState == DISP_MOVE)
drawMoveSpots();
}
gameLoop(int x, int y) {
// various logic based
// on the values of x and y
// logic may set unitSelected to true or false
// may also change gameState bteween normal and displayMoveSpots
repaint();
}

我现在的问题源于这样一个事实,即人工智能执行代码的速度比重新绘制更快。当这种情况发生时,我开始在各种绘图函数中出现错误,如NullPointerException和ConcurrentModificationException,因为gameRoop内部的逻辑更改变量的速度比重新绘制更快。如果我在人工智能调用gameRoop的频率上加上手动延迟,或者只有两个人在玩,错误就会消失。

从我对Java文档的研究和阅读中,我了解到重新绘制会立即返回,所有的图形调用都会放在EventQueue上,直到Java决定有足够的调用来保证实际的重新绘制。到目前为止,我能找到的唯一解决方案是将gameRoop中发生的逻辑代码放入一个匿名的可运行类中,并使用SwingUtilities.invokeAndWait调用代码,但这对我来说不是一个有效的解决方案,因为这会导致从点击到bug的实际人类交互。我曾考虑过使用锁来为gameRoop的逻辑部分/repaint提供互斥(这样一次只能执行一个),但我不确定这在处理Java图形时是否是一个好的做法。

在这一点上,我愿意接受任何关于我能做些什么来缓解我的问题的建议。

谢谢。

我的建议是应该使用摆动计时器

import javax.swing.Timer;
public static void main(String[] args) {
/*this is 1 sec/ 1000ms*/
Timer aiTimer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//move AI
//repaint
}
});
aiTimer.start();
}

这样你就不会经常重新喷漆了。希望能有所帮助!

相关内容

  • 没有找到相关文章

最新更新