Java applet在第一次画出BufferedImage(Java2D)时口吃

时间:2012-03-20 19:36:56

标签: java applet bufferedimage java-2d

我正在使用Java2D库和BufferedImage类将游戏编写为java applet。第一次绘制图像时,游戏会停顿(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 Viewer中不会出现问题。

我最好的猜测是,浏览器会以某种方式缓存图像,但实际上我很难过。我还没有尝试使用不同的图形库(Slick2D,LWJGL等)加载/绘制图像。谢谢你的任何建议!

1 个答案:

答案 0 :(得分:0)

大约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; 
}