Hi everyone!
The Tilemap API is in beta, and as more developers have started to use it, we have started to get some feedback on things that people prefer and don’t prefer about the API.
Change for it’s own sake is not ideal, but we are early enough in this process that I would like to talk about whether we should consider making some changes—API changes now are going to be easier than if we wait.
This is an example of how the Tilemap API might look in a project:
var bitmapData = Assets.getBitmapData ("tiles.png");
var tileset = new Tileset (bitmapData);
tileset.addTileRect (new Rectangle (0, 0, 100, 100));
var tilemap = new Tilemap (800, 600);
var tilemapLayer = new TilemapLayer (tileset);
var tile = new Tile (0);
tilemapLayer.addTile (tile);
tilemap.addLayer (tilemapLayer);
addChild (tilemap);
There is one Tileset per BitmapData, you can add tile rectangles to the tileset, which generates new tile IDs. Anyone who has used drawTiles or another batch tiling API should recognize this portion.
The Tilemap object is an OpenFL DisplayObject, which is later added to the display list. This is what controls where and how all of our tiles will be drawn. The current API allows for any number of TilemapLayer objects, which contain Tile instances. Each one of these Tile instances holds a tile ID, x, y, scale, rotation or other draw information needed when perform the final render.
TilemapLayer is locked to one Tileset only, and represents one draw call on the GPU. If you need more than one Tileset, you will need to separate into multiple layers, increasing the number of draw calls.
Here is one alternative:
var bitmapData = Assets.getBitmapData ("tiles.png");
var tileset = new Tileset (bitmapData);
tileset.addTileRect (new Rectangle (0, 0, 100, 100));
var tilemap = new Tilemap (800, 600);
var tile = new Tile (tileset, 0);
tilemap.addTile (tile);
addChild (tilemap);
In this example, TilemapLayer has been removed, each Tile needs to have both a Tileset and a tile ID value. This complicates the code internally, but allows for the batching mechanism of splitting into one or more draw calls to be done internally, and not passed onto the user. It also lends itself to shorter code, though perhaps with some lost flexibility?
Here is one more alternative:
var bitmapData = Assets.getBitmapData ("tiles.png");
var tileData = new TileData (bitmapData, new Rectangle (0, 0, 100, 100));
var tilemap = new Tilemap (800, 600);
var tile = new Tile (tileData);
tilemap.addTile (tile);
addChild (tilemap);
This extends the concept a bit further, avoiding a Tileset object to use TileData objects instead. Then a Tile needs a TileData (similar to how Bitmap requires BitmapData) but there are no longer tile IDs, and there is no need for an added Tileset object, as we already have BitmapData to begin with.
Lastly, here is one more concept:
var bitmapData = Assets.getBitmapData ("tiles.png");
var tileData = new TileData (bitmapData, new Rectangle (0, 0, 100, 100));
var tilemap = new Tilemap (800, 600);
var tile = new Tile (tileData);
tilemap.addTile (tile);
addChild (tilemap);
var tileGroup = new TileGroup ();
var tile2 = new Tile (tileData);
tile2.x = 100;
tileGroup.addTile (tile2);
tilemap.addGroup (tileGroup);
Finally, if there is a benefit to having tile layers, or other forms of built-in grouping within the API, we could consider allowing Tilemap to define a default group internally, but for us to be able to add other groups as well, manually. This might be unneeded complexity, or we might consider allowing a TileGroup to have it’s own transformation, slowing the render a bit, but adding convenience for rotating or scaling a set of tiles together.
…or we might be happy as it is, it’s simple and works similar to other APIs in other libraries. We’re open to your feedback, and appreciate your help on this.
Thank you!





