Jump to content
  • Advertisement
Sign in to follow this  
Silent Dragon

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

This topic is 3738 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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)

            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)

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

                int curTileHeight;

                // Last row of tiles
                if(((i + 1) * tileHeight) > (camera.Position.Y + camera.Height))
                    curTileHeight = (int)((camera.Position.Y + camera.Height) - (i * tileHeight));
                    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)

                    // 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))

                    // 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)) : 
                    double endPixelYTile = ((i + 1) * tileHeight > (camera.Position.Y + camera.Height)) ? 
                         (texture.Height * (((camera.Height + camera.Position.Y) - (i * tileHeight)) / tileHeight)) : 

                    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,

                    if (camera.Debug)
                        // Print out some nice debug messages

                    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;


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

Share this post

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

Share this post

Link to post
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,

Share this post

Link to post
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 this post

Link to post
Share on other sites
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.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!