# How do I cap rendering of tiles in a 2D game with SDL?

I have some boilerplate code working, I basically have a tile based map composed of just 3 colors, and some walls and render with SDL. The tiles are in a bmp file, but each tile inside it corresponds to an internal number of the type of tile(color, or wall). I have pretty basic collision detection and it works, I can also detetc continuous presses, which allows me to move pretty much anywhere I want. I also have a moving camera, which follows the object.

The problem is that, the tile based map is bigger than the resolution, thus not all of the map can be displayed on the screen, but it's still rendered. I would like to cap it, but since this is new to me, I pretty much have no idea.

Although I cannot post all the code, as even though I am a newbie and the code pretty basic, it's already quite a few lines, I can post what I tried to do

void set_camera()
{
//Center the camera over the dot
camera.x = ( player.box.x + DOT_WIDTH / 2 ) - SCREEN_WIDTH / 2;
camera.y = ( player.box.y + DOT_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;

//Keep the camera in bounds.
if(camera.x < 0 )
{
camera.x = 0;
}
if(camera.y < 0 )
{
camera.y = 0;
}
if(camera.x > LEVEL_WIDTH - camera.w )
{
camera.x = LEVEL_WIDTH - camera.w;
}
if(camera.y > LEVEL_HEIGHT - camera.h )
{
camera.y = LEVEL_HEIGHT - camera.h;
}
}


set_camera() is the function which calculates the camera position based on the player's positions. I won't pretend I know much about it.

Rectangle box = {0,0,0,0};

for(int t = 0; t < TOTAL_TILES; t++)
{
if(box.x < (camera.x - TILE_WIDTH) || box.y > (camera.y - TILE_HEIGHT))
apply_surface(box.x - camera.x, box.y - camera.y, surface, screen, &clips[tiles[t]]);

box.x += TILE_WIDTH;

//If we've gone too far
if(box.x >= LEVEL_WIDTH)
{
//Move back
box.x = 0;

//Move to the next row
box.y += TILE_HEIGHT;
}
}


This is basically my render code. The for loop loops over 192 tiles stored in an int array, each with their own unique value describing the tile type(wall or one of three possible colored tiles).

box is an SDL_Rect containing the current position of the tile, which is calculated on render.

TILE_HEIGHT and TILE_WIDTH are of value 80.

So the cap is determined by

if(box.x < (camera.x - TILE_WIDTH) || box.y > (camera.y - TILE_HEIGHT))


However, this is just me playing with the values and see what doesn't break it. I pretty much have no idea how to calculate it.

My screen resolution is 1024/768, and the tile map is of size 1280/960.

• What are DOT_WIDTHand DOT_HEIGHT? – Asakeron Dec 12 '12 at 13:57
• My object/player's width and height values which are both 20. – farmdve Dec 12 '12 at 14:02
• Not directly related to your question, but, are you using double buffer? – Asakeron Dec 12 '12 at 14:16
• I am not. I am afraid to say, I don't even know what a double buffer is used for. – farmdve Dec 12 '12 at 14:33
• See if on the SDL_SetVideoMode parameters you're passing the flag SDL_DOUBLEBUF. That will say if you're using double buffer or not. – Gustavo Maciel Dec 12 '12 at 14:58

Rather than going through all tiles only iterate over the tiles that are visible or on screen.

I'm assuming that camera coordinates are in pixels

for (int y = floor(camera.y / tile_height); y < floor((camera.y + screen.h) / tile_height; y++)
for (int x = floor(camera.x / tile_width); x < floor((camera.x + screen_width) / tile_width; x++)
renderTile(x, y);


I would write your conditional as the following:

if(!(box.x + TILE_WIDTH < camera.x //Tile is outside screen leftwards
|| box.x > camera.x + SCREEN_WIDTH //Tile is outside screen rightwards
|| box.y + TILE_HEIGTH < camera.y //Tile is outside screen upwards
|| box.y > camera.y + SCREEN_HEIGHT)) //Tile is outside screen downwards
{
...
}

• I tried this bit, but I notice the tile starting on coordinates 0,0 is always blank, and as I move down I can see the other tiles going blank, but I was hoping that I wouldn't see them going blank. – farmdve Dec 12 '12 at 14:34
• You mean the tile placed at [0,0] is always blank? – Asakeron Dec 12 '12 at 14:38
• @farmdve I edited my answer, can you try the new code? – Asakeron Dec 12 '12 at 14:58
• Certainly the tile at 0,0 is no longer black(empty). – farmdve Dec 12 '12 at 18:01
• Is everything working as expected now? – Asakeron Dec 12 '12 at 18:07