commit d19dbf96fd9ad0498235e5f08ac5a24c80a1dfc5 Author: Niko Abeler Date: Fri Dec 30 21:07:36 2022 +0100 can createa a map diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..130bb75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ + +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# debug output +world.png \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a7665da --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "tavern_keeper" +version = "0.1.0" +edition = "2021" + +[dependencies] +noise = { version = "0.8.2", features = ["images"] } +rand = "0.8.5" +image = "0.24.5" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..13a6d94 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,106 @@ +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(); + + + +} \ No newline at end of file