diff options
| author | LLLL Colonq <llll@colonq> | 2026-06-02 00:54:56 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-06-02 00:54:56 -0400 |
| commit | ab80e4583b53a7b424563cbd17ba2bf95e168cc9 (patch) | |
| tree | 54d4bb560c03585046e0b1ac0de7fafb496be94a /2026/framing | |
| parent | 7409691cb134eef99a7d9e53b57a1cba41a7ca09 (diff) | |
Update
Diffstat (limited to '2026/framing')
| -rw-r--r-- | 2026/framing/.dir-locals.el | 8 | ||||
| -rw-r--r-- | 2026/framing/Cargo.lock | 66 | ||||
| -rw-r--r-- | 2026/framing/Cargo.toml | 3 | ||||
| -rw-r--r-- | 2026/framing/index.css | 3 | ||||
| -rw-r--r-- | 2026/framing/index.html | 52 | ||||
| -rw-r--r-- | 2026/framing/src/assets.rs | 1 | ||||
| -rw-r--r-- | 2026/framing/src/assets/audio/footsteps.wav | bin | 0 -> 140588 bytes | |||
| -rw-r--r-- | 2026/framing/src/assets/textures/arm.png | bin | 0 -> 2541 bytes | |||
| -rw-r--r-- | 2026/framing/src/assets/textures/lagerboy.png | bin | 0 -> 886192 bytes | |||
| -rw-r--r-- | 2026/framing/src/assets/textures/mrblue.png | bin | 0 -> 771 bytes | |||
| -rw-r--r-- | 2026/framing/src/assets/textures/mrgreen.png (renamed from 2026/framing/src/assets/textures/test.png) | bin | 714 -> 714 bytes | |||
| -rw-r--r-- | 2026/framing/src/assets/textures/timbs.png | bin | 0 -> 4051 bytes | |||
| -rw-r--r-- | 2026/framing/src/game.rs | 198 | ||||
| -rw-r--r-- | 2026/framing/src/lagerboy.png | bin | 0 -> 886192 bytes | |||
| -rw-r--r-- | 2026/framing/src/lib.rs | 3 |
15 files changed, 250 insertions, 84 deletions
diff --git a/2026/framing/.dir-locals.el b/2026/framing/.dir-locals.el index d0146c5..ebe3652 100644 --- a/2026/framing/.dir-locals.el +++ b/2026/framing/.dir-locals.el @@ -1 +1,7 @@ -((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "x86_64-unknown-linux-gnu"))))))) +((rust-ts-mode . + ((eglot-workspace-configuration . + (:rust-analyzer + ( :check (:command "clippy") + :cargo ( :target "wasm32-unknown-unknown" + :targetDir t) + :hover (:show (:fields 10)))))))) diff --git a/2026/framing/Cargo.lock b/2026/framing/Cargo.lock index 1b66407..96a3e84 100644 --- a/2026/framing/Cargo.lock +++ b/2026/framing/Cargo.lock @@ -714,6 +714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" dependencies = [ "enum-map-derive", + "serde", ] [[package]] @@ -728,6 +729,15 @@ dependencies = [ ] [[package]] +name = "env" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc95de49ad098572c02d3fbf368c9a020bfff5ae78483685b77f51d8a7e9486d" +dependencies = [ + "num_threads", +] + +[[package]] name = "env_filter" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -860,12 +870,15 @@ name = "game_lib" version = "0.1.0" dependencies = [ "bitflags 2.11.1", + "enum-map", "glam", "lazy_static", "log", "rand", - "strum 0.26.3", + "serde", + "strum", "teleia", + "teleia_macros", "wasm-bindgen", ] @@ -1246,6 +1259,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1484,6 +1503,15 @@ dependencies = [ ] [[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] name = "objc-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2232,33 +2260,11 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" [[package]] name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - -[[package]] -name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.2", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", + "strum_macros", ] [[package]] @@ -2425,7 +2431,7 @@ dependencies = [ "serde", "serde_json", "simple-eyre", - "strum 0.27.2", + "strum", "tobj", "tracing-wasm", "tungstenite", @@ -2436,6 +2442,16 @@ dependencies = [ ] [[package]] +name = "teleia_macros" +version = "0.1.0" +dependencies = [ + "env", + "heck", + "litrs", + "walkdir", +] + +[[package]] name = "tempfile" version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/2026/framing/Cargo.toml b/2026/framing/Cargo.toml index b673692..cf605fa 100644 --- a/2026/framing/Cargo.toml +++ b/2026/framing/Cargo.toml @@ -17,12 +17,15 @@ opt-level = 2 [dependencies] # teleia = { git = "https://github.com/lcolonq/teleia" } # engine teleia = { path = "../../../teleia/crates/teleia" } # engine +teleia_macros = { path = "../../../teleia/crates/teleia_macros" } # engine glam = "*" # linear algebra bitflags = "*" # C-style bitwise flags rand = "*" # rng log = "*" # logging lazy_static = "*" # global constants strum = {version = "*", features = ["derive"]} # utility macros for enums +enum-map = {version = "2.7.3", features = ["serde"]} # enum map +serde = { version = "1.0.228", features = ["derive"] } # serialization [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "=0.2.100" # wasm bindings
\ No newline at end of file diff --git a/2026/framing/index.css b/2026/framing/index.css index aa6ff76..42d23c8 100644 --- a/2026/framing/index.css +++ b/2026/framing/index.css @@ -23,6 +23,7 @@ canvas { top: 0%; left: 50%; transform: translate(-50%, 0%); + image-rendering: pixelated; /* color: #000000; */ } @@ -37,5 +38,5 @@ canvas { font-size: 24px; font-family: Ubuntu-Light, Helvetica, sans-serif; text-align: center; - image-transform: pixelated; + image-rendering: pixelated; } diff --git a/2026/framing/index.html b/2026/framing/index.html index 7be78b5..a38f0f5 100644 --- a/2026/framing/index.html +++ b/2026/framing/index.html @@ -1,25 +1,33 @@ <!DOCTYPE html> <html> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> - <head> - <meta charset="UTF-8"> - <link data-trunk rel="rust" data-wasm-opt="2" data-target-name="game_lib" /> - <!-- <link data-trunk rel="rust" data-keep-debug="true" /> --> - <base data-trunk-public-url /> - <meta name="theme-color" media="(prefers-color-scheme: light)" content="white"> - <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#404040"> - <link rel="icon" href="data:;base64,iVBORw0KGgo="> - <link data-trunk rel="css" href="index.css" /> - <title>TODO TITLE</title> - </head> - <body> - <script> - addEventListener("TrunkApplicationStarted", async (event) => { - console.log("initialized, starting..."); - window.wasmBindings.main_js(); - }); - </script> - <div id="teleia-parent"></div> - </body> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> + <head> + <meta charset="UTF-8"> + <link data-trunk rel="rust" data-wasm-opt="2" data-target-name="game_lib" /> + <!-- <link data-trunk rel="rust" data-keep-debug="true" /> --> + <base data-trunk-public-url /> + <meta name="theme-color" media="(prefers-color-scheme: light)" content="white"> + <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#404040"> + <link rel="icon" href="data:;base64,iVBORw0KGgo="> + <link data-trunk rel="css" href="index.css" /> + <title>TODO TITLE</title> + </head> + <body> + <script type="module"> + window.addEventListener("TrunkApplicationStarted", async (event) => { + console.log("initialized, starting..."); + window.wasmBindings.main_js(); + }); + window.addEventListener("message", ev => { + switch (ev.data.op) { + case "loselife": + window.wasmBindings.lose_life(); + break; + default: console.log(`unknown event: ${ev}`); break; + } + }); + </script> + <div id="teleia-parent"></div> + </body> </html> diff --git a/2026/framing/src/assets.rs b/2026/framing/src/assets.rs new file mode 100644 index 0000000..31fa1b5 --- /dev/null +++ b/2026/framing/src/assets.rs @@ -0,0 +1 @@ +teleia_macros::generate_assets!("src/assets/"); diff --git a/2026/framing/src/assets/audio/footsteps.wav b/2026/framing/src/assets/audio/footsteps.wav Binary files differnew file mode 100644 index 0000000..57bfddf --- /dev/null +++ b/2026/framing/src/assets/audio/footsteps.wav diff --git a/2026/framing/src/assets/textures/arm.png b/2026/framing/src/assets/textures/arm.png Binary files differnew file mode 100644 index 0000000..0b4accf --- /dev/null +++ b/2026/framing/src/assets/textures/arm.png diff --git a/2026/framing/src/assets/textures/lagerboy.png b/2026/framing/src/assets/textures/lagerboy.png Binary files differnew file mode 100644 index 0000000..89992f7 --- /dev/null +++ b/2026/framing/src/assets/textures/lagerboy.png diff --git a/2026/framing/src/assets/textures/mrblue.png b/2026/framing/src/assets/textures/mrblue.png Binary files differnew file mode 100644 index 0000000..8cf2a0b --- /dev/null +++ b/2026/framing/src/assets/textures/mrblue.png diff --git a/2026/framing/src/assets/textures/test.png b/2026/framing/src/assets/textures/mrgreen.png Binary files differindex 1f1edca..1f1edca 100644 --- a/2026/framing/src/assets/textures/test.png +++ b/2026/framing/src/assets/textures/mrgreen.png diff --git a/2026/framing/src/assets/textures/timbs.png b/2026/framing/src/assets/textures/timbs.png Binary files differnew file mode 100644 index 0000000..0c093ad --- /dev/null +++ b/2026/framing/src/assets/textures/timbs.png diff --git a/2026/framing/src/game.rs b/2026/framing/src/game.rs index b704b49..8e819c0 100644 --- a/2026/framing/src/game.rs +++ b/2026/framing/src/game.rs @@ -1,37 +1,165 @@ #![allow(dead_code, unused_variables)] use std::collections::HashMap; use teleia::*; +use teleia::renderer::UberFlags; +use wasm_bindgen::prelude::*; -struct Assets { - font: font::Bitmap, - shader_flat: shader::Shader, - mesh_square: mesh::Mesh, - texture_test: texture::Texture, +use crate::assets; + +const NUM_LIVES: usize = 4; +const LIFE_LOSS_FRAMES: u64 = 120; + +#[derive(PartialEq, Eq)] +enum MrColor { + Green, + Blue, +} +impl MrColor { + fn texture(&self) -> assets::Texture { + match self { + Self::Green => assets::Texture::Mrgreen, + Self::Blue => assets::Texture::Mrblue, + } + } + fn hue(&self) -> f32 { + match self { + Self::Green => 0.3, + Self::Blue => 0.6, + } + } } -impl Assets { - fn new(ctx: &context::Context) -> Self { +struct Lives { + lives: [ui::Mode; NUM_LIVES], +} +impl Lives { + fn new() -> Self { Self { - font: font::Bitmap::default(ctx), - shader_flat: shader::Shader::new( - ctx, - include_str!("assets/shaders/flat/vert.glsl"), - include_str!("assets/shaders/flat/frag.glsl"), - ), - mesh_square: mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/square.obj")), - texture_test: texture::Texture::new(ctx, include_bytes!("assets/textures/test.png")), + lives: [ + ui::Mode::new(LIFE_LOSS_FRAMES), + ui::Mode::new(LIFE_LOSS_FRAMES), + ui::Mode::new(LIFE_LOSS_FRAMES), + ui::Mode::new(LIFE_LOSS_FRAMES), + ], + } + } + fn last_life(&self) -> Option<usize> { + self.lives.iter().rposition(|l| !l.is_active()) + } + fn lives_remaining(&self) -> i32 { + self.last_life().map(|x| (x + 1) as i32).unwrap_or(0) + } + fn lose_life(&mut self, _ctx: &context::Context, st: &state::State) { + if let Some(ll) = self.last_life() { + self.lives[ll].toggle(st.tick) } } + fn render(&self, + ctx: &context::Context, st: &mut state::State, r: &mut renderer::Renderer<assets::Assets>, + ) -> Erm<()> { + let base = glam::Vec2::new(90.0, 250.0); + let off = glam::Vec2::new(90.0, 0.0); + let t = st.tick as f32 / 10.0; + for i in 0..NUM_LIVES { + let fi = i as f32; + let pos = base + fi * off; + let osc = (t + fi * 10.0).sin(); + if self.lives[i].is_active() { + let hoff = self.lives[i].progress(st.tick) * st.render_dims.x; + draw_mr_armed(ctx, st, r, MrColor::Blue, pos + glam::Vec2::new(hoff, 0.0), osc)?; + } else { + draw_mr_armed(ctx, st, r, MrColor::Green, pos, osc)?; + }; + } + Ok(()) + } +} + +pub fn draw_texture_rotated_about( + ctx: &context::Context, st: &mut state::State, r: &mut renderer::Renderer<assets::Assets>, + texture: assets::Texture, flip: bool, hueset: Option<f32>, + pos: glam::Vec2, dims: glam::Vec2, joint: glam::Vec2, angle: f32, +) -> Erm<()> { + let origin_offset = glam::Vec3::new(-st.render_dims.x / 2.0, st.render_dims.y / 2.0, 0.0); + r.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR | UberFlags::EFFECTS); + r.set_i32(ctx, st, "effect_flip", flip as i32); + r.set_f32(ctx, st, "effect_flash", 0.0); + r.set_f32(ctx, st, "effect_huescale", if hueset.is_some() { 0.0 } else { 1.0 }); + r.set_f32(ctx, st, "effect_hueshift", if let Some(hs) = hueset { hs } else { 0.0 }); + r.bind_texture(ctx, st, texture); + r.set_position_2d_mat(ctx, st, + glam::Mat4::from_translation(glam::Vec3::new(pos.x, -pos.y, 0.0) + origin_offset) + .mul_mat4(&glam::Mat4::from_translation(glam::Vec3::new(joint.x, -joint.y, 0.0))) + .mul_mat4(&glam::Mat4::from_rotation_z(angle)) + .mul_mat4(&glam::Mat4::from_translation(glam::Vec3::new(-joint.x, joint.y, 0.0))) + .mul_mat4(&glam::Mat4::from_scale(glam::Vec3::new(dims.x / 2.0, dims.y / 2.0, 1.0))), + ); + r.render_square(ctx, st); + Ok(()) +} + +fn draw_mr_armed( + ctx: &context::Context, st: &mut state::State, r: &mut renderer::Renderer<assets::Assets>, + mr: MrColor, center: glam::Vec2, oscillation: f32, +) -> Erm<()> { + let dims = glam::Vec2::new(48.0, 48.0); + let pos = center + glam::Vec2::new(0.0, 4.0 * oscillation); + let topleft = pos - dims / 2.0; + let leftedge = pos.x - dims.x / 2.0; + let rightedge = pos.x + dims.x / 2.0; + let armheight = pos.y - dims.y / 3.0; + let legheight = pos.y + dims.y / 2.0; + let legangle = 0.2 * oscillation; + let armangle = 0.1 * oscillation; + let origin_offset = glam::Vec3::new(-st.render_dims.x / 2.0, st.render_dims.y / 2.0, 0.0); + draw_texture_rotated_about(ctx, st, r, + assets::Texture::Timbs, true, None, + glam::Vec2::new(leftedge, legheight), + dims, + glam::Vec2::new(dims.x / 2.0, -dims.y / 2.0), + legangle, + )?; + draw_texture_rotated_about(ctx, st, r, + assets::Texture::Timbs, false, None, + glam::Vec2::new(rightedge, legheight), + dims, + glam::Vec2::new(-dims.x / 2.0, -dims.y / 2.0), + -legangle, + )?; + if mr == MrColor::Green { + draw_texture_rotated_about(ctx, st, r, + assets::Texture::Arm, true, Some(mr.hue()), + glam::Vec2::new(leftedge, armheight), + dims, + glam::Vec2::new(dims.x / 2.0, dims.y / 2.0), + armangle, + )?; + draw_texture_rotated_about(ctx, st, r, + assets::Texture::Arm, false, Some(mr.hue()), + glam::Vec2::new(rightedge, armheight), + dims, + glam::Vec2::new(-dims.x / 2.0, dims.y / 2.0), + -armangle, + )?; + } + r.texture_screen(ctx, st, + mr.texture(), + topleft, + dims, + ); + Ok(()) } pub struct Game { - assets: Assets, + renderer: renderer::Renderer<assets::Assets>, + lives: Lives, } impl Game { pub fn new(ctx: &context::Context) -> Self { Self { - assets: Assets::new(ctx), + renderer: renderer::Renderer::new(ctx, assets::Assets::new), + lives: Lives::new(), } } } @@ -39,29 +167,31 @@ impl Game { impl teleia::state::Game for Game { fn initialize_audio(&self, ctx: &context::Context, st: &state::State, actx: &audio::Context) -> HashMap<String, audio::Audio> { HashMap::from_iter(vec![ - ("test".to_owned(), audio::Audio::new(&actx, include_bytes!("assets/audio/test.wav"))), + ("footsteps".to_owned(), audio::Audio::new(&actx, include_bytes!("assets/audio/footsteps.wav"))), ]) } - fn update(&mut self, _ctx: &context::Context, _st: &mut state::State) -> Erm<()> { + fn update(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { + if st.keys.new_a() { + log::info!("yo"); + self.lives.lose_life(ctx, st); + st.audio.play_sfx("footsteps"); + } Ok(()) } fn render(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { - ctx.clear_color(glam::Vec4::new(1.0, 0.0, 0.0, 0.5)); + ctx.clear_color(glam::Vec4::ZERO); ctx.clear(); - self.assets.font.render_text_at( - ctx, st, - glam::Vec2::new(0.0, 0.0), - "hello computer", - font::BitmapParams::default(), - ); - st.bind_2d(ctx, &self.assets.shader_flat); - self.assets.texture_test.bind(ctx); - self.assets.shader_flat.set_position_2d( - ctx, st, - &glam::Vec2::new(40.0, 40.0), - &glam::Vec2::new(16.0, 16.0), - ); - self.assets.mesh_square.render(ctx); + self.renderer.text_screen(ctx, st, glam::Vec2::new(0.0, 0.0), "hi"); + self.lives.render(ctx, st, &mut self.renderer)?; Ok(()) } } + +#[wasm_bindgen] +pub fn lose_life() { + contextualize(|ctx, st, g: &mut Game| { + log::info!("lose a life"); + g.lives.lose_life(ctx, st); + st.audio.play_sfx("footsteps"); + }); +} diff --git a/2026/framing/src/lagerboy.png b/2026/framing/src/lagerboy.png Binary files differnew file mode 100644 index 0000000..89992f7 --- /dev/null +++ b/2026/framing/src/lagerboy.png diff --git a/2026/framing/src/lib.rs b/2026/framing/src/lib.rs index fa27675..19ac407 100644 --- a/2026/framing/src/lib.rs +++ b/2026/framing/src/lib.rs @@ -1,4 +1,5 @@ mod game; +mod assets; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; @@ -6,5 +7,5 @@ use wasm_bindgen::prelude::*; #[cfg(target_arch = "wasm32")] #[wasm_bindgen] pub fn main_js() { - teleia::run(240, 160, teleia::Options::OVERLAY, game::Game::new); + teleia::run(480, 320, teleia::Options::OVERLAY, game::Game::new); } |
