aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input.rs124
-rw-r--r--src/lib.rs98
-rw-r--r--src/tetris/piece.rs33
3 files changed, 201 insertions, 54 deletions
diff --git a/src/input.rs b/src/input.rs
new file mode 100644
index 0000000..874b327
--- /dev/null
+++ b/src/input.rs
@@ -0,0 +1,124 @@
+use sfml::window::{Event, Key};
+
+#[derive(Debug)]
+pub enum Action {
+ Left,
+ Right,
+ Down,
+ RotateLeft,
+ RotateRight,
+ Quit,
+ LostFocus,
+ GainedFocus,
+}
+
+pub struct Actions {
+ left: bool,
+ right: bool,
+ down: bool,
+ rotate_left: bool,
+ rotate_right: bool,
+ quit: bool,
+ lost_focus: bool,
+ gained_focus: bool,
+}
+impl Actions {
+ pub fn new() -> Actions {
+ Actions{
+ left: false,
+ right: false,
+ down: false,
+ rotate_left: false,
+ rotate_right: false,
+ quit: false,
+ lost_focus: false,
+ gained_focus: false,
+ }
+ }
+
+ pub fn set(&mut self, a: Action, b: bool) {
+ match a {
+ Action::Left => self.left = b,
+ Action::Right => self.right = b,
+ Action::Down => self.down = b,
+ Action::RotateLeft => self.rotate_left = b,
+ Action::RotateRight => self.rotate_right = b,
+ Action::Quit => self.quit = b,
+ Action::LostFocus => self.lost_focus = b,
+ Action::GainedFocus => self.gained_focus = b,
+ }
+ }
+ pub fn get(&self, a: Action) -> &bool {
+ match a {
+ Action::Left => &self.left,
+ Action::Right => &self.right,
+ Action::Down => &self.down,
+ Action::RotateLeft => &self.rotate_left,
+ Action::RotateRight => &self.rotate_right,
+ Action::Quit => &self.quit,
+ Action::LostFocus => &self.lost_focus,
+ Action::GainedFocus => &self.gained_focus,
+ }
+ }
+}
+
+pub struct Input {
+ window: Option<Event>,
+ actions: Actions,
+}
+impl Input {
+ pub fn new() -> Input {
+ Input {
+ window: None,
+ actions: Actions::new(),
+ }
+ }
+
+ pub fn process(&mut self, events: Option<Event>) {
+ self.window = events;
+ self.match_actions();
+ }
+
+
+ fn match_actions(&mut self) {
+ let x = match self.window {
+ Some(Event::KeyPressed {code: c, alt: _, ctrl: _, shift: _, system: _}) => Some((c, true)),
+ Some(Event::KeyReleased {code: c, alt: _, ctrl: _, shift: _, system: _}) => Some((c, false)),
+ Some(Event::Closed) => {self.set_action(Action::Quit, true); None},
+ Some(Event::LostFocus) => {self.set_action(Action::LostFocus, true); self.set_action(Action::GainedFocus, false); None},
+ Some(Event::GainedFocus) => {self.set_action(Action::GainedFocus, true); self.set_action(Action::LostFocus, false); None},
+ _ => None
+ };
+ match x {
+ Some((Key::A, n)) => self.set_action(Action::Left, n),
+ Some((Key::S, n)) => self.set_action(Action::Down, n),
+ Some((Key::D, n)) => self.set_action(Action::Right, n),
+ Some((Key::Q, n)) => self.set_action(Action::RotateLeft, n),
+ Some((Key::E, n)) => self.set_action(Action::RotateRight, n),
+ Some((Key::Escape, n)) => self.set_action(Action::Quit, n),
+ _ => (),
+ }
+ }
+
+ pub fn set_action(&mut self, a: Action, b: bool) {
+ self.actions.set(a, b);
+ }
+
+ pub fn get_action(&self, a: Action) -> &bool {
+ self.actions.get(a)
+
+ }
+
+ pub fn get_iter(&self) -> Vec<Action> {
+ let mut vec = vec![];
+ if self.get_action(Action::Left) == &true {vec.push(Action::Left)}
+ if self.get_action(Action::Down) == &true {vec.push(Action::Down)}
+ if self.get_action(Action::Right) == &true {vec.push(Action::Right)}
+ if self.get_action(Action::RotateLeft) == &true {vec.push(Action::RotateLeft)}
+ if self.get_action(Action::RotateRight) == &true {vec.push(Action::RotateRight)}
+ if self.get_action(Action::Quit) == &true {vec.push(Action::Quit)}
+ if self.get_action(Action::LostFocus) == &true {vec.push(Action::LostFocus)}
+ if self.get_action(Action::GainedFocus) == &true {vec.push(Action::GainedFocus)}
+ return vec
+ }
+} \ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index bf0bf5d..e9f4cce 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,13 +1,15 @@
mod tetris;
+mod input;
use crate::tetris::piece;
+use crate::input::Action;
use std::time::{Instant, Duration};
use rand::Rng;
// SFML
-use sfml::window::{Style, Event, ContextSettings, Key};
-use sfml::graphics::{self, *};
+use sfml::window::{Style, ContextSettings};
+use sfml::graphics::*;
use sfml::system::{Vector2f, Vector2u};
pub struct Game {
@@ -16,22 +18,22 @@ pub struct Game {
maxfps: u64,
window_geometry: (u32, u32),
window: RenderWindow,
+ input: input::Input,
score: u64,
}
impl Game {
pub fn new() -> Game {
- let maxfps = 30;
- let geometry = (480, 480);
-
// Window setup
let mut context_settings: ContextSettings = Default::default();
context_settings.antialiasing_level = 0;
+ let mut window = RenderWindow::new(
+ (480, 480),
+ "Test",
+ Style::DEFAULT,
+ &context_settings);
- let mut window = graphics::RenderWindow::new(
- geometry,
- "Test",
- Style::DEFAULT,
- &context_settings);
+ let maxfps = 30;
+ let geometry = (480, 480);
window.set_framerate_limit(maxfps);
window.set_key_repeat_enabled(false);
@@ -51,6 +53,7 @@ impl Game {
maxfps: 30,
window_geometry: geometry,
window: window,
+ input: input::Input::new(),
score: 0,
}
}
@@ -84,13 +87,25 @@ impl Game {
fn pause(&mut self) {
loop {
- match self.window.wait_event() {
- Some(Event::GainedFocus) => break,
- _ => ()
- }
+ self.process_inputs();
+ if *self.input.get_action(Action::GainedFocus) {break}
}
}
+ fn process_inputs(&mut self) {
+ let mut poll = self.window.poll_event();
+ while poll != None {
+ self.input.process(poll);
+ poll = self.window.poll_event();
+ }
+ }
+
+ fn reset(&mut self) -> tetris::Tetris {
+ println!("{}", self.get_score());
+ self.set_score(0);
+ tetris::Tetris::new()
+ }
+
// The actual game loop
pub fn game_loop(&mut self) {
// Textures
@@ -130,28 +145,30 @@ impl Game {
let mut tetris = tetris::Tetris::new();
let mut piece = piece::Piece::random(piece::Pos(-2,3));
let mut next_piece = piece::Piece::random(piece::Pos(3,13));
- let mut key = None;
+
'main: loop {
// Clear everything from display
self.window.clear(Color::rgb(0,0,0));
+ self.process_inputs();
+
// Process events
- for x in self.window.poll_event() {
- match x {
- Event::Closed => break 'main,
- Event::Resized {width: w, height: h} => self.set_geometry((w, h)),
- Event::LostFocus => self.pause(),
- Event::KeyPressed {code: c, ctrl: _, alt: _, shift: _, system: _} => key = Some(c),
- Event::KeyReleased {code: _, ctrl: _, alt: _, shift: _, system: _} => key = None,
- _ => (),
- };
- }
+ // for x in self.window.poll_event() {
+ // match x {
+ // Event::Closed => break 'main,
+ // Event::Resized {width: w, height: h} => self.set_geometry((w, h)),
+ // Event::LostFocus => self.pause(),
+ // Event::KeyPressed {code: c, ctrl: _, alt: _, shift: _, system: _} => key = Some(c),
+ // Event::KeyReleased {code: _, ctrl: _, alt: _, shift: _, system: _} => key = None,
+ // _ => (),
+ // };
+ // }
// Check if piece is dead
if piece.is_alive() == false {
if piece.apply_to_grid(&mut tetris) == false {
// Game has been lost
- break
+ tetris = self.reset();
}
piece = next_piece;
piece.set_pos(tetris::piece::Pos(-2, 3));
@@ -186,27 +203,32 @@ impl Game {
// Reset the clock
fpscap = Instant::now();
-
// Process keys
// Limited keys
if key_count == 0 {
- match key {
- Some(Key::A) => {piece.r#move(tetris::piece::Dir::Left, &tetris)},
- Some(Key::D) => {piece.r#move(tetris::piece::Dir::Right, &tetris)},
- _ => ()
+ for action in self.input.get_iter() {
+ match action {
+ Action::Left => piece.r#move(tetris::piece::Dir::Left, &tetris),
+ Action::Right => piece.r#move(tetris::piece::Dir::Right, &tetris),
+ _ => ()
+ }
}
}
//Process keys
// Unlimited keys
- match key {
- Some(Key::S) => piece.r#move(tetris::piece::Dir::Down, &tetris),
- Some(Key::Q) => {piece.rotate(tetris::piece::Rotate::Left, &tetris); key = None},
- Some(Key::E) => {piece.rotate(tetris::piece::Rotate::Right, &tetris); key = None},
- Some(Key::Escape) => break,
- _ => ()
+ for action in self.input.get_iter() {
+ match action {
+ Action::RotateLeft => {piece.rotate(tetris::piece::Rotate::Left, &tetris); self.input.set_action(Action::RotateLeft, false)},
+ Action::RotateRight => {piece.rotate(tetris::piece::Rotate::Right, &tetris); self.input.set_action(Action::RotateRight, false)},
+ Action::Down => piece.r#move(tetris::piece::Dir::Down, &tetris),
+ Action::Quit => break 'main,
+ Action::LostFocus => self.pause(),
+ _ => ()
+ }
}
+
// Make the limit feel good
- if key != None {
+ if *self.input.get_action(Action::Left) != false || *self.input.get_action(Action::Right) != false {
key_count += 1;
} else {
key_count = 0;
diff --git a/src/tetris/piece.rs b/src/tetris/piece.rs
index 19e8e6c..fc7d1c7 100644
--- a/src/tetris/piece.rs
+++ b/src/tetris/piece.rs
@@ -198,16 +198,20 @@ impl Piece {
for pos in self.get_bits_pos() {
let new_pos = pos + dir.get();
- // Detect blocks and kill only if Dir is down
- if grid.get_grid_pos(new_pos) == 1 && *dir == Dir::Down {
- self.kill();
- return Err(())
- } else if grid.get_grid_pos(new_pos) == 1 {
- return Err(())
- } else if new_pos.0 > 19 { // Detect bottom and kill
- self.kill();
- return Err(())
- } else if new_pos.1 > 9 || new_pos.1 < 0 { // Detect sides
+ if self.is_alive() {
+ // Detect blocks and kill only if Dir is down
+ if grid.get_grid_pos(new_pos) == 1 && *dir == Dir::Down {
+ self.kill();
+ return Err(())
+ } else if grid.get_grid_pos(new_pos) == 1 {
+ return Err(())
+ } else if new_pos.0 > 19 { // Detect bottom and kill
+ self.kill();
+ return Err(())
+ } else if new_pos.1 > 9 || new_pos.1 < 0 { // Detect sides
+ return Err(())
+ }
+ } else {
return Err(())
}
}
@@ -315,15 +319,12 @@ impl Piece {
self.alive = false
}
- // Return false if the piece cannot move
pub fn r#move(&mut self, dir: Dir, grid: &Tetris) {
// If a hit is detected, don't move
// Otherwise move
- if self.is_alive() {
- match self.hit_detect(&dir, &grid) {
- Ok(_) => self.apply_dir(&dir),
- Err(_) => (),
- }
+ match self.hit_detect(&dir, &grid) {
+ Ok(_) => self.apply_dir(&dir),
+ Err(_) => (),
}
}
} \ No newline at end of file