0
\$\begingroup\$

I'm using MonoGame to build my first game (yes, I'm new to game development). I'm trying to start by creating a 2D platformer so I want to have different "tiles" for the ground, walls, ceiling, etc.

I don't recall which tutorial I was reading, but I do know that they mentioned creating a tileset.png file and they gave a code sample of how to draw a specific tile from the tileset. I found a tileset on https://opengameart.org/ that I want to use for now, until I can replace the tileset.

I'm curious, is there any advantage to creating a tileset compared to creating, for example, multiple png content files?

https://opengameart.org/content/seasonal-platformer-tiles

\$\endgroup\$
5
\$\begingroup\$

Nowadays the most important reason to use a tilemap instead of separate pngs is just for organisation. Do you want a stage to have a different theme? Then you simply create a new tilemap, that follows the same rules as the previous one, but has a new appearence, and that's it! Compared to making so many separate new tiles, and have to point to them on each stage, it seems simpler.

Although not a big concern for small games, keep in mind that for a computer it's way easier/faster to load one big image, than multiple small ones. So it's one extra reason why putting all tiles together is better.

\$\endgroup\$
  • 3
    \$\begingroup\$ To add to this: drawing is done on the GPU and 2D is still drawing triangles and textures. These draw calls are batched (you probably noticed drawing in Monogame using the 'spriteBatch' methods). Every time you switch to another texture a new batch is created. With a tilemap, you can draw everything in one batch (= one call to the GPU). This is basically the main reason to use sprite atlasses; it is the most efficient way to communicate with the GPU. \$\endgroup\$ – Felsir Feb 12 '19 at 14:53
3
\$\begingroup\$

Here's a little experiment you can do yourself to see why using a texture atlas (or tileset) is a good idea.

The goal is to draw a checker pattern using a white.png texture and a black.png texture. The result should turn out something like this:

black and white checker pattern

First, load your two textures into the game:

_black = Content.Load<Texture2D>("black");
_white = Content.Load<Texture2D>("white");

Then write the code to draw the checkerboard pattern. Something like this will do nicely:

var isWhite = true;

_spriteBatch.Begin(samplerState: SamplerState.PointClamp);

for (var x = 0; x < 450; x++)
{
    for (var y = 0; y < 450; y++)
    {
        if(isWhite)
            _spriteBatch.Draw(_white, new Vector2(x * _white.Width, y * _white.Height), Color.White);
        else
            _spriteBatch.Draw(_black, new Vector2(x * _black.Width, y * _black.Height), Color.White);

        isWhite = !isWhite;
    }

    isWhite = !isWhite;
}

_spriteBatch.End();

The point of using a checkerboard pattern like this is to force the SpriteBatch to continually switch textures during rendering. This simulates what's going to happen if you draw all your tiles on different .png files.

Next you need a way to measure the frame rate. You can make a quick and dirty FPS counter by declaring a couple of member variables in your game class like this:

private float _clock;
private int _frameCounter;

And then throw this code in your Draw method**:

_clock += (float)gameTime.ElapsedGameTime.TotalSeconds;
_frameCounter++;

if (_clock >= 1)
{
    Console.WriteLine(_frameCounter);
    _frameCounter = 0;
    _clock = 0;
}

** Note: this really is a quick and dirty FPS counter. Technically some of that code should be in your Update method but it'll do for this purpose.

When you run the game you should start seeing the frame rate spew out into the console (in Visual Studio this will be in the "Output" window).

However, all this texture switching will cause the frame rate to drop dramatically. On my computer I could only draw a 150x150 (22,500 tiles) checkerboard before my frame rate suffered. Depending on your graphics card, you might have to fiddle with the numbers to see the same effect.

Finally, you can simulate what it would be like if you used a tileset instead. Simply change the code to only use the white.png texture like this:

if(isWhite)
    _spriteBatch.Draw(_white, new Vector2(x * _white.Width, y * _white.Height), Color.White);
else
    _spriteBatch.Draw(_white, new Vector2(x * _white.Width, y * _white.Height), Color.Black);

Now, on my computer I can easily draw a 450x450 (202,500 tiles) checkerboard without breaking a frame rate sweat. That's a pretty significant difference.

Now that we know there's an advantage to using a tileset keep in mind that I could still render 22,500 tiles using 2 textures instead of one. Sometimes if you're only making a small game this will do just fine.

Sometimes it's okay to take some development shortcuts if it makes your life easier. It's always good to know these things but don't bend yourself backwards trying to do something if it's not really achieving anything in your game. At the end of the day, if your game runs at 60 FPS you're all good.

\$\endgroup\$
1
\$\begingroup\$

It comes down to performance. Tilesets are good for the engine, since it then has to only store one single path to one picture. And that picture is easily made into power of two to better be compressable and decompressable, reducing the size of your built game.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.