cargo fmt
This commit is contained in:
parent
8b6387737c
commit
d55773cdc5
7 changed files with 340 additions and 333 deletions
164
src/main.rs
164
src/main.rs
|
@ -1,9 +1,9 @@
|
||||||
use sfml::graphics::*;
|
|
||||||
use sfml::window::*;
|
|
||||||
use sfml::system::*;
|
|
||||||
use sfml::audio::*;
|
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
use gcd::Gcd;
|
use gcd::Gcd;
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
use sfml::audio::*;
|
||||||
|
use sfml::graphics::*;
|
||||||
|
use sfml::system::*;
|
||||||
|
use sfml::window::*;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
mod structs;
|
mod structs;
|
||||||
|
@ -35,14 +35,17 @@ fn main() {
|
||||||
VideoMode::new(WINDOW_WIDTH, WINDOW_HEIGHT, 16),
|
VideoMode::new(WINDOW_WIDTH, WINDOW_HEIGHT, 16),
|
||||||
"septadrop",
|
"septadrop",
|
||||||
Style::TITLEBAR | Style::CLOSE,
|
Style::TITLEBAR | Style::CLOSE,
|
||||||
&context_settings
|
&context_settings,
|
||||||
);
|
);
|
||||||
window.set_framerate_limit(FPS);
|
window.set_framerate_limit(FPS);
|
||||||
window.set_key_repeat_enabled(false);
|
window.set_key_repeat_enabled(false);
|
||||||
|
|
||||||
let icon = Image::from_file(&texture("icon")).unwrap();
|
let icon = Image::from_file(&texture("icon")).unwrap();
|
||||||
{
|
{
|
||||||
let Vector2u { x: width, y: height } = icon.size();
|
let Vector2u {
|
||||||
|
x: width,
|
||||||
|
y: height,
|
||||||
|
} = icon.size();
|
||||||
window.set_icon(width, height, icon.pixel_data());
|
window.set_icon(width, height, icon.pixel_data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +58,8 @@ fn main() {
|
||||||
let mut next_block = random_block();
|
let mut next_block = random_block();
|
||||||
|
|
||||||
// Default::default() initializes all array cells to None (no block)
|
// Default::default() initializes all array cells to None (no block)
|
||||||
let mut grid: [[Option<&TileType>; GRID_WIDTH as usize]; GRID_HEIGHT as usize] = Default::default();
|
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);
|
||||||
|
@ -73,8 +77,10 @@ fn main() {
|
||||||
let mut paused_text = Sprite::with_texture(&paused_texture);
|
let mut paused_text = Sprite::with_texture(&paused_texture);
|
||||||
let paused_texture_size = paused_texture.size();
|
let paused_texture_size = paused_texture.size();
|
||||||
paused_text.set_position(Vector2f::new(
|
paused_text.set_position(Vector2f::new(
|
||||||
PLAYFIELD_X as f32 + (GRID_WIDTH as f32 * TILE_SIZE as f32 / 2.0) - paused_texture_size.x as f32 / 2.0,
|
PLAYFIELD_X as f32 + (GRID_WIDTH as f32 * TILE_SIZE as f32 / 2.0)
|
||||||
PLAYFIELD_Y as f32 + (GRID_HEIGHT as f32 * TILE_SIZE as f32 / 2.0) - paused_texture_size.y as f32 / 2.0
|
- paused_texture_size.x as f32 / 2.0,
|
||||||
|
PLAYFIELD_Y as f32 + (GRID_HEIGHT as f32 * TILE_SIZE as f32 / 2.0)
|
||||||
|
- paused_texture_size.y as f32 / 2.0,
|
||||||
));
|
));
|
||||||
paused_text
|
paused_text
|
||||||
};
|
};
|
||||||
|
@ -84,7 +90,11 @@ fn main() {
|
||||||
let mut highscore: u32;
|
let mut highscore: u32;
|
||||||
|
|
||||||
if highscore_file_path.exists() {
|
if highscore_file_path.exists() {
|
||||||
highscore = std::fs::read_to_string(&highscore_file_path).unwrap().trim().parse::<u32>().unwrap();
|
highscore = std::fs::read_to_string(&highscore_file_path)
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.parse::<u32>()
|
||||||
|
.unwrap();
|
||||||
let point_gcd = POINTS_1_LINE
|
let point_gcd = POINTS_1_LINE
|
||||||
.gcd(POINTS_2_LINES)
|
.gcd(POINTS_2_LINES)
|
||||||
.gcd(POINTS_3_LINES)
|
.gcd(POINTS_3_LINES)
|
||||||
|
@ -152,48 +162,56 @@ fn main() {
|
||||||
Event::Closed => {
|
Event::Closed => {
|
||||||
window.close();
|
window.close();
|
||||||
break;
|
break;
|
||||||
},
|
}
|
||||||
Event::GainedFocus => {
|
Event::GainedFocus => {
|
||||||
if paused && paused_from_lost_focus {
|
if paused && paused_from_lost_focus {
|
||||||
toggle_pause = true;
|
toggle_pause = true;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Event::LostFocus => {
|
Event::LostFocus => {
|
||||||
if !paused {
|
if !paused {
|
||||||
toggle_pause = true;
|
toggle_pause = true;
|
||||||
paused_from_lost_focus = true;
|
paused_from_lost_focus = true;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Event::KeyPressed { code, alt: _, ctrl: _, shift: _, system: _ } => {
|
|
||||||
match code {
|
|
||||||
Key::ESCAPE => toggle_pause = true,
|
|
||||||
Key::SPACE => snap = !paused,
|
|
||||||
Key::UP => rotate = !paused,
|
|
||||||
Key::DOWN => fast_forward = !paused,
|
|
||||||
Key::LEFT => {
|
|
||||||
move_left = !paused;
|
|
||||||
move_left_immediate = !paused;
|
|
||||||
move_clock.restart();
|
|
||||||
},
|
|
||||||
Key::RIGHT => {
|
|
||||||
move_right = !paused;
|
|
||||||
move_right_immediate = !paused;
|
|
||||||
move_clock.restart();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::KeyReleased { code, alt: _, ctrl: _, shift: _, system: _ } => {
|
|
||||||
match code {
|
|
||||||
Key::DOWN => fast_forward = false,
|
|
||||||
Key::LEFT => move_left = false,
|
|
||||||
Key::RIGHT => move_right = false,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {},
|
Event::KeyPressed {
|
||||||
|
code,
|
||||||
|
alt: _,
|
||||||
|
ctrl: _,
|
||||||
|
shift: _,
|
||||||
|
system: _,
|
||||||
|
} => match code {
|
||||||
|
Key::ESCAPE => toggle_pause = true,
|
||||||
|
Key::SPACE => snap = !paused,
|
||||||
|
Key::UP => rotate = !paused,
|
||||||
|
Key::DOWN => fast_forward = !paused,
|
||||||
|
Key::LEFT => {
|
||||||
|
move_left = !paused;
|
||||||
|
move_left_immediate = !paused;
|
||||||
|
move_clock.restart();
|
||||||
|
}
|
||||||
|
Key::RIGHT => {
|
||||||
|
move_right = !paused;
|
||||||
|
move_right_immediate = !paused;
|
||||||
|
move_clock.restart();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Event::KeyReleased {
|
||||||
|
code,
|
||||||
|
alt: _,
|
||||||
|
ctrl: _,
|
||||||
|
shift: _,
|
||||||
|
system: _,
|
||||||
|
} => match code {
|
||||||
|
Key::DOWN => fast_forward = false,
|
||||||
|
Key::LEFT => move_left = false,
|
||||||
|
Key::RIGHT => move_right = false,
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
},
|
},
|
||||||
None => break
|
None => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,23 +219,17 @@ fn main() {
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
if paused {
|
if paused {
|
||||||
pause_clock.restart();
|
pause_clock.restart();
|
||||||
paused_clear.set_position(Vector2f::new(
|
paused_clear.set_position(Vector2f::new(PLAYFIELD_X as f32, PLAYFIELD_Y as f32));
|
||||||
PLAYFIELD_X as f32,
|
|
||||||
PLAYFIELD_Y as f32
|
|
||||||
));
|
|
||||||
paused_clear.set_size(Vector2f::new(
|
paused_clear.set_size(Vector2f::new(
|
||||||
(GRID_WIDTH * TILE_SIZE) as f32,
|
(GRID_WIDTH * TILE_SIZE) as f32,
|
||||||
(GRID_HEIGHT * TILE_SIZE) as f32
|
(GRID_HEIGHT * TILE_SIZE) as f32,
|
||||||
));
|
));
|
||||||
window.draw(&paused_clear);
|
window.draw(&paused_clear);
|
||||||
let size = Vector2f::new(
|
let size = Vector2f::new(
|
||||||
(NEXT_WIDTH * TILE_SIZE) as f32,
|
(NEXT_WIDTH * TILE_SIZE) as f32,
|
||||||
(NEXT_HEIGHT * TILE_SIZE) as f32
|
(NEXT_HEIGHT * TILE_SIZE) as f32,
|
||||||
);
|
);
|
||||||
paused_clear.set_position(Vector2f::new(
|
paused_clear.set_position(Vector2f::new(NEXT_X as f32, NEXT_Y as f32) - size / 2.0);
|
||||||
NEXT_X as f32,
|
|
||||||
NEXT_Y as f32
|
|
||||||
) - size / 2.0);
|
|
||||||
paused_clear.set_size(size);
|
paused_clear.set_size(size);
|
||||||
window.draw(&paused_clear);
|
window.draw(&paused_clear);
|
||||||
window.draw(&paused_text);
|
window.draw(&paused_text);
|
||||||
|
@ -235,9 +247,8 @@ fn main() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_update_frame =
|
let is_update_frame = update_clock.elapsed_time().as_milliseconds() - pause_offset as i32
|
||||||
update_clock.elapsed_time().as_milliseconds() - pause_offset as i32 >
|
> if fast_forward {
|
||||||
if fast_forward {
|
|
||||||
std::cmp::min(update_interval, MAX_FAST_FORWARD_INTERVAL)
|
std::cmp::min(update_interval, MAX_FAST_FORWARD_INTERVAL)
|
||||||
} else {
|
} else {
|
||||||
update_interval
|
update_interval
|
||||||
|
@ -246,9 +257,8 @@ fn main() {
|
||||||
update_clock.restart();
|
update_clock.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_move_frame =
|
let is_move_frame = move_clock.elapsed_time().as_milliseconds() - pause_offset as i32
|
||||||
move_clock.elapsed_time().as_milliseconds() - pause_offset as i32 >
|
> MOVE_FRAME_INTERVAL as i32;
|
||||||
MOVE_FRAME_INTERVAL as i32;
|
|
||||||
if is_move_frame {
|
if is_move_frame {
|
||||||
move_clock.restart();
|
move_clock.restart();
|
||||||
}
|
}
|
||||||
|
@ -296,7 +306,10 @@ 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 || tile.x + movement >= GRID_WIDTH as i32 || grid[tile.y as usize][(tile.x + movement) as usize].is_some() {
|
if tile.x + movement < 0
|
||||||
|
|| tile.x + movement >= GRID_WIDTH as i32
|
||||||
|
|| grid[tile.y as usize][(tile.x + movement) as usize].is_some()
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
@ -335,9 +348,12 @@ fn main() {
|
||||||
block.position.y += snap_offset;
|
block.position.y += snap_offset;
|
||||||
snap = false;
|
snap = false;
|
||||||
snap_sound.play();
|
snap_sound.play();
|
||||||
} else if is_update_frame { // Land checking
|
} else if is_update_frame {
|
||||||
|
// Land checking
|
||||||
for tile in block.get_tiles().iter() {
|
for tile in block.get_tiles().iter() {
|
||||||
if tile.y == GRID_HEIGHT as i32 - 1 || grid[tile.y as usize + 1][tile.x as usize].is_some() {
|
if tile.y == GRID_HEIGHT as i32 - 1
|
||||||
|
|| grid[tile.y as usize + 1][tile.x as usize].is_some()
|
||||||
|
{
|
||||||
landed = true;
|
landed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -345,10 +361,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
let landed = landed; // remove mutability
|
let landed = landed; // remove mutability
|
||||||
|
|
||||||
// Clear window
|
// Clear window
|
||||||
// Normally, one would run window.clear(),
|
// Normally, one would run window.clear(),
|
||||||
// but the background image covers the entire window.
|
// but the background image covers the entire window.
|
||||||
window.draw(&background);
|
window.draw(&background);
|
||||||
|
|
||||||
// Draw block
|
// Draw block
|
||||||
if !landed {
|
if !landed {
|
||||||
|
@ -357,13 +373,13 @@ fn main() {
|
||||||
sprite.set_texture_rect(&block.block_type.tile_type.texture_rect);
|
sprite.set_texture_rect(&block.block_type.tile_type.texture_rect);
|
||||||
sprite.set_position(Vector2f::new(
|
sprite.set_position(Vector2f::new(
|
||||||
(PLAYFIELD_X as i32 + tile.x * TILE_SIZE as i32) as f32,
|
(PLAYFIELD_X as i32 + tile.x * TILE_SIZE as i32) as f32,
|
||||||
(PLAYFIELD_Y as i32 + tile.y * TILE_SIZE as i32) as f32
|
(PLAYFIELD_Y as i32 + tile.y * TILE_SIZE as i32) as f32,
|
||||||
));
|
));
|
||||||
window.draw(&sprite);
|
window.draw(&sprite);
|
||||||
sprite.set_texture_rect(&block.block_type.tile_type.ghost_texture_rect);
|
sprite.set_texture_rect(&block.block_type.tile_type.ghost_texture_rect);
|
||||||
sprite.set_position(Vector2f::new(
|
sprite.set_position(Vector2f::new(
|
||||||
(PLAYFIELD_X as i32 + tile.x * TILE_SIZE as i32) as f32,
|
(PLAYFIELD_X as i32 + tile.x * TILE_SIZE as i32) as f32,
|
||||||
(PLAYFIELD_Y as i32 + snap_y * TILE_SIZE as i32) as f32
|
(PLAYFIELD_Y as i32 + snap_y * TILE_SIZE as i32) as f32,
|
||||||
));
|
));
|
||||||
window.draw(&sprite);
|
window.draw(&sprite);
|
||||||
}
|
}
|
||||||
|
@ -375,12 +391,16 @@ fn main() {
|
||||||
// This is assuming the next block spawns unrotated.
|
// This is assuming the next block spawns unrotated.
|
||||||
// Refactoring is needed if random rotations are added
|
// Refactoring is needed if random rotations are added
|
||||||
let x_offset = next_block.block_type.width * TILE_SIZE / 2;
|
let x_offset = next_block.block_type.width * TILE_SIZE / 2;
|
||||||
let y_offset = (next_block.block_type.height + next_block.block_type.starting_line * 2) * TILE_SIZE / 2;
|
let y_offset = (next_block.block_type.height + next_block.block_type.starting_line * 2)
|
||||||
|
* TILE_SIZE
|
||||||
|
/ 2;
|
||||||
for tile in next_block_tiles.iter() {
|
for tile in next_block_tiles.iter() {
|
||||||
sprite.set_texture_rect(&next_block.block_type.tile_type.texture_rect);
|
sprite.set_texture_rect(&next_block.block_type.tile_type.texture_rect);
|
||||||
sprite.set_position(Vector2f::new(
|
sprite.set_position(Vector2f::new(
|
||||||
(NEXT_X + (tile.x - next_block.position.x) as u32 * TILE_SIZE - x_offset) as f32,
|
(NEXT_X + (tile.x - next_block.position.x) as u32 * TILE_SIZE - x_offset)
|
||||||
(NEXT_Y + (tile.y - next_block.position.y) as u32 * TILE_SIZE - y_offset) as f32
|
as f32,
|
||||||
|
(NEXT_Y + (tile.y - next_block.position.y) as u32 * TILE_SIZE - y_offset)
|
||||||
|
as f32,
|
||||||
));
|
));
|
||||||
window.draw(&sprite);
|
window.draw(&sprite);
|
||||||
}
|
}
|
||||||
|
@ -419,7 +439,7 @@ fn main() {
|
||||||
1 => POINTS_1_LINE,
|
1 => POINTS_1_LINE,
|
||||||
2 => POINTS_2_LINES,
|
2 => POINTS_2_LINES,
|
||||||
3 => POINTS_3_LINES,
|
3 => POINTS_3_LINES,
|
||||||
_ => POINTS_4_LINES
|
_ => POINTS_4_LINES,
|
||||||
};
|
};
|
||||||
if scored > 0 {
|
if scored > 0 {
|
||||||
let level = get_level(lines);
|
let level = get_level(lines);
|
||||||
|
@ -475,7 +495,7 @@ fn main() {
|
||||||
sprite.set_texture_rect(&tile_type.texture_rect);
|
sprite.set_texture_rect(&tile_type.texture_rect);
|
||||||
sprite.set_position(Vector2f::new(
|
sprite.set_position(Vector2f::new(
|
||||||
(PLAYFIELD_X + x * TILE_SIZE) as f32,
|
(PLAYFIELD_X + x * TILE_SIZE) as f32,
|
||||||
(PLAYFIELD_Y + y * TILE_SIZE) as f32
|
(PLAYFIELD_Y + y * TILE_SIZE) as f32,
|
||||||
));
|
));
|
||||||
window.draw(&sprite);
|
window.draw(&sprite);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +1,61 @@
|
||||||
use crate::structs::BlockType;
|
|
||||||
use crate::config::GRID_WIDTH;
|
use crate::config::GRID_WIDTH;
|
||||||
|
use crate::structs::BlockType;
|
||||||
use sfml::system::Vector2i;
|
use sfml::system::Vector2i;
|
||||||
|
|
||||||
pub struct Block<'a> {
|
pub struct Block<'a> {
|
||||||
pub block_type: &'a BlockType,
|
pub block_type: &'a BlockType,
|
||||||
pub position: Vector2i,
|
pub position: Vector2i,
|
||||||
pub rotation_state: i32
|
pub rotation_state: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Block<'a> {
|
impl<'a> Block<'a> {
|
||||||
pub fn new(block_type: &'a BlockType, ) -> Self {
|
pub fn new(block_type: &'a BlockType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
block_type,
|
block_type,
|
||||||
position: Vector2i::new(
|
position: Vector2i::new(
|
||||||
GRID_WIDTH as i32 / 2 - block_type.grid[0].len() as i32 / 2,
|
GRID_WIDTH as i32 / 2 - block_type.grid[0].len() as i32 / 2,
|
||||||
0
|
0,
|
||||||
),
|
),
|
||||||
rotation_state: 0
|
rotation_state: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tiles(&mut self) -> Vec<Vector2i> {
|
pub fn get_tiles(&mut self) -> Vec<Vector2i> {
|
||||||
let mut tiles: Vec<Vector2i> = Vec::new();
|
let mut tiles: Vec<Vector2i> = Vec::new();
|
||||||
for (y, row) in self.block_type.grid.iter().enumerate() {
|
for (y, row) in self.block_type.grid.iter().enumerate() {
|
||||||
let y = y as i32;
|
let y = y as i32;
|
||||||
for (x, cell) in row.iter().enumerate() {
|
for (x, cell) in row.iter().enumerate() {
|
||||||
let x = x as i32;
|
let x = x as i32;
|
||||||
if !cell {
|
if !cell {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut rotated = Vector2i::new(x as i32, y as i32);
|
let mut rotated = Vector2i::new(x as i32, y as i32);
|
||||||
if self.block_type.rotate {
|
if self.block_type.rotate {
|
||||||
let center_x = row.len() as i32 / 2;
|
let center_x = row.len() as i32 / 2;
|
||||||
let center_y = self.block_type.grid.len() as i32 / 2;
|
let center_y = self.block_type.grid.len() as i32 / 2;
|
||||||
let offset_x = x - center_x;
|
let offset_x = x - center_x;
|
||||||
let offset_y = y - center_y;
|
let offset_y = y - center_y;
|
||||||
match self.rotation_state {
|
match self.rotation_state {
|
||||||
0 => {},
|
0 => {}
|
||||||
1 => {
|
1 => {
|
||||||
rotated.x = center_x + offset_y;
|
rotated.x = center_x + offset_y;
|
||||||
rotated.y = center_y - offset_x;
|
rotated.y = center_y - offset_x;
|
||||||
},
|
}
|
||||||
2 => {
|
2 => {
|
||||||
rotated.x = center_x - offset_x;
|
rotated.x = center_x - offset_x;
|
||||||
rotated.y = center_y - offset_y;
|
rotated.y = center_y - offset_y;
|
||||||
},
|
}
|
||||||
3 => {
|
3 => {
|
||||||
rotated.x = center_x - offset_y;
|
rotated.x = center_x - offset_y;
|
||||||
rotated.y = center_y + offset_x;
|
rotated.y = center_y + offset_x;
|
||||||
}
|
}
|
||||||
_ => self.rotation_state %= 4
|
_ => self.rotation_state %= 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let global = self.position + rotated;
|
let global = self.position + rotated;
|
||||||
tiles.push(global);
|
tiles.push(global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tiles
|
tiles
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,151 +1,128 @@
|
||||||
use crate::structs::TileType;
|
|
||||||
use crate::config::TILE_SIZE;
|
use crate::config::TILE_SIZE;
|
||||||
|
use crate::structs::TileType;
|
||||||
use sfml::graphics::IntRect;
|
use sfml::graphics::IntRect;
|
||||||
|
|
||||||
pub struct BlockType {
|
pub struct BlockType {
|
||||||
pub tile_type: TileType,
|
pub tile_type: TileType,
|
||||||
pub grid: Vec<Vec<bool>>,
|
pub grid: Vec<Vec<bool>>,
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
pub starting_line: u32,
|
pub starting_line: u32,
|
||||||
pub rotate: bool
|
pub rotate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockType {
|
impl BlockType {
|
||||||
pub fn new(tile_type: TileType, grid: Vec<Vec<bool>>, rotate: bool) -> Self {
|
pub fn new(tile_type: TileType, grid: Vec<Vec<bool>>, rotate: bool) -> Self {
|
||||||
let mut width: u32 = 0;
|
let mut width: u32 = 0;
|
||||||
let mut height: u32 = 0;
|
let mut height: u32 = 0;
|
||||||
let mut starting_line: u32 = 0;
|
let mut starting_line: u32 = 0;
|
||||||
for (y, row) in grid.iter().enumerate() {
|
for (y, row) in grid.iter().enumerate() {
|
||||||
let mut has_content = false;
|
let mut has_content = false;
|
||||||
for (x, cell) in row.iter().enumerate() {
|
for (x, cell) in row.iter().enumerate() {
|
||||||
if *cell {
|
if *cell {
|
||||||
width = std::cmp::max(width, x as u32 + 1);
|
width = std::cmp::max(width, x as u32 + 1);
|
||||||
has_content = true;
|
has_content = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if has_content {
|
if has_content {
|
||||||
if height == 0 {
|
if height == 0 {
|
||||||
starting_line = y as u32;
|
starting_line = y as u32;
|
||||||
}
|
}
|
||||||
height = y as u32 + 1 - starting_line;
|
height = y as u32 + 1 - starting_line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
tile_type,
|
tile_type,
|
||||||
grid,
|
grid,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
starting_line,
|
starting_line,
|
||||||
rotate
|
rotate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_list() -> Vec<Self> {
|
pub fn init_list() -> Vec<Self> {
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
let tile_size = TILE_SIZE as i32;
|
let tile_size = TILE_SIZE as i32;
|
||||||
|
|
||||||
const Y: bool = true;
|
const Y: bool = true;
|
||||||
const N: bool = false;
|
const N: bool = false;
|
||||||
|
|
||||||
// I block
|
// I block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(0, 0, tile_size, tile_size),
|
IntRect::new(0, 0, tile_size, tile_size),
|
||||||
IntRect::new(0, tile_size, tile_size, tile_size)
|
IntRect::new(0, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![
|
||||||
vec![N, N, N, N],
|
vec![N, N, N, N],
|
||||||
vec![Y, Y, Y, Y],
|
vec![Y, Y, Y, Y],
|
||||||
vec![N, N, N, N],
|
vec![N, N, N, N],
|
||||||
vec![N, N, N, N]
|
vec![N, N, N, N],
|
||||||
],
|
],
|
||||||
true
|
true,
|
||||||
));
|
));
|
||||||
|
|
||||||
// J Block
|
// J Block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(tile_size, 0, tile_size, tile_size),
|
IntRect::new(tile_size, 0, tile_size, tile_size),
|
||||||
IntRect::new(tile_size, tile_size, tile_size, tile_size),
|
IntRect::new(tile_size, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![vec![Y, N, N], vec![Y, Y, Y], vec![N, N, N]],
|
||||||
vec![Y, N, N],
|
true,
|
||||||
vec![Y, Y, Y],
|
));
|
||||||
vec![N, N, N]
|
|
||||||
],
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
// L Block
|
// L Block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(tile_size * 2, 0, tile_size, tile_size),
|
IntRect::new(tile_size * 2, 0, tile_size, tile_size),
|
||||||
IntRect::new(tile_size * 2, tile_size, tile_size, tile_size),
|
IntRect::new(tile_size * 2, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![vec![N, N, Y], vec![Y, Y, Y], vec![N, N, N]],
|
||||||
vec![N, N, Y],
|
true,
|
||||||
vec![Y, Y, Y],
|
));
|
||||||
vec![N, N, N]
|
|
||||||
],
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
// O Block
|
// O Block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(tile_size * 3, 0, tile_size, tile_size),
|
IntRect::new(tile_size * 3, 0, tile_size, tile_size),
|
||||||
IntRect::new(tile_size * 3, tile_size, tile_size, tile_size),
|
IntRect::new(tile_size * 3, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![vec![Y, Y], vec![Y, Y]],
|
||||||
vec![Y, Y],
|
false,
|
||||||
vec![Y, Y]
|
));
|
||||||
],
|
|
||||||
false
|
|
||||||
));
|
|
||||||
|
|
||||||
// S Block
|
// S Block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(tile_size * 4, 0, tile_size, tile_size),
|
IntRect::new(tile_size * 4, 0, tile_size, tile_size),
|
||||||
IntRect::new(tile_size * 4, tile_size, tile_size, tile_size),
|
IntRect::new(tile_size * 4, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![vec![N, Y, Y], vec![Y, Y, N], vec![N, N, N]],
|
||||||
vec![N, Y, Y],
|
true,
|
||||||
vec![Y, Y, N],
|
));
|
||||||
vec![N, N, N]
|
|
||||||
],
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
// T Block
|
// T Block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(tile_size * 5, 0, tile_size, tile_size),
|
IntRect::new(tile_size * 5, 0, tile_size, tile_size),
|
||||||
IntRect::new(tile_size * 5, tile_size, tile_size, tile_size),
|
IntRect::new(tile_size * 5, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![vec![N, Y, N], vec![Y, Y, Y], vec![N, N, N]],
|
||||||
vec![N, Y, N],
|
true,
|
||||||
vec![Y, Y, Y],
|
));
|
||||||
vec![N, N, N]
|
|
||||||
],
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
// Z Block
|
// Z Block
|
||||||
list.push(Self::new(
|
list.push(Self::new(
|
||||||
TileType::new(
|
TileType::new(
|
||||||
IntRect::new(tile_size * 6, 0, tile_size, tile_size),
|
IntRect::new(tile_size * 6, 0, tile_size, tile_size),
|
||||||
IntRect::new(tile_size * 6, tile_size, tile_size, tile_size)
|
IntRect::new(tile_size * 6, tile_size, tile_size, tile_size),
|
||||||
),
|
),
|
||||||
vec![
|
vec![vec![Y, Y, N], vec![N, Y, Y], vec![N, N, N]],
|
||||||
vec![Y, Y, N],
|
true,
|
||||||
vec![N, Y, Y],
|
));
|
||||||
vec![N, N, N]
|
|
||||||
],
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,74 +3,84 @@ use sfml::system::Vector2f;
|
||||||
use sfml::SfBox;
|
use sfml::SfBox;
|
||||||
|
|
||||||
pub struct NumberRenderer {
|
pub struct NumberRenderer {
|
||||||
texture: SfBox<Texture>,
|
texture: SfBox<Texture>,
|
||||||
comma_rect: IntRect,
|
comma_rect: IntRect,
|
||||||
numeral_rects: [IntRect; 10],
|
numeral_rects: [IntRect; 10],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumberRenderer {
|
impl NumberRenderer {
|
||||||
pub fn new(texture: SfBox<Texture>, comma_rect: IntRect, numeral_rects: [IntRect; 10]) -> Self {
|
pub fn new(texture: SfBox<Texture>, comma_rect: IntRect, numeral_rects: [IntRect; 10]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
texture,
|
texture,
|
||||||
comma_rect,
|
comma_rect,
|
||||||
numeral_rects
|
numeral_rects,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default() -> Self {
|
pub fn default() -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
Texture::from_file(&crate::texture("numerals")).unwrap(),
|
Texture::from_file(&crate::texture("numerals")).unwrap(),
|
||||||
IntRect::new(134, 0, 10, 16),
|
IntRect::new(134, 0, 10, 16),
|
||||||
[
|
[
|
||||||
IntRect::new(0, 0, 14, 16),
|
IntRect::new(0, 0, 14, 16),
|
||||||
IntRect::new(14, 0, 8, 16),
|
IntRect::new(14, 0, 8, 16),
|
||||||
IntRect::new(22, 0, 14, 16),
|
IntRect::new(22, 0, 14, 16),
|
||||||
IntRect::new(36, 0, 14, 16),
|
IntRect::new(36, 0, 14, 16),
|
||||||
IntRect::new(50, 0, 14, 16),
|
IntRect::new(50, 0, 14, 16),
|
||||||
IntRect::new(64, 0, 14, 16),
|
IntRect::new(64, 0, 14, 16),
|
||||||
IntRect::new(78, 0, 14, 16),
|
IntRect::new(78, 0, 14, 16),
|
||||||
IntRect::new(92, 0, 14, 16),
|
IntRect::new(92, 0, 14, 16),
|
||||||
IntRect::new(106, 0, 14, 16),
|
IntRect::new(106, 0, 14, 16),
|
||||||
IntRect::new(120, 0, 14, 16)
|
IntRect::new(120, 0, 14, 16),
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, window: &mut RenderWindow, number: u32, x: u32, y: u32) {
|
pub fn render(&self, window: &mut RenderWindow, number: u32, x: u32, y: u32) {
|
||||||
let number_string = number.to_string();
|
let number_string = number.to_string();
|
||||||
let get_numeral_rect = |numeral: char| self.numeral_rects[numeral.to_digit(10).unwrap() as usize];
|
let get_numeral_rect =
|
||||||
let mut numeral_position = Vector2f::new({
|
|numeral: char| self.numeral_rects[numeral.to_digit(10).unwrap() as usize];
|
||||||
let numeral = number_string.chars().last().unwrap();
|
let mut numeral_position = Vector2f::new(
|
||||||
let numeral_rect = get_numeral_rect(numeral);
|
{
|
||||||
x as f32 - numeral_rect.width as f32
|
let numeral = number_string.chars().last().unwrap();
|
||||||
}, y as f32);
|
let numeral_rect = get_numeral_rect(numeral);
|
||||||
let digits = number_string.len();
|
x as f32 - numeral_rect.width as f32
|
||||||
let mut sprite = Sprite::new();
|
},
|
||||||
sprite.set_texture(&self.texture, false);
|
y as f32,
|
||||||
// can't reverse .chars() directly since it doesn't implement std::iter::DoubleEndedIterator
|
);
|
||||||
// Instead, we must collect it to a Vec then iterate over that.
|
let digits = number_string.len();
|
||||||
// For more info, see https://users.rust-lang.org/t/43401/2
|
let mut sprite = Sprite::new();
|
||||||
for (i, numeral) in number_string.chars().collect::<Vec<char>>().iter().enumerate().rev() {
|
sprite.set_texture(&self.texture, false);
|
||||||
let numeral_rect = get_numeral_rect(*numeral);
|
// can't reverse .chars() directly since it doesn't implement std::iter::DoubleEndedIterator
|
||||||
if (digits - i) % 3 == 1 && i != digits - 1 {
|
// Instead, we must collect it to a Vec then iterate over that.
|
||||||
sprite.set_texture_rect(&self.comma_rect);
|
// For more info, see https://users.rust-lang.org/t/43401/2
|
||||||
sprite.set_position(numeral_position);
|
for (i, numeral) in number_string
|
||||||
window.draw(&sprite);
|
.chars()
|
||||||
numeral_position.x -= numeral_rect.width as f32;
|
.collect::<Vec<char>>()
|
||||||
}
|
.iter()
|
||||||
sprite.set_texture_rect(&numeral_rect);
|
.enumerate()
|
||||||
sprite.set_position(numeral_position);
|
.rev()
|
||||||
window.draw(&sprite);
|
{
|
||||||
if i == 0 {
|
let numeral_rect = get_numeral_rect(*numeral);
|
||||||
break;
|
if (digits - i) % 3 == 1 && i != digits - 1 {
|
||||||
}
|
sprite.set_texture_rect(&self.comma_rect);
|
||||||
if (digits - i) % 3 == 0 {
|
sprite.set_position(numeral_position);
|
||||||
numeral_position.x -= self.comma_rect.width as f32;
|
window.draw(&sprite);
|
||||||
continue;
|
numeral_position.x -= numeral_rect.width as f32;
|
||||||
}
|
}
|
||||||
let numeral = number_string.as_bytes()[i - 1] as char;
|
sprite.set_texture_rect(&numeral_rect);
|
||||||
let numeral_rect = get_numeral_rect(numeral);
|
sprite.set_position(numeral_position);
|
||||||
numeral_position.x -= numeral_rect.width as f32;
|
window.draw(&sprite);
|
||||||
}
|
if i == 0 {
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
if (digits - i) % 3 == 0 {
|
||||||
|
numeral_position.x -= self.comma_rect.width as f32;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let numeral = number_string.as_bytes()[i - 1] as char;
|
||||||
|
let numeral_rect = get_numeral_rect(numeral);
|
||||||
|
numeral_position.x -= numeral_rect.width as f32;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@ impl TileType {
|
||||||
pub fn new(texture_rect: IntRect, ghost_texture_rect: IntRect) -> Self {
|
pub fn new(texture_rect: IntRect, ghost_texture_rect: IntRect) -> Self {
|
||||||
Self {
|
Self {
|
||||||
texture_rect,
|
texture_rect,
|
||||||
ghost_texture_rect
|
ghost_texture_rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue