我正在尝试用Java制作动画,但是难以理解DoubleBufferImage和DoubleBufferGraphics。我了解update(),render()和paint()序列。但是,在每种方法中,我无法理解它是如何绘制的。这是代码。
gameUpdate() ///因为我首先需要了解背景,所以我将跳过更新部分。
gameRender()
private void gameRender() {
if (DoubleBufferImage == null) {
System.out.println("The Image is null: Error occurence");
DoubleBufferImage = createImage(P_WIDTH - 15, P_HEIGHT - 15);
}
DoubleBufferGraphic = DoubleBufferImage.getGraphics();
DoubleBufferGraphic.setColor(Color.LIGHT_GRAY);
DoubleBufferGraphic.fillRect(0, 0, P_WIDTH, P_HEIGHT);
DoubleBufferGraphic.setColor(Color.BLUE);
DoubleBufferGraphic.setFont(font);
DoubleBufferGraphic.drawString("Average FPS/UPS: " +
df.format(averageFPS) + df.format(averageUPS), 10, 10);
}
paint()
public void paintScreen() {
Graphics g;
try {
g = this.getGraphics();
if ((g != null) && (DoubleBufferImage != null)) {
g.drawImage(DoubleBufferImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync();
} catch (Exception e) {
System.out.println("Graphics context error: " + e);
}
}
还有从Jpanel覆盖的paintComponent方法。
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (DoubleBufferImage != null) {
g.drawImage(DoubleBufferImage, 0, 0, null);
}
}
这是我的问题。运行就像更新->渲染->和绘画 但是,从渲染中可以看到,他们使用图形进行绘制。但这都是在DoubleBufferImage中绘制的吗?图像实例是否类似于面板实例?我的意思是,它是否可以添加到框架中? 因为这是Double Buffering系统,所以我想知道哪些方法是直接绘制的,哪个是事先绘制的方法。 最终,在运行中,没有代码要添加到面板中,这是我们制作的图像或图形。我只想知道BufferedImage被绘制的时间。 请帮忙!我无法上传整个代码,所以我不确定你们是否能理解:(
答案 0 :(得分:1)
好的,所以您似乎正在对一些错误信息和误解进行打击。也许您应该先看看类似paintComponent() vs paint() and JPanel vs Canvas in a paintbrush-type GUI
的东西在AWT / Swing中,至少有两种执行自定义绘画的方法,每种方法各有利弊。
您可以使用paintComponent
,它是Swing使用的绘画系统的“钩子”。 Swing利用“被动”渲染系统。这意味着您无法控制何时绘制某些内容,绘制系统做出这些决定,然后(间接)调用组件的paintComponent
,以便您可以执行更新。
另一种机制(BufferStrategy
)使用“活动”渲染系统,该系统可以完全控制何时进行绘画。
通常,您不能混合使用它们。 Swing拥有自己的绘画系统,因此无法与BufferStrategy
配合使用,因此,这意味着如果您希望将Swing组件用作输出的一部分,则不能。
但这不会回答您的问题,或者不能直接回答
让我们尝试将其分解
gameRender
private void gameRender() {
if (DoubleBufferImage == null) {
System.out.println("The Image is null: Error occurence");
DoubleBufferImage = createImage(P_WIDTH - 15, P_HEIGHT - 15);
}
DoubleBufferGraphic = DoubleBufferImage.getGraphics();
DoubleBufferGraphic.setColor(Color.LIGHT_GRAY);
DoubleBufferGraphic.fillRect(0, 0, P_WIDTH, P_HEIGHT);
DoubleBufferGraphic.setColor(Color.BLUE);
DoubleBufferGraphic.setFont(font);
DoubleBufferGraphic.drawString("Average FPS/UPS: " +
df.format(averageFPS) + df.format(averageUPS), 10, 10);
}
此时,DoubleBufferImage
似乎是BufferedImage
,因此在调用gameRender
时,它将检查是否存在缓冲区并根据需要创建它。然后,它引用DoubleBufferImage
的{{1}}上下文,并准备对其进行渲染,从而清除以前为其绘制的内容。
Graphics
Graphics
是位于基础渲染管道上方的抽象层,取决于系统,通常使用OpenGL或DirectX来实现。它提供了一个公共层,可以以与系统无关的方式在其上执行图形操作
Graphics
paintScreen
这让我感到担忧,因为我没有上下文,但是public void paintScreen() {
Graphics g;
try {
g = this.getGraphics();
if ((g != null) && (DoubleBufferImage != null)) {
g.drawImage(DoubleBufferImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync();
} catch (Exception e) {
System.out.println("Graphics context error: " + e);
}
}
似乎正在引用组件的this.getGraphics()
上下文,并向其绘制Graphics
。
这是危险且不明智的。 DoubleBufferImage
返回组件上次绘制时的快照,可以在再次绘制组件时随时对其进行绘制。
您应该尽早摆脱这种方法。
getGraphics
paintComponent
如上所述,public void paintComponent(Graphics g) {
super.paintComponent(g);
if (DoubleBufferImage != null) {
g.drawImage(DoubleBufferImage, 0, 0, null);
}
}
是挂接到Swing的绘画系统中的首选方法。尽管它实际上应该显示为paintComponent
DoubleBufferImage
。
基本上,这是在Swing中执行双重缓冲的不当尝试,默认情况下已经双重缓冲。
但是,从渲染中可以看到,他们使用图形进行绘制。但这都是在DoubleBufferImage中绘制的吗?图像实例是否类似于面板实例?
不。组件是一个对象,它具有许多属性。它的工作之一就是绘制状态,这是通过各种绘制方法完成的,传递给g.drawImage(DoubleBufferImage, 0, 0, this);
上下文,该上下文附加到本机对等项,并最终呈现到屏幕(或打印机)。 / p>
Graphics
就是图像。 BufferedImage
上下文只是一种简单的绘制方法。然后可以将其保存到文件中,或者像在此处一样,(通过Graphics
绘制到组件上下文中。)
如上所述,Graphics
只是一个抽象层,它使您可以对许多不同的目标,屏幕,打印机,图像等进行绘画操作。
我的意思是,它是否可以添加到框架中?
不。它不是基于组件的类
因为这是Double Buffering系统,所以我想知道哪种方法是直接绘制的,哪种方法是事先绘制的。
Graphics
和(不建议使用的)paintComponent
将图像直接绘制到组件上,该组件最终将通过绘制子系统呈现到屏幕上。