it is ugly, but it works. Intro is idempotent

main
Elijah C. Voigt 2 years ago
parent 6e68b2fc2a
commit 80ee571cb1

@ -16,8 +16,8 @@ impl Plugin for GamePlugin {
.add_systems( .add_systems(
Update, Update,
( (
menu::exit_to_menu.run_if(in_state(GameState::Play)), menu::exit_to_menu
menu::exit_to_menu.run_if(in_state(GameState::Endgame)), .run_if(in_state(GameState::Play).or_else(in_state(GameState::Endgame))),
update_board update_board
.run_if(on_event::<Move>()) .run_if(on_event::<Move>())
.after(handle_selection), .after(handle_selection),

@ -6,35 +6,32 @@ pub(crate) struct IntroPlugin;
impl Plugin for IntroPlugin { impl Plugin for IntroPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems( app.init_resource::<CurrentIntroParagraph>()
.add_systems(
OnExit(GameState::Loading), OnExit(GameState::Loading),
init_intro_text init_intro_text
.run_if(resource_exists::<tweak::GameTweaks>()) .run_if(resource_exists::<tweak::GameTweaks>())
.run_if(run_once()), .run_if(run_once()),
) )
.add_systems(OnEnter(GameState::Intro), manage_intro) .add_systems(OnEnter(GameState::Intro), manage_intro)
.add_systems(OnExit(GameState::Intro), deactivate::<Intro>) .add_systems(OnExit(GameState::Intro), (deactivate::<Intro>, cleanup_intro))
.add_systems( // All of these run during GameState::Intro
Update,
manage_intro.run_if(any_component_removed::<ui::TextScrollAnimation>()),
)
.add_systems(
Update,
// Started when the TextScrollAnimation component is added to the parent entity
// Updated for as long as there is scrolling text
manage_scroll_text_animation
.run_if(in_state(GameState::Intro))
.run_if(any_component_added::<ui::TextScrollAnimation>.or_else(
|keys: Res<Input<KeyCode>>| -> bool { keys.just_pressed(KeyCode::Return) },
)),
)
.add_systems( .add_systems(
Update, Update,
// Play intro manages playing the intro of each individual paragraph (
// Runs every time the TextScroll component (managed by manage_scroll_text_animation) is updated menu::exit_to_menu,
scroll_text manage_intro.run_if(any_component_removed::<ui::TextScrollAnimation>()),
.run_if(in_state(GameState::Intro)) // Started when the TextScrollAnimation component is added to the parent entity
.run_if(any_with_component::<ui::TextScroll>()), // Updated for as long as there is scrolling text
manage_scroll_text_animation
.run_if(any_component_added::<ui::TextScrollAnimation>.or_else(
|keys: Res<Input<KeyCode>>| -> bool { keys.just_pressed(KeyCode::Return) },
)),
// Play intro manages playing the intro of each individual paragraph
// Runs every time the TextScroll component (managed by manage_scroll_text_animation) is updated
scroll_text
.run_if(any_with_component::<ui::TextScroll>()),
).run_if(in_state(GameState::Intro))
); );
} }
} }
@ -127,16 +124,49 @@ fn manage_intro(
query: Query<Entity, (With<Node>, With<Intro>, Without<Parent>)>, query: Query<Entity, (With<Node>, With<Intro>, Without<Parent>)>,
mut commands: Commands, mut commands: Commands,
) { ) {
info!("Managing intro");
query.iter().for_each(|e| { query.iter().for_each(|e| {
commands commands
.entity(e) .entity(e)
.insert(ui::TextScrollAnimation) .insert(ui::TextScrollAnimation)
.insert(Visibility::Inherited); .insert(Visibility::Visible);
}); });
} }
fn cleanup_intro(
query: Query<Entity, With<Intro>>,
mut texts: Query<&mut Text, With<Intro>>,
mut curr: ResMut<CurrentIntroParagraph>,
tweaks_file: Res<tweak::GameTweaks>,
tweaks: Res<Assets<tweak::Tweaks>>,
mut commands: Commands,
) {
info!("Cleaning up intro");
query.iter().for_each(|e| {
commands.entity(e).remove::<ui::TextScrollAnimation>().remove::<ui::TextScroll>().insert(Visibility::Hidden);
});
{
// Reset text colors
let tweak = tweaks.get(tweaks_file.handle.clone()).expect("Load tweaks");
let text_hidden_hex = tweak.get::<String>("intro_rgba_hidden").unwrap();
let text_hidden_color = Color::hex(text_hidden_hex).unwrap();
texts.iter_mut().for_each(|mut text| {
text.sections.iter_mut().for_each(|s| {
s.style.color = text_hidden_color;
});
});
}
curr.0 = None;
}
#[derive(Debug, Resource, Default)]
struct CurrentIntroParagraph(Option<Entity>);
fn manage_scroll_text_animation( fn manage_scroll_text_animation(
roots: Query<Entity, With<ui::TextScrollAnimation>>, roots: Query<Entity, Or<(With<ui::TextScrollAnimation>, Added<ui::TextScrollAnimation>)>>,
texts: Query<Entity, (With<Text>, With<Intro>)>, texts: Query<Entity, (With<Text>, With<Intro>)>,
animated_texts: Query<&ui::TextScroll>, animated_texts: Query<&ui::TextScroll>,
parents: Query<&Parent>, parents: Query<&Parent>,
@ -144,9 +174,11 @@ fn manage_scroll_text_animation(
time: Res<Time>, time: Res<Time>,
framecount: Res<FrameCount>, framecount: Res<FrameCount>,
mut next_state: ResMut<NextState<GameState>>, mut next_state: ResMut<NextState<GameState>>,
mut curr: Local<Option<Entity>>, mut curr: ResMut<CurrentIntroParagraph>,
mut commands: Commands, mut commands: Commands,
) { ) {
info!("Managing scroll text animation");
roots.iter().for_each(|r| { roots.iter().for_each(|r| {
info!("Processing {:?} at frame {:?}", r, framecount.0); info!("Processing {:?} at frame {:?}", r, framecount.0);
@ -154,14 +186,14 @@ fn manage_scroll_text_animation(
if animated_texts.is_empty() { if animated_texts.is_empty() {
info!( info!(
"No animations playing, moving on to next paragraph {:?}", "No animations playing, moving on to next paragraph {:?}",
*curr curr.0
); );
// Create an iterator over all paragraphs // Create an iterator over all paragraphs
let mut paragraphs = texts.iter_many(children.iter_descendants(r)); let mut paragraphs = texts.iter_many(children.iter_descendants(r));
if curr.is_some() { if curr.0.is_some() {
// Hide the last active entity // Hide the last active entity
if let Some(e) = *curr { if let Some(e) = curr.0 {
let p = parents.get(e).unwrap(); let p = parents.get(e).unwrap();
commands.entity(p.get()).insert(Visibility::Hidden); commands.entity(p.get()).insert(Visibility::Hidden);
@ -169,18 +201,17 @@ fn manage_scroll_text_animation(
} }
// Locate the last entity we were operating with // Locate the last entity we were operating with
while let Some(entity) = paragraphs.next() { while let Some(entity) = paragraphs.next() {
if *curr == Some(entity) { if curr.0 == Some(entity) {
break; break;
} }
} }
} }
// Operate on the next entity in the list // Operate on the next entity in the list
*curr = paragraphs.next(); curr.0 = paragraphs.next();
info!("Curr: {:?}", *curr); info!("Curr: {:?}", curr.0);
// TEMP: Just testing if the paragraph animation works if let Some(e) = curr.0 {
if let Some(e) = *curr {
commands.entity(e).insert(ui::TextScroll { commands.entity(e).insert(ui::TextScroll {
progress: 0, progress: 0,
start: time.elapsed_seconds(), start: time.elapsed_seconds(),

@ -165,8 +165,8 @@ fn initialize_tutorial(
style: Style { style: Style {
width: Val::Percent(100.0), width: Val::Percent(100.0),
height: Val::Percent(100.0), height: Val::Percent(100.0),
justify_content: JustifyContent::FlexStart, justify_content: JustifyContent::FlexEnd,
align_items: AlignItems::Center, align_items: AlignItems::FlexEnd,
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
padding: UiRect::all(Val::Px(50.0)), padding: UiRect::all(Val::Px(50.0)),
@ -183,6 +183,8 @@ fn initialize_tutorial(
step.clone(), step.clone(),
NodeBundle { NodeBundle {
style: Style { style: Style {
width: Val::Percent(33.0),
height: Val::Percent(33.0),
padding: UiRect::all(Val::Px(25.0)), padding: UiRect::all(Val::Px(25.0)),
..default() ..default()
}, },

Loading…
Cancel
Save