use game::{Controllable, Game, Tickable}; use graphics::COLOR_BACKGROUND; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sdl2::{render::Canvas, video::Window}; use std::time::Duration; use tokio::time::interval; mod game; mod graphics; mod playfield; mod random; mod srs; mod tetromino; const TICKS_PER_SECOND: usize = 60; pub trait Renderable { fn render(&self, canvas: &mut Canvas) -> Result<(), String>; } #[tokio::main] async fn main() -> Result<(), Box> { let sdl_context = sdl2::init()?; let video_subsystem = sdl_context.video()?; let window = video_subsystem .window("retris", 800, 800) .position_centered() .build()?; let mut canvas = window.into_canvas().build()?; let mut event_pump = sdl_context.event_pump()?; let mut game = Game::default(); let mut interval = interval(Duration::from_millis(1000 / TICKS_PER_SECOND as u64)); 'running: while !game.is_game_over() { for event in event_pump.poll_iter() { match event { Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => 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::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), .. } | Event::KeyDown { keycode: Some(Keycode::Up), .. } => game.hard_drop(), Event::KeyDown { keycode: Some(Keycode::LShift), .. } => game.hold(), _ => {} } } game.tick(); canvas.set_draw_color(COLOR_BACKGROUND); canvas.clear(); game.render(&mut canvas)?; canvas.present(); interval.tick().await; } dbg!(game); Ok(()) }