简体   繁体   English

Java-如何有效绘制图形

[英]Java - How to effectively draw graphics

What i´m trying to do here is rendering all graphics in my game as fast as possible. 我在这里试图做的就是尽可能快地渲染游戏中的所有图形。 The game is tile-based and needs a lot of images to be rendered. 该游戏是基于图块的,需要渲染很多图像。 The problem i´m having is that it takes to long to draw all the images. 我遇到的问题是绘制所有图像需要很长时间。 I don´t know if i´m supposed to draw the tiles in a special way but right now i´m rendering all tiles that are inside of the view port one by one. 我不知道我是否应该以特殊的方式绘制拼贴,但现在我正在逐一渲染视口内部的所有拼贴。

Here is my drawing method: 这是我的绘制方法:

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

    }

All of the images are loaded in the tileset class. 所有图像都加载在tileet类中。
The games fps/ups is locked at 60. 游戏的fps / ups锁定为60。
This method is called from the core class which has the gameloop. 从具有游戏循环的核心类中调用此方法。

The thing i want to know is what am i doing wrong? 我想知道的是我做错了什么?
Do i need to change the draw method? 我需要更改抽奖方法吗?
Do i need to load the images in a special way? 我是否需要以特殊方式加载图像?
Do i need to change the way i´m painting? 我需要改变绘画方式吗?

My goal is to make a lag free 2d tile game. 我的目标是制作无滞后的2D图块游戏。

The things i noticed myself was that my bufferedimages that hold the tile images was in RGBA format. 我自己发现的事情是,保存切片图像的bufferedimages是RGBA格式。 But when i made it RGB it took a lot less time to render. 但是当我将其设为RGB时,渲染所需的时间要少得多。 I know the extra info is taking more time to draw. 我知道额外的信息需要花费更多的时间来绘制。 But what i didn't know was how much it really was. 但是我不知道到底是多少。

I managed to find one thing that made the performance better. 我设法找到一种使性能更好的东西。
If i loaded all my images and copied them over to a image created in this way: 如果我加载了所有图像并将它们复制到以此方式创建的图像中:

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();

Then the it took a lot less time to draw all the tiles. 这样一来,绘制所有瓷砖的时间就大大减少了。 But it could still be better. 但这可能会更好。 And when i´m going to make the light engine(for example underground). 当我要制造光引擎时(例如地下)。 Then i would have to use transparent rectangles over the tiles. 然后,我将不得不在瓷砖上使用透明矩形。 Or if someone could suggest a better way of making tiles darker without using transparent rectangles. 或者,如果有人可以提出一种无需使用透明矩形而使瓷砖变暗的更好方法。 But the thing is that the lag comes when trying to draw transparent rectangles too. 但问题是,当尝试绘制透明矩形时也会出现延迟。 I don´t know if i´m supposed to avoid using transparent images and rectangles or what. 我不知道我是否应该避免使用透明图像和矩形或其他东西。

Hope someone can point me in the right direction. 希望有人能指出正确的方向。

Some tricks you might find helpful: 一些技巧可能会有所帮助:

  • If you have lot of static background tiles , then don't redraw them all every frame - just draw them once into a BufferedImage and use this to draw the entire background in one go. 如果您有很多静态背景图块 ,则不要在每一帧都重绘它们 -只需将它们绘制一次到BufferedImage中,并使用它一次绘制整个背景。 You only need to update this background image if one of the tiles changes or if you scroll the screen etc. 仅当其中一个图块发生更改或滚动屏幕等时才需要更新此背景图像。
  • Make sure you are only drawing tiles that are visible . 确保仅绘制可见的图块 It looks like you might be doing this, but if core.blcHeight and core.blcWidth are too large then you could be drawing too many tiles. 看起来您可能正在执行此操作,但是如果core.blcHeight和core.blcWidth太大,则可能会绘制过多的图块。
  • Don't worry about locking to 60FPs . 不必担心锁定到60FP For a tile based game, this probably isn't going to be necessary. 对于基于图块的游戏,这可能不是必需的。 I'd suggest decoupling your game logic from the frame rate, and letting the game render at whatever speed it can handle. 我建议您将游戏逻辑与帧速率解耦,并让游戏以其可以处理的任何速度渲染。
  • For solid background tiles, you don't need to be drawing with alpha shading . 对于纯色背景图块, 无需使用alpha阴影进行绘制 This can significantly speed up drawing in some cases. 在某些情况下,这可以大大加快绘图速度。 ie you can use TYPE_INT_RGB rather than TYPE_INT_ARGB 即您可以使用TYPE_INT_RGB而不是TYPE_INT_ARGB

If you really want high performance drawing/animation then you may want to consider switching to an OpenGL-based rendering engine - Slick2D or LWJGL for example. 如果您确实想要高性能的绘图/动画,则可能需要考虑切换到基于OpenGL的渲染引擎-例如Slick2DLWJGL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM