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

This commit is contained in:
11 changed files with 246 additions and 181 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ fn main() {
.set(bevy::log::LogPlugin { .set(bevy::log::LogPlugin {
level: Level::INFO, level: Level::INFO,
filter: "wgpu_hal=warn,bevy_learning=trace".to_string(), filter: "wgpu_hal=warn,bevy_learning=trace".to_string(),
fmt_layer: |_| snake_game::define_log_layer(), // fmt_layer: |_| snake_game::define_log_layer(),
..Default::default() ..Default::default()
}) })
.set(TaskPoolPlugin { .set(TaskPoolPlugin {
+87
View File
@@ -0,0 +1,87 @@
use bevy::{color::palettes::tailwind::*, prelude::*};
use crate::{
domain::{End, FIELD_SIZE, GRID_SIZE, Tail},
observers::schedule_set_velocity,
};
/// Создать границу игрового поля
pub fn spawn_bounds(commands: &mut Commands) {
commands.spawn((
Sprite::from_color(AMBER_500, vec2((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32, 5.0)), //
Transform {
translation: vec3(0.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32, 5.0)), //
Transform {
translation: vec3(0.0, -(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2(5.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32)), //
Transform {
translation: vec3((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2(5.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32)), //
Transform {
translation: vec3(-(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0, 0.0),
..Default::default()
},
));
}
/// Создать змейку
pub fn spawn_snake(commands: &mut Commands) {
use crate::domain::{Direction, HEAD_SIZE, Head, SNAKE_VELOCITY, Velocity};
let head = commands
.spawn((
Head(Direction::default()),
Direction::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(head),
End,
Direction::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()
},
))
.id();
commands.entity(head).observe(schedule_set_velocity(tail));
}
+1
View File
@@ -1,4 +1,5 @@
//! модуль с инструментами отладки //! модуль с инструментами отладки
#![allow(unused)]
use bevy::{color::palettes::tailwind::*, prelude::*}; use bevy::{color::palettes::tailwind::*, prelude::*};
-14
View File
@@ -1,7 +1,5 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::domain::Position;
/// Направление движения /// Направление движения
#[derive(Component, PartialEq, Clone, Copy, Debug)] #[derive(Component, PartialEq, Clone, Copy, Debug)]
pub enum Direction { pub enum Direction {
@@ -56,18 +54,6 @@ impl Direction {
} }
} }
/// Получить следующую позицию для текущего направления
pub fn dst_pos(&self, transform: &Transform) -> Position {
let mut pos = Position::from(transform);
match self {
Direction::Up => pos.y += 1,
Direction::Left => (),
Direction::Down => (),
Direction::Right => pos.x += 1,
};
pos
}
/// Получить ориентацию в пространстве /// Получить ориентацию в пространстве
pub fn orientation(&self) -> Quat { pub fn orientation(&self) -> Quat {
use std::f32::consts::PI; use std::f32::consts::PI;
+1 -10
View File
@@ -5,7 +5,7 @@ use bevy::{
transform::components::Transform, transform::components::Transform,
}; };
use crate::domain::{Direction, GRID_SIZE}; use crate::domain::GRID_SIZE;
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Position { pub struct Position {
@@ -18,15 +18,6 @@ impl Position {
Self { x, y } Self { x, y }
} }
pub fn shift(&mut self, direction: &Direction) {
match direction {
Direction::Up => self.y += 1,
Direction::Left => self.x -= 1,
Direction::Down => self.y -= 1,
Direction::Right => self.x += 1,
}
}
pub fn translation(&self) -> Vec2 { pub fn translation(&self) -> Vec2 {
vec2(self.x as f32 * GRID_SIZE as f32, self.y as f32 * GRID_SIZE as f32) vec2(self.x as f32 * GRID_SIZE as f32, self.y as f32 * GRID_SIZE as f32)
} }
+42
View File
@@ -0,0 +1,42 @@
use bevy::prelude::*;
pub struct SnakeGame;
impl Plugin for SnakeGame {
fn build(&self, app: &mut bevy::app::App) {
app.add_plugins(
DefaultPlugins
.build()
.set(bevy::log::LogPlugin {
level: tracing::Level::INFO,
filter: "wgpu_hal=warn,snake_game=trace".to_string(),
fmt_layer: |_| crate::tools::define_log_layer(),
..Default::default()
})
.set(TaskPoolPlugin {
task_pool_options: TaskPoolOptions::with_num_threads(1),
}),
);
app.add_systems(Startup, crate::startup::setup_window);
app.add_systems(Startup, crate::startup::setup_time);
app.add_systems(Startup, crate::startup::startup);
app.add_systems(Update, crate::gameplay::head_rotation);
app.add_systems(PostUpdate, crate::gameplay::check_bounds_colisions);
app.add_systems(PostUpdate, crate::gameplay::check_tail_colisions);
app.add_systems(PostUpdate, crate::gameplay::check_meal_collisions);
app.add_systems(FixedUpdate, crate::gameplay::head_moving);
app.add_systems(FixedUpdate, crate::gameplay::snake_moving);
// DEBUG:
// app.add_systems(PostStartup, crate::debug::print_all_entities);
app.add_systems(Startup, crate::debug::set_initial_time_speed_to_slow_and_pause);
app.add_systems(Update, crate::debug::grow_up_on_tab);
app.add_systems(Update, crate::debug::print_all_entities_by_press_enter);
app.add_systems(Update, crate::debug::time_speed);
}
}
+90
View File
@@ -0,0 +1,90 @@
use bevy::{color::palettes::tailwind::*, prelude::*};
use crate::{
domain::{End, FIELD_SIZE, GRID_SIZE, Tail},
observers::schedule_set_velocity,
};
/// Создать границу игрового поля
pub fn spawn_bounds(commands: &mut Commands) {
commands.spawn((
Sprite::from_color(AMBER_500, vec2((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32, 5.0)), //
Transform {
translation: vec3(0.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32, 5.0)), //
Transform {
translation: vec3(0.0, -(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2(5.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32)), //
Transform {
translation: vec3((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2(5.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32)), //
Transform {
translation: vec3(-(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0, 0.0),
..Default::default()
},
));
}
/// Создать змейку
pub fn spawn_snake(commands: &mut Commands) {
use crate::domain::{Direction, HEAD_SIZE, Head, SNAKE_VELOCITY, Velocity};
commands.spawn(Observer::new(crate::debug::trace_snake_moving));
commands.spawn(Observer::new(crate::observers::handle_collisions));
let head = commands
.spawn((
Head(Direction::default()),
Direction::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(head),
End,
Direction::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()
},
))
.id();
commands.entity(head).observe(schedule_set_velocity(tail));
}
+1 -1
View File
@@ -102,7 +102,7 @@ pub fn snake_moving(
snake_path: Res<SnakePath>, snake_path: Res<SnakePath>,
mut commands: Commands, mut commands: Commands,
) { ) {
let _span = trace_span!("off_head_snake_moving").entered(); let _span = trace_span!("snake_moving").entered();
for (mut transform, mut direction, Velocity(velocity), entity) in query.into_iter() { for (mut transform, mut direction, Velocity(velocity), entity) in query.into_iter() {
let snake_path = &snake_path; let snake_path = &snake_path;
let switch_direction = move |pos: Position| snake_path.get(&pos).cloned(); let switch_direction = move |pos: Position| snake_path.get(&pos).cloned();
+4 -4
View File
@@ -1,10 +1,10 @@
pub mod debug; mod core;
mod debug;
mod domain; mod domain;
mod game;
mod gameplay; mod gameplay;
mod observers; mod observers;
mod startup; mod startup;
mod tools; mod tools;
pub use gameplay::{check_bounds_colisions, check_meal_collisions, check_tail_colisions, head_moving, head_rotation, snake_moving}; pub use game::SnakeGame;
pub use startup::{setup_window, startup};
pub use tools::define_log_layer;
+1 -55
View File
@@ -1,57 +1,3 @@
use bevy::prelude::*;
use snake_game::{check_bounds_colisions, check_meal_collisions, check_tail_colisions, head_moving, head_rotation, setup_window, snake_moving, startup};
fn main() { fn main() {
App::new() bevy::app::App::new().add_plugins(snake_game::SnakeGame).run();
.add_plugins(
DefaultPlugins
.build()
.set(bevy::log::LogPlugin {
level: tracing::Level::INFO,
filter: "wgpu_hal=warn,snake_game=trace".to_string(),
fmt_layer: |_| snake_game::define_log_layer(),
..Default::default()
})
.set(TaskPoolPlugin {
task_pool_options: TaskPoolOptions::with_num_threads(1),
}),
)
.insert_resource(ClearColor(Color::srgb(0.3, 0.6, 0.8)))
.add_systems(
Startup,
(
|| {}, //
setup_window,
startup,
snake_game::debug::set_initial_time_speed_to_slow_and_pause,
),
)
.add_systems(
PostStartup,
(
|| {},
// snake_game::debug::print_all_entities,
),
)
.add_systems(
Update,
(
|| {}, //
head_rotation,
snake_game::debug::grow_up_on_tab,
),
)
.add_systems(FixedUpdate, (head_moving, snake_moving))
.add_systems(
PostUpdate,
(
|| {}, //
check_bounds_colisions,
check_tail_colisions,
check_meal_collisions,
snake_game::debug::print_all_entities_by_press_enter,
snake_game::debug::time_speed,
),
)
.run();
} }
+18 -96
View File
@@ -1,10 +1,8 @@
use bevy::{color::palettes::tailwind::*, prelude::*}; use bevy::{color::palettes::tailwind::*, prelude::*};
use crate::{ use crate::domain::{FIELD_SIZE, GRID_SIZE, SnakePath};
domain::{End, FIELD_SIZE, GRID_SIZE, SnakePath, Tail},
observers::schedule_set_velocity,
};
/// Настройка игрового окна
pub fn setup_window(mut window: Single<&mut Window>) { pub fn setup_window(mut window: Single<&mut Window>) {
window.resolution.set( window.resolution.set(
(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 + 20.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 + 20.0,
@@ -12,106 +10,30 @@ pub fn setup_window(mut window: Single<&mut Window>) {
); );
} }
/// Инициализация игрового мира /// Настройка игрового времени
pub fn startup(mut commands: Commands, mut time: ResMut<Time<Fixed>>) { pub fn setup_time(mut time: ResMut<Time<Fixed>>) {
time.set_timestep_hz(32.0); time.set_timestep_hz(32.0);
}
/// Инициализация игрового мира
pub fn startup(mut commands: Commands) {
commands.insert_resource(ClearColor(SKY_600.into()));
commands.insert_resource(SnakePath::default()); commands.insert_resource(SnakePath::default());
commands.spawn(Observer::new(crate::observers::clean_snake_path)); commands.spawn(Observer::new(crate::observers::clean_snake_path));
commands.spawn(Observer::new(crate::observers::grow_up_snake)); commands.spawn(Observer::new(crate::observers::grow_up_snake));
commands.spawn(Observer::new(crate::observers::handle_collisions));
crate::core::spawn_bounds(&mut commands);
crate::core::spawn_snake(&mut commands);
commands.spawn(Camera2d);
// DEBUG:
commands.spawn(Observer::new(crate::debug::trace_collisions)); commands.spawn(Observer::new(crate::debug::trace_collisions));
commands.spawn(Observer::new(crate::debug::trace_snake_moving));
spawn_bounds(&mut commands);
spawn_snake(&mut commands);
crate::debug::spawn_grid(&mut commands); crate::debug::spawn_grid(&mut commands);
crate::debug::spawn_some_meal(&mut commands); crate::debug::spawn_some_meal(&mut commands);
commands.spawn(Camera2d);
}
/// Создать границу игрового поля
fn spawn_bounds(commands: &mut Commands) {
commands.spawn((
Sprite::from_color(AMBER_500, vec2((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32, 5.0)), //
Transform {
translation: vec3(0.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32, 5.0)), //
Transform {
translation: vec3(0.0, -(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2(5.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32)), //
Transform {
translation: vec3((FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0, 0.0),
..Default::default()
},
));
commands.spawn((
Sprite::from_color(AMBER_500, vec2(5.0, (FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32)), //
Transform {
translation: vec3(-(FIELD_SIZE as f32 + 1.0) * GRID_SIZE as f32 / 2.0, 0.0, 0.0),
..Default::default()
},
));
}
/// Создать голову змеи
fn spawn_snake(commands: &mut Commands) {
use crate::domain::{Direction, HEAD_SIZE, Head, SNAKE_VELOCITY, Velocity};
commands.spawn(Observer::new(crate::debug::trace_snake_moving));
commands.spawn(Observer::new(crate::observers::handle_collisions));
let head = commands
.spawn((
Head(Direction::default()),
Direction::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(head),
End,
Direction::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()
},
))
.id();
commands.entity(head).observe(schedule_set_velocity(tail));
} }