Java 为什么每次重新绘制时我的小程序都会闪烁?
我在网上找到了一些Java游戏代码,我正在尝试修改它。我把它从JFrame转换成了Applet,但每次我重新绘制屏幕时,我的游戏都开始闪烁。我尝试了双重缓冲,但没有区别 资料来源:Java 为什么每次重新绘制时我的小程序都会闪烁?,java,applet,awt,Java,Applet,Awt,我在网上找到了一些Java游戏代码,我正在尝试修改它。我把它从JFrame转换成了Applet,但每次我重新绘制屏幕时,我的游戏都开始闪烁。我尝试了双重缓冲,但没有区别 资料来源: private void paintDisks(Graphics g) { try { for (Disk d : disk) paintDisk(g, d); } catch (Exception ex) {
private void paintDisks(Graphics g) {
try {
for (Disk d : disk)
paintDisk(g, d);
} catch (Exception ex) {
//System.out.println(ex.getMessage());
paintDisks(g); // retry so the disks never not get painted
}
}
private void paintDisk(Graphics g, Disk d) {
if (d == null)
return;
if (diskimg[d.player] == null) {
g.setColor(colour[d.player]);
g.fillOval((int)d.x - 1, (int)d.y - 1, 32, 32);
} else {
g.drawImage(diskimg[d.player],
(int)d.x - 1, (int)d.y - 1,
32, 32, this);
}
}
@Override
public void paint(Graphics g) {
// paint real panel stuff
super.paint(g);
Graphics gr;
if (offScreenBuffer==null ||
(! (offScreenBuffer.getWidth(this) == this.size().width
&& offScreenBuffer.getHeight(this) == this.size().height)))
{
offScreenBuffer = this.createImage(size().width, size().height);
}
gr = offScreenBuffer.getGraphics();
gr.clearRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this));
// paint the disks
paintDisks(gr);
// paint the curser ontop of the disks
paintCurser(gr);
g.drawImage(offScreenBuffer, 0, 0, this);
}
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(9, 1);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
}
}
简短回答:不要在
Board.paint()方法中调用super.paint()
详细回答:Applet也是一个容器,它有自己的显示属性,包括通过setBackground(color.WHITE)设置的背景色代码>作为构造函数的一部分。通过调用super.paint(g)
可以使小程序在显示图形上绘制其白色背景,以及调用任何包含的组件绘制。这就是闪烁的原因-每个绘制周期,它都会将屏幕上的显示涂成白色,然后将offscreenBuffer
图像复制到屏幕上的显示
也许最好是显式的,忘记Applet背景,删除super.paint(g)
,然后自己完成所有的绘制步骤。您需要将clearRect()
替换为setColor()
和fillRect()
您还应该实现update()
@Override
public void update(Graphics g) { paint(g); }
@Override
public void paint(Graphics g) {
// no super.paint(g)
if (offScreenBuffer==null ||
(! (offScreenBuffer.getWidth(this) == this.size().width
&& offScreenBuffer.getHeight(this) == this.size().height)))
{
offScreenBuffer = this.createImage(size().width, size().height);
}
Graphics gr = offScreenBuffer.getGraphics();
// blank the canvas
gr.setColor(Color.WHITE);
gr.fillRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this));
// paint the disks
paintDisks(gr);
// paint the curser ontop of the disks
paintCurser(gr);
g.drawImage(offScreenBuffer, 0, 0, this);
}
简短回答:不要在Board.paint()方法中调用super.paint()
详细回答:Applet也是一个容器,它有自己的显示属性,包括通过setBackground(color.WHITE)设置的背景色代码>作为构造函数的一部分。通过调用super.paint(g)
可以使小程序在显示图形上绘制其白色背景,以及调用任何包含的组件绘制。这就是闪烁的原因-每个绘制周期,它都会将屏幕上的显示涂成白色,然后将offscreenBuffer
图像复制到屏幕上的显示
也许最好是显式的,忘记Applet背景,删除super.paint(g)
,然后自己完成所有的绘制步骤。您需要将clearRect()
替换为setColor()
和fillRect()
您还应该实现update()
@Override
public void update(Graphics g) { paint(g); }
@Override
public void paint(Graphics g) {
// no super.paint(g)
if (offScreenBuffer==null ||
(! (offScreenBuffer.getWidth(this) == this.size().width
&& offScreenBuffer.getHeight(this) == this.size().height)))
{
offScreenBuffer = this.createImage(size().width, size().height);
}
Graphics gr = offScreenBuffer.getGraphics();
// blank the canvas
gr.setColor(Color.WHITE);
gr.fillRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this));
// paint the disks
paintDisks(gr);
// paint the curser ontop of the disks
paintCurser(gr);
g.drawImage(offScreenBuffer, 0, 0, this);
}
从中查看游戏引擎。我非常喜欢它
它使用了BufferStrategy
,我认为这是将缓冲区加倍的最佳方式。从中查看游戏引擎。我非常喜欢它
它使用了BufferStrategy
,我认为这是将缓冲区加倍的最佳方式。如果您首先将其简化为一个简单的自包含示例来说明问题,那么对您和我们来说,调试可能会更容易,如果您首先将其分解为一个更简单的自包含示例来说明问题。