Compare commits

..

1 Commits

Author SHA1 Message Date
70fb2b9503 fix: working movement again with ecs 2025-08-14 18:35:23 -05:00
4 changed files with 49 additions and 49 deletions

View File

@@ -1,9 +1,10 @@
use bevy_ecs::{ use bevy_ecs::{
event::{EventReader, EventWriter}, event::{EventReader, EventWriter},
query::With,
system::{Query, Res, ResMut}, system::{Query, Res, ResMut},
}; };
use tracing::debug;
use crate::entity::graph::EdgePermissions;
use crate::{ use crate::{
ecs::{DeltaTime, GlobalState, PlayerControlled, Position, Velocity}, ecs::{DeltaTime, GlobalState, PlayerControlled, Position, Velocity},
error::{EntityError, GameError}, error::{EntityError, GameError},
@@ -15,11 +16,11 @@ use crate::{
pub fn movement_system( pub fn movement_system(
map: Res<Map>, map: Res<Map>,
delta_time: Res<DeltaTime>, delta_time: Res<DeltaTime>,
mut entities: Query<(&PlayerControlled, &mut Velocity, &mut Position)>, mut entities: Query<(&mut PlayerControlled, &mut Velocity, &mut Position)>,
mut errors: EventWriter<GameError>, mut errors: EventWriter<GameError>,
) { ) {
for (player, mut velocity, mut position) in entities.iter_mut() { for (mut player, mut velocity, mut position) in entities.iter_mut() {
let distance = velocity.speed.unwrap_or(0.0) * delta_time.0; let distance = velocity.speed * 60.0 * delta_time.0;
// Decrement the remaining frames for the next direction // Decrement the remaining frames for the next direction
if let Some((direction, remaining)) = velocity.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. // We're not moving, but a buffered direction is available.
if let Some((next_direction, _)) = velocity.next_direction { if let Some((next_direction, _)) = velocity.next_direction {
if let Some(edge) = map.graph.find_edge_in_direction(node_id, next_direction) { if let Some(edge) = map.graph.find_edge_in_direction(node_id, next_direction) {
// if edge.permissions.can_traverse(edge) { if can_traverse(&mut player, edge) {
// // Start moving in that direction // Start moving in that direction
*position = Position::BetweenNodes { *position = Position::BetweenNodes {
from: node_id, from: node_id,
to: edge.target, to: edge.target,
traversed: distance, traversed: distance,
}; };
velocity.direction = next_direction; velocity.direction = next_direction;
// } else { velocity.next_direction = None;
// return Err(crate::error::GameError::Entity(crate::error::EntityError::InvalidMovement( }
// format!(
// "Cannot traverse edge from {} to {} in direction {:?}",
// node_id, edge.target, next_direction
// ),
// )));
// }
} else { } else {
errors.write( errors.write(
EntityError::InvalidMovement(format!( EntityError::InvalidMovement(format!(
@@ -60,8 +55,6 @@ pub fn movement_system(
.into(), .into(),
); );
} }
velocity.next_direction = None; // Consume the buffered direction regardless of whether we started moving with it
} }
} }
Position::BetweenNodes { from, to, traversed } => { 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 we buffered a direction, try to find an edge in that direction
if let Some((next_dir, _)) = velocity.next_direction { if let Some((next_dir, _)) = velocity.next_direction {
if let Some(edge) = map.graph.find_edge_in_direction(to, next_dir) { if let Some(edge) = map.graph.find_edge_in_direction(to, next_dir) {
// if edge.permissions.can_traverse(edge) { if can_traverse(&mut player, edge) {
// *position = Position::BetweenNodes { *position = Position::BetweenNodes {
// from: to, from: to,
// to: edge.target, to: edge.target,
// traversed: overflow, traversed: overflow,
// }; };
velocity.direction = next_dir; // Remember our new direction velocity.direction = next_dir; // Remember our new direction
velocity.next_direction = None; // Consume the buffered direction velocity.next_direction = None; // Consume the buffered direction
moved = true; moved = true;
// } }
} }
} }
// If we didn't move, try to continue in the current direction // If we didn't move, try to continue in the current direction
if !moved { if !moved {
if let Some(edge) = map.graph.find_edge_in_direction(to, velocity.direction) { if let Some(edge) = map.graph.find_edge_in_direction(to, velocity.direction) {
// if edge.permissions.can_traverse(edge) { if can_traverse(&mut player, edge) {
*position = Position::BetweenNodes { *position = Position::BetweenNodes {
from: to, from: to,
to: edge.target, to: edge.target,
traversed: overflow, traversed: overflow,
}; };
// } else { } else {
// *position = Position::AtNode(to); *position = Position::AtNode(to);
// velocity.next_direction = None; velocity.next_direction = None;
// } }
} else { } else {
*position = Position::AtNode(to); *position = Position::AtNode(to);
velocity.next_direction = None; 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 // Handles
pub fn interact_system( pub fn interact_system(
mut events: EventReader<GameEvent>, mut events: EventReader<GameEvent>,
@@ -160,7 +157,7 @@ pub fn interact_system(
match event { match event {
GameEvent::Command(command) => match command { GameEvent::Command(command) => match command {
GameCommand::MovePlayer(direction) => { GameCommand::MovePlayer(direction) => {
velocity.direction = *direction; velocity.next_direction = Some((*direction, 90));
} }
GameCommand::Exit => { GameCommand::Exit => {
state.exit = true; state.exit = true;

View File

@@ -126,7 +126,7 @@ impl Position {
pub struct Velocity { pub struct Velocity {
pub direction: Direction, pub direction: Direction,
pub next_direction: Option<(Direction, u8)>, pub next_direction: Option<(Direction, u8)>,
pub speed: Option<f32>, pub speed: f32,
} }
#[derive(Bundle)] #[derive(Bundle)]

View File

@@ -11,18 +11,21 @@ use sdl2::video::Window;
/// Updates the directional animated texture of an entity. /// Updates the directional animated texture of an entity.
pub fn directional_render_system( pub fn directional_render_system(
dt: Res<DeltaTime>, dt: Res<DeltaTime>,
mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable)>, mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable, &Position)>,
mut errors: EventWriter<GameError>, mut errors: EventWriter<GameError>,
) { ) {
for (velocity, mut texture, mut renderable) in renderables.iter_mut() { for (velocity, mut texture, mut renderable, position) in renderables.iter_mut() {
let texture = if velocity.speed.is_none() { let stopped = matches!(position, Position::AtNode(_));
let texture = if stopped {
texture.stopped_textures[velocity.direction.as_usize()].as_mut() texture.stopped_textures[velocity.direction.as_usize()].as_mut()
} else { } else {
texture.textures[velocity.direction.as_usize()].as_mut() texture.textures[velocity.direction.as_usize()].as_mut()
}; };
if let Some(texture) = texture { if let Some(texture) = texture {
texture.tick(dt.0); if !stopped {
texture.tick(dt.0);
}
renderable.sprite = *texture.current_tile(); renderable.sprite = *texture.current_tile();
} else { } else {
errors.write(TextureError::RenderFailed(format!("Entity has no texture")).into()); errors.write(TextureError::RenderFailed(format!("Entity has no texture")).into());

View File

@@ -135,7 +135,7 @@ impl Game {
velocity: Velocity { velocity: Velocity {
direction: Direction::Up, direction: Direction::Up,
next_direction: None, next_direction: None,
speed: Some(1.0), speed: 1.125,
}, },
sprite: Renderable { sprite: Renderable {
sprite: SpriteAtlas::get_tile(&atlas, "pacman/full.png") sprite: SpriteAtlas::get_tile(&atlas, "pacman/full.png")