diff options
Diffstat (limited to 'src/cell.rs')
-rw-r--r-- | src/cell.rs | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/cell.rs b/src/cell.rs new file mode 100644 index 0000000..b085c5e --- /dev/null +++ b/src/cell.rs @@ -0,0 +1,143 @@ +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 rand::{ + distributions::{Distribution, Standard}, + Rng, +}; + +use std::time::Instant; +#[derive(Clone, Copy, PartialEq)] +pub enum Occupant { + None, + Green, + Yellow, + Diamond, + Red, + Explosion { frame: usize, timer: Instant }, +} + +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(Clone, Copy)] +pub struct Cell { + pub occupant: Occupant, + position: Point2<f32>, + hover: bool, + clicked: bool, +} + +impl Cell { + pub fn new(position: Point2<f32>) -> Cell { + Cell { + occupant: rand::random(), + position, + hover: false, + clicked: false, + } + } + + 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 moveable(&self) -> bool { + //!matches!(self.occupant, Occupant::Explosion{ ..} | Occupant::None) + match self.occupant { + Occupant::Explosion { .. } => false, + Occupant::None => false, + _ => true, + } + } + + pub fn clicked_on(&mut self) { + self.clicked = true; + } + + pub fn clicked_off(&mut self) { + self.clicked = false; + } + + pub fn hover_on(&mut self) { + self.hover = true; + } + + pub fn hover_off(&mut self) { + self.hover = false; + } + + 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, + }), + ); + } + + 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())?; + } + 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())?; + } + Ok(()) + } +} |