use noise::{Perlin, ScalePoint, Add, NoiseFn, Multiply, ScaleBias}; use noise::utils::{NoiseMapBuilder, PlaneMapBuilder}; use image::{RgbImage, Rgb}; use rand::prelude::*; struct BorderNoise { pub center: [f64; 2], pub radius: f64, pub falloff: f64, } impl BorderNoise { pub fn new(center: [f64; 2], radius: f64, falloff: f64) -> BorderNoise { BorderNoise { center: center, radius: radius, falloff: falloff } } } impl NoiseFn for BorderNoise { fn get(&self, _point: [f64; 2]) -> f64 { let dist = ( (self.center[0] - _point[0]).powi(2) + (self.center[1] - _point[1]).powi(2) ).sqrt(); if dist > self.radius { 1.0 - ((dist - self.radius) * self.falloff) } else { 1.0 } } } fn main() { let mut rng = rand::thread_rng(); let map_size = 256; let map_center = map_size / 2; let height = Add::new( ScaleBias::new( Add::new( ScalePoint::new(Perlin::new(rng.gen::())) .set_x_scale(0.04) .set_y_scale(0.04), ScalePoint::new(Perlin::new(rng.gen::())) .set_x_scale(0.011) .set_y_scale(0.011), ), ).set_scale(2000.0).set_bias(1000.0), BorderNoise::new( [map_center as f64, map_center as f64], map_size as f64 * 0.4, 100.0 ), ); let plane = PlaneMapBuilder::<_, 2>::new(&height) .set_size(map_size, map_size) .set_x_bounds(0.0, map_size as f64) .set_y_bounds(0.0, map_size as f64) .build(); let min = plane.iter().fold(f64::MAX, |min, &val| val.min(min)); let max = plane.iter().fold(f64::MIN, |max, &val| val.max(max)); println!("Min: {}", min); println!("Max: {}", max); let mut img = RgbImage::new(map_size as u32, map_size as u32); for x in 0..map_size { for y in 0..map_size { let h = plane.get_value(x, y); if h < -2000.0 { // deep ocean img.put_pixel(x as u32, y as u32, Rgb([20, 60, 255])); } else if h < 0.0 { // ocean img.put_pixel(x as u32, y as u32, Rgb([20, 120, 255])); } else if h < 10.0 { // beach img.put_pixel(x as u32, y as u32, Rgb([255, 255, 100])); } else if h < 1000.0 { // grass img.put_pixel(x as u32, y as u32, Rgb([0, 204, 0])); } else if h < 2000.0 { // hills img.put_pixel(x as u32, y as u32, Rgb([102, 153, 0])); } else if h < 3500.0 { // mountains img.put_pixel(x as u32, y as u32, Rgb([153, 153, 102])); } else { // snow img.put_pixel(x as u32, y as u32, Rgb([230, 230, 230])); } } } img.save("world.png").unwrap(); }