tavern_keeper/src/main.rs

106 lines
3.0 KiB
Rust

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<f64, 2> 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::<u32>()))
.set_x_scale(0.04)
.set_y_scale(0.04),
ScalePoint::new(Perlin::new(rng.gen::<u32>()))
.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();
}