I've been wondering how you would go about labeling an area on a 2D tile map. What I'd like to do is associate tiles with an area i.e Forest Area, Desert Area, etc.

Keep in mind this is an idea, so far I've been thinking that one way to go about this is to have each area store tile positions as the pivot points and you need at least four of these pivot points before it is a valid area. This way would allow for some of the granularity I would like as my first idea was to just associate every tile with an area id, which is pretty inefficient time-wise, though the task would have been alleviated somewhat with a map editor that I am going to build (i.e. just paint a tile with an area color/number).

What are your ideas on this?

Also, the map, areas, and etc will be stored in an sql database FYI.

  • 1
    \$\begingroup\$ By "area" you seem mean "type of terrain", don't you? \$\endgroup\$ – sam hocevar Jan 2 '13 at 12:19
  • \$\begingroup\$ Not exactly. An area to me is just a label for tiles being associated with a place, so the area could be a city area/place as well. \$\endgroup\$ – Norm Jan 2 '13 at 12:37
  • \$\begingroup\$ What do you mean by "label"? \$\endgroup\$ – Anko Jan 2 '13 at 12:58
  • \$\begingroup\$ Consider the case of Google maps, for instance, the concept of an area (in my game) isn't limited to terrain, but rather designating States of the US or Ocean, Arizona desert, and etc., but I am thinking of the highest possible concept, which would be like Continents. Also, you could also think about Pokemon as well, where there are "city" "route" "water" labels. Each area is unique as well! \$\endgroup\$ – Norm Jan 2 '13 at 13:09

I've done something similar to this using an abstract concept of Area. An Area is just basically collection of Tiles, calculated at run time, but will allow you to work with that collection much easier. An Area made up of a collection of individual Tiles will also allow you to have irregular (not just square) areas of forests and deserts.

Using this concept, you can also join up Areas if say for example, a tree grows between two adjacent forests. Your code can then determine whether it joins two areas, and if so, combine them into one.

The Area would not be persisted into a database, but calculated at run time. The Tiles themselves are the actual data that would be stored (and created in your map editor). The Area would just make working with a large collection of tiles easier. A Tile knows nothing about the Area it is contained within. All game logic would then deal with the concept of Area rather than Tile. This should be much faster as there are usually a lot less Areas than Tiles.

In your game, you might want to know what Area your player is in, and assign associated values to the size of that Area. For example if your player is in a large forest (Area.GetSize() returns the actual number of Tiles), then the chance of encountering a more lethal enemy might increase. Likewise, entering a small desert might drain the players endurance less.

In order to work out the areas to begin with, you would need to iterate over every tile in your map when you load the map. If that Tile was not next to an Area of the same type, create a new Area and add that Tile to it. If the Tile is next to an similar Area, just add that Tile to it.

If a Tile is adjacent to more than one Area of the same type, combine all Tiles contained in all of those Areas into one Area.

Then if you are simulating a growing / changing world and a new forest does sprout, just use the same method as above to see whether that Tile is adjacent to an Area and act accordingly.

  • \$\begingroup\$ Ideally, I'd like to use the database to store as much as possible, but in a flexible way to handle changes. I threw the idea of pivots out there because I felt it would be easier handle changes without having to iterate through the tiles. I would be querying the database for areas that contain the tile, but this would be somewhat complicated unless I determined a key piece of information such as the avg tile position to come up with a center point for the area for use of finding the closest areas to the current tile and determining whether the tile is contained in an area or not. \$\endgroup\$ – Norm Jan 2 '13 at 13:21

Not sure if associating each tile to its type should be a major concern in terms of execution speed. You'll only be doing this when the game loads, not on every frame. Regarding how I'd do it:

I would define simple rectangle structures in case there are none defined in your environment:

structure Rect has components:
    XPosition : integer
    YPosition : integer
    Width : integer
    Height : integer

and extend this to:

structure AreaTypeRect has components:
      <components from Rect>
      AreaType[] : symbol

And store them in a SQL (since you're using it) table. Map each rectangle to the level it belongs to with a foreign key.

Basically, the rectangle with XPosition = 5, YPosition = 5, Width = 10, Height = 10 means the tiles in the rectangle defined by the points (5, 5), (5, 15), (15, 5), (15, 15). Why did I define AreaType as array? You may define it as a single value-type if you absolutely won't need terrain type blending. But you might reach some nice effects with multiple types per tile. For example, you could mark a particular tile to be of the type Grass and then add the type Water to it. This could result in a Grass tile with some Water stains on it, as if it rained a lot.

I might be overthinking this though. Perhaps a single AreaType per tile is enough for your needs. AreaType can be any kind of symbol, but you must tell your game how to interpret it. I would go with integers and map them like this:

(integer AreaTypeID, Texture TileSprite)

or with colors, as you mentioned you'll be using in the editor (blending colors from multiple terrain types is even easier):

(integer AreaTypeID, Color TileColor)


(0, GrassTile)
(1, WoodTile)

You can do this mapping in a SQL table, if you do store things such as textures in the SQL database. I'd store artwork on the hard drive though.

  • \$\begingroup\$ The rectangles would be a limitation in this design. The easiest thing i could do is designate four pivot points (xmin, ymin, xmax, ymax) to areas and run a range query against my current tile position. The area's wouldn't have to be objects loaded into the program, for now, as sql can handle range queries pretty well. This idea seems to be a little similar to my first idea though, which kinda suggests my first idea may be a better way of going about this. \$\endgroup\$ – Norm Jan 2 '13 at 13:29
  • 1
    \$\begingroup\$ Not sure how it would be a limitation in design. Four pivot points define a rectangle themselves, it's just a bit less well organised from a structural point of view. You can use simple formulas to see if a particular tile is inside of a rectangle or not; see this: stackoverflow.com/questions/2752725/… \$\endgroup\$ – user15805 Jan 2 '13 at 14:02
  • \$\begingroup\$ It is a limitation in that it would only support rectangles. The idea behind having > 4 pivots and the idea of associating areasIds with the tiles is to handle complex shapes for the areas. At some point in the future, I'd hope to designate safe areas and things like that, which is the idea behind "areas". That post though, I do like the idea for checking against edges! \$\endgroup\$ – Norm Jan 2 '13 at 14:16
  • \$\begingroup\$ Well, you never mentioned you'd want more than 4 pivot points :) You could make a Polygon structure, with a list of points in it, each being a pair of coordinates (x, y). \$\endgroup\$ – user15805 Jan 2 '13 at 14:36

Just add another column (of type string) to your 'tiles' table to allow you to enter values such as 'The valley of uncanny'?


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.