I need to draw only the tiles on screen to increase performance. What is a viable way to do this?
I tried this that brings me close but end up with a bug i cant seem to solve.
//world position to start drawing from
int sPosX = (int)(cam.Position.X - (device.Viewport.Width / 2));
int sPosY = (int)(cam.Position.Y - (device.Viewport.Height / 2));
//tile position to start drawing from
int sTileX = (int)((sPosX + (2*sPosY) - (Map.TileWidth/2)) / Map.TileWidth -1);
int sTileY = (int)((sPosX - (2 * sPosY) - (Map.TileHeight / 2)) / -Map.TileWidth - 1);
//amount of rows/collumns to draw
int rowCount = (int)(device.Viewport.Height / (Map.TileHeight / 2) + 2);
int colCount = (int)(device.Viewport.Width / Map.TileWidth + 2);
//current tile to draw
int tileX;
int tileY;
for (int row = 0; row < rowCount; row++)
{
for (int col = 0; col < colCount; col++)
{
tileX = sTileX + col + (int)((row / 2));
tileY = sTileY - col + (int)((row / 2));
if (tileX >= 0 && tileX < tileMap.GetLength(0) && tileY >= 0 && tileY < tileMap.GetLength(1))
{
batch.Draw(grid, new Rectangle((tileX * (TileWidth / 2)) - (tileY * (TileWidth / 2)), (tileX * (TileHeight / 2) + (tileY * (TileHeight / 2))), TileWidth, TileHeight), Color.White);
batch.DrawString(tiny, tileX + "," + tileY, new Vector2(tileX * (TileWidth / 2) - (tileY * (TileWidth / 2)) + 24, tileX * (TileHeight / 2) + (tileY * (TileHeight / 2)) + 12), Color.White);
}
}
}
Here i try drawing my tilemap row by row. First i find out what the first tile to be drawn is (upper left corner) then i find out how many collumns and how many rows need to be drawn.
At first i only worked with floats and cast to end at the last moment, while converting the floats step by step to int i was able to get the full X=0 and full Y=0 row on the screen but the rest still showed up as this picture.
While moving the camera, the tiles shown/rendered switch between uneven and even, so if i move a small amount down suddenly all the tiles show in the picture disappear and the blanks get shown. Moving further and it reverses, if i keep moving it flickers between those two states. I figured it has something to do with the (row/2) but i cant seem to fix it.
The way i am calculating which tiles to draw seems to be good. I get this when i zoom out (zooming is not altering the formula yet). In the picture below you can see the 2nd state as well where the other tiles being drawn.
tileX = sTileX + col + (int)((row / 2) + (row%2));
The modulus fixes it since on each second row should be increased by one in addition to the first.
Still i think this is valuable information as i spent hours finding out how to do this properly and ended up doing it myself. I think this is the most efficient way to draw everything since it allows for rendering a diamond style isometric map as a zigzag square.