This code creates a Voronoi Diagram of a low-resolution space, generating an approximation of regional divisions of an overworld map typical of the first Legend of Zelda or Link's Awakening. The white squares are randomly generated "centers".
-
-
Save polm/1357620 to your computer and use it in GitHub Desktop.
World Generator with d3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>World Generator</title> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script> | |
</head> | |
<body> | |
<div id="viz" ></div> | |
<script type="text/javascript"> | |
function worldgen(x,y,bc){ | |
//Initialize the array | |
var world = new Array(x); | |
for(i=0;i<world.length;i++){world[i]=new Array(y);} | |
//Generate some biomes! | |
var biomes = [ "G", "M", "B", "W", "F", "D", "S" ]; | |
var centers = new Array(bc); | |
for(count=0; count<bc; count++){ | |
var cx = parseInt(Math.random() * (x-1)); | |
var cy = parseInt(Math.random() * (y-1)); | |
//No overwriting | |
if (world[cx][cy] != null) {count--; continue;} | |
else { | |
var nb = biomes[parseInt(Math.random() * (biomes.length -1))]; | |
world[cx][cy] = nb; | |
centers.push([cx, cy, world[cx][cy].toLowerCase()]); | |
} | |
} | |
//OK, that was the centers. | |
//Now to fill. | |
//Strategy: | |
//Pick a square. | |
//Find the closest center (capital letter). | |
//Fill all squares from the square in question to the capital letter with lowercase. | |
//continue to next blank square. | |
for(i=0;i<x;i++){ | |
for(j=0;j<y;j++){ | |
//We only modify empties | |
if(world[i][j] != null) continue; | |
//Find the closest center - n^2 but we don't care! | |
var mindist = x * y * 100; | |
centers.forEach(function(c){ | |
var dist = Math.sqrt( Math.pow((c[0] - i),2) + Math.pow((c[1] - j),2)); | |
if (dist < mindist){ | |
mindist = dist; | |
world[i][j] = c[2]; | |
} | |
}); | |
} | |
} | |
//And output it! | |
var newworld = new Array(0); | |
for(i=0;i<x;i++){ | |
var row = ""; | |
for(j=0;j<y;j++){ | |
row = row + world[i][j]; | |
newworld.push([i, j, world[i][j]]); | |
} | |
console.log(row); | |
} | |
return newworld; | |
} | |
var map = worldgen(96, 50, 30); | |
var w = 960, h = 500; | |
var v = d3.select("#viz") | |
.append("svg:svg") | |
.attr("width", w) | |
.attr("height", h) | |
.append("svg:g") | |
.attr("class", "wrapper"); | |
v.selectAll("g.box").data(map).enter() | |
.append("svg:rect") | |
.attr("x", function(d){ return 10 * d[0];}) | |
.attr("y", function(d){return 10 * d[1];}) | |
.attr("width", 10) | |
.attr("height", 10) | |
.style("fill", function(d){switch (d[2]){ | |
case "w": return "blue"; | |
case "f": return "darkgreen"; | |
case "g": return "green"; | |
case "b": return "orange"; | |
case "d": return "yellow"; | |
case "s": return "purple"; | |
case "m": return "brown"; | |
default: return "white"; | |
}}) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment