The art of programming tilemaps
= Types of tilemaps =
== The classic fixed-cell grid-map ==
This is the simplest form of a tilemap. Just define a grid and store a tile-id in each cell.
== Optimized fixed-cell map ==
There are various ways to optimize the simple tilemap to consume less memory. For example, quad-trees or similar techniques. A quad-tree can optimize away large empty areas, and makes it easy to have different-sized tiles as long as bigger ones have double the dimensions of smaller ones.
== Layers ==
Simply have multiple layers, one on top of another. This can have many uses, for example different tile-sizes and parallax scrolling.
== Non-rectangle ==
Popular types of tiles don’t use a fixed rectangular grid, but use hexagon or isometric maps. We’ll deal with both of them.
= The basics =
== Drawing ==
Assume, we have a fixed cell map. The x and y position of a tile can be calculated like this:
If the map data are stored as an array, and each map position just stores a tile number, we can retriece it like this:
So now, we have all we need. We can draw the tile to its position. Doing this for all tiles in the map, we can draw the complete map.
== Picking ==
Something which is not obvious to do at first, but will be useful soon, is how to pick tiles out of a map. Thinking about it, it is quite simple to do. It is, in a sense, the opposite of drawing.
We have a (pixel) position, and want to know which tile lies under it.
== Collision ==
Since we know how to pick a tile from a position, we can easily do collision detection now.
= Non-rectangular maps =
== Isometric (diamond layout) ==
== Hexagon (diamond layout) ==
== Isometric (row or column shifted layout) ==
== Hexagon (row or coumn shifted layout) ==
Parameters: LandGrid * self, LandView * view
Parameters: LandGrid * self, LandView * view, float view_x, float view_y, float * cell_x, float * cell_y
Given a view position, return the corresponding cell position.
For a wrapped grid, the returned position will always be normalized to lie within the grid, even if the passed position or the view's scroll position are outside.
Parameters: LandGrid * self, LandView * view, float cell_x, float cell_y, float * view_x, float * view_y
Given a cell position, return the corresponding view position, in pixels.
For a wrapped grid, the returned position will first be normalized to lie within the grid, and then related to the view position. Try normalizing the view's scroll position first (land_view_ensure_inside_grid) so it lies within the grid, if you experience unexpected offsets.
Parameters: LandGrid * self, int cell_w, int cell_h, int x_cells, int y_cells
no parameters
Parameters: LandGrid * self