mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
Merge pull request #40 from kristoferssolo/feature/pause-screen
This commit is contained in:
commit
4864ecca93
@ -2,7 +2,13 @@ pub mod common;
|
||||
pub mod despawn;
|
||||
pub mod respawn;
|
||||
pub mod spawn;
|
||||
mod toogle_pause;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use toogle_pause::toggle_walls;
|
||||
|
||||
pub(super) fn plugin(_app: &mut App) {}
|
||||
use crate::screens::Screen;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(Update, toggle_walls.run_if(state_changed::<Screen>));
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ use crate::{
|
||||
components::{HexMaze, MazeConfig, Tile, Wall},
|
||||
resources::GlobalMazeConfig,
|
||||
},
|
||||
screens::Screen,
|
||||
screens::GameplayElement,
|
||||
theme::palette::rose_pine::RosePineDawn,
|
||||
};
|
||||
|
||||
@ -62,7 +62,7 @@ pub fn spawn_maze(
|
||||
config.clone(),
|
||||
Transform::from_translation(Vec3::ZERO.with_y(y_offset)),
|
||||
Visibility::Visible,
|
||||
StateScoped(Screen::Gameplay),
|
||||
GameplayElement,
|
||||
))
|
||||
.insert_if(CurrentFloor, || floor == 1) // Only floor 1 gets CurrentFloor
|
||||
.id();
|
||||
|
||||
13
src/maze/systems/toogle_pause.rs
Normal file
13
src/maze/systems/toogle_pause.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::{maze::components::Wall, screens::Screen};
|
||||
|
||||
pub fn toggle_walls(mut query: Query<&mut Visibility, With<Wall>>, state: Res<State<Screen>>) {
|
||||
for mut visibility in query.iter_mut() {
|
||||
*visibility = match *state.get() {
|
||||
Screen::Gameplay => Visibility::Visible,
|
||||
Screen::Pause => Visibility::Hidden,
|
||||
_ => *visibility,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ mod movement;
|
||||
pub mod respawn;
|
||||
mod sound_effect;
|
||||
pub mod spawn;
|
||||
mod toogle_pause;
|
||||
mod vertical_transition;
|
||||
|
||||
use crate::{screens::Screen, AppSet};
|
||||
@ -11,6 +12,7 @@ use bevy::prelude::*;
|
||||
use input::player_input;
|
||||
use movement::player_movement;
|
||||
use sound_effect::play_movement_sound;
|
||||
use toogle_pause::toggle_player;
|
||||
use vertical_transition::handle_floor_transition;
|
||||
|
||||
use super::assets::PlayerAssets;
|
||||
@ -30,4 +32,5 @@ pub(super) fn plugin(app: &mut App) {
|
||||
.chain()
|
||||
.run_if(in_state(Screen::Gameplay)),
|
||||
);
|
||||
app.add_systems(Update, toggle_player.run_if(state_changed::<Screen>));
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{
|
||||
assets::{blue_material, generate_pill_mesh},
|
||||
components::{CurrentPosition, Player},
|
||||
},
|
||||
screens::Screen,
|
||||
screens::GameplayElement,
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
@ -33,6 +33,6 @@ pub fn spawn_player(
|
||||
Mesh3d(meshes.add(generate_pill_mesh(player_radius, player_height / 2.))),
|
||||
MeshMaterial3d(materials.add(blue_material())),
|
||||
Transform::from_xyz(start_pos.x, y_offset, start_pos.y),
|
||||
StateScoped(Screen::Gameplay),
|
||||
GameplayElement,
|
||||
));
|
||||
}
|
||||
|
||||
13
src/player/systems/toogle_pause.rs
Normal file
13
src/player/systems/toogle_pause.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::{player::components::Player, screens::Screen};
|
||||
|
||||
pub fn toggle_player(mut query: Query<&mut Visibility, With<Player>>, state: Res<State<Screen>>) {
|
||||
for mut visibility in query.iter_mut() {
|
||||
*visibility = match *state.get() {
|
||||
Screen::Gameplay => Visibility::Visible,
|
||||
Screen::Pause => Visibility::Hidden,
|
||||
_ => *visibility,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ use crate::{
|
||||
use bevy::{input::common_conditions::input_just_pressed, prelude::*};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.init_resource::<GameplayInitialized>();
|
||||
app.add_systems(
|
||||
OnEnter(Screen::Gameplay),
|
||||
(
|
||||
@ -16,16 +17,46 @@ pub(super) fn plugin(app: &mut App) {
|
||||
spawn_hint_command,
|
||||
spawn_stats_command,
|
||||
)
|
||||
.chain(),
|
||||
.chain()
|
||||
.run_if(not(resource_exists::<GameplayInitialized>)),
|
||||
);
|
||||
app.add_systems(OnEnter(Screen::Gameplay), |mut commands: Commands| {
|
||||
commands.insert_resource(GameplayInitialized(true));
|
||||
});
|
||||
app.add_systems(Update, cleanup_game.run_if(state_changed::<Screen>));
|
||||
|
||||
app.add_systems(OnEnter(Screen::Title), reset_gameplay_state);
|
||||
|
||||
app.add_systems(
|
||||
Update,
|
||||
return_to_title_screen
|
||||
.run_if(in_state(Screen::Gameplay).and(input_just_pressed(KeyCode::Escape))),
|
||||
pause_game.run_if(in_state(Screen::Gameplay).and(input_just_pressed(KeyCode::Escape))),
|
||||
);
|
||||
}
|
||||
|
||||
fn return_to_title_screen(mut next_screen: ResMut<NextState<Screen>>) {
|
||||
next_screen.set(Screen::Title);
|
||||
fn pause_game(mut next_screen: ResMut<NextState<Screen>>) {
|
||||
next_screen.set(Screen::Pause);
|
||||
}
|
||||
|
||||
fn reset_gameplay_state(mut commands: Commands) {
|
||||
commands.remove_resource::<GameplayInitialized>();
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Reflect, Resource, DerefMut, Deref)]
|
||||
#[reflect(Resource)]
|
||||
pub struct GameplayInitialized(bool);
|
||||
|
||||
#[derive(Debug, Reflect, Component)]
|
||||
#[reflect(Component)]
|
||||
pub struct GameplayElement;
|
||||
|
||||
fn cleanup_game(
|
||||
mut commands: Commands,
|
||||
query: Query<Entity, With<GameplayElement>>,
|
||||
state: Res<State<Screen>>,
|
||||
) {
|
||||
if !matches!(*state.get(), Screen::Gameplay | Screen::Pause) {
|
||||
for entity in query.iter() {
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,10 +2,12 @@
|
||||
|
||||
mod gameplay;
|
||||
mod loading;
|
||||
mod pause;
|
||||
mod splash;
|
||||
mod title;
|
||||
|
||||
use bevy::prelude::*;
|
||||
pub use gameplay::{GameplayElement, GameplayInitialized};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.init_state::<Screen>();
|
||||
@ -16,6 +18,7 @@ pub(super) fn plugin(app: &mut App) {
|
||||
loading::plugin,
|
||||
splash::plugin,
|
||||
title::plugin,
|
||||
pause::plugin,
|
||||
));
|
||||
}
|
||||
|
||||
@ -28,4 +31,5 @@ pub enum Screen {
|
||||
Loading,
|
||||
Title,
|
||||
Gameplay,
|
||||
Pause,
|
||||
}
|
||||
|
||||
57
src/screens/pause.rs
Normal file
57
src/screens/pause.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use bevy::{input::common_conditions::input_just_pressed, prelude::*};
|
||||
|
||||
use crate::theme::{
|
||||
events::OnPress,
|
||||
palette::rose_pine::RosePineDawn,
|
||||
prelude::ColorScheme,
|
||||
widgets::{Containers, Widgets},
|
||||
};
|
||||
|
||||
use super::Screen;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(OnEnter(Screen::Pause), spawn_pause_overlay);
|
||||
app.add_systems(
|
||||
Update,
|
||||
return_to_game.run_if(in_state(Screen::Pause).and(input_just_pressed(KeyCode::Escape))),
|
||||
);
|
||||
}
|
||||
|
||||
fn spawn_pause_overlay(mut commands: Commands) {
|
||||
commands
|
||||
.ui_root()
|
||||
.insert((
|
||||
StateScoped(Screen::Pause),
|
||||
BackgroundColor(RosePineDawn::Muted.to_color().with_alpha(0.5)),
|
||||
))
|
||||
.with_children(|parent| {
|
||||
parent
|
||||
.spawn(Node {
|
||||
bottom: Val::Px(100.),
|
||||
..default()
|
||||
})
|
||||
.with_children(|parent| {
|
||||
parent.header("Paused");
|
||||
});
|
||||
|
||||
parent.button("Continue").observe(return_to_game_trigger);
|
||||
parent
|
||||
.button("Exit")
|
||||
.observe(return_to_title_screen_trigger);
|
||||
});
|
||||
}
|
||||
|
||||
fn return_to_game_trigger(_trigger: Trigger<OnPress>, mut next_screen: ResMut<NextState<Screen>>) {
|
||||
next_screen.set(Screen::Gameplay);
|
||||
}
|
||||
|
||||
fn return_to_title_screen_trigger(
|
||||
_trigger: Trigger<OnPress>,
|
||||
mut next_screen: ResMut<NextState<Screen>>,
|
||||
) {
|
||||
next_screen.set(Screen::Title);
|
||||
}
|
||||
|
||||
fn return_to_game(mut next_screen: ResMut<NextState<Screen>>) {
|
||||
next_screen.set(Screen::Gameplay);
|
||||
}
|
||||
@ -13,23 +13,26 @@ use reset::reset_timers;
|
||||
use score::{update_score, update_score_display};
|
||||
use total_timer::{update_total_timer, update_total_timer_display};
|
||||
|
||||
use crate::screens::Screen;
|
||||
use crate::screens::{GameplayInitialized, Screen};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(OnEnter(Screen::Gameplay), reset_timers)
|
||||
.add_systems(
|
||||
Update,
|
||||
app.add_systems(
|
||||
OnEnter(Screen::Gameplay),
|
||||
reset_timers.run_if(not(resource_exists::<GameplayInitialized>)),
|
||||
);
|
||||
app.add_systems(
|
||||
Update,
|
||||
(
|
||||
(
|
||||
(
|
||||
update_score.before(update_floor_timer),
|
||||
update_score_display,
|
||||
)
|
||||
.chain(),
|
||||
(update_floor_timer, update_floor_timer_display).chain(),
|
||||
(update_total_timer, update_total_timer_display).chain(),
|
||||
update_floor_display,
|
||||
update_highest_floor_display,
|
||||
update_score.before(update_floor_timer),
|
||||
update_score_display,
|
||||
)
|
||||
.run_if(in_state(Screen::Gameplay)),
|
||||
);
|
||||
.chain(),
|
||||
(update_floor_timer, update_floor_timer_display).chain(),
|
||||
(update_total_timer, update_total_timer_display).chain(),
|
||||
update_floor_display,
|
||||
update_highest_floor_display,
|
||||
)
|
||||
.run_if(in_state(Screen::Gameplay)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -59,8 +59,6 @@ fn calculate_score(floor_number: u8, completion_time: f32) -> usize {
|
||||
time_factor.max(MIN_TIME_MULTIPLIER) * TIME_BONUS_MULTIPLIER
|
||||
};
|
||||
|
||||
dbg!(base_score * time_multiplier);
|
||||
|
||||
(base_score * time_multiplier) as usize
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
screens::Screen,
|
||||
screens::GameplayElement,
|
||||
stats::{
|
||||
components::{
|
||||
FloorDisplay, FloorTimerDisplay, HighestFloorDisplay, ScoreDisplay, TotalTimerDisplay,
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
pub fn spawn_stats(mut commands: Commands) {
|
||||
commands
|
||||
.ui_stats()
|
||||
.insert(StateScoped(Screen::Gameplay))
|
||||
.insert(GameplayElement)
|
||||
.with_children(|parent| {
|
||||
parent.stats("Floor: 1", FloorDisplay);
|
||||
parent.stats("Highest Floor: 1", HighestFloorDisplay);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user