diff --git a/snake-game/src/domain.rs b/snake-game/src/domain.rs index a5c7f37..629031c 100644 --- a/snake-game/src/domain.rs +++ b/snake-game/src/domain.rs @@ -23,7 +23,7 @@ pub struct Head(pub Direction); /// Сегмент змеиного хвоста #[derive(Component)] -pub struct Tail; +pub struct Tail(pub Entity); /// Конец змеиного хвоста #[derive(Component)] diff --git a/snake-game/src/domain/events.rs b/snake-game/src/domain/events.rs index a63ce92..12d6e07 100644 --- a/snake-game/src/domain/events.rs +++ b/snake-game/src/domain/events.rs @@ -22,5 +22,6 @@ pub struct GrowUp; #[derive(Event, Debug)] pub enum Collision { Bounds, - Entity(Entity), + Tail, + Meal, } diff --git a/snake-game/src/gameplay.rs b/snake-game/src/gameplay.rs index 52b2ae2..3cc7a7f 100644 --- a/snake-game/src/gameplay.rs +++ b/snake-game/src/gameplay.rs @@ -119,3 +119,24 @@ pub fn check_bounds_colisions(head: Single<(&Transform,), (With,)>, mut co commands.trigger(Collision::Bounds); }; } + +/// Система отслеживания столкновений c хвостом +pub fn check_tail_colisions( + head: Single<(&Transform, Entity), (With,)>, + query: Query<(&Transform, &Velocity, &Tail)>, + mut commands: Commands, // +) { + let (head_transform, head_entity) = head.into_inner(); + for (tail_transform, velocity, tail) in query.into_iter() { + if velocity.0 == 0.0 || tail.0 == head_entity { + continue; + } + let distance = head_transform.translation.distance(tail_transform.translation); + if distance < GRID_SIZE as f32 { + commands.trigger(Collision::Tail); + } + } +} + +/// Система отслеживания столкновений с едой +pub fn check_meal_collisions() {} diff --git a/snake-game/src/lib.rs b/snake-game/src/lib.rs index 7da9fd5..1f5835e 100644 --- a/snake-game/src/lib.rs +++ b/snake-game/src/lib.rs @@ -5,6 +5,6 @@ mod observers; mod startup; mod tools; -pub use gameplay::{check_bounds_colisions, head_moving, head_rotation, snake_moving}; +pub use gameplay::{check_bounds_colisions, check_meal_collisions, check_tail_colisions, head_moving, head_rotation, snake_moving}; pub use startup::{setup_window, startup}; pub use tools::define_log_layer; diff --git a/snake-game/src/main.rs b/snake-game/src/main.rs index 85ce8d5..a9af779 100644 --- a/snake-game/src/main.rs +++ b/snake-game/src/main.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use snake_game::{check_bounds_colisions, head_moving, head_rotation, setup_window, snake_moving, startup}; +use snake_game::{check_bounds_colisions, check_meal_collisions, check_tail_colisions, head_moving, head_rotation, setup_window, snake_moving, startup}; fn main() { App::new() @@ -47,6 +47,8 @@ fn main() { ( || {}, // check_bounds_colisions, + check_tail_colisions, + check_meal_collisions, snake_game::debug::print_all_entities_by_press_enter, snake_game::debug::time_speed, ), diff --git a/snake-game/src/observers.rs b/snake-game/src/observers.rs index d1942c5..f1e1c63 100644 --- a/snake-game/src/observers.rs +++ b/snake-game/src/observers.rs @@ -1,6 +1,6 @@ use crate::domain::*; -use bevy::prelude::*; +use bevy::{color::palettes::tailwind::*, prelude::*}; /// Запланировать установку скорости движения [Velocity] при следующем событии [GridBarier] pub fn schedule_set_velocity(tail: Entity) -> impl Fn(On, Commands, Query<(&mut Velocity, &Transform)>) { @@ -29,7 +29,7 @@ pub fn grow_up_snake(_: On, mut commands: Commands, query: Single<(Entit let pos = Position::from(transform); let new_end = commands .spawn(( - Tail, + Tail(entity), End, direction.clone(), Velocity(0.0), @@ -42,3 +42,21 @@ pub fn grow_up_snake(_: On, mut commands: Commands, query: Single<(Entit .id(); commands.entity(entity).observe(schedule_set_velocity(new_end)); } + +/// Обработка столкновений +pub fn handle_collisions( + event: On, // + query: Query<(&mut Velocity, &mut Sprite), Or<(With, With, With)>>, +) { + match event.event() { + Collision::Meal => { + todo!() + } + Collision::Bounds | Collision::Tail => { + for (mut velocity, mut sprite) in query.into_iter() { + velocity.0 = 0.0; + sprite.color = RED_300.into(); + } + } + } +} diff --git a/snake-game/src/startup.rs b/snake-game/src/startup.rs index b90859c..38f1d67 100644 --- a/snake-game/src/startup.rs +++ b/snake-game/src/startup.rs @@ -68,6 +68,7 @@ fn spawn_snake(commands: &mut Commands) { use crate::domain::{Direction, HEAD_SIZE, Head, SNAKE_VELOCITY, Velocity}; commands.spawn(Observer::new(crate::debug::trace_snake_moving)); + commands.spawn(Observer::new(crate::observers::handle_collisions)); let head = commands .spawn(( @@ -100,7 +101,7 @@ fn spawn_snake(commands: &mut Commands) { let tail = commands .spawn(( - Tail, + Tail(head), End, Direction::default(), Velocity(0.0),