Проектная работа - WIP
This commit is contained in:
@@ -12,7 +12,7 @@ fn main() {
|
||||
.set(bevy::log::LogPlugin {
|
||||
level: Level::INFO,
|
||||
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()
|
||||
})
|
||||
.set(TaskPoolPlugin {
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
//! модуль с инструментами отладки
|
||||
#![allow(unused)]
|
||||
|
||||
use bevy::{color::palettes::tailwind::*, prelude::*};
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::domain::Position;
|
||||
|
||||
/// Направление движения
|
||||
#[derive(Component, PartialEq, Clone, Copy, Debug)]
|
||||
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 {
|
||||
use std::f32::consts::PI;
|
||||
|
||||
@@ -5,7 +5,7 @@ use bevy::{
|
||||
transform::components::Transform,
|
||||
};
|
||||
|
||||
use crate::domain::{Direction, GRID_SIZE};
|
||||
use crate::domain::GRID_SIZE;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Position {
|
||||
@@ -18,15 +18,6 @@ impl Position {
|
||||
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 {
|
||||
vec2(self.x as f32 * GRID_SIZE as f32, self.y as f32 * GRID_SIZE as f32)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -102,7 +102,7 @@ pub fn snake_moving(
|
||||
snake_path: Res<SnakePath>,
|
||||
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() {
|
||||
let snake_path = &snake_path;
|
||||
let switch_direction = move |pos: Position| snake_path.get(&pos).cloned();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
pub mod debug;
|
||||
mod core;
|
||||
mod debug;
|
||||
mod domain;
|
||||
mod game;
|
||||
mod gameplay;
|
||||
mod observers;
|
||||
mod startup;
|
||||
mod tools;
|
||||
|
||||
pub use gameplay::{check_bounds_colisions, check_meal_collisions, check_tail_colisions, head_moving, head_rotation, snake_moving};
|
||||
pub use startup::{setup_window, startup};
|
||||
pub use tools::define_log_layer;
|
||||
pub use game::SnakeGame;
|
||||
|
||||
+1
-55
@@ -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() {
|
||||
App::new()
|
||||
.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();
|
||||
bevy::app::App::new().add_plugins(snake_game::SnakeGame).run();
|
||||
}
|
||||
|
||||
+18
-96
@@ -1,10 +1,8 @@
|
||||
use bevy::{color::palettes::tailwind::*, prelude::*};
|
||||
|
||||
use crate::{
|
||||
domain::{End, FIELD_SIZE, GRID_SIZE, SnakePath, Tail},
|
||||
observers::schedule_set_velocity,
|
||||
};
|
||||
use crate::domain::{FIELD_SIZE, GRID_SIZE, SnakePath};
|
||||
|
||||
/// Настройка игрового окна
|
||||
pub fn setup_window(mut window: Single<&mut Window>) {
|
||||
window.resolution.set(
|
||||
(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);
|
||||
}
|
||||
|
||||
/// Инициализация игрового мира
|
||||
pub fn startup(mut commands: Commands) {
|
||||
commands.insert_resource(ClearColor(SKY_600.into()));
|
||||
commands.insert_resource(SnakePath::default());
|
||||
|
||||
commands.spawn(Observer::new(crate::observers::clean_snake_path));
|
||||
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));
|
||||
|
||||
spawn_bounds(&mut commands);
|
||||
|
||||
spawn_snake(&mut commands);
|
||||
commands.spawn(Observer::new(crate::debug::trace_snake_moving));
|
||||
|
||||
crate::debug::spawn_grid(&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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user