Initial commit

This commit is contained in:
DenisToxic
2026-10-27 19:02:27 +01:00
commit f1cafa14d8
24 changed files with 7234 additions and 0 deletions

128
src/player.rs Normal file
View File

@@ -0,0 +1,128 @@
use crate::{
game::{GameState, WorldEntity},
maze::{self, Maze},
settings::Settings,
};
use bevy::{
input::mouse::AccumulatedMouseMotion,
prelude::*,
window::{CursorGrabMode, CursorOptions},
};
#[derive(Component)]
pub struct Player {
pub yaw: f32,
pub pitch: f32,
pub distance: f32,
}
pub const SPAWN_YAW: f32 = std::f32::consts::FRAC_PI_2;
pub fn spawn(mut commands: Commands, maze: Res<Maze>, settings: Res<Settings>) {
commands.spawn((
WorldEntity,
Player {
yaw: SPAWN_YAW,
pitch: 0.,
distance: 0.,
},
Camera3d::default(),
bevy::render::view::NoIndirectDrawing,
bevy::core_pipeline::tonemapping::Tonemapping::None,
if settings.low {
Msaa::Off
} else {
Msaa::Sample4
},
Projection::Perspective(PerspectiveProjection {
fov: 80_f32.to_radians(),
near: 0.05,
far: 90.,
..default()
}),
Transform::from_translation(maze::position(maze.spawn()) + Vec3::Y * 1.15)
.with_rotation(Quat::from_rotation_y(SPAWN_YAW)),
));
}
pub fn cursor(state: Res<State<GameState>>, mut windows: Query<(&Window, &mut CursorOptions)>) {
for (window, mut c) in &mut windows {
let grab = *state.get() == GameState::Playing && window.focused;
c.visible = !grab;
c.grab_mode = if grab {
CursorGrabMode::Locked
} else {
CursorGrabMode::None
};
}
}
pub fn move_player(
time: Res<Time>,
keys: Res<ButtonInput<KeyCode>>,
mouse: Res<AccumulatedMouseMotion>,
pads: Query<&Gamepad>,
settings: Res<Settings>,
maze: Res<Maze>,
mut players: Query<(&mut Player, &mut Transform)>,
) {
let dt = time.delta_secs().min(0.1);
for (mut p, mut t) in &mut players {
let mut walk = Vec2::ZERO;
if keys.pressed(KeyCode::KeyW) {
walk.y += 1.;
}
if keys.pressed(KeyCode::KeyS) {
walk.y -= 1.;
}
if keys.pressed(KeyCode::KeyD) {
walk.x += 1.;
}
if keys.pressed(KeyCode::KeyA) {
walk.x -= 1.;
}
let mut turn = Vec2::ZERO;
if keys.pressed(KeyCode::ArrowLeft) {
turn.x -= 1.;
}
if keys.pressed(KeyCode::ArrowRight) {
turn.x += 1.;
}
for pad in &pads {
let left = pad.left_stick();
if left.length() > 0.18 {
walk += left;
}
let right = pad.right_stick();
if right.length() > 0.18 {
turn += Vec2::new(right.x, -right.y);
}
}
p.yaw -= turn.x * dt * 2.;
p.pitch = (p.pitch - turn.y * dt * 1.5).clamp(-1.1, 1.1);
if !settings.keyboard_only {
p.yaw -= mouse.delta.x * settings.sensitivity;
p.pitch = (p.pitch - mouse.delta.y * settings.sensitivity).clamp(-1.1, 1.1);
}
let rotation = Quat::from_rotation_y(p.yaw);
let velocity =
rotation * Vec3::new(walk.x, 0., -walk.y).clamp_length_max(1.) * settings.speed * dt;
// Small swept substeps prevent tunneling even after a long frame.
let steps = (velocity.length() / 0.08).ceil().max(1.) as u32;
let delta = velocity / steps as f32;
for _ in 0..steps {
let x = t.translation + Vec3::X * delta.x;
if maze.fits(x, 0.25) {
t.translation = x;
}
let z = t.translation + Vec3::Z * delta.z;
if maze.fits(z, 0.25) {
t.translation = z;
}
}
p.distance += velocity.length();
t.translation.y = 1.15
+ if settings.bob && !settings.low {
(p.distance * 7.).sin() * 0.025
} else {
0.
};
t.rotation = rotation * Quat::from_rotation_x(p.pitch);
}
}