mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-07 11:15:47 -06:00
fix: working movement again with ecs
This commit is contained in:
@@ -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<Map>,
|
||||
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>,
|
||||
) {
|
||||
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<GameEvent>,
|
||||
@@ -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;
|
||||
|
||||
@@ -126,7 +126,7 @@ impl Position {
|
||||
pub struct Velocity {
|
||||
pub direction: Direction,
|
||||
pub next_direction: Option<(Direction, u8)>,
|
||||
pub speed: Option<f32>,
|
||||
pub speed: f32,
|
||||
}
|
||||
|
||||
#[derive(Bundle)]
|
||||
|
||||
@@ -11,18 +11,21 @@ use sdl2::video::Window;
|
||||
/// Updates the directional animated texture of an entity.
|
||||
pub fn directional_render_system(
|
||||
dt: Res<DeltaTime>,
|
||||
mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable)>,
|
||||
mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable, &Position)>,
|
||||
mut errors: EventWriter<GameError>,
|
||||
) {
|
||||
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());
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user