I used AutoTileGen to create the tilesets for my #gbjam game, but at that time the algorithm for actually arranging the tiles in a tilemap didn’t exist for Flash. I got in contact with the creator and put this together with his help.
Here’s how you use it:
- Design your map in the editor of your choice, but don’t actually place the tiles. In Ogmo, I used a grid layer to specify which tiles were solid.
- Load your map into a Grid.
- Create a Tilemap using the image AutoTileGen creates from your source.
// To generate the entire map, do this:
AutoTileSet.createFromGrid(map, grid);
// To only set one tile, do this:
AutoTileSet.setTile(map, grid, x, y);
package
{
import net.flashpunk.graphics.Tilemap;
import net.flashpunk.masks.Grid;
public class AutoTileSet
{
/**
* Instantiating this has no effect, so probably don't do it.
*/
public function AutoTileSet() {}
/**
* Set each tile in a tilemap based on its neighbors
* @param map The tilemap to set the tiles of
* @param grid The grid to use for determining tile neighbors
*/
public static function createFromGrid(map:Tilemap, grid:Grid):void
{
var near:Array = [];
for (var x:int = 0; x < grid.columns; x++)
{
for (var y:int = 0; y < grid.rows; y++)
{
setTile(map, grid, x, y, near);
}
}
}
/**
* Set a tile based on its neighbors
* @param map The tilemap to set the tiles of
* @param grid The grid to use for determining tile neighbors
* @param x X index of the tile
* @param y Y index of the tile
* @param near Optional array to use for storing neighbor data. If not supplied, the function will create a new one to use.
*/
public static function setTile(map:Tilemap, grid:Grid, x:int, y:int, near:Array = null):void
{
if (!grid.getTile(x, y))
{
map.setTile(x, y, map.tileCount - 1);
return;
}
near = near || [];
function test(i:int, j:int):Boolean { return grid.getTile(x + i, y + j); }
near[0] = test(0, -1);
near[1] = test(1, 0);
near[2] = test(0, 1);
near[3] = test(-1, 0);
near[4] = test(-1, -1);
near[5] = test(1, -1);
near[6] = test(1, 1);
near[7] = test( -1, 1);
// value for a single block with no neighbors, otherwise it'll be set to (0, 0)
var sx:int = 6, sy:int = 2;
if (all(near[3])){sx=2;sy=2;}
if (all(near[0])){sx=3;sy=2;}
if (all(near[1])){sx=4;sy=2;}
if (all(near[2])){sx=5;sy=2;}
if (all(near[1],near[3])){sx=0;sy=2;}
if (all(near[0],near[2])){sx=1;sy=2;}
if (all(near[0],near[3])){sx=7;sy=1;}
if (all(near[1],near[0])){sx=0;sy=0;}
if (all(near[2],near[1])){sx=1;sy=0;}
if (all(near[3],near[2])){sx=2;sy=0;}
if (all(near[2],near[3],near[7])){sx=4;sy=3;}
if (all(near[3],near[0],near[4])){sx=5;sy=3;}
if (all(near[0],near[1],near[5])){sx=6;sy=3;}
if (all(near[1],near[2],near[6])){sx=7;sy=3;}
if (all(near[0],near[1],near[3])){sx=3;sy=0;}
if (all(near[1],near[2],near[0])){sx=4;sy=0;}
if (all(near[2],near[3],near[1])){sx=5;sy=0;}
if (all(near[3],near[0],near[2])){sx=6;sy=0;}
if (all(near[0],near[1],near[2],near[3])){sx=7;sy=4;}
if (all(near[0],near[2],near[3],near[7])){sx=7;sy=2;}
if (all(near[1],near[3],near[0],near[4])){sx=0;sy=1;}
if (all(near[2],near[0],near[1],near[5])){sx=1;sy=1;}
if (all(near[3],near[1],near[2],near[6])){sx=2;sy=1;}
if (all(near[0],near[1],near[3],near[5])){sx=3;sy=1;}
if (all(near[1],near[2],near[0],near[6])){sx=4;sy=1;}
if (all(near[2],near[3],near[1],near[7])){sx=5;sy=1;}
if (all(near[3],near[0],near[2],near[4])){sx=6;sy=1;}
if (all(near[1],near[2],near[3],near[6],near[7])){sx=0;sy=3;}
if (all(near[0],near[2],near[3],near[4],near[7])){sx=1;sy=3;}
if (all(near[0],near[1],near[3],near[4],near[5])){sx=2;sy=3;}
if (all(near[0],near[1],near[2],near[5],near[6])){sx=3;sy=3;}
if (all(near[0],near[1],near[2],near[3],near[7])){sx=3;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[4])){sx=4;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[5])){sx=5;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[6])){sx=6;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[5],near[7])){sx=1;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[4],near[6])){sx=2;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[6],near[7])){sx=5;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[4],near[7])){sx=6;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[4],near[5])){sx=7;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[5],near[6])){sx=0;sy=4;}
if (all(near[0],near[1],near[2],near[3],near[5],near[6],near[7])){sx=1;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[4],near[6],near[7])){sx=2;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[4],near[5],near[7])){sx=3;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[4],near[5],near[6])){sx=4;sy=5;}
if (all(near[0],near[1],near[2],near[3],near[4],near[5],near[6],near[7])){sx=0;sy=5;}
// convert coords for top-left index
var currentTileIndex:int = ( 5 - sy ) * 8 + sx;
map.setTile(x, y, currentTileIndex);
}
private static function all(...bools):Boolean
{
return bools.indexOf(false) < 0;
}
}
}