From 2da8a312f34553923f5865b9f16d02dfde547630 Mon Sep 17 00:00:00 2001 From: Ryan Walters Date: Thu, 28 Aug 2025 18:32:19 -0500 Subject: [PATCH] chore: remove PlayerLifecycle, move MovementModifiers directly into PlayerBundle --- src/game.rs | 6 +++--- src/systems/components.rs | 10 ++-------- src/systems/player.rs | 37 ++++--------------------------------- src/systems/render.rs | 7 ++----- 4 files changed, 11 insertions(+), 49 deletions(-) diff --git a/src/game.rs b/src/game.rs index 8c6ecf0..1cfbe48 100644 --- a/src/game.rs +++ b/src/game.rs @@ -8,7 +8,7 @@ use crate::events::GameEvent; use crate::map::builder::Map; use crate::map::direction::Direction; use crate::systems::blinking::Blinking; -use crate::systems::{self, ghost_collision_system}; +use crate::systems::{self, ghost_collision_system, MovementModifiers}; use crate::systems::movement::{BufferedDirection, Position, Velocity}; use crate::systems::profiling::SystemId; @@ -18,7 +18,7 @@ use crate::systems::{ ghost_movement_system, hud_render_system, item_system, profile, render_system, AudioEvent, AudioResource, AudioState, BackbufferResource, Collider, DebugFontResource, DebugState, DebugTextureResource, DeltaTime, DirectionalAnimated, EntityType, Frozen, Ghost, GhostBundle, GhostCollider, GlobalState, ItemBundle, ItemCollider, MapTextureResource, - PacmanCollider, PlayerBundle, PlayerControlled, PlayerStateBundle, Renderable, ScoreResource, StartupSequence, SystemTimings, + PacmanCollider, PlayerBundle, PlayerControlled, Renderable, ScoreResource, StartupSequence, SystemTimings, }; use crate::texture::animated::AnimatedTexture; use bevy_ecs::event::EventRegistry; @@ -184,6 +184,7 @@ impl Game { speed: 1.15, direction: Direction::Left, }, + movement_modifiers: MovementModifiers::default(), buffered_direction: BufferedDirection::None, sprite: Renderable { sprite: SpriteAtlas::get_tile(&atlas, "pacman/full.png") @@ -203,7 +204,6 @@ impl Game { // Spawn player and attach initial state bundle let player_entity = world.spawn(player).id(); - world.entity_mut(player_entity).insert(PlayerStateBundle::default()); world.entity_mut(player_entity).insert(Frozen); world.insert_non_send_resource(atlas); diff --git a/src/systems/components.rs b/src/systems/components.rs index 8a355a9..2d8a6c4 100644 --- a/src/systems/components.rs +++ b/src/systems/components.rs @@ -5,7 +5,7 @@ use crate::{ map::graph::TraversalFlags, systems::{ movement::{BufferedDirection, Position, Velocity}, - Collider, GhostCollider, ItemCollider, PacmanCollider, PlayerLifecycle, + Collider, GhostCollider, ItemCollider, PacmanCollider, }, texture::{animated::AnimatedTexture, sprite::AtlasTile}, }; @@ -160,14 +160,8 @@ pub struct PlayerBundle { pub directional_animated: DirectionalAnimated, pub entity_type: EntityType, pub collider: Collider, - pub pacman_collider: PacmanCollider, -} - -/// Convenience bundle for attaching the hybrid FSM to the player entity -#[derive(Bundle, Default)] -pub struct PlayerStateBundle { - pub lifecycle: PlayerLifecycle, pub movement_modifiers: MovementModifiers, + pub pacman_collider: PacmanCollider, } #[derive(Bundle)] diff --git a/src/systems/player.rs b/src/systems/player.rs index 47ef2ef..f691403 100644 --- a/src/systems/player.rs +++ b/src/systems/player.rs @@ -1,5 +1,4 @@ use bevy_ecs::{ - component::Component, event::{EventReader, EventWriter}, query::{With, Without}, system::{Query, Res, ResMut}, @@ -17,28 +16,6 @@ use crate::{ }, }; -/// Lifecycle state for the player entity. -#[derive(Component, Debug, Clone, Copy, PartialEq, Eq)] -pub enum PlayerLifecycle { - Spawning, - Alive, - Dying, - Respawning, -} - -impl PlayerLifecycle { - /// Returns true when gameplay input and movement should be active - pub fn is_interactive(self) -> bool { - matches!(self, PlayerLifecycle::Alive) - } -} - -impl Default for PlayerLifecycle { - fn default() -> Self { - PlayerLifecycle::Spawning - } -} - pub fn can_traverse(entity_type: EntityType, edge: Edge) -> bool { let entity_flags = entity_type.traversal_flags(); edge.traversal_flags.contains(entity_flags) @@ -64,7 +41,7 @@ pub fn player_control_system( match command { GameCommand::MovePlayer(direction) => { // Get the player's movable component (ensuring there is only one player) - let (mut buffered_direction) = match players.single_mut() { + let mut buffered_direction = match players.single_mut() { Ok(tuple) => tuple, Err(e) => { errors.write(GameError::InvalidState(format!( @@ -101,22 +78,16 @@ pub fn player_control_system( /// Handles movement logic including buffered direction changes, edge traversal validation, and continuous movement between nodes. /// When stopped, prioritizes buffered directions for responsive controls, falling back to current direction. /// Supports movement chaining within a single frame when traveling at high speeds. +#[allow(clippy::type_complexity)] pub fn player_movement_system( map: Res, delta_time: Res, mut entities: Query< - ( - &PlayerLifecycle, - &MovementModifiers, - &mut Position, - &mut Velocity, - &mut BufferedDirection, - ), + (&MovementModifiers, &mut Position, &mut Velocity, &mut BufferedDirection), (With, Without), >, - // mut errors: EventWriter, ) { - for (lifecycle, modifiers, mut position, mut velocity, mut buffered_direction) in entities.iter_mut() { + for (modifiers, mut position, mut velocity, mut buffered_direction) in entities.iter_mut() { // Decrement the buffered direction remaining time if let BufferedDirection::Some { direction, diff --git a/src/systems/render.rs b/src/systems/render.rs index dcd3e04..1e95cdd 100644 --- a/src/systems/render.rs +++ b/src/systems/render.rs @@ -1,16 +1,13 @@ use crate::constants::CANVAS_SIZE; use crate::error::{GameError, TextureError}; use crate::map::builder::Map; -use crate::systems::{ - Blinking, DeltaTime, DirectionalAnimated, EntityType, GhostCollider, PlayerControlled, Position, Renderable, ScoreResource, - StartupSequence, Velocity, -}; +use crate::systems::{DeltaTime, DirectionalAnimated, Position, Renderable, ScoreResource, StartupSequence, Velocity}; use crate::texture::sprite::SpriteAtlas; use crate::texture::text::TextTexture; use bevy_ecs::component::Component; use bevy_ecs::entity::Entity; use bevy_ecs::event::EventWriter; -use bevy_ecs::query::{Changed, Or, With, Without}; +use bevy_ecs::query::{Changed, Or, Without}; use bevy_ecs::removal_detection::RemovedComponents; use bevy_ecs::resource::Resource; use bevy_ecs::system::{NonSendMut, Query, Res, ResMut};