我在这里要做的是尽可能快地渲染游戏中的所有图形。游戏是基于瓦片的,需要大量的图像来渲染。我遇到的问题是,绘制所有图像需要很长时间。我不知道我是否应该用一种特殊的方式绘制瓷砖,但现在我正在逐一渲染视图端口内的所有瓷砖。
这是我的绘图方法:
public void draw(Graphics2D g){
boolean drawn=false; // if player is drawn
int px=vpPosX, py=vpPosY; // Viewport Position
for(int y=Math.round(py/64); y<Math.round(py/64)+core.blcHeight; y++){
for(int x=Math.round(px/64); x<Math.round(px/64)+core.blcWidth; x++){
if(y<height && x<width && y>-1 && x>-1 && worldData[currentLayer][x][y] != 0){ // if tile is inside map
BufferedImage img = tileset.tiles[worldData[currentLayer][x][y]]; //tile image
if(-py+player.PosY+64-15 < (y*64)-py-(img.getHeight())+64 && drawn==false){player.draw(g);drawn=true;} // if player should be drawn
if(worldBackground[currentLayer][x][y]!=0){ // if tile has background
BufferedImage imgBack = tileset.tiles[worldBackground[currentLayer][x][y]]; // background tile
g.drawImage(imgBack, (x*64)-px-(((imgBack.getWidth())-64)/2), (y*64)-py-(imgBack.getHeight())+64, null); //draw background
}
g.drawImage(img, (x*64)-px-(((img.getWidth())-64)/2), (y*64)-py-(img.getHeight())+64, null); // draw tile
}
}
}
if(!drawn){player.draw(g);} // if drawn equals false draw player
}
所有图像都加载在tileset类中
游戏fps/ups锁定在60。
此方法是从具有gameloop的核心类调用的。
我想知道的是我做错了什么
我需要更改绘图方法吗
我需要以特殊方式加载图像吗
我需要改变画画的方式吗?
我的目标是制作一款无延迟的2d互动游戏。
我自己注意到的是,我保存瓷砖图像的bufferedimage是RGBA格式的。但当我把它做成RGB时,渲染所花的时间要少得多。我知道额外的信息需要更多的时间来绘制。但我不知道它到底有多少。
我设法找到了一件能让表现更好的东西
如果我加载了所有的图像并将它们复制到以这种方式创建的图像:
BufferedImage bi = ImageIO.read(ims[i]);
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage b = gc.createCompatibleImage(bi.getWidth()*4, bi.getHeight()*4, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = b.createGraphics();
g.drawImage(bi, 0, 0, bi.getWidth()*4, bi.getHeight()*4, null);
tiles[id]=b;
g.dispose();
然后,绘制所有瓷砖所花的时间要少得多。但情况可能会更好。当我要制造光引擎时(例如地下)。然后我必须在瓷砖上使用透明的矩形。或者,如果有人能提出一种更好的方法,在不使用透明矩形的情况下使瓷砖更暗。但问题是,当试图绘制透明矩形时,也会出现滞后。我不知道我是否应该避免使用透明的图像和矩形或其他什么。
希望有人能给我指明正确的方向。
您可能会发现一些有用的技巧:
- 如果你有很多静态背景瓦片,那么不要每帧都重新绘制它们——只需将它们绘制一次到BufferedImage中,然后使用它一次性绘制整个背景。您只需要在其中一个瓷砖发生变化或滚动屏幕等情况下更新此背景图像
- 请确保仅绘制可见的分幅。看起来你可能正在这样做,但如果core.blcHeight和core.blcWidth太大,那么你可能绘制了太多瓷砖
- 不要担心锁定到60FP。对于一个基于瓦片的游戏来说,这可能没有必要。我建议将游戏逻辑与帧速率脱钩,并让游戏以其所能处理的任何速度渲染
- 对于实心背景瓷砖,不需要使用alpha着色进行绘制。在某些情况下,这可以显著加快绘图速度。即您可以使用
TYPE_INT_RGB
而不是TYPE_INT_ARGB
如果您真的想要高性能的绘图/动画,那么您可能需要考虑切换到基于OpenGL的渲染引擎,例如Slick2D或LWJGL。