From b181f9293f1b0ac8ef3f218d122cb4f1800e1b04 Mon Sep 17 00:00:00 2001 From: dawnDus <96957561+dawndus@users.noreply.github.com> Date: Thu, 20 Jan 2022 21:14:12 -0500 Subject: [PATCH] Initial pause menu --- src/menu/mod.rs | 8 ++- src/menu/pause_menu.rs | 140 ++++++++++++++++++++++++++++++++++++++++ src/scene/game_scene.rs | 16 +++++ 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 src/menu/pause_menu.rs diff --git a/src/menu/mod.rs b/src/menu/mod.rs index 77d9469..b1aa2ce 100644 --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -6,6 +6,7 @@ use crate::framework::error::GameResult; use crate::input::combined_menu_controller::CombinedMenuController; use crate::shared_game_state::SharedGameState; +pub mod pause_menu; pub mod settings_menu; pub struct MenuSaveInfo {} @@ -318,7 +319,7 @@ impl Menu { ctx, )?; - state.font.draw_colored_text( + state.font.draw_colored_text( description_text.chars(), self.x as f32 + 20.0, y + 14.0, @@ -382,7 +383,10 @@ impl Menu { y += entry.height() as f32; match entry { - MenuEntry::Active(_) | MenuEntry::Toggle(_, _) | MenuEntry::Options(_, _, _) | MenuEntry::DescriptiveOptions(_, _, _, _) + MenuEntry::Active(_) + | MenuEntry::Toggle(_, _) + | MenuEntry::Options(_, _, _) + | MenuEntry::DescriptiveOptions(_, _, _, _) if (self.selected == idx && controller.trigger_ok()) || state.touch_controls.consume_click_in(entry_bounds) => { diff --git a/src/menu/pause_menu.rs b/src/menu/pause_menu.rs new file mode 100644 index 0000000..a8aace5 --- /dev/null +++ b/src/menu/pause_menu.rs @@ -0,0 +1,140 @@ +use crate::framework::context::Context; +use crate::framework::error::GameResult; +use crate::input::combined_menu_controller::CombinedMenuController; +use crate::menu::MenuEntry; +use crate::menu::{Menu, MenuSelectionResult}; +use crate::scene::title_scene::TitleScene; +use crate::shared_game_state::SharedGameState; + +use super::settings_menu::SettingsMenu; + +#[derive(PartialEq, Eq, Copy, Clone)] +#[repr(u8)] +#[allow(unused)] +enum CurrentMenu { + PauseMenu, + OptionsMenu, +} + +pub struct PauseMenu { + is_paused: bool, + current_menu: CurrentMenu, + option_menu: SettingsMenu, + controller: CombinedMenuController, + pause_menu: Menu, + tick: u32, +} + +impl PauseMenu { + pub fn new() -> PauseMenu { + let main = Menu::new(0, 0, 75, 0); + + PauseMenu { + is_paused: false, + current_menu: CurrentMenu::PauseMenu, + option_menu: SettingsMenu::new(), + controller: CombinedMenuController::new(), + pause_menu: main, + tick: 0, + } + } + + pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { + self.controller.add(state.settings.create_player1_controller()); + self.controller.add(state.settings.create_player2_controller()); + + self.pause_menu.push_entry(MenuEntry::Active("Resume".to_owned())); + self.pause_menu.push_entry(MenuEntry::Active("Retry".to_owned())); + self.pause_menu.push_entry(MenuEntry::Active("Options".to_owned())); + self.pause_menu.push_entry(MenuEntry::Active("Main Menu".to_owned())); + self.pause_menu.push_entry(MenuEntry::Disabled(" --- ".to_owned())); + self.pause_menu.push_entry(MenuEntry::Active("Quit".to_owned())); + + self.update_sizes(state); + + self.option_menu.init(state, ctx)?; + + self.controller.update(state, ctx)?; + self.controller.update_trigger(); + + Ok(()) + } + + fn update_sizes(&mut self, state: &SharedGameState) { + self.pause_menu.update_height(); + self.pause_menu.x = ((state.canvas_size.0 - self.pause_menu.width as f32) / 2.0).floor() as isize; + self.pause_menu.y = ((state.canvas_size.1 - self.pause_menu.height as f32) / 2.0).floor() as isize; + } + + pub fn pause(&mut self) { + self.is_paused = true; + } + + pub fn is_paused(&mut self) -> bool { + self.is_paused + } + + pub fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { + self.update_sizes(state); + + self.controller.update(state, ctx)?; + self.controller.update_trigger(); + + self.is_paused = true; + + match self.current_menu { + CurrentMenu::PauseMenu => match self.pause_menu.tick(&mut self.controller, state) { + MenuSelectionResult::Selected(0, _) | MenuSelectionResult::Canceled => { + // double tap prevention + if self.tick >= 3 { + self.tick = 0; + self.is_paused = false; + } + } + MenuSelectionResult::Selected(1, _) => { + state.load_or_start_game(ctx)?; + } + MenuSelectionResult::Selected(2, _) => { + self.current_menu = CurrentMenu::OptionsMenu; + } + MenuSelectionResult::Selected(3, _) => { + state.next_scene = Some(Box::new(TitleScene::new())); + } + MenuSelectionResult::Selected(5, _) => { + state.shutdown(); + } + _ => (), + }, + CurrentMenu::OptionsMenu => { + let cm = &mut self.current_menu; + self.option_menu.tick( + &mut || { + *cm = CurrentMenu::PauseMenu; + }, + &mut self.controller, + state, + ctx, + )?; + } + } + + self.tick += 1; + + Ok(()) + } + + pub fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { + if self.is_paused { + match self.current_menu { + CurrentMenu::PauseMenu => { + self.pause_menu.draw(state, ctx)?; + } + CurrentMenu::OptionsMenu => { + self.option_menu.draw(state, ctx)?; + } + } + } + + Ok(()) + } +} diff --git a/src/scene/game_scene.rs b/src/scene/game_scene.rs index 9bc613c..bc0768d 100644 --- a/src/scene/game_scene.rs +++ b/src/scene/game_scene.rs @@ -32,6 +32,7 @@ use crate::framework::{filesystem, graphics}; use crate::input::touch_controls::TouchControlType; use crate::inventory::{Inventory, TakeExperienceResult}; use crate::map::WaterParams; +use crate::menu::pause_menu::PauseMenu; use crate::npc::boss::BossNPC; use crate::npc::list::NPCList; use crate::npc::{NPCLayer, NPC}; @@ -78,6 +79,7 @@ pub struct GameScene { pub bullet_manager: BulletManager, pub lighting_mode: LightingMode, pub intro_mode: bool, + pub pause_menu: PauseMenu, pub stage_textures: Rc>, map_name_counter: u16, skip_counter: u16, @@ -153,6 +155,7 @@ impl GameScene { bullet_manager: BulletManager::new(), lighting_mode: LightingMode::None, intro_mode: false, + pause_menu: PauseMenu::new(), stage_textures, map_name_counter: 0, skip_counter: 0, @@ -1566,6 +1569,8 @@ impl Scene for GameScene { _ => LightingMode::None, }; + self.pause_menu.init(state, ctx)?; + Ok(()) } @@ -1594,6 +1599,15 @@ impl Scene for GameScene { } } + if self.player1.controller.trigger_menu_pause() { + self.pause_menu.pause(); + } + + if self.pause_menu.is_paused() { + self.pause_menu.tick(state, ctx)?; + return Ok(()); + } + match state.textscript_vm.state { TextScriptExecutionState::Running(_, _) | TextScriptExecutionState::WaitTicks(_, _, _) @@ -1891,6 +1905,8 @@ impl Scene for GameScene { self.draw_debug_outlines(state, ctx)?; } + self.pause_menu.draw(state, ctx)?; + //draw_number(state.canvas_size.0 - 8.0, 8.0, timer::fps(ctx) as usize, Alignment::Right, state, ctx)?; Ok(()) }