Skip to content

Commit

Permalink
Use a vec of splash screen images
Browse files Browse the repository at this point in the history
  • Loading branch information
will-hart committed Aug 10, 2024
1 parent f8d8e60 commit 5d9b424
Showing 1 changed file with 93 additions and 2 deletions.
95 changes: 93 additions & 2 deletions src/screens/splash.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! A splash screen that plays briefly at startup.
use std::collections::VecDeque;

use bevy::{
input::common_conditions::input_just_pressed,
prelude::*,
Expand All @@ -12,6 +14,8 @@ use crate::{theme::prelude::*, AppSet};
pub(super) fn plugin(app: &mut App) {
// Spawn splash screen.
app.insert_resource(ClearColor(SPLASH_BACKGROUND_COLOR));
app.init_resource::<SplashScreenImageList>();

app.add_systems(OnEnter(Screen::Splash), spawn_splash);

// Animate splash screen.
Expand Down Expand Up @@ -49,11 +53,71 @@ const SPLASH_BACKGROUND_COLOR: Color = Color::srgb(0.157, 0.157, 0.157);
const SPLASH_DURATION_SECS: f32 = 1.8;
const SPLASH_FADE_DURATION_SECS: f32 = 0.6;

#[derive(Component)]
struct SplashScreenContainer;

#[derive(Resource)]
struct SplashScreenImageList(VecDeque<&'static str>);

impl Default for SplashScreenImageList {
fn default() -> Self {
// Use paths here rather than an ImageHandle as the loading screen hasn't
// run yet. To show your own splash images, replace or add here
Self(VecDeque::from_iter(["images/splash.png"].into_iter()))
}
}

fn exit_splash_screen(mut next_screen: ResMut<NextState<Screen>>) {
next_screen.set(Screen::Loading);
}

fn splash_image_bundle(asset_server: &AssetServer, path: &'static str) -> impl Bundle {
(
Name::new("Splash image"),
ImageBundle {
style: Style {
margin: UiRect::all(Val::Auto),
width: Val::Percent(70.0),
..default()
},
image: UiImage::new(asset_server.load_with_settings(
// This should be an embedded asset for instant loading, but that is
// currently [broken on Windows Wasm builds](https://github.com/bevyengine/bevy/issues/14246).
path,
|settings: &mut ImageLoaderSettings| {
// Make an exception for the splash image in case
// `ImagePlugin::default_nearest()` is used for pixel art.
settings.sampler = ImageSampler::linear();
},
)),
background_color: BackgroundColor(Color::srgba(0., 0., 0., 0.)),
..default()
},
UiImageFadeInOut {
total_duration: SPLASH_DURATION_SECS,
fade_duration: SPLASH_FADE_DURATION_SECS,
t: 0.0,
},
)
}

fn spawn_splash(
mut commands: Commands,
splash_images: Res<SplashScreenImageList>,
mut next_screen: ResMut<NextState<Screen>>,
) {
if splash_images.0.is_empty() {
// if there are no splash images, go directly to the loading screen
next_screen.set(Screen::Loading);
} else {
// spawn the UI root but wait for the first timer tick to show an image
commands.ui_root().insert((
Name::new("Splash screen container"),
BackgroundColor(SPLASH_BACKGROUND_COLOR),
StateScoped(Screen::Splash),
SplashScreenContainer,
));
}
}

#[derive(Component, Reflect)]
Expand Down Expand Up @@ -112,8 +176,35 @@ fn tick_splash_timer(time: Res<Time>, mut timer: ResMut<SplashTimer>) {
timer.0.tick(time.delta());
}

fn check_splash_timer(timer: ResMut<SplashTimer>, mut next_screen: ResMut<NextState<Screen>>) {
if timer.0.just_finished() {
fn check_splash_timer(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut timer: ResMut<SplashTimer>,
mut next_screen: ResMut<NextState<Screen>>,
mut splash_screens: ResMut<SplashScreenImageList>,
containers: Query<Entity, With<SplashScreenContainer>>,
) {
if !timer.0.just_finished() {
return;
}

// try to get the next splash screen. If there isn't one, we move on to the next screen
if let Some(next_splash_image) = splash_screens.0.pop_front() {
// despawn other splash images
if let Ok(container) = containers.get_single() {
commands
.entity(container)
.despawn_descendants()
.with_children(|parent| {
parent.spawn(splash_image_bundle(&asset_server, next_splash_image));
});
}

// reset the timer
timer.0.reset();
} else {
// no more splash screens, exit
next_screen.set(Screen::Loading);
return;
}
}

0 comments on commit 5d9b424

Please sign in to comment.