Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

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!();
}