--- a/assets/background.wgsl +++ b/assets/background.wgsl @@ -4,7 +4,7 @@ #import bevy_sprite::mesh2d_vertex_output::VertexOutput struct BackgroundMaterial { - time: f32, + time: vec4, }; @group(2) @binding(0) @@ -30,7 +30,7 @@ in: VertexOutput ) -> @location(0) vec4 { let dir = vec3(in.uv * zoom, 1.0); - let time = background.time * speed + 0.25; + let time = background.time.x * speed + 0.25; var from_ = vec3(1.0, 0.5, 0.5); from_ = from_ + vec3(time * 2., time, -2.); --- a/Cargo.lock +++ b/Cargo.lock @@ -280,24 +280,6 @@ ] [[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.1.2", - "slab", - "windows-sys 0.61.2", -] - -[[package]] name = "async-lock" version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -957,7 +939,6 @@ "bevy_post_process", "bevy_ptr", "bevy_reflect", - "bevy_remote", "bevy_render", "bevy_scene", "bevy_shader", @@ -1239,31 +1220,6 @@ ] [[package]] -name = "bevy_remote" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e053684d1735e62d8e491cb68f5d9f7219edcb6528d1ac5fe179f24e5fe497" -dependencies = [ - "anyhow", - "async-channel", - "async-io", - "bevy_app", - "bevy_asset", - "bevy_derive", - "bevy_ecs", - "bevy_log", - "bevy_platform", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "http-body-util", - "hyper", - "serde", - "serde_json", - "smol-hyper", -] - -[[package]] name = "bevy_render" version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1454,7 +1410,6 @@ dependencies = [ "async-channel", "async-executor", - "async-io", "async-task", "atomic-waker", "bevy_platform", @@ -2536,8 +2491,10 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -2920,73 +2877,6 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", -] - -[[package]] name = "image" version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3129,6 +3019,7 @@ "avian2d", "bevy", "bevy_hanabi", + "getrandom 0.2.16", "leafwing-input-manager", "rand 0.8.5", ] @@ -4091,12 +3982,6 @@ checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] name = "piper" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4780,19 +4665,6 @@ ] [[package]] -name = "smol-hyper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7428a49d323867702cd12b97b08a6b0104f39ec13b49117911f101271321bc1a" -dependencies = [ - "async-executor", - "async-io", - "futures-io", - "hyper", - "pin-project-lite", -] - -[[package]] name = "smol_str" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5017,15 +4889,6 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "tokio" -version = "1.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" -dependencies = [ - "pin-project-lite", -] - -[[package]] name = "toml_datetime" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,12 @@ opt-level = 3 [dependencies] -bevy = { version = "0.17", features = ["bevy_remote"] } +# Browser build: without "bevy_remote" (a debug-only HTTP inspector whose dependencies do not build for the web). +bevy = { version = "0.17" } leafwing-input-manager = "0.18" rand = "0.8" bevy_hanabi = "0.17" -avian2d = { version = "0.4" , features = [ "debug-plugin" ] } \ No newline at end of file +avian2d = { version = "0.4" , features = [ "debug-plugin" ] } +# Browser build: rand 0.8 uses getrandom 0.2, which needs its "js" feature on the web. +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] } --- a/src/background.rs +++ b/src/background.rs @@ -24,14 +24,15 @@ commands.spawn(( Mesh2d(meshes.add(Rectangle::default())), Transform::from_scale(Vec3::new(ARENA_WIDTH, ARENA_HEIGHT, 1.0)), - MeshMaterial2d(materials.add(BackgroundMaterial { time: 0.0 })), + MeshMaterial2d(materials.add(BackgroundMaterial { time: Vec4::ZERO })), )); } #[derive(Asset, AsBindGroup, Debug, Clone, TypePath)] struct BackgroundMaterial { + // Browser build: WebGL2 needs uniform buffers in multiples of 16 bytes, so the time goes in a vec4 (x). #[uniform(0)] - time: f32, + time: Vec4, } impl Material2d for BackgroundMaterial { @@ -47,7 +48,7 @@ ) { if state.is_none() || state.unwrap().get() != &GameState::Paused { for (_, background) in backgrounds.iter_mut() { - background.time += time.delta_secs(); + background.time.x += time.delta_secs(); } } } --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,7 @@ } use avian2d::prelude::PhysicsPlugins; +#[cfg(all(debug_assertions, not(target_arch = "wasm32")))] use bevy::remote::{RemotePlugin, http::RemoteHttpPlugin}; use crate::prelude::*; @@ -38,17 +39,23 @@ let mut app = App::new(); app.insert_resource(ClearColor(Color::srgb_u8(0, 0, 0))); - app.add_plugins(DefaultPlugins.set(WindowPlugin { + app.add_plugins(DefaultPlugins.set(bevy::asset::AssetPlugin { + // Browser build: no .meta files next to the assets, so do not ask the server for them. + meta_check: bevy::asset::AssetMetaCheck::Never, + ..default() + }).set(WindowPlugin { primary_window: Some(Window { title: "Kataster".to_string(), resolution: (ARENA_WIDTH as u32, ARENA_HEIGHT as u32).into(), + // Browser build: the page's canvas #bevy, scaled to fit by the page. + canvas: Some("#bevy".into()), ..default() }), ..default() })); // Add some plugins to help debugging only when compiled in debug mode - #[cfg(debug_assertions)] + #[cfg(all(debug_assertions, not(target_arch = "wasm32")))] // Enable Avian2d debug renders app.add_plugins(PhysicsDebugPlugin::default()) // Enable connection to external tools, like vscode inspector --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -56,13 +56,20 @@ commands.insert_resource(ActionState::::default()); } +// A web page cannot quit: the browser build leaves out the last entry of every menu ("Exit"). +fn web_entries(mut entries: Vec) -> Vec { + #[cfg(target_arch = "wasm32")] + entries.pop(); + entries +} + fn spawn_main_menu(mut commands: Commands, assets: ResMut) { let entity = MenuHandler { main_text: "Kataster".into(), main_text_color: Color::srgb(0.0, 0.7, 0.7), main_text_blink: false, selected_id: 0, - entries: vec!["Play".into(), "Credits".into(), "Exit".into()], + entries: web_entries(vec!["Play".into(), "Credits".into(), "Exit".into()]), } .spawn(&mut commands, assets.font.clone()); commands @@ -76,7 +83,7 @@ main_text_color: Color::srgb_u8(0xAA, 0x22, 0x22), main_text_blink: false, selected_id: 0, - entries: vec!["Menu".into(), "Exit".into()], + entries: web_entries(vec!["Menu".into(), "Exit".into()]), } .spawn(&mut commands, assets.font.clone()); commands @@ -90,7 +97,7 @@ main_text_color: Color::srgb_u8(0xF8, 0xE4, 0x73), main_text_blink: true, selected_id: 0, - entries: vec!["Resume".into(), "Menu".into(), "Exit".into()], + entries: web_entries(vec!["Resume".into(), "Menu".into(), "Exit".into()]), } .spawn(&mut commands, assets.font.clone()); commands @@ -104,7 +111,7 @@ main_text_color: Color::srgb(0.0, 0.7, 0.7), main_text_blink: false, selected_id: 0, - entries: vec!["Menu".into(), "Exit".into()], + entries: web_entries(vec!["Menu".into(), "Exit".into()]), } .spawn(&mut commands, assets.font.clone()); commands