use crate::domain::*; use bevy::{color::palettes::tailwind::*, prelude::*}; /// Запланировать установку скорости движения [Velocity] при следующем событии [GridBarier] pub fn schedule_set_velocity(tail: Entity) -> impl Fn(On, Commands, Query<(&mut Velocity, &Transform)>) { move |event: On, mut commands: Commands, mut query: Query<(&mut Velocity, &Transform)>| { if let Ok((mut velocity, transform)) = query.get_mut(tail) { let position = Position::from(transform); if event.position != position { velocity.0 = SNAKE_VELOCITY as f32; commands.entity(event.observer()).despawn(); } } } } /// Очистка [SnakePath] от старых значений pub fn clean_snake_path(event: On, query: Query<&End>, mut snake_path: ResMut) { if query.contains(event.entity) { let v = snake_path.remove(&event.position); trace!("clean_snake_path: removed {v:?} for {}", &event.position); } } /// Обработка события [GrowUp] #[allow(clippy::type_complexity)] pub fn grow_up_snake(_: On, mut commands: Commands, query: Single<(Entity, &Direction, &Transform, &mut Sprite), (With, With)>) { let (entity, direction, transform, mut sprite) = query.into_inner(); sprite.color = GRAY_300.into(); commands.entity(entity).remove::(); let pos = Position::from(transform); let new_end = commands .spawn(( Tail(entity), End, *direction, Velocity(0.0), Sprite::from_color(YELLOW_500, vec2(HEAD_SIZE as f32 * 0.8, HEAD_SIZE as f32 * 0.8)), Transform { translation: pos.translation().extend(0.0), ..Default::default() }, )) .id(); commands.entity(entity).observe(schedule_set_velocity(new_end)); } /// Обработка столкновений #[allow(clippy::type_complexity)] pub fn handle_collisions( event: On, // query: Query<(&mut Velocity, &mut Sprite), Or<(With, With, With)>>, mut commands: Commands, ) { match event.event() { Collision::Meal(entity) => { commands.entity(*entity).despawn(); commands.trigger(GrowUp); } Collision::Bounds | Collision::Tail => { for (mut velocity, mut sprite) in query.into_iter() { velocity.0 = 0.0; sprite.color = RED_300.into(); } } } }