1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! The render code for various scenes
//!
//! ## Overview
//!
//! This will probably become a messy module over time. Stick your rendering code here
use raylib::prelude::*;

use crate::{
    discord::DiscordChannel, global_resource_package::GlobalResources,
    project_constants::ProjectConstants,
};

use self::{
    main_menu::{MainMenu, MenuStateSignal},
    player_interaction::PlayableScene,
    test_fox::TestFoxScene,
};
mod main_menu;
mod player_interaction;
mod test_fox;

/// Delegate for handling rendering.
/// This is a struct to allow for stateful data (like sub-screens) to be set up
pub struct SceneRenderDelegate {
    menu_control_signal: MenuStateSignal,
    /* Scenes */
    scene_test_fox: TestFoxScene,
    scene_playable: PlayableScene,
    scene_main_menu: MainMenu,
}

impl SceneRenderDelegate {
    /// This is called when the game first loads
    pub fn on_game_start(
        raylib: &mut RaylibHandle,
        rl_thread: &RaylibThread,
        constants: &ProjectConstants,
    ) -> Self {
        // TODO: Stick any init code you want here.

        // Init some scenes
        let scene_test_fox = TestFoxScene::new(raylib, rl_thread);
        let scene_playable = PlayableScene::new(raylib, rl_thread, constants);
        let scene_main_menu = MainMenu::new(raylib, rl_thread, constants);

        Self {
            menu_control_signal: MenuStateSignal::DoMainMenu,
            scene_test_fox,
            scene_playable,
            scene_main_menu,
        }
    }

    /// This is called every frame once the game has started.
    ///
    /// Keep in mind everything you do here will block the main thread (no loading files plz)
    pub async fn process_ingame_frame(
        &mut self,
        raylib: &mut RaylibHandle,
        rl_thread: &RaylibThread,
        discord: &DiscordChannel,
        global_resources: &GlobalResources,
        constants: &ProjectConstants,
    ) {
        // Render the main menu if in it, otherwise, render the game
        match self.menu_control_signal {
            MenuStateSignal::StartGame => {
                // self.scene_playable
                //     .render_frame(raylib, rl_thread, &discord, global_resources, constants)
                //     .await;

                // TODO: remove this test scene
                self.scene_test_fox
                    .render_frame(raylib, rl_thread, &discord, global_resources)
                    .await;
            }
            MenuStateSignal::QuitGame => unimplemented!(),
            MenuStateSignal::DoMainMenu => {
                self.menu_control_signal = self
                    .scene_main_menu
                    .render_main_menu_frame(raylib, rl_thread, discord, global_resources, constants)
                    .await
            }
            MenuStateSignal::DoOptions => {
                self.menu_control_signal = self
                    .scene_main_menu
                    .render_options_frame(raylib, rl_thread, discord, global_resources, constants)
                    .await
            }
            MenuStateSignal::DoCredits => {
                self.menu_control_signal = self
                    .scene_main_menu
                    .render_credits_frame(raylib, rl_thread, discord, global_resources, constants)
                    .await
            }
            MenuStateSignal::DoLeaderboard => {
                self.menu_control_signal = self
                    .scene_main_menu
                    .render_leaderboard_frame(
                        raylib,
                        rl_thread,
                        discord,
                        global_resources,
                        constants,
                    )
                    .await
            }
        }
    }
}

impl Drop for SceneRenderDelegate {
    /// If you need anything to happen when the game closes, stick it here.
    fn drop(&mut self) {}
}