Files
Space-Game/apps/game/src/ui/main_menu.rs
francy51 75f58bcd54 Rename galaxy_creation to galaxy; add character creation skeleton
- Rename GalaxyCreationPlugin -> GalaxyPlugin, AppState::GalaxyCreation
  -> AppState::Galaxy, module path galaxy_creation -> galaxy (folder
  rename preserves git history via git mv).
- Rename GalaxyCreationSpawned -> GalaxySpawned, despawn_galaxy_creation
  -> despawn_galaxy.
- Update AGENTS.md module layout, plugin pattern example, and naming
  table for the new names.
- Add apps/game/src/gameplay/character_creation/ skeleton: placeholder
  UI with Confirm (-> InGame) and Back (-> Galaxy) buttons plus Escape
  shortcut. Wired into main.rs via CharacterCreationPlugin.
2026-06-07 17:11:56 -04:00

157 lines
4.8 KiB
Rust

use bevy::prelude::*;
use crate::state::AppState;
// ── Markers ─────────────────────────────────────────────────────────────────
#[derive(Component)]
pub struct MainMenuUi;
#[derive(Component)]
pub enum MenuButton {
ContinueGame, //Needed for later once save game functionality is implemented, should have a check to see if a save game exists and only show this button if it does
NewGame,
Options,
Exit,
}
// ── Main Menu ───────────────────────────────────────────────────────────────
pub fn setup_main_menu(mut commands: Commands) {
let button_style = Node {
width: Val::Px(280.0),
height: Val::Px(64.0),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..default()
};
let button_text_font = TextFont {
font_size: 28.0,
..default()
};
commands
.spawn((
Node {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
display: Display::Flex,
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
row_gap: Val::Px(24.0),
..default()
},
BackgroundColor(Color::srgb(0.02, 0.02, 0.06)),
MainMenuUi,
))
.with_children(|parent| {
// Title
parent.spawn((
Text::new("VOID::NAV"),
TextFont {
font_size: 72.0,
..default()
},
TextColor(Color::srgb(0.7, 0.85, 1.0)),
Node {
margin: UiRect::bottom(Val::Px(48.0)),
..default()
},
));
// Subtitle
parent.spawn((
Text::new("A space exploration RPG"),
TextFont {
font_size: 18.0,
..default()
},
TextColor(Color::srgb(0.4, 0.5, 0.6)),
Node {
margin: UiRect::bottom(Val::Px(32.0)),
..default()
},
));
// Start Game button
spawn_menu_button(
&mut parent.spawn_empty(),
"Start Game",
MenuButton::NewGame,
&button_style,
&button_text_font,
);
// Options button
spawn_menu_button(
&mut parent.spawn_empty(),
"Options",
MenuButton::Options,
&button_style,
&button_text_font,
);
// Exit button
spawn_menu_button(
&mut parent.spawn_empty(),
"Exit",
MenuButton::Exit,
&button_style,
&button_text_font,
);
});
}
fn spawn_menu_button(
cmd: &mut EntityCommands,
label: &str,
marker: MenuButton,
style: &Node,
text_font: &TextFont,
) {
cmd.insert((
Button,
style.clone(),
BackgroundColor(Color::srgb(0.08, 0.1, 0.18)),
BorderColor(Color::srgb(0.3, 0.45, 0.7)),
BorderRadius::all(Val::Px(8.0)),
marker,
))
.with_children(|btn| {
btn.spawn((
Text::new(label),
text_font.clone(),
TextColor(Color::srgb(0.75, 0.85, 1.0)),
));
});
}
pub fn despawn_main_menu(mut commands: Commands, query: Query<Entity, With<MainMenuUi>>) {
for entity in &query {
commands.entity(entity).despawn();
}
}
// ── Button Interaction ──────────────────────────────────────────────────────
pub fn main_menu_buttons(
mut next_state: ResMut<NextState<AppState>>,
mut exit: EventWriter<AppExit>,
interaction_query: Query<(&Interaction, &MenuButton), Changed<Interaction>>,
) {
for (interaction, button) in &interaction_query {
if *interaction == Interaction::Pressed {
match button {
MenuButton::ContinueGame => next_state.set(AppState::InGame), // Placeholder for now
MenuButton::NewGame => next_state.set(AppState::Galaxy),
MenuButton::Options => next_state.set(AppState::Options),
MenuButton::Exit => {
exit.write(AppExit::Success);
}
}
}
}
}