use bevy::prelude::*; use crate::{ domain::{End, SnakePath, Tail}, observers::{cleanup_snake_path, schedule_set_velocity, tail_observer}, }; /// Инициализация игрового мира pub fn startup(mut commands: Commands, mut timer: ResMut>) { timer.set_timestep_hz(32.0); spawn_snake(&mut commands); crate::debug::spawn_grid(&mut commands); commands.spawn(Camera2d); } /// Создать голову змеи fn spawn_snake(commands: &mut Commands) { use crate::domain::{Direction, HEAD_SIZE, Head, Inert, SNAKE_VELOCITY, Velocity}; commands.insert_resource(SnakePath::default()); commands.spawn(Observer::new(cleanup_snake_path)); /* commands.spawn(Observer::new(|e: On| { let entity = e.entity; let src = e.src_pos; let dst = e.dst_pos; trace!("...<{entity:?}> moving {src:>16} => {dst:>16}"); })); */ let head = commands .spawn(( Head, Direction::default(), Inert::default(), Velocity(SNAKE_VELOCITY as f32), Sprite::from_color(Color::srgb(1., 1., 1.), vec2(HEAD_SIZE as f32, HEAD_SIZE as f32)), Transform { translation: vec3(0.0, 0.0, 1.0), ..Default::default() }, )) .id(); commands.spawn(( Sprite::from_color(Color::srgb(1., 0., 0.), 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, 1.0), ..Default::default() }, ChildOf(head), )); commands.spawn(( Sprite::from_color(Color::srgb(0., 0., 1.), 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, 1.0), ..Default::default() }, ChildOf(head), )); let tail = commands .spawn(( Tail, End, 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() }, Observer::new(tail_observer), )) .id(); commands.entity(head).observe(schedule_set_velocity(tail)); }