From d2c59a4d07efa3ec4418d7e82352a1cdf38e1518 Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Fri, 19 Mar 2021 19:21:11 +0100 Subject: branch trying out bevy --- src/cell.rs | 143 ----------------------------- src/cosmonaut.rs | 110 ---------------------- src/game.rs | 271 ------------------------------------------------------- src/lib.rs | 3 - src/main.rs | 14 +-- 5 files changed, 5 insertions(+), 536 deletions(-) delete mode 100644 src/cell.rs delete mode 100644 src/cosmonaut.rs delete mode 100644 src/game.rs (limited to 'src') 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 for Standard { - fn sample(&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, - hover: bool, - clicked: bool, -} - -impl Cell { - pub fn new(position: Point2) -> Cell { - Cell { - occupant: rand::random(), - position, - hover: false, - clicked: false, - } - } - - pub fn contains(&self, position: Point2) -> 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, - image: Image, - frame: CosmonautFrames, - timer: Instant, - scale: Vector2, -} - -impl Cosmonaut { - pub fn new(context: &mut Context) -> GameResult { - 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) -> 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>, - background: Image, - cosmonaut: Cosmonaut, -} - -impl Game { - pub fn new(context: &mut Context) -> GameResult { - 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(()) - } -} diff --git a/src/lib.rs b/src/lib.rs index 78bbb9a..0b6d2c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(); } -- cgit v1.2.3 From e131d553d2526edb7cffbe9f4ba48d9c6ae4e44f Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Sat, 20 Mar 2021 11:17:52 +0100 Subject: draw background --- src/main.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 30df8fb..c4e40f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,90 @@ -use bevy::prelude::App; +use bevy::math::Vec3; +use bevy::prelude::*; +use gems::constants; -struct Gem; -struct Position { x: f32, y: f32} +enum Occupant { + None, + Green, +} + +struct Cell { + x: u8, + y: u8, + occupant: Occupant, +} + +impl Cell { + pub fn new(x: u8, y: u8) -> Cell { + Cell { + x, + y, + occupant: Occupant::None, + } + } +} + +struct Position { + x: f32, + y: f32, +} + +pub fn add_cells(commands: &mut Commands) { + for i in 0..8 { + for j in 0..8 { + commands.spawn(( + Cell::new(i, j), + Position { + x: (i as f32 * constants::TILE_HEIGHT), + y: (j as f32 * constants::TILE_WIDTH), + }, + )); + } + } +} + +pub fn add_background( + commands: &mut Commands, + asset_server: Res, + mut materials: ResMut>, +) { + let texture_handle = asset_server.load("background.png"); + commands + .spawn(Camera2dBundle { + transform: Transform { + translation: Vec3{ + x: -40.0, + y: 0.0, + z: 0.0, + }, + scale: Vec3::splat(0.3), + ..Default::default() + }, + ..Default::default() + }) + .spawn(SpriteBundle { + material: materials.add(texture_handle.into()), + ..Default::default() + }); +} + +pub struct GemsPlugin; +impl Plugin for GemsPlugin { + fn build(&self, app: &mut AppBuilder) { + app.add_startup_system(add_background.system()); + app.add_startup_system(add_cells.system()); + } +} pub fn main() { - App::build().run(); + App::build() + .add_resource(WindowDescriptor { + title: "gems".to_string(), + width: 800.0, + height: 600.0, + resizable: false, + ..Default::default() + }) + .add_plugins(DefaultPlugins) + .add_plugin(GemsPlugin) + .run(); } -- cgit v1.2.3 From ec95776771d061c21af17686491181c78b7955c9 Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Sat, 20 Mar 2021 12:35:38 +0100 Subject: draw grid --- src/constants.rs | 2 +- src/main.rs | 89 ++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/constants.rs b/src/constants.rs index f9a5003..5952fa5 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,5 +1,5 @@ pub const TILE_SCALE: f32 = 3.0; -pub const TILE_HEIGHT: f32 = 16.0; +pub const TILE_SIZE: f32 = 16.0; pub const TILE_WIDTH: f32 = 16.0; pub const BORDER_SIZE: f32 = 3.0; pub const SHIFT_X: f32 = 50.0; diff --git a/src/main.rs b/src/main.rs index c4e40f9..acecaad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,55 +23,86 @@ impl Cell { } } -struct Position { - x: f32, - y: f32, -} - -pub fn add_cells(commands: &mut Commands) { - for i in 0..8 { - for j in 0..8 { - commands.spawn(( - Cell::new(i, j), - Position { - x: (i as f32 * constants::TILE_HEIGHT), - y: (j as f32 * constants::TILE_WIDTH), - }, - )); - } - } -} - -pub fn add_background( +pub fn setup( commands: &mut Commands, asset_server: Res, mut materials: ResMut>, + mut texture_atlases: ResMut>, ) { - let texture_handle = asset_server.load("background.png"); + let background = asset_server.load("background.png"); + let tileset = asset_server.load("tileset.png"); + + let atlas = TextureAtlas::from_grid(tileset, Vec2::new(16.0, 16.0), 4, 4); + let atlas_handle = texture_atlases.add(atlas); + commands - .spawn(Camera2dBundle { + .spawn(Camera2dBundle::default()) + .spawn(SpriteBundle { + material: materials.add(background.into()), transform: Transform { - translation: Vec3{ - x: -40.0, + translation: Vec3 { + x: 50.0, y: 0.0, z: 0.0, }, - scale: Vec3::splat(0.3), + scale: Vec3::splat(3.5), ..Default::default() }, ..Default::default() }) - .spawn(SpriteBundle { - material: materials.add(texture_handle.into()), + .spawn(SpriteSheetBundle { + sprite: TextureAtlasSprite::new(8), + texture_atlas: atlas_handle.clone(), + transform: Transform { + translation: Vec3 { + x: 225.0, + y: -200.0, + z: 0.0, + }, + scale: Vec3::splat(3.5), + ..Default::default() + }, + ..Default::default() + }) + .spawn(SpriteSheetBundle { + sprite: TextureAtlasSprite::new(12), + texture_atlas: atlas_handle.clone(), + transform: Transform { + translation: Vec3 { + x: 225.0, + y: -200.0 + (-16.0) * 3.5, + z: 0.0, + }, + scale: Vec3::splat(3.5), + ..Default::default() + }, ..Default::default() }); + + for i in 0..8 { + for j in 0..8 { + commands.spawn(SpriteSheetBundle { + sprite: TextureAtlasSprite::new(1), + texture_atlas: atlas_handle.clone(), + transform: Transform { + translation: Vec3 { + x: ((i as f32) * 16.0 * 3.5) - 320.0, + y: ((j as f32) * 16.0 * 3.5) - 170.0, + z: 0.0, + }, + scale: Vec3::splat(3.5), + ..Default::default() + }, + ..Default::default() + }); + } + } } pub struct GemsPlugin; impl Plugin for GemsPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_startup_system(add_background.system()); - app.add_startup_system(add_cells.system()); + app.add_startup_system(setup.system()); } } -- cgit v1.2.3 From baad8b54bdff624b648af7bcf977f14711ff59bc Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Sat, 20 Mar 2021 14:00:10 +0100 Subject: populate top row with new gems --- src/main.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index acecaad..f3d41b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,44 @@ use bevy::math::Vec3; use bevy::prelude::*; -use gems::constants; +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; +#[derive(Debug, PartialEq)] enum Occupant { None, Green, + Yellow, + Red, + Diamond, } +impl Occupant { + pub fn to_index(&self) -> u32 { + match self { + Occupant::Green => 0, + Occupant::Yellow => 1, + Occupant::Red => 2, + Occupant::Diamond => 3, + Occupant::None => 13, + } + } +} + +impl Distribution for Standard { + fn sample(&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(Debug)] struct Cell { x: u8, y: u8, @@ -23,6 +55,17 @@ impl Cell { } } +fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) { + for (mut cell, mut sprite) in cell_query.iter_mut() { + if cell.occupant == Occupant::None { + if cell.y == 7 { + cell.occupant = rand::random(); + sprite.index = cell.occupant.to_index(); + } + } + } +} + pub fn setup( commands: &mut Commands, asset_server: Res, @@ -81,20 +124,22 @@ pub fn setup( for i in 0..8 { for j in 0..8 { - commands.spawn(SpriteSheetBundle { - sprite: TextureAtlasSprite::new(1), - texture_atlas: atlas_handle.clone(), - transform: Transform { - translation: Vec3 { - x: ((i as f32) * 16.0 * 3.5) - 320.0, - y: ((j as f32) * 16.0 * 3.5) - 170.0, - z: 0.0, + commands + .spawn(SpriteSheetBundle { + texture_atlas: atlas_handle.clone(), + sprite: TextureAtlasSprite::new(11), + transform: Transform { + translation: Vec3 { + x: ((i as f32) * 16.0 * 3.5) - 320.0, + y: ((j as f32) * 16.0 * 3.5) - 160.0, + z: 0.0, + }, + scale: Vec3::splat(3.5), + ..Default::default() }, - scale: Vec3::splat(3.5), ..Default::default() - }, - ..Default::default() - }); + }) + .with(Cell::new(i, j)); } } } @@ -103,6 +148,7 @@ pub struct GemsPlugin; impl Plugin for GemsPlugin { fn build(&self, app: &mut AppBuilder) { app.add_startup_system(setup.system()); + app.add_system(cell_falling_system.system()); } } -- cgit v1.2.3 From 4fe231fcc252f19e3fa5e50d369571f1caf6ad33 Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Sat, 20 Mar 2021 15:35:18 +0100 Subject: gems now fall --- src/main.rs | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index f3d41b0..56f2ea9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use rand::{ Rng, }; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] enum Occupant { None, Green, @@ -38,7 +38,7 @@ impl Distribution for Standard { } } -#[derive(Debug)] +#[derive(Debug, Clone)] struct Cell { x: u8, y: u8, @@ -55,7 +55,7 @@ impl Cell { } } -fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) { +fn cell_insert_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) { for (mut cell, mut sprite) in cell_query.iter_mut() { if cell.occupant == Occupant::None { if cell.y == 7 { @@ -66,6 +66,36 @@ fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite } } +fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) { + let mut have_gems = Vec::new(); + for (cell, _sprite) in cell_query.iter_mut() { + if cell.occupant != Occupant::None { + have_gems.push(cell.clone()); + } + } + + let mut moved_gems = Vec::new(); + for (mut cell, mut sprite) in cell_query.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.occupant = c.occupant.clone(); + sprite.index = cell.occupant.to_index(); + moved_gems.push(c.clone()); + } + } + } + + for (mut cell, mut sprite) in cell_query.iter_mut() { + if moved_gems.iter().any(|c| (c.x, c.y) == (cell.x, cell.y)) { + cell.occupant = Occupant::None; + sprite.index = cell.occupant.to_index(); + } + } +} + pub fn setup( commands: &mut Commands, asset_server: Res, @@ -148,6 +178,7 @@ pub struct GemsPlugin; impl Plugin for GemsPlugin { fn build(&self, app: &mut AppBuilder) { app.add_startup_system(setup.system()); + app.add_system(cell_insert_system.system()); app.add_system(cell_falling_system.system()); } } -- cgit v1.2.3 From c657649cdc1a4159f2c76852b32fc563d1279509 Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Sat, 20 Mar 2021 16:11:32 +0100 Subject: added check system --- src/main.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 56f2ea9..c81203f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,25 @@ use bevy::math::Vec3; use bevy::prelude::*; +use gems::constants; use rand::{ distributions::{Distribution, Standard}, Rng, }; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] enum Occupant { None, Green, Yellow, Red, Diamond, + Explosion, +} + +impl Default for Occupant { + fn default() -> Occupant { + Occupant::None + } } impl Occupant { @@ -21,6 +29,7 @@ impl Occupant { Occupant::Yellow => 1, Occupant::Red => 2, Occupant::Diamond => 3, + Occupant::Explosion => 4, Occupant::None => 13, } } @@ -38,15 +47,15 @@ impl Distribution for Standard { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default, Copy)] struct Cell { - x: u8, - y: u8, + x: usize, + y: usize, occupant: Occupant, } impl Cell { - pub fn new(x: u8, y: u8) -> Cell { + pub fn new(x: usize, y: usize) -> Cell { Cell { x, y, @@ -57,10 +66,78 @@ impl Cell { fn cell_insert_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) { for (mut cell, mut sprite) in cell_query.iter_mut() { - if cell.occupant == Occupant::None { - if cell.y == 7 { - cell.occupant = rand::random(); - sprite.index = cell.occupant.to_index(); + if cell.occupant == Occupant::None && cell.y == constants::ROWS - 1 { + cell.occupant = rand::random(); + sprite.index = cell.occupant.to_index(); + } + } +} + +fn cell_check_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite)>) { + let mut cells = [[Cell::default(); constants::COLUMNS]; constants::ROWS]; + for (cell, _) in cell_query.iter_mut() { + cells[cell.x][cell.y] = *cell; + } + + let mut last = Occupant::None; + let mut connected = Vec::new(); + + for (i, _) in cells.iter().enumerate() { + let mut c = Vec::new(); + for j in 0..constants::ROWS { + if cells[i][j].occupant == last && last != Occupant::None { + 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; + } + + for c in connected.iter() { + if c.len() > 3 { + for (i, j) in c.iter() { + for (mut cell, mut sprite) in cell_query.iter_mut() { + if &cell.x == i && &cell.y == j { + cell.occupant = Occupant::Explosion; + sprite.index = cell.occupant.to_index(); + } + } + } + } + } + + connected.clear(); + + 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 { + 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; + } + + for c in connected.iter() { + if c.len() > 3 { + for (i, j) in c.iter() { + for (mut cell, mut sprite) in cell_query.iter_mut() { + if &cell.x == i && &cell.y == j { + cell.occupant = Occupant::Explosion; + sprite.index = cell.occupant.to_index(); + } + } } } } @@ -70,7 +147,7 @@ fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite let mut have_gems = Vec::new(); for (cell, _sprite) in cell_query.iter_mut() { if cell.occupant != Occupant::None { - have_gems.push(cell.clone()); + have_gems.push(*cell); } } @@ -81,9 +158,9 @@ fn cell_falling_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite .iter() .find(|&c| (c.x, c.y) == (cell.x, cell.y + 1)) { - cell.occupant = c.occupant.clone(); + cell.occupant = c.occupant; sprite.index = cell.occupant.to_index(); - moved_gems.push(c.clone()); + moved_gems.push(c); } } } @@ -152,8 +229,8 @@ pub fn setup( ..Default::default() }); - for i in 0..8 { - for j in 0..8 { + for i in 0..constants::COLUMNS { + for j in 0..constants::ROWS { commands .spawn(SpriteSheetBundle { texture_atlas: atlas_handle.clone(), @@ -180,6 +257,7 @@ impl Plugin for GemsPlugin { app.add_startup_system(setup.system()); app.add_system(cell_insert_system.system()); app.add_system(cell_falling_system.system()); + app.add_system(cell_check_system.system()); } } -- cgit v1.2.3 From c24bf56c3d69b826078307ddebb129a7be99ad97 Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Sat, 20 Mar 2021 17:22:49 +0100 Subject: explosion animation system --- src/main.rs | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index c81203f..4df4fa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,6 +73,36 @@ fn cell_insert_system(mut cell_query: Query<(&mut Cell, &mut TextureAtlasSprite) } } +fn explosion_animation_system( + time: Res