Game over system fix

This commit is contained in:
2022-08-10 22:38:23 +02:00
parent fe5f91966f
commit 10daae1cf6
4 changed files with 86 additions and 75 deletions

21
src/canvas.rs Normal file
View File

@@ -0,0 +1,21 @@
use crate::grid;
use bevy::prelude::*;
pub struct ModPlugin;
impl Plugin for ModPlugin {
fn build(&self, app: &mut App) {
app.add_startup_system(spawn_background);
}
}
fn spawn_background(mut commands: Commands) {
commands.spawn_bundle(SpriteBundle {
sprite: Sprite {
color: Color::DARK_GRAY,
custom_size: Some(Vec2::splat(grid::SEGMENT_SIZE * grid::SIZE as f32)),
..Default::default()
},
..Default::default()
});
}

View File

@@ -1,65 +1,46 @@
use bevy::prelude::*; use bevy::prelude::*;
use std::ops::{Add, AddAssign}; use std::ops::{Add, AddAssign};
pub type GridType = i16; pub type Index = i16;
pub const GRID_SIZE: GridType = 21; pub const SIZE: Index = 17;
pub const GRID_SEGMENT_SIZE: f32 = 20.; pub const SEGMENT_SIZE: f32 = 20.;
#[derive(Component, Clone, Copy, Default, Debug)] #[derive(Component, Clone, Copy, Default, Debug)]
pub struct GridCoordinate(pub GridType, pub GridType); pub struct Coordinate(pub Index, pub Index);
impl GridCoordinate { impl Coordinate {
pub fn splat(v: GridType) -> Self { pub fn splat(v: Index) -> Self {
Self(v, v) Self(v, v)
} }
} }
impl Add for GridCoordinate { impl Add for Coordinate {
type Output = Self; type Output = Self;
fn add(self, rhs: GridCoordinate) -> Self::Output { fn add(self, rhs: Coordinate) -> Self::Output {
GridCoordinate(self.0 + rhs.0, self.1 + rhs.1) Coordinate(self.0 + rhs.0, self.1 + rhs.1)
} }
} }
impl AddAssign for GridCoordinate { impl AddAssign for Coordinate {
fn add_assign(&mut self, rhs: Self) { fn add_assign(&mut self, rhs: Self) {
*self = Self(self.0 + rhs.0, self.1 + rhs.1) *self = Self(self.0 + rhs.0, self.1 + rhs.1)
} }
} }
impl From<GridCoordinate> for Transform { impl From<Coordinate> for Transform {
fn from(grid_coordinate: GridCoordinate) -> Self { fn from(grid_coordinate: Coordinate) -> Self {
(&grid_coordinate).into() (&grid_coordinate).into()
} }
} }
impl From<&GridCoordinate> for Transform { impl From<&Coordinate> for Transform {
fn from(grid_coordinate: &GridCoordinate) -> Self { fn from(grid_coordinate: &Coordinate) -> Self {
Transform::from_xyz( Transform::from_xyz(
(grid_coordinate.0 - GRID_SIZE / 2) as f32 * GRID_SEGMENT_SIZE, (grid_coordinate.0 - SIZE / 2) as f32 * SEGMENT_SIZE,
(grid_coordinate.1 - GRID_SIZE / 2) as f32 * GRID_SEGMENT_SIZE, (grid_coordinate.1 - SIZE / 2) as f32 * SEGMENT_SIZE,
0., 0.,
) )
} }
} }
pub struct GridPlugin;
impl Plugin for GridPlugin {
fn build(&self, app: &mut App) {
app.add_startup_system(spawn_background);
}
}
fn spawn_background(mut commands: Commands) {
commands.spawn_bundle(SpriteBundle {
sprite: Sprite {
color: Color::DARK_GRAY,
custom_size: Some(Vec2::splat(GRID_SEGMENT_SIZE * GRID_SIZE as f32)),
..Default::default()
},
..Default::default()
});
}

View File

