mirror of
https://github.com/Xevion/Pac-Man.git
synced 2026-01-31 04:25:07 -06:00
feat(game): implement pause system with Escape key and visual overlay
This commit is contained in:
+3
-3
@@ -541,9 +541,9 @@ impl Game {
|
|||||||
))
|
))
|
||||||
.configure_sets((
|
.configure_sets((
|
||||||
GameplaySet::Input,
|
GameplaySet::Input,
|
||||||
GameplaySet::Update.run_if(|paused: Res<PauseState>| paused.active()),
|
GameplaySet::Update.run_if(|paused: Res<PauseState>| !paused.active()),
|
||||||
GameplaySet::Respond.run_if(|paused: Res<PauseState>| paused.active()),
|
GameplaySet::Respond.run_if(|paused: Res<PauseState>| !paused.active()),
|
||||||
RenderSet::Animation.run_if(|paused: Res<PauseState>| paused.active()),
|
RenderSet::Animation.run_if(|paused: Res<PauseState>| !paused.active()),
|
||||||
RenderSet::Draw,
|
RenderSet::Draw,
|
||||||
RenderSet::Present,
|
RenderSet::Present,
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use crate::constants;
|
use crate::constants;
|
||||||
use crate::error::{GameError, TextureError};
|
use crate::error::{GameError, TextureError};
|
||||||
use crate::systems::{BackbufferResource, GameStage, ScoreResource, StartupSequence};
|
use crate::systems::{BackbufferResource, GameStage, PauseState, ScoreResource, StartupSequence};
|
||||||
use crate::texture::sprite::SpriteAtlas;
|
use crate::texture::sprite::SpriteAtlas;
|
||||||
use crate::texture::text::TextTexture;
|
use crate::texture::text::TextTexture;
|
||||||
use bevy_ecs::event::EventWriter;
|
use bevy_ecs::event::EventWriter;
|
||||||
use bevy_ecs::system::{NonSendMut, Res};
|
use bevy_ecs::system::{NonSendMut, Res};
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
|
use sdl2::rect::Rect;
|
||||||
use sdl2::render::Canvas;
|
use sdl2::render::Canvas;
|
||||||
use sdl2::video::Window;
|
use sdl2::video::Window;
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ pub fn hud_render_system(
|
|||||||
mut atlas: NonSendMut<SpriteAtlas>,
|
mut atlas: NonSendMut<SpriteAtlas>,
|
||||||
score: Res<ScoreResource>,
|
score: Res<ScoreResource>,
|
||||||
stage: Res<GameStage>,
|
stage: Res<GameStage>,
|
||||||
|
pause_state: Res<PauseState>,
|
||||||
mut errors: EventWriter<GameError>,
|
mut errors: EventWriter<GameError>,
|
||||||
) {
|
) {
|
||||||
let _ = canvas.with_texture_canvas(&mut backbuffer.0, |canvas| {
|
let _ = canvas.with_texture_canvas(&mut backbuffer.0, |canvas| {
|
||||||
@@ -82,5 +84,28 @@ pub fn hud_render_system(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render pause overlay when game is paused (allowed during any stage)
|
||||||
|
if pause_state.active() {
|
||||||
|
// Enable blending for transparency
|
||||||
|
canvas.set_blend_mode(sdl2::render::BlendMode::Blend);
|
||||||
|
|
||||||
|
// Draw semi-transparent black overlay
|
||||||
|
canvas.set_draw_color(Color::RGBA(0, 0, 0, 160));
|
||||||
|
let _ = canvas.fill_rect(Rect::new(0, 0, constants::CANVAS_SIZE.x, constants::CANVAS_SIZE.y));
|
||||||
|
|
||||||
|
// Render "PAUSED" text centered and larger (2.5x scale)
|
||||||
|
let mut paused_renderer = TextTexture::new(2.5);
|
||||||
|
let paused_text = "PAUSED";
|
||||||
|
let paused_width = paused_renderer.text_width(paused_text);
|
||||||
|
let paused_height = paused_renderer.text_height();
|
||||||
|
let paused_position = glam::UVec2::new(
|
||||||
|
(constants::CANVAS_SIZE.x - paused_width) / 2,
|
||||||
|
(constants::CANVAS_SIZE.y - paused_height) / 2
|
||||||
|
);
|
||||||
|
if let Err(e) = paused_renderer.render_with_color(canvas, &mut atlas, paused_text, paused_position, Color::YELLOW) {
|
||||||
|
errors.write(TextureError::RenderFailed(format!("Failed to render PAUSED text: {}", e)).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ impl Default for Bindings {
|
|||||||
key_bindings.insert(Keycode::D, GameCommand::MovePlayer(Direction::Right));
|
key_bindings.insert(Keycode::D, GameCommand::MovePlayer(Direction::Right));
|
||||||
|
|
||||||
// Game actions
|
// Game actions
|
||||||
key_bindings.insert(Keycode::P, GameCommand::TogglePause);
|
key_bindings.insert(Keycode::Escape, GameCommand::TogglePause);
|
||||||
key_bindings.insert(Keycode::Space, GameCommand::ToggleDebug);
|
key_bindings.insert(Keycode::Space, GameCommand::ToggleDebug);
|
||||||
key_bindings.insert(Keycode::M, GameCommand::MuteAudio);
|
key_bindings.insert(Keycode::M, GameCommand::MuteAudio);
|
||||||
key_bindings.insert(Keycode::R, GameCommand::ResetLevel);
|
key_bindings.insert(Keycode::R, GameCommand::ResetLevel);
|
||||||
@@ -89,7 +89,6 @@ impl Default for Bindings {
|
|||||||
|
|
||||||
#[cfg(not(target_os = "emscripten"))]
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
{
|
{
|
||||||
key_bindings.insert(Keycode::Escape, GameCommand::Exit);
|
|
||||||
key_bindings.insert(Keycode::Q, GameCommand::Exit);
|
key_bindings.insert(Keycode::Q, GameCommand::Exit);
|
||||||
// Desktop-only fullscreen toggle
|
// Desktop-only fullscreen toggle
|
||||||
key_bindings.insert(Keycode::F, GameCommand::ToggleFullscreen);
|
key_bindings.insert(Keycode::F, GameCommand::ToggleFullscreen);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ pub enum PauseState {
|
|||||||
|
|
||||||
impl Default for PauseState {
|
impl Default for PauseState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Active { remaining_ticks: None }
|
Self::Inactive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user