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(
Update,
(
menu::exit_to_menu.run_if(in_state(GameState::Play)),
menu::exit_to_menu.run_if(in_state(GameState::Endgame)),
menu::exit_to_menu
.run_if(in_state(GameState::Play).or_else(in_state(GameState::Endgame))),
update_board
.run_if(on_event::<Move>())
.after(handle_selection),

@ -6,35 +6,32 @@ pub(crate) struct IntroPlugin;
impl Plugin for IntroPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
app.init_resource::<CurrentIntroParagraph>()
.add_systems(
OnExit(GameState::Loading),
init_intro_text
.run_if(resource_exists::<tweak::GameTweaks>())
.run_if(run_once()),
)
.add_systems(OnEnter(GameState::Intro), manage_intro)
.add_systems(OnExit(GameState::Intro), deactivate::<Intro>)
.add_systems(
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(OnExit(GameState::Intro), (deactivate::<Intro>, cleanup_intro))
// All of these run during GameState::Intro
.add_systems(
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
scroll_text
.run_if(in_state(GameState::Intro))
.run_if(any_with_component::<ui::TextScroll>()),
(
menu::exit_to_menu,
manage_intro.run_if(any_component_removed::<ui::TextScrollAnimation>()),
// 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(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>)>,
mut commands: Commands,
) {
info!("Managing intro");
query.iter().for_each(|e| {
commands
.entity(e)
.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(
roots: Query<Entity, With<ui::TextScrollAnimation>>,
roots: Query<Entity, Or<(With<ui::TextScrollAnimation>, Added<ui::TextScrollAnimation>)>>,
texts: Query<Entity, (With<Text>, With<Intro>)>,
animated_texts: Query<&ui::TextScroll>,
parents: Query<&Parent>,
@ -144,9 +174,11 @@ fn manage_scroll_text_animation(
time: Res<Time>,
framecount: Res<FrameCount>,
mut next_state: ResMut<NextState<GameState>>,
mut curr: Local<Option<Entity>>,
mut curr: ResMut<CurrentIntroParagraph>,
mut commands: Commands,
) {
info!("Managing scroll text animation");
roots.iter().for_each(|r| {
info!("Processing {:?} at frame {:?}", r, framecount.0);
@ -154,14 +186,14 @@ fn manage_scroll_text_animation(
if animated_texts.is_empty() {
info!(
"No animations playing, moving on to next paragraph {:?}",
*curr
curr.0
);
// Create an iterator over all paragraphs
let mut paragraphs = texts.iter_many(children.iter_descendants(r));
if curr.is_some() {
if curr.0.is_some() {
// Hide the last active entity
if let Some(e) = *curr {
if let Some(e) = curr.0 {
let p = parents.get(e).unwrap();
commands.entity(p.get()).insert(Visibility::Hidden);
@ -169,18 +201,17 @@ fn manage_scroll_text_animation(
}
// Locate the last entity we were operating with
while let Some(entity) = paragraphs.next() {
if *curr == Some(entity) {
if curr.0 == Some(entity) {
break;
}
}
}
// 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 {
if let Some(e) = curr.0 {
commands.entity(e).insert(ui::TextScroll {
progress: 0,
start: time.elapsed_seconds(),

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

Loading…
Cancel
Save