I am trying to create a simple 2d scrolling game as a learning exercise in monogame (XNA). Currently I load tile information from a text file, creating an array (tiles[,]) with a tile object storing information about where the tile is written and what texture should be used when the draw method is called. Currently I draw every tile in the array at once and then simple update the position of the tile to move it across the screen. Obviously drwaing all tiles at once is a bit of a pain, and I think it would be better if I only drew the tiles visible on the screen, so as the tiles move across the screen more tiles are drawn. I am not sure how best to do this? I am a bit lost as to how I can tell what tiles should be drawn. Any help would be greatly appreciated. Here is my draw and update methods in my level class - it simply calls methods in the Tile class to draw/update position.
/// <summary>
/// Draws each individual tile in the level.
/// </summary>
private void DrawTiles(SpriteBatch spriteBatch)
{
// For each tile position
for (int y = 0; y < Height; ++y)
{
for (int x = 0; x < Width; ++x)
{
tiles[x, y].Draw(spriteBatch);
}
}
}
public void Update(GameTime gameTime, int scrollSpeed, ScrollDirection direction)
{
// Update the positions of each of the Background sprites
foreach (Tile tile in tiles)
{
tile.Update(gameTime, new Vector2(0, scrollSpeed), scrollDirection);
}
}
}
Thanks in advance
I am now trying to only loop through the tiles visible on the screen to draw, using a viewport passed from the graphics device. I basically try to get the number of tiles that can fit on the screen before trying to draw them, by dividing the height of the screen by the height of a tile and the same for width. This works just fine, and it draws all tiles visible on in the viewpoint.
The only problem is it no longer draws any of the tiles which began outside of the viewport, so even though in the update tiles are moved into the viewport they are not drawn as the loop uses their original location. I cant think of a way of fixing this without looping through all tiles though :-(
As a level can be big it would be very inefficient to loop through all tiles to only draw what was in the screen.
Any advice would be greatly appreciated.
here is the updated draw:
private void DrawTiles(SpriteBatch spriteBatch)
{
float tileWidth = 40;
float tileHeight = 32;
for (int y = 0; y < (int)Math.Ceiling(mViewport.Height / tileHeight); ++y)
{
for (int x = 0; x < (int)Math.Ceiling(mViewport.Width / tileWidth); ++x)
{
tiles[x, y].Draw(spriteBatch);
}
}
}