Skip to main content

fantasy_craft/graphics/
splash_screen.rs

1use macroquad::prelude::*;
2use crate::gui::gui_element::GuiElement;
3use crate::prelude::{Context, Transform};
4use crate::gui::gui_box::GuiBox;
5use crate::gui::gui_dimension::GuiDimension;
6use crate::gui::gui_image::GuiImage;
7
8#[derive(Debug)]
9pub struct SplashScreenData {
10    pub background_color: Color
11}
12
13#[derive(Debug)]
14pub struct SplashScreenTag;
15
16#[derive(Debug)]
17pub struct SplashAnimation {
18    pub timer: f32,
19    pub fade_in_time: f32,
20    pub fade_out_time: f32,
21    pub total_duration: f32
22}
23
24pub fn setup_splash_screen(ctx: &mut Context) {
25    let screen_w = screen_width();
26    let screen_h = screen_height();
27    let logo_w = 400.0;
28    let logo_h = 400.0;
29
30    let pos_x = (screen_w / 2.0) - (logo_w / 2.0);
31    let pos_y = (screen_h / 2.0) - (logo_h / 2.0);
32
33    let splash_screen_data = ctx.get_resource::<SplashScreenData>();
34
35    let color = if let Some(data) = splash_screen_data {
36        data.background_color
37    }
38    else {
39        BLACK
40    };
41    
42    ctx.world.spawn((
43        Transform {
44            position: vec2(pos_x, pos_y),
45            ..Default::default()
46        },
47        GuiBox {
48            width: GuiDimension::Pixels(logo_w),
49            height: GuiDimension::Pixels(logo_h),
50            color,
51            ..Default::default()
52        },
53        GuiImage {
54            texture: Some("splash_screen_logo".to_string()),
55            col_row: uvec2(0, 0),
56            tint: WHITE,
57            ..Default::default()
58        },
59        GuiElement,
60        SplashScreenTag,
61        SplashAnimation {
62            timer: 0.0,
63            fade_in_time: 1.2,
64            fade_out_time: 1.0,
65            total_duration: 3.0
66        }
67    ));
68}
69
70pub fn animate_splash_screen(ctx: &mut Context) {
71    for (_, (transform, gui_image, anim)) in ctx.world.query::<(&mut Transform, &mut GuiImage, &mut SplashAnimation)>().iter() {
72        anim.timer += ctx.dt();
73
74        if anim.timer < anim.fade_in_time {
75            let t = anim.timer / anim.fade_in_time;
76            gui_image.tint.a = t.clamp(0.0, 1.0);
77        }
78        else if anim.timer < anim.total_duration - anim.fade_out_time {
79            let t = (anim.timer - anim.fade_in_time) * 2.0;
80            transform.scale = vec2(1.0 + 0.02 * (t.sin()), 1.0 + 0.02 * (t.sin()));
81            gui_image.tint.a = 1.0;
82        }
83        else {
84            let t = (anim.total_duration - anim.timer) / anim.fade_out_time;
85            gui_image.tint.a = t.clamp(0.0, 1.0);
86        }
87    }
88}
89
90pub fn despawn_splash_screen(ctx: &mut Context) {
91    let mut entities_to_despawn = Vec::new();
92
93    for (entity, _) in ctx.world.query::<&SplashScreenTag>().iter() {
94        entities_to_despawn.push(entity);
95    }
96
97    for entity in entities_to_despawn {
98        ctx.world.despawn(entity).expect("Failed to despawn splash entity");
99    }
100}