diff --git a/src/interaction/objects.rs b/src/interaction/objects.rs index bcf6650..fefcdd1 100644 --- a/src/interaction/objects.rs +++ b/src/interaction/objects.rs @@ -1,4 +1,4 @@ -use bevy::{gltf::GltfMesh, math::Vec3A, prelude::*, render::mesh::MeshAabb}; +use bevy::{prelude::*}; use bevy_rapier3d::prelude::{Collider, RigidBody}; use crate::{GameState, asset_loading::GltfAssets}; diff --git a/src/player.rs b/src/player.rs index d18eb48..8d27b89 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,14 +1,17 @@ + use bevy::{ - input::mouse::AccumulatedMouseMotion, prelude::*, render::view::RenderLayers, transform, window::{self, PrimaryWindow} + input::mouse::AccumulatedMouseMotion, prelude::*, render::view::RenderLayers, window::{PrimaryWindow, WindowResized} }; use bevy_rapier3d::prelude::*; pub mod toolbar; -use crate::{asset_loading::{FlashlightAssets}, GameState}; +use crate::{asset_loading::FlashlightAssets, GameState}; -#[derive(Debug, Component)] -pub struct Player; +#[derive(Debug, Component, Default)] +pub struct Player { + pub speed_factor: f32, +} #[derive(Debug, Component, Deref, DerefMut)] pub struct CameraSensitivity(Vec2); @@ -19,19 +22,41 @@ impl Default for CameraSensitivity { } #[derive(Debug, Component)] -struct WorldModelCamera; +pub struct WorldModelCamera; #[derive(Debug, Component, Default)] pub struct PlayerInput { movement_direction: Vec3, } +#[derive(Component, Debug)] +pub struct HeadBob { + pub enabled: bool, + pub intensity: f32, + pub speed: f32, + pub time_offset: f32, +} + +impl Default for HeadBob { + fn default() -> Self { + Self { + enabled: true, + intensity: 0.05, + speed: 10.0, + time_offset: 0.0, + } + } +} + +#[derive(Component, Debug)] +pub struct BaseTransform(pub Transform); + pub fn plugin(app: &mut App) { app.add_plugins(toolbar::plugin) .add_systems(OnEnter(GameState::Playing), (init_player, hide_cursor)) .add_systems( Update, - (move_camera, handle_input).run_if(in_state(GameState::Playing)), + (move_camera, handle_input, apply_head_bob, on_resize_system).run_if(in_state(GameState::Playing)), ) .add_systems( FixedUpdate, @@ -39,7 +64,7 @@ pub fn plugin(app: &mut App) { ); } -/// used by the view model camera and the player's arm. +// used by the view model camera and the player's arm. const STATIC_LAYER: usize = 1; pub fn init_player( @@ -47,15 +72,14 @@ pub fn init_player( flashlights: Res, window: Query<&Window>, ) { - let window = window.single(); - commands .spawn(( - Player, + Player::default(), PlayerAction::default(), CameraSensitivity::default(), PlayerInput::default(), toolbar::Item::none(), + HeadBob::default(), // rapier RigidBody::Dynamic, Collider::capsule(Vec3::new(0.0, -0.5, 0.0), Vec3::new(0.0, 0.5, 0.0), 0.5), @@ -88,24 +112,45 @@ pub fn init_player( RenderLayers::layer(STATIC_LAYER), )); - let window_size = Vec2::new(window.resolution.width(), window.resolution.height()); - let sprite_size = Vec2::new(101.0, 101.0); - let scale = window.resolution.width() / 600.0; - let world_size = sprite_size * scale; - let offset = window_size.x / 4.0 - 40.0; - - let mut transform = Transform::from_translation( - Vec3::new(window_size.x / 2.0 - world_size.x / 2.0 - offset, -window_size.y / 2.0 + world_size.y / 2.0, 0.0) - ); - transform.scale = Vec3::new(scale, scale, 1.0); + let window = window.single(); + let transform = flashlight_base_transform(window.width(), window.height()); parent.spawn(( Sprite::from_image(flashlights.flash_hold_4.clone()), + transform.0.clone(), transform, RenderLayers::layer(STATIC_LAYER), )); }); } +fn on_resize_system( + mut resize_reader: EventReader, + mut sprites: Query<(&mut Transform, &mut BaseTransform), With>, +) { + for e in resize_reader.read() { + for (mut transform, mut base_transform) in sprites.iter_mut() { + let new_pos = flashlight_base_transform(e.width, e.height); + *transform = new_pos.0.clone(); + *base_transform = new_pos; + } + } +} + +fn flashlight_base_transform(width: f32, height: f32) -> BaseTransform { + let window_size = Vec2::new(width, height); + let sprite_size = Vec2::new(101.0, 101.0); + let scale = width / 600.0; + let world_size = sprite_size * scale; + let xoffset = window_size.x / 4.0 - 40.0; + let yoffset = 15.0; + + let mut transform = Transform::from_translation( + Vec3::new(window_size.x / 2.0 - world_size.x / 2.0 - xoffset, -window_size.y / 2.0 + world_size.y / 2.0 - yoffset, 0.0) + ); + transform.scale = Vec3::new(scale, scale, 1.0); + return BaseTransform(transform); +} + fn hide_cursor(mut windows: Query<&mut Window, With>) { for mut window in windows.iter_mut() { window.cursor_options.visible = false; @@ -145,9 +190,9 @@ pub(crate) enum PlayerAction { pub fn handle_input( keyboard_input: Res>, - mut query: Query<(&Transform, &mut PlayerInput, &mut PlayerAction), With>, + mut query: Query<(&Transform, &mut PlayerInput, &mut PlayerAction, &mut Player), With>, ) { - for (transform, mut input, mut action) in query.iter_mut() { + for (transform, mut input, mut action, mut player) in query.iter_mut() { let forward = transform.forward(); let right = transform.right(); let mut movement_direction = Vec3::ZERO; @@ -168,7 +213,11 @@ pub fn handle_input( movement_direction += Vec3::Y; } if keyboard_input.pressed(KeyCode::ShiftLeft) { - movement_direction -= Vec3::Y; + player.speed_factor = 1.35; + } else if keyboard_input.pressed(KeyCode::ControlLeft) { + player.speed_factor = 0.65; + } else { + player.speed_factor = 1.0; } if keyboard_input.pressed(KeyCode::KeyE) { *action = PlayerAction::Interact @@ -178,15 +227,16 @@ pub fn handle_input( } } -pub fn apply_player_movement(mut player_query: Query<(&PlayerInput, &mut Velocity), With>) { - const SPEED: f32 = 3.0; +pub fn apply_player_movement(mut player_query: Query<(&PlayerInput, &mut Velocity, &Player), With>) { + const SPEED: f32 = 2.6; const JUMP_FORCE: f32 = 4.0; - for (input, mut velocity) in player_query.iter_mut() { + for (input, mut velocity, player) in player_query.iter_mut() { + let speed = SPEED * player.speed_factor; let horizontal_movement = Vec3::new( - input.movement_direction.x * SPEED, + input.movement_direction.x * speed, 0.0, - input.movement_direction.z * SPEED, + input.movement_direction.z * speed, ); velocity.linvel.x = horizontal_movement.x; @@ -194,8 +244,75 @@ pub fn apply_player_movement(mut player_query: Query<(&PlayerInput, &mut Velocit if input.movement_direction.y > 0.0 { velocity.linvel.y = JUMP_FORCE; - } else if input.movement_direction.y < 0.0 { - velocity.linvel.y = -SPEED; - } + } } } + +pub fn apply_head_bob( + time: Res