| 1 | use common::Point2D; |
| 2 | use core::render::Renderer; |
| 3 | use rand::Rng; |
| 4 | use sprites::SpriteManager; |
| 5 | |
| 6 | ////////// LEVEL /////////////////////////////////////////////////////////////// |
| 7 | |
| 8 | #[derive(Default)] |
| 9 | pub struct Level { |
| 10 | pub gravity: Point2D<f64>, |
| 11 | pub ground: f64, // just to have something |
| 12 | pub grid: Grid, |
| 13 | iterations: u8, |
| 14 | } |
| 15 | |
| 16 | impl Level { |
| 17 | pub fn new(gravity: Point2D<f64>, ground: f64) -> Self { |
| 18 | Level { gravity, ground, grid: Grid::generate(10), iterations: 10 } |
| 19 | } |
| 20 | |
| 21 | pub fn regenerate(&mut self) { |
| 22 | self.grid = Grid::generate(self.iterations); |
| 23 | } |
| 24 | |
| 25 | pub fn increase_iteration(&mut self) { |
| 26 | self.iterations += 1; |
| 27 | self.regenerate(); |
| 28 | println!("iterate {} time(s)", self.iterations); |
| 29 | } |
| 30 | |
| 31 | pub fn decrease_iteration(&mut self) { |
| 32 | self.iterations -= 1; |
| 33 | self.regenerate(); |
| 34 | println!("iterate {} time(s)", self.iterations); |
| 35 | } |
| 36 | |
| 37 | pub fn render(&mut self, renderer: &mut Renderer, _sprites: &SpriteManager) { |
| 38 | let w = renderer.viewport().0 as i32; |
| 39 | |
| 40 | renderer.canvas().set_draw_color((64, 64, 64)); |
| 41 | let size = self.grid.cell_size; |
| 42 | for x in 0..self.grid.width { |
| 43 | for y in 0..self.grid.height { |
| 44 | if self.grid.cells[x][y] { |
| 45 | renderer.canvas().fill_rect(sdl2::rect::Rect::new(x as i32 * size as i32, y as i32 * size as i32, size as u32, size as u32)).unwrap(); |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | for i in 1..11 { |
| 51 | let y = (i * i - 1) as i32 + self.ground as i32; |
| 52 | renderer.canvas().set_draw_color((255 - i * 20, 255 - i * 20, 0)); |
| 53 | renderer.canvas().draw_line((0, y), (w, y)).unwrap(); |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | ////////// GRID //////////////////////////////////////////////////////////////// |
| 59 | |
| 60 | #[derive(Default)] |
| 61 | pub struct Grid { |
| 62 | pub width: usize, |
| 63 | pub height: usize, |
| 64 | pub cell_size: usize, |
| 65 | pub cells: Vec<Vec<bool>>, |
| 66 | } |
| 67 | |
| 68 | impl Grid { |
| 69 | fn generate(iterations: u8) -> Grid { |
| 70 | let cell_size = 20; |
| 71 | let (width, height) = (2560 / cell_size, 1440 / cell_size); |
| 72 | |
| 73 | let mut grid = Grid { |
| 74 | cell_size, |
| 75 | width, |
| 76 | height, |
| 77 | cells: vec!(vec!(true; height); width), |
| 78 | }; |
| 79 | |
| 80 | // start with some noise |
| 81 | // grid.simplex_noise(); |
| 82 | grid.random_noise(); |
| 83 | |
| 84 | // smooth with cellular automata |
| 85 | grid.smooth(iterations); |
| 86 | // grid.smooth_until_equilibrium(); |
| 87 | |
| 88 | // increase resolution |
| 89 | for _i in 0..1 { |
| 90 | grid = grid.subdivide(); |
| 91 | grid.smooth(iterations); |
| 92 | } |
| 93 | |
| 94 | grid |
| 95 | } |
| 96 | |
| 97 | #[allow(dead_code)] |
| 98 | fn simplex_noise(&mut self) { |
| 99 | use noise::{NoiseFn, OpenSimplex, Seedable}; |
| 100 | let noise = OpenSimplex::new().set_seed(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs() as u32); |
| 101 | self.set_each(|x, y| noise.get([x as f64 / 12.0, y as f64 / 12.0]) > 0.055, 1); |
| 102 | } |
| 103 | |
| 104 | #[allow(dead_code)] |
| 105 | fn random_noise(&mut self) { |
| 106 | let mut rng = rand::thread_rng(); |
| 107 | self.set_each(|_x, _y| rng.gen_range(0, 100) > 55, 1); |
| 108 | } |
| 109 | |
| 110 | #[allow(dead_code)] |
| 111 | fn smooth(&mut self, iterations: u8) { |
| 112 | let distance = 1; |
| 113 | for _i in 0..iterations { |
| 114 | let mut next = vec!(vec!(true; self.height); self.width); |
| 115 | for x in distance..(self.width - distance) { |
| 116 | for y in distance..(self.height - distance) { |
| 117 | match Grid::neighbours(&self.cells, x, y, distance) { |
| 118 | n if n < 4 => next[x][y] = false, |
| 119 | n if n > 4 => next[x][y] = true, |
| 120 | _ => next[x][y] = self.cells[x][y] |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | if self.cells == next { |
| 125 | break; // exit early |
| 126 | } else { |
| 127 | self.cells = next; |
| 128 | } |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | #[allow(dead_code)] |
| 133 | fn smooth_until_equilibrium(&mut self) { |
| 134 | let distance = 1; |
| 135 | let mut count = 0; |
| 136 | loop { |
| 137 | count += 1; |
| 138 | let mut next = vec!(vec!(true; self.height); self.width); |
| 139 | for x in distance..(self.width - distance) { |
| 140 | for y in distance..(self.height - distance) { |
| 141 | match Grid::neighbours(&self.cells, x, y, distance) { |
| 142 | n if n < 4 => next[x][y] = false, |
| 143 | n if n > 4 => next[x][y] = true, |
| 144 | _ => next[x][y] = self.cells[x][y] |
| 145 | }; |
| 146 | } |
| 147 | } |
| 148 | if self.cells == next { |
| 149 | break; |
| 150 | } else { |
| 151 | self.cells = next; |
| 152 | } |
| 153 | } |
| 154 | println!("{} iterations needed", count); |
| 155 | } |
| 156 | |
| 157 | fn neighbours(grid: &Vec<Vec<bool>>, px: usize, py: usize, distance: usize) -> u8 { |
| 158 | let mut count = 0; |
| 159 | for x in (px - distance)..=(px + distance) { |
| 160 | for y in (py - distance)..=(py + distance) { |
| 161 | if !(x == px && y == py) && grid[x][y] { |
| 162 | count += 1; |
| 163 | } |
| 164 | } |
| 165 | } |
| 166 | count |
| 167 | } |
| 168 | |
| 169 | fn set_each<F: FnMut(usize, usize) -> bool>(&mut self, mut func: F, walls: usize) { |
| 170 | for x in walls..(self.width - walls) { |
| 171 | for y in walls..(self.height - walls) { |
| 172 | self.cells[x][y] = func(x, y); |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | fn subdivide(&mut self) -> Grid { |
| 178 | let (width, height) = (self.width * 2, self.height * 2); |
| 179 | let mut cells = vec!(vec!(true; height); width); |
| 180 | for x in 1..(width - 1) { |
| 181 | for y in 1..(height - 1) { |
| 182 | cells[x][y] = self.cells[x / 2][y / 2]; |
| 183 | } |
| 184 | } |
| 185 | Grid { |
| 186 | cell_size: self.cell_size / 2, |
| 187 | width, |
| 188 | height, |
| 189 | cells |
| 190 | } |
| 191 | } |
| 192 | } |