From 8b402500a4d36882c0dce7074666a2e1012b0aea Mon Sep 17 00:00:00 2001 From: curly Date: Wed, 17 Aug 2022 20:38:11 -0600 Subject: functional --- Cargo.toml | 3 +- TODO | 13 ++-- backgroundxcf.xcf | Bin 0 -> 93892 bytes src/assets/background.png | Bin 0 -> 2037 bytes src/assets/bit.png | Bin 0 -> 144 bytes src/bit.xcf | Bin 0 -> 955 bytes src/display.rs | 21 ------ src/input.rs | 6 -- src/lib.rs | 171 ++++++++++++++++++++++++++++++++++++++-------- src/main.rs | 6 +- 10 files changed, 154 insertions(+), 66 deletions(-) create mode 100644 backgroundxcf.xcf create mode 100644 src/assets/background.png create mode 100644 src/assets/bit.png create mode 100644 src/bit.xcf delete mode 100644 src/display.rs delete mode 100644 src/input.rs diff --git a/Cargo.toml b/Cargo.toml index 0428edd..12ffc9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rand = "0.8.5" \ No newline at end of file +rand = "0.8.5" +sfml = "0.17.0" \ No newline at end of file diff --git a/TODO b/TODO index 03bf292..6f87946 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,12 @@ -SFML input -SFML graphics -Select between debug(cli) and gui display Next piece in gui Add sounds (mostly for losing, winning and clearing a row) -Pause on lose focus Also add a pause Have a menu -Add to score on line clear \ No newline at end of file +Add to score on line clear + +redo input system. It feels like junk +Implement win condition + +Import pieces from files to make it data driven +Refactor getting 2d array from piece area + Make it a pointer to the values in the area \ No newline at end of file diff --git a/backgroundxcf.xcf b/backgroundxcf.xcf new file mode 100644 index 0000000..66c61c7 Binary files /dev/null and b/backgroundxcf.xcf differ diff --git a/src/assets/background.png b/src/assets/background.png new file mode 100644 index 0000000..fe234aa Binary files /dev/null and b/src/assets/background.png differ diff --git a/src/assets/bit.png b/src/assets/bit.png new file mode 100644 index 0000000..32fb054 Binary files /dev/null and b/src/assets/bit.png differ diff --git a/src/bit.xcf b/src/bit.xcf new file mode 100644 index 0000000..95e0b34 Binary files /dev/null and b/src/bit.xcf differ diff --git a/src/display.rs b/src/display.rs deleted file mode 100644 index b57f68f..0000000 --- a/src/display.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::tetris::piece::{Piece, Pos}; - -pub fn display(grid: &Vec>, piece: &Piece) { - let piece_pos_vec = piece.get_bits_pos(); - - let mut yc = 0; - for y in grid { - let mut xc = 0; - for mut x in y { - for bit in &piece_pos_vec { - if bit == &Pos(yc, xc) { - x = &1; - } - } - xc += 1; - print!("{} ", x); - } - print!("\n"); - yc += 1; - } -} \ No newline at end of file diff --git a/src/input.rs b/src/input.rs deleted file mode 100644 index 23d0040..0000000 --- a/src/input.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub struct Input {} -impl Input { - pub fn new() -> Input { - Input{} - } -} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 5b4bbb0..6d7cd75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,56 +1,169 @@ -pub mod input; mod tetris; -mod display; use crate::tetris::piece; -use std::io::stdin; -use crate::input::Input; + +use std::time::{Instant, Duration}; + +// SFML +use sfml::window::{Style, Event, ContextSettings, Key}; +use sfml::graphics::{self, *}; +use sfml::system::{Vector2f, Vector2u}; pub struct Game { - tickrate: u8, // How many times things are checked a second - maxfps: u8, // Between 1 and 240 - gamespeed: u8, // How quickly r#move(down) is called in ms + tickrate: Duration, // How many times things are checked a second + maxfps: u64, + window_geometry: (u32, u32), + window: RenderWindow, } 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 = graphics::RenderWindow::new( + geometry, + "Test", + Style::DEFAULT, + &context_settings); + + window.set_framerate_limit(maxfps); + window.clear(Color::rgb(250, 250, 250)); + + // View + let view_geometry = (geometry.0 as f32, geometry.1 as f32); + let view = View::new( + Vector2f::from(view_geometry) / 2.0, + Vector2f::from(view_geometry)); + window.set_view(&view); + Game{ - tickrate: 20, + tickrate: Duration::from_secs(1), maxfps: 30, - gamespeed: 250, + window_geometry: geometry, + window: window, } } + pub fn set_geometry(&mut self, geometry: (u32, u32)) { + self.window_geometry = geometry; + self.window.set_size(Vector2u::from(geometry)); + } + + fn pause(&mut self) { + println!("paused"); + loop { + match self.window.wait_event() { + Some(Event::GainedFocus) => break, + _ => () + } + } + println!("resumed"); + } + // The actual game loop - pub fn game_loop(&self, input: &Input) { + pub fn game_loop(&mut self) { + + // Textures + let background = Texture::from_file("assets/background.png").expect("Cannot load texture"); + let bit = Texture::from_file("assets/bit.png").expect("Cannot load texture"); + + // Objects + let mut background = RectangleShape::with_texture(&background); + background.set_size(Vector2f::new(480.0, 480.0)); + + let mut bit = RectangleShape::with_texture(&bit); + bit.set_size(Vector2f::new(24.0, 24.0)); + + // Initialize the background + self.window.draw(&background); + + // Timing + let mut tick = Instant::now(); + let mut fpscap = Instant::now(); + + // Game setup let mut tetris = tetris::Tetris::new(); - let mut piece = piece::Piece::random(piece::Pos(0,0)); + let mut piece = piece::Piece::random(piece::Pos(-2,3)); loop { - tetris.check_lines(); - piece.r#move(piece::Dir::Down, &tetris); + // Process events + let mut key: Option = None; + match self.window.poll_event() { + Some(n) => match n { + Event::Closed => break, + 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, + _ => (), + }, + None => (), + } + + // Process keys + use tetris::piece::{Dir, Rotate}; + match key { + Some(Key::A) => piece.r#move(Dir::Left, &tetris), + Some(Key::S) => piece.r#move(Dir::Down, &tetris), + Some(Key::D) => piece.r#move(Dir::Right, &tetris), + Some(Key::Q) => piece.rotate(Rotate::Left, &tetris), + Some(Key::E) => piece.rotate(Rotate::Right, &tetris), + _ => () + } // Check if piece is dead if piece.is_alive() == false { piece.apply_to_grid(&mut tetris); - piece = piece::Piece::random(piece::Pos(0,0)); + piece = piece::Piece::random(piece::Pos(-2,3)); // piece = piece::Piece::new(piece::Pieces::Cube, piece::Pos(0,0)); } - - let grid = tetris.return_grid(); - display::display(&grid, &piece); - - let mut input = String::new(); - - stdin().read_line(&mut input).expect("Could not read line"); - let input = input.get(0..1).expect("Nothing to get"); - match input { - "a" => piece.r#move(piece::Dir::Left, &tetris), - "d" => piece.r#move(piece::Dir::Right, &tetris), - "e" => piece.rotate(piece::Rotate::Right, &tetris), - "q" => piece.rotate(piece::Rotate::Left, &tetris), - " " => break, - _ => (), + + // Check if there are full lines + tetris.check_lines(); + + // Execute on tick + if tick.elapsed() >= self.tickrate { + // Reset the clock + tick = Instant::now(); + + // Timed logic + piece.r#move(piece::Dir::Down, &tetris) + } + + if fpscap.elapsed() >= Duration::from_millis(1 / self.maxfps) { + // Reset the clock + fpscap = Instant::now(); + + // Draw the background + self.window.draw(&background); + + // Start drawing everything + let grid = tetris.return_grid(); + + // Draw all the bits + for y in (0..grid.len()).rev() { + for x in 0..grid.len() { + if *grid.get(y).unwrap_or(&vec![0]).get(x).unwrap_or(&0) == 1 { + bit.set_position(((x * 24) as f32, (y * 24) as f32)); + self.window.draw(&bit); + } + } + } + for piece_bit in piece.get_bits_pos() { + if !(piece_bit.0 < 0 || piece_bit.1 < 0) { + bit.set_position(((piece_bit.1 as f32) * 24.0, (piece_bit.0 as f32) * 24.0)); + self.window.draw(&bit); + } + } + + self.window.display(); } } + + self.window.close(); } } diff --git a/src/main.rs b/src/main.rs index aba1e8f..153019b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,6 @@ use tetris::Game; -use tetris::input::Input; fn main() { - let input = Input::new(); - let game = Game::new(); - game.game_loop(&input) + let mut game = Game::new(); + game.game_loop() } \ No newline at end of file -- cgit v1.2.3