From 582b8bff6d33bd24ad2ea606c31b45d32bc06f4f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 16 Jan 2023 16:25:28 +0100 Subject: [PATCH] blocks, better camera --- Cargo.toml | 1 + src/game/blocks.rs | 29 ++++++++++++++++++--------- src/game/chunk.rs | 3 +++ src/game/controller.rs | 42 ++++++++++++++++++++++++--------------- src/game/shaders/chunk.rs | 4 ++-- src/game/world.rs | 5 ++++- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 377d3ff..cf4ba9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ glium = "0.32" image = { version = "0.24", default_features = false, features = ["png"] } log = "0.4" env_logger = "0.10" +strum = { version = "0.24", features = ["derive"] } diff --git a/src/game/blocks.rs b/src/game/blocks.rs index 34c662b..b5c0fa1 100644 --- a/src/game/blocks.rs +++ b/src/game/blocks.rs @@ -1,3 +1,4 @@ +use strum::{EnumIter, IntoEnumIterator}; use crate::game::items::Item; #[derive(Clone, Copy, Debug)] @@ -70,7 +71,7 @@ impl BlockDescriptor { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, EnumIter)] pub enum Block { Air, Stone, @@ -79,13 +80,16 @@ pub enum Block { Sand, } impl Block { - pub const fn get_by_id(id: &str) -> Option { - Some(match id { - "air" => Self::Air, - "stone" => Self::Stone, - _ => { return None }, - }) - } + //TODO make this O(1) with compile-time computed maps + pub fn get_by_id(id: &str) -> Option { + for block in Self::iter() { + if block.descriptor().id == id { + return Some(block) + } + } + None + } + pub const fn descriptor(self) -> BlockDescriptor { match self { Self::Air => BlockDescriptor { @@ -120,7 +124,14 @@ impl Block { render: Some((RenderType::OpaqueBlock, BlockTextures::top_sides_bottom(0, 3, 2))), item: Some(Item::DirtBlock) }, - _ => unimplemented!() + Self::Sand => BlockDescriptor { + name: "Sand", + id: "sand", + collision: Some(CollisionType::Solid), + raycast_collision: true, + render: Some((RenderType::OpaqueBlock, BlockTextures::all(4))), //this is not a sand tex + item: Some(Item::StoneBlock) + } } } } diff --git a/src/game/chunk.rs b/src/game/chunk.rs index b33a9ea..fdd49ea 100644 --- a/src/game/chunk.rs +++ b/src/game/chunk.rs @@ -1,3 +1,6 @@ +pub const CHUNK_SIZE: u8 = 16; +pub const CHUNK_HEIGHT: u8 = 255; + pub struct Chunk { } diff --git a/src/game/controller.rs b/src/game/controller.rs index 7a2a58c..7ba25d5 100644 --- a/src/game/controller.rs +++ b/src/game/controller.rs @@ -1,11 +1,12 @@ use glium::glutin::event::{VirtualKeyCode, ElementState}; +use std::f32::consts::PI; use crate::game::camera::Camera; #[derive(Default, Clone, Copy)] pub struct InputAmounts { - move_x: f32, - move_y: f32, - move_z: f32, + move_x: (f32, f32), + move_y: (f32, f32), + move_z: (f32, f32), look_h: f32, look_v: f32, } @@ -19,6 +20,7 @@ impl Actions { //Apply rotation camera.yaw -= self.rotation[0]; camera.pitch -= self.rotation[1]; + camera.pitch = camera.pitch.clamp(-PI/2. + f32::EPSILON, PI/2. - f32::EPSILON); camera.update_direction(); //Apply movement let (yaw_sin, yaw_cos) = camera.yaw.sin_cos(); @@ -51,39 +53,45 @@ impl Controls { self.inputs.look_v += dy as f32; } pub fn process_keyboard_input(&mut self, key: VirtualKeyCode, state: ElementState) { - if state != ElementState::Pressed { return } + let value = match state { + ElementState::Pressed => 1., + ElementState::Released => 0., + }; match key { VirtualKeyCode::W | VirtualKeyCode::Up => { - self.inputs.move_z += 1.; + self.inputs.move_z.0 = value; } VirtualKeyCode::S | VirtualKeyCode::Down => { - self.inputs.move_z -= 1.; + self.inputs.move_z.1 = -value; } VirtualKeyCode::A | VirtualKeyCode::Left => { - self.inputs.move_x -= 1.; + self.inputs.move_x.0 = -value; } VirtualKeyCode::D | VirtualKeyCode::Right => { - self.inputs.move_x += 1.; + self.inputs.move_x.1 = value; } VirtualKeyCode::Space => { - self.inputs.move_y += 1.; + self.inputs.move_y.0 = value; } VirtualKeyCode::LShift => { - self.inputs.move_y -= 1.; + self.inputs.move_y.1 = -value; } _ => () } } pub fn calculate(&mut self, dt: f32) -> Actions { let movement = { - let magnitude = (self.inputs.move_x.powi(2) + self.inputs.move_y.powi(2) + self.inputs.move_z.powi(2)).sqrt(); + let move_x = self.inputs.move_x.0 + self.inputs.move_x.1; + let move_y = self.inputs.move_y.0 + self.inputs.move_y.1; + let move_z = self.inputs.move_z.0 + self.inputs.move_z.1; + let magnitude = (move_x.powi(2) + move_y.powi(2) + move_z.powi(2)).sqrt(); if magnitude == 0. { [0., 0., 0.] } else { [ - dt * self.speed * (self.inputs.move_x / magnitude), - dt * self.speed * (self.inputs.move_y / magnitude), - dt * self.speed * (self.inputs.move_z / magnitude) + dt * self.speed * (move_x / magnitude), + dt * self.speed * (move_y / magnitude), + dt * self.speed * (move_z / magnitude) ] } }; @@ -91,7 +99,9 @@ impl Controls { dt * self.inputs.look_h * self.sensitivity, dt * self.inputs.look_v * self.sensitivity ]; - self.inputs = Default::default(); + //Only mouse related actions need to be reset + self.inputs.look_h = 0.; + self.inputs.look_v = 0.; Actions { movement, rotation } } } @@ -99,7 +109,7 @@ impl Default for Controls { fn default() -> Self { Self { inputs: Default::default(), - speed: 10., + speed: 1., sensitivity: 2., } } diff --git a/src/game/shaders/chunk.rs b/src/game/shaders/chunk.rs index 77f696f..c865391 100644 --- a/src/game/shaders/chunk.rs +++ b/src/game/shaders/chunk.rs @@ -10,7 +10,7 @@ implement_vertex!(Vertex, position, normal, uv); //TODO store vertex data in a more compact way pub const VERTEX_SHADER: &str = r#" - #version 150 + #version 150 core in vec3 position; in vec3 normal; @@ -29,7 +29,7 @@ pub const VERTEX_SHADER: &str = r#" } "#; pub const FRAGMENT_SHADER: &str = r#" - #version 150 + #version 150 core in vec2 v_uv; out vec4 color; diff --git a/src/game/world.rs b/src/game/world.rs index cc73959..ab3ce3b 100644 --- a/src/game/world.rs +++ b/src/game/world.rs @@ -1,3 +1,6 @@ +use std::collections::HashMap; +use crate::game::chunk::Chunk; + pub struct World { - chunks: Vec<()> + chunks: HashMap<(i32, i32), Chunk> }