Skip to content
This repository has been archived by the owner on Oct 25, 2021. It is now read-only.

Commit

Permalink
Disable conflicting behavior systems and add Boids seek system
Browse files Browse the repository at this point in the history
  • Loading branch information
sunreef committed May 27, 2019
1 parent 9644b76 commit 334924e
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 83 deletions.
9 changes: 4 additions & 5 deletions resources/prefabs/creatures/carnivore.ron
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,13 @@ Prefab (
faction: "Carnivores",
),
),
intelligence_tag: (),
perception: (
range: 5.0,
range: 6.0,
),
boids: (
avoid: (
names: ["Carnivore"],
strength: 2.0,
seek: (
names: ["Herbivore"],
strength: 10.0,
),
),
),
Expand Down
14 changes: 9 additions & 5 deletions resources/prefabs/creatures/herbivore.ron
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,26 @@ Prefab (
),
),
perception: (
range: 5.0,
range: 4.0,
),
boids: (
flocking: (
strength: 0.4,
),
match_velocity: (
strength: 2.0,
strength: 3.0,
),
avoid: (
names: ["Carnivore"],
strength: 30.0,
strength: 20.0,
),
seek: (
names: ["Plant"],
strength: 10.0,
),
minimum_distance: (
minimum: 1.3,
strength: 15.0,
minimum: 1.5,
strength: 5.0,
),
),
),
Expand Down
15 changes: 14 additions & 1 deletion src/components/experimental/boids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ impl Component for AvoidRule {
type Storage = DenseVecStorage<Self>;
}

#[derive(Default, Clone, Serialize, Deserialize, PrefabData)]
#[prefab(Component)]
#[serde(default)]
pub struct SeekRule {
pub names: Vec<String>,
pub strength: f32,
}

impl Component for SeekRule {
type Storage = DenseVecStorage<Self>;
}

