10

好的,我了解您对 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变量取决于您自己的屏幕设置,并且您必须更改它以便游戏以适合您屏幕的分辨率显示。

4

6 回答 6

7

我明白它为什么闪烁了----

BufferStrategy正在从组件的paint()方法中进行单独的绘画工作,它们似乎使用不同的Graphics对象,并且它们以不同的速度刷新——

paint()之前调用时show(),没关系。但

paint()在 之后调用时show(),它会将组件重新绘制为其初始的空白外观——因此会发生闪烁。


消除闪烁非常容易:( ) 的覆盖paint()方法,因为您不需要它做任何事情(可以让您更精确地控制绘画的东西):JFrameGameMainBufferStrategy

@Override
public void paint (Graphics g) {}

就这样。(我已经测试过了,它工作正常,希望这可能会有所帮助:))


===== 更新 =====

而不是覆盖paint()方法,更好的方法是调用setIgnoreRepaint(true)你的JFrame( GameMain)——这个方法就是为这样的目的而设计的!使用它

private GameMain(String ... args)
{
    setIgnoreRepaint(true);
    .....
}
于 2013-02-03T14:15:06.237 回答
1

当您设置 hwnd.createBufferStrategy(2)自己的方法时,它可能对您有用。

于 2013-02-01T10:07:15.077 回答
1

这就是我实现双缓冲的方式,可能会帮助您了解这个概念。请注意,它是在 JPanel 中实现的,但我认为它可以在其他容器中实现:

JApplet.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);
    }
}

JPanel.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);
    }
}

希望这有帮助,祝你好运。

于 2013-02-02T18:37:14.207 回答
1

我有一个基于 Java AWT 的跨平台动画程序。在我严格遵循JavaBufferStrategy文档中的示例代码之前,它一直存在闪烁问题。但是,我使用的是嵌入在 Swing 层次结构中的 AWT Canvas,而不是像您一样全屏显示。感兴趣的可以看这里的代码

另一件需要注意的事情是,AWT 管道使用 OpenGL 原语以获得良好的性能,而 OpenGL 支持在许多视频驱动程序中存在缺陷。尝试为您的平台安装最新版本的驱动程序。

于 2013-02-02T19:27:06.060 回答
1

Java 呈现透明背景GIF图像时出现问题。这可能是问题所在。

于 2013-02-03T02:15:45.913 回答
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
  ...
}

如果这没有帮助,请提供您的代码的工作示例,以便人们可以重现该问题。

于 2013-02-02T19:13:04.187 回答