use tinybit::events::{events, Event, KeyCode, KeyEvent, EventModel};
use tinybit::{
term_size, Camera, Renderer, ScreenPos, ScreenSize, StdoutTarget, Viewport,
WorldPos, Pixel, Color
};
use tinybit::widgets::{Text, Border};
struct Mob {
pixel: Pixel,
world_pos: WorldPos,
tick: i64,
}
impl Mob {
fn update(&mut self) {
self.tick += 1;
if self.tick > 10 {
self.world_pos.x += 1;
self.tick = 0;
}
}
}
fn main() {
let (width, height) = term_size().expect("Can't get the term size? Can't play the game!");
let viewport_size = ScreenSize::new(width / 2, height / 2);
let mut viewport = Viewport::new(ScreenPos::new(0, 4), viewport_size);
let mut status_viewport = Viewport::new(ScreenPos::zero(), ScreenSize::new(width, 3));
let camera_pos = WorldPos::zero();
let mut camera = Camera::from_viewport(camera_pos, &viewport).with_limit(5, 5, 5, 5);
let stdout_renderer = StdoutTarget::new().expect("Failed to enter raw mode");
let mut renderer = Renderer::new(stdout_renderer);
let mut player = ('@', camera_pos);
let mut player_pixel = Pixel::new(player.0, camera.to_screen(player.1), Some(Color::Yellow), None);
let mut mob = Mob {
pixel: Pixel::new('&', camera.to_screen(player.1), Some(Color::Red), None),
world_pos: WorldPos::new(camera_pos.x - 2, camera_pos.y - 6),
tick: 0,
};
let grass_positions = field_of_grass(&camera);
let mut grass = grass_positions.iter().map(|_| Pixel::new(
'w',
camera.to_screen(camera.position),
Some(Color::Green),
None
)).collect::<Vec<_>>();
let (_, events) = events::<()>(EventModel::Fps(20));
for event in events {
match event {
Event::User(()) => {}
Event::Tick => {
viewport.draw_pixels(&grass);
viewport.draw_pixel(player_pixel);
mob.pixel.pos = camera.to_screen(mob.world_pos);
viewport.draw_pixel(mob.pixel);
mob.update();
let camera_border = Border::thin(Some(Color::Green), None);
viewport.draw_widget(&camera_border, ScreenPos::zero());
camera.track(player.1);
player_pixel.pos = camera.to_screen(player.1);
grass_positions.iter().zip(&mut grass).for_each(|(world_pos, grass)| {
grass.pos = camera.to_screen(*world_pos);
});
let status = Text::new(
format!("player x {} | y {} camera x {} | y {}",
player.1.x,
player.1.y,
camera.position.x,
camera.position.y,
),
Some(Color::Red),
None,
);
let status_border = Border::new("╭─╮│╯─╰│", Some(Color::White), None);
status_viewport.swap_buffers();
status_viewport.draw_widget(&status_border, ScreenPos::zero());
status_viewport.draw_widget(&status, ScreenPos::new(1, 1));
let _ = renderer.render(&mut status_viewport);
let _ = renderer.render(&mut viewport);
viewport.swap_buffers();
}
Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => break,
Event::Key(KeyEvent { code: kc, .. }) => {
match kc {
KeyCode::Left => { player.1.x -= 1; }
KeyCode::Right => { player.1.x += 1; }
KeyCode::Up => { player.1.y -= 1; }
KeyCode::Down => { player.1.y += 1; }
_ => {}
}
}
Event::Resize(_w, _h) => {}
}
}
}
fn field_of_grass<T>(camera: &Camera<T>) -> Vec<WorldPos> {
let pos = camera.position;
let field_size = 3;
let x_range = pos.x - field_size..pos.x + field_size;
let y_range = pos.y - field_size..pos.y + field_size;
let mut pixels = Vec::new();
for x in x_range {
for y in y_range.clone() {
let pos = WorldPos::new(x, y);
pixels.push(pos);
}
}
pixels
}