Question

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.

Isometric display problem

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.

enter image description here

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top