Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have done mostly tile based games, but never really bothered with optimization. I always just rendered all the tiles that convered the viewport. I am currently working on platformer for a mobile device, which has some performance issues, ecspecially when using multiple layers of tiles.

Most tiles are pretty static without animations. I wouldn't really have to render them each frame. The clear() -> draw() loop is really printed into my brain, I'm having a hard time thinking how the handle rendering without clearing the screen each frame.

I'm currently doing this: - start game, render screen once - Once a tile changes, save this in a "tile_changed" array - Each frame, re-render all the changed tiles and clear the array

This works pretty fine, and there is a notable boos in performance. However, there are a view issues - The PlayN framework offers no way to "erase" drawn items. Whenever I want to erase a single tile I have to completely clear the screen and redraw every tile. (PlayN SurfaceLayer). I'm using a scroll background, so can't just fill an empty tile with the background color. I can imagine low level libraries like opengl having this same issue, do they use some sort of workaround for this?

  • I'm not sure how to recognize when new tiles come into the screen whenever the camera moves. I would normally just render the tiles in view each frame, so this never posed a problem.

  • I have no idea if having such a big drawn rendertarget in memory is a good idea. The player could have walked across a huge map and have thousands of tiles drawn. Should I worry about this?

Any other optimiztions that I'm missing are appreciated.


The awnsers note that most engines draw all tiles every frame. But I know that on some less powerfull platforms this is not the case. I believe flashpunk is using some sort of buffer that only draws new tiles when you make changes in the grid. Unfortunately this is not possible for me because I have no way of clearing a single tile without clearing the entire buffer.

I'm looking into optimazations like this, which enable me to have a very large amount of tiles on the screen.

share|improve this question
1  
As far as I know, most modern 2D engines redraw the scene completely at every Update. Are you sure, this is the cause of your performance issues? How big is your scene? How many objects are on the scene? If you have too many tiles, only run the Update on the ones that are visible (or near the edge of the screen). –  Marton Jul 12 '12 at 7:50
    
I'm pretty sure, since all I do right now is draw a tilegrid and a player. Also, just because modern 2d engines redraw everything does not mean that that is the way to go. It personally annoys me that I'm redrawing everything while I feel that shouldn't have to. –  omgnoseat Jul 12 '12 at 21:11
    
@omgnoseat: Actually, that does mean it's the way to go. If games like Terraria, which has lot of lighting effects and dynamic maps, can do it, then yours can too. You need to be more familiar with how things are currently done and why they are before you can start trusting your instincts about whether or not those are the right way to handle things. –  Nicol Bolas Jul 23 '12 at 18:29

2 Answers 2

When designing for current PC GPUs you are not playing after the same performance rules, as, for example, a cellphone or the Amiga.

Modern GPUs are way more powerful than you can imagine and most of the time the bottleneck is not the drawing itself but actually the communication between your code running on the CPU and the GPU.

Take a look at this answer for performance suggestions on modern GPUs:
Drawing lots of tiles with OpenGL, the modern way

share|improve this answer

Basically its like Marthon said, that most engines simply redraw the whole scene on every render call and not only portions of the visible scene. What you are looking for is a way to limit the objects/tiles, that are actually rendered. If you have a 2d array of tiles, that are all same sized its pretty simple to find the start and the end index of the x and y loop. My render method for a tile layer looks something like this:

public void render(Graphics g, MappedTile[][] tiles, int width, int height, float offsetX, float offsetY, float screenX, float screenY)
{
    int layers = 1;
    int startX = (int) (-offsetX / tileWidth);
    int startY = (int) (-offsetY / tileHeight);
    int endX = (int) ((-offsetX + screenX) / tileWidth + 1);
    int endY = (int) ((-offsetY + screenY) / tileHeight + 1);
    if(startX < 0)
        startX = 0;
    if(startY < 0)
        startY = 0;
    if(endX > width)
        endX = width;
    if(endY > height)
        endY = height;

    for(int y = startY; y < endY; y++)
    {
        for(int x = startX; x < endX; x++)
        {
            //Put render code in here... Select tile, apply offset and render
        }
    }
}

The idea is that you only render those tiles, that are visible on screen and skip those that are outside of the viewport. You don't have to recognize when a new tiles comes into the screen, as you recalculate the variables on every render call. Alternatively you could only update the position, if the viewport has changed since the last render pass.

Note, if you want to add scaling functionality, you would also need to change the calculation of startX, startY, endX and endY, so the scaling is taken into account.

For other objects, for example sprites, that can be positioned freely on a map, a better data structure is needed. You could implement a quad tree and use it to distribute the objects around cells. You then simply select only the visible cells and render the objects from those cells (after you sorted them on the y axis). But thats another topic.

share|improve this answer
    
I'm already doing this, but that is indeed a good optimization. –  omgnoseat Jul 23 '12 at 18:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.