hide cursor

This commit is contained in:
LorrensP-2158466
2025-04-05 19:39:59 +02:00
parent 1328caab5c
commit e71e840d9f
3 changed files with 54 additions and 25 deletions

157
src/player.rs Normal file
View File

@@ -0,0 +1,157 @@
use crate::{
GameState,
physics_plugin::{
AccumulatedInput, PhysicalTranslation, PreviousPhysicalTranslation, Velocity,
},
};
use bevy::{
input::mouse::AccumulatedMouseMotion, pbr::NotShadowCaster, prelude::*,
render::view::RenderLayers,
};
#[derive(Debug, Component)]
pub struct Player;
#[derive(Debug, Component, Deref, DerefMut)]
pub struct CameraSensitivity(Vec2);
impl Default for CameraSensitivity {
fn default() -> Self {
Self(Vec2::new(0.003, 0.002))
}
}
#[derive(Debug, Component)]
struct WorldModelCamera;
pub fn plugin(app: &mut App) {
app.add_systems(OnEnter(GameState::Playing), init_player)
.add_systems(Update, move_camera.run_if(in_state(GameState::Playing)))
.add_systems(
RunFixedMainLoop,
handle_input
.in_set(RunFixedMainLoopSystem::BeforeFixedMainLoop)
.run_if(in_state(GameState::Playing)),
);
}
/// Used implicitly by all entities without a `RenderLayers` component.
/// Our world model camera and all objects other than the player are on this layer.
/// The light source belongs to both layers.
// const DEFAULT_RENDER_LAYER: usize = 0;
/// Used by the view model camera and the player's arm.
/// The light source belongs to both layers.
const STATIC_LAYER: usize = 1;
pub fn init_player(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let arm = meshes.add(Cuboid::new(0.1, 0.1, 0.5));
let arm_material = materials.add(Color::WHITE);
commands
.spawn((
Player,
CameraSensitivity::default(),
Transform::from_xyz(0.0, 1.0, 0.0),
Visibility::default(),
AccumulatedInput::default(),
Velocity::default(),
PhysicalTranslation(Vec3::new(0.0, 1.0, 0.0)),
PreviousPhysicalTranslation(Vec3::new(0.0, 1.0, 0.0)),
))
.with_children(|parent| {
parent.spawn((
WorldModelCamera,
Camera3d::default(),
Projection::from(PerspectiveProjection {
fov: 90.0_f32.to_radians(),
..default()
}),
));
// we use a second layer ("framebuffer") to draw the player's arm on
// there also a second camera that only views this buffer
// this makes it easy because the second camera doesn't move with the player
parent.spawn((
Camera3d::default(),
Camera {
order: 1,
..default()
},
Projection::from(PerspectiveProjection {
fov: 70.0_f32.to_radians(),
..default()
}),
RenderLayers::layer(STATIC_LAYER),
));
parent.spawn((
Mesh3d(arm),
MeshMaterial3d(arm_material),
Transform::from_xyz(0.2, -0.1, -0.25),
RenderLayers::layer(STATIC_LAYER),
NotShadowCaster,
));
});
}
use std::f32::consts::FRAC_PI_2;
const PITCH_LIMIT: f32 = FRAC_PI_2 - 0.01;
pub fn move_camera(
accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
mut player: Query<(&mut Transform, &CameraSensitivity), With<Player>>,
) {
let Ok((mut transform, camera_sensitivity)) = player.get_single_mut() else {
return;
};
let delta = accumulated_mouse_motion.delta;
if delta != Vec2::ZERO {
let delta_yaw = -delta.x * camera_sensitivity.x;
let delta_pitch = -delta.y * camera_sensitivity.y;
let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ);
let yaw = yaw + delta_yaw;
let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);
transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
}
}
pub fn handle_input(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut query: Query<(&Transform, &mut AccumulatedInput, &mut Velocity), With<Player>>,
) {
const SPEED: f32 = 2.0;
for (transform, mut input, mut velocity) in query.iter_mut() {
let forward = transform.forward(); // Forward direction (z axis)
let right = transform.right(); // Right direction (x axis)
if keyboard_input.pressed(KeyCode::KeyW) {
input.x += forward.x;
input.z += forward.z;
}
if keyboard_input.pressed(KeyCode::KeyS) {
input.x -= forward.x;
input.z -= forward.z;
}
if keyboard_input.pressed(KeyCode::KeyA) {
input.x -= right.x;
input.z -= right.z;
}
if keyboard_input.pressed(KeyCode::KeyD) {
input.x += right.x;
input.z += right.z;
}
if keyboard_input.pressed(KeyCode::Space) {
input.y += 1.0;
}
if keyboard_input.pressed(KeyCode::ShiftLeft) {
input.y -= 1.0;
}
velocity.0 = input.normalize_or_zero() * SPEED;
}
}