build method
Build the map. Recommend that implementations use synchronous generators so that the building of complex maps can be driven incrementally by the game loop. For example: place one room at a time for a dungeon map. The string values emitted by the returned Iterable could be used to dynamically update a loading screen.
Implementation
@override
Iterable<String> build() sync* {
// add rooms until we get to the target density or we fail too many times
var failures = 0;
while (roomDensity < _targetDensity && failures < 100) {
var room = _roomGen.nextRoom();
if (_canPlaceRoom(room)) {
_placeRoom(room);
failures = 0;
_regions.nextRegion();
yield 'Room';
} else {
failures++;
}
}
// fill the remaining open area with mazes
var mazeGen = MazeGenerator(regions);
var maze = mazeGen.nextMaze();
while (maze.isNotEmpty) {
for (var pos in maze) {
_tileMap[pos] = LevelTile.corridor;
}
_regions.nextRegion();
maze = mazeGen.nextMaze();
yield 'Corridor';
}
// connect regions
var connector = RegionConnector(regions);
for (var conn in connector.carveConnections()) {
if (conn.type == ConnectorType.duplicate) {
_tileMap[conn.position] = LevelTile.duplicateConnector;
} else {
_tileMap[conn.position] = LevelTile.connector;
}
yield 'Connector';
}
// cull dead ends
var culler = DeadEndCuller(map);
for (var deadEnd in culler.cullDeadEnds()) {
for (var pos in deadEnd) {
_tileMap[pos] = LevelTile.solid;
}
yield 'Dead end';
}
}