race.rs
use bevy::app::AppExit;
use bevy::ecs::schedule::ShouldRun;
use bevy::prelude::*;
const TRACK_LENGTH: f32 = 1000.;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
enum RaceState {
Running,
Finished,
}
pub struct Race;
impl Plugin for Race {
fn build(&self, app: &mut App) {
app.add_plugins(MinimalPlugins)
.add_state(RaceState::Running)
.insert_resource(RoundTimer(Timer::from_seconds(0.1, true)))
.add_startup_system(add_racers)
.add_system_set(
SystemSet::on_update(RaceState::Running)
.with_run_criteria(tick)
.with_system(racers_movement_system.label("move"))
.with_system(track_visualisation_system.label("display").after("move"))
.with_system(determine_end_system.after("display")),
)
.add_system_set(SystemSet::on_enter(RaceState::Finished).with_system(race_end_system));
}
}
fn tick(time: Res<Time>, mut timer: ResMut<RoundTimer>) -> ShouldRun {
if timer.0.tick(time.delta()).just_finished() {
ShouldRun::Yes
} else {
ShouldRun::No
}
}
#[derive(Component)]
struct Racer(usize);
#[derive(Component)]
struct Velocity(f32);
#[derive(Component)]
struct Position(f32);
#[derive(Component)]
struct Acceleration(f32);
fn add_racers(mut commands: Commands) {
let racer_init_stats: Vec<f32> = vec![2., 3., 0.5];
for (n, &a) in racer_init_stats.iter().enumerate() {
commands
.spawn()
.insert(Racer(n))
.insert(Position(0.))
.insert(Velocity(0.))
.insert(Acceleration(a));
}
}
struct RoundTimer(Timer);
fn racers_movement_system(
mut query: Query<(&mut Position, &mut Velocity, &Acceleration), With<Racer>>,
) {
for (mut p, mut v, a) in query.iter_mut() {
v.0 = v.0 + a.0;
p.0 = p.0 + v.0;
}
}
fn determine_end_system(mut state: ResMut<State<RaceState>>, query: Query<&Position>) {
if query.iter().map(|p| p.0).reduce(f32::max).unwrap() >= TRACK_LENGTH {
state.replace(RaceState::Finished).unwrap();
}
}
fn race_end_system(mut app_exit_events: EventWriter<AppExit>) {
app_exit_events.send(AppExit);
}
fn track_visualisation_system(racers_query: Query<(&Racer, &Position, &Velocity)>) {
for (r, p, v) in racers_query.iter() {
let progression = ((p.0 / TRACK_LENGTH * 100.).round() as usize).min(100);
print!(
"{:-^l$}#{:-^r$}",
"",
"",
l = progression,
r = 100 - progression
);
println!(" Racer {} position {}, velocity {}", r.0, p.0, v.0);
}
println!();
}