summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cell.rs207
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs215
3 files changed, 214 insertions, 209 deletions
diff --git a/src/cell.rs b/src/cell.rs
new file mode 100644
index 0000000..6b42fdf
--- /dev/null
+++ b/src/cell.rs
@@ -0,0 +1,207 @@
+use crate::constants;
+use bevy::prelude::*;
+use rand::{
+ distributions::{Distribution, Standard},
+ Rng,
+};
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum Occupant {
+ None,
+ Green,
+ Yellow,
+ Red,
+ Diamond,
+ Explosion,
+}
+
+impl Default for Occupant {
+ fn default() -> Occupant {
+ Occupant::None
+ }
+}
+
+impl Occupant {
+ pub fn to_index(&self) -> u32 {
+ match self {
+ Occupant::Green => 0,
+ Occupant::Yellow => 1,
+ Occupant::Red => 2,
+ Occupant::Diamond => 3,
+ Occupant::Explosion => 4,
+ Occupant::None => 13,
+ }
+ }
+}
+
+impl Distribution<Occupant> for Standard {
+ fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Occupant {
+ match rng.gen_range(0..=3) {
+ 0 => Occupant::Green,
+ 1 => Occupant::Yellow,
+ 2 => Occupant::Diamond,
+ 3 => Occupant::Red,
+ _ => Occupant::None,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Default, Copy)]
+pub struct Cell {
+ pub x: usize,
+ pub y: usize,
+ pub occupant: Occupant,
+ pub selected: bool,
+ pub hovered: bool,
+}
+
+impl Cell {
+ pub fn new(x: usize, y: usize) -> Cell {
+ Cell {
+ x,
+ y,
+ occupant: Occupant::None,
+ selected: false,
+ hovered: false,
+ }
+ }
+}
+
+pub fn insert(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) {
+ for (mut cell, mut sprite) in cell_query.iter_mut() {
+ if cell.occupant == Occupant::None && cell.y == constants::ROWS - 1 {
+ cell.occupant = rand::random();
+ sprite.index = cell.occupant.to_index();
+ }
+ }
+}
+
+pub fn explosion_animation(
+ time: Res<Time>,
+ commands: &mut Commands,
+ mut cell_query: Query<(
+ Entity,
+ &mut Cell,
+ &mut TextureAtlasSprite,
+ Option<&mut Timer>,
+ )>,
+) {
+ for (entity, mut cell, mut sprite, timer) in cell_query.iter_mut() {
+ if cell.occupant == Occupant::Explosion {
+ if let Some(mut timer) = timer {
+ timer.tick(time.delta_seconds());
+ if timer.finished() {
+ if sprite.index < 7 && sprite.index >= 4 {
+ sprite.index += 1;
+ } else {
+ cell.occupant = Occupant::None;
+ sprite.index = cell.occupant.to_index();
+ commands.remove_one::<Timer>(entity);
+ }
+ }
+ } else {
+ commands.insert(entity, (Timer::from_seconds(0.1, true),));
+ }
+ }
+ }
+}
+
+pub fn check(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) {
+ let mut cells = [[Cell::default(); constants::COLUMNS]; constants::ROWS];
+ for (cell, _) in cell_query.iter_mut() {
+ cells[cell.x][cell.y] = *cell;
+ }
+
+ let mut last = Occupant::None;
+ let mut connected = Vec::new();
+
+ for (i, _) in cells.iter().enumerate() {
+ let mut c = Vec::new();
+ for j in 0..constants::ROWS {
+ if cells[i][j].occupant == last && last != Occupant::None {
+ c.push((i, j));
+ c.push((i, j - 1));
+ } else {
+ connected.push(c.clone());
+ c.clear();
+ }
+ last = cells[i][j].occupant;
+ }
+ connected.push(c);
+ last = Occupant::None;
+ }
+
+ for c in connected.iter() {
+ if c.len() > 4 {
+ for (i, j) in c.iter() {
+ for (mut cell, mut sprite) in cell_query.iter_mut() {
+ if &cell.x == i && &cell.y == j && cell.occupant != Occupant::Explosion {
+ cell.occupant = Occupant::Explosion;
+ sprite.index = cell.occupant.to_index();
+ }
+ }
+ }
+ }
+ }
+
+ connected.clear();
+
+ for (i, row) in cells.iter().enumerate() {
+ let mut c = Vec::new();
+ for (j, _) in row.iter().enumerate() {
+ if cells[j][i].occupant == last && last != Occupant::None {
+ c.push((j, i));
+ c.push((j - 1, i));
+ } else {
+ connected.push(c.clone());
+ c.clear();
+ }
+ last = cells[j][i].occupant;
+ }
+ connected.push(c);
+ last = Occupant::None;
+ }
+
+ for c in connected.iter() {
+ if c.len() > 4 {
+ for (i, j) in c.iter() {
+ for (mut cell, mut sprite) in cell_query.iter_mut() {
+ if &cell.x == i && &cell.y == j && cell.occupant != Occupant::Explosion {
+ cell.occupant = Occupant::Explosion;
+ sprite.index = cell.occupant.to_index();
+ }
+ }
+ }
+ }
+ }
+}
+
+pub fn falling(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) {
+ let mut have_gems = Vec::new();
+ for (cell, _sprite) in cell_query.iter_mut() {
+ if cell.occupant != Occupant::None {
+ have_gems.push(*cell);
+ }
+ }
+
+ let mut moved_gems = Vec::new();
+ for (mut cell, mut sprite) in cell_query.iter_mut() {
+ if cell.occupant == Occupant::None {
+ if let Some(c) = have_gems
+ .iter()
+ .find(|&c| (c.x, c.y) == (cell.x, cell.y + 1))
+ {
+ cell.occupant = c.occupant;
+ sprite.index = cell.occupant.to_index();
+ moved_gems.push(c);
+ }
+ }
+ }
+
+ for (mut cell, mut sprite) in cell_query.iter_mut() {
+ if moved_gems.iter().any(|c| (c.x, c.y) == (cell.x, cell.y)) {
+ cell.occupant = Occupant::None;
+ sprite.index = cell.occupant.to_index();
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 0b6d2c4..b7fde1e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1 +1,2 @@
+pub mod cell;
pub mod constants;
diff --git a/src/main.rs b/src/main.rs
index f0a7eb6..566ded5 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,181 +1,8 @@
use bevy::math::Vec3;
use bevy::prelude::*;
+use gems::cell::{self, Cell};
use gems::constants;
-use rand::{
- distributions::{Distribution, Standard},
- thread_rng, Rng,
-};
-
-#[derive(Debug, PartialEq, Clone, Copy)]
-enum Occupant {
- None,
- Green,
- Yellow,
- Red,
- Diamond,
- Explosion,
-}
-
-impl Default for Occupant {
- fn default() -> Occupant {
- Occupant::None
- }
-}
-
-impl Occupant {
- pub fn to_index(&self) -> u32 {
- match self {
- Occupant::Green => 0,
- Occupant::Yellow => 1,
- Occupant::Red => 2,
- Occupant::Diamond => 3,
- Occupant::Explosion => 4,
- Occupant::None => 13,
- }
- }
-}
-
-impl Distribution<Occupant> for Standard {
- fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Occupant {
- match rng.gen_range(0..=3) {
- 0 => Occupant::Green,
- 1 => Occupant::Yellow,
- 2 => Occupant::Diamond,
- 3 => Occupant::Red,
- _ => Occupant::None,
- }
- }
-}
-
-#[derive(Debug, Clone, Default, Copy)]
-struct Cell {
- x: usize,
- y: usize,
- occupant: Occupant,
- selected: bool,
- hovered: bool,
-}
-
-impl Cell {
- pub fn new(x: usize, y: usize) -> Cell {
- Cell {
- x,
- y,
- occupant: Occupant::None,
- selected: false,
- hovered: false,
- }
- }
-}
-
-fn cell_insert_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) {
- for (mut cell, mut sprite) in cell_query.iter_mut() {
- if cell.occupant == Occupant::None && cell.y == constants::ROWS - 1 {
- cell.occupant = rand::random();
- sprite.index = cell.occupant.to_index();
- }
- }
-}
-
-fn explosion_animation_system(
- time: Res<Time>,
- commands: &mut Commands,
- mut cell_query: Query<(
- Entity,
- &mut Cell,
- &mut TextureAtlasSprite,
- Option<&mut Timer>,
- )>,
-) {
- for (entity, mut cell, mut sprite, timer) in cell_query.iter_mut() {
- if cell.occupant == Occupant::Explosion {
- if let Some(mut timer) = timer {
- timer.tick(time.delta_seconds());
- if timer.finished() {
- if sprite.index < 7 && sprite.index >= 4 {
- sprite.index += 1;
- } else {
- cell.occupant = Occupant::None;
- sprite.index = cell.occupant.to_index();
- commands.remove_one::<Timer>(entity);
- }
- }
- } else {
- commands.insert(entity, (Timer::from_seconds(0.1, true),));
- }
- }
- }
-}
-
-fn cell_check_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) {
- let mut cells = [[Cell::default(); constants::COLUMNS]; constants::ROWS];
- for (cell, _) in cell_query.iter_mut() {
- cells[cell.x][cell.y] = *cell;
- }
-
- let mut last = Occupant::None;
- let mut connected = Vec::new();
-
- for (i, _) in cells.iter().enumerate() {
- let mut c = Vec::new();
- for j in 0..constants::ROWS {
- if cells[i][j].occupant == last && last != Occupant::None {
- c.push((i, j));
- c.push((i, j - 1));
- } else {
- connected.push(c.clone());
- c.clear();
- }
- last = cells[i][j].occupant;
- }
- connected.push(c);
- last = Occupant::None;
- }
-
- for c in connected.iter() {
- if c.len() > 4 {
- for (i, j) in c.iter() {
- for (mut cell, mut sprite) in cell_query.iter_mut() {
- if &cell.x == i && &cell.y == j && cell.occupant != Occupant::Explosion {
- cell.occupant = Occupant::Explosion;
- sprite.index = cell.occupant.to_index();
- }
- }
- }
- }
- }
-
- connected.clear();
-
- for (i, row) in cells.iter().enumerate() {
- let mut c = Vec::new();
- for (j, _) in row.iter().enumerate() {
- if cells[j][i].occupant == last && last != Occupant::None {
- c.push((j, i));
- c.push((j - 1, i));
- } else {
- connected.push(c.clone());
- c.clear();
- }
- last = cells[j][i].occupant;
- }
- connected.push(c);
- last = Occupant::None;
- }
-
- for c in connected.iter() {
- if c.len() > 4 {
- for (i, j) in c.iter() {
- for (mut cell, mut sprite) in cell_query.iter_mut() {
- if &cell.x == i && &cell.y == j && cell.occupant != Occupant::Explosion {
- cell.occupant = Occupant::Explosion;
- sprite.index = cell.occupant.to_index();
- }
- }
- }
- }
- }
-}
+use rand::{thread_rng, Rng};
fn star_spawning_system(commands: &mut Commands, time: Res<Time>, mut q: Query<&mut Timer>) {
for mut timer in q.iter_mut() {
@@ -204,36 +31,6 @@ fn star_spawning_system(commands: &mut Commands, time: Res<Time>, mut q: Query<&
}
}
-fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) {
- let mut have_gems = Vec::new();
- for (cell, _sprite) in cell_query.iter_mut() {
- if cell.occupant != Occupant::None {
- have_gems.push(*cell);
- }
- }
-
- let mut moved_gems = Vec::new();
- for (mut cell, mut sprite) in cell_query.iter_mut() {
- if cell.occupant == Occupant::None {
- if let Some(c) = have_gems
- .iter()
- .find(|&c| (c.x, c.y) == (cell.x, cell.y + 1))
- {
- cell.occupant = c.occupant;
- sprite.index = cell.occupant.to_index();
- moved_gems.push(c);
- }
- }
- }
-
- for (mut cell, mut sprite) in cell_query.iter_mut() {
- if moved_gems.iter().any(|c| (c.x, c.y) == (cell.x, cell.y)) {
- cell.occupant = Occupant::None;
- sprite.index = cell.occupant.to_index();
- }
- }
-}
-
pub fn setup(
commands: &mut Commands,
asset_server: Res<AssetServer>,
@@ -444,10 +241,10 @@ pub struct GemsPlugin;
impl Plugin for GemsPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_startup_system(setup.system());
- app.add_system(cell_insert_system.system());
- app.add_system(cell_falling_system.system());
- app.add_system(cell_check_system.system());
- app.add_system(explosion_animation_system.system());
+ app.add_system(cell::insert.system());
+ app.add_system(cell::falling.system());
+ app.add_system(cell::check.system());
+ app.add_system(cell::explosion_animation.system());
app.add_system(mouse_system.system());
app.add_system(cosmonaut_detect_system.system());
app.add_system(animation_system.system());