summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs200
1 files changed, 183 insertions, 17 deletions
diff --git a/src/main.rs b/src/main.rs
index 1caa62a..888c494 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,18 +1,22 @@
use ggez;
use ggez::event;
use ggez::graphics::{
- self, spritebatch::SpriteBatch, DrawParam, FilterMode, Image, Rect, WrapMode,
+ self, spritebatch::SpriteBatch, Color, DrawMode, DrawParam, FilterMode, Image, Mesh, Rect,
+ StrokeOptions, WrapMode,
};
-use ggez::nalgebra::{Point2, Vector2};
+use ggez::input::mouse;
+use ggez::mint::{Point2, Vector2};
use rand::{
distributions::{Distribution, Standard},
Rng,
};
-pub const TILE_SCALE: f32 = 3.0;
+pub const TILE_SCALE: f32 = 2.0;
pub const TILE_HEIGHT: f32 = 16.0;
pub const TILE_WIDTH: f32 = 16.0;
+pub const BORDER_SIZE: f32 = 3.0;
+#[derive(Clone, Copy)]
enum Occupant {
None,
Green,
@@ -33,9 +37,12 @@ impl Distribution<Occupant> for Standard {
}
}
+#[derive(Clone, Copy)]
struct Cell {
occupant: Occupant,
position: Point2<f32>,
+ hover: bool,
+ clicked: bool,
}
impl Cell {
@@ -43,10 +50,42 @@ impl Cell {
Cell {
occupant: rand::random(),
position: position,
+ hover: false,
+ clicked: false,
}
}
- pub fn draw(&self, spritebatch: &mut SpriteBatch) {
+ pub fn contains(&self, position: Point2<f32>) -> bool {
+ if position.x > self.position.x {
+ if position.y > self.position.y {
+ if position.x < self.position.x + TILE_WIDTH * TILE_SCALE {
+ if position.y < self.position.y + TILE_WIDTH * TILE_SCALE {
+ return true;
+ }
+ }
+ }
+ }
+
+ false
+ }
+
+ 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 ggez::Context, spritebatch: &mut SpriteBatch) {
let source = match self.occupant {
Occupant::None => None,
Occupant::Green => Some(Rect::new(0.0, 0.0, 0.25, 1.0)),
@@ -60,13 +99,46 @@ impl Cell {
DrawParam::default()
.src(source)
.dest(self.position)
- .scale(Vector2::new(TILE_SCALE, TILE_SCALE)),
+ .scale(Vector2 {
+ x: TILE_SCALE,
+ y: TILE_SCALE,
+ }),
+ );
+ }
+
+ if self.hover {
+ let mesh = Mesh::new_rectangle(
+ context,
+ DrawMode::Stroke(StrokeOptions::default()),
+ Rect::new(
+ self.position.x,
+ self.position.y,
+ TILE_WIDTH * TILE_SCALE,
+ TILE_HEIGHT * TILE_SCALE,
+ ),
+ Color::from_rgb(255, 100, 100),
+ );
+ graphics::draw(context, &mesh.unwrap(), DrawParam::default()).unwrap();
+ }
+ if self.clicked {
+ let mesh = Mesh::new_rectangle(
+ context,
+ DrawMode::Stroke(StrokeOptions::default()),
+ Rect::new(
+ self.position.x,
+ self.position.y,
+ TILE_WIDTH * TILE_SCALE,
+ TILE_HEIGHT * TILE_SCALE,
+ ),
+ Color::from_rgb(100, 255, 100),
);
+ graphics::draw(context, &mesh.unwrap(), DrawParam::default()).unwrap();
}
}
}
struct Game {
+ selected: Option<(usize, usize)>,
spritebatch: SpriteBatch,
grid: Vec<Vec<Cell>>,
}
@@ -81,37 +153,131 @@ impl Game {
let mut y = 0.0;
for _ in 0..8 {
let mut column = Vec::new();
- column.push(Cell::new(Point2::new(0.0, y)));
- column.push(Cell::new(Point2::new(TILE_WIDTH * TILE_SCALE, y)));
- column.push(Cell::new(Point2::new(2.0 * TILE_WIDTH * TILE_SCALE, y)));
- column.push(Cell::new(Point2::new(3.0 * TILE_WIDTH * TILE_SCALE, y)));
- column.push(Cell::new(Point2::new(4.0 * TILE_WIDTH * TILE_SCALE, y)));
- column.push(Cell::new(Point2::new(5.0 * TILE_WIDTH * TILE_SCALE, y)));
- column.push(Cell::new(Point2::new(6.0 * TILE_WIDTH * TILE_SCALE, y)));
- column.push(Cell::new(Point2::new(7.0 * TILE_WIDTH * TILE_SCALE, y)));
-
- y += TILE_HEIGHT * TILE_SCALE;
+ column.push(Cell::new(Point2 { x: 0.0, y: y }));
+ column.push(Cell::new(Point2 {
+ x: 1.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+ column.push(Cell::new(Point2 {
+ x: 2.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+ column.push(Cell::new(Point2 {
+ x: 3.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+ column.push(Cell::new(Point2 {
+ x: 4.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+ column.push(Cell::new(Point2 {
+ x: 5.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+ column.push(Cell::new(Point2 {
+ x: 6.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+ column.push(Cell::new(Point2 {
+ x: 7.0 * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE),
+ y: y,
+ }));
+
+ y += TILE_HEIGHT * TILE_SCALE + BORDER_SIZE;
grid.push(column);
}
Ok(Game {
grid: grid,
+ selected: None,
spritebatch: SpriteBatch::new(image),
})
}
}
impl event::EventHandler for Game {
- fn update(&mut self, _context: &mut ggez::Context) -> ggez::GameResult {
+ fn update(&mut self, context: &mut ggez::Context) -> ggez::GameResult {
+ for row in self.grid.iter_mut() {
+ for cell in row.iter_mut() {
+ cell.hover_off();
+ }
+ }
+
+ let position = mouse::position(context);
+
+ for row in self.grid.iter_mut() {
+ for cell in row.iter_mut() {
+ if cell.contains(position) {
+ cell.hover_on();
+ }
+ }
+ }
+
Ok(())
}
+ fn mouse_button_down_event(
+ &mut self,
+ _context: &mut ggez::Context,
+ button: mouse::MouseButton,
+ x: f32,
+ y: f32,
+ ) {
+ if button == mouse::MouseButton::Left {
+ let position = Point2 { x: x, y: y };
+ for (i, row) in self.grid.iter_mut().enumerate() {
+ for (j, cell) in row.iter_mut().enumerate() {
+ if cell.contains(position) {
+ self.selected = Some((i, j));
+ cell.clicked_on();
+ }
+ }
+ }
+ }
+ }
+
+ fn mouse_button_up_event(
+ &mut self,
+ _context: &mut ggez::Context,
+ button: mouse::MouseButton,
+ x: f32,
+ y: f32,
+ ) {
+ if button == mouse::MouseButton::Left {
+ for row in self.grid.iter_mut() {
+ for cell in row.iter_mut() {
+ cell.clicked_off();
+ }
+ }
+
+ if let Some(selected) = self.selected {
+ let position = Point2 { x: x, y: y };
+ let mut swap = None;
+ for (i, row) in self.grid.iter_mut().enumerate() {
+ for (j, cell) in row.iter_mut().enumerate() {
+ if cell.contains(position) {
+ if (i + 1 == selected.0) && (j == selected.1) {
+ swap = Some((i, j));
+ }
+ }
+ }
+ }
+ if let Some((i, j)) = swap {
+ let clone = self.grid[i][j].occupant.clone();
+ self.grid[i][j].occupant = self.grid[selected.0][selected.1].occupant;
+ self.grid[selected.0][selected.1].occupant = clone;
+ self.selected = None;
+ }
+ }
+ }
+ }
+
fn draw(&mut self, context: &mut ggez::Context) -> ggez::GameResult {
graphics::clear(context, [0.1, 0.2, 0.3, 1.0].into());
for row in self.grid.iter() {
for cell in row.iter() {
- cell.draw(&mut self.spritebatch)
+ cell.draw(context, &mut self.spritebatch)
}
}