use AppState; use core::app::StateChange; use core::controller::ControllerManager; use core::level::{Level, LevelGenerator}; use core::object::{Object, Objects, ObjectState}; use core::object::character::Character; use core::render::Renderer; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sprites::SpriteManager; use teststate::TestState; use time::Duration; ////////// GAMESTATE /////////////////////////////////////////////////////////// #[derive(Default)] pub struct GameState { world: World, lvlgen: LevelGenerator, debug_mode: bool, } impl GameState { pub fn new() -> Self { let lvlgen = LevelGenerator::new(0); GameState { world: World::new(lvlgen.generate()), lvlgen, ..Default::default() } } } impl AppState for GameState { fn enter(&mut self, ctrl_man: &ControllerManager) { for (_k, v) in ctrl_man.controllers.iter() { self.world.add(Box::new(Character::new(v.clone()))); } } fn leave(&mut self) {} fn update(&mut self, dt: Duration) -> Option { self.world.update(dt); None } fn render(&mut self, renderer: &mut Renderer, sprites: &SpriteManager) { self.world.render(renderer, sprites, self.debug_mode); } fn handle_event(&mut self, event: Event) -> Option { match event { Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { return Some(StateChange::Pop) } Event::KeyDown { keycode: Some(Keycode::Return), .. } => { return Some(StateChange::Push(Box::new(TestState::new()))) } Event::KeyDown { keycode: Some(Keycode::KpEnter), .. } => { self.debug_mode = !self.debug_mode; } Event::KeyDown { keycode: Some(Keycode::Space), .. } => { self.lvlgen.seed = std::time::UNIX_EPOCH.elapsed().unwrap().as_secs() as u32; self.world.level = self.lvlgen.generate(); } Event::KeyDown { keycode: Some(Keycode::KpPlus), .. } => { self.lvlgen.iterations += 1; self.world.level = self.lvlgen.generate(); } Event::KeyDown { keycode: Some(Keycode::KpMinus), .. } => { if self.lvlgen.iterations > 0 { self.lvlgen.iterations -= 1; self.world.level = self.lvlgen.generate(); } } Event::KeyDown { keycode: Some(Keycode::KpMultiply), .. } => { self.lvlgen.wall_smooth_radius += 1; self.world.level = self.lvlgen.generate(); } Event::KeyDown { keycode: Some(Keycode::KpDivide), .. } => { if self.lvlgen.wall_smooth_radius > 0 { self.lvlgen.wall_smooth_radius -= 1; self.world.level = self.lvlgen.generate(); } } _ => {} } None } } ////////// WORLD /////////////////////////////////////////////////////////////// #[derive(Default)] pub struct World { level: Level, objects: Objects, } impl World { pub fn new(level: Level) -> Self { World { level, ..Default::default() } } pub fn update(&mut self, dt: Duration) { let mut breeding_ground = vec!(); for i in (0..self.objects.len()).rev() { if self.objects[i].update(&mut breeding_ground, &self.level, dt) == ObjectState::Dead { self.objects.remove(i); // swap_remove is more efficient, but changes the order of the array } } for o in breeding_ground { self.add(o); } println!("\x1b[Kobject count: {}\x1b[1A", self.objects.len()); // clear line, print, move cursor up } pub fn render(&mut self, renderer: &mut Renderer, sprites: &SpriteManager, debug_mode: bool) { self.level.render(renderer, sprites, debug_mode); for o in &mut self.objects { o.render(renderer, sprites); } } pub fn add(&mut self, object: Box) { self.objects.push(object); } }