movement
This commit is contained in:
parent
ab74480bfd
commit
9c4b208b8b
4 changed files with 107 additions and 28 deletions
32
src/game.rs
32
src/game.rs
|
@ -20,7 +20,7 @@ pub struct Game {
|
||||||
rotation_system: SRS,
|
rotation_system: SRS,
|
||||||
level: u8,
|
level: u8,
|
||||||
points: u32,
|
points: u32,
|
||||||
pub tick: u64,
|
tick: u64,
|
||||||
next_gravity_tick: u64,
|
next_gravity_tick: u64,
|
||||||
next_lock_tick: u64,
|
next_lock_tick: u64,
|
||||||
next_spawn_tick: u64,
|
next_spawn_tick: u64,
|
||||||
|
@ -121,7 +121,7 @@ impl Renderable for Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Controllable {
|
pub trait Controllable {
|
||||||
fn move_left(&mut self);
|
fn move_left(&mut self);
|
||||||
fn move_up(&mut self);
|
fn move_up(&mut self);
|
||||||
fn move_right(&mut self);
|
fn move_right(&mut self);
|
||||||
|
@ -133,13 +133,27 @@ trait Controllable {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controllable for Game {
|
impl Controllable for Game {
|
||||||
fn move_left(&mut self) {}
|
fn move_left(&mut self) {
|
||||||
fn move_up(&mut self) {}
|
self.playfield.move_offset(-1, 0);
|
||||||
fn move_right(&mut self) {}
|
}
|
||||||
fn move_down(&mut self) {}
|
fn move_up(&mut self) {
|
||||||
fn rotate_left(&mut self) {}
|
// self.playfield.move_up();
|
||||||
fn rotate_right(&mut self) {}
|
}
|
||||||
fn hard_drop(&mut self) {}
|
fn move_right(&mut self) {
|
||||||
|
self.playfield.move_offset(1, 0);
|
||||||
|
}
|
||||||
|
fn move_down(&mut self) {
|
||||||
|
// self.playfield.move_down();
|
||||||
|
}
|
||||||
|
fn rotate_left(&mut self) {
|
||||||
|
// self.playfield.rotate_left();
|
||||||
|
}
|
||||||
|
fn rotate_right(&mut self) {
|
||||||
|
// self.playfield.rotate_right();
|
||||||
|
}
|
||||||
|
fn hard_drop(&mut self) {
|
||||||
|
// self.playfield.hard_drop();
|
||||||
|
}
|
||||||
|
|
||||||
fn hold(&mut self) {
|
fn hold(&mut self) {
|
||||||
// if self.can_swap_hold {
|
// if self.can_swap_hold {
|
||||||
|
|
41
src/main.rs
41
src/main.rs
|
@ -1,4 +1,4 @@
|
||||||
use game::{Game, Tickable};
|
use game::{Controllable, Game, Tickable};
|
||||||
use graphics::COLOR_BACKGROUND;
|
use graphics::COLOR_BACKGROUND;
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
|
@ -30,7 +30,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut canvas = window.into_canvas().build()?;
|
let mut canvas = window.into_canvas().build()?;
|
||||||
let mut event_pump = sdl_context.event_pump()?;
|
let mut event_pump = sdl_context.event_pump()?;
|
||||||
let mut game = Game::default();
|
let mut game = Game::default();
|
||||||
let mut interval = interval(Duration::from_millis(60 / TICKS_PER_SECOND as u64));
|
let mut interval = interval(Duration::from_millis(1000 / TICKS_PER_SECOND as u64));
|
||||||
|
|
||||||
'running: while !game.is_game_over() {
|
'running: while !game.is_game_over() {
|
||||||
for event in event_pump.poll_iter() {
|
for event in event_pump.poll_iter() {
|
||||||
|
@ -40,6 +40,40 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
keycode: Some(Keycode::Escape),
|
keycode: Some(Keycode::Escape),
|
||||||
..
|
..
|
||||||
} => break 'running,
|
} => break 'running,
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Left),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
game.move_left();
|
||||||
|
}
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Right),
|
||||||
|
..
|
||||||
|
} => game.move_right(),
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Up),
|
||||||
|
..
|
||||||
|
} => game.move_up(),
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Down),
|
||||||
|
..
|
||||||
|
} => game.move_down(),
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Z),
|
||||||
|
..
|
||||||
|
} => game.rotate_left(),
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::X),
|
||||||
|
..
|
||||||
|
} => game.rotate_right(),
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Space),
|
||||||
|
..
|
||||||
|
} => game.hard_drop(),
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::LShift),
|
||||||
|
..
|
||||||
|
} => game.hold(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,8 +85,5 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
interval.tick().await;
|
interval.tick().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Game over! Final game state:");
|
|
||||||
dbg!(game);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,36 @@ impl PlayField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_offset(&mut self, x: isize, y: isize) -> bool {
|
||||||
|
if self.can_move_offset(x, y) {
|
||||||
|
match self.active_piece {
|
||||||
|
Some(mut piece) => {
|
||||||
|
piece.position.x = (x + piece.position.x as isize) as usize;
|
||||||
|
piece.position.y = (y + piece.position.y as isize) as usize;
|
||||||
|
self.active_piece = Some(piece);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
None => panic!("Active piece missing!"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_move_offset(&self, x: isize, y: isize) -> bool {
|
||||||
|
match self.active_piece {
|
||||||
|
Some(piece) => piece
|
||||||
|
.get_occupied_spaces(piece.position.offset(x, y))
|
||||||
|
.iter()
|
||||||
|
.fold(true, |acc, pos| {
|
||||||
|
acc && pos.y < self.field.len()
|
||||||
|
&& pos.x < PLAYFIELD_WIDTH
|
||||||
|
&& self.field[pos.y as usize][pos.x as usize].is_none()
|
||||||
|
}),
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spawn_tetromino(&mut self) {
|
pub fn spawn_tetromino(&mut self) {
|
||||||
self.active_piece = Some(Tetromino::from(
|
self.active_piece = Some(Tetromino::from(
|
||||||
self.next_pieces
|
self.next_pieces
|
||||||
|
@ -120,10 +150,14 @@ impl PlayField {
|
||||||
pub fn can_active_piece_move_down(&self) -> bool {
|
pub fn can_active_piece_move_down(&self) -> bool {
|
||||||
self.active_piece
|
self.active_piece
|
||||||
.and_then(|p| {
|
.and_then(|p| {
|
||||||
Some(p.get_next_occupied_spaces().iter().fold(true, |acc, pos| {
|
Some(
|
||||||
|
p.get_falling_occupied_spaces()
|
||||||
|
.iter()
|
||||||
|
.fold(true, |acc, pos| {
|
||||||
acc && pos.y < self.field.len()
|
acc && pos.y < self.field.len()
|
||||||
&& self.field[pos.y as usize][pos.x as usize].is_none()
|
&& self.field[pos.y as usize][pos.x as usize].is_none()
|
||||||
}))
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| false)
|
.unwrap_or_else(|| false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset(&self, x: isize, y: isize) -> Position {
|
pub fn offset(&self, x: isize, y: isize) -> Position {
|
||||||
Self {
|
Self {
|
||||||
x: (x + self.x as isize) as usize,
|
x: (x + self.x as isize) as usize,
|
||||||
y: (y + self.y as isize) as usize,
|
y: (y + self.y as isize) as usize,
|
||||||
|
@ -129,14 +129,6 @@ impl Tetromino {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_next_occupied_spaces(&self) -> Vec<Position> {
|
|
||||||
self.get_occupied_spaces(self.position.offset(0, 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_cur_occupied_spaces(&self) -> Vec<Position> {
|
|
||||||
self.get_occupied_spaces(self.position)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_color(&self) -> MinoColor {
|
pub fn get_color(&self) -> MinoColor {
|
||||||
match self.piece_type {
|
match self.piece_type {
|
||||||
TetrominoType::I => MinoColor::Cyan,
|
TetrominoType::I => MinoColor::Cyan,
|
||||||
|
@ -157,7 +149,15 @@ impl Tetromino {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_occupied_spaces(&self, center: Position) -> Vec<Position> {
|
pub fn get_falling_occupied_spaces(&self) -> Vec<Position> {
|
||||||
|
self.get_occupied_spaces(self.position.offset(0, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cur_occupied_spaces(&self) -> Vec<Position> {
|
||||||
|
self.get_occupied_spaces(self.position)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_occupied_spaces(&self, center: Position) -> Vec<Position> {
|
||||||
let mut spaces = vec![center];
|
let mut spaces = vec![center];
|
||||||
match self.piece_type {
|
match self.piece_type {
|
||||||
TetrominoType::I => match self.rotation_state {
|
TetrominoType::I => match self.rotation_state {
|
||||||
|
|
Loading…
Reference in a new issue