# [C# - XNA] 2D Tile Drawing, rounding error?

## Recommended Posts

Hi guys, I've recently been working on a tile engine in XNA and have a problem that I've been trying to fix for quite a while. The image below sums it up pretty much. As I scroll around, occasionally I get a gap inbetween tiles. I assume this is to do with how I draw my tiles. Basically, what it does is works out the portion of the tile that should be displayed within the cameras borders and then uses that percentage to work out the source area of the texture. It then draws the tile in relation to the cameras borders. I feel that this explanation is a bit crappy, so I've included my 'Draw' method. But I feel I should explain some of my variables, as they are strangely named as I've been faffing about with this for a while. Camera.x and Camera.y - Give the position of the top left pixel of the camera, relative to the top left of the screen. Camera.Position - Vector2 that gives the top left pixel position of the camera, relative to the top left of the map.
public void draw(SpriteBatch spriteBatch, Camera camera)
{
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

int curDrawX = camera.x;
int curDrawY = camera.y;

for (int i = 0; i < rows.Count; i++)
{
// If the row is above the camera's view, then skip to the next row
if (((i + 1) * tileHeight) < camera.Position.Y)
continue;

// If the row is below of the camera's view, then don't draw it
if ((i  * tileHeight) > (camera.Position.Y + camera.Height))
break;

int curTileHeight;

// Last row of tiles
if(((i + 1) * tileHeight) > (camera.Position.Y + camera.Height))
curTileHeight = (int)((camera.Position.Y + camera.Height) - (i * tileHeight));
else
curTileHeight = tileHeight;

for (int j = 0; j < rows[i].Count; j++)
{
// If the tile is to the left of the camera, skip to the next one without drawing
if (((j + 1) * tileWidth) < camera.Position.X)
continue;

// If the tile is out of the camera's view, then don't continue with this row
if ((j * tileWidth) > (camera.Position.X + camera.Width))
break;

// float curTileWidth;

Rectangle dest, src;
Texture2D texture = tiles.getTile(rows[i][j]).getTexture();
Color colour = new Color(new Vector4(1f, 1f, 1f, alpha));

double startPixelXTile = (j * tileWidth >= camera.Position.X) ?
0 :
(texture.Width * ((camera.Position.X - (j * tileWidth)) / tileWidth));
double startPixelYTile = (i * tileHeight >= camera.Position.Y) ?
0 :
(texture.Height * ((camera.Position.Y - (i * tileHeight)) / tileHeight));

double endPixelXTile = ((j + 1) * tileWidth > (camera.Position.X + camera.Width)) ?
(texture.Width * (((camera.Width + camera.Position.X) - (j  * tileWidth)) / tileWidth)) :
texture.Width;
double endPixelYTile = ((i + 1) * tileHeight > (camera.Position.Y + camera.Height)) ?
(texture.Height * (((camera.Height + camera.Position.Y) - (i * tileHeight)) / tileHeight)) :
texture.Height;

src = new Rectangle(
(int)Math.Round(startPixelXTile, 0),
(int)Math.Round(startPixelYTile, 0),
(int)Math.Round((endPixelXTile - startPixelXTile), 0),
(int)Math.Round((endPixelYTile - startPixelYTile), 0));

int curTileWidth = (int)Math.Round((tileWidth * ((float)src.Width / texture.Width)), 0);
curTileHeight = (int)Math.Round((tileHeight * ((float)src.Height / texture.Height)), 0);

dest = new Rectangle(curDrawX,
curDrawY,
curTileWidth,
curTileHeight);

if (camera.Debug)
{
// Print out some nice debug messages
System.Console.WriteLine(src.ToString());
System.Console.WriteLine(dest.ToString());
}

spriteBatch.Draw(texture, dest, src, colour);

// Update the variables
curDrawX += (int)Math.Round((tileWidth * ((float)src.Width / texture.Width)), 0);
}

// Reset the variables for the next row
curDrawY += (int)curTileHeight;
curDrawX = camera.x;
}

spriteBatch.End();
}


Any general tips on improving the code are welcome, and anyone who helps me fix this issue gets a cookie! Thanks, - SD

##### Share on other sites
Moe    1256
Just out of curiosity, are you using tiles that are a size of a power of 2 (Eg: 32x32, or 64x4)?

##### Share on other sites
Ahh, I wonder if that is something to do with it. Most of them are, but I just grabbed some other images to test it, and I remember that one is 20x20. I'll try it with purely images of powers of 2 and report back.

Thanks for the feedback,
-SD

##### Share on other sites
Thanks Moe. I feel rather foolish now, going over and over the code, doing drawings and etc. Seems to work without any gaps now, which is nice, although id looks odd when scrolling, this could be that I've tinkered with the code too much and messed something up, or just that I'm scrolling too fast. But ahh well, I'm glad there are no more gaps.

- SD

##### Share on other sites
Moe    1256
Actually, I was wondering if your tile sizes were sizes of a power of 2, not your texture sizes. I guess it doesn't matter as your problem seems to be solved.