var canvas = d3.select("canvas"); var ctx = canvas.node().getContext('2d'); var SEED = 123456; var noisegens = []; (function makeNoiseGens() { for (var i = 0; i < 10; i++) { var rng = makeRandFloat(SEED + i); noisegens[i] = new SimplexNoise(rng); } })(); function smooth_biome_color(z, m) { // This function copied from another project; see http://www.redblobgames.com/maps/terrain-from-noise/#biomes var water = 0.1; // Reshape these because perlin noise isn't evenly distributed z = z * 1.3 - 0.45; m = m * 3.0 - 0.7; if (z < water) { return d3.rgb(48 + 48*z/water, 64 + 64*z/water, 127 + 64 + 64*z/water); } // Green or brown at low elevation, and make it more white-ish // as you go up z = z * z * 0.7; var r = 210 - 100*m, g = 215 - 70*m, b = 139 - 45*m; return d3.rgb(255 * z + r * (1-z), 255 * z + g * (1-z), 255 * z + b * (1-z)); } function noise_at(x, y, u, v, spectrum, frequency) { var total = 0.0; var z = 0; for (var octave = 0; octave < spectrum.length; octave++, frequency *= 2) { z += spectrum[octave] * (noisegens[octave].noise4D(x * frequency, y * frequency, u, v)/2 + 0.5); total += spectrum[octave]; } return 1.2 * z / total - 0.05; /* hackery */ } function color_at_xy(x, y, phase) { var z = noise_at(x, y, 2 + phase, 0, [1, 1/4, 1/8], 3); var m = noise_at(x, y, 0, 2 + phase, [1, 1/2, 1/3], 3); return smooth_biome_color(z, m); } function makeHexGrid(size, phase) { this.ctx.clearRect(0, 0, 1050, 1500); var layout = Layout(layout_pointy, Point(size, size), Point(0, 0)); for (var row = 0; row <= 1500/size; row++) { for (var col = 0; col <= 1050/size; col++) { var hex = roffset_to_cube(EVEN, OffsetCoord(col, row)); var center = hex_to_pixel(layout, hex); var color = color_at_xy(center.x / 1050, center.y / 1500, phase); var polygon = polygon_corners(layout, hex); this.ctx.beginPath(); this.ctx.fillStyle = color.toString(); this.ctx.strokeStyle = color.toString(); this.ctx.moveTo(polygon[5].x, polygon[5].y); for (var j = 0; j < polygon.length; j++) { this.ctx.lineTo(polygon[j].x, polygon[j].y); } this.ctx.fill(); this.ctx.stroke(); } } } var frame = 0; function redraw() { makeHexGrid(15, frame/20); frame++; } redraw(); setInterval(redraw, 1000);