Basically the intro works...

There's def some bugs with clicking through the intro title...
main
Elijah C. Voigt 2 years ago
parent 95559d8887
commit 52f978e70a

@ -4,28 +4,26 @@ fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, init) .add_systems(Startup, init)
.add_systems(Update, add_shadows) .add_systems(Update, add_shadows)
.run(); .run();
} }
fn init( fn init(server: Res<AssetServer>, mut commands: Commands) {
server: Res<AssetServer>, commands.spawn(SceneBundle {
mut commands: Commands, scene: server.load("models/shadow-example.gltf#Scene0"),
) { ..default()
commands.spawn(SceneBundle { });
scene: server.load("models/shadow-example.gltf#Scene0"),
..default()
});
} }
fn add_shadows( fn add_shadows(
mut lights: Query<(Entity, &mut PointLight), Added<PointLight>>, mut lights: Query<(Entity, &mut PointLight), Added<PointLight>>,
mut commands: Commands, mut commands: Commands,
) { ) {
lights.iter_mut().for_each(|(e, mut l)| { lights.iter_mut().for_each(|(e, mut l)| {
l.shadows_enabled = true; l.shadows_enabled = true;
let config: bevy::pbr::CascadeShadowConfig = bevy::pbr::CascadeShadowConfigBuilder { ..default() }.into(); let config: bevy::pbr::CascadeShadowConfig =
commands.entity(e).insert(config); bevy::pbr::CascadeShadowConfigBuilder { ..default() }.into();
}); commands.entity(e).insert(config);
});
} }

@ -27,7 +27,9 @@ impl Plugin for AudioPlugin {
audio_trigger.run_if(on_event::<AudioEvent>()), audio_trigger.run_if(on_event::<AudioEvent>()),
control_volume.run_if(resource_changed::<AudioVolume>), control_volume.run_if(resource_changed::<AudioVolume>),
toggle_volume.run_if(just_pressed(KeyCode::KeyM)), toggle_volume.run_if(just_pressed(KeyCode::KeyM)),
set_intensity.run_if(in_state(GameState::Play).and_then(resource_exists::<tweak::GameTweaks>.and_then(resource_changed::<game::Board>))), set_intensity.run_if(in_state(GameState::Play).and_then(
resource_exists::<tweak::GameTweaks>.and_then(resource_changed::<game::Board>),
)),
), ),
); );
} }
@ -171,10 +173,14 @@ fn set_intensity(
(intensity_ratio * intensity_range) + intensity_min (intensity_ratio * intensity_range) + intensity_min
}; };
query.iter() query
.iter()
.filter(|(_, event)| **event == AudioEvent::MainMusic) .filter(|(_, event)| **event == AudioEvent::MainMusic)
.for_each(|(source, _)| { .for_each(|(source, _)| {
info!("Setting music intensity to {:?}", value); info!("Setting music intensity to {:?}", value);
source.event_instance.set_parameter_by_name("Intensity", value, true).expect("Set intensity parameter"); source
.event_instance
.set_parameter_by_name("Intensity", value, true)
.expect("Set intensity parameter");
}); });
} }

