use bevy::prelude::*; use bevy::render::texture::ImageSampler; use iyes_loopless::state::NextState; use micro_musicbox::music_box::MusicBox; use crate::assets::AssetHandles; use crate::splash_screen::components::{ SplashAnimation, SplashAnimationBundle, SplashAnimationTimer, SplashAnimationType, }; use crate::system::flow::AppState; use crate::system::load_config::virtual_size; use crate::system::utilities::f32_min; const C_TRANS: Color = Color::rgba(1.0, 1.0, 1.0, 0.0); const C_WHITE: Color = Color::rgba(1.0, 1.0, 1.0, 1.0); fn interpolate_colours(from: Color, to: Color, percent: f32) -> Color { let diff_r = to.r() - from.r(); let diff_g = to.g() - from.g(); let diff_b = to.b() - from.b(); let diff_a = to.a() - from.a(); Color::rgba( from.r() + diff_r * percent, from.g() + diff_g * percent, from.b() + diff_b * percent, from.a() + diff_a * percent, ) } pub fn setup_splash_screen( mut commands: Commands, mut image_assets: ResMut<Assets<Image>>, handles: Res<AssetHandles>, mut music_box: MusicBox<AssetHandles>, ) { let (window_width, window_height) = virtual_size(); let handle = match handles.images.get("splash") { Some(handle) => handle, None => { log::error!("No splash image was found; Skipping"); commands.insert_resource(NextState(AppState::Menu)); return; } }; let image_data = image_assets .get_mut(handle) .expect("An image was stored without the handle being persisted"); commands.insert_resource(ClearColor(Color::hex("001122").unwrap())); let scale_factor = match window_width > window_height { true => window_height / image_data.texture_descriptor.size.height as f32, false => window_width / image_data.texture_descriptor.size.width as f32, }; image_data.sampler_descriptor = ImageSampler::linear(); music_box.play_sfx("splash_sting"); commands .spawn_bundle(SpriteBundle { texture: handle.clone_weak(), sprite: Sprite { color: C_TRANS, ..Default::default() }, transform: Transform { scale: [scale_factor, scale_factor, 1.0].into(), ..Default::default() }, ..Default::default() }) .insert_bundle(SplashAnimationBundle::from_animation( SplashAnimation::wait( 1.0, Some(Box::new(SplashAnimation::fade( C_TRANS, C_WHITE, 1.0, Some(Box::new(SplashAnimation::wait( 1.0, Some(Box::new(SplashAnimation::fade( C_WHITE, C_TRANS, 0.75, Some(Box::new(SplashAnimation::wait(0.75, None))), ))), ))), ))), ), )); } pub fn tick_splash_system( mut commands: Commands, time: Res<Time>, mut query: Query<(&mut Sprite, &mut SplashAnimation, &mut SplashAnimationTimer)>, ) { let tick = time.delta_seconds(); for (mut sprite, mut anims, mut timer) in query.iter_mut() { timer.0 += tick; match anims.anim { SplashAnimationType::FadeColour { from, to } => { let percent = f32_min(1.0, timer.0 / anims.duration); sprite.color = interpolate_colours(from, to, percent); } SplashAnimationType::Wait => {} } if timer.0 >= anims.duration { timer.0 = 0.0; match &anims.then { Some(anim) => { *anims = *anim.clone(); } None => { commands.insert_resource(NextState(AppState::Menu)); } } } } } pub fn remove_splash_entities(mut commands: Commands, query: Query<Entity, With<SplashAnimation>>) { for entity in query.iter() { commands.entity(entity).despawn_recursive(); } }