Fading title image

I agree it looks better than the dissolve 3d effect (with the board
dissolving behind it)

Probably needs tweaks but pretty good.
main
Elijah C. Voigt 1 year ago
parent ce697ba342
commit 29144126e9

@ -229,6 +229,7 @@ title = "Title"
[title] [title]
image = "images/title.png" image = "images/title.png"
fade_in_seconds = 6.0
width_px = 400.0 width_px = 400.0
[display3d.models.animations] [display3d.models.animations]

@ -99,7 +99,6 @@ impl Plugin for Display3dPlugin {
.or_else(any_component_removed::<Promoted>()), .or_else(any_component_removed::<Promoted>()),
), ),
set_board_model.run_if(any_component_added::<game::BoardComponent>()), set_board_model.run_if(any_component_added::<game::BoardComponent>()),
set_title_model.run_if(any_component_added::<TitleText>()),
set_valid_move_model.run_if(any_component_added::<game::ValidMove>()), set_valid_move_model.run_if(any_component_added::<game::ValidMove>()),
set_tile_hitbox.run_if(any_component_added::<game::Tile>()), set_tile_hitbox.run_if(any_component_added::<game::Tile>()),
dissolve_animation.run_if(any_with_component::<Dissolving>), dissolve_animation.run_if(any_with_component::<Dissolving>),
@ -164,17 +163,21 @@ impl Plugin for Display3dPlugin {
.add_systems( .add_systems(
OnEnter(GameState::Title), OnEnter(GameState::Title),
( (
intro_title_dissolve, fade_title_in,
fixup_shadows fixup_shadows
) )
) )
.add_systems(OnExit(GameState::Title), outro_title_dissolve) .add_systems(OnExit(GameState::Title), fade_title_out)
.add_systems( .add_systems(
Update, Update,
(
fade_title
.run_if(any_with_component::<Fading>),
continue_title continue_title
.run_if(in_state(GameState::Title)) .run_if(in_state(GameState::Title))
.run_if(not(any_with_component::<Dissolving>)) .run_if(not(any_with_component::<Fading>))
.run_if(just_pressed(KeyCode::Enter).or_else(just_pressed(MouseButton::Left))), .run_if(just_pressed(KeyCode::Enter).or_else(just_pressed(MouseButton::Left))),
)
); );
} }
} }
@ -197,6 +200,12 @@ pub(crate) enum Dissolving {
Out(f32), Out(f32),
} }
#[derive(Debug, Component)]
pub(crate) enum Fading {
In(f32),
Out(f32),
}
#[derive(Debug, Resource)] #[derive(Debug, Resource)]
pub(crate) struct AnimationSpeed { pub(crate) struct AnimationSpeed {
pub movement: f32, pub movement: f32,
@ -216,6 +225,7 @@ impl Default for AnimationSpeed {
struct AssetsMap { struct AssetsMap {
hitbox_shape: Handle<Mesh>, hitbox_shape: Handle<Mesh>,
hitbox_material: Handle<StandardMaterial>, hitbox_material: Handle<StandardMaterial>,
title_image: Handle<Image>,
} }
/// Load 3d models /// Load 3d models
@ -225,6 +235,8 @@ fn load_assets(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
tweaks_file: Res<tweak::GameTweaks>,
tweaks: Res<Assets<Tweaks>>,
) { ) {
let hitbox_shape = meshes.add(Cuboid::new(1.0, 0.1, 1.0)); let hitbox_shape = meshes.add(Cuboid::new(1.0, 0.1, 1.0));
let hitbox_material = materials.add(StandardMaterial { let hitbox_material = materials.add(StandardMaterial {
@ -234,15 +246,46 @@ fn load_assets(
alpha_mode: AlphaMode::Blend, alpha_mode: AlphaMode::Blend,
..default() ..default()
}); });
let tweak = tweaks
.get(tweaks_file.handle.clone())
.expect("Load tweakfile");
let title_image = tweak.get_handle::<Image>("title_image").unwrap();
commands.insert_resource(AssetsMap { commands.insert_resource(AssetsMap {
hitbox_shape, hitbox_shape,
hitbox_material, hitbox_material,
title_image,
}); });
} }
/// Initialize the board and pieces /// Initialize the board and pieces
fn initialize(mut commands: Commands, board: Res<game::Board>, assets: Res<AssetsMap>) { fn initialize(mut commands: Commands, board: Res<game::Board>, assets: Res<AssetsMap>) {
debug!("Initializing root"); debug!("Initializing root");
// Title
commands.spawn((
DisplayState::Display3d,
Display3d,
ImageBundle {
style: Style {
width: Val::Percent(75.0),
height: Val::Percent(75.0),
align_self: AlignSelf::Center,
justify_self: JustifySelf::Center,
..default()
},
background_color: Color::WHITE.with_a(0.0).into(),
image: UiImage {
texture: assets.title_image.clone(),
..default()
},
visibility: Visibility::Hidden,
..default()
},
TitleText,
));
// 3D objects root
commands commands
.spawn(( .spawn((
SpatialBundle { SpatialBundle {
@ -254,22 +297,6 @@ fn initialize(mut commands: Commands, board: Res<game::Board>, assets: Res<Asset
.with_children(|parent| { .with_children(|parent| {
debug!("Intializing 3D Board!"); debug!("Intializing 3D Board!");
// Title
parent.spawn((
DisplayState::Display3d,
Display3d,
// GameState::Title,
SceneBundle {
visibility: Visibility::Hidden,
..default()
},
TitleText,
Dissolvable {
start: 0.0,
duration: 12.0,
}, // Marks title text as dissolving
));
// Board // Board
parent parent
.spawn(( .spawn((
@ -530,45 +557,6 @@ fn set_board_model(
}); });
} }
fn set_title_model(
mut titles: Query<
(&mut Handle<Scene>, &mut Transform, &mut Visibility),
(Added<TitleText>, With<Display3d>),
>,
gltfs: Res<Assets<Gltf>>,
tweaks: Res<Assets<Tweaks>>,
tweaks_file: Res<tweak::GameTweaks>,
) {
let tweak = tweaks
.get(tweaks_file.handle.clone())
.expect("Load tweakfile");
titles
.iter_mut()
.for_each(|(mut handle, mut transform, mut visibility)| {
debug!("Setting title model");
let assets_handle = tweak
.get_handle::<Gltf>("display3d_models_assets_file")
.unwrap();
let gltf = gltfs.get(assets_handle).expect("Load GLTF content");
*handle = gltf
.named_scenes
.get(
tweak
.get::<String>("display3d_models_scenes_title")
.unwrap()
.as_str(),
)
.expect("Game title model")
.clone();
transform.translation -= Vec3::Y * 0.5;
transform.rotate_local_z(std::f32::consts::PI);
transform.rotate_local_y(std::f32::consts::PI / 2.0);
*visibility = Visibility::Hidden;
});
}
/// Given a board index returns the Vec3 location in space /// Given a board index returns the Vec3 location in space
fn board_translation(&BoardIndex { x, y }: &BoardIndex) -> Vec3 { fn board_translation(&BoardIndex { x, y }: &BoardIndex) -> Vec3 {
// Scale x down by 4 to account for -4..4 scaling // Scale x down by 4 to account for -4..4 scaling
@ -1269,28 +1257,6 @@ fn monitor_animations(
}); });
} }
fn intro_title_dissolve(
mut query: Query<(Entity, &Dissolvable), With<TitleText>>,
mut commands: Commands,
) {
query.iter_mut().for_each(|(entity, dissolving)| {
commands
.entity(entity)
.insert(Dissolving::In(dissolving.duration));
});
}
fn outro_title_dissolve(
mut query: Query<(Entity, &Dissolvable), With<TitleText>>,
mut commands: Commands,
) {
query.iter_mut().for_each(|(entity, dissolving)| {
commands
.entity(entity)
.insert(Dissolving::Out(dissolving.duration));
});
}
fn continue_title(mut next_state: ResMut<NextState<GameState>>) { fn continue_title(mut next_state: ResMut<NextState<GameState>>) {
next_state.set(GameState::Play) next_state.set(GameState::Play)
} }
@ -1438,3 +1404,71 @@ fn bloom_tweak(
bloom.intensity = tweak.get::<f32>("color_bloom_intensity").unwrap(); bloom.intensity = tweak.get::<f32>("color_bloom_intensity").unwrap();
}) })
} }
fn fade_title_in(
query: Query<Entity, With<TitleText>>,
tweaks: Res<Assets<Tweaks>>,
tweaks_file: Res<tweak::GameTweaks>,
mut commands: Commands,
) {
let tweak = tweaks
.get(tweaks_file.handle.clone())
.expect("Load tweakfile");
let seconds = tweak.get::<f32>("title_fade_in_seconds").unwrap();
query.iter().for_each(|e| {
commands.entity(e).insert(Fading::In(seconds));
})
}
fn fade_title_out(
query: Query<Entity, With<TitleText>>,
tweaks: Res<Assets<Tweaks>>,
tweaks_file: Res<tweak::GameTweaks>,
mut commands: Commands,
) {
let tweak = tweaks
.get(tweaks_file.handle.clone())
.expect("Load tweakfile");
let seconds = tweak.get::<f32>("title_fade_in_seconds").unwrap();
query.iter().for_each(|e| {
commands.entity(e).insert(Fading::Out(seconds));
})
}
fn fade_title(
mut query: Query<(Entity, &mut BackgroundColor, &mut Visibility, &Fading), With<TitleText>>,
time: Res<Time>,
mut commands: Commands,
) {
query.iter_mut().for_each(|(e, mut bgc, mut v, d)| {
if *v != Visibility::Inherited {
*v = Visibility::Inherited;
}
// Determine how much to change alpha
let step = match d {
Fading::In(duration) => {
// If we are fully saturated, remove dissolving
if bgc.0.a() >= 1.0 {
commands.entity(e).remove::<Fading>().insert(Visibility::Inherited);
}
// Delta is simple
time.delta_seconds() / duration
},
Fading::Out(duration) => {
// If we are fully saturated, remove dissolving
if bgc.0.a() <= 0.0 {
commands.entity(e).remove::<Fading>().insert(Visibility::Hidden);
}
// Negative delta because we are fading out
-(time.delta_seconds() / duration)
},
};
// Increment/decrement the alpha value
let new_a = (bgc.0.a() + step).min(1.0).max(0.0);
bgc.0.set_a(new_a);
})
}
Loading…
Cancel
Save