Fix over-application of cohesion forces

The cohesion function was erroneously applying forces to boids that
shouldn't be experiencing them. It shouldn't be iterating over all
boids-with-velocity and adding speed. It should be applying that force
only to the one boid that the loop is examining at that iteration.

I also cleaned up the signature to have just one query struct. I had it
split as two because I was getting issues with mutability. The fix was
to make the query mutable, and then keep the Transforms as immutable
references. This way I can reach through and update the Velocity alone.
This commit is contained in:
2024-07-10 14:03:38 -05:00
parent a0323af081
commit 95cdd90485

View File

@@ -9,8 +9,8 @@ const BACKGROUND_COLOR: Color = Color::srgb(0.4, 0.4, 0.4);
const PLAYERBOID_COLOR: Color = Color::srgb(1.0, 0.0, 0.0); const PLAYERBOID_COLOR: Color = Color::srgb(1.0, 0.0, 0.0);
const TURN_FACTOR: f32 = 1.; const TURN_FACTOR: f32 = 1.;
const BOID_VIEW_RANGE: f32 = 50.0; const BOID_VIEW_RANGE: f32 = 50.0;
const COHESION_FACTOR: f32 = 0.1; const COHESION_FACTOR: f32 = 1.0;
const SEPARATION_FACTOR: f32 = 0.05; const SEPARATION_FACTOR: f32 = 0.1;
pub struct BoidsPlugin; pub struct BoidsPlugin;
@@ -168,10 +168,9 @@ fn check_keyboard(
fn cohesion( fn cohesion(
spatial_tree: Res<KDTree2<TrackedByKdTree>>, spatial_tree: Res<KDTree2<TrackedByKdTree>>,
boids: Query<&Transform, With<Boid>>, mut boids: Query<(&Transform, &mut Velocity), With<Boid>>,
mut velocities: Query<&mut Velocity, With<Boid>>,
) { ) {
for transform in &boids { for (transform, mut velocity) in &mut boids {
let neighbors = spatial_tree.within_distance( let neighbors = spatial_tree.within_distance(
transform.translation.xy(), transform.translation.xy(),
BOID_VIEW_RANGE BOID_VIEW_RANGE
@@ -181,12 +180,10 @@ fn cohesion(
.map(|(pos, _opt_entity)| pos ) .map(|(pos, _opt_entity)| pos )
.sum::<Vec2>() / neighbors.len() as f32; .sum::<Vec2>() / neighbors.len() as f32;
for mut velocity in &mut velocities {
let towards = (center_of_mass - transform.translation.xy()).normalize(); let towards = (center_of_mass - transform.translation.xy()).normalize();
**velocity += towards.extend(0.0) * COHESION_FACTOR; **velocity += towards.extend(0.0) * COHESION_FACTOR;
} }
} }
}
} }
fn separation( fn separation(
@@ -200,7 +197,7 @@ fn separation(
for (boid_transform, mut boid_acceleration) in &mut boids { for (boid_transform, mut boid_acceleration) in &mut boids {
let neighbors = spatial_tree.within_distance( let neighbors = spatial_tree.within_distance(
boid_transform.translation.xy(), boid_transform.translation.xy(),
BOID_VIEW_RANGE, BOID_VIEW_RANGE / 4.0,
); );
let accel = neighbors.iter() let accel = neighbors.iter()
.map(|(pos, _)| pos.extend(0.0)) .map(|(pos, _)| pos.extend(0.0))