Merge branch 'main' of github.com-personal:Back777space/among-me

This commit is contained in:
Back777space
2025-04-05 18:38:39 +02:00
parent 27d0292c01
commit 9a41db14bb
5 changed files with 422 additions and 14200 deletions

165
Cargo.lock generated
View File

@@ -2119,7 +2119,7 @@ dependencies = [
"vec_map", "vec_map",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"windows 0.54.0", "windows 0.60.0",
] ]
[[package]] [[package]]
@@ -2235,7 +2235,7 @@ dependencies = [
"log", "log",
"presser", "presser",
"thiserror", "thiserror",
"windows 0.54.0", "windows 0.58.0",
] ]
[[package]] [[package]]
@@ -2514,7 +2514,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"libc", "libc",
"redox_syscall 0.5.10", "redox_syscall 0.5.11",
] ]
[[package]] [[package]]
@@ -3111,7 +3111,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall 0.5.10", "redox_syscall 0.5.11",
"smallvec", "smallvec",
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
@@ -3410,9 +3410,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.10" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
] ]
@@ -3744,7 +3744,7 @@ dependencies = [
"libc", "libc",
"memchr", "memchr",
"ntapi", "ntapi",
"windows 0.54.0", "windows 0.57.0",
] ]
[[package]] [[package]]
@@ -4306,6 +4306,16 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
dependencies = [
"windows-core 0.57.0",
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "windows" name = "windows"
version = "0.58.0" version = "0.58.0"
@@ -4316,6 +4326,28 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529"
dependencies = [
"windows-collections",
"windows-core 0.60.1",
"windows-future",
"windows-link",
"windows-numerics",
]
[[package]]
name = "windows-collections"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec"
dependencies = [
"windows-core 0.60.1",
]
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.54.0" version = "0.54.0"
@@ -4326,19 +4358,65 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-core"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
dependencies = [
"windows-implement 0.57.0",
"windows-interface 0.57.0",
"windows-result 0.1.2",
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.58.0" version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [ dependencies = [
"windows-implement", "windows-implement 0.58.0",
"windows-interface", "windows-interface 0.58.0",
"windows-result 0.2.0", "windows-result 0.2.0",
"windows-strings", "windows-strings 0.1.0",
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-core"
version = "0.60.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247"
dependencies = [
"windows-implement 0.59.0",
"windows-interface 0.59.1",
"windows-link",
"windows-result 0.3.2",
"windows-strings 0.3.1",
]
[[package]]
name = "windows-future"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0"
dependencies = [
"windows-core 0.60.1",
"windows-link",
]
[[package]]
name = "windows-implement"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "windows-implement" name = "windows-implement"
version = "0.58.0" version = "0.58.0"
@@ -4350,6 +4428,28 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "windows-implement"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "windows-interface" name = "windows-interface"
version = "0.58.0" version = "0.58.0"
@@ -4361,6 +4461,33 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-numerics"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed"
dependencies = [
"windows-core 0.60.1",
"windows-link",
]
[[package]] [[package]]
name = "windows-result" name = "windows-result"
version = "0.1.2" version = "0.1.2"
@@ -4379,6 +4506,15 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-result"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-strings" name = "windows-strings"
version = "0.1.0" version = "0.1.0"
@@ -4389,6 +4525,15 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-strings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.45.0" version = "0.45.0"

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +0,0 @@
use bevy::{input::mouse::MouseMotion, prelude::*, input::mouse::a};
#[derive(Debug, Component)]
struct Player;
#[derive(Debug, Component, Deref, DerefMut)]
struct CameraSensitivity(Vec2);
impl Default for CameraSensitivity {
fn default() -> Self {
Self(
Vec2::new(0.003, 0.002),
)
}
}
#[derive(Debug, Component)]
struct WorldModelCamera;
use std::f32::consts::FRAC_PI_2;
pub fn move_camera(
mut motion_evr: EventReader<MouseMotion>,
time: Res<Time>,
mut camera_query: Query<(&mut Transform, &mut Camera)>,
) {
let Ok((mut transform, camera_sensitivity)) = player.get_single_mut() else {
return;
};
let delta = accumulated_mouse_motion.delta;
if delta != Vec2::ZERO {
// Note that we are not multiplying by delta_time here.
// The reason is that for mouse movement, we already get the full movement that happened since the last frame.
// This means that if we multiply by delta_time, we will get a smaller rotation than intended by the user.
// This situation is reversed when reading e.g. analog input from a gamepad however, where the same rules
// as for keyboard input apply. Such an input should be multiplied by delta_time to get the intended rotation
// independent of the framerate.
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;
// If the pitch was ±¹⁄₂ π, the camera would look straight up or down.
// When the user wants to move the camera back to the horizon, which way should the camera face?
// The camera has no way of knowing what direction was "forward" before landing in that extreme position,
// so the direction picked will for all intents and purposes be arbitrary.
// Another issue is that for mathematical reasons, the yaw will effectively be flipped when the pitch is at the extremes.
// To not run into these issues, we clamp the pitch to a safe range.
const PITCH_LIMIT: f32 = FRAC_PI_2 - 0.01;
let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);
transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
}
}

View File

@@ -1,24 +1,46 @@
use bevy::prelude::*; use bevy::prelude::*;
fn main() -> AppExit { pub mod player;
fn main() {
App::new() App::new()
.add_plugins((DefaultPlugins)) .add_plugins(DefaultPlugins)
// We need to register components to make them visible to Blenvy .add_systems(Startup, (setup, player::init_player))
.add_plugins((DefaultPlugins, BlenvyPlugin::default())) .add_systems(Update, player::move_camera)
.add_systems(Startup, setup) .add_systems(FixedUpdate, player::advance_physics)
.add_systems(Update, camera::move_camera) .add_systems(
.run() RunFixedMainLoop,
(
player::handle_input.in_set(RunFixedMainLoopSystem::BeforeFixedMainLoop),
player::interpolate_rendered_transform.in_set(RunFixedMainLoopSystem::AfterFixedMainLoop),
),
)
.run();
} }
#[derive(Component, Reflect)] fn setup(
struct Player { mut commands: Commands,
strength: f32, mut meshes: ResMut<Assets<Mesh>>,
perception: f32, mut materials: ResMut<Assets<StandardMaterial>>,
endurance: f32, ) {
charisma: f32, // circular base
intelligence: f32, commands.spawn((
agility: f32, Mesh3d(meshes.add(Circle::new(4.0))),
luck: f32, MeshMaterial3d(materials.add(Color::WHITE)),
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
));
// cube
commands.spawn((
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
Transform::from_xyz(3.0, 0.5, 0.0),
));
// light
commands.spawn((
PointLight {
shadows_enabled: true,
..default()
},
Transform::from_xyz(4.0, 8.0, 4.0),
));
} }
fn setup(mut commands: Commands) {}

