我正在用Java开发类似于Worms的游戏(具有可破坏的地形和所有内容)。
一切都很好,直到我尝试使用位掩码更新地形图像。
让我详细解释该过程:
每当发生弹丸碰撞时,我都会在我的身上画一个黑圈
地形遮罩(黑色代表透明,白色代表不透明像素)。
public void drawExplosion(Vector2 position,BufferedImage explosionImage){
Graphics2D gMask = (Graphics2D) terrainMask.getGraphics();
gMask.drawImage(explosionImage,(int) position.x, (int) position.y, null);
gMask.dispose();
}
将黑色圆圈绘制到我的地形中后,遮罩
BufferedImage
的类型为BufferedImage.TYPE_BYTE_INDEXED
,我通过设置来更新可见的地形BufferedImage
如果terrainMask的像素在相同位置为黑色,则每个像素均设为0。
public void mapUpdate(){
for(int x = 0 ; x < terrainMask.getWidth(); x++){
for(int y = 0 ; y < terrainMask.getHeight(); y++){
if(terrainMask.getRGB(x, y) == -16777216){
terrain.setRGB(x, y, 0);
}
}
}
}
完成这些步骤后,地形
BufferedImage
将更新,并且每个外观都很好,显示了地形中的爆炸孔。
这是我的问题:
每当我呼叫
mapUpdate()
时,游戏就会停止300-500毫秒,检查2400 * 600像素,如果检查结果为true,则在地形中设置透明像素。如果没有
setRGB()
,则不会发生延迟。所以我的问题是我如何将位掩码应用于BufferedImage
更有效。重要提示:所有
BufferedImages
都将使用GraphicsConfiguration.createCompatibleImage()
方法。当我在
getData()
上调用BufferedImage
以获取像素阵列时,fps下降至约23 fps,导致游戏无法玩,因此这里不是一个选择。
我也设置了
System.setProperty("sun.java2d.opengl","True");
启用OpenGL Pipeline。另一个奇怪的事情是,每当我没有设置openGL属性时,我的游戏就会达到700 fps(启用openGL时为140-250 fps)并且笔记本电脑完全死机。我的游戏循环与此处描述的相同:http://www.koonsolo.com/news/dewitters-gameloop/(恒定游戏速度独立于Variable FPS,最后一个)。
最佳答案
据我所知,在Java(即没有OpenGL)中执行此操作的最快方法是:
a)将蒙版(terrainMask
)图像的颜色更改为白色和透明(而不是白色和黑色)。我猜只是更改颜色表(IndexColorModel
)就可以。
b)使用正确的alpha合成规则,通过在地形上绘制蒙版来替换双getRGB/setRGB
循环。由于查找,颜色转换和可能的数据类型转换(均取决于您的图像),setRGB
和getRGB
都可能是较慢的操作,因此在性能关键的代码中通常应避免使用它们。更新后的代码可能类似于以下内容:
public void mapUpdate() {
Graphics2D g = terrain.createGraphics();
try {
g.setComposite(AlphaComposite.DstIn); // Porter-Duff "destination-in" rule
g.drawImage(terrainMask); // Clear out transparent parts from terrainMask
}
finally {
g.dispose();
}
}
以这种方式进行操作还应使您的图片保持托管状态(即不降低fps)。
有关
AlphaComposite
的更多信息,请参见Java2D Advanced Topics教程中的Compositing Graphics。PS:您可以做的另一种优化方法是仅更新爆炸所覆盖的
terrain
部分(即position.x, position.y, explosionImage.getWidth(), explosionImage.getHeight()
覆盖的矩形)。无需更新您不知道的像素...关于java - 将位掩码应用于BufferedImage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24394515/