mirror of
https://github.com/doublespeakgames/adarkroom.git
synced 2026-05-28 08:11:54 +08:00
world.js: Improve road drawing algorithm
Instead of drawing an 'L' shape road to the village, find the closest road, outpost or village and draw the road to it. Care is taken to ensure that a road is drawn if you are standing on top of an outpost, as the outpost may be created before the tile it stands on is connected to the road network.
This commit is contained in:
+51
-10
@@ -152,27 +152,68 @@ var World = {
|
||||
},
|
||||
|
||||
drawRoad: function() {
|
||||
var xDist = World.curPos[0] - World.RADIUS;
|
||||
var yDist = World.curPos[1] - World.RADIUS;
|
||||
var findClosestRoad = function(startPos) {
|
||||
// We'll search in a spiral to find the closest road tile
|
||||
// We spiral out along manhattan distance contour
|
||||
// lines to ensure we draw the shortest road possible.
|
||||
// No attempt is made to reduce the search space for
|
||||
// tiles outside the map.
|
||||
var searchX, searchY, dtmp,
|
||||
x = 0,
|
||||
y = 0,
|
||||
dx = 1,
|
||||
dy = -1;
|
||||
for (var i = 0; i < Math.pow(World.getDistance(startPos, World.VILLAGE_POS) + 2, 2); i++) {
|
||||
searchX = startPos[0] + x;
|
||||
searchY = startPos[1] + y;
|
||||
if (0 < searchX && searchX < World.RADIUS * 2 && 0 < searchY && searchY < World.RADIUS * 2) {
|
||||
// check for road
|
||||
var tile = World.state.map[searchX][searchY];
|
||||
if (
|
||||
tile === World.TILE.ROAD ||
|
||||
(tile === World.TILE.OUTPOST && !(x === 0 && y === 0)) || // outposts are connected to roads
|
||||
tile === World.TILE.VILLAGE // all roads lead home
|
||||
) {
|
||||
return [searchX, searchY];
|
||||
}
|
||||
}
|
||||
if (x === 0 || y === 0) {
|
||||
// Turn the corner
|
||||
dtmp = dx;
|
||||
dx = -dy;
|
||||
dy = dtmp;
|
||||
}
|
||||
if (x === 0 && y <= 0) {
|
||||
x++;
|
||||
} else {
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
return World.VILLAGE_POS;
|
||||
};
|
||||
var closestRoad = findClosestRoad(World.curPos);
|
||||
var xDist = World.curPos[0] - closestRoad[0];
|
||||
var yDist = World.curPos[1] - closestRoad[1];
|
||||
var xDir = Math.abs(xDist)/xDist;
|
||||
var yDir = Math.abs(yDist)/yDist;
|
||||
var xIntersect, yIntersect;
|
||||
if(Math.abs(xDist) > Math.abs(yDist)) {
|
||||
xIntersect = World.RADIUS;
|
||||
yIntersect = World.RADIUS + yDist;
|
||||
xIntersect = closestRoad[0];
|
||||
yIntersect = closestRoad[1] + yDist;
|
||||
} else {
|
||||
xIntersect = World.RADIUS + xDist;
|
||||
yIntersect = World.RADIUS;
|
||||
xIntersect = closestRoad[0] + xDist;
|
||||
yIntersect = closestRoad[1];
|
||||
}
|
||||
|
||||
for(var x = 0; x < Math.abs(xDist); x++) {
|
||||
if(World.isTerrain(World.state.map[World.RADIUS + (xDir*x)][yIntersect])) {
|
||||
World.state.map[World.RADIUS + (xDir*x)][yIntersect] = World.TILE.ROAD;
|
||||
if(World.isTerrain(World.state.map[closestRoad[0] + (xDir*x)][yIntersect])) {
|
||||
World.state.map[closestRoad[0] + (xDir*x)][yIntersect] = World.TILE.ROAD;
|
||||
}
|
||||
}
|
||||
for(var y = 0; y < Math.abs(yDist); y++) {
|
||||
if(World.isTerrain(World.state.map[xIntersect][World.RADIUS + (yDir*y)])) {
|
||||
World.state.map[xIntersect][World.RADIUS + (yDir*y)] = World.TILE.ROAD;
|
||||
if(World.isTerrain(World.state.map[xIntersect][closestRoad[1] + (yDir*y)])) {
|
||||
World.state.map[xIntersect][closestRoad[1] + (yDir*y)] = World.TILE.ROAD;
|
||||
}
|
||||
}
|
||||
World.drawMap();
|
||||
|
||||
Reference in New Issue
Block a user