diff --git a/src/game.rs b/src/game.rs index 8059892..4469405 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,18 +1,34 @@ use glium::{Surface, uniform}; use glium::glutin::{ - event::{Event, WindowEvent, VirtualKeyCode}, + event::{Event, WindowEvent, DeviceEvent, VirtualKeyCode}, event_loop::{EventLoop, ControlFlow}, }; +use std::time::Instant; mod assets; mod display; mod shaders; mod camera; +mod controller; use assets::Assets; use display::init_display; use shaders::{Programs, chunk::Vertex as ChunkVertex}; use camera::Camera; +use controller::Controls; + +struct State { + pub camera: Camera, + pub controls: Controls, +} +impl State { + pub fn init() -> Self { + Self { + camera: Camera::default(), + controls: Controls::default(), + } + } +} pub fn run() { log::info!("starting up"); @@ -23,8 +39,8 @@ pub fn run() { let programs = Programs::compile_all(&display); log::info!("loading assets"); let assets = Assets::load_all_sync(&display); - log::info!("init camera"); - let mut camera = Camera::default(); + log::info!("init game state"); + let mut state = State::init(); log::info!("game loaded"); //======================= @@ -35,56 +51,42 @@ pub fn run() { let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); //======================= - event_loop.run(move |ev, _, control_flow| { - #[allow(clippy::single_match, clippy::collapsible_match)] - match ev { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => { - log::info!("exit requested"); - *control_flow = ControlFlow::Exit; - return - }, - WindowEvent::KeyboardInput { input, .. } => { - match input.virtual_keycode { - Some(VirtualKeyCode::Up) => { - camera.pitch += 0.01; - } - Some(VirtualKeyCode::Down) => { - camera.pitch -= 0.01; - } - Some(VirtualKeyCode::Right) => { - camera.yaw -= 0.01; - } - Some(VirtualKeyCode::Left) => { - camera.yaw += 0.01; - } - - Some(VirtualKeyCode::W) => { - camera.position[2] += 0.01; - } - Some(VirtualKeyCode::S) => { - camera.position[2] -= 0.01; - } - Some(VirtualKeyCode::A) => { - camera.position[0] -= 0.01; - } - Some(VirtualKeyCode::D) => { - camera.position[0] += 0.01; - } + let mut last_render = Instant::now(); - _ => () - } + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Poll; + match event { + Event::MainEventsCleared => (), + Event::DeviceEvent { + event: DeviceEvent::MouseMotion{ delta, }, + .. + } => { + state.controls.process_mouse_input(delta.0, delta.1); + } + Event::WindowEvent { event, .. } => { + match event { + WindowEvent::CloseRequested => { + log::info!("exit requested"); + *control_flow = ControlFlow::Exit; + return + }, + _ => return } - _ => () }, - _ => () + _ => return } + + let now = Instant::now(); + let dt = (now - last_render).as_secs_f32(); + last_render = now; + + let actions = state.controls.calculate(dt); + actions.apply_to_camera(&mut state.camera); let mut target = display.draw(); let target_dimensions = target.get_dimensions(); - camera.update_direction(); - let perspective = camera.perspective_matrix(target_dimensions); - let view = camera.view_matrix(); + let perspective = state.camera.perspective_matrix(target_dimensions); + let view = state.camera.view_matrix(); target.clear_color_and_depth((0.5, 0.5, 1., 1.), 1.); target.draw( &vertex_buffer, diff --git a/src/game/controller.rs b/src/game/controller.rs new file mode 100644 index 0000000..299ce19 --- /dev/null +++ b/src/game/controller.rs @@ -0,0 +1,89 @@ +use glium::glutin::event::{VirtualKeyCode, ElementState}; +use crate::game::camera::Camera; + +#[derive(Default, Clone, Copy)] +pub struct InputAmounts { + move_x: f32, + move_y: f32, + move_z: f32, + look_h: f32, + look_v: f32, +} + +pub struct Actions { + movement: [f32; 3], + rotation: [f32; 2], +} +impl Actions { + pub fn apply_to_camera(&self, camera: &mut Camera) { + //Apply movement + for v in camera.position.iter_mut().zip(self.movement) { + *v.0 += v.1; + } + //Apply rotation + camera.yaw += self.rotation[0]; + camera.pitch += self.rotation[1]; + camera.update_direction(); + } +} + +pub struct Controls { + inputs: InputAmounts, + pub speed: f32, + pub sensitivity: f32, +} +impl Controls { + pub fn process_mouse_input(&mut self, dx: f64, dy: f64) { + self.inputs.look_h += dx as f32; + self.inputs.look_v += dy as f32; + } + pub fn process_keyboard_input(&mut self, key: VirtualKeyCode, state: ElementState) { + if state != ElementState::Pressed { return } + match key { + VirtualKeyCode::W | VirtualKeyCode::Up => { + self.inputs.move_z += 1.; + } + VirtualKeyCode::S | VirtualKeyCode::Down => { + self.inputs.move_z -= 1.; + } + VirtualKeyCode::A | VirtualKeyCode::Left => { + self.inputs.move_x -= 1.; + } + VirtualKeyCode::D | VirtualKeyCode::Right => { + self.inputs.move_x += 1.; + } + VirtualKeyCode::Space => { + self.inputs.move_y += 1.; + } + VirtualKeyCode::LShift => { + self.inputs.move_y -= 1.; + } + _ => () + } + } + pub fn calculate(&mut self, dt: f32) -> Actions { + let mut movement = { + let magnitude = (self.inputs.move_x.powi(2) + self.inputs.move_y.powi(2) + self.inputs.move_z.powi(2)).sqrt(); + [ + dt * self.speed * (self.inputs.move_x / magnitude), + dt * self.speed * (self.inputs.move_y / magnitude), + dt * self.speed * (self.inputs.move_z / magnitude) + ] + }; + let rotation = [ + dt * self.inputs.look_h * self.sensitivity, + dt * self.inputs.look_v * self.sensitivity + ]; + self.inputs = Default::default(); + Actions { movement, rotation } + } +} +impl Default for Controls { + fn default() -> Self { + Self { + inputs: Default::default(), + speed: 1., + sensitivity: 1., + } + } +} diff --git a/src/game/display.rs b/src/game/display.rs index d57e139..97d7e02 100644 --- a/src/game/display.rs +++ b/src/game/display.rs @@ -7,7 +7,8 @@ use glium::glutin::{ }; pub fn init_display(event_loop: &EventLoop<()>) -> Display { - let wb = WindowBuilder::new(); + let wb = WindowBuilder::new() + .with_maximized(true); let cb = ContextBuilder::new() .with_depth_buffer(24) .with_gl_profile(GlProfile::Core); diff --git a/src/logging.rs b/src/logging.rs index 18f67d9..013b4e9 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -7,7 +7,7 @@ use std::io::Write; pub fn init() { let mut env = Env::default(); if cfg!(debug_assertions) { - env = env.filter_or("RUST_LOG", "info"); + env = env.filter_or("RUST_LOG", "trace"); } Builder::from_env(env) .format(|buf, record| {