diff options
author | Tom Barrett <tom@tombarrett.xyz> | 2021-04-10 13:08:00 +0200 |
---|---|---|
committer | Tom Barrett <tom@tombarrett.xyz> | 2021-04-10 13:08:00 +0200 |
commit | d8a5e679e931c302da03d675caf4bd208dbde988 (patch) | |
tree | bd568a7f62403bdfdf3e3fbc41e434f9fa118b66 /src/cell.rs | |
parent | 07eb2dc0cbeaa7eb64645a86bd11842717a107a6 (diff) | |
parent | 893805baa14972dc6c1c28170856097bb54bf280 (diff) |
Merge branch 'bevy_5'
moved to bevy
Diffstat (limited to 'src/cell.rs')
-rw-r--r-- | src/cell.rs | 229 |
1 files changed, 137 insertions, 92 deletions
diff --git a/src/cell.rs b/src/cell.rs index b085c5e..e4be4ac 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -1,143 +1,188 @@ use crate::constants; -use ggez::graphics::{ - self, spritebatch::SpriteBatch, Color, DrawMode, DrawParam, Mesh, Rect, StrokeOptions, -}; -use ggez::mint::{Point2, Vector2}; -use ggez::{Context, GameResult}; +use bevy::prelude::*; use rand::{ distributions::{Distribution, Standard}, Rng, }; -use std::time::Instant; -#[derive(Clone, Copy, PartialEq)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum Occupant { None, Green, Yellow, - Diamond, Red, - Explosion { frame: usize, timer: Instant }, + Blue, + Purple, + Explosion, +} + +impl Default for Occupant { + fn default() -> Occupant { + Occupant::None + } +} + +impl Occupant { + pub fn to_index(&self) -> u32 { + match self { + Occupant::Green => constants::TILESHEET_GREEN, + Occupant::Yellow => constants::TILESHEET_YELLOW, + Occupant::Red => constants::TILESHEET_RED, + Occupant::Blue => constants::TILESHEET_BLUE, + Occupant::Purple => constants::TILESHEET_PURPLE, + Occupant::Explosion => constants::TILESHEET_EXPLOSION1, + Occupant::None => 0, + } + } } impl Distribution<Occupant> for Standard { fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Occupant { - match rng.gen_range(0..=3) { + match rng.gen_range(0..=4) { 0 => Occupant::Green, 1 => Occupant::Yellow, - 2 => Occupant::Diamond, + 2 => Occupant::Blue, 3 => Occupant::Red, + 4 => Occupant::Purple, _ => Occupant::None, } } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Default, Copy)] pub struct Cell { + pub x: usize, + pub y: usize, pub occupant: Occupant, - position: Point2<f32>, - hover: bool, - clicked: bool, + pub selected: bool, + pub hovered: bool, } impl Cell { - pub fn new(position: Point2<f32>) -> Cell { + pub fn new(x: usize, y: usize) -> Cell { Cell { - occupant: rand::random(), - position, - hover: false, - clicked: false, + x, + y, + occupant: Occupant::None, + selected: false, + hovered: false, + } + } + + pub fn set_occupant( + &mut self, + occupant: Occupant, + sprite: &mut TextureAtlasSprite, + visible: &mut Visible, + ) { + self.occupant = occupant; + sprite.index = self.occupant.to_index(); + if self.occupant == Occupant::None { + visible.is_visible = false; + } else { + visible.is_visible = true; } } +} - pub fn contains(&self, position: Point2<f32>) -> bool { - position.x > self.position.x - && position.y > self.position.y - && position.x < self.position.x + constants::TILE_WIDTH * constants::TILE_SCALE - && position.y < self.position.y + constants::TILE_WIDTH * constants::TILE_SCALE +pub fn insert(mut q: Query<(&mut Cell, &mut TextureAtlasSprite, &mut Visible)>) { + for (mut cell, mut sprite, mut visible) in q.iter_mut() { + if cell.occupant == Occupant::None && cell.y == constants::GRID_SIZE - 1 { + cell.set_occupant(rand::random(), &mut sprite, &mut visible); + } } +} - pub fn moveable(&self) -> bool { - //!matches!(self.occupant, Occupant::Explosion{ ..} | Occupant::None) - match self.occupant { - Occupant::Explosion { .. } => false, - Occupant::None => false, - _ => true, +pub fn start_explosion(mut commands: Commands, mut q: Query<(Entity, &Cell), Without<Timer>>) { + for (entity, cell) in q.iter_mut() { + if cell.occupant == Occupant::Explosion { + commands + .entity(entity) + .insert(Timer::from_seconds(0.1, true)); } } +} - pub fn clicked_on(&mut self) { - self.clicked = true; +pub fn check(mut q: Query<(&mut Cell, &mut TextureAtlasSprite, &mut Visible)>) { + let mut cells = [[Cell::default(); constants::GRID_SIZE]; constants::GRID_SIZE]; + for (cell, _, _) in q.iter_mut() { + cells[cell.x][cell.y] = *cell; } - pub fn clicked_off(&mut self) { - self.clicked = false; + let mut last = Occupant::None; + let mut connected = Vec::new(); + + for (i, row) in cells.iter().enumerate() { + let mut c = Vec::new(); + for (j, _) in row.iter().enumerate() { + if cells[i][j].occupant == last && last != Occupant::None && last != Occupant::Explosion + { + 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; } - pub fn hover_on(&mut self) { - self.hover = true; + 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 && last != Occupant::Explosion + { + 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; } - pub fn hover_off(&mut self) { - self.hover = false; + connected = connected.into_iter().filter(|c| c.len() > 4).collect(); + + for c in connected.iter() { + for (i, j) in c.iter() { + for (mut cell, mut sprite, mut visible) in q.iter_mut() { + if &cell.x == i && &cell.y == j && cell.occupant != Occupant::Explosion { + cell.set_occupant(Occupant::Explosion, &mut sprite, &mut visible); + } + } + } } +} - pub fn draw(&self, context: &mut Context, spritebatch: &mut SpriteBatch) -> GameResult { - let source = match self.occupant { - Occupant::None => None, - Occupant::Explosion { frame, .. } => match frame { - 0 => Some(Rect::new(0.0, 0.5, 0.25, 0.5)), - 1 => Some(Rect::new(0.25, 0.5, 0.25, 0.5)), - 2 => Some(Rect::new(0.50, 0.5, 0.25, 0.5)), - 3 => Some(Rect::new(0.75, 0.5, 0.25, 0.5)), - _ => None, - }, - Occupant::Green => Some(Rect::new(0.0, 0.0, 0.25, 0.5)), - Occupant::Yellow => Some(Rect::new(0.25, 0.0, 0.25, 0.5)), - Occupant::Diamond => Some(Rect::new(0.50, 0.0, 0.25, 0.5)), - Occupant::Red => Some(Rect::new(0.75, 0.0, 0.25, 0.5)), - }; - - if let Some(source) = source { - spritebatch.add( - DrawParam::default() - .src(source) - .dest(self.position) - .scale(Vector2 { - x: constants::TILE_SCALE, - y: constants::TILE_SCALE, - }), - ); +pub fn falling(mut q: Query<(&mut Cell, &mut TextureAtlasSprite, &mut Visible)>) { + let mut have_gems = Vec::new(); + for (cell, _sprite, _visible) in q.iter_mut() { + if cell.occupant != Occupant::None { + have_gems.push(*cell); } + } - if self.hover { - let mesh = Mesh::new_rectangle( - context, - DrawMode::Stroke(StrokeOptions::default()), - Rect::new( - self.position.x, - self.position.y, - constants::TILE_WIDTH * constants::TILE_SCALE, - constants::TILE_HEIGHT * constants::TILE_SCALE, - ), - Color::from_rgb(255, 100, 100), - )?; - graphics::draw(context, &mesh, DrawParam::default())?; + let mut moved_gems = Vec::new(); + for (mut cell, mut sprite, mut visible) in q.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.set_occupant(c.occupant, &mut sprite, &mut visible); + moved_gems.push(c); + } } - if self.clicked { - let mesh = Mesh::new_rectangle( - context, - DrawMode::Stroke(StrokeOptions::default()), - Rect::new( - self.position.x, - self.position.y, - constants::TILE_WIDTH * constants::TILE_SCALE, - constants::TILE_HEIGHT * constants::TILE_SCALE, - ), - Color::from_rgb(100, 255, 100), - )?; - graphics::draw(context, &mesh, DrawParam::default())?; + } + + for (mut cell, mut sprite, mut visible) in q.iter_mut() { + if moved_gems.iter().any(|c| (c.x, c.y) == (cell.x, cell.y)) { + cell.set_occupant(Occupant::None, &mut sprite, &mut visible); } - Ok(()) } } |