- 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.
157 lines
4.8 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|