diff --git a/examples/cube.rs b/examples/cube.rs index 77fa115..80d8e74 100644 --- a/examples/cube.rs +++ b/examples/cube.rs @@ -1,4 +1,4 @@ -use osmium::{sleep, terminal}; +use osmium::{entity::Component, sleep, terminal}; fn main() { terminal::hide_cursor().unwrap(); @@ -6,8 +6,15 @@ fn main() { let engine = osmium::init(); engine.thread("Main.tick", |engine| { + let mut tick = 0; loop { - engine.tick(); + if tick == 60000 { + tick = 0; + } + + engine.tick(tick); + + tick += 1; sleep(4); } }); @@ -18,7 +25,36 @@ fn main() { r.draw_rect(2, 0, 1, 2, 0x0000ff); }); + my_rect.component(Velocity(300)); + engine.start(); terminal::show_cursor().unwrap(); } + +pub struct Velocity(pub i32); + +impl Component for Velocity { + fn tick(&mut self, entity: &std::sync::Arc, tick: u16) { + let mut position = entity.position(); + apply_velocity(tick, self.0, &mut position.x); + } +} + +fn apply_velocity(tick: u16, velocity: i32, x: &mut u16) -> bool { + let abs_v = velocity.abs(); + if abs_v == 0 { + return false; + } + + let interval = (1000 / abs_v).max(1); + if tick as i32 % interval == 0 { + if velocity > 0 { + *x = x.saturating_add(1); + } else { + *x = x.saturating_sub(1); + } + return true; + } + false +} diff --git a/src/entity.rs b/src/entity.rs index 33ef37a..304e38e 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -1,6 +1,6 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex, MutexGuard}; -use crate::Renderer; +use crate::{Renderer, renderer::Point}; pub trait Component: Send + Sync { #[allow(unused_variables)] @@ -8,10 +8,11 @@ pub trait Component: Send + Sync { #[allow(unused_variables)] fn init(&mut self, entity: &Arc) {} #[allow(unused_variables)] - fn tick(&mut self, entity: &Arc) {} + fn tick(&mut self, entity: &Arc, tick: u16) {} } pub struct Entity { + pos: Mutex, components: Mutex>>, render: Box, } @@ -19,12 +20,13 @@ pub struct Entity { impl Entity { pub fn new(render: F) -> Arc { Arc::new(Self { + pos: Mutex::new(Point { x: 0, y: 0 }), components: Mutex::new(Vec::new()), render: Box::new(render), }) } - pub fn component(&mut self, c: C) { + pub fn component(self: &Arc, c: C) { self.components.lock().unwrap().push(Box::new(c)); } @@ -32,9 +34,27 @@ impl Entity { (self.render)(renderer) } - pub fn tick(self: &Arc) { + pub fn tick(self: &Arc, tick: u16) { for comp in self.components.lock().unwrap().iter_mut() { - comp.tick(self); + comp.tick(self, tick); } } + + pub fn position<'a>(self: &'a Arc) -> MutexGuard<'a, Point> { + self.pos.lock().unwrap() + } + + pub fn get_position<'a>(self: &'a Arc) -> Point { + self.pos.lock().unwrap().clone() + } + + pub fn set_position(&mut self, x: u16, y: u16) { + let mut pos = self.pos.lock().unwrap(); + pos.x = x; + pos.y = y; + } + + pub fn set_position_point<'a>(self: &'a Arc, pos: Point) { + *self.pos.lock().unwrap() = pos; + } } diff --git a/src/lib.rs b/src/lib.rs index 257f238..e582792 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,13 +51,14 @@ impl Engine { let mut renderer = renderer::Renderer::new(); for entity in self.entities.lock().unwrap().iter() { + renderer.set_position_point(entity.get_position()); entity.render(&mut renderer); } } - pub fn tick(self: &Arc) { + pub fn tick(self: &Arc, tick: u16) { for entity in self.entities.lock().unwrap().iter() { - entity.tick(); + entity.tick(tick); } } diff --git a/src/renderer.rs b/src/renderer.rs index 4cd35ca..6f237d6 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,15 +1,34 @@ use crate::terminal::{hex_bg, print_liner}; -pub struct Renderer {} +#[derive(Debug, Clone)] +pub struct Point { + pub x: u16, + pub y: u16, +} + +pub struct Renderer { + pos: Point, +} impl Renderer { pub fn new() -> Self { - Self {} + Self { + pos: Point { x: 0, y: 0 }, + } } pub fn draw_rect(&self, x: u16, y: u16, width: u16, height: u16, color: u32) { let rl = " ".repeat(width as usize) + "\x1b[0m"; let rect = (rl + "\n").repeat(height as usize); - print_liner(x, y, &hex_bg(color), &rect); + print_liner(self.pos.x + x, self.pos.y + y, &hex_bg(color), &rect); + } + + pub fn set_position(&mut self, x: u16, y: u16) { + self.pos.x = x; + self.pos.y = y; + } + + pub fn set_position_point(&mut self, pos: Point) { + self.pos = pos; } }