use bevy::prelude::*; use crate::{loading::TextureAssets, GameState}; pub struct MenuPlugin; impl Plugin for MenuPlugin { fn build(&self, app: &mut App) { app.add_systems(OnEnter(GameState::Menu), setup) .add_systems(Update, click_button.run_if(in_state(GameState::Menu))) .add_systems(OnExit(GameState::Menu), cleanup); } } #[derive(Component)] struct ButtonColours { normal: Color, hovered: Color, } impl Default for ButtonColours { fn default() -> Self { Self { normal: Color::srgb(88.0 / 255.0, 91.0 / 255.0, 112.0 / 255.0), hovered: Color::srgb(116.0 / 255.0, 199.0 / 255.0, 236.0 / 255.0), } } } #[derive(Component)] struct Menu; fn setup(mut commands: Commands, textures: Res) { commands.spawn((Camera2dBundle::default(), Menu)); commands .spawn(( NodeBundle { style: Style { width: Val::Percent(100.0), height: Val::Percent(100.0), flex_direction: FlexDirection::Column, align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, ..default() }, Menu, )) .with_children(|children| { let button_colours = ButtonColours::default(); children .spawn(( ButtonBundle { style: Style { width: Val::Px(140.0), height: Val::Px(90.0), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, background_color: button_colours.normal.into(), ..default() }, button_colours, ChangeState(GameState::Playing), )) .with_children(|parent| { parent.spawn(TextBundle::from_section( "Play", TextStyle { font_size: 40.0, color: Color::srgb(205.0 / 255.0, 214.0 / 255.0, 244.0 / 255.0), ..default() }, )); }); }); commands .spawn(( NodeBundle { style: Style { flex_direction: FlexDirection::Row, align_items: AlignItems::Center, justify_content: JustifyContent::SpaceAround, bottom: Val::Px(5.), width: Val::Percent(100.), position_type: PositionType::Absolute, ..default() }, ..default() }, Menu, )) .with_children(|children| { children .spawn(( ButtonBundle { style: Style { width: Val::Px(170.0), height: Val::Px(50.0), justify_content: JustifyContent::SpaceAround, align_items: AlignItems::Center, padding: UiRect::all(Val::Px(5.)), ..Default::default() }, background_color: Color::NONE.into(), ..Default::default() }, ButtonColours { normal: Color::NONE, ..default() }, OpenLink("https://bevyengine.org"), )) .with_children(|parent| { parent.spawn(TextBundle::from_section( "Made with Bevy", TextStyle { font_size: 15.0, color: Color::srgb(205.0 / 255.0, 214.0 / 255.0, 244.0 / 255.0), ..default() }, )); parent.spawn(ImageBundle { image: textures.bevy.clone().into(), style: Style { width: Val::Px(32.), ..default() }, ..default() }); }); children .spawn(( ButtonBundle { style: Style { width: Val::Px(170.0), height: Val::Px(50.0), justify_content: JustifyContent::SpaceAround, align_items: AlignItems::Center, padding: UiRect::all(Val::Px(5.)), ..default() }, background_color: Color::NONE.into(), ..Default::default() }, ButtonColours { normal: Color::NONE, ..default() }, OpenLink("https://git.ragarock.moe/silvana/yuno"), )) .with_children(|parent| { parent.spawn(TextBundle::from_section( "repository", TextStyle { font_size: 15.0, color: Color::srgb(205.0 / 255.0, 214.0 / 255.0, 244.0 / 255.0), ..default() }, )); parent.spawn(ImageBundle { image: textures.forgejo.clone().into(), style: Style { width: Val::Px(32.), ..default() }, ..default() }); }); }); } #[derive(Component)] struct ChangeState(GameState); #[derive(Component)] struct OpenLink(&'static str); fn click_button( mut next_state: ResMut>, mut interaction_query: Query< ( &Interaction, &mut BackgroundColor, &ButtonColours, Option<&ChangeState>, Option<&OpenLink>, ), (Changed, With