From 39d1306d93aaecc8ca0a10ea0ae2d4f881e344a8 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Wed, 26 Nov 2025 23:07:19 +0100 Subject: [PATCH] Jumping and zig zag motion --- examples/components/mod.rs | 89 ++++++++++++++++++++++++++++++++++++++ examples/cube.rs | 28 ++++-------- src/entity.rs | 20 +++++++-- 3 files changed, 114 insertions(+), 23 deletions(-) diff --git a/examples/components/mod.rs b/examples/components/mod.rs index 712a1c3..bf532f6 100644 --- a/examples/components/mod.rs +++ b/examples/components/mod.rs @@ -1,7 +1,12 @@ pub mod threads; +use std::{any::Any, sync::Arc}; + use osmium::{entity::Component, renderer::Point}; +pub struct Jumping(pub u16, pub u16); +pub struct ZigZag(pub u16); + pub struct Velocity(pub Point); impl Component for Velocity { @@ -33,3 +38,87 @@ fn apply_velocity(tick: u16, velocity: i32, x: &mut u16) -> bool { } false } + +impl Component for Jumping { + fn tick(&mut self, entity: &Arc, _tick: u16) { + let target = self.1; + + let mut pos = entity.position(); + + // on first tick, start upward velocity + if self.0 == 0 { + std::thread::spawn({ + let entity = entity.clone(); + move || { + entity.update_component(|v: &mut Velocity| { + v.0.y = -150; + }); + } + }); + } + + // If above the peak, fall down + if pos.y < target - 6 { + std::thread::spawn({ + let entity = entity.clone(); + move || { + entity.update_component(|v: &mut Velocity| { + v.0.y = 150; + }); + } + }); + } + + // If we reached the ground, stop and remove component + if self.0 > 30 && pos.y >= target { + pos.y = target; + std::thread::spawn({ + let entity = entity.clone(); + move || { + entity.update_component(|v: &mut Velocity| { + v.0.y = 0; + }); + entity.remove_component::(); + } + }); + } + + self.0 += 1; + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } +} + +impl Component for ZigZag { + fn tick(&mut self, entity: &Arc, _tick: u16) { + let pos = entity.get_position(); + + if pos.x == 0 { + std::thread::spawn({ + let entity = entity.clone(); + move || { + entity.update_component(|v: &mut Velocity| { + v.0.x = 200; + }); + } + }); + } + + if pos.x >= self.0 { + std::thread::spawn({ + let entity = entity.clone(); + move || { + entity.update_component(|v: &mut Velocity| { + v.0.x = -200; + }); + } + }); + } + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } +} diff --git a/examples/cube.rs b/examples/cube.rs index 58e651b..7d7bba1 100644 --- a/examples/cube.rs +++ b/examples/cube.rs @@ -3,6 +3,9 @@ pub mod components; use osmium::{renderer::Point, terminal}; fn main() { + let (term_width, term_height) = crossterm::terminal::size().unwrap(); + let a = term_height - 3; + let engine = osmium::init(); let my_rect = engine.entity(|r| { @@ -12,6 +15,9 @@ fn main() { }); my_rect.component(components::Velocity(Point { x: 0, y: 0 })); + my_rect.component(components::ZigZag(term_width - 3)); + + my_rect.set_position(0, term_height - 3); components::threads::tick(&engine); components::threads::key(&engine); @@ -21,26 +27,8 @@ fn main() { move |e: &crossterm::event::Event| { if let Some(key_event) = e.as_key_event() { match key_event.code { - crossterm::event::KeyCode::Right => { - my_rect.update_component(|c: &mut components::Velocity| { - c.0.x = 100; - }); - } - crossterm::event::KeyCode::Left => { - my_rect.update_component(|c: &mut components::Velocity| { - c.0.x = -100; - }); - } - - crossterm::event::KeyCode::Down => { - my_rect.update_component(|c: &mut components::Velocity| { - c.0.y = 100; - }); - } - crossterm::event::KeyCode::Up => { - my_rect.update_component(|c: &mut components::Velocity| { - c.0.y = -100; - }); + crossterm::event::KeyCode::Char(' ') => { + my_rect.component(components::Jumping(0, a)); } _ => {} } diff --git a/src/entity.rs b/src/entity.rs index 0e4e028..e1de0b5 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -47,6 +47,20 @@ impl Entity { } } + pub fn remove_component(self: &Arc) { + self.components.lock().unwrap().remove(&TypeId::of::()); + } + + pub fn get_component(self: &Arc) -> Option { + if let Some(a) = self.components.lock().unwrap().get_mut(&TypeId::of::()) { + if let Some(c) = a.as_any_mut().downcast_mut::() { + return Some(c.clone()); + } + } + + None + } + pub fn render(self: &Arc, renderer: &mut Renderer) { (self.render)(renderer) } @@ -61,17 +75,17 @@ impl Entity { self.pos.lock().unwrap() } - pub fn get_position<'a>(self: &'a Arc) -> Point { + pub fn get_position(self: &Arc) -> Point { self.pos.lock().unwrap().clone() } - pub fn set_position(&mut self, x: u16, y: u16) { + pub fn set_position(self: &Arc, 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) { + pub fn set_position_point(self: Arc, pos: Point) { *self.pos.lock().unwrap() = pos; } }