@@ -1,8 +1,9 @@
use bevy::{prelude::*, render::camera::ScalingMode}; use bevy::{prelude::*, render::camera::ScalingMode};
// use bevy_editor_pls::prelude::*; // use bevy_editor_pls::prelude::*;
use grid::{GRID_SEGMENT_SIZE, GRID_SIZE}; use grid::{SEGMENT_SIZE, SIZE};
use iyes_loopless::prelude::*; use iyes_loopless::prelude::*;
mod canvas;
mod grid; mod grid;
mod snake; mod snake;
@@ -31,8 +32,8 @@ fn main() {
.add_loopless_state(AppState::Begin) .add_loopless_state(AppState::Begin)
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
// .add_plugin(EditorPlugin) // .add_plugin(EditorPlugin)
.add_plugin(snake::SnakePlugin) .add_plugin(snake::ModPlugin)
.add_plugin(grid::GridPlugin) .add_plugin(canvas::ModPlugin)
.add_startup_system(setup_system) .add_startup_system(setup_system)
.add_system(camera_move_system) .add_system(camera_move_system)
.add_system(bevy::window::close_on_esc) .add_system(bevy::window::close_on_esc)
@@ -41,7 +42,7 @@ fn main() {
} }
fn setup_system(mut commands: Commands) { fn setup_system(mut commands: Commands) {
let grid_dimensions = GRID_SIZE as f32 * GRID_SEGMENT_SIZE * 1.2; let grid_dimensions = SIZE as f32 * SEGMENT_SIZE * 1.2;
commands commands
.spawn_bundle(Camera2dBundle { .spawn_bundle(Camera2dBundle {

View File

@@ -1,7 +1,4 @@
use crate::{ use crate::{grid, AppState};
grid::{GridCoordinate, GridType, GRID_SEGMENT_SIZE, GRID_SIZE},
AppState,
};
use bevy::prelude::*; use bevy::prelude::*;
use itertools::Itertools; use itertools::Itertools;
use iyes_loopless::prelude::*; use iyes_loopless::prelude::*;
@@ -10,27 +7,36 @@ use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Eq, Hash, StageLabel)] #[derive(Debug, Clone, PartialEq, Eq, Hash, StageLabel)]
struct FixedTimeStage; struct FixedTimeStage;
pub struct SnakePlugin; pub struct ModPlugin;
impl Plugin for SnakePlugin { impl Plugin for ModPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
let mut fixed_time_systems0 = SystemStage::parallel(); let mut fixed_time_systems0 = SystemStage::parallel();
fixed_time_systems0.add_system(segments_movement_system.run_in_state(AppState::InGame)); fixed_time_systems0.add_system(segments_movement_system.run_in_state(AppState::InGame));
let mut fixed_time_systems1 = SystemStage::parallel(); let mut fixed_time_systems1 = SystemStage::parallel();
fixed_time_systems1.add_system(head_movement_system.run_in_state(AppState::InGame)); fixed_time_systems1
.add_system(
head_movement_system
.run_in_state(AppState::InGame)
.run_if_not(about_to_lose),
)
.add_system(
game_over_system
.run_in_state(AppState::InGame)
.run_if(about_to_lose),
);
app.add_startup_system(setup_snake_system) app.add_startup_system(setup_snake_system)
.add_stage_before( .add_stage_before(
CoreStage::Update, CoreStage::Update,
FixedTimeStage, FixedTimeStage,
FixedTimestepStage::new(Duration::from_millis(100)) FixedTimestepStage::new(Duration::from_millis(125))
.with_stage(fixed_time_systems0) .with_stage(fixed_time_systems0)
.with_stage(fixed_time_systems1), .with_stage(fixed_time_systems1),
) )
.add_system(game_over_system.run_in_state(AppState::InGame))
.add_system(add_direction_system.run_in_state(AppState::Begin)) .add_system(add_direction_system.run_in_state(AppState::Begin))
.add_system(direction_system.run_in_state(AppState::InGame)) .add_system(change_direction_system.run_in_state(AppState::InGame))
.add_system(grid_transform_system.run_in_state(AppState::InGame)) .add_system(grid_transform_system.run_in_state(AppState::InGame))
.add_system(add_tail_system); .add_system(add_tail_system);
} }
@@ -78,12 +84,12 @@ impl Direction {
} }
} }
fn create_snake_segment(commands: &mut Commands, grid_position: GridCoordinate) -> Entity { fn create_snake_segment(commands: &mut Commands, grid_position: grid::Coordinate) -> Entity {
commands commands
.spawn_bundle(SpriteBundle { .spawn_bundle(SpriteBundle {
sprite: Sprite { sprite: Sprite {
color: Color::RED, color: Color::RED,
custom_size: Some(Vec2::splat(GRID_SEGMENT_SIZE) * 0.9), custom_size: Some(Vec2::splat(grid::SEGMENT_SIZE) * 0.9),
..Default::default() ..Default::default()
}, },
transform: grid_position.into(), transform: grid_position.into(),
@@ -95,7 +101,7 @@ fn create_snake_segment(commands: &mut Commands, grid_position: GridCoordinate)
} }
fn setup_snake_system(mut commands: Commands) { fn setup_snake_system(mut commands: Commands) {
let snake_head = create_snake_segment(&mut commands, GridCoordinate::splat(GRID_SIZE / 2)); let snake_head = create_snake_segment(&mut commands, grid::Coordinate::splat(grid::SIZE / 2));
commands commands
.entity(snake_head) .entity(snake_head)
@@ -130,14 +136,15 @@ fn add_tail_system(
mut snake_query: Query<(Entity, &mut SnakeSegments)>, mut snake_query: Query<(Entity, &mut SnakeSegments)>,
) { ) {
if keypress.just_pressed(KeyCode::Space) { if keypress.just_pressed(KeyCode::Space) {
let segment = create_snake_segment(&mut commands, GridCoordinate::splat(GridType::MIN / 2)); let segment =
create_snake_segment(&mut commands, grid::Coordinate::splat(grid::Index::MIN / 2));
let (snake, mut snake_segments) = snake_query.single_mut(); let (snake, mut snake_segments) = snake_query.single_mut();
snake_segments.0.push(segment); snake_segments.0.push(segment);
commands.entity(snake).add_child(segment); commands.entity(snake).add_child(segment);
} }
} }
fn direction_system( fn change_direction_system(
keypress: Res<Input<KeyCode>>, keypress: Res<Input<KeyCode>>,
mut query: Query<&mut Direction, With<SnakeHead>>, mut query: Query<&mut Direction, With<SnakeHead>>,
) { ) {
@@ -156,26 +163,28 @@ fn direction_system(
} }
} }
fn grid_transform_system(mut query: Query<(&mut Transform, &GridCoordinate), With<SnakeSegment>>) { fn grid_transform_system(
mut query: Query<(&mut Transform, &grid::Coordinate), With<SnakeSegment>>,
) {
for (mut transform, grid_coordinate) in query.iter_mut() { for (mut transform, grid_coordinate) in query.iter_mut() {
*transform = grid_coordinate.into(); *transform = grid_coordinate.into();
} }
} }
fn head_movement_system(mut query: Query<(&mut GridCoordinate, &Direction), With<SnakeHead>>) { fn head_movement_system(mut query: Query<(&mut grid::Coordinate, &Direction), With<SnakeHead>>) {
let (mut grid_coordinate, direction) = query.single_mut(); let (mut grid_coordinate, direction) = query.single_mut();
match direction { match direction {
Direction::Up => *grid_coordinate += GridCoordinate(0, 1), Direction::Up => *grid_coordinate += grid::Coordinate(0, 1),
Direction::Down => *grid_coordinate += GridCoordinate(0, -1), Direction::Down => *grid_coordinate += grid::Coordinate(0, -1),
Direction::Left => *grid_coordinate += GridCoordinate(-1, 0), Direction::Left => *grid_coordinate += grid::Coordinate(-1, 0),
Direction::Right => *grid_coordinate += GridCoordinate(1, 0), Direction::Right => *grid_coordinate += grid::Coordinate(1, 0),
}; };
} }
fn segments_movement_system( fn segments_movement_system(
snake_segments_query: Query<&SnakeSegments>, snake_segments_query: Query<&SnakeSegments>,
mut segment_query: Query<&mut GridCoordinate, With<SnakeSegment>>, mut segment_query: Query<&mut grid::Coordinate, With<SnakeSegment>>,
) { ) {
for snake_segments in snake_segments_query.iter() { for snake_segments in snake_segments_query.iter() {
for (&segment_entity, &previous_segment_entity) in for (&segment_entity, &previous_segment_entity) in
@@ -188,19 +197,18 @@ fn segments_movement_system(
} }
} }
fn game_over_system( fn about_to_lose(query: Query<(&grid::Coordinate, &Direction), With<SnakeHead>>) -> bool {
mut commands: Commands, const HIGH_BARRIER: grid::Index = grid::SIZE - 1;
query: Query<(&GridCoordinate, &Direction), With<SnakeHead>>,
) {
const HIGH_BARRIER: GridType = GRID_SIZE - 1;
match query.single() { matches!(
(GridCoordinate(_, 0), Direction::Down) query.single(),
| (GridCoordinate(_, HIGH_BARRIER), Direction::Up) (grid::Coordinate(_, 0), Direction::Down)
| (GridCoordinate(0, _), Direction::Left) | (grid::Coordinate(_, HIGH_BARRIER), Direction::Up)
| (GridCoordinate(HIGH_BARRIER, _), Direction::Right) => { | (grid::Coordinate(0, _), Direction::Left)
commands.insert_resource(NextState(AppState::End)) | (grid::Coordinate(HIGH_BARRIER, _), Direction::Right)
} )
_ => (), }
};
fn game_over_system(mut commands: Commands) {
commands.insert_resource(NextState(AppState::End));
} }