1

在开始某事之前进行研究是一个好主意,所以在开始一个项目之前,我一直在查看 Stackverflow 上的文章。

现在,在查找 tilemaps 时,其他问题之一将我引向 Java 教程之一,特别是这个页面 ( http://docs.oracle.com/javase/tutorial/uiswing/painting/step3.html ),其中一些东西引起了我的注意, 这个:

private void moveSquare(int x, int y) {
    int OFFSET = 1;
    if ((squareX!=x) || (squareY!=y)) {
        repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
        squareX=x;
        squareY=y;
        repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
    } 
}

对于那些不知道调用paint时发生了什么的人,在squareX,squareY处绘制红色正方形,这是允许您更改squareX和squareY的方法,它通过告诉Java限制区域来加快重绘过程仅重绘到旧位置和新位置(这是重绘的两个调用)

现在这听起来像是我应该使用的东西,当更新瓷砖时,它的坐标会被重新绘制,但瓷砖地图通常涉及二维数组并在绘画时循环遍历整个数组,可能涉及单个位置的多个图像,而大部分地图没有重绘,仍然可以减慢它的速度。

因此,您向您的图块添加一个标志,说明某些内容是否发生了变化,这将导致自上次绘制所有内容以来它具有不同的外观,并且仅放置已更改的图块的图像。

这工作得很好,直到像绘制图形的窗口之类的东西经历了最小化/最大循环,现在每个图块都需要更新它的图形,但没有一个会被标记为这样,导致空白屏幕。

处理这个问题的最佳理由是什么?

我还错过了什么?

4

1 回答 1

1

问题repaint(int,int,int,int);是两个文件夹。

首先,不能保证实际上只有这个区域会被安排进行更新。可以将RepaintManager多个重绘请求合并为一个请求,组合要绘制的区域可能使要重绘的区域更大。

其次,所有repaint请求都被安排回事件调度线程,这意味着它paintXxx无论如何都会冒泡到您的方法中。

因此,除非您的paintXxx方法经过优化以处理更新,否则它对您没有任何帮助。

正如您还指出的那样,您实际上需要能够根据Graphics上下文的剪切矩形计算哪些标题要更新。

更好的方法可能是使用屏幕外缓冲区,该缓冲区在某些后台线程中更新,作为游戏引擎的一部分。然后,当它准备好时,这将切换到“活动”缓冲区以绘制到屏幕上。

此时您可以利用剪辑,如果您发现将整个屏幕更新为无效,则仅渲染活动缓冲区的一小部分

...恕我直言...

在 AWT 和 Swing中的绘画中实际上对此进行了一些讨论

于 2013-08-23T06:26:35.163 回答