【问题标题】:Java applet stutters on first time drawing a BufferedImage (Java2D)Java 小程序在第一次绘制 BufferedImage (Java2D) 时出现口吃
【发布时间】:2012-03-20 19:36:55
【问题描述】:

我正在使用 Java2D 库和 BufferedImage 类将游戏编写为 Java 小程序。第一次绘制图像时游戏会卡顿(2-3 秒)。 BufferImage文件都是在游戏开始前加载的,使用这个方法:

bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);       
    try {
           URL url = new URL(a.getCodeBase(), "images//smoke5frames.png");
           bufferedImage = ImageIO.read(url);           
    } catch (IOException e) { e.printStackTrace(); }        
    mSmoke = bufferedImage;

要绘制图像,我使用的是这种方法:

public void draw(Graphics2D g) {    
g.drawImage(mTextures[iCurrentFrame], mAffineTransform, null); }

有问题的图像是 SheetedSprites,通常使用以下方法从精灵表中剪切:

for each frame in animation...

myBufferedImage.getSubimage(i * iFrameWidth, 0, iFrameWidth, iHeight);

这是在游戏过程中创建实体时完成的。删除这条线并没有解决问题,所以我假设(可能很糟糕) getSubimage() 的成本不足以导致问题。

我可以循环播放动画的每一帧并将它们全部绘制出来以便快速修复,但我想更多地了解这个问题以及它发生的原因。

关键是一旦SheetedSprite 被绘制了一次,您就可以刷新页面并且问题不会再次出现。一切都画好之后,游戏运行非常流畅。 IE 和 Chrome 都是这种情况(我没有在任何其他浏览器上尝试过)。附带说明一下,Eclipse 的 Applet 查看器中永远不会出现此问题。

我最好的猜测是浏览器以某种方式缓存了图像,尽管我真的很难过。我也没有尝试使用一组不同的图形库(Slick2D、LWJGL 等)加载/绘制图像。感谢您的任何建议!

【问题讨论】:

  • draw(G2D)从哪里调用&图形对象是如何获得的?实际上不,不考虑那个确切的问题,以SSCCE 的形式提供答案。
  • 这是一个展示用于绘制图像的方法的项目的 zip:dan.nemmons.net/stack/UnprofStackQuestion.zip 在 Applet 子类中,我创建了一个具有屏幕尺寸的 Image 对象。我通过 image.getGraphics() 获得了这个 Image 的 Graphics 成员。每次绘制调用,我都会清除图形,并将它们传递给将 Graphics 对象转换为 Graphics2D 的游戏。游戏从这里对所有精灵调用 sprite.draw(graphics2d)。最后,在 Applet 的 draw 方法结束时,我将 Image 绘制到屏幕上。
  • 您能否将代码写得足够短,使其成为可以作为编辑发布的 SSCCE?这就是我要研究的内容。

标签: java applet bufferedimage java-2d


【解决方案1】:

大约 2 年前我遇到了这个问题,我在很棒的 Java-gaming.org 上找到了解决方法。对我来说,问题是 Java 在某些类型的 png 文件上存在问题。有些在第一次使用时会导致延迟,有些则不会。这个“fixer-upper-method”接受一个 BufferedImage,并返回一个 BufferedImage,但在这两者之间,它做了一些魔术,使 Java 更容易解码图像(不要问我如何解码)。 享受吧!

private BufferedImage toCompatibleImage(BufferedImage image)
{
    if(image==null)System.out.println("Image is null");
    // obtain the current system graphical settings
    GraphicsConfiguration gfx_config = GraphicsEnvironment.
            getLocalGraphicsEnvironment().getDefaultScreenDevice().
            getDefaultConfiguration();

    /*
     * if image is already compatible and optimized for current system 
     * settings, simply return it
     */
    if (image.getColorModel().equals(gfx_config.getColorModel()))
            return image;

    // image is not optimized, so create a new image that is
    BufferedImage new_image = gfx_config.createCompatibleImage(
                    image.getWidth(), image.getHeight(), image.getTransparency());

    // get the graphics context of the new image to draw the old image on
    Graphics2D g2d = (Graphics2D) new_image.getGraphics();

    // actually draw the image and dispose of context no longer needed
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();

    // return the new optimized image
    return new_image; 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 2019-11-04
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    相关资源
    最近更新 更多