Working maze
This commit is contained in:
parent
1b4dab55c6
commit
021a611df2
@ -613,6 +613,25 @@ impl<const X: usize, const Y: usize, const SIZE: usize> BinaryMapVisitor<X, Y, S
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn binary_to_ascii_broad<const X: usize, const Y: usize>(b: &[MazePart], f: &mut impl Write) {
|
||||
use MazePart::Passage as P;
|
||||
use MazePart::Wall as W;
|
||||
use MazePart::*;
|
||||
|
||||
write!(f, "\n").unwrap();
|
||||
for y in 0..Y {
|
||||
for x in 0..X {
|
||||
let c = match b[y * X + x] {
|
||||
P => '.',
|
||||
W => '#',
|
||||
Noop => '?',
|
||||
Player => 'O',
|
||||
};
|
||||
write!(f, "{c}").unwrap();
|
||||
}
|
||||
write!(f, "\n").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum MazePart {
|
||||
|
@ -1,15 +1,15 @@
|
||||
use epd_waveshare::color::Color;
|
||||
use maze::{AsciiBroad, BinaryMapVisitor, Direction};
|
||||
use maze::{binary_to_ascii_broad, BinaryMapVisitor, Direction, MazePart};
|
||||
|
||||
use crate::Button;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub const MAZE_WIDTH: usize = 42;
|
||||
pub const MAZE_HEIGHT: usize = 42;
|
||||
pub const MAZE_WIDTH: usize = 25;
|
||||
pub const MAZE_HEIGHT: usize = 25;
|
||||
|
||||
pub struct MazeGame {
|
||||
map: maze::BinaryMap<MAZE_WIDTH, MAZE_HEIGHT, 1764>,
|
||||
map: maze::BinaryMap<MAZE_WIDTH, MAZE_HEIGHT, 625>,
|
||||
player: Point,
|
||||
old_player: Option<Point>,
|
||||
}
|
||||
@ -27,6 +27,7 @@ impl MazeGame {
|
||||
impl MazeGame {
|
||||
const X_OFFSET: i32 = 4;
|
||||
const Y_OFFSET: i32 = 4;
|
||||
const CELL_SIZE: i32 = 6;
|
||||
|
||||
fn player_pos(&self) -> (u16, u16) {
|
||||
(self.player.x as u16, self.player.y as u16)
|
||||
@ -34,24 +35,30 @@ impl MazeGame {
|
||||
|
||||
fn draw_walls(&self, ctx: &mut Context) {
|
||||
let wall_style = PrimitiveStyleBuilder::new()
|
||||
.stroke_color(Color::Black)
|
||||
.stroke_width(3)
|
||||
.fill_color(Color::Black)
|
||||
.build();
|
||||
let passage_style = PrimitiveStyleBuilder::new()
|
||||
.fill_color(Color::White)
|
||||
.build();
|
||||
|
||||
for x in 0..MAZE_WIDTH {
|
||||
for y in 0..MAZE_HEIGHT {
|
||||
if self.map.at(x as u16, y as u16) == maze::MazePart::Wall {
|
||||
for x in 0..MAZE_WIDTH {
|
||||
let style = match self.map.at(x as u16, y as u16) {
|
||||
maze::MazePart::Wall => &wall_style,
|
||||
_ => &passage_style,
|
||||
};
|
||||
Rectangle::new(
|
||||
Point::new(x as i32 * Self::X_OFFSET, y as i32 * Self::Y_OFFSET),
|
||||
Size::new(3, 3),
|
||||
Point::new(
|
||||
(x as i32 * Self::CELL_SIZE) + Self::X_OFFSET,
|
||||
(y as i32 * Self::CELL_SIZE) + Self::Y_OFFSET,
|
||||
),
|
||||
Size::new(Self::CELL_SIZE as u32, Self::CELL_SIZE as u32),
|
||||
)
|
||||
.draw_styled(&wall_style, &mut ctx.epaper.display)
|
||||
.draw_styled(style, &mut ctx.epaper.display)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_player(&self, ctx: &mut Context) {
|
||||
let player_style = PrimitiveStyleBuilder::new()
|
||||
@ -62,29 +69,53 @@ impl MazeGame {
|
||||
|
||||
Rectangle::new(
|
||||
Point::new(
|
||||
self.player.x * Self::X_OFFSET,
|
||||
self.player.y * Self::Y_OFFSET,
|
||||
(self.player.x * Self::CELL_SIZE) + Self::X_OFFSET + 1,
|
||||
(self.player.y * Self::CELL_SIZE) + Self::Y_OFFSET + 1,
|
||||
),
|
||||
Size::new(1, 1),
|
||||
Size::new(4, 4),
|
||||
)
|
||||
.draw_styled(&player_style, &mut ctx.epaper.display)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn generate_map(&mut self, trng: &mut Trng) {
|
||||
let mut grid = maze::Grid::<12, 12, 144>::new();
|
||||
maze::RecursiveDivision.generate(&mut grid, trng);
|
||||
BinaryMapVisitor.format(&mut grid, &mut self.map.0);
|
||||
for x in 0..MAZE_WIDTH {
|
||||
let part = &mut self.map.0[(MAZE_WIDTH + x) as usize];
|
||||
if *part != MazePart::Wall {
|
||||
break;
|
||||
}
|
||||
|
||||
*part = MazePart::Passage;
|
||||
}
|
||||
for x in (0..MAZE_WIDTH).into_iter().rev() {
|
||||
let part = &mut self.map.0[((MAZE_WIDTH * (MAZE_HEIGHT - 2)) + x) as usize];
|
||||
if *part != MazePart::Wall {
|
||||
break;
|
||||
}
|
||||
|
||||
*part = MazePart::Passage;
|
||||
}
|
||||
|
||||
let mut result = heapless::String::<4_000>::new();
|
||||
// AsciiBroad.format(&grid, &mut result);
|
||||
binary_to_ascii_broad::<MAZE_WIDTH, MAZE_HEIGHT>(&self.map.0, &mut result);
|
||||
println!("{result}");
|
||||
}
|
||||
}
|
||||
|
||||
impl App for MazeGame {
|
||||
fn start(&mut self, trng: &mut Trng) {
|
||||
let mut grid = maze::Grid::<20, 20, 400>::new();
|
||||
maze::RecursiveDivision.generate(&mut grid, trng);
|
||||
BinaryMapVisitor.format(&mut grid, &mut self.map.0);
|
||||
|
||||
let mut result = heapless::String::<500>::new();
|
||||
AsciiBroad.format(&grid, &mut result);
|
||||
println!("{result}");
|
||||
self.generate_map(trng);
|
||||
}
|
||||
|
||||
fn draw(&self, ctx: &mut Context) {
|
||||
let Some(old) = &self.old_player else {
|
||||
self.draw_walls(ctx);
|
||||
self.draw_player(ctx);
|
||||
// FIXME: Partial update
|
||||
/*let Some(old) = &self.old_player else {
|
||||
self.draw_walls(ctx);
|
||||
self.draw_player(ctx);
|
||||
return;
|
||||
@ -97,7 +128,7 @@ impl App for MazeGame {
|
||||
},
|
||||
&[Color::White as u8],
|
||||
);
|
||||
self.draw_player(ctx);
|
||||
self.draw_player(ctx);*/
|
||||
}
|
||||
|
||||
fn update(&mut self, ctx: &mut Context) -> Option<Action> {
|
||||
|
@ -166,6 +166,12 @@ impl<'d> Epaper<'d> {
|
||||
let _ = self.driver.sleep(&mut self.spi, &mut self.delay);
|
||||
}
|
||||
|
||||
pub fn clear_frame(&mut self) {
|
||||
self.driver
|
||||
.clear_frame(&mut self.spi, &mut self.delay)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn partial_update(&mut self, pos: Point, size: Size, buffer: &[u8]) {
|
||||
let _ = self.driver.update_partial_frame(
|
||||
&mut self.spi,
|
||||
|
@ -94,6 +94,7 @@ fn main() -> ! {
|
||||
loop {
|
||||
ctx.button_pressed = kbd.pressed();
|
||||
if ctx.button_pressed.is_some() {
|
||||
ctx.epaper.clear_frame();
|
||||
log::info!("Wake up!");
|
||||
app.update_and_draw(&mut ctx, &mut trng);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user