@ -1,5 +1,5 @@
use bevy::core_pipeline::{ use bevy::core_pipeline::{
contrast_adaptive_sharpening::ContrastAdaptiveSharpeningSettings, fxaa::Fxaa contrast_adaptive_sharpening::ContrastAdaptiveSharpeningSettings, fxaa::Fxaa,
}; };
use crate::prelude::*; use crate::prelude::*;
@ -12,6 +12,7 @@ impl Plugin for Display3dPlugin {
TemporalAntiAliasPlugin, TemporalAntiAliasPlugin,
MaterialPlugin::<DissolveMaterial>::default(), MaterialPlugin::<DissolveMaterial>::default(),
)) ))
.init_state::<DissolvingAnimation>()
.insert_resource(Msaa::Off) .insert_resource(Msaa::Off)
.insert_resource(AmbientLight { .insert_resource(AmbientLight {
color: Color::WHITE, color: Color::WHITE,
@ -28,7 +29,7 @@ impl Plugin for Display3dPlugin {
// Systems related to color and camera // Systems related to color and camera
.add_systems( .add_systems(
Update, Update,
( (
color_grading_tweak color_grading_tweak
.run_if(resource_exists::<tweak::GameTweaks>) .run_if(resource_exists::<tweak::GameTweaks>)
.run_if(on_event::<AssetEvent<Tweaks>>()), .run_if(on_event::<AssetEvent<Tweaks>>()),
@ -38,7 +39,7 @@ impl Plugin for Display3dPlugin {
bloom_tweak bloom_tweak
.run_if(resource_exists::<tweak::GameTweaks>) .run_if(resource_exists::<tweak::GameTweaks>)
.run_if(on_event::<AssetEvent<Tweaks>>()), .run_if(on_event::<AssetEvent<Tweaks>>()),
) ),
) )
.add_systems( .add_systems(
Update, Update,
@ -83,9 +84,9 @@ impl Plugin for Display3dPlugin {
skip_animation skip_animation
.run_if(in_state(GameState::Play)) .run_if(in_state(GameState::Play))
.run_if(pressed(KeyCode::Enter).or_else(pressed(MouseButton::Left))), .run_if(pressed(KeyCode::Enter).or_else(pressed(MouseButton::Left))),
un_skip_animation un_skip_animation.run_if(in_state(GameState::Play)).run_if(
.run_if(in_state(GameState::Play)) just_released(KeyCode::Enter).or_else(just_released(MouseButton::Left)),
.run_if(just_released(KeyCode::Enter).or_else(just_released(MouseButton::Left))), ),
monitor_animations monitor_animations
.run_if(in_state(GameState::Play)) .run_if(in_state(GameState::Play))
.run_if(any_component_changed::<AnimationPlayer>()), .run_if(any_component_changed::<AnimationPlayer>()),
@ -105,18 +106,22 @@ impl Plugin for Display3dPlugin {
.run_if(in_state(GameState::Play)) .run_if(in_state(GameState::Play))
.run_if(in_state(DisplayState::Display3d)), .run_if(in_state(DisplayState::Display3d)),
) )
.add_systems(
Update,
(
animate_title_light_in.run_if(in_state(DissolvingAnimation::In)),
animate_title_light_out.run_if(in_state(DissolvingAnimation::Out)),
)
)
.add_systems( .add_systems(
OnEnter(GameState::Intro), OnEnter(GameState::Intro),
( (
// Toggle hidden/visible 3d entities // Toggle hidden/visible 3d entities
manage_state_entities::<DisplayState>(), manage_state_entities::<DisplayState>(),
// fixup_shadows, // fixup_shadows,
color_grading_tweak color_grading_tweak.run_if(resource_exists::<tweak::GameTweaks>),
.run_if(resource_exists::<tweak::GameTweaks>), fog_tweak.run_if(resource_exists::<tweak::GameTweaks>),
fog_tweak bloom_tweak.run_if(resource_exists::<tweak::GameTweaks>),
.run_if(resource_exists::<tweak::GameTweaks>),
bloom_tweak
.run_if(resource_exists::<tweak::GameTweaks>),
update_pieces.run_if(resource_exists::<tweak::GameTweaks>), update_pieces.run_if(resource_exists::<tweak::GameTweaks>),
), ),
) )
@ -129,20 +134,17 @@ impl Plugin for Display3dPlugin {
.run_if(in_state(DisplayState::Display3d)), .run_if(in_state(DisplayState::Display3d)),
), ),
) )
.add_systems(OnEnter(GameState::Title), ( .add_systems(
fixup_shadows, OnEnter(GameState::Title),
intro_title_dissolve, (fixup_shadows, intro_title_dissolve),
)) )
.add_systems(OnExit(GameState::Title), outro_title_dissolve) .add_systems(OnExit(GameState::Title), outro_title_dissolve)
.add_systems( .add_systems(
Update, Update,
continue_title.run_if( continue_title
in_state(GameState::Title) .run_if(in_state(GameState::Title))
.and_then(not(any_with_component::<Dissolving>)) .run_if(not(any_with_component::<Dissolving>))
.and_then( .run_if(just_pressed(KeyCode::Enter).or_else(just_pressed(MouseButton::Left))),
just_pressed(KeyCode::Enter).or_else(just_pressed(MouseButton::Left)),
),
),
); );
} }
} }
@ -165,6 +167,14 @@ pub(crate) enum Dissolving {
Out(f32), Out(f32),
} }
#[derive(Debug, States, Hash, Default, PartialEq, Eq, Clone, Component)]
enum DissolvingAnimation {
#[default]
None,
In,
Out
}
#[derive(Debug, Resource, Clone)] #[derive(Debug, Resource, Clone)]
struct AssetsMap { struct AssetsMap {
hitbox_shape: Handle<Mesh>, hitbox_shape: Handle<Mesh>,
@ -356,9 +366,7 @@ fn hydrate_camera(
}, },
FogSettings { FogSettings {
color: Color::rgba(0.25, 0.25, 0.25, 1.0), color: Color::rgba(0.25, 0.25, 0.25, 1.0),
falloff: FogFalloff::Exponential { falloff: FogFalloff::Exponential { density: 0.0 },
density: 0.0,
},
..default() ..default()
}, },
)); ));
@ -465,7 +473,7 @@ fn set_board_model(
} }
fn set_title_model( fn set_title_model(
mut titles: Query<(&mut Handle<Scene>, &mut Transform), (Added<TitleText>, With<Display3d>)>, mut titles: Query<(&mut Handle<Scene>, &mut Transform, &mut Visibility), (Added<TitleText>, With<Display3d>)>,
gltfs: Res<Assets<Gltf>>, gltfs: Res<Assets<Gltf>>,
tweaks: Res<Assets<Tweaks>>, tweaks: Res<Assets<Tweaks>>,
tweaks_file: Res<tweak::GameTweaks>, tweaks_file: Res<tweak::GameTweaks>,
@ -473,7 +481,7 @@ fn set_title_model(
let tweak = tweaks let tweak = tweaks
.get(tweaks_file.handle.clone()) .get(tweaks_file.handle.clone())
.expect("Load tweakfile"); .expect("Load tweakfile");
titles.iter_mut().for_each(|(mut handle, mut transform)| { titles.iter_mut().for_each(|(mut handle, mut transform, mut visibility)| {
info!("Setting title model"); info!("Setting title model");
let assets_handle = tweak let assets_handle = tweak
.get_handle::<Gltf>("display3d_models_assets_file") .get_handle::<Gltf>("display3d_models_assets_file")
@ -489,9 +497,12 @@ fn set_title_model(
) )
.expect("Game title model") .expect("Game title model")
.clone(); .clone();
transform.translation -= Vec3::Y * 0.5; transform.translation -= Vec3::Y * 0.5;
transform.rotate_local_z(std::f32::consts::PI); transform.rotate_local_z(std::f32::consts::PI);
transform.rotate_local_y(std::f32::consts::PI / 2.0); transform.rotate_local_y(std::f32::consts::PI / 2.0);
*visibility = Visibility::Hidden;
}); });
} }
@ -631,8 +642,8 @@ fn update_pieces(
// Set scene model for this piece // Set scene model for this piece
// if *scene != *scene_handle { // if *scene != *scene_handle {
warn!("Updating scene for piece {:?}", entity); warn!("Updating scene for piece {:?}", entity);
*scene = scene_handle.clone(); *scene = scene_handle.clone();
// } // }
} }
}, },
@ -957,9 +968,7 @@ fn skip_animation(
}) })
} }
fn un_skip_animation( fn un_skip_animation(mut players: Query<&mut AnimationPlayer, With<Animating>>) {
mut players: Query<&mut AnimationPlayer, With<Animating>>,
) {
players.iter_mut().for_each(|mut p| { players.iter_mut().for_each(|mut p| {
debug!("Un-Skipping animation"); debug!("Un-Skipping animation");
p.set_speed(1.0); p.set_speed(1.0);
@ -1179,7 +1188,10 @@ struct Animating;
fn monitor_animations( fn monitor_animations(
active: Query<(Entity, &AnimationPlayer), (Changed<AnimationPlayer>, With<Animating>)>, active: Query<(Entity, &AnimationPlayer), (Changed<AnimationPlayer>, With<Animating>)>,
mut inactive: Query<(Entity, &mut AnimationPlayer), (Changed<AnimationPlayer>, Without<Animating>)>, mut inactive: Query<
(Entity, &mut AnimationPlayer),
(Changed<AnimationPlayer>, Without<Animating>),
>,
mut commands: Commands, mut commands: Commands,
) { ) {
// Remove Animating component from players that are done // Remove Animating component from players that are done
@ -1192,7 +1204,11 @@ fn monitor_animations(
// Set inactive entities to active // Set inactive entities to active
inactive.iter_mut().for_each(|(entity, mut player)| { inactive.iter_mut().for_each(|(entity, mut player)| {
if !player.is_finished() && *player.animation_clip() != Handle::<AnimationClip>::default() { if !player.is_finished() && *player.animation_clip() != Handle::<AnimationClip>::default() {
info!("Entity {:?} is playing {:?}, adding animating marker", entity, player.animation_clip()); info!(
"Entity {:?} is playing {:?}, adding animating marker",
entity,
player.animation_clip()
);
commands.entity(entity).insert(Animating); commands.entity(entity).insert(Animating);
player.set_speed(1.0); player.set_speed(1.0);
} }
@ -1202,22 +1218,26 @@ fn monitor_animations(
fn intro_title_dissolve( fn intro_title_dissolve(
mut query: Query<(Entity, &Dissolvable), With<TitleText>>, mut query: Query<(Entity, &Dissolvable), With<TitleText>>,
mut commands: Commands, mut commands: Commands,
mut next: ResMut<NextState<DissolvingAnimation>>,
) { ) {
query.iter_mut().for_each(|(entity, dissolving)| { query.iter_mut().for_each(|(entity, dissolving)| {
commands commands
.entity(entity) .entity(entity)
.insert(Dissolving::In(dissolving.duration)); .insert(Dissolving::In(dissolving.duration));
next.set(DissolvingAnimation::In);
}); });
} }
fn outro_title_dissolve( fn outro_title_dissolve(
mut query: Query<(Entity, &Dissolvable), With<TitleText>>, mut query: Query<(Entity, &Dissolvable), With<TitleText>>,
mut commands: Commands, mut commands: Commands,
mut next: ResMut<NextState<DissolvingAnimation>>,
) { ) {
query.iter_mut().for_each(|(entity, dissolving)| { query.iter_mut().for_each(|(entity, dissolving)| {
commands commands
.entity(entity) .entity(entity)
.insert(Dissolving::Out(dissolving.duration)); .insert(Dissolving::Out(dissolving.duration));
next.set(DissolvingAnimation::Out);
}); });
} }
@ -1239,6 +1259,7 @@ fn dissolve_animation(
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mouse: Res<ButtonInput<MouseButton>>, mouse: Res<ButtonInput<MouseButton>>,
time: Res<Time>, time: Res<Time>,
mut next: ResMut<NextState<DissolvingAnimation>>,
) { ) {
query query
.iter_mut() .iter_mut()
@ -1294,6 +1315,7 @@ fn dissolve_animation(
entity, percentage entity, percentage
); );
commands.entity(entity).remove::<Dissolving>(); commands.entity(entity).remove::<Dissolving>();
next.set(DissolvingAnimation::None);
} }
}); });
} }
@ -1330,7 +1352,10 @@ fn color_grading_tweak(
query.iter_mut().for_each(|mut cg| { query.iter_mut().for_each(|mut cg| {
*cg = ColorGrading { *cg = ColorGrading {
exposure, gamma, pre_saturation, post_saturation exposure,
gamma,
pre_saturation,
post_saturation,
} }
}) })
} }
@ -1340,7 +1365,6 @@ fn fog_tweak(
tweaks: Res<Assets<Tweaks>>, tweaks: Res<Assets<Tweaks>>,
tweaks_file: Res<tweak::GameTweaks>, tweaks_file: Res<tweak::GameTweaks>,
) { ) {
query.iter_mut().for_each(|mut fog| { query.iter_mut().for_each(|mut fog| {
let tweak = tweaks let tweak = tweaks
.get(tweaks_file.handle.clone()) .get(tweaks_file.handle.clone())
@ -1365,3 +1389,71 @@ fn bloom_tweak(
bloom.intensity = tweak.get::<f32>("color_bloom_intensity").unwrap(); bloom.intensity = tweak.get::<f32>("color_bloom_intensity").unwrap();
}) })
} }
fn animate_title_light_in(
mut query: Query<(Entity, &mut Visibility), With<TitleText>>,
children: Query<&Children>,
mut lights: Query<&mut SpotLight>,
mut t: Local<Timer>,
mut started: Local<bool>,
time: Res<Time>,
) {
// Over 6 seconds, fade in to 600 intensity
if !(*started) {
*t = Timer::from_seconds(6.0, TimerMode::Once);
*started = true
} else {
t.tick(time.delta());
}
info!("Spotlight in");
let intensity = t.fraction() * 409800.0;
query.iter_mut().for_each(|(e, mut v)| {
if *v == Visibility::Hidden {
*v = Visibility::Inherited;
}
children.iter_descendants(e).for_each(|c| {
if let Ok(mut spot_light) = lights.get_mut(c) {
info!("SPOTLIGHT UPDATE {:?}", spot_light);
spot_light.intensity = intensity;
}
})
});
}
fn animate_title_light_out(
mut query: Query<(Entity, &mut Visibility), With<TitleText>>,
children: Query<&Children>,
mut lights: Query<&mut SpotLight>,
mut t: Local<Timer>,
mut started: Local<bool>,
time: Res<Time>,
) {
// Over 6 seconds, fade in to 600 intensity
if !(*started) {
*t = Timer::from_seconds(3.0, TimerMode::Once);
*started = true
} else {
t.tick(time.delta());
}
info!("Spotlight out");
let intensity = (1.0 - t.fraction()) * 409800.0;
query.iter_mut().for_each(|(e, mut v)| {
if *v == Visibility::Hidden {
*v = Visibility::Inherited;
}
children.iter_descendants(e).for_each(|c| {
if let Ok(mut spot_light) = lights.get_mut(c) {
info!("SPOTLIGHT UPDATE {:?}", spot_light);
spot_light.intensity = intensity;
}
})
});
}

@ -236,6 +236,7 @@ fn scroll_text(
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mouse: Res<ButtonInput<MouseButton>>, mouse: Res<ButtonInput<MouseButton>>,
parents: Query<&Parent>, parents: Query<&Parent>,
mut prompt: ResMut<NextState<ui::Prompt>>,
mut commands: Commands, mut commands: Commands,
) { ) {
let tweak = tweaks.get(tweaks_file.handle.clone()).expect("Load tweaks"); let tweak = tweaks.get(tweaks_file.handle.clone()).expect("Load tweaks");
@ -282,6 +283,9 @@ fn scroll_text(
// If the entire paragraph is played out, remove the component // If the entire paragraph is played out, remove the component
if text.sections.iter().all(|s| s.style.color == text_color) { if text.sections.iter().all(|s| s.style.color == text_color) {
commands.entity(entity).remove::<ui::TextScroll>(); commands.entity(entity).remove::<ui::TextScroll>();
// Let the user know they can skip this
prompt.set(ui::Prompt::ClickToContinue);
} }
}); });
} }

@ -4,20 +4,26 @@ pub(crate) struct UiPlugin;
impl Plugin for UiPlugin { impl Plugin for UiPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Startup, load_assets).add_systems( app.add_systems(Startup, load_assets)
Update, .init_state::<Prompt>()
( .add_systems(Startup, init_prompts)
manage_cursor.run_if( .add_systems(
any_component_changed::<Interaction>().or_else(state_changed::<GameState>), Update,
(
manage_cursor.run_if(
any_component_changed::<Interaction>().or_else(state_changed::<GameState>),
),
interactive_button.run_if(any_component_changed::<Interaction>()),
scale_ui.run_if(
on_event::<AssetEvent<tweak::Tweaks>>()
.or_else(any_component_changed::<Window>())
.and_then(resource_exists::<tweak::GameTweaks>),
),
), ),
interactive_button.run_if(any_component_changed::<Interaction>()), )
scale_ui.run_if( .add_systems(OnEnter(GameState::Intro), show_click_prompt)
on_event::<AssetEvent<tweak::Tweaks>>() .add_systems(OnExit(GameState::Title), hide_click_prompt)
.or_else(any_component_changed::<Window>()) ;
.and_then(resource_exists::<tweak::GameTweaks>),
),
),
);
} }
} }
@ -35,6 +41,13 @@ pub(crate) struct TextScroll {
#[derive(Debug, Component)] #[derive(Debug, Component)]
pub(crate) struct TextScrollAnimation; pub(crate) struct TextScrollAnimation;
#[derive(Debug, States, Hash, Default, PartialEq, Eq, Clone, Component)]
pub(crate) enum Prompt {
#[default]
None,
ClickToContinue,
}
fn load_assets(server: ResMut<AssetServer>, mut commands: Commands) { fn load_assets(server: ResMut<AssetServer>, mut commands: Commands) {
commands.insert_resource(UiFont { commands.insert_resource(UiFont {
handle: server.load("fonts/Silkscreen/Silkscreen-Regular.ttf"), handle: server.load("fonts/Silkscreen/Silkscreen-Regular.ttf"),
@ -145,3 +158,45 @@ fn scale_ui(
} }
}); });
} }
fn init_prompts(mut commands: Commands) {
// ClickToContinue
commands
.spawn((
Prompt::ClickToContinue,
NodeBundle {
style: Style {
position_type: PositionType::Absolute,
width: Val::Percent(100.0),
height: Val::Auto,
bottom: Val::Px(0.0),
align_items: AlignItems::Center,
justify_items: JustifyItems::Center,
justify_content: JustifyContent::Center,
..default()
},
visibility: Visibility::Hidden,
..default()
},
))
.with_children(|parent| {
parent.spawn(TextBundle {
style: Style { ..default() },
text: Text::from_section("Click to continue", TextStyle { ..default() }),
visibility: Visibility::Inherited,
..default()
});
});
}
fn show_click_prompt(
mut query: Query<(&mut Visibility, &Prompt)>,
) {
query.iter_mut().for_each(|(mut vis, _)| *vis = Visibility::Inherited);
}
fn hide_click_prompt(
mut query: Query<(&mut Visibility, &Prompt)>,
) {
query.iter_mut().for_each(|(mut vis, _)| *vis = Visibility::Hidden);
}
Loading…
Cancel
Save