Skip to content

Commit

Permalink
Main Menu Code
Browse files Browse the repository at this point in the history
  • Loading branch information
frederickjjoubert committed Mar 28, 2023
1 parent a05fa7c commit c5f157e
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 5 deletions.
Binary file added assets/fonts/FiraSans-Bold.ttf
Binary file not shown.
10 changes: 10 additions & 0 deletions src/main_menu/components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use bevy::prelude::Component;

#[derive(Component)]
pub struct MainMenu {}

#[derive(Component)]
pub struct PlayButton {}

#[derive(Component)]
pub struct QuitButton {}
24 changes: 19 additions & 5 deletions src/main_menu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
mod components;
mod styles;
mod systems;

use systems::interactions::*;
use systems::layout::*;

use bevy::prelude::*;

use crate::AppState;

pub struct MainMenuPlugin;

impl Plugin for MainMenuPlugin {
fn build(&self, app: &mut App) {
app.add_startup_system(main_menu);
app
// OnEnter State Systems
.add_system(spawn_main_menu.in_schedule(OnEnter(AppState::MainMenu)))
// Systems
.add_systems(
(interact_with_play_button, interact_with_quit_button)
.in_set(OnUpdate(AppState::MainMenu)),
)
// OnExit State Systems
.add_system(despawn_main_menu.in_schedule(OnExit(AppState::MainMenu)));
}
}

pub fn main_menu() {
println!("You are on the main menu.");
}
51 changes: 51 additions & 0 deletions src/main_menu/styles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use bevy::prelude::*;

pub const NORMAL_BUTTON_COLOR: Color = Color::rgb(0.15, 0.15, 0.15);
pub const HOVERED_BUTTON_COLOR: Color = Color::rgb(0.25, 0.25, 0.25);
pub const PRESSED_BUTTON_COLOR: Color = Color::rgb(0.35, 0.75, 0.35);

pub const MAIN_MENU_STYLE: Style = Style {
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
gap: Size::new(Val::Px(8.0), Val::Px(8.0)),
..Style::DEFAULT
};

pub const BUTTON_STYLE: Style = Style {
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
size: Size::new(Val::Px(200.0), Val::Px(80.0)),
..Style::DEFAULT
};

pub const IMAGE_STYLE: Style = Style {
size: Size::new(Val::Px(64.0), Val::Px(64.0)),
margin: UiRect::new(Val::Px(8.0), Val::Px(8.0), Val::Px(8.0), Val::Px(8.0)),
..Style::DEFAULT
};

pub const TITLE_STYLE: Style = Style {
flex_direction: FlexDirection::Row,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
size: Size::new(Val::Px(300.0), Val::Px(120.0)),
..Style::DEFAULT
};

pub fn get_title_text_style(asset_server: &Res<AssetServer>) -> TextStyle {
TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 64.0,
color: Color::WHITE,
}
}

pub fn get_button_text_style(asset_server: &Res<AssetServer>) -> TextStyle {
TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 32.0,
color: Color::WHITE,
}
}
52 changes: 52 additions & 0 deletions src/main_menu/systems/interactions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use bevy::app::AppExit;
use bevy::prelude::*;

use crate::main_menu::components::*;
use crate::main_menu::styles::{HOVERED_BUTTON_COLOR, NORMAL_BUTTON_COLOR, PRESSED_BUTTON_COLOR};
use crate::AppState;

pub fn interact_with_play_button(
mut button_query: Query<
(&Interaction, &mut BackgroundColor),
(Changed<Interaction>, With<PlayButton>),
>,
mut app_state_next_state: ResMut<NextState<AppState>>,
) {
if let Ok((interaction, mut background_color)) = button_query.get_single_mut() {
match *interaction {
Interaction::Clicked => {
*background_color = PRESSED_BUTTON_COLOR.into();
app_state_next_state.set(AppState::Game);
}
Interaction::Hovered => {
*background_color = HOVERED_BUTTON_COLOR.into();
}
Interaction::None => {
*background_color = NORMAL_BUTTON_COLOR.into();
}
}
}
}

pub fn interact_with_quit_button(
mut app_exit_event_writer: EventWriter<AppExit>,
mut button_query: Query<
(&Interaction, &mut BackgroundColor),
(Changed<Interaction>, With<QuitButton>),
>,
) {
if let Ok((interaction, mut background_color)) = button_query.get_single_mut() {
match *interaction {
Interaction::Clicked => {
*background_color = PRESSED_BUTTON_COLOR.into();
app_exit_event_writer.send(AppExit);
}
Interaction::Hovered => {
*background_color = HOVERED_BUTTON_COLOR.into();
}
Interaction::None => {
*background_color = NORMAL_BUTTON_COLOR.into();
}
}
}
}
108 changes: 108 additions & 0 deletions src/main_menu/systems/layout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use bevy::prelude::*;

use crate::main_menu::components::*;
use crate::main_menu::styles::*;

pub fn spawn_main_menu(mut commands: Commands, asset_server: Res<AssetServer>) {
let main_menu_entity = build_main_menu(&mut commands, &asset_server);
}

pub fn despawn_main_menu(mut commands: Commands, main_menu_query: Query<Entity, With<MainMenu>>) {
if let Ok(main_menu_entity) = main_menu_query.get_single() {
commands.entity(main_menu_entity).despawn_recursive();
}
}

pub fn build_main_menu(commands: &mut Commands, asset_server: &Res<AssetServer>) -> Entity {
let main_menu_entity = commands
.spawn((
NodeBundle {
style: MAIN_MENU_STYLE,
..default()
},
MainMenu {},
))
.with_children(|parent| {
// === Title ===
parent
.spawn(NodeBundle {
style: TITLE_STYLE,
..default()
})
.with_children(|parent| {
// Image 1
parent.spawn(ImageBundle {
style: IMAGE_STYLE,
image: asset_server.load("sprites/ball_blue_large.png").into(),
..default()
});
// Text
parent.spawn(TextBundle {
text: Text {
sections: vec![TextSection::new(
"Bevy Ball Game",
get_title_text_style(&asset_server),
)],
alignment: TextAlignment::Center,
..default()
},
..default()
});
// Image 2
parent.spawn(ImageBundle {
style: IMAGE_STYLE,
image: asset_server.load("sprites/ball_red_large.png").into(),
..default()
});
});
// === Play Button ===
parent
.spawn((
ButtonBundle {
style: BUTTON_STYLE,
background_color: NORMAL_BUTTON_COLOR.into(),
..default()
},
PlayButton {},
))
.with_children(|parent| {
parent.spawn(TextBundle {
text: Text {
sections: vec![TextSection::new(
"Play",
get_button_text_style(&asset_server),
)],
alignment: TextAlignment::Center,
..default()
},
..default()
});
});
// === Quit Button ===
parent
.spawn((
ButtonBundle {
style: BUTTON_STYLE,
background_color: NORMAL_BUTTON_COLOR.into(),
..default()
},
QuitButton {},
))
.with_children(|parent| {
parent.spawn(TextBundle {
text: Text {
sections: vec![TextSection::new(
"Quit",
get_button_text_style(&asset_server),
)],
alignment: TextAlignment::Center,
..default()
},
..default()
});
});
})
.id();

main_menu_entity
}
2 changes: 2 additions & 0 deletions src/main_menu/systems/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod interactions;
pub mod layout;

0 comments on commit c5f157e

Please sign in to comment.