这个问题不是“整个屏幕闪烁”类型的问题。
我正在尝试理解Java图形并制作一个简单的游戏,但是当用新对象重新绘制场景时,一些对象会一直闪烁, odly 而不是整个屏幕
这是我的render()
方法:
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
createBufferStrategy(6);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2d = (Graphics2D)g;
//fill screen with black background
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
//draw cool stuff
try {
for (int i = 0; i < Element.elements.size(); i++) {
Element.elements.get(i).render(g2d);
}
} catch (Exception e) {
System.err.println("No such element to render");
}
//dispose graphics
g.dispose();
g2d.dispose();
bs.show();
}
什么可能导致这个问题?我不认为大量的气泡会导致这个问题。
答案 0 :(得分:2)
您的模型更新(在鼠标移动时在事件线程中完成)需要与渲染线程同步。闪烁发生是因为渲染发生时模型有时处于不一致状态。
解决此问题的一种方法是在线程中渲染您正在更新模型。您可以在事件线程中使用SwingUtilities
运行渲染:
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
render();
}
});
} catch (InvocationTargetException | InterruptedException e) {
running = false;
System.err.println("Render interrupted");
}
如果您正在使用由AWT或Swing呈现的组件,那么总是在事件线程中进行渲染。
当您自己控制整个渲染过程时,您可以选择在单独的线程中进行渲染,但是您必须同步对模型的访问(即,应该同步对事件线程执行的模型的写入使用渲染线程执行的读取。
例如:
在Shredder.scan()
中(从事件线程调用)
public static void scan() {
synchronized (Element.elements) {
for (Element element : Element.elements) {
if (element.containsMouse()) {
if (element.getSize() < 24) {
Element.elements.remove(element);
} else {
element.cloneItself();
Element.elements.remove(element);
}
skip = true;
break;
}
}
}
}
在你的渲染线程中:
synchronized (Element.elements) {
for (int i = 0; i < Element.elements.size(); i++) {
Element.elements.get(i).render(g2d);
}
}
作为一种形式,将需要同步的代码放在一个位置是个好主意,这样调用代码就不必关心保持一致性。