diff --git a/Cargo.lock b/Cargo.lock index dfa6872..99744a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -899,6 +899,43 @@ dependencies = [ "tracing-wasm", ] +[[package]] +name = "bevy_lunex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877b8ef6daf3a36403fc859a4017537573d7d05177986fe00ca6fb40c07f2a32" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_derive", + "bevy_ecs", + "bevy_gizmos", + "bevy_image", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_mesh", + "bevy_pbr", + "bevy_picking", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_rich_text3d", + "bevy_sprite", + "bevy_sprite_render", + "bevy_text", + "bevy_time", + "bevy_transform", + "bevy_window", + "bevy_winit", + "colored", + "cosmic-text", + "radsort", + "rand", +] + [[package]] name = "bevy_macro_utils" version = "0.17.3" @@ -1195,6 +1232,20 @@ dependencies = [ "syn", ] +[[package]] +name = "bevy_rich_text3d" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d2a20437b6f1c9ef6371b0ff07731d42b565ce4713c4244c84d36c3e65f497" +dependencies = [ + "bevy", + "cosmic-text", + "rustc-hash 2.1.1", + "sys-locale", + "thiserror 2.0.17", + "zeno", +] + [[package]] name = "bevy_scene" version = "0.17.3" @@ -1322,6 +1373,7 @@ name = "bevy_stock_photo" version = "0.1.0" dependencies = [ "bevy", + "bevy_lunex", "bevy_prototype_lyon", "enumset", "rand", @@ -1764,6 +1816,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "combine" version = "4.6.7" diff --git a/Cargo.toml b/Cargo.toml index d24b3d3..ad3c664 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] bevy = "0.17.3" +bevy_lunex = "0.5.0" bevy_prototype_lyon = "0.15.0" enumset = "1.1.10" rand = "0.9.2" diff --git a/src/gameplay/navi.rs b/src/gameplay/navi.rs index cb57c84..def8fa4 100644 --- a/src/gameplay/navi.rs +++ b/src/gameplay/navi.rs @@ -49,7 +49,7 @@ pub fn setup_scene( // clear_color: ClearColorConfig::None, ..default() }, - Bloom::NATURAL, + // Bloom::NATURAL, RenderLayers::layer(0), )); } diff --git a/src/gameplay/pause.rs b/src/gameplay/pause.rs index 1fb5aa0..5ef3b3f 100644 --- a/src/gameplay/pause.rs +++ b/src/gameplay/pause.rs @@ -6,6 +6,8 @@ use bevy::{ render::render_resource::{Extent3d, TextureDimension, TextureFormat}, sprite::Anchor, }; +use bevy_lunex::{Rectangle2D, UiState, prelude::*}; +use bevy_prototype_lyon::prelude::*; use crate::{ GameState, PauseState, @@ -20,15 +22,17 @@ pub struct PausePlugin; impl Plugin for PausePlugin { fn build(&self, app: &mut App) { - app.add_systems(Startup, setup_pause).add_systems( - Update, - ( - listen_for_pause.run_if(in_state(PauseState::Running)), - listen_for_unpause.run_if(in_state(PauseState::Paused)), - animate_in.run_if(in_state(PauseState::AnimatingIntoPause)), - animate_out.run_if(in_state(PauseState::AnimatingOutOfPause)), - ), - ); + app.add_plugins((UiLunexPlugins, UiLunexDebugPlugin::<3, 0>)) + .add_systems(Startup, setup_pause) + .add_systems( + Update, + ( + listen_for_pause.run_if(in_state(PauseState::Running)), + listen_for_unpause.run_if(in_state(PauseState::Paused)), + animate_in.run_if(in_state(PauseState::AnimatingIntoPause)), + animate_out.run_if(in_state(PauseState::AnimatingOutOfPause)), + ), + ); } } @@ -45,68 +49,113 @@ fn setup_pause( mut materials: ResMut>, mut images: ResMut>, ) { - // commands.spawn(( - // Mesh2d(meshes.add(Triangle2d::new( - // Vec2::new(-100., -100.), - // Vec2::new(-100., 100.), - // Vec2::new(-100., 100.), - // ))), - // MeshMaterial2d(materials.add(Color::srgb(0.2, 0.2, 0.3))), - // RenderLayers::layer(3), - // )); - - let cam = commands - .spawn(( - PauseCamera, - Camera2d, - Camera { - order: 3, - clear_color: ClearColorConfig::None, - ..default() - }, - // Bloom::NATURAL, - RenderLayers::layer(3), - )) - .id(); + // Spawn camera commands.spawn(( - Node { - position_type: PositionType::Relative, - width: px(200), - height: px(700), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, + // This camera will become the source for all UI paired to index 0. + Camera2d, + PauseCamera, + UiSourceCamera::<0>, + // Ui nodes start at 0 and move + on the Z axis with each depth layer. + // This will ensure you will see up to 1000 nested children. + Camera { + order: 2, + clear_color: ClearColorConfig::None, ..default() }, - // UiTransform::from_translation(Val2::px(0., 0.)), - BackgroundColor(COLOR_BG), - Visibility::Visible, - PauseMenuRoot, - children![( - Button, - Node { - width: px(150), - height: px(65), - border: UiRect::all(px(5)), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, - position_type: PositionType::Relative, - ..default() - }, - BorderColor::all(Color::WHITE), - BorderRadius::MAX, - BackgroundColor(COLOR_HL1), - children![( - Text::new("Button"), - TextFont { - font: assets.load("fonts/GloriaHalleluja.ttf"), - font_size: 33.0, - ..default() - }, - TextColor(Color::srgb(0.9, 0.9, 0.9)), - TextShadow::default(), - )] - )], + Transform::from_translation(Vec3::Z * 1000.0), + RenderLayers::layer(3), )); + + commands + .spawn(( + UiLayoutRoot::new_2d(), + UiFetchFromCamera::<0>, + PauseMenuRoot, + RenderLayers::layer(3), + )) + .with_children(|ui| { + let button_font = TextFont::default() + .with_font(assets.load("fonts/GloriaHalleluja.ttf")) + .with_font_size(256.0); + ui.spawn(( + UiLayout::window().size(Rl(100.)).pack(), + UiMeshPlane2d, + MeshMaterial2d(materials.add(COLOR_BG)), + // UiColor::from(COLOR_BG), + RenderLayers::layer(3), + )); + ui.spawn(( + UiLayout::boundary().pos1(Rl(05.0)).pos2(Rl(95.0)).pack(), + RenderLayers::layer(3), + )) + .with_children(|ui| { + ui.spawn(( + UiLayout::window() + .pos((Rl(5.), Rl(5.))) + .anchor(Anchor::TOP_LEFT) + .pack(), + Text2d::new("Pause"), + UiTextSize::from(Rl(20.)), + UiColor::from(Color::BLACK), + button_font.clone(), // Maybe make bold? + RenderLayers::layer(3), + )); + ui.spawn((UiLayout::boundary() + .pos1((Rl(05.), Rl(30.))) + .pos2((Rl(95.), Rl(90.))) + .pack(),)) + .with_children(|ui| { + let gap: f32 = 20.; + let mut offset: f32 = 0.; + for opt in ["Opt 1", "Opt 2", "Option 3"] { + info!("{}", opt); + ui.spawn(( + UiLayout::window() + .pos((Rl(0.), Rl(offset))) + .size((Rl(40.), Rl(10.))) + .pack(), + RenderLayers::layer(3), + )) + .with_children(|ui| { + ui.spawn(( + UiLayout::boundary() + .pos1((Ab(-1000.0), Rl(0.))) + .pos2((Rl(85.), Rl(100.))) + .pack(), + UiMeshPlane2d, + MeshMaterial2d(materials.add(COLOR_HL2)), + RenderLayers::layer(3), + )); + // Not rendering, needs to be a sprite + ui.spawn(( + Mesh2d(meshes.add(Circle::default())), + UiMeshPlane2d, + MeshMaterial2d(materials.add(COLOR_HL2)), + UiLayout::window() + .pos((Rl(85.), Rl(50.))) + .size(Rh(100.)) + .anchor(Anchor::CENTER) + .pack(), + RenderLayers::layer(3), + )); + ui.spawn(( + UiLayout::window() + .pos((Rl(85.), Rl(50.))) + .anchor(Anchor::CENTER_RIGHT) + .pack(), + Text2d::new(opt), + button_font.clone(), + UiColor::from(Color::BLACK), + UiTextSize::from(Rh(90.)), + RenderLayers::layer(3), + UiDepth::Add(1.), + )); + }); + offset += gap; + } + }); + }); + }); } fn listen_for_pause(