| 1 | use AppState; |
| 2 | use core::app::StateChange; |
| 3 | use core::controller::ControllerManager; |
| 4 | use core::level::{Level, LevelGenerator}; |
| 5 | use core::object::{Object, Objects, ObjectState}; |
| 6 | use core::object::character::Character; |
| 7 | use core::render::Renderer; |
| 8 | use sdl2::event::Event; |
| 9 | use sdl2::keyboard::Keycode; |
| 10 | use sprites::SpriteManager; |
| 11 | use teststate::TestState; |
| 12 | use time::Duration; |
| 13 | |
| 14 | ////////// GAMESTATE /////////////////////////////////////////////////////////// |
| 15 | |
| 16 | #[derive(Default)] |
| 17 | pub struct GameState { |
| 18 | world: World, |
| 19 | lvlgen: LevelGenerator, |
| 20 | debug_mode: bool, |
| 21 | } |
| 22 | |
| 23 | impl GameState { |
| 24 | pub fn new() -> Self { |
| 25 | let lvlgen = LevelGenerator::new(0); |
| 26 | GameState { |
| 27 | world: World::new(lvlgen.generate()), |
| 28 | lvlgen, |
| 29 | ..Default::default() |
| 30 | } |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | impl AppState for GameState { |
| 35 | fn enter(&mut self, ctrl_man: &ControllerManager) { |
| 36 | for (_k, v) in ctrl_man.controllers.iter() { |
| 37 | self.world.add(Box::new(Character::new(v.clone()))); |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | fn leave(&mut self) {} |
| 42 | |
| 43 | fn update(&mut self, dt: Duration) -> Option<StateChange> { |
| 44 | self.world.update(dt); |
| 45 | None |
| 46 | } |
| 47 | |
| 48 | fn render(&mut self, renderer: &mut Renderer, sprites: &SpriteManager) { |
| 49 | self.world.render(renderer, sprites, self.debug_mode); |
| 50 | } |
| 51 | |
| 52 | fn handle_event(&mut self, event: Event) -> Option<StateChange> { |
| 53 | match event { |
| 54 | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { |
| 55 | return Some(StateChange::Pop) |
| 56 | } |
| 57 | Event::KeyDown { keycode: Some(Keycode::Return), .. } => { |
| 58 | return Some(StateChange::Push(Box::new(TestState::new()))) |
| 59 | } |
| 60 | Event::KeyDown { keycode: Some(Keycode::KpEnter), .. } => { |
| 61 | self.debug_mode = !self.debug_mode; |
| 62 | } |
| 63 | Event::KeyDown { keycode: Some(Keycode::Space), .. } => { |
| 64 | self.lvlgen.seed = std::time::UNIX_EPOCH.elapsed().unwrap().as_secs() as u32; |
| 65 | self.world.level = self.lvlgen.generate(); |
| 66 | } |
| 67 | Event::KeyDown { keycode: Some(Keycode::KpPlus), .. } => { |
| 68 | self.lvlgen.iterations += 1; |
| 69 | self.world.level = self.lvlgen.generate(); |
| 70 | } |
| 71 | Event::KeyDown { keycode: Some(Keycode::KpMinus), .. } => { |
| 72 | if self.lvlgen.iterations > 0 { |
| 73 | self.lvlgen.iterations -= 1; |
| 74 | self.world.level = self.lvlgen.generate(); |
| 75 | } |
| 76 | } |
| 77 | Event::KeyDown { keycode: Some(Keycode::KpMultiply), .. } => { |
| 78 | self.lvlgen.wall_smooth_radius += 1; |
| 79 | self.world.level = self.lvlgen.generate(); |
| 80 | } |
| 81 | Event::KeyDown { keycode: Some(Keycode::KpDivide), .. } => { |
| 82 | if self.lvlgen.wall_smooth_radius > 0 { |
| 83 | self.lvlgen.wall_smooth_radius -= 1; |
| 84 | self.world.level = self.lvlgen.generate(); |
| 85 | } |
| 86 | } |
| 87 | _ => {} |
| 88 | } |
| 89 | None |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | ////////// WORLD /////////////////////////////////////////////////////////////// |
| 94 | |
| 95 | #[derive(Default)] |
| 96 | pub struct World { |
| 97 | level: Level, |
| 98 | objects: Objects, |
| 99 | } |
| 100 | |
| 101 | impl World { |
| 102 | pub fn new(level: Level) -> Self { |
| 103 | World { |
| 104 | level, |
| 105 | ..Default::default() |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | pub fn update(&mut self, dt: Duration) { |
| 110 | let mut breeding_ground = vec!(); |
| 111 | |
| 112 | for i in (0..self.objects.len()).rev() { |
| 113 | if self.objects[i].update(&mut breeding_ground, &self.level, dt) == ObjectState::Dead { |
| 114 | self.objects.remove(i); // swap_remove is more efficient, but changes the order of the array |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | for o in breeding_ground { |
| 119 | self.add(o); |
| 120 | } |
| 121 | |
| 122 | println!("\x1b[Kobject count: {}\x1b[1A", self.objects.len()); // clear line, print, move cursor up |
| 123 | } |
| 124 | |
| 125 | pub fn render(&mut self, renderer: &mut Renderer, sprites: &SpriteManager, debug_mode: bool) { |
| 126 | self.level.render(renderer, sprites, debug_mode); |
| 127 | for o in &mut self.objects { |
| 128 | o.render(renderer, sprites); |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | pub fn add(&mut self, object: Box<dyn Object>) { |
| 133 | self.objects.push(object); |
| 134 | } |
| 135 | } |