227
src/player.rs Normal file
View File

@@ -0,0 +1,227 @@
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;
#[derive(Debug, Component, Clone, Copy, PartialEq, Default, Deref, DerefMut)]
pub struct AccumulatedInput(Vec3);
#[derive(Debug, Component, Clone, Copy, PartialEq, Default, Deref, DerefMut)]
pub struct Velocity(Vec3);
/// The actual position of the player in the physics simulation.
/// This is separate from the `Transform`, which is merely a visual representation.
///
/// If you want to make sure that this component is always initialized
/// with the same value as the `Transform`'s translation, you can
/// use a [component lifecycle hook](https://docs.rs/bevy/0.14.0/bevy/ecs/component/struct.ComponentHooks.html)
#[derive(Debug, Component, Clone, Copy, PartialEq, Default, Deref, DerefMut)]
pub struct PhysicalTranslation(Vec3);
/// The value [`PhysicalTranslation`] had in the last fixed timestep.
/// Used for interpolation in the `interpolate_rendered_transform` system.
#[derive(Debug, Component, Clone, Copy, PartialEq, Default, Deref, DerefMut)]
pub struct PreviousPhysicalTranslation(Vec3);
/// 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);
}
}
// PLAYER MOVEMENT
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 += 1.0; }
if keyboard_input.pressed(KeyCode::KeyS) { input.x -= 1.0; }
if keyboard_input.pressed(KeyCode::KeyA) { input.z -= 1.0; }
if keyboard_input.pressed(KeyCode::KeyD) { input.z += 1.0; }
if keyboard_input.pressed(KeyCode::Space) { input.y += 1.0; }
if keyboard_input.pressed(KeyCode::ShiftLeft) { input.y -= 1.0; }
// velocity.0 = input * SPEED;
}
}
pub fn step(
fixed_time: Res<Time<Fixed>>,
mut query: Query<(
&mut PhysicalTranslation,
&mut PreviousPhysicalTranslation,
&mut AccumulatedInput,
&Velocity,
)>,
) {
for (
mut current_physical_translation,
mut previous_physical_translation,
mut input,
velocity,
) in query.iter_mut()
{
previous_physical_translation.0 = current_physical_translation.0;
current_physical_translation.0 += velocity.0 * fixed_time.delta_secs();
input.0 = Vec3::ZERO;
}
}
pub fn interpolate_rendered_transform(
fixed_time: Res<Time<Fixed>>,
mut query: Query<(
&mut Transform,
&PhysicalTranslation,
&PreviousPhysicalTranslation,
)>,
) {
for (mut transform, current_physical_translation, previous_physical_translation) in
query.iter_mut()
{
let previous = previous_physical_translation.0;
let current = current_physical_translation.0;
// The overstep fraction is a value between 0 and 1 that tells us how far we are between two fixed timesteps.
let alpha = fixed_time.overstep_fraction();
let rendered_translation = previous.lerp(current, alpha);
transform.translation = rendered_translation;
}
}
pub fn advance_physics(
fixed_time: Res<Time<Fixed>>,
mut query: Query<(
&mut PhysicalTranslation,
&mut PreviousPhysicalTranslation,
&mut AccumulatedInput,
&Velocity,
)>,
) {
for (
mut current_physical_translation,
mut previous_physical_translation,
mut input,
velocity,
) in query.iter_mut()
{
previous_physical_translation.0 = current_physical_translation.0;
current_physical_translation.0 += velocity.0 * fixed_time.delta_secs();
// Reset the input accumulator, as we are currently consuming all input that happened since the last fixed timestep.
input.0 = Vec3::ZERO;
}
}