好的,我理解你需要一个SSCCE,所以我创建了(我的第一个)。
我设法用200行代码复制问题。在我的系统上,这个演示编译并完美运行(当然只有闪烁仍在那里)。 我剥夺了与它无关的所有东西。所以基本上我们现在有两个源文件:屏幕管理器和游戏管理器。
屏幕管理员: http://pastebin.com/WeKpxEXW
游戏经理: http://pastebin.com/p3C5m8UN
您可以使用此make文件编译此代码(我使用移植版本的Linux'make for Windows): CC = javac BASE = nl / jorikoolstra / jLevel CLASS_FILES = classes / $(BASE)/Game/GameMain.class classes / $(BASE)/ Graphics / ScreenManager.class
jLevel: $(CLASS_FILES)
@echo Done.
classes/%.class : src/%.java
@echo Compiling src/$*.java to $@ [command: $(CC) src/$*.java ] ...
@$(CC) -Xlint:unchecked -d classes -classpath src src/$*.java
源文件放在/src
目录和/classes
目录中的类中。
编译成字节码后,可以使用以下.bat文件启动游戏:
@set STARUP_CLASS=nl.jorikoolstra.jLevel.Game.GameMain
@set ARGUMENTS=1280 1024 32
@java -cp classes;resources %STARUP_CLASS% %ARGUMENTS%
请注意,ARGUMENT
变量取决于您自己的屏幕设置,并且您必须更改它,以便以适合您屏幕的分辨率显示游戏。
答案 0 :(得分:5)
我明白为什么它会闪烁----
BufferStrategy
正在使用Component的paint()
方法执行单独的绘制作业,它们似乎使用不同的Graphics
对象,并且它们以不同的速率刷新 -
在paint()
之前调用show()
时,没关系。但
在paint()
之后调用show()
时,它会将组件重新绘制为其初始空白外观 - 因此闪烁发生。
消除闪烁非常容易:覆盖paint()
(JFrame
)的GameMain
方法,因为您不需要它做任何事情(BufferStrategy
可以给出你可以更精确地控制绘画内容):
@Override
public void paint (Graphics g) {}
这就是全部。 (我已经测试过,它运行正常,希望这可能会有所帮助:))
而不是覆盖paint()
方法,更好的方法是为setIgnoreRepaint(true)
(JFrame
)调用GameMain
- 此方法仅用于此类目的! 使用IT !
private GameMain(String ... args)
{
setIgnoreRepaint(true);
.....
}
答案 1 :(得分:1)
当您使用自己的方法设置hwnd.createBufferStrategy(2)
时,它可能适合您。
答案 2 :(得分:1)
这是我实现双缓冲的方式,可能会帮助你获得这个概念。 请注意,它是在JPanel中实现的,但我认为它可以在其他容器中实现:
TheJApplet.java:
import java.awt.*;
import javax.swing.*;
public class TheJApplet extends JApplet
{
private Image myImage;
java.net.URL GameURL = CheckerGameJApplet.class.getResource("GameIMG");
String GamePath = GameURL.getPath();
@Override
public void init()
{
String GraphPath = GamePath+"/";
File myImage_File = new File(GraphPath+"myImage.jpg");
try
{
myImage = ImageIO.read(myImage_File);
}
catch (IOException ex)
{
// Add how you like to catch the IOExeption
}
final TheJPanel myJPanel = new TheJPanel(myImage);
add(myJPanel);
}
}
TheJPanel.java:
import java.awt.*;
import javax.swing.*;
public class TheJPanel extends JPanel
{
private int screenWidth = 500;
private int screenHeight = 500;
private BufferedImage BuffImg = new BufferedImage
(screenWidth,
screenHeight,
BufferedImage.TYPE_INT_RGB);
private Graphics2D Graph = BuffImg.createGraphics();
private Image myImage;
public TheJPanel(Image myImage)
{
this.myImage = myImage;
repaint();
}
@Override
public void paintComponent(Graphics G)
{
Graphics2D Graph2D = (Graphics2D)G;
super.paintComponent(Graph2D);
if(BuffImg == null)
{
System.err.println("BuffImg is null");
}
Graph.drawImage(myImage, 0, 0, this);
Graph2D.drawImage(BuffImg, 0, 0, this);
}
}
希望这会有所帮助,祝你好运。
答案 3 :(得分:1)
我有一个基于Java AWT的跨平台程序,带有动画。在我严格遵循in the Java BufferStrategy
documentation的示例代码之前,它有闪烁的问题。但是我使用的是嵌入在Swing层次结构中的AWT Canvas,而不是全屏幕。如果感兴趣,你可以see the code here。
另外需要注意的是,AWT管道使用OpenGL原语以获得良好的性能,并且OpenGL支持在许多视频驱动程序中都存在错误。尝试为您的平台安装最新版本的驱动程序。
答案 4 :(得分:1)
Java渲染透明背景GIF图像时出现问题。这可能是问题所在。
答案 5 :(得分:0)
我发现没有SCCSE就很难回答你的问题。我也想知道RepaintManagerResetter的作用。
您可能希望将背景颜色设置为某些奇特的颜色(如0xFF00FF),以确定是否有人在绘图发生之前“清除”背景。如果闪烁图像是紫色的,那就是 - 如果它包含垃圾或旧图像,它可能是双缓冲。
无论如何,我会尽力确保没有人期望自己。首先,尝试阻止本机Windows代码绘制窗口背景。设置一次:
/*
* Set a Windows specific AWT property that prevents heavyweight components
* from erasing their background.
*/
System.setProperty("sun.awt.noerasebackground", "true");
另外,请确保在JFrame中覆盖它(如果您使用的是Swing组件)
@Override
public void paintComponent(Graphics G)
{
// do not call super.pC() here
...
}
如果这没有帮助,请提供代码的工作示例,以便人们可以重现问题。