build method

  1. @override
Iterable<String> build()
override

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';
  }
}