1
\$\begingroup\$

I'm trying to think of a way to manage tiles in my game, so far I have a Tile class that has characteristics about the tile in question, a TileDictionary class to keep a list of tiles to use, and the map is simply just a Tile[,] array.

class Tile
{
    public Texture2D graphic;
    string name;
    bool walkable;



    public Tile()
    {
        name = "Dirt";
        graphic = null;
        walkable = true;
    }

    public Tile(string _name, Texture2D _graphic, Boolean _walkable)
    {
        name = _name;
        graphic = _graphic;
        walkable = _walkable;
    }


static class TileDictionary
{
    public static Tile DIRT_TILE = new Tile("Dirt",null,true);
    public static Tile STONE_TILE = new Tile("Stone", null, true);
    public static Tile CLAY_TILE = new Tile("Clay", null, true);

    public static void LoadTileGraphics(ContentManager content)
    {
        DIRT_TILE.setGraphic(content.Load<Texture2D>("tiles/dirt"));
        STONE_TILE.setGraphic(content.Load<Texture2D>("tiles/stone"));
        CLAY_TILE.setGraphic(content.Load<Texture2D>("tiles/clay"));
    }

Is this a good method? I see games like Minecraft using static Block instances to reference their blocks, but knowing that it was previously all magic numbers, I feel like this system was just a band-aid over the old system. Obviously all tiles would be loaded via the TileDictionary, but I am confused on how using this method would handle implementing and using more complex blocks that have functions tied to them or anything.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

As long as your tiles have no actual state or unique information, this is going to work just fine.

When you do add a little state, like a door which can be open or closed, you can implement this with two different tile types (TileDictionary.DOOR_OPEN_TILE and TileDictionary.DOOR_CLOSED_TILE).

But when it gets more complex, like if you have destructible tiles with individual hitpoint cost or signs with unique texts the player-character can read, then this won't be sufficient anymore.

You could then still use your architecture by putting some objects into your Tile[,] array which are not actually static members of TileDictionary but ad-hoc instantiated objects form classes which extend your Tile class.

However, this means that you might have to add some methods to Tile which are implemented as a no-op in Tile and only serve to be overridden by the more complex Tile subclasses. This might turn out to be a minor performance hook, because it means that this methods will now be called for every tile, even if it doesn't actually do anything most of the time.

It might be better to implement such objects not as tiles but as mobile game objects, just like the enemies and the player.

I'm looking forward to playing your game.

\$\endgroup\$
0
\$\begingroup\$

I believe the Flyweight pattern is what you need.

Flyweight, like its name implies, comes into play when you have objects that need to be more lightweight, generally because you have too many of them.

A simple implementation is listed at the page.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ The code shown in the question appears to already implement the flyweight pattern. They have a small set of tile objects, and a large number of instances (slots in the array) referencing those few objects. \$\endgroup\$
    – DMGregory
    Commented Jul 6, 2018 at 17:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .