diff options
-rw-r--r-- | src/cell.rs | 207 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 215 |
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(); + } + } +} @@ -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()); |