|
| 1 | +use crate::object::{Object, ObjectPool}; |
| 2 | +use crate::physics::PhysicsHandler; |
| 3 | +use crate::renderer::Renderer; |
| 4 | +use crate::screen::*; |
| 5 | +use macroquad::prelude::*; |
| 6 | + |
| 7 | +pub struct ControlHandler { |
| 8 | + move_speed: f32, |
| 9 | + scale_speed: f32, |
| 10 | + place_elevation: f32, |
| 11 | + control_state: ControlState, |
| 12 | + ghost_obj: Option<Object>, |
| 13 | +} |
| 14 | + |
| 15 | +impl ControlHandler { |
| 16 | + fn new(move_speed: f32, scale_speed: f32) -> Self { |
| 17 | + ControlHandler { |
| 18 | + move_speed, |
| 19 | + scale_speed, |
| 20 | + place_elevation: 0.0, |
| 21 | + control_state: ControlState::Idle, |
| 22 | + ghost_obj: None, |
| 23 | + } |
| 24 | + } |
| 25 | + |
| 26 | + pub fn handle_input( |
| 27 | + &mut self, |
| 28 | + renderer: &mut Renderer, |
| 29 | + objects: &mut ObjectPool, |
| 30 | + physics_handler: &PhysicsHandler, |
| 31 | + dt: f32, |
| 32 | + ) { |
| 33 | + self.handle_movement(renderer, dt); |
| 34 | + self.handle_ghost_obj(dt); |
| 35 | + |
| 36 | + self.control_state = match self.control_state { |
| 37 | + ControlState::Idle => self.handle_idle(renderer, objects), |
| 38 | + ControlState::Place => self.handle_place(renderer), |
| 39 | + ControlState::Drag => self.handle_drag(renderer, physics_handler, objects), |
| 40 | + }; |
| 41 | + } |
| 42 | + |
| 43 | + fn handle_idle(&mut self, renderer: &mut Renderer, objects: &mut ObjectPool) -> ControlState { |
| 44 | + if let Some(obj) = self.get_hovered_obj(renderer, objects) { |
| 45 | + let color = Color { |
| 46 | + a: 0.2, |
| 47 | + ..obj.color |
| 48 | + }; |
| 49 | + |
| 50 | + renderer.draw_halo(obj.position, obj.radius * 1.1, Some(color)); |
| 51 | + } |
| 52 | + |
| 53 | + if is_key_released(KeyCode::R) { |
| 54 | + if let Some(obj) = self.get_hovered_obj(renderer, objects) { |
| 55 | + objects.remove(obj.id); |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + if is_mouse_button_released(MouseButton::Left) { |
| 60 | + return ControlState::Place; |
| 61 | + } |
| 62 | + |
| 63 | + ControlState::Idle |
| 64 | + } |
| 65 | + |
| 66 | + fn handle_place(&mut self, renderer: &mut Renderer) -> ControlState { |
| 67 | + if self.ghost_obj.is_none() { |
| 68 | + self.ghost_obj = Some(Object::new( |
| 69 | + Vec3::ZERO, |
| 70 | + Vec3::ZERO, |
| 71 | + 1.0, |
| 72 | + 1.0, |
| 73 | + Self::random_color(), |
| 74 | + )); |
| 75 | + } |
| 76 | + |
| 77 | + let ray = Ray::new_from_mouse(renderer.get_cam()); |
| 78 | + |
| 79 | + if let Some(obj) = &mut self.ghost_obj { |
| 80 | + obj.position = ray.plane_intersect(Some(self.place_elevation)); |
| 81 | + obj.draw(renderer); |
| 82 | + } |
| 83 | + |
| 84 | + if is_mouse_button_released(MouseButton::Left) { |
| 85 | + return ControlState::Drag; |
| 86 | + } |
| 87 | + |
| 88 | + if is_key_released(KeyCode::Escape) { |
| 89 | + self.ghost_obj = None; |
| 90 | + return ControlState::Idle; |
| 91 | + } |
| 92 | + |
| 93 | + ControlState::Place |
| 94 | + } |
| 95 | + |
| 96 | + fn handle_drag( |
| 97 | + &mut self, |
| 98 | + renderer: &mut Renderer, |
| 99 | + physics_handler: &PhysicsHandler, |
| 100 | + objects: &mut ObjectPool, |
| 101 | + ) -> ControlState { |
| 102 | + let ray = Ray::new_from_mouse(renderer.get_cam()); |
| 103 | + |
| 104 | + if let Some(obj) = &mut self.ghost_obj { |
| 105 | + renderer.draw_arrow( |
| 106 | + obj.position, |
| 107 | + ray.plane_intersect(Some(self.place_elevation)), |
| 108 | + Some(obj.color), |
| 109 | + ); |
| 110 | + |
| 111 | + let veloc = (ray.plane_intersect(Some(self.place_elevation)) - obj.position) / 100.0; |
| 112 | + |
| 113 | + let virtual_obj: Object = obj.clone().add_velocity(veloc).clone(); |
| 114 | + virtual_obj.draw_path(objects, renderer, physics_handler, 5000, 10); |
| 115 | + |
| 116 | + // let mut clones = objects.clone(); |
| 117 | + // clones.push(virtual_obj.clone()); |
| 118 | + |
| 119 | + // for obj in clones.iter() { |
| 120 | + // obj.draw_path(&clones, renderer, physics_handler, 5000, 10); |
| 121 | + // } |
| 122 | + |
| 123 | + obj.draw(renderer); |
| 124 | + } |
| 125 | + |
| 126 | + if is_mouse_button_released(MouseButton::Left) { |
| 127 | + if let Some(obj) = &mut self.ghost_obj { |
| 128 | + let veloc = |
| 129 | + (ray.plane_intersect(Some(self.place_elevation)) - obj.position) / 100.0; |
| 130 | + obj.add_velocity(veloc); |
| 131 | + objects.push(obj.clone()); |
| 132 | + self.ghost_obj = None; |
| 133 | + } |
| 134 | + |
| 135 | + return ControlState::Idle; |
| 136 | + } |
| 137 | + |
| 138 | + if is_key_released(KeyCode::Escape) { |
| 139 | + self.ghost_obj = None; |
| 140 | + return ControlState::Idle; |
| 141 | + } |
| 142 | + |
| 143 | + ControlState::Drag |
| 144 | + } |
| 145 | + |
| 146 | + fn handle_movement(&mut self, renderer: &mut Renderer, dt: f32) { |
| 147 | + renderer.move_cam(self.get_input_dir() * self.move_speed * dt); |
| 148 | + } |
| 149 | + |
| 150 | + fn handle_ghost_obj(&mut self, dt: f32) { |
| 151 | + if let Some(obj) = &mut self.ghost_obj { |
| 152 | + if is_key_down(KeyCode::Up) { |
| 153 | + obj.mass += self.scale_speed * dt; |
| 154 | + obj.radius += self.scale_speed * dt; |
| 155 | + } |
| 156 | + if is_key_down(KeyCode::Down) { |
| 157 | + obj.mass -= self.scale_speed * dt; |
| 158 | + obj.radius -= self.scale_speed * dt; |
| 159 | + } |
| 160 | + |
| 161 | + if is_key_down(KeyCode::E) { |
| 162 | + self.place_elevation += self.move_speed * dt; |
| 163 | + } |
| 164 | + if is_key_down(KeyCode::Q) { |
| 165 | + self.place_elevation -= self.move_speed * dt; |
| 166 | + } |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + fn get_input_dir(&self) -> Vec3 { |
| 171 | + let mut dir = Vec3::ZERO; |
| 172 | + |
| 173 | + if is_key_down(KeyCode::W) { |
| 174 | + dir.z += 1.0; |
| 175 | + } |
| 176 | + if is_key_down(KeyCode::S) { |
| 177 | + dir.z -= 1.0; |
| 178 | + } |
| 179 | + if is_key_down(KeyCode::D) { |
| 180 | + dir.x += 1.0; |
| 181 | + } |
| 182 | + if is_key_down(KeyCode::A) { |
| 183 | + dir.x -= 1.0; |
| 184 | + } |
| 185 | + if is_key_down(KeyCode::LeftShift) { |
| 186 | + dir.y += 1.0; |
| 187 | + } |
| 188 | + if is_key_down(KeyCode::LeftControl) { |
| 189 | + dir.y -= 1.0; |
| 190 | + } |
| 191 | + |
| 192 | + dir |
| 193 | + } |
| 194 | + |
| 195 | + fn get_hovered_obj(&mut self, renderer: &mut Renderer, objects: &ObjectPool) -> Option<Object> { |
| 196 | + let ray = Ray::new_from_mouse(renderer.get_cam()); |
| 197 | + for obj in objects.iter() { |
| 198 | + if !ray.raycast(obj.position, obj.radius) { |
| 199 | + continue; |
| 200 | + } |
| 201 | + |
| 202 | + return Some(obj.clone()); |
| 203 | + } |
| 204 | + |
| 205 | + None |
| 206 | + } |
| 207 | + |
| 208 | + fn random_color() -> Color { |
| 209 | + Color { |
| 210 | + r: rand::gen_range(0.0, 1.0), |
| 211 | + g: rand::gen_range(0.0, 1.0), |
| 212 | + b: rand::gen_range(0.0, 1.0), |
| 213 | + a: 1.0, |
| 214 | + } |
| 215 | + } |
| 216 | +} |
| 217 | + |
| 218 | +impl Default for ControlHandler { |
| 219 | + fn default() -> Self { |
| 220 | + ControlHandler::new(20.0, 5.0) |
| 221 | + } |
| 222 | +} |
| 223 | + |
| 224 | +#[derive(Debug, PartialEq)] |
| 225 | +enum ControlState { |
| 226 | + Idle, |
| 227 | + Place, |
| 228 | + Drag, |
| 229 | +} |
0 commit comments