Original Post
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. Any general tips on improving the code are welcome, and anyone who helps me fix this issue gets a cookie! Thanks, - SD
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.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[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();
}