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

This commit is contained in:
7 changed files with 151 additions and 31 deletions
+121
View File
@@ -0,0 +1,121 @@
//! An example that illustrates how Time is handled in ECS.
use bevy::{app::AppExit, prelude::*};
use std::{
io::{self, BufRead},
time::Duration,
};
fn banner() {
println!("This example is meant to intuitively demonstrate how Time works in Bevy.");
println!();
println!("Time will be printed in three different schedules in the app:");
println!("- PreUpdate: real time is printed");
println!("- FixedUpdate: fixed time step time is printed, may be run zero or multiple times");
println!("- Update: virtual game time is printed");
println!();
println!("Max delta time is set to 5 seconds. Fixed timestep is set to 1 second.");
println!();
}
fn help() {
println!("The app reads commands line-by-line from standard input.");
println!();
println!("Commands:");
println!(" empty line: Run app.update() once on the Bevy App");
println!(" q: Quit the app.");
println!(" f: Set speed to fast, 2x");
println!(" n: Set speed to normal, 1x");
println!(" s: Set speed to slow, 0.5x");
println!(" p: Pause");
println!(" u: Unpause");
}
fn runner(mut app: App) -> AppExit {
banner();
help();
let stdin = io::stdin();
for line in stdin.lock().lines() {
if let Err(err) = line {
println!("read err: {err:#}");
break;
}
match line.unwrap().as_str() {
"" => {
app.update();
}
"f" => {
println!("FAST: setting relative speed to 2x");
app.world_mut()
.resource_mut::<Time<Virtual>>()
.set_relative_speed(2.0);
}
"n" => {
println!("NORMAL: setting relative speed to 1x");
app.world_mut()
.resource_mut::<Time<Virtual>>()
.set_relative_speed(1.0);
}
"s" => {
println!("SLOW: setting relative speed to 0.5x");
app.world_mut()
.resource_mut::<Time<Virtual>>()
.set_relative_speed(0.5);
}
"p" => {
println!("PAUSE: pausing virtual clock");
app.world_mut().resource_mut::<Time<Virtual>>().pause();
}
"u" => {
println!("UNPAUSE: resuming virtual clock");
app.world_mut().resource_mut::<Time<Virtual>>().unpause();
}
"q" => {
println!("QUITTING!");
break;
}
_ => {
help();
}
}
}
AppExit::Success
}
fn print_real_time(time: Res<Time<Real>>) {
println!(
"PreUpdate: this is real time clock, delta is {:?} and elapsed is {:?}",
time.delta(),
time.elapsed()
);
}
fn print_fixed_time(time: Res<Time>) {
println!(
"FixedUpdate: this is generic time clock inside fixed, delta is {:?} and elapsed is {:?}",
time.delta(),
time.elapsed()
);
}
fn print_time(time: Res<Time>) {
println!(
"Update: this is generic time clock, delta is {:?} and elapsed is {:?}",
time.delta(),
time.elapsed()
);
}
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.insert_resource(Time::<Virtual>::from_max_delta(Duration::from_secs(5)))
.insert_resource(Time::<Fixed>::from_duration(Duration::from_secs(1)))
.add_systems(PreUpdate, print_real_time)
.add_systems(FixedUpdate, print_fixed_time)
.add_systems(Update, print_time)
.set_runner(runner)
.run();
}
+5 -5
View File
@@ -2,7 +2,6 @@ use std::collections::HashMap;
use bevy::prelude::*;
pub const FRAMES_PER_SECOND: u8 = 24;
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;
@@ -104,14 +103,15 @@ impl SnakePath {
)
}
pub fn push(&mut self, transform: &Transform, direction: Direction) {
pub fn push(&mut self, transform: &Transform, direction: Direction) -> (i16, i16, Direction) {
let key = SnakePath::to_key(transform);
self.0.insert(key, direction.clone());
(key.0, key.1, direction.clone())
}
pub fn pick(&self, transform: &Transform) -> Option<Direction> {
pub fn pick(&self, transform: &Transform) -> Option<(i16, i16, Direction)> {
let key = SnakePath::to_key(transform);
self.0.get(&key).cloned()
self.0.get(&key).cloned().map(|d| (key.0, key.1, d))
}
pub fn drop(&mut self, transform: &Transform) -> Option<(i16, i16, Direction)> {
@@ -132,7 +132,7 @@ mod test {
snake_path.push(&Transform::default(), Direction::default());
assert_eq!(snake_path.0.len(), 1);
assert!(snake_path.pick(&Transform::default()) == Some(Direction::default()));
assert!(snake_path.pick(&Transform::default()) == Some((0, 0, Direction::default())));
assert_eq!(snake_path.0.len(), 1);
assert!(snake_path.drop(&Transform::default()) == Some((0, 0, Direction::default())));
+12 -3
View File
@@ -32,9 +32,9 @@ pub fn head_rotation(
}
}
/// Системе движения для всех движущихся сущностей
/// Система движения для всех движущихся сущностей
pub fn moving(
time: Res<Time>,
time: Res<Time<Fixed>>,
query: Query<(&mut Transform, &mut Inert, &Direction, &Velocity, Entity)>,
mut commands: Commands,
) {
@@ -43,7 +43,7 @@ pub fn moving(
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(src, dst, GRID_SIZE as f32).into_iter();
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() {
@@ -57,3 +57,12 @@ pub fn moving(
}
}
}
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
}
+1 -1
View File
@@ -6,5 +6,5 @@ mod startup;
mod tools;
pub use gameplay::{head_rotation, moving};
pub use startup::{setup_frame_rate, startup};
pub use startup::startup;
pub use tools::define_log_layer;
+4 -4
View File
@@ -1,5 +1,5 @@
use bevy::prelude::*;
use snake_game::{head_rotation, moving, setup_frame_rate, startup};
use snake_game::{head_rotation, moving, startup};
fn main() {
App::new()
@@ -16,11 +16,11 @@ fn main() {
task_pool_options: TaskPoolOptions::with_num_threads(1),
}),
)
.insert_resource(bevy::winit::WinitSettings::desktop_app())
.insert_resource(ClearColor(Color::srgb(0.3, 0.6, 0.8)))
.add_systems(Startup, (startup, setup_frame_rate))
.add_systems(Startup, (startup,))
// .add_systems(PostStartup, snake_game::debug::print_all_entities)
.add_systems(Update, (head_rotation, moving))
.add_systems(Update, (head_rotation,))
.add_systems(FixedUpdate, (moving,))
// .add_systems(
// PostUpdate,
// snake_game::debug::print_all_entities_by_press_enter,
+5 -5
View File
@@ -9,13 +9,13 @@ pub fn tail_observer(
mut query: Query<(&mut Direction, &Transform)>,
snake_path: Res<SnakePath>,
) {
trace!("...changing direction: triggered");
if event.observer() == event.0 {
trace!("...changing direction: observer == event.0");
if let Ok((mut direction, transform)) = query.get_mut(event.0) {
trace!("...changing direction: query success");
if let Some(new_direction) = snake_path.pick(transform) {
trace!("change direction for {:?} to {:?}", event.0, new_direction);
if let Some((x, y, new_direction)) = snake_path.pick(transform) {
trace!(
"change direction for {:?} in ({:?}, {:?}) to {:?}",
event.0, x, y, new_direction
);
*direction = new_direction;
}
}
+3 -13
View File
@@ -1,23 +1,13 @@
use bevy::{prelude::*, winit::WinitSettings};
use std::time::Duration;
use bevy::prelude::*;
use crate::{
domain::{End, SnakePath, Tail},
observers::{cleanup_snake_path, schedule_set_velocity, tail_observer},
};
/// Настройка частоты кадров
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) {
pub fn startup(mut commands: Commands, mut timer: ResMut<Time<Fixed>>) {
timer.set_timestep_hz(32.0);
spawn_snake(&mut commands);
crate::debug::spawn_grid(&mut commands);
commands.spawn(Camera2d);