140 lines
4.0 KiB
Rust
140 lines
4.0 KiB
Rust
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<Position, Direction>);
|
|
|
|
#[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);
|
|
}
|
|
}
|