use std::{ process, thread, time::{Duration, Instant}, }; use sdl2::{ event::{Event, WindowEvent}, keyboard::Keycode, }; pub mod chunk; use crate::{Game, InWorld, RenderAvailable, input::InputHandler, vector::Vector3}; #[derive(Debug, Default)] pub struct Camera { pub origin: Vector3, pub rotation: Vector3, } impl Game { /// The main gameloop, this will exit the program is the game is requested to close, /// or return to the [`RenderAvailable`] state if the world is closed and we want to /// return to a menu. pub fn main_loop(mut self) -> Game { println!("Starting main loop"); let mut event_pump = self .state .sdl_context .event_pump() .expect("Failed to get event pump"); let mouse = self.state.sdl_context.mouse(); mouse.set_relative_mouse_mode(true); let mut running = true; while running { let now = Instant::now(); for event in event_pump.poll_iter() { match event { // Setting running to false just returns to // RenderAvailable state (and then main menu) Event::Quit { .. } => process::exit(0), Event::Window { win_event: WindowEvent::Resized(w, h), .. } => { self.window_resize((w as u32, h as u32)); } Event::KeyDown { keycode: Some(keycode), keymod, repeat, .. } => self.handle_keydown(keycode, keymod, repeat), Event::KeyUp { keycode: Some(keycode), keymod, repeat, .. } => self.handle_keyup(keycode, keymod, repeat), Event::MouseMotion { mousestate, x, y, xrel, yrel, .. } => self.handle_mouse_motion(mousestate, (x, y), (xrel, yrel)), _ => {} } } event_pump .keyboard_state() .pressed_scancodes() .filter_map(Keycode::from_scancode) .for_each(|k| self.handle_cont_key(k)); self.render_frame(); let elapsed = now.elapsed(); let delay = (1_000_000u128 / 60).saturating_sub(elapsed.as_micros()); thread::sleep(Duration::from_micros(delay as u64)); } Game { state: RenderAvailable { sdl_context: self.state.sdl_context, window: self.state.window, ctx: self.state.ctx, }, } } }