summaryrefslogtreecommitdiff
path: root/src/cell.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cell.rs')
-rw-r--r--src/cell.rs143
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(())
+ }
+}