diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cell.rs | 143 | ||||
-rw-r--r-- | src/cosmonaut.rs | 110 | ||||
-rw-r--r-- | src/game.rs | 271 | ||||
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/main.rs | 14 |
5 files changed, 5 insertions, 536 deletions
diff --git a/src/cell.rs b/src/cell.rs deleted file mode 100644 index b085c5e..0000000 --- a/src/cell.rs +++ /dev/null @@ -1,143 +0,0 @@ -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(()) - } -} diff --git a/src/cosmonaut.rs b/src/cosmonaut.rs deleted file mode 100644 index 235861e..0000000 --- a/src/cosmonaut.rs +++ /dev/null @@ -1,110 +0,0 @@ -use crate::constants; -use ggez::graphics::{self, DrawParam, FilterMode, Image, Rect}; -use ggez::mint::{Point2, Vector2}; -use ggez::{Context, GameResult}; -use std::time::Instant; - -#[derive(Clone, Copy)] -enum CosmonautFrames { - None, - One, - Two, - Three, - Four, -} - -impl CosmonautFrames { - pub fn next(&mut self) { - *self = match self { - CosmonautFrames::None => CosmonautFrames::One, - CosmonautFrames::One => CosmonautFrames::Two, - CosmonautFrames::Two => CosmonautFrames::Three, - CosmonautFrames::Three => CosmonautFrames::Four, - CosmonautFrames::Four => CosmonautFrames::None, - }; - } -} - -pub struct Cosmonaut { - destination: Point2<f32>, - image: Image, - frame: CosmonautFrames, - timer: Instant, - scale: Vector2<f32>, -} - -impl Cosmonaut { - pub fn new(context: &mut Context) -> GameResult<Cosmonaut> { - let mut image = Image::new(context, "/cosmonaut.png")?; - image.set_filter(FilterMode::Nearest); - - Ok(Cosmonaut { - image, - destination: Point2 { x: 600.0, y: 200.0 }, - frame: CosmonautFrames::None, - timer: Instant::now(), - scale: Vector2 { - x: constants::TILE_SCALE * 2.0, - y: constants::TILE_SCALE * 2.0, - }, - }) - } - - pub fn draw(&self, context: &mut Context) -> GameResult { - graphics::draw( - context, - &self.image, - DrawParam::default() - .dest(self.destination) - .scale(self.scale) - .src(Rect::new(0.0, 0.0, 1.0 / 3.0, 1.0)), - )?; - let source = match self.frame { - CosmonautFrames::None => None, - CosmonautFrames::One => Some(Rect::new(1.0 / 3.0, 0.0, 1.0 / 3.0, 1.0 / 2.0)), - CosmonautFrames::Two => Some(Rect::new(2.0 / 3.0, 0.0, 1.0, 1.0 / 2.0)), - CosmonautFrames::Three => Some(Rect::new(1.0 / 3.0, 1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0)), - CosmonautFrames::Four => Some(Rect::new(2.0 / 3.0, 1.0 / 2.0, 1.0, 1.0)), - }; - if let Some(source) = source { - graphics::draw( - context, - &self.image, - DrawParam::default() - .dest(self.destination) - .src(source) - .scale(self.scale), - )?; - } - - Ok(()) - } - - pub fn update(&mut self) { - match self.frame { - CosmonautFrames::None => (), - _ => { - if self.timer.elapsed().as_millis() > 50 { - self.frame.next(); - self.timer = Instant::now(); - } - } - } - } - - pub fn start(&mut self) { - if let CosmonautFrames::None = self.frame { - if self.timer.elapsed().as_secs() > 5 { - self.timer = Instant::now(); - self.frame.next() - } - } - } - - pub fn contains(&self, position: Point2<f32>) -> bool { - position.x > self.destination.x - && position.y > self.destination.y - && position.x < self.destination.x + constants::TILE_WIDTH * constants::TILE_SCALE * 2.0 - && position.y < self.destination.y + constants::TILE_WIDTH * constants::TILE_SCALE * 2.0 - } -} diff --git a/src/game.rs b/src/game.rs deleted file mode 100644 index 5b72d9d..0000000 --- a/src/game.rs +++ /dev/null @@ -1,271 +0,0 @@ -use ggez::event::EventHandler; -use ggez::graphics::{self, spritebatch::SpriteBatch, DrawParam, FilterMode, Image, WrapMode}; -use ggez::input::mouse; -use ggez::mint::Point2; -use ggez::{Context, GameResult}; -use std::time::Instant; - -use crate::cell::{Cell, Occupant}; -use crate::constants; -use crate::cosmonaut::Cosmonaut; - -pub struct Game { - selected: Option<(usize, usize)>, - spritebatch: SpriteBatch, - grid: Vec<Vec<Cell>>, - background: Image, - cosmonaut: Cosmonaut, -} - -impl Game { - pub fn new(context: &mut Context) -> GameResult<Game> { - let mut background = Image::new(context, "/background.png")?; - background.set_filter(FilterMode::Nearest); - - let mut image = Image::new(context, "/tileset.png")?; - image.set_filter(FilterMode::Nearest); - image.set_wrap(WrapMode::Mirror, WrapMode::Mirror); - - let mut grid = Vec::new(); - let mut y = 0.0; - - for _ in 0..constants::COLUMNS { - let mut column = Vec::new(); - for j in 0..constants::ROWS { - column.push(Cell::new(Point2 { - x: (j as f32) - * (constants::TILE_WIDTH * constants::TILE_SCALE + constants::BORDER_SIZE) - + constants::SHIFT_X, - y: y + constants::SHIFT_Y, - })); - } - y += constants::TILE_HEIGHT * constants::TILE_SCALE + constants::BORDER_SIZE; - grid.push(column); - } - - Ok(Game { - grid, - selected: None, - cosmonaut: Cosmonaut::new(context)?, - spritebatch: SpriteBatch::new(image), - background, - }) - } - - fn update_explosions(&mut self) { - let mut last = Occupant::None; - let mut connected = Vec::new(); - for i in 0..constants::COLUMNS { - let mut c = Vec::new(); - for j in 0..constants::ROWS { - if self.grid[i][j].occupant == last && last != Occupant::None { - c.push((i, j)); - c.push((i, j - 1)); - } else { - connected.push(c.clone()); - c.clear(); - } - last = self.grid[i][j].occupant; - } - connected.push(c); - last = Occupant::None; - } - - for c in connected.iter() { - if c.len() > 3 { - for (i, j) in c.iter() { - self.grid[*i][*j].occupant = Occupant::Explosion { - frame: 0, - timer: Instant::now(), - }; - } - } - } - - connected.clear(); - for i in 0..constants::COLUMNS { - let mut c = Vec::new(); - for j in 0..constants::ROWS { - if self.grid[j][i].occupant == last && last != Occupant::None { - c.push((j, i)); - c.push((j - 1, i)); - } else { - connected.push(c.clone()); - c.clear(); - } - last = self.grid[j][i].occupant; - } - connected.push(c); - last = Occupant::None; - } - - for c in connected.iter() { - if c.len() > 3 { - for (j, i) in c.iter() { - self.grid[*j][*i].occupant = Occupant::Explosion { - frame: 0, - timer: Instant::now(), - }; - } - } - } - } - - fn update_dropping(&mut self) { - for i in 1..constants::COLUMNS { - for j in 0..constants::ROWS { - if self.grid[i][j].occupant == Occupant::None - && self.grid[i - 1][j].occupant != Occupant::None - { - self.grid[i][j].occupant = self.grid[i - 1][j].occupant; - self.grid[i - 1][j].occupant = Occupant::None; - } - } - } - } - - fn update_feeding(&mut self) { - for i in 0..constants::COLUMNS { - if self.grid[0][i].occupant == Occupant::None { - self.grid[0][i].occupant = rand::random(); - } - } - } - - fn update_frames(&mut self) { - for row in self.grid.iter_mut() { - for cell in row.iter_mut() { - let mut done = false; - if let Occupant::Explosion { - ref mut frame, - ref mut timer, - } = cell.occupant - { - if timer.elapsed().as_millis() > 500 { - if *frame < 4 { - *frame += 1; - *timer = Instant::now(); - } else { - done = true; - } - } - } - if done { - cell.occupant = Occupant::None; - } - } - } - } -} - -impl EventHandler for Game { - fn update(&mut self, context: &mut Context) -> GameResult { - for row in self.grid.iter_mut() { - for cell in row.iter_mut() { - cell.hover_off(); - } - } - - let position = mouse::position(context); - - if self.cosmonaut.contains(position) { - self.cosmonaut.start(); - } - - self.cosmonaut.update(); - - for row in self.grid.iter_mut() { - for cell in row.iter_mut() { - if cell.contains(position) { - cell.hover_on(); - } - } - } - - self.update_explosions(); - self.update_frames(); - self.update_dropping(); - self.update_feeding(); - - Ok(()) - } - - fn mouse_button_down_event( - &mut self, - _context: &mut Context, - button: mouse::MouseButton, - x: f32, - y: f32, - ) { - if button == mouse::MouseButton::Left { - let position = Point2 { x, y }; - for (i, row) in self.grid.iter_mut().enumerate() { - for (j, cell) in row.iter_mut().enumerate() { - if cell.contains(position) && cell.moveable() { - self.selected = Some((i, j)); - cell.clicked_on(); - } - } - } - } - } - - fn mouse_button_up_event( - &mut self, - _context: &mut 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, 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) - && cell.moveable() - && (((i + 1 == selected.0) && (j == selected.1)) - || ((i.overflowing_sub(1).0 == selected.0) && (j == selected.1)) - || ((i == selected.0) && (j + 1 == selected.1)) - || ((i == selected.0) && (j.overflowing_sub(1)).0 == selected.1)) - { - swap = Some((i, j)); - } - } - } - if let Some((i, j)) = swap { - let clone = self.grid[i][j].occupant; - 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 Context) -> GameResult { - graphics::clear(context, [0.0, 0.0, 0.0, 1.0].into()); - graphics::draw(context, &self.background, DrawParam::default())?; - self.cosmonaut.draw(context)?; - - for row in self.grid.iter() { - for cell in row.iter() { - cell.draw(context, &mut self.spritebatch)?; - } - } - - graphics::draw(context, &self.spritebatch, DrawParam::default())?; - - self.spritebatch.clear(); - - graphics::present(context)?; - Ok(()) - } -} @@ -1,4 +1 @@ -pub mod cell; pub mod constants; -pub mod cosmonaut; -pub mod game; diff --git a/src/main.rs b/src/main.rs index a1fee19..30df8fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,8 @@ -use ggez::event::{self}; -use ggez::{ContextBuilder, GameResult}; +use bevy::prelude::App; -use gems::game::Game; +struct Gem; +struct Position { x: f32, y: f32} -pub fn main() -> GameResult { - let (ref mut context, ref mut event_loop) = ContextBuilder::new("gems", "jw&tb") - .add_resource_path("./resources") - .build()?; - let game = &mut Game::new(context)?; - event::run(context, event_loop, game) +pub fn main() { + App::build().run(); } |