diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-08 15:23:24 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-08 15:23:24 +0800 |
| commit | fc0d77d6838b16d811ffe5e999d3d77d499b470f (patch) | |
| tree | 00565a452f9045b4fb357ae04a1cae349163839a /plugins/movement | |
chore: initialize project workspace and movement plugin
Diffstat (limited to 'plugins/movement')
| -rw-r--r-- | plugins/movement/Cargo.toml | 9 | ||||
| -rw-r--r-- | plugins/movement/src/lib.rs | 52 | ||||
| -rw-r--r-- | plugins/movement/src/movement.rs | 5 | ||||
| -rw-r--r-- | plugins/movement/src/position.rs | 12 | ||||
| -rw-r--r-- | plugins/movement/src/reducer.rs | 62 | ||||
| -rw-r--r-- | plugins/movement/src/velocity.rs | 12 |
6 files changed, 152 insertions, 0 deletions
diff --git a/plugins/movement/Cargo.toml b/plugins/movement/Cargo.toml new file mode 100644 index 0000000..e70cca0 --- /dev/null +++ b/plugins/movement/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ch-movement" +version.workspace = true +edition.workspace = true + +[dependencies] +bevy.workspace = true + +ch-macro-rules.workspace = true diff --git a/plugins/movement/src/lib.rs b/plugins/movement/src/lib.rs new file mode 100644 index 0000000..f7f6ba5 --- /dev/null +++ b/plugins/movement/src/lib.rs @@ -0,0 +1,52 @@ +//! CH Modules - Movement +//! +//! CH Movement provides a set of systems for driving Entity movement. +//! +//! # Included +//! +//! - **Velocity**: Represents the entity's current momentum, used by systems to calculate the next frame's position +//! - **Position**: Represents the entity's current location +//! - **Movement**: A pure marker, used to flag this entity as movable +//! - **VelocityReducer**: Controls how Velocity is reduced + +#![deny(missing_docs)] + +use bevy::{ + app::{FixedUpdate, Plugin}, + ecs::{query::With, system::Query}, +}; +use ch_macro_rules::import; + +// Basic data +import!(position, velocity, movement); + +// Modifiers +import!(reducer); + +/// Cigarette Hacker movement plugin +/// +/// Used to describe the movement of characters in the game +pub struct CHMovementPlugins; + +impl Plugin for CHMovementPlugins { + fn build(&self, app: &mut bevy::app::App) { + app.add_systems(FixedUpdate, update_movement); + } +} + +fn update_movement( + query: Query<(&mut Position, &mut Velocity, Option<&VelocityReducer>), With<Movement>>, +) { + for (mut pos, mut velo, reducer) in query { + // Add Velocity to Position + pos.x += velo.x; + pos.y += velo.y; + pos.z += velo.z; + + // Apply velocity reduction (default to Lerp(0.25) if no reducer present) + match reducer { + Some(reducer) => reducer.calculate(&mut velo), + None => VelocityReducer::Lerp(0.25).calculate(&mut velo), + } + } +} diff --git a/plugins/movement/src/movement.rs b/plugins/movement/src/movement.rs new file mode 100644 index 0000000..4c13908 --- /dev/null +++ b/plugins/movement/src/movement.rs @@ -0,0 +1,5 @@ +use bevy::ecs::component::Component; + +/// Indicates that an entity is **movable**, used for CHMovementPlugins systems to recognize it +#[derive(Component)] +pub struct Movement; diff --git a/plugins/movement/src/position.rs b/plugins/movement/src/position.rs new file mode 100644 index 0000000..c6dc598 --- /dev/null +++ b/plugins/movement/src/position.rs @@ -0,0 +1,12 @@ +use bevy::{ + ecs::component::Component, + math::Vec3, + prelude::{Deref, DerefMut}, +}; + +/// Used to represent the actual position of the current entity +#[derive(Component, Deref, DerefMut, PartialEq, Default, Clone)] +pub struct Position { + #[deref] + pos: Vec3, +} diff --git a/plugins/movement/src/reducer.rs b/plugins/movement/src/reducer.rs new file mode 100644 index 0000000..334d37e --- /dev/null +++ b/plugins/movement/src/reducer.rs @@ -0,0 +1,62 @@ +use bevy::{ecs::component::Component, math::Vec3}; + +use crate::Velocity; + +/// Controls how Velocity is reduced +#[derive(Component)] +pub enum VelocityReducer { + /// Sync mode, only applies the current Velocity to Position each time, does not reduce itself + Sync, + + /// Move mode, directly zeroes out the velocity (momentum is transferred to Position) + Move, + + /// Constant reduction mode, reduces by a fixed amount each time until it becomes Vec3::ZERO + Reduce(Vec3), + + /// Lerp, reduces velocity using linear interpolation each time until it becomes Vec3::ZERO + Lerp(f32), + + /// Function, calls a custom function to process velocity + Func(Box<dyn Fn(Vec3) -> Vec3 + Send + Sync + 'static>), +} + +impl VelocityReducer { + /// Calculates velocity reduction, writing the result back to the Velocity component + pub fn calculate(&self, origin: &mut Velocity) { + self.calculate_vec(&mut *origin); + } + + /// Calculates velocity reduction, writing the result back to Vec3 + pub fn calculate_vec(&self, origin_vec: &mut Vec3) { + match self { + VelocityReducer::Sync => { + // DO NOTHING + } + VelocityReducer::Move => { + *origin_vec = Vec3::ZERO; + } + VelocityReducer::Reduce(vec3) => { + let mut vec = *origin_vec - *vec3; + // Handle direction: if sign flips, clamp to zero + if (origin_vec.x > 0.0 && vec.x < 0.0) || (origin_vec.x < 0.0 && vec.x > 0.0) { + vec.x = 0.0; + } + if (origin_vec.y > 0.0 && vec.y < 0.0) || (origin_vec.y < 0.0 && vec.y > 0.0) { + vec.y = 0.0; + } + if (origin_vec.z > 0.0 && vec.z < 0.0) || (origin_vec.z < 0.0 && vec.z > 0.0) { + vec.z = 0.0; + } + *origin_vec = vec; + } + VelocityReducer::Lerp(lerp) => { + let lerp = lerp.clamp(0., 1.); + *origin_vec = origin_vec.lerp(Vec3::ZERO, lerp); + } + VelocityReducer::Func(fn_mut) => { + *origin_vec = fn_mut(*origin_vec); + } + } + } +} diff --git a/plugins/movement/src/velocity.rs b/plugins/movement/src/velocity.rs new file mode 100644 index 0000000..c445e64 --- /dev/null +++ b/plugins/movement/src/velocity.rs @@ -0,0 +1,12 @@ +use bevy::{ + ecs::component::Component, + math::Vec3, + prelude::{Deref, DerefMut}, +}; + +/// Used to record the amount of movement an object is currently undergoing +#[derive(Component, Deref, DerefMut, PartialEq, Default, Clone)] +pub struct Velocity { + #[deref] + velocity: Vec3, +} |
