mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-06 21:15:48 -06:00
feat: entity type for proper edge permission calculations
This commit is contained in:
@@ -8,7 +8,7 @@ use crate::error::{GameError, GameResult, TextureError};
|
||||
use crate::events::GameEvent;
|
||||
use crate::map::builder::Map;
|
||||
use crate::systems::components::{
|
||||
DeltaTime, DirectionalAnimated, GlobalState, PlayerBundle, PlayerControlled, Position, Renderable, Velocity,
|
||||
DeltaTime, DirectionalAnimated, EntityType, GlobalState, PlayerBundle, PlayerControlled, Position, Renderable, Velocity,
|
||||
};
|
||||
use crate::systems::control::player_system;
|
||||
use crate::systems::movement::movement_system;
|
||||
@@ -143,6 +143,7 @@ impl Game {
|
||||
textures,
|
||||
stopped_textures,
|
||||
},
|
||||
entity_type: EntityType::Player,
|
||||
};
|
||||
|
||||
world.insert_non_send_resource(atlas);
|
||||
|
||||
@@ -11,6 +11,16 @@ use crate::{
|
||||
#[derive(Default, Component)]
|
||||
pub struct PlayerControlled;
|
||||
|
||||
/// A tag component denoting the type of entity.
|
||||
#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum EntityType {
|
||||
Player,
|
||||
Ghost,
|
||||
Pellet,
|
||||
PowerPellet,
|
||||
Wall,
|
||||
}
|
||||
|
||||
/// A component for entities that have a sprite, with a layer for ordering.
|
||||
///
|
||||
/// This is intended to be modified by other entities allowing animation.
|
||||
@@ -127,6 +137,7 @@ pub struct PlayerBundle {
|
||||
pub velocity: Velocity,
|
||||
pub sprite: Renderable,
|
||||
pub directional_animated: DirectionalAnimated,
|
||||
pub entity_type: EntityType,
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
use crate::entity::graph::EdgePermissions;
|
||||
use crate::entity::graph::{Edge, EdgePermissions, Graph};
|
||||
use crate::error::{EntityError, GameError};
|
||||
use crate::map::builder::Map;
|
||||
use crate::systems::components::{DeltaTime, PlayerControlled, Position, Velocity};
|
||||
use crate::systems::components::{DeltaTime, EntityType, Position, Velocity};
|
||||
use bevy_ecs::event::EventWriter;
|
||||
use bevy_ecs::system::{Query, Res};
|
||||
|
||||
fn can_traverse(_player: &mut PlayerControlled, edge: crate::entity::graph::Edge) -> bool {
|
||||
matches!(edge.permissions, EdgePermissions::All)
|
||||
fn can_traverse(entity_type: EntityType, edge: Edge) -> bool {
|
||||
match entity_type {
|
||||
EntityType::Player => matches!(edge.permissions, EdgePermissions::All),
|
||||
EntityType::Ghost => matches!(edge.permissions, EdgePermissions::All | EdgePermissions::GhostsOnly),
|
||||
_ => matches!(edge.permissions, EdgePermissions::All),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn movement_system(
|
||||
map: Res<Map>,
|
||||
delta_time: Res<DeltaTime>,
|
||||
mut entities: Query<(&mut PlayerControlled, &mut Velocity, &mut Position)>,
|
||||
mut entities: Query<(&mut Velocity, &mut Position, &EntityType)>,
|
||||
mut errors: EventWriter<GameError>,
|
||||
) {
|
||||
for (mut player, mut velocity, mut position) in entities.iter_mut() {
|
||||
for (mut velocity, mut position, entity_type) in entities.iter_mut() {
|
||||
let distance = velocity.speed * 60.0 * delta_time.0;
|
||||
|
||||
// Decrement the remaining frames for the next direction
|
||||
@@ -32,7 +36,7 @@ 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 can_traverse(&mut player, edge) {
|
||||
if can_traverse(*entity_type, edge) {
|
||||
// Start moving in that direction
|
||||
*position = Position::BetweenNodes {
|
||||
from: node_id,
|
||||
@@ -90,7 +94,7 @@ 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 can_traverse(&mut player, edge) {
|
||||
if can_traverse(*entity_type, edge) {
|
||||
*position = Position::BetweenNodes {
|
||||
from: to,
|
||||
to: edge.target,
|
||||
@@ -107,7 +111,7 @@ pub fn movement_system(
|
||||
// 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 can_traverse(&mut player, edge) {
|
||||
if can_traverse(*entity_type, edge) {
|
||||
*position = Position::BetweenNodes {
|
||||
from: to,
|
||||
to: edge.target,
|
||||
|
||||
@@ -9,6 +9,8 @@ use sdl2::render::{Canvas, Texture};
|
||||
use sdl2::video::Window;
|
||||
|
||||
/// Updates the directional animated texture of an entity.
|
||||
///
|
||||
/// This runs before the render system so it can update the sprite based on the current direction of travel, as well as whether the entity is moving.
|
||||
pub fn directional_render_system(
|
||||
dt: Res<DeltaTime>,
|
||||
mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable, &Position)>,
|
||||
@@ -34,7 +36,10 @@ pub fn directional_render_system(
|
||||
}
|
||||
}
|
||||
|
||||
/// A non-send resource for the map texture. This just wraps the texture with a type so it can be differentiated when exposed as a resource.
|
||||
pub struct MapTextureResource(pub Texture<'static>);
|
||||
|
||||
/// A non-send resource for the backbuffer texture. This just wraps the texture with a type so it can be differentiated when exposed as a resource.
|
||||
pub struct BackbufferResource(pub Texture<'static>);
|
||||
|
||||
pub fn render_system(
|
||||
@@ -43,7 +48,7 @@ pub fn render_system(
|
||||
mut backbuffer: NonSendMut<BackbufferResource>,
|
||||
mut atlas: NonSendMut<SpriteAtlas>,
|
||||
map: Res<Map>,
|
||||
mut renderables: Query<(Entity, &mut Renderable, &Position)>,
|
||||
renderables: Query<(Entity, &mut Renderable, &Position)>,
|
||||
mut errors: EventWriter<GameError>,
|
||||
) {
|
||||
// Clear the main canvas first
|
||||
@@ -64,7 +69,11 @@ pub fn render_system(
|
||||
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
|
||||
|
||||
// Render all entities to the backbuffer
|
||||
for (_, mut renderable, position) in renderables.iter_mut() {
|
||||
for (_, mut renderable, position) in renderables
|
||||
// .iter_mut()
|
||||
// .sort_by_key::<&mut Renderable, _, _>(|(renderable, renderable, renderable)| renderable.layer)
|
||||
// .collect()
|
||||
{
|
||||
let pos = position.get_pixel_pos(&map.graph);
|
||||
match pos {
|
||||
Ok(pos) => {
|
||||
|
||||
Reference in New Issue
Block a user