use bevy::prelude::*; use crate::{ domain::{Direction, GRID_SIZE, GridBarier, Head, Inert, SnakePath, Velocity}, tools::split_by_grid, }; /// Система поворота головы змеи pub fn head_rotation( input: Res>, query: Single<(&mut Transform, &mut Direction), With>, mut snake_path: ResMut, ) { use core::f32::consts::PI; let (mut transform, mut direction) = query.into_inner(); let mut append_snake_path = |transform: &Transform, direction: &Direction| { snake_path.push(&transform, direction.clone()); trace!("append snake_path: {:?}", snake_path); }; if input.just_pressed(KeyCode::ArrowLeft) { transform.rotate_z(PI / 2.0); direction.rotate_left(); append_snake_path(&transform, &direction); } if input.just_pressed(KeyCode::ArrowRight) { transform.rotate_z(-PI / 2.0); direction.rotate_right(); append_snake_path(&transform, &direction); } } /// Система движения для всех движущихся сущностей pub fn moving( time: Res>, query: Query<(&mut Transform, &mut Inert, &Direction, &Velocity, Entity)>, mut commands: Commands, ) { for (mut transform, mut inert, direction, Velocity(velocity), entity) in query.into_iter() { let delta = velocity * time.delta_secs(); let src = inert.0.get_coord(&transform); let sign = inert.0.get_change_sign(); let dst = src + sign * delta; let mut splited = _split_by_grid_tracing(src, dst, GRID_SIZE as f32).into_iter(); let first = splited.next().unwrap_or((0.0, 0.0)); inert.0.set_coord(&mut transform, first.0); if let Some(second) = splited.next() { let delta = second.1.abs(); inert.0 = *direction; let src = inert.0.get_coord(&transform); let sign = inert.0.get_change_sign(); let dst = src + sign * delta; inert.0.set_coord(&mut transform, dst); commands.trigger(GridBarier(entity)); } } } fn _split_by_grid_tracing(src: f32, dst: f32, grid: f32) -> Vec<(f32, f32)> { let result = split_by_grid(src, dst, grid); trace!( "\tsplit_by_grid({:?}, {:?}, {:?}) -> {:?}", src, dst, grid, result ); result }