Game over system fix
This commit is contained in:
21
src/canvas.rs
Normal file
21
src/canvas.rs
Normal 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()
|
||||
});
|
||||
}
|
||||
51
src/grid.rs
51
src/grid.rs
@@ -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()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
80
src/snake.rs
80
src/snake.rs
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user