Update Bevy to 0.10
This commit is contained in:
1521
Cargo.lock
generated
1521
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
18
Cargo.toml
18
Cargo.toml
@@ -3,20 +3,16 @@ name = "bevy-snake"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
iyes_loopless = "0.9.1"
|
||||
itertools = "0.10.5"
|
||||
rand = "0.8.5"
|
||||
bevy_editor_pls = "0.2.0"
|
||||
bevy_tweening = "0.6.0"
|
||||
leafwing-input-manager = "0.8.0"
|
||||
bevy_editor_pls = "0.3.0"
|
||||
bevy_tweening = "0.7.0"
|
||||
leafwing-input-manager = "0.9.0"
|
||||
|
||||
[dependencies.bevy]
|
||||
version = "0.9.1"
|
||||
features = ["dynamic", "wayland"]
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
version = "0.10"
|
||||
features = ["wayland"]
|
||||
|
||||
# [profile.dev.package."*"]
|
||||
# opt-level = 3
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
||||
# [toolchain]
|
||||
# channel = "nightly"
|
||||
|
||||
@@ -7,7 +7,7 @@ use bevy::{
|
||||
render::{
|
||||
render_resource::{encase, AsBindGroup, OwnedBindingResource, ShaderRef, ShaderType},
|
||||
renderer::RenderQueue,
|
||||
RenderApp, RenderStage,
|
||||
RenderApp, RenderSet,
|
||||
},
|
||||
sprite::{Material2d, Material2dPlugin, MaterialMesh2dBundle, RenderMaterials2d},
|
||||
};
|
||||
@@ -23,8 +23,8 @@ impl Plugin for CanvasPlugin {
|
||||
.add_startup_system(spawn_canvas);
|
||||
|
||||
app.sub_app_mut(RenderApp)
|
||||
.add_system_to_stage(RenderStage::Extract, extract_tile_lights)
|
||||
.add_system_to_stage(RenderStage::Prepare, prepare_canvas_material);
|
||||
.add_system(extract_tile_lights.in_schedule(ExtractSchedule))
|
||||
.add_system(prepare_canvas_material.in_set(RenderSet::Prepare));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
grid,
|
||||
snake::{self, SnakeHead},
|
||||
tick,
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
use iyes_loopless::prelude::*;
|
||||
use rand::prelude::*;
|
||||
|
||||
const Z_HEIGHT: f32 = snake::Z_HEIGHT / 2.;
|
||||
@@ -15,7 +13,7 @@ impl Plugin for FruitPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_event::<EatenEvent>()
|
||||
.add_startup_system(spawn_fruit_system)
|
||||
.add_fixed_timestep_system(tick::TICK_TIME_STEP_NAME, 0, eat_fruit_system)
|
||||
.add_system(eat_fruit_system.in_schedule(CoreSchedule::FixedUpdate))
|
||||
.add_system(despawn_fruit_system)
|
||||
.add_system(spawn_fruit_system.run_if(eaten_event_sent));
|
||||
}
|
||||
|
||||
59
src/main.rs
59
src/main.rs
@@ -1,8 +1,12 @@
|
||||
use crate::{canvas::CanvasPlugin, fruit::FruitPlugin, snake::SnakePlugin, tick::TickPlugin};
|
||||
use bevy::{prelude::*, render::camera::ScalingMode};
|
||||
use crate::{
|
||||
canvas::CanvasPlugin,
|
||||
fruit::FruitPlugin,
|
||||
grid::{SEGMENT_SIZE, SIZE},
|
||||
snake::SnakePlugin,
|
||||
};
|
||||
use bevy::{prelude::*, render::camera::ScalingMode, window::WindowResolution};
|
||||
use bevy_tweening::TweeningPlugin;
|
||||
use grid::{SEGMENT_SIZE, SIZE};
|
||||
use iyes_loopless::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
use bevy_editor_pls::prelude::*;
|
||||
@@ -11,14 +15,16 @@ mod canvas;
|
||||
mod fruit;
|
||||
mod grid;
|
||||
mod snake;
|
||||
mod tick;
|
||||
|
||||
const ASPECT_RATIO: f32 = 16. / 9.;
|
||||
const WINDOW_WIDTH: f32 = 720. * ASPECT_RATIO;
|
||||
const WINDOW_WIDTH: f32 = WINDOW_HEIGHT * ASPECT_RATIO;
|
||||
const WINDOW_HEIGHT: f32 = 720.;
|
||||
const TICK_PERIOD: Duration = Duration::from_millis(125);
|
||||
const CLEAR_COLOR: Color = Color::rgba(0.15, 0.15, 0.15, 1.0);
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
enum AppState {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
|
||||
enum GameState {
|
||||
#[default]
|
||||
Begin,
|
||||
InGame,
|
||||
Paused,
|
||||
@@ -28,30 +34,31 @@ enum AppState {
|
||||
fn main() {
|
||||
let mut app = App::new();
|
||||
|
||||
app.insert_resource(ClearColor(Color::rgb_u8(12, 12, 12)))
|
||||
.add_loopless_state(AppState::Begin)
|
||||
app.insert_resource(ClearColor(CLEAR_COLOR))
|
||||
.insert_resource(FixedTime::new(TICK_PERIOD))
|
||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
window: WindowDescriptor {
|
||||
primary_window: Some(Window {
|
||||
title: "Bevy-Snake".into(),
|
||||
resizable: true,
|
||||
width: WINDOW_WIDTH,
|
||||
height: WINDOW_HEIGHT,
|
||||
resolution: WindowResolution::new(WINDOW_WIDTH, WINDOW_HEIGHT),
|
||||
..Default::default()
|
||||
},
|
||||
}),
|
||||
..Default::default()
|
||||
}))
|
||||
.add_state::<GameState>()
|
||||
.add_plugin(TweeningPlugin)
|
||||
.add_plugin(TickPlugin)
|
||||
.add_plugin(SnakePlugin)
|
||||
.add_plugin(FruitPlugin)
|
||||
.add_plugin(CanvasPlugin)
|
||||
.add_startup_system(setup_system)
|
||||
.add_system(camera_move_system)
|
||||
.add_system(bevy::window::close_on_esc)
|
||||
.add_system(pause_system);
|
||||
.add_system(camera_move_system);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
app.add_plugin(EditorPlugin);
|
||||
{
|
||||
app.add_plugin(EditorPlugin)
|
||||
.add_system(bevy::window::close_on_esc)
|
||||
.add_system(pause_system);
|
||||
}
|
||||
|
||||
app.run();
|
||||
}
|
||||
@@ -62,7 +69,7 @@ fn setup_system(mut commands: Commands) {
|
||||
commands
|
||||
.spawn(Camera2dBundle {
|
||||
projection: OrthographicProjection {
|
||||
scaling_mode: ScalingMode::Auto {
|
||||
scaling_mode: ScalingMode::AutoMin {
|
||||
min_width: grid_dimensions,
|
||||
min_height: grid_dimensions,
|
||||
},
|
||||
@@ -110,17 +117,17 @@ fn camera_move_system(
|
||||
}
|
||||
|
||||
fn pause_system(
|
||||
mut commands: Commands,
|
||||
keypress: Res<Input<KeyCode>>,
|
||||
state: Res<CurrentState<AppState>>,
|
||||
current_state: Res<State<GameState>>,
|
||||
mut next_state: ResMut<NextState<GameState>>,
|
||||
) {
|
||||
if keypress.just_pressed(KeyCode::P) {
|
||||
let next_state = match state.0 {
|
||||
AppState::InGame => AppState::Paused,
|
||||
AppState::Paused => AppState::InGame,
|
||||
let state = match current_state.0 {
|
||||
GameState::InGame => GameState::Paused,
|
||||
GameState::Paused => GameState::InGame,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
commands.insert_resource(NextState(next_state));
|
||||
next_state.set(state);
|
||||
}
|
||||
}
|
||||
|
||||
79
src/snake.rs
79
src/snake.rs
@@ -3,53 +3,65 @@ mod bulge;
|
||||
mod direction;
|
||||
mod movement;
|
||||
|
||||
use crate::{fruit, grid, tick, AppState};
|
||||
use crate::{fruit, grid, GameState};
|
||||
use bevy::prelude::*;
|
||||
use direction::Direction;
|
||||
use itertools::Itertools;
|
||||
use iyes_loopless::prelude::*;
|
||||
use leafwing_input_manager::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, SystemLabel)]
|
||||
enum SystemLabel {
|
||||
Collision,
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
enum SystemSet {
|
||||
Movement,
|
||||
DirectionFlush,
|
||||
CollisionDetection,
|
||||
}
|
||||
|
||||
pub struct SnakePlugin;
|
||||
|
||||
impl Plugin for SnakePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
let movement_system_set =
|
||||
SystemSet::new().with_system(segments_movement_system.run_in_state(AppState::InGame));
|
||||
|
||||
let ticked_system_set = SystemSet::new()
|
||||
.with_system(direction::apply_direction_system.run_in_state(AppState::InGame));
|
||||
|
||||
let collision_system_set = SystemSet::new()
|
||||
.with_system(
|
||||
game_over_system
|
||||
.run_in_state(AppState::InGame)
|
||||
.after(SystemLabel::Collision),
|
||||
)
|
||||
.with_system(
|
||||
collision_system
|
||||
.run_in_state(AppState::InGame)
|
||||
.label(SystemLabel::Collision),
|
||||
);
|
||||
|
||||
app.add_fixed_timestep_system_set(tick::TICK_TIME_STEP_NAME, 0, ticked_system_set)
|
||||
.add_fixed_timestep_child_stage(tick::TICK_TIME_STEP_NAME)
|
||||
.add_fixed_timestep_system_set(tick::TICK_TIME_STEP_NAME, 1, collision_system_set)
|
||||
.add_fixed_timestep_child_stage(tick::TICK_TIME_STEP_NAME)
|
||||
.add_fixed_timestep_system_set(tick::TICK_TIME_STEP_NAME, 2, movement_system_set);
|
||||
app.configure_set(SystemSet::Movement.after(SystemSet::CollisionDetection));
|
||||
|
||||
app.add_plugin(InputManagerPlugin::<direction::Direction>::default())
|
||||
.add_event::<AddTailEvent>()
|
||||
.insert_resource(bulge::PropagationTimer::default())
|
||||
.add_startup_system(setup_snake_system)
|
||||
.add_system(direction::start_game_system.run_in_state(AppState::Begin))
|
||||
.add_system(
|
||||
segments_movement_system
|
||||
.in_schedule(CoreSchedule::FixedUpdate)
|
||||
.in_set(SystemSet::Movement)
|
||||
.run_if(in_state(GameState::InGame))
|
||||
.after(SystemSet::DirectionFlush),
|
||||
)
|
||||
.add_system(
|
||||
direction::apply_direction_system
|
||||
.in_schedule(CoreSchedule::FixedUpdate)
|
||||
.run_if(in_state(GameState::InGame))
|
||||
.before(SystemSet::DirectionFlush),
|
||||
)
|
||||
.add_system(
|
||||
apply_system_buffers
|
||||
.in_schedule(CoreSchedule::FixedUpdate)
|
||||
.in_set(SystemSet::DirectionFlush)
|
||||
.run_if(in_state(GameState::InGame)),
|
||||
)
|
||||
.add_system(
|
||||
collision_system
|
||||
.in_schedule(CoreSchedule::FixedUpdate)
|
||||
.in_set(SystemSet::CollisionDetection)
|
||||
.run_if(in_state(GameState::InGame))
|
||||
.after(SystemSet::DirectionFlush),
|
||||
)
|
||||
.add_system(
|
||||
game_over_system
|
||||
.in_schedule(CoreSchedule::FixedUpdate)
|
||||
.in_set(SystemSet::CollisionDetection)
|
||||
.in_set(OnUpdate(GameState::InGame))
|
||||
.after(collision_system),
|
||||
)
|
||||
.add_system(direction::start_game_system.in_set(OnUpdate(GameState::Begin)))
|
||||
.add_system(direction::change_direction_system)
|
||||
.add_system(grid_transform_system.run_in_state(AppState::InGame))
|
||||
.add_system(grid_transform_system.in_set(OnUpdate(GameState::InGame)))
|
||||
.add_system(add_tail_system)
|
||||
.add_system(bulge::add_bulge_system)
|
||||
.add_system(bulge::propagate_bulge_system)
|
||||
@@ -220,9 +232,12 @@ fn collision_system(
|
||||
}
|
||||
}
|
||||
|
||||
fn game_over_system(query: Query<&Collision, With<Snake>>, mut commands: Commands) {
|
||||
fn game_over_system(
|
||||
query: Query<&Collision, With<Snake>>,
|
||||
mut next_state: ResMut<NextState<GameState>>,
|
||||
) {
|
||||
if query.get_single().unwrap().about_to_collide {
|
||||
commands.insert_resource(NextState(AppState::End));
|
||||
next_state.set(GameState::End);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::{AddTailEvent, Segments, Snake, SnakeHead, SnakeSegment};
|
||||
use crate::tick::TICK_PERIOD;
|
||||
use crate::TICK_PERIOD;
|
||||
use bevy::prelude::*;
|
||||
use bevy_tweening::{lens::TransformScaleLens, *};
|
||||
use std::time::Duration;
|
||||
@@ -13,10 +13,7 @@ pub(super) struct PropagationTimer(Timer);
|
||||
|
||||
impl Default for PropagationTimer {
|
||||
fn default() -> Self {
|
||||
Self(Timer::new(
|
||||
Duration::from_millis(TICK_PERIOD / 4),
|
||||
TimerMode::Repeating,
|
||||
))
|
||||
Self(Timer::new(TICK_PERIOD / 4, TimerMode::Repeating))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
61
src/snake/direction.rs
Normal file
61
src/snake/direction.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use super::Snake;
|
||||
use crate::GameState;
|
||||
use bevy::prelude::*;
|
||||
use leafwing_input_manager::prelude::*;
|
||||
|
||||
#[derive(Actionlike, Component, Copy, Clone, Debug)]
|
||||
pub(super) enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Component, Copy, Clone, Debug)]
|
||||
#[component(storage = "SparseSet")]
|
||||
pub(super) struct NewDirection(Direction);
|
||||
|
||||
pub(super) fn start_game_system(
|
||||
query: Query<&ActionState<Direction>>,
|
||||
mut next_state: ResMut<NextState<GameState>>,
|
||||
) {
|
||||
let action_state = query.single();
|
||||
|
||||
if !action_state.get_just_pressed().is_empty() {
|
||||
next_state.set(GameState::InGame);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn apply_direction_system(
|
||||
mut commands: Commands,
|
||||
mut query: Query<(Entity, &NewDirection), With<Snake>>,
|
||||
) {
|
||||
for (snake, new_direction) in query.iter_mut() {
|
||||
commands
|
||||
.entity(snake)
|
||||
.insert(new_direction.0)
|
||||
.remove::<NewDirection>();
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn change_direction_system(
|
||||
mut commands: Commands,
|
||||
mut query: Query<(Entity, &ActionState<Direction>, Option<&Direction>), With<Snake>>,
|
||||
) {
|
||||
let (snake, action_state, direction) = query.single_mut();
|
||||
let new_direction = action_state.get_pressed().iter().cloned().last();
|
||||
|
||||
if let Some(new_direction) = new_direction {
|
||||
if let Some(current_direction) = direction {
|
||||
if let (Direction::Up, Direction::Down)
|
||||
| (Direction::Down, Direction::Up)
|
||||
| (Direction::Left, Direction::Right)
|
||||
| (Direction::Right, Direction::Left) = (current_direction, new_direction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
commands.entity(snake).insert(NewDirection(new_direction));
|
||||
}
|
||||
}
|
||||
14
src/tick.rs
14
src/tick.rs
@@ -1,14 +0,0 @@
|
||||
use bevy::prelude::*;
|
||||
use iyes_loopless::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
pub const TICK_PERIOD: u64 = 125;
|
||||
pub const TICK_TIME_STEP_NAME: &str = "tick_time_step";
|
||||
|
||||
pub struct TickPlugin;
|
||||
|
||||
impl Plugin for TickPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_fixed_timestep(Duration::from_millis(TICK_PERIOD), TICK_TIME_STEP_NAME);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user