drop
This commit is contained in:
115
src/player.rs
115
src/player.rs
@@ -1,13 +1,18 @@
|
||||
|
||||
use bevy::{
|
||||
input::mouse::AccumulatedMouseMotion, prelude::*, render::view::RenderLayers, window::{PrimaryWindow, WindowResized}
|
||||
input::mouse::AccumulatedMouseMotion,
|
||||
prelude::*,
|
||||
render::view::RenderLayers,
|
||||
window::{PrimaryWindow, WindowResized},
|
||||
};
|
||||
use bevy_kira_audio::{Audio, AudioControl};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
pub mod toolbar;
|
||||
|
||||
use crate::{asset_loading::{AudioAssets, FlashlightAssets}, GameState};
|
||||
use crate::{
|
||||
GameState,
|
||||
asset_loading::{AudioAssets, FlashlightAssets},
|
||||
};
|
||||
|
||||
#[derive(Debug, Component, Default)]
|
||||
pub struct Player {
|
||||
@@ -64,13 +69,12 @@ pub struct FlashlightButtonAnimation {
|
||||
impl Default for FlashlightButtonAnimation {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
timer: Timer::from_seconds(0.20, TimerMode::Once),
|
||||
timer: Timer::from_seconds(0.20, TimerMode::Once),
|
||||
is_pressed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.add_plugins(toolbar::plugin)
|
||||
.add_systems(OnEnter(GameState::Playing), (init_player, hide_cursor))
|
||||
@@ -78,12 +82,13 @@ pub fn plugin(app: &mut App) {
|
||||
Update,
|
||||
(
|
||||
move_camera,
|
||||
handle_input,
|
||||
apply_head_bob,
|
||||
handle_input,
|
||||
apply_head_bob,
|
||||
on_resize_system,
|
||||
handle_flashlight,
|
||||
update_flashlight_button_animation,
|
||||
).run_if(in_state(GameState::Playing)),
|
||||
)
|
||||
.run_if(in_state(GameState::Playing)),
|
||||
)
|
||||
.add_systems(
|
||||
FixedUpdate,
|
||||
@@ -138,8 +143,6 @@ pub fn init_player(
|
||||
},
|
||||
RenderLayers::layer(STATIC_LAYER),
|
||||
));
|
||||
|
||||
// pitslamp sprite
|
||||
let window = window.single();
|
||||
let transform = flashlight_base_transform(window.width(), window.height());
|
||||
parent.spawn((
|
||||
@@ -149,18 +152,18 @@ pub fn init_player(
|
||||
RenderLayers::layer(STATIC_LAYER),
|
||||
FlashlightButtonAnimation::default(),
|
||||
));
|
||||
|
||||
|
||||
// feitelijke pitslamp
|
||||
parent.spawn((
|
||||
Flashlight,
|
||||
SpotLight {
|
||||
intensity: 0.0,
|
||||
intensity: 0.0,
|
||||
color: Color::WHITE,
|
||||
range: 4.0,
|
||||
range: 4.0,
|
||||
outer_angle: 30.0_f32.to_radians(), // wide cone for flashlight
|
||||
inner_angle: 10.0_f32.to_radians(), // narrower inner cone
|
||||
shadows_enabled: false, // (set to true for realism)
|
||||
radius: 0.35, // low value for hard light
|
||||
shadows_enabled: false, // (set to true for realism)
|
||||
radius: 0.35, // low value for hard light
|
||||
..default()
|
||||
},
|
||||
Transform::from_xyz(0.0, -0.15, 0.5),
|
||||
@@ -184,15 +187,17 @@ fn on_resize_system(
|
||||
|
||||
fn flashlight_base_transform(window_width: f32, window_height: f32) -> BaseTransform {
|
||||
let window_size = Vec2::new(window_width, window_height);
|
||||
let sprite_size = Vec2::new(101.0, 101.0);
|
||||
let scale = window_width / 600.0;
|
||||
let sprite_size = Vec2::new(404.0, 404.0);
|
||||
let scale = window_width / 2400.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)
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -231,8 +236,10 @@ pub(crate) enum PlayerAction {
|
||||
Move,
|
||||
Sprint,
|
||||
Jump,
|
||||
Interact,
|
||||
ToggleFlashlight
|
||||
ToggleFlashlight,
|
||||
// Objects and stuff
|
||||
PickUp,
|
||||
Drop,
|
||||
}
|
||||
|
||||
pub fn handle_input(
|
||||
@@ -240,7 +247,7 @@ pub fn handle_input(
|
||||
mut query: Query<(&Transform, &mut PlayerInput, &mut PlayerAction, &mut Player), With<Player>>,
|
||||
) {
|
||||
for (transform, mut input, mut action, mut player) in query.iter_mut() {
|
||||
*action = PlayerAction::Move;
|
||||
*action = PlayerAction::Move;
|
||||
|
||||
let forward = transform.forward();
|
||||
let right = transform.right();
|
||||
@@ -267,10 +274,13 @@ pub fn handle_input(
|
||||
} else if keyboard_input.pressed(KeyCode::ControlLeft) {
|
||||
player.speed_factor = 0.65;
|
||||
} else {
|
||||
player.speed_factor = 1.0;
|
||||
player.speed_factor = 1.0;
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::KeyE) {
|
||||
*action = PlayerAction::Interact
|
||||
*action = PlayerAction::PickUp;
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::KeyQ) {
|
||||
*action = PlayerAction::Drop;
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::KeyF) {
|
||||
*action = PlayerAction::ToggleFlashlight;
|
||||
@@ -280,7 +290,9 @@ pub fn handle_input(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_player_movement(mut player_query: Query<(&PlayerInput, &mut Velocity, &Player), With<Player>>) {
|
||||
pub fn apply_player_movement(
|
||||
mut player_query: Query<(&PlayerInput, &mut Velocity, &Player), With<Player>>,
|
||||
) {
|
||||
const SPEED: f32 = 2.6;
|
||||
const JUMP_FORCE: f32 = 4.0;
|
||||
|
||||
@@ -297,7 +309,7 @@ pub fn apply_player_movement(mut player_query: Query<(&PlayerInput, &mut Velocit
|
||||
|
||||
if input.movement_direction.y > 0.0 {
|
||||
velocity.linvel.y = JUMP_FORCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,14 +317,18 @@ pub fn apply_head_bob(
|
||||
time: Res<Time>,
|
||||
mut query: Query<(&PlayerInput, &mut HeadBob, &Player), With<Player>>,
|
||||
mut camera_query: Query<&mut Transform, (With<WorldModelCamera>, Without<Player>)>,
|
||||
mut sprite_query: Query<(&mut Transform, &Sprite, &BaseTransform), (With<Sprite>, Without<WorldModelCamera>, Without<Player>)>,
|
||||
mut sprite_query: Query<
|
||||
(&mut Transform, &Sprite, &BaseTransform),
|
||||
(With<Sprite>, Without<WorldModelCamera>, Without<Player>),
|
||||
>,
|
||||
) {
|
||||
let Ok((input, mut head_bob, player)) = query.get_single_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
// bob when moving horizontally
|
||||
let horizontal_movement = Vec3::new(input.movement_direction.x, 0.0, input.movement_direction.z);
|
||||
let horizontal_movement =
|
||||
Vec3::new(input.movement_direction.x, 0.0, input.movement_direction.z);
|
||||
let is_moving = horizontal_movement.length_squared() > 0.01;
|
||||
let bobbing_speed = head_bob.speed * player.speed_factor;
|
||||
|
||||
@@ -325,7 +341,7 @@ pub fn apply_head_bob(
|
||||
if let Some(camera_transform) = camera_query.iter_mut().next() {
|
||||
let current_offset = camera_transform.translation.y;
|
||||
if current_offset.abs() < 0.005 {
|
||||
// cancel out so head_bob.time_offset
|
||||
// cancel out so head_bob.time_offset
|
||||
offset = -head_bob.time_offset;
|
||||
}
|
||||
}
|
||||
@@ -336,7 +352,7 @@ pub fn apply_head_bob(
|
||||
// calculate vertical and horizontal offsets using sine and cosine
|
||||
let vertical_offset = head_bob.intensity * f32::sin(head_bob.time_offset);
|
||||
let horizontal_offset = (head_bob.intensity * 0.5) * f32::cos(head_bob.time_offset * 0.5);
|
||||
|
||||
|
||||
// apply
|
||||
for mut transform in camera_query.iter_mut() {
|
||||
transform.translation.y = vertical_offset;
|
||||
@@ -347,32 +363,31 @@ pub fn apply_head_bob(
|
||||
transform.translation.x *= 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// apply offsets to flashlight
|
||||
for (mut transform, _sprite, base_transform) in sprite_query.iter_mut() {
|
||||
let scale_factor = 40.0 * player.speed_factor;
|
||||
|
||||
|
||||
if is_moving {
|
||||
transform.translation.x = base_transform.0.translation.x + horizontal_offset * scale_factor;
|
||||
transform.translation.y = base_transform.0.translation.y + vertical_offset * scale_factor;
|
||||
|
||||
transform.rotation = Quat::from_euler(
|
||||
EulerRot::XYZ,
|
||||
0.0,
|
||||
0.0,
|
||||
horizontal_offset * 0.1,
|
||||
);
|
||||
transform.translation.x =
|
||||
base_transform.0.translation.x + horizontal_offset * scale_factor;
|
||||
transform.translation.y =
|
||||
base_transform.0.translation.y + vertical_offset * scale_factor;
|
||||
|
||||
transform.rotation =
|
||||
Quat::from_euler(EulerRot::XYZ, 0.0, 0.0, horizontal_offset * 0.1);
|
||||
} else {
|
||||
transform.translation = transform.translation.lerp(base_transform.0.translation, 0.1);
|
||||
transform.translation = transform
|
||||
.translation
|
||||
.lerp(base_transform.0.translation, 0.1);
|
||||
transform.rotation = transform.rotation.slerp(Quat::IDENTITY, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_flashlight(
|
||||
player_query: Query<&PlayerAction, With<Player>>,
|
||||
mut flashlight_query: Query<&mut SpotLight, With<Flashlight>>,
|
||||
mut flashlight_query: Query<&mut SpotLight, With<Flashlight>>,
|
||||
mut flashlight_sprite_query: Query<&mut FlashlightButtonAnimation>,
|
||||
audio_assets: Res<AudioAssets>,
|
||||
audio: Res<Audio>,
|
||||
@@ -390,9 +405,9 @@ pub fn handle_flashlight(
|
||||
if let Ok(mut spotlight) = flashlight_query.get_single_mut() {
|
||||
audio.play(audio_assets.flash_click.clone());
|
||||
|
||||
spotlight.intensity = if spotlight.intensity > 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
spotlight.intensity = if spotlight.intensity > 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
300_000.0
|
||||
};
|
||||
}
|
||||
@@ -414,4 +429,4 @@ pub fn update_flashlight_button_animation(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user