好吧,我明白你对SSCCE的需求,所以我创造了(我的第一个)。
我设法用200行代码复制了这个问题。 在我的系统上,这个演示编译和运行完美(当然,只有闪烁仍然存在)。 我剥夺了一切与它无关的东西。 所以基本上我们现在有两个源文件:屏幕pipe理器和游戏pipe理器。
屏幕pipe理器: http : //pastebin.com/WeKpxEXW
游戏经理: http : //pastebin.com/p3C5m8UN
如何使用augtool没有镜头?
如果Steam可以映射XBox 360控制器上的指南button,为什么我不能
读控制台缓冲区/输出C ++
漂亮的shell脚本(菜单,图像,抗锯齿,1080p,颜色,淡入淡出效果等)?
你可以使用这个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目录中的/classes 。
编译为字节码后,可以使用以下.bat文件启动游戏:
@set STARUP_CLASS=nl.jorikoolstra.jLevel.Game.GameMain @set ARGUMENTS=1280 1024 32 @java -cp classes;resources %sTARUP_CLASS% %ARGUMENTS%
请注意, ARGUMENtvariables取决于您自己的屏幕设置,您必须更改它,以便游戏以正确的屏幕分辨率显示。
我明白为什么它闪烁
BufferStrategy正在从组件的paint()方法中做一个单独的绘画工作,它们似乎使用不同的Graphics对象,并且以不同的速率刷新 –
当paint()在show()之前被调用的时候,没关系。 但
在show()之后调用paint()时,它将重新绘制组件的初始空白外观 – 所以闪烁发生。
消除闪烁是很容易的:覆盖你的JFrame ( GameMain )的paint()方法,因为你不需要做任何事情( BufferStrategy可以给你更精确的控制绘画的东西):
@Override public void paint (Graphics g) {}
就这样。 (我测试了它,它工作正常,希望这可以帮助:))
=====更新=====
而不是重写paint()方法,更好的方法是为你的JFrame ( GameMain )调用setIgnoreRepaint(true) ) – 这个方法只是为了这个目的而设计的! 使用它 !
private GameMain(String ... args) { setIgnoreRepaint(true); ..... }
这是我如何实现双缓冲,可能会帮助你得到的概念。 注意它在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,this); Graph2D.drawImage(BuffImg,this); } }
希望这有帮助,祝你好运。
我有一个基于Java AWT的跨平台的动画程序。 直到我严格按照Java BufferStrategy文档中的示例代码进行操作之后,才出现闪烁的问题。 不过,我正在使用嵌入在Swing层次结构中的AWT Canvas,而不是像你一样的全屏。 如果感兴趣,你可以在这里看到代码 。
另外需要注意的是,AWT管道使用OpenGL原语来获得良好的性能,OpenGL支持在很多视频驱动程序中都是有问题的。 尝试为您的平台安装最新版本的驱动程序。
当你在你自己的方法中设置hwnd.createBufferStrategy(2)时,它可能适用于你。
Java渲染透明背景gif图像时出现问题。 这可能是问题。
没有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 ... }
如果这样做没有帮助,请提供一个您的代码的工作示例,以便人们可以重现该问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。