mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-08 06:07:46 -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::events::GameEvent;
|
||||||
use crate::map::builder::Map;
|
use crate::map::builder::Map;
|
||||||
use crate::systems::components::{
|
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::control::player_system;
|
||||||
use crate::systems::movement::movement_system;
|
use crate::systems::movement::movement_system;
|
||||||
@@ -143,6 +143,7 @@ impl Game {
|
|||||||
textures,
|
textures,
|
||||||
stopped_textures,
|
stopped_textures,
|
||||||
},
|
},
|
||||||
|
entity_type: EntityType::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
world.insert_non_send_resource(atlas);
|
world.insert_non_send_resource(atlas);
|
||||||
|
|||||||
@@ -11,6 +11,16 @@ use crate::{
|
|||||||
#[derive(Default, Component)]
|
#[derive(Default, Component)]
|
||||||
pub struct PlayerControlled;
|
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.
|
/// A component for entities that have a sprite, with a layer for ordering.
|
||||||
///
|
///
|
||||||
/// This is intended to be modified by other entities allowing animation.
|
/// This is intended to be modified by other entities allowing animation.
|
||||||
@@ -127,6 +137,7 @@ pub struct PlayerBundle {
|
|||||||
pub velocity: Velocity,
|
pub velocity: Velocity,
|
||||||
pub sprite: Renderable,
|
pub sprite: Renderable,
|
||||||
pub directional_animated: DirectionalAnimated,
|
pub directional_animated: DirectionalAnimated,
|
||||||
|
pub entity_type: EntityType,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[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::error::{EntityError, GameError};
|
||||||
use crate::map::builder::Map;
|
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::event::EventWriter;
|
||||||
use bevy_ecs::system::{Query, Res};
|
use bevy_ecs::system::{Query, Res};
|
||||||
|
|
||||||
fn can_traverse(_player: &mut PlayerControlled, edge: crate::entity::graph::Edge) -> bool {
|
fn can_traverse(entity_type: EntityType, edge: Edge) -> bool {
|
||||||
matches!(edge.permissions, EdgePermissions::All)
|
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(
|
pub fn movement_system(
|
||||||
map: Res<Map>,
|
map: Res<Map>,
|
||||||
delta_time: Res<DeltaTime>,
|
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>,
|
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;
|
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
|
||||||
@@ -32,7 +36,7 @@ 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 can_traverse(&mut player, edge) {
|
if can_traverse(*entity_type, edge) {
|
||||||
// Start moving in that direction
|
// Start moving in that direction
|
||||||
*position = Position::BetweenNodes {
|
*position = Position::BetweenNodes {
|
||||||
from: node_id,
|
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 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 can_traverse(&mut player, edge) {
|
if can_traverse(*entity_type, edge) {
|
||||||
*position = Position::BetweenNodes {
|
*position = Position::BetweenNodes {
|
||||||
from: to,
|
from: to,
|
||||||
to: edge.target,
|
to: edge.target,
|
||||||
@@ -107,7 +111,7 @@ pub fn movement_system(
|
|||||||
// 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 can_traverse(&mut player, edge) {
|
if can_traverse(*entity_type, edge) {
|
||||||
*position = Position::BetweenNodes {
|
*position = Position::BetweenNodes {
|
||||||
from: to,
|
from: to,
|
||||||
to: edge.target,
|
to: edge.target,
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ use sdl2::render::{Canvas, Texture};
|
|||||||
use sdl2::video::Window;
|
use sdl2::video::Window;
|
||||||
|
|
||||||
/// Updates the directional animated texture of an entity.
|
/// 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(
|
pub fn directional_render_system(
|
||||||
dt: Res<DeltaTime>,
|
dt: Res<DeltaTime>,
|
||||||
mut renderables: Query<(&Velocity, &mut DirectionalAnimated, &mut Renderable, &Position)>,
|
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>);
|
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 struct BackbufferResource(pub Texture<'static>);
|
||||||
|
|
||||||
pub fn render_system(
|
pub fn render_system(
|
||||||
@@ -43,7 +48,7 @@ pub fn render_system(
|
|||||||
mut backbuffer: NonSendMut<BackbufferResource>,
|
mut backbuffer: NonSendMut<BackbufferResource>,
|
||||||
mut atlas: NonSendMut<SpriteAtlas>,
|
mut atlas: NonSendMut<SpriteAtlas>,
|
||||||
map: Res<Map>,
|
map: Res<Map>,
|
||||||
mut renderables: Query<(Entity, &mut Renderable, &Position)>,
|
renderables: Query<(Entity, &mut Renderable, &Position)>,
|
||||||
mut errors: EventWriter<GameError>,
|
mut errors: EventWriter<GameError>,
|
||||||
) {
|
) {
|
||||||
// Clear the main canvas first
|
// Clear the main canvas first
|
||||||
@@ -64,7 +69,11 @@ pub fn render_system(
|
|||||||
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
|
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
|
||||||
|
|
||||||
// Render all entities to the backbuffer
|
// 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);
|
let pos = position.get_pixel_pos(&map.graph);
|
||||||
match pos {
|
match pos {
|
||||||
Ok(pos) => {
|
Ok(pos) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user