diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..f6ae742 Binary files /dev/null and b/assets/logo.png differ diff --git a/src/menu.rs b/src/menu.rs index dc7fdd3..2a4fbc4 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -1,3 +1,5 @@ +// Note: this is more of a "ui" than a "menu" module + use bevy::{ color::palettes::css::{BLACK, WHITE}, prelude::*, @@ -6,7 +8,7 @@ use bevy::{ use crate::{ boot, deck::{Card, Deck, ItemColor, ItemNumber, ItemPattern, ItemShape}, - play::{check_for_sets, check_set}, + play::{check_for_sets, check_set, SetNumber}, view::{button_set_state, ViewState}, }; @@ -15,15 +17,15 @@ pub struct MenuPlugin; impl Plugin for MenuPlugin { fn build(&self, app: &mut App) { - app.add_systems( + app.add_observer(set_set_count).add_systems( Startup, ( setup, + setup_play, setup_about, setup_how_to_play.after(boot::load), setup_deck, setup_sets, - setup_set_check_button, ), ); } @@ -43,7 +45,7 @@ fn button_builder(node: Node) -> (Button, BackgroundColor, Node, BorderColor) { ) } -fn setup(mut commands: Commands) { +fn setup(mut commands: Commands, server: Res) { commands .spawn(( ViewState::Menu, @@ -59,12 +61,24 @@ fn setup(mut commands: Commands) { .with_children(|parent| { parent .spawn(Node { + width: Val::Percent(100.0), flex_direction: FlexDirection::Column, align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }) .with_children(|parent| { + parent.spawn(( + ImageNode { + image: server.load("logo.png"), + ..default() + }, + Node { + height: Val::Px(300.0), + ..default() + }, + )); + parent .spawn(button_builder(Node::default())) .with_children(|parent| { @@ -101,40 +115,75 @@ fn setup(mut commands: Commands) { .observe(quit_button); }); }); +} + +#[derive(Component)] +pub(crate) struct SetCounter; +fn setup_play(mut commands: Commands) { commands - .spawn((ViewState::Play, Node::default())) + .spawn(( + ViewState::Play, + Node { + width: Val::Percent(100.0), + justify_content: JustifyContent::SpaceBetween, + ..default() + }, + )) .with_children(|parent| { parent - .spawn((button_builder(Node::default()), GlobalZIndex(1))) + .spawn(( + Button, + BackgroundColor(BLACK.with_alpha(0.9).into()), + Node { + margin: UiRect::all(Val::Px(5.0)), + padding: UiRect::all(Val::Px(10.0)), + border: UiRect::all(Val::Px(1.0)), + ..default() + }, + BorderColor(WHITE.into()), + GlobalZIndex(1), + )) .with_children(|parent| { parent.spawn(Text("Menu".to_string())); }) .observe(button_hover_on) .observe(button_hover_off) .observe(button_set_state(ViewState::Menu)); - /* - parent - .spawn((button_builder(Node::default()), GlobalZIndex(1))) - .with_children(|parent| { - parent.spawn(Text("Deck".to_string())); - }) - .observe(button_hover_on) - .observe(button_hover_off) - .observe(button_set_state(ViewState::Deck)); - */ - /* + parent - .spawn((button_builder(Node::default()), GlobalZIndex(1))) + .spawn(( + Button, + BackgroundColor(BLACK.with_alpha(0.9).into()), + Node { + margin: UiRect::all(Val::Px(5.0)), + padding: UiRect::all(Val::Px(10.0)), + border: UiRect::all(Val::Px(1.0)), + ..default() + }, + BorderColor(WHITE.into()), + GlobalZIndex(1), + )) .with_children(|parent| { - parent.spawn(Text("Sets".to_string())); + parent.spawn(Text("Set!".to_string())); }) .observe(button_hover_on) .observe(button_hover_off) - .observe(button_set_state(ViewState::Sets)); - */ + .observe(check_set); + parent - .spawn((button_builder(Node::default()), GlobalZIndex(1))) + .spawn(( + Button, + BackgroundColor(BLACK.with_alpha(0.9).into()), + Node { + margin: UiRect::all(Val::Px(5.0)), + padding: UiRect::all(Val::Px(10.0)), + border: UiRect::all(Val::Px(1.0)), + ..default() + }, + BorderColor(WHITE.into()), + GlobalZIndex(1), + )) .with_children(|parent| { parent.spawn(Text("Help!".to_string())); }) @@ -142,18 +191,105 @@ fn setup(mut commands: Commands) { .observe(button_hover_off) .observe(check_for_sets); }); + + commands + .spawn(( + Node { + position_type: PositionType::Absolute, + bottom: Val::Px(0.0), + width: Val::Percent(100.0), + justify_content: JustifyContent::End, + ..default() + }, + ViewState::Play, + )) + .with_children(|parent| { + parent + .spawn(( + Node { + padding: UiRect::all(Val::Px(10.0)), + margin: UiRect::all(Val::Px(10.0)), + border: UiRect::all(Val::Px(1.0)), + ..default() + }, + BackgroundColor(Color::BLACK.with_alpha(0.9).into()), + BorderColor(WHITE.into()), + )) + .with_children(|parent| { + parent.spawn(Text("Sets:".into())); + parent.spawn((Text("##".into()), SetCounter)); + }); + }); +} + +fn set_set_count( + trigger: Trigger, + mut query: Query<&mut Text, With>, + set_number: Query<&SetNumber>, +) { + query.single_mut().0 = format!("{}", set_number.get(trigger.entity()).unwrap().0); } fn setup_about(mut commands: Commands) { commands - .spawn((ViewState::About, Node::default())) + .spawn(( + ViewState::About, + Node { + position_type: PositionType::Absolute, + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + flex_direction: FlexDirection::Column, + ..default() + }, + )) .with_children(|parent| { parent - .spawn(button_builder(Node::default())) + .spawn(button_builder(Node { + position_type: PositionType::Absolute, + top: Val::Px(0.0), + left: Val::Px(0.0), + ..default() + })) .with_children(|parent| { parent.spawn(Text("Menu".to_string())); }) .observe(button_set_state(ViewState::Menu)); + + parent + .spawn(( + Node { + width: Val::Px(500.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + flex_direction: FlexDirection::Column, + ..default() + }, + BackgroundColor(BLACK.with_alpha(0.9).into()), + )) + .with_children(|parent| { + parent.spawn(( + Text("About the Game".into()), + TextFont::default().with_font_size(30.0), + )); + parent.spawn(( + Text("The real-time card game SET! originally designed by Marsha Falco and published by Set Enterprises.".into()), + Node { + margin: UiRect::all(Val::Px(5.0)), + padding: UiRect::all(Val::Px(5.0)), + ..default() + }, + )); + parent.spawn(( + Text("This videogame version was developed by Elijah Voigt.".into()), + Node { + margin: UiRect::all(Val::Px(5.0)), + padding: UiRect::all(Val::Px(5.0)), + ..default() + }, + )); + }); }); } @@ -332,30 +468,6 @@ fn setup_sets(mut commands: Commands) { }); } -pub(crate) fn setup_set_check_button(mut commands: Commands) { - commands - .spawn(( - Node { - width: Val::Percent(100.0), - position_type: PositionType::Absolute, - top: Val::Px(0.0), - flex_direction: FlexDirection::Column, - align_items: AlignItems::Center, - ..default() - }, - Visibility::default(), - ViewState::Play, - )) - .with_children(|parent| { - parent - .spawn(button_builder(Node::default())) - .with_children(|parent| { - parent.spawn(Text("Set!".to_string())); - }) - .observe(check_set); - }); -} - fn quit_button(_trigger: Trigger>, mut exit_event: EventWriter) { exit_event.send(AppExit::Success); }