我正在编写一个寻路函数来为我的随机世界生成器创建河流,该生成器在地图上采用高湿度和高度的随机点并继续选择相邻的像素,找到具有最低高度的像素并继续在循环,直到它到达地图的边缘或打水。 世界发电机作为一个整体使用中点位移创建高程和湿度图,然后比较两个地图以评估生物群落和水。这部分工作正常,它刚刚实现我的河流创建功能,页面没有加载,我无法在调试时检查我的河流数组在控制台。 几乎是我唯一的问题是使用setRivers功能。我不知道我是否在事故中无限循环,如果这是一个错误,或者河流技师只是废话。
继承我的代码:
function createMap(size) {
var map = [];
for (var x = 0; x < size; x++) {
map[x] = [];
for (var y = 0; y < size; y++) {
map[x][y] = 0;
}
}
map[0][0] = 128;
map[size - 1][0] = 128;
map[size - 1][size - 1] = 128;
map[0][size - 1] = 128;
midpoint(0, 0, size - 1, size - 1);
return map;
function midpoint(x1, y1, x2, y2) {
if (x2 - x1 < 2 && y2 - y1 < 2) {
return;
}
var dist = (x2 - x1 + y2 - y1);
var hdist = Math.floor(dist / 2);
var rx = function(n, d) {
return Math.floor(((n + Math.floor(Math.random() * dist) - hdist) / d));
};
// var r2 = function(n) { return Math.floor(((n + Math.floor(Math.random() * dist) - hdist) / 2)); };
var set = function(x, y, n) {
if (map[x][y] == 0) {
map[x][y] = rx(n, 2);
}
};
var midx = Math.floor((x1 + x2) / 2);
var midy = Math.floor((y1 + y2) / 2);
var c1 = map[x1][y1];
var c2 = map[x2][y1];
var c3 = map[x2][y2];
var c4 = map[x1][y2];
set(midx, y1, c1 + c2);
set(midx, y2, c4 + c3);
set(x1, midy, c1 + c4);
set(x2, midy, c2 + c3);
map[midx][midy] = rx(c1 + c2 + c3 + c4, 4);
midpoint(x1, y1, midx, midy);
midpoint(midx, y1, x2, midy);
midpoint(x1, midy, midx, y2);
midpoint(midx, midy, x2, y2);
}
}
function getColor(elevation, moisture, river) {
var cb = function(e, m) {
return (elevation >= e && moisture >= m);
};
var ce = function(e) {
return elevation >= e;
};
var cm = function(m) {
return moisture >= m;
};
if (cb(250, 178)) {
return "#FFFFFF";
} //snow
if (cb(250, 142)) {
return "#CCFFFF";
} //tundra
if (cb(250, 100)) {
return "#808080";
} //bare
if (ce(250)) {
return "black";
} //scorched
if (cb(175, 214)) {
return "#006600";
} //taiga
if (cb(175, 142)) {
return "#009933";
} //shrubland
if (ce(175)) {
return "#FFCC66";
} //temperate desert
if (cb(100, 250)) {
return "#00FF99";
} //temperate rainforest
if (cb(100, 178)) {
return "#00CC00";
} //temperate deciduous forest
if (cb(100, 100)) {
return "#CCFF33";
} //grassland
if (ce(100)) {
return "#FFCC66";
} //temperate desert
if (cm(214)) {
return "#336600";
} //tropical rainforeest
if (cm(142)) {
return "#339966";
} //tropical seasonal forest
if (cm(100)) {
return "#CCFF33";
} //grassland
if (cm(70)) {
return "orange";
} //subtropical desert
return "blue"; //water
}
function setRivers(es, ms, size) {
var riverMap = [];
for (var x = 0; x < size; x++) {
riverMap[x] = [];
for (var y = 0; y < size; y++) {
riverMap[x][y] = 0;
}
}
var riverChance = 30;
for (var x = 1; x < size; x++) {
for (var y = 1; y < size; y++) {
if (es[x][y] > 175 && ms[x][y] > 142) {
var r = Math.floor(Math.random() * 100) + 1;
var hitWater = false;
var hitEdge = false;
var ex = x;
var ey = y;
if (r >= riverChance) {
riverMap[ex][ey] = 1;
while (hitWater == false && hitEdge == false) {
var neighbors = [es[ex - 1][ey], es[ex + 1][ey], es[ex][ey + 1], es[ex][ey - 1], es[ex][ey]];
// north , south, east, west, current position
var lowestElevation = 0;
for (var i = 1; i < neighbors.length; i++) {
if (neighbors[i] < neighbors[lowestElevation]) lowestElevation = i;
}
switch (lowestElevation) {
case 0:
riverMap[ex - 1][ey] = 'r';
ex -= 1;
break;
case 1:
riverMap[ex + 1][ey] = 'r';
ex += 1;
break;
case 2:
riverMap[ex][ey + 1] = 'r';
ey += 1;
break;
case 3:
riverMap[ex][ey - 1] = 'r';
ey -= 1;
break;
case 4:
hitWater = true;
break;
}
if (ex == 1 || ey == 1 || ex == (size - 1) || ey == (size - 1)) {
hitEdge = true;
}
if (es[ex][ey] < 100 && ms[ex][ey] < 70) {
hitWater = true;
}
}
}
}
}
}
return river;
}
function createWorld(worldSize) {
var size = worldSize;
var es = createMap(size);
var ms = createMap(size);
var rs = setRivers(es, ms, size);
console.log(river);
var draw = function(ctx) {
for (var i = 0; i < size; i++) {
for (var j = 0; j < size; j++) {
ctx.fillStyle = getColor(es[i][j], ms[i][j]);
ctx.fillRect(i, j, 1, 1);
if (river[i][j] == 1) {
ctx.fillStyle = 'blue';
ctx.fillRect(i, j, 1, 1);
}
}
}
};
return {
size: size,
elevation: es,
moisture: ms,
river: rs,
draw: draw
};
}
var world = createWorld(513);
var c = document.getElementById("main");
world.draw(c.getContext("2d"));
<!DOCTYPE html>
<html>
<body>
<canvas id='main' height='768' width='1024'></canvas>
</body>
</html>