diff --git a/Cargo.lock b/Cargo.lock index 6d0f398..ee9585f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1172,8 +1172,7 @@ dependencies = [ [[package]] name = "bevy_voxel_world" version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e49c4ac63eb3216955222643de7d60098f2863f43d8311b6167a81fdeaa17c8d" +source = "git+https://github.com/splashdust/bevy_voxel_world.git?rev=115bd34#115bd34b058b737df35a4bfef83ba45b89c25d17" dependencies = [ "bevy", "block-mesh", diff --git a/Cargo.toml b/Cargo.toml index 49cedc5..32fb00e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ webbrowser = { version = "0.8", features = ["hardened"] } # keep the following in sync with Bevy's dependencies winit = { version = "0.28.7", default-features = false } image = { version = "0.24", default-features = false } -bevy_voxel_world = "0.3.3" +bevy_voxel_world = {git = "https://github.com/splashdust/bevy_voxel_world.git", rev = "115bd34"} # "0.3.3" noise = "0.8.2" lazy_static = "1.4.0" strum = "0.25.0" diff --git a/credits/CREDITS.md b/credits/CREDITS.md index 6a9e73c..5fec704 100644 --- a/credits/CREDITS.md +++ b/credits/CREDITS.md @@ -18,5 +18,6 @@ * Game [project template](https://github.com/NiklasEi/bevy_game_template) - Nikl (`@nikl_me@mastodon.online`) * Voxel World Plugin ([bevy_voxel_world](https://github.com/splashdust/bevy_voxel_world)) - `splashdust` (Joacim Magnusson) +* [bevy_fly_camera](https://github.com/mcpar-land/bevy_fly_camera) - modified and used in codebase (MIT license). * [Bevy](https://bevyengine.org/) - The Bevy Team! * The Rust programming language diff --git a/src/actions/game_control.rs b/src/actions/game_control.rs deleted file mode 100644 index bc74325..0000000 --- a/src/actions/game_control.rs +++ /dev/null @@ -1,51 +0,0 @@ -use bevy::prelude::{Input, KeyCode, MouseButton, Res}; - -pub enum GameControl { - Up, - Down, - Left, - Right, - Space, - C, - ClickTarget, - OpenMenu, -} - -impl GameControl { - pub fn pressed( - &self, - keyboard_input: &Res>, - mouse_input: &Res>, - ) -> bool { - match self { - GameControl::Up => { - keyboard_input.pressed(KeyCode::W) || keyboard_input.pressed(KeyCode::Up) - } - GameControl::Down => { - keyboard_input.pressed(KeyCode::S) || keyboard_input.pressed(KeyCode::Down) - } - GameControl::Left => { - keyboard_input.pressed(KeyCode::A) || keyboard_input.pressed(KeyCode::Left) - } - GameControl::Right => { - keyboard_input.pressed(KeyCode::D) || keyboard_input.pressed(KeyCode::Right) - } - GameControl::Space => keyboard_input.pressed(KeyCode::Space), - GameControl::C => keyboard_input.pressed(KeyCode::C), - GameControl::ClickTarget => mouse_input.pressed(MouseButton::Left), - GameControl::OpenMenu => keyboard_input.pressed(KeyCode::Escape), - } - } -} - -pub fn get_movement( - control: GameControl, - key_input: &Res>, - mouse_input: &Res>, -) -> f32 { - if control.pressed(key_input, mouse_input) { - 1.0 - } else { - 0.0 - } -} diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 48daf5d..e4f3aa7 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,10 +1,8 @@ use bevy::prelude::*; -use crate::actions::game_control::{get_movement, GameControl}; +use crate::game_control::{GameControl, MovementControl}; use crate::GameState; -mod game_control; - //pub const FOLLOW_EPSILON: f32 = 5.; pub struct ActionsPlugin; @@ -22,7 +20,7 @@ impl Plugin for ActionsPlugin { #[derive(Default, Resource)] pub struct Actions { - pub player_movement: Option, + pub player_movement: Vec, pub left_click_crosshair: bool, pub open_menu: bool, } @@ -35,14 +33,18 @@ pub fn set_playing_actions( //player: Query<&Transform, With>, //camera: Query<(&Camera, &GlobalTransform), With>, ) { - let player_movement = Vec3::new( - get_movement(GameControl::Right, &keyboard_input, &mouse_input) - - get_movement(GameControl::Left, &keyboard_input, &mouse_input), - get_movement(GameControl::Space, &keyboard_input, &mouse_input) - - get_movement(GameControl::C, &keyboard_input, &mouse_input), - get_movement(GameControl::Up, &keyboard_input, &mouse_input) - - get_movement(GameControl::Down, &keyboard_input, &mouse_input), - ); + let game_controls_from_keys: Vec = keyboard_input + .get_pressed() + .filter_map(|key_code| GameControl::from_key_code(*key_code)) + .collect(); + let game_controls_from_mouse: Vec = mouse_input + .get_pressed() + .filter_map(|mouse_button| GameControl::from_mouse_button(*mouse_button)) + .collect(); + actions.player_movement = game_controls_from_keys + .iter() + .filter_map(|key_code| GameControl::movement_control(key_code.clone())) + .collect(); /*if let Some(touch_position) = touch_input.first_pressed_position() { let (camera, camera_transform) = camera.single(); @@ -54,13 +56,11 @@ pub fn set_playing_actions( } } }*/ + actions.left_click_crosshair = game_controls_from_mouse + .iter() + .any(|x| *x == GameControl::ClickTarget); - if player_movement != Vec3::ZERO { - actions.player_movement = Some(player_movement.normalize()); - } else { - actions.player_movement = None; - } - - actions.left_click_crosshair = GameControl::ClickTarget.pressed(&keyboard_input, &mouse_input); - actions.open_menu = GameControl::OpenMenu.pressed(&keyboard_input, &mouse_input); + actions.open_menu = game_controls_from_keys + .iter() + .any(|x| *x == GameControl::OpenMenu); } diff --git a/src/audio.rs b/src/audio.rs index 5fdad16..11aed55 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -41,12 +41,12 @@ fn control_flying_sound( if let Some(instance) = audio_instances.get_mut(&audio.0) { match instance.state() { PlaybackState::Paused { .. } => { - if actions.player_movement.is_some() { + if !actions.player_movement.is_empty() { instance.resume(AudioTween::default()); } } PlaybackState::Playing { .. } => { - if actions.player_movement.is_none() { + if actions.player_movement.is_empty() { instance.pause(AudioTween::default()); } } diff --git a/src/camera_handler.rs b/src/camera_handler.rs index 7b004b9..4c641a1 100644 --- a/src/camera_handler.rs +++ b/src/camera_handler.rs @@ -1,8 +1,9 @@ +use crate::actions::*; +use crate::game_control::*; +use crate::player::Player; +use crate::GameState; use bevy::{input::mouse::MouseMotion, prelude::*, window::CursorGrabMode}; use bevy_voxel_world::prelude::*; - -use crate::GameState; - pub struct CameraHandlerPlugin; /// This plugin makes the camera move @@ -10,41 +11,172 @@ pub struct CameraHandlerPlugin; impl Plugin for CameraHandlerPlugin { fn build(&self, app: &mut App) { app.add_systems(OnEnter(GameState::Playing), setup_mouse) - .add_systems(Update, move_camera.run_if(in_state(GameState::Playing))); + .add_systems( + Update, + mouse_motion_system.run_if(in_state(GameState::Playing)), + ) + .add_systems( + Update, + camera_movement_system.run_if(in_state(GameState::Playing)), + ); } } -fn move_camera( - mut motion_evr: EventReader, +#[derive(Component)] +pub struct FlyCamera { + /// The speed the FlyCamera accelerates at. Defaults to `1.5` + pub accel: f32, + /// The maximum speed the FlyCamera can move at. Defaults to `0.5` + pub max_speed: f32, + /// The sensitivity of the FlyCamera's motion based on mouse movement. Defaults to `3.0` + pub sensitivity: f32, + /// The amount of deceleration to apply to the camera's motion. Defaults to `1.0` + pub friction: f32, + /// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html) + pub pitch: f32, + /// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html) + pub yaw: f32, + /// The current velocity of the FlyCamera. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html) + pub velocity: Vec3, + pub enabled: bool, +} +impl Default for FlyCamera { + fn default() -> Self { + Self { + accel: 1.5, + max_speed: 0.5, + sensitivity: 3.0, + friction: 1.0, + pitch: 0.0, + yaw: 0.0, + velocity: Vec3::ZERO, + enabled: true, + } + } +} + +fn setup_mouse(mut windows: Query<&mut Window>) { + let mut window = windows.single_mut(); + + window.cursor.visible = false; + window.cursor.grab_mode = CursorGrabMode::Locked; +} + +fn forward_vector(rotation: &Quat) -> Vec3 { + rotation.mul_vec3(Vec3::Z).normalize() +} + +fn forward_walk_vector(rotation: &Quat) -> Vec3 { + let f = forward_vector(rotation); + + Vec3::new(f.x, 0.0, f.z).normalize() +} + +fn strafe_vector(rotation: &Quat) -> Vec3 { + // Rotate it 90 degrees to get the strafe direction + Quat::from_rotation_y(90.0f32.to_radians()) + .mul_vec3(forward_walk_vector(rotation)) + .normalize() +} + +fn camera_movement_system( time: Res