Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"

[dependencies]
bevy = { version = "0.7.0", features = ["dynamic"] }
rand = "0.8.5"

# Enable a small amount of optimization in debug mode
[profile.dev]
Expand Down
25 changes: 25 additions & 0 deletions src/apple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use bevy::prelude::*;
use bevy::core::FixedTimestep;

use crate::board::Board;

pub struct Plugin;

impl bevy::prelude::Plugin for Plugin {
fn build(&self, app: &mut App) {
app.add_system_set(
SystemSet::new()
.with_run_criteria(FixedTimestep::step(5.0))
.with_system(add_apple)
);
}
}

#[derive(Component)]
pub struct Apple;

fn add_apple(mut commands: Commands, mut board: ResMut<Board>) {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the major design decision. How much game state/knowledge should be encapsulated in Board vs. the ECS?

let loc = board.spawn_apple();
info!("spawning apple: {:?}", &loc);
commands.spawn().insert(Apple).insert(loc);
}
43 changes: 38 additions & 5 deletions src/board.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use std::collections::HashSet;
use bevy::prelude::*;
use bevy::math::*;

use rand::prelude::*;

use crate::App;
use crate::location::Location;
use crate::direction::Direction;
Expand All @@ -14,6 +18,7 @@ impl bevy::prelude::Plugin for Plugin {

pub(crate) struct Board {
pub(crate) limit: UVec2,
taken: HashSet<UVec2>,
}

impl Board {
Expand All @@ -22,22 +27,50 @@ impl Board {

let result_coord = match dir {
Direction::Up if coord.y < self.limit.y => uvec2(coord.x, coord.y + 1),
Direction::Down if coord.y > 0 => uvec2(coord.x, coord.y - 1),
Direction::Left if coord.x > 0 => uvec2(coord.x - 1, coord.y),
Direction::Down if coord.y > 0 => uvec2(coord.x, coord.y - 1),
Direction::Left if coord.x > 0 => uvec2(coord.x - 1, coord.y),
Direction::Right if coord.x < self.limit.x => uvec2(coord.x + 1, coord.y),
_ => return None,
};

Some(Location::new(result_coord))
}

pub fn starting_location(&self) -> Location {
Location::new(uvec2(self.limit.x / 2, (self.limit.y - 1) / 2 + 1))
pub fn reset(&mut self) -> Location {
self.taken.clear();
let coord = uvec2(self.limit.x / 2, (self.limit.y - 1) / 2 + 1);
self.taken.insert(coord);
Location::new(coord)
}

pub fn spawn_apple(&mut self) -> Location {
let x_range = 0..=self.limit.x;
let y_range = 0..=self.limit.y;
let mut rng = thread_rng();
loop {
let coord = uvec2(rng.gen_range(x_range.clone()), rng.gen_range(y_range.clone()));
if !self.taken.contains(&coord) {
self.taken.insert(coord);
return Location::new(coord);
}
}
}

pub fn block(&mut self, loc: &Location) {
assert!(!self.taken.contains(&loc.coord));
self.taken.insert(loc.coord);
}

pub fn clear(&mut self, loc: &Location) {
self.taken.remove(&loc.coord);
}
}

impl Default for Board {
fn default() -> Self {
Board { limit: uvec2(15, 8) }
Board {
limit: uvec2(15, 8),
taken: HashSet::new(),
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll eventually need to know what is at the location though.

}
}
}
4 changes: 2 additions & 2 deletions src/location.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy::prelude::*;

#[derive(Component, Clone)]
#[derive(Component, Clone, Debug)]
pub struct Location {
pub coord: UVec2,
}
Expand All @@ -9,4 +9,4 @@ impl Location {
pub fn new(coord: UVec2) -> Self {
Self { coord }
}
}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod board;
mod render;
mod input;
mod window;
mod apple;

use bevy::prelude::*;

Expand All @@ -16,5 +17,6 @@ fn main() {
.add_plugin(render::Plugin)
.add_plugin(input::Plugin)
.add_plugin(board::Plugin)
.add_plugin(apple::Plugin)
.run();
}
15 changes: 9 additions & 6 deletions src/snake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ impl bevy::prelude::Plugin for Plugin {
}
}

fn setup(mut commands: Commands, board: Res<Board>) {
fn setup(mut commands: Commands, mut board: ResMut<Board>) {
let starting_loc = board.reset();
commands.spawn()
.insert(Head)
.insert(board.starting_location())
.insert(starting_loc)
.insert(Moving::default());
}

Expand All @@ -33,17 +34,19 @@ pub struct Moving {
pub(crate) last_dir: Direction,
}

fn move_snakes(board: Res<Board>, mut query: Query<(&mut Location, &mut Moving), With<Head>>) {
fn move_snakes(mut board: ResMut<Board>, mut query: Query<(&mut Location, &mut Moving), With<Head>>) {
for (mut loc, mut moving) in query.iter_mut() {
*loc = match board.adjacent(&loc, &moving.dir) {
Some(loc) => {
Some(new_loc) => {
board.clear(&loc);
board.block(&new_loc);
moving.last_dir = moving.dir;
loc
new_loc
},
None => {
println!("Snake hit a wall!");
*moving = Moving::default();
board.starting_location()
board.reset()
},
};
}
Expand Down