Files
Zxq5-OS/src/user/bin/tetris.rs
T
FantasyPvP 461c9d9c6a - got text boxes fully working
- this includes text wrapping not cutting words in half (can be disabled using a method on the text box)
- refactored frame.rs, cg_core.rs and cg_widgets.rs to avoid code reuse and duplication
- created a simplified unified interface for rendering frames to the screen using the Frame struct provided by frame.rs instead of Element, FrameGen, etc.
- moved all widgets from cg_core.rs to cg_widgets.rs
- the label widget now works
- also added CgIndicatorBar and CgIndicatorWidget widgets to eventually make a working status bar
- refactored all applications in the system to use the new api to render to the screen
2023-11-23 00:29:04 +00:00

119 lines
2.7 KiB
Rust

use async_trait::async_trait;
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
use crate::kernel::render::ScreenChar;
use crate::{serial_print, serial_println};
use crate::std::application::{Application, Error};
use crate::std::io::Screen;
use crate::user::lib::coords::{Direction, Position, PositionReal};
pub(crate) struct TetrisEngine {
score: u32,
next: TetrisPiece,
completed_frame: [[ScreenChar; 80]; 25], // this frame does not contain falling blocks, only static ones
}
#[async_trait]
impl Application for TetrisEngine {
fn new() -> Self {
Self {
score: 0,
next: TetrisPiece::new(PieceType::OPiece),
completed_frame: [[ScreenChar::null(); 80]; 25],
}
}
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
// setup:
Screen::application_mode();
let piece_type = PieceType::OPiece;
let mut piece = TetrisPiece::new(piece_type);
serial_println!("{:?}", piece.get_positions());
piece.rotate_right();
serial_println!("{:?}", piece.get_positions());
Screen::terminal_mode();
Ok(())
}
}
enum PieceType {
OPiece,
IPiece,
JPiece,
LPiece,
SPiece,
ZPiece,
}
struct TetrisPiece {
type_: PieceType,
pos: Position,
rotation: Direction,
}
impl TetrisPiece {
fn new(type_: PieceType) -> Self {
Self {
type_,
pos: Position { x: 40, y: 30 },
rotation: Direction::Degrees0,
}
}
fn rotate_right(&mut self) {
self.rotation = match self.rotation {
Direction::Degrees90 => Direction::Degrees180,
Direction::Degrees180 => Direction::Degrees270,
Direction::Degrees270 => Direction::Degrees0,
Direction::Degrees0 => Direction::Degrees90,
Direction::None => panic!("direction should never be none in this application"),
};
}
/// function that maps the coordinates of the object.
fn get_positions(&self) -> Vec<Position> {
match self.type_ {
PieceType::OPiece => {
let positions = vec![
PositionReal { x: -0.5, y: -0.5 },
PositionReal { x: 0.5, y: -0.5 },
PositionReal { x: -0.5, y: 0.5 },
PositionReal { x: 0.5, y: 0.5 },
];
positions.into_iter().map(|p|
( p.rotate(self.rotation.clone()) + self.pos.clone().real() + PositionReal { x: -0.5, y: 0.5 } ).integer()
).collect::<Vec<Position>>()
}
_ => unimplemented!("E"),
}
}
}