Files
rust-otus/snake-game/src/domain.rs
T

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);
}
}