From 70fb2b9503354d45e1af5854fb8c3dba20c7a1fe Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 14 Aug 2025 18:35:23 -0500 Subject: [PATCH] fix: working movement again with ecs --- src/ecs/interact.rs | 83 ++++++++++++++++++++++----------------------- src/ecs/mod.rs | 2 +- src/ecs/render.rs | 11 +++--- src/game/mod.rs | 2 +- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/ecs/interact.rs b/src/ecs/interact.rs index 4f51957..2273052 100644 --- a/src/ecs/interact.rs +++ b/src/ecs/interact.rs @@ -1,9 +1,10 @@ use bevy_ecs::{ event::{EventReader, EventWriter}, - query::With, system::{Query, Res, ResMut}, }; +use tracing::debug; +use crate::entity::graph::EdgePermissions; use crate::{ ecs::{DeltaTime, GlobalState, PlayerControlled, Position, Velocity}, error::{EntityError, GameError}, @@ -15,11 +16,11 @@ use crate::{ pub fn movement_system( map: Res, delta_time: Res, - mut entities: Query<(&PlayerControlled, &mut Velocity, &mut Position)>, + mut entities: Query<(&mut PlayerControlled, &mut Velocity, &mut Position)>, mut errors: EventWriter, ) { - for (player, mut velocity, mut position) in entities.iter_mut() { - let distance = velocity.speed.unwrap_or(0.0) * delta_time.0; + for (mut player, mut velocity, mut position) in entities.iter_mut() { + let distance = velocity.speed * 60.0 * delta_time.0; // Decrement the remaining frames for the next direction if let Some((direction, remaining)) = velocity.next_direction { @@ -35,22 +36,16 @@ pub fn movement_system( // We're not moving, but a buffered direction is available. if let Some((next_direction, _)) = velocity.next_direction { if let Some(edge) = map.graph.find_edge_in_direction(node_id, next_direction) { - // if edge.permissions.can_traverse(edge) { - // // Start moving in that direction - *position = Position::BetweenNodes { - from: node_id, - to: edge.target, - traversed: distance, - }; - velocity.direction = next_direction; - // } else { - // return Err(crate::error::GameError::Entity(crate::error::EntityError::InvalidMovement( - // format!( - // "Cannot traverse edge from {} to {} in direction {:?}", - // node_id, edge.target, next_direction - // ), - // ))); - // } + if can_traverse(&mut player, edge) { + // Start moving in that direction + *position = Position::BetweenNodes { + from: node_id, + to: edge.target, + traversed: distance, + }; + velocity.direction = next_direction; + velocity.next_direction = None; + } } else { errors.write( EntityError::InvalidMovement(format!( @@ -60,8 +55,6 @@ pub fn movement_system( .into(), ); } - - velocity.next_direction = None; // Consume the buffered direction regardless of whether we started moving with it } } Position::BetweenNodes { from, to, traversed } => { @@ -101,33 +94,33 @@ pub fn movement_system( // If we buffered a direction, try to find an edge in that direction if let Some((next_dir, _)) = velocity.next_direction { if let Some(edge) = map.graph.find_edge_in_direction(to, next_dir) { - // if edge.permissions.can_traverse(edge) { - // *position = Position::BetweenNodes { - // from: to, - // to: edge.target, - // traversed: overflow, - // }; + if can_traverse(&mut player, edge) { + *position = Position::BetweenNodes { + from: to, + to: edge.target, + traversed: overflow, + }; - velocity.direction = next_dir; // Remember our new direction - velocity.next_direction = None; // Consume the buffered direction - moved = true; - // } + velocity.direction = next_dir; // Remember our new direction + velocity.next_direction = None; // Consume the buffered direction + moved = true; + } } } // If we didn't move, try to continue in the current direction if !moved { if let Some(edge) = map.graph.find_edge_in_direction(to, velocity.direction) { - // if edge.permissions.can_traverse(edge) { - *position = Position::BetweenNodes { - from: to, - to: edge.target, - traversed: overflow, - }; - // } else { - // *position = Position::AtNode(to); - // velocity.next_direction = None; - // } + if can_traverse(&mut player, edge) { + *position = Position::BetweenNodes { + from: to, + to: edge.target, + traversed: overflow, + }; + } else { + *position = Position::AtNode(to); + velocity.next_direction = None; + } } else { *position = Position::AtNode(to); velocity.next_direction = None; @@ -139,6 +132,10 @@ pub fn movement_system( } } +fn can_traverse(_player: &mut PlayerControlled, edge: crate::entity::graph::Edge) -> bool { + matches!(edge.permissions, EdgePermissions::All) +} + // Handles pub fn interact_system( mut events: EventReader, @@ -160,7 +157,7 @@ pub fn interact_system( match event { GameEvent::Command(command) => match command { GameCommand::MovePlayer(direction) => { - velocity.direction = *direction; + velocity.next_direction = Some((*direction, 90)); } GameCommand::Exit => { state.exit = true; diff --git a/src/ecs/mod.rs b/src/ecs/mod.rs index 13160fa..375cdcf 100644 --- a/src/ecs/mod.rs +++ b/src/ecs/mod.rs @@ -126,7 +126,7 @@ impl Position { pub struct Velocity { pub direction: Direction, pub next_direction: Option<(Direction, u8)>, - pub speed: Option, + pub speed: f32, } #[derive(Bundle)] diff --git a/src/ecs/render.rs b/src/ecs/render.rs index 1b86530..84050b7 100644 --- a/src/ecs/render.rs +++ b/src/ecs/render.rs @@ -11,18 +11,21 @@ use sdl2::video::Window; /// Updates the directional animated texture of an entity. pub fn directional_render_system( dt: Res, - mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable)>, + mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable, &Position)>, mut errors: EventWriter, ) { - for (velocity, mut texture, mut renderable) in renderables.iter_mut() { - let texture = if velocity.speed.is_none() { + for (velocity, mut texture, mut renderable, position) in renderables.iter_mut() { + let stopped = matches!(position, Position::AtNode(_)); + let texture = if stopped { texture.stopped_textures[velocity.direction.as_usize()].as_mut() } else { texture.textures[velocity.direction.as_usize()].as_mut() }; if let Some(texture) = texture { - texture.tick(dt.0); + if !stopped { + texture.tick(dt.0); + } renderable.sprite = *texture.current_tile(); } else { errors.write(TextureError::RenderFailed(format!("Entity has no texture")).into()); diff --git a/src/game/mod.rs b/src/game/mod.rs index d07d55a..1633fe3 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -135,7 +135,7 @@ impl Game { velocity: Velocity { direction: Direction::Up, next_direction: None, - speed: Some(1.0), + speed: 1.125, }, sprite: Renderable { sprite: SpriteAtlas::get_tile(&atlas, "pacman/full.png")