use std::{collections::HashMap, fmt::Debug}; use bevy::prelude::*; use crate::tools::Position; pub const GRID_SIZE: u8 = 48; pub const HEAD_SIZE: u8 = (GRID_SIZE as f32 * 1.1) as u8; pub const SNAKE_VELOCITY: u8 = (GRID_SIZE as f32 / 1.0) as u8; /// Голова змеи #[derive(Component)] pub struct Head; /// Сегмент змеиного хвоста #[derive(Component)] pub struct Tail; /// Конец змеиного хвоста #[derive(Component)] pub struct End; /// Событие прохождения границы сетки #[derive(EntityEvent)] pub struct GridBarier { pub entity: Entity, pub pos: Position, } impl GridBarier { pub fn new(entity: Entity, pos: Position) -> Self { Self { entity, pos } } } /// Направление движения #[derive(Component, PartialEq, Clone, Copy, Debug)] pub enum Direction { Up, Left, Down, Right, } impl Direction { /// Поворот налево pub fn rotate_left(&mut self) { *self = match self { Direction::Up => Direction::Left, Direction::Left => Direction::Down, Direction::Down => Direction::Right, Direction::Right => Direction::Up, }; } /// Поворот направо pub fn rotate_right(&mut self) { *self = match self { Direction::Up => Direction::Right, Direction::Right => Direction::Down, Direction::Down => Direction::Left, Direction::Left => Direction::Up, }; } /// Получить значение кооринаты соответствующей направлению движения pub fn get_coord(&self, vec: &Transform) -> f32 { match self { Direction::Up | Direction::Down => vec.translation.y, Direction::Left | Direction::Right => vec.translation.x, } } /// Получить знак изменения соответствующий направлению движения pub fn get_change_sign(&self) -> f32 { match self { Direction::Up | Direction::Right => 1.0, Direction::Down | Direction::Left => -1.0, } } /// Установить значение кооринаты соответствующей направлению движения pub fn set_coord(&self, vec: &mut Transform, value: f32) { match self { Direction::Up | Direction::Down => vec.translation.y = value, Direction::Left | Direction::Right => vec.translation.x = value, } } /// Получить следующую по направлению координатную позицию pub fn next_pos(&self, transform: &Transform) -> Position { let mut pos = Position::from(transform); match self { Direction::Up => pos.y += 1, Direction::Left => pos.x -= 1, Direction::Down => pos.y -= 1, Direction::Right => pos.x += 1, }; pos } } impl Default for Direction { fn default() -> Self { Direction::Up } } /// Скорость движения #[derive(Component)] pub struct Velocity(pub f32); /// Инерция #[derive(Component, Default)] pub struct Inert(pub Direction); /// Путь змеи #[derive(Resource, Default, Debug, Deref, DerefMut)] pub struct SnakePath(HashMap); #[cfg(test)] mod test { use crate::domain::*; use std::collections::HashMap; #[test] fn test_snake_path() { let mut snake_path = SnakePath(HashMap::default()); snake_path.push(&Transform::default(), Direction::default()); assert_eq!(snake_path.0.len(), 1); assert!(snake_path.pick(&Transform::default()) == Some((Position::default(), Direction::default()))); assert_eq!(snake_path.0.len(), 1); assert!(snake_path.drop(&Transform::default()) == Some((Position::default(), Direction::default()))); assert_eq!(snake_path.0.len(), 0); } }