tetres/iced-tetris/src/main.rs

116 lines
2.9 KiB
Rust

use iced::{executor, keyboard, Rectangle, Point, Size, Color, Application, Command, Settings, Element, Subscription, Length};
use iced::widget::canvas::{self, Path};
use iced_native::{event, subscription, Event};
fn main() -> iced::Result {
Tetris::run(Settings::default())
}
struct Tetris {
color: Color,
background_cache: canvas::Cache,
}
impl Tetris {
fn new() -> Tetris {
Tetris {
color: Color::BLACK,
background_cache: canvas::Cache::default(),
}
}
}
impl Application for Tetris {
type Executor = executor::Default;
type Message = Message;
type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) {
(Tetris::new(), Command::none())
}
fn title(&self) -> String {
String::from("Tetris - Iced")
}
fn update(&mut self, message: Self::Message) -> Command<Message> {
match message {
Message::Up => self.color = Color::new(1.0, 0.0, 1.0, 1.0),
Message::Down => self.color = Color::new(0.0, 0.0, 1.0, 1.0),
Message::Left => self.color = Color::new(0.0, 1.0, 1.0, 1.0),
Message::Right => self.color = Color::new(0.8, 0.3, 1.0, 1.0),
_ => (),
}
Command::none()
}
fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, status| {
if let event::Status::Captured = status {
return None;
}
match event {
Event::Keyboard(keyboard::Event::KeyPressed {
modifiers,
key_code,
}) => handle_keypress(key_code),
_ => None,
}
})
}
fn view(&mut self) -> Element<Self::Message> {
canvas::Canvas::new(self)
.width(Length::Fill)
.height(Length::Fill)
.into()
}
}
impl<'a> canvas::Program<Message> for Tetris {
fn draw(&self, bounds: Rectangle, _cursor: canvas::Cursor) -> Vec<canvas::Geometry> {
let game_width = bounds.width / 3.0;
let block_size = game_width / 10.0;
let background = self.background_cache.draw(bounds.size(), |frame| {
let center = bounds.center();
let top_left = Point::new(center.x - game_width / 2.0, 0.0);
let game_size = Size::new(block_size * 10.0, block_size * 20.0);
let game_bg = Path::rectangle(top_left, game_size);
frame.fill(&game_bg, Color::BLACK);
});
let mut frame = canvas::Frame::new(bounds.size());
let circle = Path::circle(frame.center(), 10.0);
frame.fill(&circle, self.color);
vec![background, frame.into_geometry()]
}
}
fn handle_keypress(key_code: keyboard::KeyCode) -> Option<Message> {
use keyboard::KeyCode;
println!("Handling keycode: {:?}", key_code);
Some(match key_code {
KeyCode::Up => Message::Up,
KeyCode::Down => Message::Down,
KeyCode::Right => Message::Right,
KeyCode::Left => Message::Left,
_ => return None,
})
}
#[derive(Debug)]
enum Message {
Up,
Down,
Left,
Right,
Pause
}