Renderer improvement

This commit is contained in:
2025-11-26 20:39:51 +01:00
parent cf207477f1
commit dff435a6d1
4 changed files with 89 additions and 13 deletions
+38 -2
View File
@@ -1,4 +1,4 @@
use osmium::{sleep, terminal}; use osmium::{entity::Component, sleep, terminal};
fn main() { fn main() {
terminal::hide_cursor().unwrap(); terminal::hide_cursor().unwrap();
@@ -6,8 +6,15 @@ fn main() {
let engine = osmium::init(); let engine = osmium::init();
engine.thread("Main.tick", |engine| { engine.thread("Main.tick", |engine| {
let mut tick = 0;
loop { loop {
engine.tick(); if tick == 60000 {
tick = 0;
}
engine.tick(tick);
tick += 1;
sleep(4); sleep(4);
} }
}); });
@@ -18,7 +25,36 @@ fn main() {
r.draw_rect(2, 0, 1, 2, 0x0000ff); r.draw_rect(2, 0, 1, 2, 0x0000ff);
}); });
my_rect.component(Velocity(300));
engine.start(); engine.start();
terminal::show_cursor().unwrap(); terminal::show_cursor().unwrap();
} }
pub struct Velocity(pub i32);
impl Component for Velocity {
fn tick(&mut self, entity: &std::sync::Arc<osmium::entity::Entity>, 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
}
+26 -6
View File
@@ -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 { pub trait Component: Send + Sync {
#[allow(unused_variables)] #[allow(unused_variables)]
@@ -8,10 +8,11 @@ pub trait Component: Send + Sync {
#[allow(unused_variables)] #[allow(unused_variables)]
fn init(&mut self, entity: &Arc<Entity>) {} fn init(&mut self, entity: &Arc<Entity>) {}
#[allow(unused_variables)] #[allow(unused_variables)]
fn tick(&mut self, entity: &Arc<Entity>) {} fn tick(&mut self, entity: &Arc<Entity>, tick: u16) {}
} }
pub struct Entity { pub struct Entity {
pos: Mutex<Point>,
components: Mutex<Vec<Box<dyn Component>>>, components: Mutex<Vec<Box<dyn Component>>>,
render: Box<dyn Fn(&mut Renderer) + Send + Sync>, render: Box<dyn Fn(&mut Renderer) + Send + Sync>,
} }
@@ -19,12 +20,13 @@ pub struct Entity {
impl Entity { impl Entity {
pub fn new<F: Fn(&mut Renderer) + Send + Sync + 'static>(render: F) -> Arc<Self> { pub fn new<F: Fn(&mut Renderer) + Send + Sync + 'static>(render: F) -> Arc<Self> {
Arc::new(Self { Arc::new(Self {
pos: Mutex::new(Point { x: 0, y: 0 }),
components: Mutex::new(Vec::new()), components: Mutex::new(Vec::new()),
render: Box::new(render), render: Box::new(render),
}) })
} }
pub fn component<C: Component + 'static>(&mut self, c: C) { pub fn component<C: Component + 'static>(self: &Arc<Self>, c: C) {
self.components.lock().unwrap().push(Box::new(c)); self.components.lock().unwrap().push(Box::new(c));
} }
@@ -32,9 +34,27 @@ impl Entity {
(self.render)(renderer) (self.render)(renderer)
} }
pub fn tick(self: &Arc<Self>) { pub fn tick(self: &Arc<Self>, tick: u16) {
for comp in self.components.lock().unwrap().iter_mut() { for comp in self.components.lock().unwrap().iter_mut() {
comp.tick(self); comp.tick(self, tick);
} }
} }
pub fn position<'a>(self: &'a Arc<Self>) -> MutexGuard<'a, Point> {
self.pos.lock().unwrap()
}
pub fn get_position<'a>(self: &'a Arc<Self>) -> 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<Self>, pos: Point) {
*self.pos.lock().unwrap() = pos;
}
} }
+3 -2
View File
@@ -51,13 +51,14 @@ impl Engine {
let mut renderer = renderer::Renderer::new(); let mut renderer = renderer::Renderer::new();
for entity in self.entities.lock().unwrap().iter() { for entity in self.entities.lock().unwrap().iter() {
renderer.set_position_point(entity.get_position());
entity.render(&mut renderer); entity.render(&mut renderer);
} }
} }
pub fn tick(self: &Arc<Self>) { pub fn tick(self: &Arc<Self>, tick: u16) {
for entity in self.entities.lock().unwrap().iter() { for entity in self.entities.lock().unwrap().iter() {
entity.tick(); entity.tick(tick);
} }
} }
+22 -3
View File
@@ -1,15 +1,34 @@
use crate::terminal::{hex_bg, print_liner}; 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 { impl Renderer {
pub fn new() -> Self { 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) { pub fn draw_rect(&self, x: u16, y: u16, width: u16, height: u16, color: u32) {
let rl = " ".repeat(width as usize) + "\x1b[0m"; let rl = " ".repeat(width as usize) + "\x1b[0m";
let rect = (rl + "\n").repeat(height as usize); 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;
} }
} }