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 std::ops::{Add, AddAssign};
pub type GridType = i16;
pub type Index = i16;
pub const GRID_SIZE: GridType = 21;
pub const GRID_SEGMENT_SIZE: f32 = 20.;
pub const SIZE: Index = 17;
pub const SEGMENT_SIZE: f32 = 20.;
#[derive(Component, Clone, Copy, Default, Debug)]
pub struct GridCoordinate(pub GridType, pub GridType);
pub struct Coordinate(pub Index, pub Index);
impl GridCoordinate {
pub fn splat(v: GridType) -> Self {
impl Coordinate {
pub fn splat(v: Index) -> Self {
Self(v, v)
}
}
impl Add for GridCoordinate {
impl Add for Coordinate {
type Output = Self;
fn add(self, rhs: GridCoordinate) -> Self::Output {
GridCoordinate(self.0 + rhs.0, self.1 + rhs.1)
fn add(self, rhs: Coordinate) -> Self::Output {
Coordinate(self.0 + rhs.0, self.1 + rhs.1)
}
}
impl AddAssign for GridCoordinate {
impl AddAssign for Coordinate {
fn add_assign(&mut self, rhs: Self) {
*self = Self(self.0 + rhs.0, self.1 + rhs.1)
}
}
impl From<GridCoordinate> for Transform {
fn from(grid_coordinate: GridCoordinate) -> Self {
impl From<Coordinate> for Transform {
fn from(grid_coordinate: Coordinate) -> Self {
(&grid_coordinate).into()
}
}
impl From<&GridCoordinate> for Transform {
fn from(grid_coordinate: &GridCoordinate) -> Self {
impl From<&Coordinate> for Transform {
fn from(grid_coordinate: &Coordinate) -> Self {
Transform::from_xyz(
(grid_coordinate.0 - GRID_SIZE / 2) as f32 * GRID_SEGMENT_SIZE,
(grid_coordinate.1 - GRID_SIZE / 2) as f32 * GRID_SEGMENT_SIZE,
(grid_coordinate.0 - SIZE / 2) as f32 * SEGMENT_SIZE,
(grid_coordinate.1 - SIZE / 2) as f32 * SEGMENT_SIZE,
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_editor_pls::prelude::*;
use grid::{GRID_SEGMENT_SIZE, GRID_SIZE};
use grid::{SEGMENT_SIZE, SIZE};
use iyes_loopless::prelude::*;
mod canvas;
mod grid;
mod snake;
@@ -31,8 +32,8 @@ fn main() {
.add_loopless_state(AppState::Begin)
.add_plugins(DefaultPlugins)
// .add_plugin(EditorPlugin)
.add_plugin(snake::SnakePlugin)
.add_plugin(grid::GridPlugin)
.add_plugin(snake::ModPlugin)
.add_plugin(canvas::ModPlugin)
.add_startup_system(setup_system)
.add_system(camera_move_system)
.add_system(bevy::window::close_on_esc)
@@ -41,7 +42,7 @@ fn main() {
}
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
.spawn_bundle(Camera2dBundle {

View File

@@ -1,7 +1,4 @@
use crate::{
grid::{GridCoordinate, GridType, GRID_SEGMENT_SIZE, GRID_SIZE},
AppState,
};
use crate::{grid, AppState};
use bevy::prelude::*;
use itertools::Itertools;
use iyes_loopless::prelude::*;
@@ -10,27 +7,36 @@ use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Eq, Hash, StageLabel)]
struct FixedTimeStage;
pub struct SnakePlugin;
pub struct ModPlugin;
impl Plugin for SnakePlugin {
impl Plugin for ModPlugin {
fn build(&self, app: &mut App) {
let mut fixed_time_systems0 = SystemStage::parallel();
fixed_time_systems0.add_system(segments_movement_system.run_in_state(AppState::InGame));
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)
.add_stage_before(
CoreStage::Update,
FixedTimeStage,
FixedTimestepStage::new(Duration::from_millis(100))
FixedTimestepStage::new(Duration::from_millis(125))
.with_stage(fixed_time_systems0)
.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(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(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
.spawn_bundle(SpriteBundle {
sprite: Sprite {
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()
},
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) {
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
.entity(snake_head)
@@ -130,14 +136,15 @@ fn add_tail_system(
mut snake_query: Query<(Entity, &mut SnakeSegments)>,
) {
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();
snake_segments.0.push(segment);
commands.entity(snake).add_child(segment);
}
}
fn direction_system(
fn change_direction_system(
keypress: Res<Input<KeyCode>>,
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() {
*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();
match direction {
Direction::Up => *grid_coordinate += GridCoordinate(0, 1),
Direction::Down => *grid_coordinate += GridCoordinate(0, -1),
Direction::Left => *grid_coordinate += GridCoordinate(-1, 0),
Direction::Right => *grid_coordinate += GridCoordinate(1, 0),
Direction::Up => *grid_coordinate += grid::Coordinate(0, 1),
Direction::Down => *grid_coordinate += grid::Coordinate(0, -1),
Direction::Left => *grid_coordinate += grid::Coordinate(-1, 0),
Direction::Right => *grid_coordinate += grid::Coordinate(1, 0),
};
}
fn segments_movement_system(
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 (&segment_entity, &previous_segment_entity) in
@@ -188,19 +197,18 @@ fn segments_movement_system(
}
}
fn game_over_system(
mut commands: Commands,
query: Query<(&GridCoordinate, &Direction), With<SnakeHead>>,
) {
const HIGH_BARRIER: GridType = GRID_SIZE - 1;
fn about_to_lose(query: Query<(&grid::Coordinate, &Direction), With<SnakeHead>>) -> bool {
const HIGH_BARRIER: grid::Index = grid::SIZE - 1;
match query.single() {
(GridCoordinate(_, 0), Direction::Down)
| (GridCoordinate(_, HIGH_BARRIER), Direction::Up)
| (GridCoordinate(0, _), Direction::Left)
| (GridCoordinate(HIGH_BARRIER, _), Direction::Right) => {
commands.insert_resource(NextState(AppState::End))
}
_ => (),
};
matches!(
query.single(),
(grid::Coordinate(_, 0), Direction::Down)
| (grid::Coordinate(_, HIGH_BARRIER), Direction::Up)
| (grid::Coordinate(0, _), Direction::Left)
| (grid::Coordinate(HIGH_BARRIER, _), Direction::Right)
)
}
fn game_over_system(mut commands: Commands) {
commands.insert_resource(NextState(AppState::End));
}