Add anthilll + ants spawning from it over time
This commit is contained in:
BIN
assets/sprites/anthill.png
Normal file
BIN
assets/sprites/anthill.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 180 KiB |
45
src/components/anthill.rs
Normal file
45
src/components/anthill.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Bundle)]
|
||||||
|
#[allow(clippy::module_name_repetitions)]
|
||||||
|
pub struct AnthillBundle {
|
||||||
|
pub capacity: AntCapacity,
|
||||||
|
pub group_size: GroupSize,
|
||||||
|
pub spawn_timer: SpawnTimer,
|
||||||
|
pub sprite: SpriteBundle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct AntCapacity(pub u32);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct GroupSize(pub u32);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct SpawnTimer(pub Timer);
|
||||||
|
|
||||||
|
impl AnthillBundle {
|
||||||
|
pub fn new(
|
||||||
|
ant_count: u32,
|
||||||
|
group_size: u32,
|
||||||
|
period: f32,
|
||||||
|
position: Vec2,
|
||||||
|
scale: Vec2,
|
||||||
|
texture: Handle<Image>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
capacity: AntCapacity(ant_count),
|
||||||
|
group_size: GroupSize(group_size),
|
||||||
|
spawn_timer: SpawnTimer(Timer::from_seconds(period, TimerMode::Repeating)),
|
||||||
|
sprite: SpriteBundle {
|
||||||
|
transform: Transform {
|
||||||
|
translation: position.extend(1.), // Make sure the anthill occludes the ants
|
||||||
|
scale: scale.extend(1.),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
texture,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
pub mod ant;
|
pub mod ant;
|
||||||
|
pub mod anthill;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
@ -9,6 +9,7 @@ use systems::{
|
|||||||
animation_system, position_update_system, randomized_velocity_change_system,
|
animation_system, position_update_system, randomized_velocity_change_system,
|
||||||
randomized_velocity_system, wall_avoidance_system,
|
randomized_velocity_system, wall_avoidance_system,
|
||||||
},
|
},
|
||||||
|
anthill::leave_anthill_system,
|
||||||
startup::{hello_ants_system, setup_system},
|
startup::{hello_ants_system, setup_system},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -16,9 +17,9 @@ use systems::{
|
|||||||
const MIN_POSITION: Vec2 = Vec2::splat(-450.);
|
const MIN_POSITION: Vec2 = Vec2::splat(-450.);
|
||||||
const MAX_POSITION: Vec2 = Vec2::splat(450.);
|
const MAX_POSITION: Vec2 = Vec2::splat(450.);
|
||||||
|
|
||||||
const ANT_COUNT: u32 = 200;
|
const ANT_COUNT: u32 = 20;
|
||||||
const ANT_SPEED: f32 = 0.5;
|
const ANT_SPEED: f32 = 0.5;
|
||||||
const ANT_ANIMATION_SPEED: f32 = 1. / 62.;
|
const ANT_ANIMATION_SPEED: f32 = 1. / 82.;
|
||||||
const ANT_SCALE: f32 = 0.15;
|
const ANT_SCALE: f32 = 0.15;
|
||||||
|
|
||||||
const VELOCITY_CHANGE_SCALE: f32 = PI / 180. * 1.; // Single degree
|
const VELOCITY_CHANGE_SCALE: f32 = PI / 180. * 1.; // Single degree
|
||||||
@ -53,6 +54,7 @@ fn main() {
|
|||||||
app.add_systems(
|
app.add_systems(
|
||||||
FixedUpdate,
|
FixedUpdate,
|
||||||
(
|
(
|
||||||
|
leave_anthill_system,
|
||||||
randomized_velocity_change_system,
|
randomized_velocity_change_system,
|
||||||
randomized_velocity_system,
|
randomized_velocity_system,
|
||||||
wall_avoidance_system,
|
wall_avoidance_system,
|
||||||
|
72
src/systems/anthill.rs
Normal file
72
src/systems/anthill.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
components::{
|
||||||
|
ant::AntBundle,
|
||||||
|
anthill::{AntCapacity, GroupSize, SpawnTimer},
|
||||||
|
common::AnimationIndices,
|
||||||
|
},
|
||||||
|
ANT_COUNT, ANT_SCALE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
pub fn leave_anthill_system(
|
||||||
|
mut query: Query<(&mut AntCapacity, &GroupSize, &mut SpawnTimer)>,
|
||||||
|
mut commands: Commands,
|
||||||
|
time: Res<Time>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
||||||
|
) {
|
||||||
|
for (mut capacity, group_size, mut timer) in &mut query {
|
||||||
|
timer.0.tick(time.delta());
|
||||||
|
|
||||||
|
// Anthill empty :(
|
||||||
|
if capacity.0 == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each timer period we want to spawn between 1 and group_size ants
|
||||||
|
if timer.0.just_finished() {
|
||||||
|
let num_ants: u32 = rand::thread_rng()
|
||||||
|
.gen_range(1..group_size.0)
|
||||||
|
.clamp(1, capacity.0);
|
||||||
|
|
||||||
|
for _ in 0..num_ants {
|
||||||
|
spawn_cute_ant(&mut commands, &asset_server, &mut texture_atlas_layouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
capacity.0 -= num_ants;
|
||||||
|
println!(
|
||||||
|
"Spawned {} cute ants 😍, {} ants are still at home 🏠",
|
||||||
|
num_ants, capacity.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_cute_ant(
|
||||||
|
commands: &mut Commands,
|
||||||
|
asset_server: &Res<AssetServer>,
|
||||||
|
texture_atlas_layouts: &mut ResMut<Assets<TextureAtlasLayout>>,
|
||||||
|
) {
|
||||||
|
// https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_sheet.rs
|
||||||
|
let texture: Handle<Image> = asset_server.load("sprites/ant_walk_anim.png");
|
||||||
|
let layout = TextureAtlasLayout::from_grid(UVec2::new(202, 248), 8, 8, None, None);
|
||||||
|
let texture_atlas_layout = texture_atlas_layouts.add(layout);
|
||||||
|
let animation_indices = AnimationIndices { first: 0, last: 61 };
|
||||||
|
let texture_atlas = TextureAtlas {
|
||||||
|
layout: texture_atlas_layout,
|
||||||
|
index: rand::thread_rng().gen_range(animation_indices.first..=animation_indices.last),
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.spawn(AntBundle::new(
|
||||||
|
Vec2::ZERO,
|
||||||
|
texture,
|
||||||
|
texture_atlas,
|
||||||
|
animation_indices,
|
||||||
|
Vec2::splat(ANT_SCALE),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enter_anthill_system() {}
|
@ -1,2 +1,3 @@
|
|||||||
pub mod ant;
|
pub mod ant;
|
||||||
|
pub mod anthill;
|
||||||
pub mod startup;
|
pub mod startup;
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
use crate::{
|
use crate::{components::anthill::AnthillBundle, ANT_COUNT};
|
||||||
components::{ant::AntBundle, common::AnimationIndices},
|
|
||||||
ANT_COUNT, ANT_SCALE, MAX_POSITION,
|
|
||||||
};
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use rand::Rng;
|
|
||||||
|
|
||||||
/// Signal that the app has started by printing a message to the terminal.
|
/// Signal that the app has started by printing a message to the terminal.
|
||||||
pub fn hello_ants_system() {
|
pub fn hello_ants_system() {
|
||||||
@ -12,35 +8,18 @@ pub fn hello_ants_system() {
|
|||||||
|
|
||||||
/// Prepares the environment before the Update schedule by spawning required entities.
|
/// Prepares the environment before the Update schedule by spawning required entities.
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
pub fn setup_system(
|
pub fn setup_system(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
mut commands: Commands,
|
|
||||||
asset_server: Res<AssetServer>,
|
|
||||||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
|
||||||
) {
|
|
||||||
// Using the default camera, world space coordinates correspond 1:1 with screen pixels.
|
// Using the default camera, world space coordinates correspond 1:1 with screen pixels.
|
||||||
// The point (0, 0) is in the center of the screen.
|
// The point (0, 0) is in the center of the screen.
|
||||||
commands.spawn(Camera2dBundle::default());
|
commands.spawn(Camera2dBundle::default());
|
||||||
|
|
||||||
// Spawn cute ants
|
// Spawn the anthill that will spawn the ants
|
||||||
// https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_sheet.rs
|
commands.spawn(AnthillBundle::new(
|
||||||
// TODO: Some weird cloning here
|
ANT_COUNT,
|
||||||
let texture: Handle<Image> = asset_server.load("sprites/ant_walk_anim.png");
|
5,
|
||||||
let layout = TextureAtlasLayout::from_grid(UVec2::new(202, 248), 8, 8, None, None);
|
1.,
|
||||||
let texture_atlas_layout = texture_atlas_layouts.add(layout);
|
|
||||||
for _ in 0..ANT_COUNT {
|
|
||||||
let animation_indices = AnimationIndices { first: 0, last: 61 };
|
|
||||||
let texture_atlas = TextureAtlas {
|
|
||||||
layout: texture_atlas_layout.clone(),
|
|
||||||
index: rand::thread_rng().gen_range(animation_indices.first..=animation_indices.last),
|
|
||||||
};
|
|
||||||
|
|
||||||
commands.spawn(AntBundle::new(
|
|
||||||
Vec2::ZERO,
|
Vec2::ZERO,
|
||||||
texture.clone(),
|
Vec2::splat(0.2),
|
||||||
texture_atlas,
|
asset_server.load("sprites/anthill.png"),
|
||||||
animation_indices,
|
|
||||||
Vec2::splat(ANT_SCALE),
|
|
||||||
));
|
));
|
||||||
}
|
|
||||||
println!("Spawned {ANT_COUNT} cute ants 😍");
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user