Fix panicking on wall kicks, add utility Grid struct

main
Elnu 3 years ago
parent 19990061b2
commit f7c560ae3e

@ -57,9 +57,7 @@ fn main() {
let mut block = random_block(); let mut block = random_block();
let mut next_block = random_block(); let mut next_block = random_block();
// Default::default() initializes all array cells to None (no block) let mut grid = Grid::new();
let mut grid: [[Option<&TileType>; GRID_WIDTH as usize]; GRID_HEIGHT as usize] =
Default::default();
let blocks_texture = Texture::from_file(&texture("blocks")).unwrap(); let blocks_texture = Texture::from_file(&texture("blocks")).unwrap();
let mut sprite = Sprite::with_texture(&blocks_texture); let mut sprite = Sprite::with_texture(&blocks_texture);
@ -271,7 +269,7 @@ fn main() {
// Check to see if new rotation state is overlapping any tiles // Check to see if new rotation state is overlapping any tiles
let mut offset_required: i32 = 0; let mut offset_required: i32 = 0;
for tile in block.get_tiles().iter() { for tile in block.get_tiles().iter() {
if grid[tile.y as usize][tile.x as usize].is_some() { if grid.get(tile.x, tile.y).is_some() {
// Can't wall kick off of blocks // Can't wall kick off of blocks
block.rotation_state -= 1; block.rotation_state -= 1;
break; break;
@ -306,9 +304,7 @@ fn main() {
} }
if movement != 0 { if movement != 0 {
for (i, tile) in block.get_tiles().iter().enumerate().rev() { for (i, tile) in block.get_tiles().iter().enumerate().rev() {
if tile.x + movement < 0 if grid.filled(tile.x + movement, tile.y)
|| tile.x + movement >= GRID_WIDTH as i32
|| grid[tile.y as usize][(tile.x + movement) as usize].is_some()
{ {
break; break;
} }
@ -334,7 +330,7 @@ fn main() {
'outer: loop { 'outer: loop {
for tile in block.get_tiles().iter() { for tile in block.get_tiles().iter() {
let y = tile.y + snap_offset; let y = tile.y + snap_offset;
if y >= GRID_HEIGHT as i32 || grid[y as usize][tile.x as usize].is_some() { if grid.filled(tile.x, y) {
snap_offset -= 1; snap_offset -= 1;
break 'outer; break 'outer;
} }
@ -352,7 +348,7 @@ fn main() {
// Land checking // Land checking
for tile in block.get_tiles().iter() { for tile in block.get_tiles().iter() {
if tile.y == GRID_HEIGHT as i32 - 1 if tile.y == GRID_HEIGHT as i32 - 1
|| grid[tile.y as usize + 1][tile.x as usize].is_some() || grid.filled(tile.x, tile.y + 1)
{ {
landed = true; landed = true;
break; break;
@ -411,13 +407,13 @@ fn main() {
tiles += block.get_tiles().len() as u32; tiles += block.get_tiles().len() as u32;
blocks += 1; blocks += 1;
for tile in block.get_tiles().iter() { for tile in block.get_tiles().iter() {
grid[tile.y as usize][tile.x as usize] = Some(&block.block_type.tile_type); grid.set(tile.x, tile.y, Some(&block.block_type.tile_type));
} }
let mut cleared_lines = 0; let mut cleared_lines = 0;
for y in 0..GRID_HEIGHT { for y in 0..GRID_HEIGHT {
let mut completed = true; let mut completed = true;
for x in 0..GRID_WIDTH { for x in 0..GRID_WIDTH {
if grid[y as usize][x as usize].is_none() { if !grid.filled(x as i32, y as i32) {
completed = false; completed = false;
break; break;
} }
@ -426,10 +422,10 @@ fn main() {
continue; continue;
} }
for z in (0..y).rev() { for z in (0..y).rev() {
let z = z as usize; let z = z as i32;
for x in 0..GRID_WIDTH { for x in 0..GRID_WIDTH {
let x = x as usize; let x = x as i32;
grid[z + 1][x] = grid[z][x]; grid.set(x, z + 1, grid.get(x, z));
} }
} }
cleared_lines += 1; cleared_lines += 1;
@ -466,12 +462,12 @@ fn main() {
row_clear_sound.play(); row_clear_sound.play();
} }
for tile in next_block.get_tiles().iter() { for tile in next_block.get_tiles().iter() {
if grid[tile.y as usize][tile.x as usize].is_some() { if grid.filled(tile.x, tile.y) {
score = 0; score = 0;
lines = 0; lines = 0;
blocks = 0; blocks = 0;
tiles = 0; tiles = 0;
grid = Default::default(); // reset grid grid.clear();
update_interval = get_update_interval(0); update_interval = get_update_interval(0);
game_over_sound.play(); game_over_sound.play();
next_block = random_block(); next_block = random_block();
@ -487,7 +483,7 @@ fn main() {
// Drawing grid // Drawing grid
for y in 0..GRID_HEIGHT { for y in 0..GRID_HEIGHT {
for x in 0..GRID_WIDTH { for x in 0..GRID_WIDTH {
let tile_type = grid[y as usize][x as usize]; let tile_type = grid.get(x as i32, y as i32);
if tile_type.is_none() { if tile_type.is_none() {
continue; continue;
} }

@ -0,0 +1,42 @@
use crate::config::*;
use crate::structs::TileType;
pub struct Grid<'a> {
grid: [[Option<&'a TileType>; GRID_WIDTH as usize]; GRID_HEIGHT as usize],
}
impl<'a> Grid<'a> {
pub fn new() -> Self {
Self {
grid: Default::default()
}
}
pub fn out_of_bounds(&self, x: i32, y: i32) -> bool {
x < 0 || x >= GRID_WIDTH as i32 || y < 0 || y >= GRID_HEIGHT as i32
}
pub fn get(&self, x: i32, y: i32) -> Option<&'a TileType> {
if self.out_of_bounds(x, y) {
None
} else {
self.grid[y as usize][x as usize]
}
}
// Checks if a coordinate is filled, either by a tile or out of bounds space
// For checking if there is a tile specifically, do .get(x, y).is_some()
pub fn filled(&self, x: i32, y: i32) -> bool {
self.out_of_bounds(x, y) || self.get(x, y).is_some()
}
pub fn set(&mut self, x: i32, y: i32, tile_type: Option<&'a TileType>) {
if !self.out_of_bounds(x, y) {
self.grid[y as usize][x as usize] = tile_type;
}
}
pub fn clear(&mut self) {
self.grid = Default::default();
}
}

@ -9,3 +9,6 @@ pub use tile_type::TileType;
mod number_renderer; mod number_renderer;
pub use number_renderer::NumberRenderer; pub use number_renderer::NumberRenderer;
mod grid;
pub use grid::Grid;

Loading…
Cancel
Save