#[derive(Clone, Serialize, Deserialize, PrefabData)]
#[prefab(Component)]
pub struct WorldBoundsRule {
Expand All @@ -61,7 +73,7 @@ pub struct WorldBoundsRule {

impl Default for WorldBoundsRule {
fn default() -> Self {
WorldBoundsRule { strength: 10.0 }
WorldBoundsRule { strength: 20.0 }
}
}

Expand All @@ -76,6 +88,7 @@ pub struct BoidsPrefabData {
flocking: Option<FlockingRule>,
match_velocity: Option<MatchVelocityRule>,
avoid: Option<AvoidRule>,
seek: Option<SeekRule>,
minimum_distance: Option<MinimumDistanceRule>,

#[serde(skip)]
Expand Down
93 changes: 47 additions & 46 deletions src/states/main_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl MainGameState {
&["entity_detection"],
)
.with(boids::AvoidSystem, "avoid", &["entity_detection"])
.with(boids::SeekSystem, "seek", &["entity_detection"])
.with(
boids::MinimumDistanceSystem,
"minimum_distance",
Expand All @@ -60,52 +61,52 @@ impl MainGameState {
"world_bounds",
&["entity_detection"],
)
.with(
QueryPredatorsAndPreySystem,
"query_predators_and_prey_system",
&[],
)
.with(ClosestObstacleSystem, "closest_obstacle_system", &[])
.with(
ClosestSystem::<Prey>::default(),
"closest_prey_system",
&["query_predators_and_prey_system"],
)
.with(
ClosestSystem::<Predator>::default(),
"closest_predator_system",
&["query_predators_and_prey_system"],
)
.with(
SeekSystem::<Prey>::new(
Rotation3::from_axis_angle(&Vector3::z_axis(), 0.0),
1.0,
),
"seek_prey_system",
&["closest_prey_system"],
)
.with(
SeekSystem::<Predator>::new(
// 180 degrees, run away!
Rotation3::from_axis_angle(&Vector3::z_axis(), std::f32::consts::PI),
1.0,
),
"avoid_predator_system",
&["closest_predator_system"],
)
.with(
SeekSystem::<Obstacle>::new(
// 120 degrees. A little more than perpendicular so the creature
// tries to steer away from the wall rather than just follow it.
Rotation3::from_axis_angle(
&Vector3::z_axis(),
2f32 * std::f32::consts::FRAC_PI_3,
),
5.0,
),
"avoid_obstacle_system",
&["closest_obstacle_system"],
)
//.with(
//QueryPredatorsAndPreySystem,
//"query_predators_and_prey_system",
//&[],
//)
//.with(ClosestObstacleSystem, "closest_obstacle_system", &[])
//.with(
//ClosestSystem::<Prey>::default(),
//"closest_prey_system",
//&["query_predators_and_prey_system"],
//)
//.with(
//ClosestSystem::<Predator>::default(),
//"closest_predator_system",
//&["query_predators_and_prey_system"],
//)
//.with(
//SeekSystem::<Prey>::new(
//Rotation3::from_axis_angle(&Vector3::z_axis(), 0.0),
//1.0,
//),
//"seek_prey_system",
//&["closest_prey_system"],
//)
//.with(
//SeekSystem::<Predator>::new(
//// 180 degrees, run away!
//Rotation3::from_axis_angle(&Vector3::z_axis(), std::f32::consts::PI),
//1.0,
//),
//"avoid_predator_system",
//&["closest_predator_system"],
//)
//.with(
//SeekSystem::<Obstacle>::new(
//// 120 degrees. A little more than perpendicular so the creature
//// tries to steer away from the wall rather than just follow it.
//Rotation3::from_axis_angle(
//&Vector3::z_axis(),
//2f32 * std::f32::consts::FRAC_PI_3,
//),
//5.0,
//),
//"avoid_obstacle_system",
//&["closest_obstacle_system"],
//)
//.with(
//behaviors::wander::WanderSystem,
//"wander_system",
Expand Down
97 changes: 72 additions & 25 deletions src/systems/experimental/boids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use amethyst::{
};

use std::collections::HashMap;
use std::f32;

use crate::{
components::{boids::*, creatures::Movement, perception::DetectedEntities},
Expand Down Expand Up @@ -114,6 +115,7 @@ pub struct MinimumDistanceSystem;

impl<'s> System<'s> for MinimumDistanceSystem {
type SystemData = (
ReadStorage<'s, Named>,
ReadStorage<'s, MinimumDistanceRule>,
ReadStorage<'s, DetectedEntities>,
ReadStorage<'s, GlobalTransform>,
Expand All @@ -123,21 +125,29 @@ impl<'s> System<'s> for MinimumDistanceSystem {

fn run(
&mut self,
(min_distances, detected_entities, globals, mut movements, time): Self::SystemData,
(names, min_distances, detected_entities, globals, mut movements, time): Self::SystemData,
) {
let delta_time = time.delta_seconds();
for (min_distance, detected, global, movement) in
(&min_distances, &detected_entities, &globals, &mut movements).join()
for (name, min_distance, detected, global, movement) in (
&names,
&min_distances,
&detected_entities,
&globals,
&mut movements,
)
.join()
{
let sq_min_dist = min_distance.minimum * min_distance.minimum;
let pos = Vector4::from(global.as_ref()[3]).xyz();
let mut total_diff = Vector3::new(0.0, 0.0, 0.0);
for (other_global, _) in (&globals, &detected.entities).join() {
let other_pos = Vector4::from(other_global.as_ref()[3]).xyz();
let diff = pos - other_pos;
let dist = diff.norm_squared();
if dist < sq_min_dist {
total_diff += diff;
for (other_name, other_global, _) in (&names, &globals, &detected.entities).join() {
if name.name == other_name.name {
let other_pos = Vector4::from(other_global.as_ref()[3]).xyz();
let diff = pos - other_pos;
let dist = diff.norm_squared();
if dist < sq_min_dist {
total_diff += diff;
}
}
}
movement.velocity += delta_time * min_distance.strength * total_diff;
Expand Down Expand Up @@ -166,20 +176,59 @@ impl<'s> System<'s> for AvoidSystem {
(&avoid_rules, &detected_entities, &globals, &mut movements).join()
{
let pos = Vector4::from(global.as_ref()[3]).xyz();
let mut average_position = Vector3::new(0.0, 0.0, 0.0);
let mut count = 0;
let mut min_sq_dist = std::f32::MAX;
let mut min_pos = pos;
for (other_name, other_global, _) in (&names, &globals, &detected.entities).join() {
if rule.names.contains(&(&*other_name.name).to_string()) {
let other_pos = Vector4::from(other_global.as_ref()[3]).xyz();
average_position += other_pos;
count += 1;
let sq_dist = (other_pos - pos).norm_squared();
if sq_dist < min_sq_dist {
min_sq_dist = sq_dist;
min_pos = other_pos;
}
}
}
if count >= 1 {
average_position /= count as f32;
let diff_vector = average_position - pos;
movement.velocity -= delta_time * rule.strength * diff_vector;
let diff_vector = min_pos - pos;
movement.velocity -= delta_time * rule.strength * diff_vector;
}
}
}

pub struct SeekSystem;

impl<'s> System<'s> for SeekSystem {
type SystemData = (
ReadStorage<'s, Named>,
ReadStorage<'s, SeekRule>,
ReadStorage<'s, DetectedEntities>,
ReadStorage<'s, GlobalTransform>,
WriteStorage<'s, Movement>,
Read<'s, Time>,
);

fn run(
&mut self,
(names, seek_rules, detected_entities, globals, mut movements, time): Self::SystemData,
) {
let delta_time = time.delta_seconds();
for (rule, detected, global, movement) in
(&seek_rules, &detected_entities, &globals, &mut movements).join()
{
let pos = Vector4::from(global.as_ref()[3]).xyz();
let mut min_sq_dist = std::f32::MAX;
let mut min_pos = pos;
for (other_name, other_global, _) in (&names, &globals, &detected.entities).join() {
if rule.names.contains(&(&*other_name.name).to_string()) {
let other_pos = Vector4::from(other_global.as_ref()[3]).xyz();
let sq_dist = (other_pos - pos).norm_squared();
if sq_dist < min_sq_dist {
min_sq_dist = sq_dist;
min_pos = other_pos;
}
}
}
let diff_vector = min_pos - pos;
movement.velocity += delta_time * rule.strength * diff_vector;
}
}
}
Expand All @@ -201,16 +250,14 @@ impl<'s> System<'s> for WorldBoundsSystem {
let pos = Vector4::from(global.as_ref()[3]).xyz();

if pos[0] < bounds.left {
movement.velocity[0] += delta_time * rule.strength;
}
if pos[0] > bounds.right {
movement.velocity[0] -= delta_time * rule.strength;
movement.velocity[0] += delta_time * rule.strength * (bounds.left - pos[0]);
} else if pos[0] > bounds.right {
movement.velocity[0] -= delta_time * rule.strength * (pos[0] - bounds.right);
}
if pos[1] < bounds.bottom {
movement.velocity[1] += delta_time * rule.strength;
}
if pos[1] > bounds.top {
movement.velocity[1] -= delta_time * rule.strength;
movement.velocity[1] += delta_time * rule.strength * (bounds.bottom - pos[1]);
} else if pos[1] > bounds.top {
movement.velocity[1] -= delta_time * rule.strength * (pos[1] - bounds.top);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/systems/spawner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Distribution<CreatureTypeDistribution> for Standard {
0 => CreatureTypeDistribution {
creature_type: "Carnivore".to_string(),
},
1 => CreatureTypeDistribution {
1 | 2 | 3 => CreatureTypeDistribution {
creature_type: "Plant".to_string(),
},
_ => CreatureTypeDistribution {
Expand Down

0 comments on commit 334924e

Please sign in to comment.