在Java中加载图像后FPS下降 [英] FPS drops after loading images in java

查看:77
本文介绍了在Java中加载图像后FPS下降的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我最近问了一个有关如何在Java中预加载图像的问题(在Java中预加载图像),效果很好!直到我去玩游戏.帧速率急剧下降.我不知道那是什么,但是基本上,我已经将整个精灵图加载到了一个数组中.每个图像对应一个三度旋转.因此,将5度变成3度图像,将6保留为6,依此类推(我尝试过Math.round,它实际上使5度和4度图像变成了6度图像,这是更可取的,但是速度较慢)
我正在寻找一些优化代码的方法.这是我的角度计算:

So, I recently asked a question on how to preload images in Java (preloading images in Java) and it worked great! Until I went to play the game. Framerate dropped drastically. I don't know what it was, but basically, I have a whole sprite map loaded into an array. Each image corresponds to a three-degree rotation. So, 5 degrees would become the 3-degree image, 6 would stay the 6, and so on (I tried Math.round and it actually made the 5 and 4-degree images go to the 6-degree image, and that's more desirable, however, it's slower)
I am looking for some ways to optimize the code. Here are my angle calculations:

private float getAngle(double x, double y) {
    float angle = (float) Math.toDegrees(Math.atan2(y - this.getCenterY(), x - this.getCenterX()));
    if(angle < 0){
        angle += 360;
    }
    return angle;
}

输入到方法中的x和y值是执行此计算的塔所针对的敌人的中心x和y值.然后在draw方法中执行以下代码:

The x and y values inputted into the method are the center x and y values of the enemy being targeted by the tower performing this calculation. Then this code is executed in the draw method:

if(airID==Value.towerCannon && (airRow>0 && airRow<5) && angle>=0) {
    if(angle==Canvas.rotatedAirMap.length) angle = 0;
        g.drawImage(Canvas.rotatedAirMap[angle][level-1], x, y, width, height, null); 
    } else {
        g.drawImage(Canvas.airMap[airRow][airID], x, y, width, height, null); 
    }
}

这将绘制适当的,以指定角度旋转的预加载图像(当塔射击时,将角度计算结果除以三,然后将其转换为整数,就可以计算出角度"-或图像标识符-我也可以舍入该值)
关于如何优化此设置的任何建议,这样我就不会出现这么大的丢帧现象?我认为丢帧是由于VM堆大小过小而引起的,但是我已经增加了它,但仍然没有发生任何重大变化.任何帮助将不胜感激.
谢谢!

@VGR这是我对您的回复所做的:

This will draw the appropriate, preloaded image rotated at the specified angle (The "angle" - or image identifier - is calculated when the tower shoots by dividing the result of the angle calculation by three and then casting that to an int - I could also round that value)
Any suggestions on how to optimize this so I don't get such massive frame drops? I assume the frame drops are due to the VM heap size being too small, but I've increased it and still, nothing significant happens. Any help would be greatly appreciated.
Thanks!

@VGR here is what I did with your response:

public void paintComponent(Graphics g) {
    if(isFirst) { //Define stuff when isFirst is true
        define(); //Sets up the image arrays

        GraphicsConfiguration config = getGraphicsConfiguration();
        if(config == null) {
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            config = env.getDefaultScreenDevice().getDefaultConfiguration();
        }

        BufferedImage compatibleImage = config.createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency());

        g = compatibleImage.createGraphics();

        isFirst = false;
    }
}

这稍微快一些了,但我不得不做一些变通方法.repaint()在游戏循环中调用(此类实现可运行),所以repaint方法创建的图形组件(无论如何起作用)是我在整个游戏中使用的图形.这是正确的方法吗?

This works a little bit faster, but I had to do some workarounds. repaint() is called in the game loop (this class implements runnable) So the graphics component created by the repaint method (however that works) is the graphics I use for the whole game. Would this be the correct way to do it?

推荐答案

将图像从其固有的颜色模型转换为当前视频模式的颜色模型会降低渲染速度.为避免这种情况,您可以确保每个图像与窗口所在的屏幕兼容:

Translating images from their inherent color model to the color model of the current video mode can slow down rendering. To avoid this, you can make sure each image is compatible with the screen where your window resides:

BufferedImage image = ImageIO.read(/* ... */);

GraphicsConfiguration config = getGraphicsConfiguration();
if (config == null) {
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment;
    config = env.getDefaultScreenDevice().getDefaultConfiguration();
}

BufferedImage compatibleImage = config.createCompatibleImage(
    image.getWidth(), image.getHeight(), image.getTransparency());

Graphics2D g = compatibleImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();

image = compatibleImage;

如果图像的颜色模型与当前视频模式相同,则绘制时无需翻译.甚至有可能完全由GPU完成此类图像的绘制.

If an image has the same color model as the current video mode, there is no translation needed when drawing it. It’s even possible that painting of such an image may be done entirely by the GPU.

这篇关于在Java中加载图像后FPS下降的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