我在线发现了一些Java游戏代码,我正在尝试修改它。我将它从JFrame转换为Applet,但每次重新绘制屏幕时我的游戏都会开始闪烁。我试过双缓冲,但没有区别。
来源:
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());
}
}
}
}
答案 0 :(得分:3)
简答:请勿在{{1}}方法中致电super.paint()
。
长答案: Applet也是一个具有自己的显示属性的容器,包括您通过Board.paint()
设置的背景颜色作为构造函数的一部分。通过调用setBackground(Color.WHITE);
,您可以使applet将其白色背景绘制到显示图形,以及调用任何包含的组件绘制。这是闪烁的原因 - 每个绘画周期,它将屏幕显示画为白色,然后将super.paint(g)
图像复制到屏幕显示。
可能最好是明确的,忘记Applet背景,删除offscreenBuffer
,然后自己完成所有绘制步骤。您需要将super.paint(g)
替换为clearRect()
和setColor()
。
此外,您还应该实施fillRect()
。
update()
答案 1 :(得分:1)
从Bonsai查看游戏引擎Ivo Wetzel。我很喜欢它。
它使用BufferStrategy
,我认为这是双缓冲的最佳方法。