mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-25 16:28:42 -06:00
controls
This commit is contained in:
parent
2056170f34
commit
a91834a65c
86
src/game.rs
86
src/game.rs
|
@ -1,18 +1,34 @@
|
||||||
use glium::{Surface, uniform};
|
use glium::{Surface, uniform};
|
||||||
use glium::glutin::{
|
use glium::glutin::{
|
||||||
event::{Event, WindowEvent, VirtualKeyCode},
|
event::{Event, WindowEvent, DeviceEvent, VirtualKeyCode},
|
||||||
event_loop::{EventLoop, ControlFlow},
|
event_loop::{EventLoop, ControlFlow},
|
||||||
};
|
};
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
mod assets;
|
mod assets;
|
||||||
mod display;
|
mod display;
|
||||||
mod shaders;
|
mod shaders;
|
||||||
mod camera;
|
mod camera;
|
||||||
|
mod controller;
|
||||||
|
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
use display::init_display;
|
use display::init_display;
|
||||||
use shaders::{Programs, chunk::Vertex as ChunkVertex};
|
use shaders::{Programs, chunk::Vertex as ChunkVertex};
|
||||||
use camera::Camera;
|
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() {
|
pub fn run() {
|
||||||
log::info!("starting up");
|
log::info!("starting up");
|
||||||
|
@ -23,8 +39,8 @@ pub fn run() {
|
||||||
let programs = Programs::compile_all(&display);
|
let programs = Programs::compile_all(&display);
|
||||||
log::info!("loading assets");
|
log::info!("loading assets");
|
||||||
let assets = Assets::load_all_sync(&display);
|
let assets = Assets::load_all_sync(&display);
|
||||||
log::info!("init camera");
|
log::info!("init game state");
|
||||||
let mut camera = Camera::default();
|
let mut state = State::init();
|
||||||
log::info!("game loaded");
|
log::info!("game loaded");
|
||||||
|
|
||||||
//=======================
|
//=======================
|
||||||
|
@ -35,56 +51,42 @@ pub fn run() {
|
||||||
let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
|
let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
|
||||||
//=======================
|
//=======================
|
||||||
|
|
||||||
event_loop.run(move |ev, _, control_flow| {
|
let mut last_render = Instant::now();
|
||||||
#[allow(clippy::single_match, clippy::collapsible_match)]
|
|
||||||
match ev {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
Event::WindowEvent { event, .. } => match event {
|
*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 => {
|
WindowEvent::CloseRequested => {
|
||||||
log::info!("exit requested");
|
log::info!("exit requested");
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
WindowEvent::KeyboardInput { input, .. } => {
|
_ => return
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => ()
|
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => 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 mut target = display.draw();
|
||||||
let target_dimensions = target.get_dimensions();
|
let target_dimensions = target.get_dimensions();
|
||||||
camera.update_direction();
|
let perspective = state.camera.perspective_matrix(target_dimensions);
|
||||||
let perspective = camera.perspective_matrix(target_dimensions);
|
let view = state.camera.view_matrix();
|
||||||
let view = camera.view_matrix();
|
|
||||||
target.clear_color_and_depth((0.5, 0.5, 1., 1.), 1.);
|
target.clear_color_and_depth((0.5, 0.5, 1., 1.), 1.);
|
||||||
target.draw(
|
target.draw(
|
||||||
&vertex_buffer,
|
&vertex_buffer,
|
||||||
|
|
89
src/game/controller.rs
Normal file
89
src/game/controller.rs
Normal file
|
@ -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.,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,8 @@ use glium::glutin::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init_display(event_loop: &EventLoop<()>) -> Display {
|
pub fn init_display(event_loop: &EventLoop<()>) -> Display {
|
||||||
let wb = WindowBuilder::new();
|
let wb = WindowBuilder::new()
|
||||||
|
.with_maximized(true);
|
||||||
let cb = ContextBuilder::new()
|
let cb = ContextBuilder::new()
|
||||||
.with_depth_buffer(24)
|
.with_depth_buffer(24)
|
||||||
.with_gl_profile(GlProfile::Core);
|
.with_gl_profile(GlProfile::Core);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::io::Write;
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
let mut env = Env::default();
|
let mut env = Env::default();
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
env = env.filter_or("RUST_LOG", "info");
|
env = env.filter_or("RUST_LOG", "trace");
|
||||||
}
|
}
|
||||||
Builder::from_env(env)
|
Builder::from_env(env)
|
||||||
.format(|buf, record| {
|
.format(|buf, record| {
|
||||||
|
|
Loading…
Reference in a new issue