java - 如何在 JPanel 中快速更新图形

标签 java swing graphics jpanel paint

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

AI 通过将 x 和 y 变量发送到名为 gameLoop 的函数来与游戏交互,该函数通常由 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 之类的错误,因为 gameLoop 内部的逻辑更改变量的速度比重绘发生的速度更快。如果我在 AI 调用 gameLoop 的频率上添加手动延迟或只有 2 个人玩,错误就会消失。

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

目前,我愿意接受任何关于如何缓解我的问题的建议。

谢谢。

最佳答案

我的建议是你应该使用 Swing 计时器

  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();

}

这样做你就不会那么频繁地重画。希望有帮助!

关于java - 如何在 JPanel 中快速更新图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22086827/

相关文章:

java - 使用免费数据库和带有 Spring & Hibernate Web 应用程序的 Java 进行冗余数据库复制

java - 为什么我的 Spring Security 不工作?

java - JFrame 背景图像顶部出现奇怪的白色条纹

swing - Java SE 二进制崩溃

java - 修复由 2D 数组制成的 BufferedImage 的锯齿状边缘

java - Thread.start() 不初始化 run()

Java - iCal4j - 设置 X-ALT-DESC;FMTTYPE=text/html

java - 开发用于学习目的的 Java 桌面应用程序?

image - 如何从R中的三个矩阵创建RGB图像?

c++ - 运行 SFML 图形后看不到新窗口