From 83b17f69191f9d5e5764a02efb0f9544c214cece Mon Sep 17 00:00:00 2001 From: sofyak0zyreva Date: Sun, 30 Nov 2025 13:39:45 +0300 Subject: [PATCH 1/2] feat: add function for changing main object position programmatically Signed-off-by: sofyak0zyreva --- src/engine/mod.rs | 10 +++++++--- src/engine/scripts.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/engine/scripts.rs diff --git a/src/engine/mod.rs b/src/engine/mod.rs index a710f38..43a371f 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -11,12 +11,14 @@ pub mod config; pub mod input; pub mod scene; pub mod scene_manager; +pub mod scripts; use crate::Resolution; use crate::engine::config::Config; use crate::engine::scene::Scene; use crate::engine::scene::game_object::Object; use crate::engine::scene_manager::SceneManager; +use crate::engine::scripts::main_obj_script; use crate::render::renderer::{DEFAULT_BACKGROUND_COLOR, Renderer}; use crate::screen::{App, HEIGHT, WIDTH}; //use image::ImageReader; @@ -139,12 +141,13 @@ impl Engine for GameEngine { Some(KeyCode::KeyD) => (1, 0), _ => (0, 0), };*/ - let dx = (keys_pressed_clone.d.load(Ordering::Relaxed) as i32) + let dx_keys = (keys_pressed_clone.d.load(Ordering::Relaxed) as i32) - (keys_pressed_clone.a.load(Ordering::Relaxed) as i32); - let dy = (keys_pressed_clone.w.load(Ordering::Relaxed) as i32) + let dy_keys = (keys_pressed_clone.w.load(Ordering::Relaxed) as i32) - (keys_pressed_clone.s.load(Ordering::Relaxed) as i32); - let vector_move = (dx, dy); + let (dx_script, dy_script) = main_obj_script(); + let vector_move = (dx_keys + dx_script, dy_keys + dy_script); renderer .write() @@ -155,6 +158,7 @@ impl Engine for GameEngine { .add_position((vector_move.0, vector_move.1)); renderer.write().unwrap().render(); + match renderer.write().unwrap().emit() { Some(colors) => { let mut pixels = shared_pixel_data_clone diff --git a/src/engine/scripts.rs b/src/engine/scripts.rs new file mode 100644 index 0000000..dd6ab58 --- /dev/null +++ b/src/engine/scripts.rs @@ -0,0 +1,27 @@ +pub fn main_obj_script() -> (i32, i32) { + // this is just an example behavior for main object + // if you run 'cargo run --bin main' you'll see the ship travelling in a square-like shape + // so in this funciton you can write custom main object script + + static mut DIR: usize = 0; // 0 = right, 1 = down, 2 = left, 3 = up + static mut MOVED: i32 = 0; // steps moved along current direction + const SIDE: i32 = 50; // length of one side of square + const SPEED: i32 = 1; // movement per frame + + // direction vectors: right, down, left, up + let dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]; + + let (dx, dy) = dirs[unsafe { DIR }]; + unsafe { + MOVED += SPEED; + if MOVED >= SIDE { + MOVED = 0; + DIR = (DIR + 1) % 4; // rotate to next direction + } + } + + (dx * SPEED, dy * SPEED) + + // this is the default behavior -- the ship is not moving unless some key is pressed + // (0, 0) +} From 05c683a3cb435575fc474d2769b69c1f3e098977 Mon Sep 17 00:00:00 2001 From: sofyak0zyreva Date: Mon, 1 Dec 2025 03:31:32 +0300 Subject: [PATCH 2/2] feat: example of main onj movement logic Signed-off-by: sofyak0zyreva --- src/engine/scripts.rs | 61 ++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/engine/scripts.rs b/src/engine/scripts.rs index dd6ab58..5e571ca 100644 --- a/src/engine/scripts.rs +++ b/src/engine/scripts.rs @@ -1,27 +1,52 @@ +use std::sync::{Mutex, OnceLock}; +use std::time::{Duration, Instant}; + +struct ScriptState { + last_cycle_start: Instant, + jumping: bool, +} + +static STATE: OnceLock> = OnceLock::new(); + pub fn main_obj_script() -> (i32, i32) { // this is just an example behavior for main object - // if you run 'cargo run --bin main' you'll see the ship travelling in a square-like shape + // if you run 'cargo run --bin main' you'll see the ship "falling" every 3 seconds // so in this funciton you can write custom main object script - static mut DIR: usize = 0; // 0 = right, 1 = down, 2 = left, 3 = up - static mut MOVED: i32 = 0; // steps moved along current direction - const SIDE: i32 = 50; // length of one side of square - const SPEED: i32 = 1; // movement per frame + const COOLDOWN: Duration = Duration::from_secs(3); + const JUMP_DURATION: Duration = Duration::from_millis(200); - // direction vectors: right, down, left, up - let dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]; + let state = STATE.get_or_init(|| { + Mutex::new(ScriptState { + last_cycle_start: Instant::now(), + jumping: false, + }) + }); - let (dx, dy) = dirs[unsafe { DIR }]; - unsafe { - MOVED += SPEED; - if MOVED >= SIDE { - MOVED = 0; - DIR = (DIR + 1) % 4; // rotate to next direction + let mut st = state.lock().unwrap(); + let elapsed = st.last_cycle_start.elapsed(); + + if st.jumping { + // currently in jumping phase + if elapsed >= JUMP_DURATION { + // jump finished + st.jumping = false; + st.last_cycle_start = Instant::now(); // restart cycle after jump ends + return (0, 0); + } else { + // still jumping + return (0, -4); // height of jump + } + } else { + // waiting for the 3-second cooldown + if elapsed >= COOLDOWN { + // start a new jump + st.jumping = true; + st.last_cycle_start = Instant::now(); // mark start of jump + return (0, -4); + } else { + // still cooling down + return (0, 0); } } - - (dx * SPEED, dy * SPEED) - - // this is the default behavior -- the ship is not moving unless some key is pressed - // (0, 0) }