问题
我正在尝试制作一个城市生成器,用于创建具有类型(住宅,工业,商业)类型的块的游戏。我所有的街道都将在90度,因为我希望它是块状的(而不是锯齿形)。
途径
我的第一个方法是选择一个起点,然后在地图上随机移动X个移动点。如果我走到了死胡同,我会追溯到一些随机数,有点像迷宫发电机,但这给我留下了许多区域,道路旁边的公路和道路没有直线行驶。我也看过使用柏林噪音,但我相信这两个会给我经常锯齿的道路。
当前解决方案
我想出了一种方法,它给了我很多我想要的东西,但我认为它比它需要的更复杂,或者至少比它更低效。目前,如果我尝试将其扩展到更大的地图,则可能需要几秒钟来处理。
JS Fiddle
https://jsfiddle.net/jrj2211/0exe9jne/
算法
缩放数组示例(有点像缩放图像):
[1, 2, 2] [1, 1, 2, 2, 2, 2]
[1, 3, 3] => [1, 1, 3, 3, 3 ,3]
[4, 4, 4] [4, 4, 4, 4, 4, 4]
我放大网格的原因是,如果我不这样做,之前是1x1区域的任何图块都会生成一个地图,其中两个或多个道路图块将成为邻居。
可视化
最终输出
注意:这与可视化
中的输出不同摘要
总结一下我的问题,是否有人就如何提高效率或更清洁提出任何建议。我认为很难为我当前的流程编写伪代码,所以我认为还有改进的余地。我还必须做更复杂的事情,比如去除1x1的细胞,因为没有房子被四面八方的街道包围。我也不希望这个城市成为一个完美的广场(所以我必须删除沿边界的随机区域并关闭他们的街道)。
答案 0 :(得分:1)
规避大数组创建的一种方法是直接实现所需的布局。关键是要缩放curTile
而不是grid
,请注意从++
到+=2
的更改。
// Get all cells as a 1 dimensional array
function GetAllCells() {
var cells = [];
for (var i = 0; i < mapSize; i+=2) {
for (var j = 0; j < mapSize; j+=2) {
cells.push(grid[i][j]);
}
}
return cells;
}
背靠背
IsInBoundsScaled
→IsInBounds
newGrid
→grid
<强>迭代强>
要获得相同的块次序,我们必须加倍方形尺寸(参考minSize
,maxSize
)。
// Get a random order to loop through the cells
var checkOrder = shuffle(GetAllCells());
var minSize = 4;
var maxSize = 10;
for (var id = 1; id < checkOrder.length; id++) {
var curTile = checkOrder[id];
if (curTile.type == TYPES.NONE) {
var direction = (Math.random() > .5 ? 1 : 0);
var square_width = RandomRange(minSize, (direction ? maxSize : minSize));
var square_height = RandomRange(minSize, (direction ? minSize : maxSize));
var zones = [TYPES.RESIDENTIAL, TYPES.COMMERCIAL, TYPES.COMMERCIAL, TYPES.RESIDENTIAL, TYPES.INDUSTRIAL];
var zone = zones[Math.floor(Math.random() * zones.length)];
var color = getRandomColor();
for (var i = 0; i < square_width; i+=2) {
for (var j = 0; j < square_height; j+=2) {
if (IsInBounds(curTile.i + i+1, curTile.j + j+1)) {
grid[curTile.i + i][curTile.j + j].id = id; // [x] O
grid[curTile.i + i][curTile.j + j].type = zone; // O O
grid[curTile.i + i+1][curTile.j + j].id = id; // x [O]
grid[curTile.i + i+1][curTile.j + j].type = zone; // O O
grid[curTile.i + i][curTile.j + j+1].id = id; // x O
grid[curTile.i + i][curTile.j + j+1].type = zone; // [O] O
grid[curTile.i + i+1][curTile.j + j+1].id = id; // x O
grid[curTile.i + i+1][curTile.j + j+1].type = zone; // O [O]
}
}
}
}
}
JS Fiddle Fork