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

This commit is contained in:
7 changed files with 85 additions and 113 deletions
+69 -60
View File
@@ -1,92 +1,101 @@
use bevy::prelude::*;
use crate::{
domain::{Direction, End, GRID_SIZE, GridBarier, Head, Position, SnakePath, Tail, Velocity},
domain::{Direction, GRID_SIZE, GridBarier, Head, Position, SnakePath, Tail, Velocity},
tools::split_by_grid,
};
/// Система поворота головы змеи
pub fn head_rotation(
input: Res<ButtonInput<KeyCode>>, //
query: Single<(&mut Transform, &Direction), With<Head>>,
mut snake_path: ResMut<SnakePath>,
query: Single<(&mut Transform, &mut Head, &Direction)>,
) {
let _span = trace_span!("head_rotation").entered();
if input.just_pressed(KeyCode::ArrowLeft) {
let (mut transform, direction) = query.into_inner();
let (mut transform, mut head, direction) = query.into_inner();
let translation = transform.translation.clone();
let cur_pos = Position::from(&*transform);
let mut dst_pos = direction.dst_pos(&*transform);
let mut new_direction = direction.clone();
new_direction.rotate_left();
if !snake_path.push(dst_pos, new_direction) {
trace!("try 1 failed: cannot push [{dst_pos} => {new_direction}] into SnakePath");
dst_pos.shift(&direction);
if !snake_path.push(dst_pos, new_direction) {
trace!("try 2 failed: cannot push [{dst_pos} => {new_direction}] into SnakePath");
return;
}
}
head.0 = new_direction;
transform.rotation = new_direction.orientation();
trace!("running {direction} at {cur_pos} {translation}: go {new_direction} on {dst_pos}");
trace!("running {direction} at {cur_pos} {translation}: go {new_direction}");
} else if input.just_pressed(KeyCode::ArrowRight) {
let (mut transform, direction) = query.into_inner();
let (mut transform, mut head, direction) = query.into_inner();
let translation = transform.translation.clone();
let cur_pos = Position::from(&*transform);
let mut dst_pos = direction.dst_pos(&*transform);
let mut new_direction = direction.clone();
new_direction.rotate_right();
if !snake_path.push(dst_pos, new_direction) {
trace!("try 1 failed: cannot push [{dst_pos} => {new_direction}] into SnakePath");
dst_pos.shift(&direction);
if !snake_path.push(dst_pos, new_direction) {
trace!("try 2 failed: cannot push [{dst_pos} => {new_direction}] into SnakePath");
return;
}
}
head.0 = new_direction;
transform.rotation = new_direction.orientation();
trace!("running {direction} at {cur_pos} {translation}: go {new_direction} on {dst_pos}");
trace!("running {direction} at {cur_pos} {translation}: go {new_direction}");
}
}
/// Система движения змеи
pub fn snake_moving(
time: Res<Time<Fixed>>,
mut snake_path: ResMut<SnakePath>,
query: Query<(&mut Transform, &mut Direction, &Velocity, Entity, Has<End>), Or<(With<Head>, With<Tail>, With<End>)>>,
mut commands: Commands,
fn moving(
velocity: &f32,
time: &Time<Fixed>,
direction: &mut Direction,
mut transform: &mut Transform,
entity: Entity,
commands: &mut Commands,
switch_direction: impl FnOnce(Position) -> Option<Direction>,
) {
let _span = trace_span!("snake_moving").entered();
for (mut transform, mut direction, Velocity(velocity), entity, has_end) in query.into_iter() {
// первая часть движения - до границы сетки
let delta = velocity * time.delta_secs();
let src = direction.get_coord(&transform);
// первая часть движения - до границы сетки
let delta = velocity * time.delta_secs();
let src = direction.get_coord(&transform);
let sign = direction.get_change_sign();
let dst = src + sign * delta;
let mut splited = split_by_grid(src, dst, GRID_SIZE as f32).into_iter();
let first = splited.next().unwrap_or((0.0, 0.0));
direction.set_coord(&mut transform, first.0);
// вторая часть движения - после границы сетки
if let Some(second) = splited.next() {
let delta = second.1.abs();
let pos = Position::from(&*transform);
if let Some(dir) = switch_direction(pos) {
trace!("set new direction for {entity} in {pos} --> {dir}");
*direction = dir;
}
let src = direction.get_coord(&*transform);
let sign = direction.get_change_sign();
let dst = src + sign * delta;
let mut splited = split_by_grid(src, dst, GRID_SIZE as f32).into_iter();
let first = splited.next().unwrap_or((0.0, 0.0));
direction.set_coord(&mut transform, first.0);
direction.set_coord(&mut transform, dst);
// вторая часть движения - после границы сетки
if let Some(second) = splited.next() {
let delta = second.1.abs();
let pos = Position::from(&*transform);
if let Some(dir) = snake_path.peek(&pos) {
trace!("set new direction for {entity} in {pos} --> {dir}");
*direction = dir.clone();
}
let src = direction.get_coord(&*transform);
let sign = direction.get_change_sign();
let dst = src + sign * delta;
direction.set_coord(&mut transform, dst);
// создать событие прохождения границы сетки
commands.entity(entity).trigger(|e| GridBarier::new(e, pos, (&*direction).clone()));
// если это кончик хвоста, то нужно очистить [SnakePath] за собой
if has_end {
snake_path.drop(&pos);
}
}
// создать событие прохождения границы сетки
commands.entity(entity).trigger(|e| GridBarier::new(e, pos, (&*direction).clone()));
}
}
pub fn head_moving(
query: Query<(&mut Transform, &mut Direction, &Velocity, &Head, Entity)>,
time: Res<Time<Fixed>>,
mut snake_path: ResMut<SnakePath>,
mut commands: Commands,
) {
let _span = trace_span!("head_moving").entered();
for (mut transform, mut direction, Velocity(velocity), head, entity) in query.into_iter() {
let next_dir = head.0.clone();
let snake_path = &mut snake_path;
let switch_direction = move |pos: Position| {
snake_path.insert(pos.clone(), next_dir.clone());
Some(next_dir)
};
moving(velocity, &time, &mut direction, &mut transform, entity, &mut commands, switch_direction);
}
}
pub fn snake_moving(
query: Query<(&mut Transform, &mut Direction, &Velocity, Entity), (With<Tail>, Without<Head>)>,
time: Res<Time<Fixed>>,
snake_path: Res<SnakePath>,
mut commands: Commands,
) {
let _span = trace_span!("off_head_snake_moving").entered();
for (mut transform, mut direction, Velocity(velocity), entity) in query.into_iter() {
let snake_path = &snake_path;
let switch_direction = move |pos: Position| snake_path.get(&pos).cloned();
moving(velocity, &time, &mut direction, &mut transform, entity, &mut commands, switch_direction);
}
}