Moved out objects from game module
[kaka/rust-sdl-test.git] / src / core / game.rs
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 }