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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum MazePart {
|
pub enum MazePart {
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
use epd_waveshare::color::Color;
|
use epd_waveshare::color::Color;
|
||||||
use maze::{AsciiBroad, BinaryMapVisitor, Direction};
|
use maze::{binary_to_ascii_broad, BinaryMapVisitor, Direction, MazePart};
|
||||||
|
|
||||||
use crate::Button;
|
use crate::Button;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub const MAZE_WIDTH: usize = 42;
|
pub const MAZE_WIDTH: usize = 25;
|
||||||
pub const MAZE_HEIGHT: usize = 42;
|
pub const MAZE_HEIGHT: usize = 25;
|
||||||
|
|
||||||
pub struct MazeGame {
|
pub struct MazeGame {
|
||||||
map: maze::BinaryMap<MAZE_WIDTH, MAZE_HEIGHT, 1764>,
|
map: maze::BinaryMap<MAZE_WIDTH, MAZE_HEIGHT, 625>,
|
||||||
player: Point,
|
player: Point,
|
||||||
old_player: Option<Point>,
|
old_player: Option<Point>,
|
||||||
}
|
}
|
||||||
@ -27,6 +27,7 @@ impl MazeGame {
|
|||||||
impl MazeGame {
|
impl MazeGame {
|
||||||
const X_OFFSET: i32 = 4;
|
const X_OFFSET: i32 = 4;
|
||||||
const Y_OFFSET: i32 = 4;
|
const Y_OFFSET: i32 = 4;
|
||||||
|
const CELL_SIZE: i32 = 6;
|
||||||
|
|
||||||
fn player_pos(&self) -> (u16, u16) {
|
fn player_pos(&self) -> (u16, u16) {
|
||||||
(self.player.x as u16, self.player.y as u16)
|
(self.player.x as u16, self.player.y as u16)
|
||||||
@ -34,21 +35,27 @@ impl MazeGame {
|
|||||||
|
|
||||||
fn draw_walls(&self, ctx: &mut Context) {
|
fn draw_walls(&self, ctx: &mut Context) {
|
||||||
let wall_style = PrimitiveStyleBuilder::new()
|
let wall_style = PrimitiveStyleBuilder::new()
|
||||||
.stroke_color(Color::Black)
|
|
||||||
.stroke_width(3)
|
|
||||||
.fill_color(Color::Black)
|
.fill_color(Color::Black)
|
||||||
.build();
|
.build();
|
||||||
|
let passage_style = PrimitiveStyleBuilder::new()
|
||||||
|
.fill_color(Color::White)
|
||||||
|
.build();
|
||||||
|
|
||||||
for x in 0..MAZE_WIDTH {
|
for y in 0..MAZE_HEIGHT {
|
||||||
for y in 0..MAZE_HEIGHT {
|
for x in 0..MAZE_WIDTH {
|
||||||
if self.map.at(x as u16, y as u16) == maze::MazePart::Wall {
|
let style = match self.map.at(x as u16, y as u16) {
|
||||||
Rectangle::new(
|
maze::MazePart::Wall => &wall_style,
|
||||||
Point::new(x as i32 * Self::X_OFFSET, y as i32 * Self::Y_OFFSET),
|
_ => &passage_style,
|
||||||
Size::new(3, 3),
|
};
|
||||||
)
|
Rectangle::new(
|
||||||
.draw_styled(&wall_style, &mut ctx.epaper.display)
|
Point::new(
|
||||||
.unwrap();
|
(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(style, &mut ctx.epaper.display)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,29 +69,53 @@ impl MazeGame {
|
|||||||
|
|
||||||
Rectangle::new(
|
Rectangle::new(
|
||||||
Point::new(
|
Point::new(
|
||||||
self.player.x * Self::X_OFFSET,
|
(self.player.x * Self::CELL_SIZE) + Self::X_OFFSET + 1,
|
||||||
self.player.y * Self::Y_OFFSET,
|
(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)
|
.draw_styled(&player_style, &mut ctx.epaper.display)
|
||||||
.unwrap();
|
.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 {
|
impl App for MazeGame {
|
||||||
fn start(&mut self, trng: &mut Trng) {
|
fn start(&mut self, trng: &mut Trng) {
|
||||||
let mut grid = maze::Grid::<20, 20, 400>::new();
|
self.generate_map(trng);
|
||||||
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}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, ctx: &mut Context) {
|
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_walls(ctx);
|
||||||
self.draw_player(ctx);
|
self.draw_player(ctx);
|
||||||
return;
|
return;
|
||||||
@ -97,7 +128,7 @@ impl App for MazeGame {
|
|||||||
},
|
},
|
||||||
&[Color::White as u8],
|
&[Color::White as u8],
|
||||||
);
|
);
|
||||||
self.draw_player(ctx);
|
self.draw_player(ctx);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, ctx: &mut Context) -> Option<Action> {
|
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);
|
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]) {
|
pub fn partial_update(&mut self, pos: Point, size: Size, buffer: &[u8]) {
|
||||||
let _ = self.driver.update_partial_frame(
|
let _ = self.driver.update_partial_frame(
|
||||||
&mut self.spi,
|
&mut self.spi,
|
||||||
|
@ -94,6 +94,7 @@ fn main() -> ! {
|
|||||||
loop {
|
loop {
|
||||||
ctx.button_pressed = kbd.pressed();
|
ctx.button_pressed = kbd.pressed();
|
||||||
if ctx.button_pressed.is_some() {
|
if ctx.button_pressed.is_some() {
|
||||||
|
ctx.epaper.clear_frame();
|
||||||
log::info!("Wake up!");
|
log::info!("Wake up!");
|
||||||
app.update_and_draw(&mut ctx, &mut trng);
|
app.update_and_draw(&mut ctx, &mut trng);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user