Проектная работа - WIP

This commit is contained in:
5 changed files with 48 additions and 89 deletions
+4
View File
@@ -9,6 +9,10 @@ pub const SNAKE_VELOCITY: u8 = (GRID_SIZE as f32 / 1.0) as u8;
#[derive(Component)]
pub struct Head;
/// Сегмент змеиного хвоста
#[derive(Component)]
pub struct Tail(pub u16);
/// Направление движения
#[derive(Component, PartialEq, Clone, Copy)]
pub enum Direction {
-76
View File
@@ -40,42 +40,6 @@ pub fn moving(time: Res<Time>, query: Query<(&mut Transform, &mut Inert, &Direct
}
}
fn get_overflow(grid: f32, coord: f32, delta: f32) -> f32 {
let rem = coord % grid;
let rem = if rem < 0.0 { grid + rem } else { rem };
let new = rem + delta;
if new >= 0.0 && new <= grid {
0.0
} else {
new % grid
}
}
/// Найти значение значение на границе сетки, если она находится между значениями old и new
fn find_grid_bound(old: f32, new: f32, grid: f32) -> f32 {
use std::f32::NAN;
if grid <= 0.0 {
return NAN;
};
let old_grid = old / grid;
let new_grid = new / grid;
let old_grid_left = old_grid.floor();
let old_grid_right = old_grid.ceil();
let new_grid_left = new_grid.floor();
let new_grid_right = new_grid.ceil();
if old_grid_right == new_grid_left {
old_grid_right * grid
} else if old_grid_left == new_grid_right {
old_grid_left * grid
} else {
NAN
}
}
/// Разбиение изменения координаты по границам сетки
fn split_by_grid(src: f32, dst: f32, grid: f32) -> Vec<(f32, f32)> {
if grid <= 0.0 {
@@ -114,46 +78,6 @@ fn split_by_grid(src: f32, dst: f32, grid: f32) -> Vec<(f32, f32)> {
mod test {
use crate::gameplay::*;
#[test]
fn test_get_overflow() {
assert_eq!(get_overflow(5.0, -6.0, 3.0), 2.0);
assert_eq!(get_overflow(5.0, 6.0, 3.0), 0.0);
assert_eq!(get_overflow(5.0, -6.0, -3.0), 0.0);
assert_eq!(get_overflow(5.0, 6.0, -3.0), -2.0);
}
#[test]
fn test_find_grid_bound() {
// проверка с положительными значениями old и new
assert!(find_grid_bound(1.0, 4.0, 5.0).is_nan());
assert!(find_grid_bound(4.0, 1.0, 5.0).is_nan());
assert_eq!(find_grid_bound(4.0, 6.0, 5.0), 5.0);
assert_eq!(find_grid_bound(6.0, 4.0, 5.0), 5.0);
assert!(find_grid_bound(1.0, 11.0, 5.0).is_nan());
assert!(find_grid_bound(11.0, 1.0, 5.0).is_nan());
// проверка с отрицательными значениями old и new
assert!(find_grid_bound(-1.0, -4.0, 5.0).is_nan());
assert!(find_grid_bound(-4.0, -1.0, 5.0).is_nan());
assert_eq!(find_grid_bound(-4.0, -6.0, 5.0), -5.0);
assert_eq!(find_grid_bound(-6.0, -4.0, 5.0), -5.0);
assert!(find_grid_bound(-1.0, -11.0, 5.0).is_nan());
assert!(find_grid_bound(-11.0, -1.0, 5.0).is_nan());
// проверка перехода через 0
assert_eq!(find_grid_bound(-1.0, 1.0, 5.0), 0.0);
assert_eq!(find_grid_bound(1.0, -1.0, 5.0), 0.0);
assert_eq!(find_grid_bound(-1.0, 1.0, 10.0), 0.0);
assert_eq!(find_grid_bound(1.0, -1.0, 10.0), 0.0);
assert!(find_grid_bound(-1.0, 10.0, 5.0).is_nan());
assert!(find_grid_bound(-10.0, 1.0, 5.0).is_nan());
// проверка при grid <= 0
assert!(find_grid_bound(1.0, 2.0, 0.0).is_nan());
assert!(find_grid_bound(1.0, 2.0, -0.0).is_nan());
assert!(find_grid_bound(1.0, 2.0, -0.1).is_nan());
}
#[test]
fn test_split_by_grid() {
// движение вправо
+1 -1
View File
@@ -42,4 +42,4 @@ mod gameplay;
mod startup;
pub use gameplay::{head_rotation, moving};
pub use startup::startup;
pub use startup::{setup_frame_rate, startup};
+2 -2
View File
@@ -1,5 +1,5 @@
use bevy::prelude::*;
use snake_game::{head_rotation, moving, startup};
use snake_game::{head_rotation, moving, setup_frame_rate, startup};
fn main() {
App::new()
@@ -18,7 +18,7 @@ fn main() {
)
.insert_resource(bevy::winit::WinitSettings::desktop_app())
.insert_resource(ClearColor(Color::srgb(0.3, 0.6, 0.8)))
.add_systems(Startup, startup)
.add_systems(Startup, (startup, setup_frame_rate))
.add_systems(Update, (head_rotation, moving))
.run();
}
+41 -10
View File
@@ -1,17 +1,29 @@
use std::time::Duration;
use bevy::{ecs::spawn, prelude::*, winit::WinitSettings};
use bevy::{prelude::*, winit::WinitSettings};
use crate::domain::{Direction, FRAMES_PER_SECOND, GRID_SIZE, Inert, SNAKE_VELOCITY, Velocity};
use crate::domain::Tail;
/// Инициализация игрового мира
pub fn startup(mut commands: Commands, mut winit: ResMut<WinitSettings>) {
use crate::domain::{HEAD_SIZE, Head};
/// Настройка частоты кадров
pub fn setup_frame_rate(mut winit: ResMut<WinitSettings>) {
use crate::domain::FRAMES_PER_SECOND;
winit.focused_mode =
bevy::winit::UpdateMode::reactive(Duration::from_secs_f32(1. / FRAMES_PER_SECOND as f32));
winit.unfocused_mode =
bevy::winit::UpdateMode::reactive(Duration::from_secs_f32(1. / FRAMES_PER_SECOND as f32));
}
/// Инициализация игрового мира
pub fn startup(mut commands: Commands) {
spawn_snake(&mut commands);
spawn_grid(&mut commands);
commands.spawn(Camera2d);
}
/// Создать голову змеи
fn spawn_snake(commands: &mut Commands) {
use crate::domain::{Direction, HEAD_SIZE, Head, Inert, SNAKE_VELOCITY, Velocity};
let head = commands
.spawn((
@@ -24,7 +36,7 @@ pub fn startup(mut commands: Commands, mut winit: ResMut<WinitSettings>) {
vec2(HEAD_SIZE as f32, HEAD_SIZE as f32),
),
Transform {
translation: vec3(0., 0., 0.),
translation: vec3(0.0, 0.0, 1.0),
..Default::default()
},
))
@@ -35,7 +47,7 @@ pub fn startup(mut commands: Commands, mut winit: ResMut<WinitSettings>) {
vec2(HEAD_SIZE as f32 * 0.3, HEAD_SIZE as f32 * 0.3),
),
Transform {
translation: vec3(HEAD_SIZE as f32 * -0.25, HEAD_SIZE as f32 * 0.25, 0.),
translation: vec3(HEAD_SIZE as f32 * -0.25, HEAD_SIZE as f32 * 0.25, 0.0),
..Default::default()
},
ChildOf(head),
@@ -46,12 +58,33 @@ pub fn startup(mut commands: Commands, mut winit: ResMut<WinitSettings>) {
vec2(HEAD_SIZE as f32 * 0.2, HEAD_SIZE as f32 * 0.2),
),
Transform {
translation: vec3(HEAD_SIZE as f32 * 0.25, HEAD_SIZE as f32 * 0.25, 0.),
translation: vec3(HEAD_SIZE as f32 * 0.25, HEAD_SIZE as f32 * 0.25, 0.0),
..Default::default()
},
ChildOf(head),
));
commands.spawn((
Tail(0),
Direction::default(),
Inert::default(),
Velocity(0.0),
Sprite::from_color(
Color::srgb(0.7, 0.7, 0.7),
vec2(HEAD_SIZE as f32 * 0.8, HEAD_SIZE as f32 * 0.8),
),
Transform {
translation: vec3(0.0, 0.0, 0.0),
..Default::default()
},
// ChildOf(head),
));
}
/// Создать координатную сетку
fn spawn_grid(commands: &mut Commands) {
use crate::domain::GRID_SIZE;
for x in -20..=20 {
commands.spawn((
Sprite::from_color(Color::srgb(1.0, 1.0, 0.5), vec2(1.0, 2000.0)),
@@ -70,6 +103,4 @@ pub fn startup(mut commands: Commands, mut winit: ResMut<WinitSettings>) {
},
));
}
commands.spawn(Camera2d);
}