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..5e571ca --- /dev/null +++ b/src/engine/scripts.rs @@ -0,0 +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 "falling" every 3 seconds + // so in this funciton you can write custom main object script + + const COOLDOWN: Duration = Duration::from_secs(3); + const JUMP_DURATION: Duration = Duration::from_millis(200); + + let state = STATE.get_or_init(|| { + Mutex::new(ScriptState { + last_cycle_start: Instant::now(), + jumping: false, + }) + }); + + 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); + } + } +}