use crate::GameState; use bevy::{ color::palettes::css::{BLACK, GREEN, LIGHT_BLUE, RED}, prelude::*, }; pub fn preparation_widget_plugin(app: &mut App) { app.add_systems(OnEnter(GameState::GetReady), spawn_get_ready) .add_systems(OnExit(GameState::GetReady), despawn_get_ready) .add_systems( Update, (animate_get_ready_widget).run_if(in_state(GameState::GetReady)), ) .insert_resource(ReadySetGoTimer(Timer::from_seconds(3.0, TimerMode::Once))); } /// Marker component for things on the get-ready indicator #[derive(Component)] struct OnReadySetGo; /// Newtype wrapper for `Timer`. Used to count down during the "get ready" phase. #[derive(Deref, DerefMut, Resource)] struct ReadySetGoTimer(Timer); /// Marker for the counter text segment #[derive(Component)] struct CountdownText; /// Marker for the counter bar segment #[derive(Component)] struct CountdownBar; fn spawn_get_ready(mut commands: Commands) { commands.spawn(( OnReadySetGo, // marker, so this can be de-spawned properly Node { align_self: AlignSelf::Center, justify_self: JustifySelf::Center, align_items: AlignItems::Center, justify_content: JustifyContent::Center, flex_direction: FlexDirection::Column, width: Val::Percent(30.), height: Val::Percent(30.), ..default() }, BackgroundColor(LIGHT_BLUE.into()), children![ (Text::new("Get Ready!"), TextColor(BLACK.into())), ( CountdownBar, Node { width: Val::Percent(90.0), height: Val::Percent(10.), ..default() }, BackgroundColor(GREEN.into()), ), ( CountdownText, Text::new(""), TextColor(RED.into()), ) ], )); } // TODO: Replace this with a generic somewhere else in the crate // want: `despawn_screen::>()` fn despawn_get_ready(mut commands: Commands, to_despawn: Query>) { for entity in to_despawn { commands.entity(entity).despawn(); } } fn animate_get_ready_widget( mut text_segment: Single<&mut Text, With>, mut bar_segment: Single<&mut Node, With>, time: Res