Проектная работа - WIP
This commit is contained in:
@@ -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();
|
||||
}
|
||||
@@ -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())));
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user