Update menus
This commit is contained in:
parent
614e1fc865
commit
f1cc49caf8
4 changed files with 180 additions and 2 deletions
|
@ -5,8 +5,9 @@ use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash, States)]
|
#[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash, States)]
|
||||||
enum AppState {
|
enum AppState {
|
||||||
MainView,
|
|
||||||
#[default]
|
#[default]
|
||||||
|
Loading,
|
||||||
|
MainView,
|
||||||
Menu,
|
Menu,
|
||||||
List,
|
List,
|
||||||
Graph
|
Graph
|
||||||
|
@ -36,11 +37,15 @@ fn main() {
|
||||||
.insert_resource(ViewerMode::PokerTip2D)
|
.insert_resource(ViewerMode::PokerTip2D)
|
||||||
.init_state::<AppState>()
|
.init_state::<AppState>()
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.add_plugins(((plugins::main_menu::menu_plugin, plugins::main_view::main_view_plugin)))
|
.add_plugins((plugins::loading::loading_plugin, plugins::main_menu::menu_plugin, plugins::main_view::main_view_plugin))
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands) {
|
||||||
|
commands.spawn(Camera2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Generic system that takes a component as a parameter, and will despawn all entities with that component
|
// Generic system that takes a component as a parameter, and will despawn all entities with that component
|
||||||
|
|
59
progress-pile-app/src/plugins/loading.rs
Normal file
59
progress-pile-app/src/plugins/loading.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::{despawn_screen, AppState};
|
||||||
|
|
||||||
|
// This plugin will display a splash screen with Bevy logo for 1 second before switching to the menu
|
||||||
|
pub fn loading_plugin(app: &mut App) {
|
||||||
|
// As this plugin is managing the splash screen, it will focus on the state `GameState::Splash`
|
||||||
|
app
|
||||||
|
// When entering the state, spawn everything needed for this screen
|
||||||
|
.add_systems(OnEnter(AppState::Loading), loading_setup)
|
||||||
|
// While in this state, run the `countdown` system
|
||||||
|
.add_systems(Update, countdown.run_if(in_state(AppState::Loading)))
|
||||||
|
// When exiting the state, despawn everything that was spawned for this screen
|
||||||
|
.add_systems(OnExit(AppState::Loading), despawn_screen::<OnLoadingScreen>);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag component used to tag entities added on the splash screen
|
||||||
|
#[derive(Component)]
|
||||||
|
struct OnLoadingScreen;
|
||||||
|
|
||||||
|
// Newtype to use a `Timer` for this screen as a resource
|
||||||
|
#[derive(Resource, Deref, DerefMut)]
|
||||||
|
struct LoadingTimer(Timer);
|
||||||
|
|
||||||
|
fn loading_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
let icon = asset_server.load("textures/Game Icons/wrench.png");
|
||||||
|
// Display the logo
|
||||||
|
commands.spawn((
|
||||||
|
Node {
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
width: Val::Percent(100.0),
|
||||||
|
height: Val::Percent(100.0),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
OnLoadingScreen,
|
||||||
|
children![(
|
||||||
|
ImageNode::new(icon),
|
||||||
|
Node {
|
||||||
|
// This will set the logo to be 200px wide, and auto adjust its height
|
||||||
|
width: Val::Px(200.0),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
)],
|
||||||
|
));
|
||||||
|
// Insert the timer as a resource
|
||||||
|
commands.insert_resource(LoadingTimer(Timer::from_seconds(1.0, TimerMode::Once)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tick the timer, and change state when finished
|
||||||
|
fn countdown(
|
||||||
|
mut game_state: ResMut<NextState<AppState>>,
|
||||||
|
time: Res<Time>,
|
||||||
|
mut timer: ResMut<LoadingTimer>,
|
||||||
|
) {
|
||||||
|
if timer.tick(time.delta()).finished() {
|
||||||
|
game_state.set(AppState::MainView);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
use bevy::{
|
||||||
|
app::AppExit,
|
||||||
|
color::palettes::css::CRIMSON,
|
||||||
|
ecs::spawn::{SpawnIter, SpawnWith},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
despawn_screen,
|
||||||
|
themes::dark::{self, NORMAL_BUTTON},
|
||||||
|
DisplayQuality,
|
||||||
|
AppState,
|
||||||
|
Volume,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main_view_plugin(app: &mut App) {
|
||||||
|
app
|
||||||
|
.add_systems(OnEnter(AppState::MainView), main_view_setup)
|
||||||
|
.add_systems(OnExit(AppState::MainView), despawn_screen::<OnMainViewScreen>)
|
||||||
|
.add_systems(
|
||||||
|
Update,
|
||||||
|
(menu_action, button_system).run_if(in_state(AppState::MainView))
|
||||||
|
)
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
||||||
|
#[derive(Component)]
|
||||||
|
struct OnMainViewScreen;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct SelectedOption;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
enum MainViewButtonAction {
|
||||||
|
OpenMainMenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_system(
|
||||||
|
mut interaction_query: Query<(&Interaction, &mut BackgroundColor, Option<&SelectedOption>),(Changed<Interaction>, With<Button>)>
|
||||||
|
) {
|
||||||
|
for (interaction, mut background_color, selected) in &mut interaction_query {
|
||||||
|
*background_color = match (*interaction, selected) {
|
||||||
|
(Interaction::Pressed, _) | (_, Some(_)) => dark::PRESSED_BUTTON.into(),
|
||||||
|
(Interaction::Hovered, None) => dark::HOVERED_BUTTON.into(),
|
||||||
|
(Interaction::None, None) => dark::NORMAL_BUTTON.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_view_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
let header_node = Node {
|
||||||
|
width: Val::Percent(100.0),
|
||||||
|
height: Val::Px(20.0),
|
||||||
|
justify_content: JustifyContent::SpaceBetween,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
let body_node = Node{
|
||||||
|
width: Val::Percent(100.0),
|
||||||
|
height: Val::Auto,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
let wrench_icon = asset_server.load("textures/Game Icons/wrench.png");
|
||||||
|
|
||||||
|
commands.spawn((
|
||||||
|
Node {
|
||||||
|
width: Val::Percent(100.0),
|
||||||
|
height: Val::Percent(100.0),
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
OnMainViewScreen,
|
||||||
|
children![(
|
||||||
|
header_node,
|
||||||
|
children![(
|
||||||
|
Button,
|
||||||
|
Node{
|
||||||
|
width: Val::Px(30.0),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
MainViewButtonAction::OpenMainMenu,
|
||||||
|
children![(
|
||||||
|
ImageNode::new(wrench_icon),
|
||||||
|
Node::default()
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
)]
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn menu_action(
|
||||||
|
interaction_query: Query<
|
||||||
|
(&Interaction, &MainViewButtonAction),
|
||||||
|
(Changed<Interaction>, With<Button>),
|
||||||
|
>,
|
||||||
|
mut app_exit_events: EventWriter<AppExit>,
|
||||||
|
mut game_state: ResMut<NextState<AppState>>,
|
||||||
|
) {
|
||||||
|
for (interaction, menu_button_action) in &interaction_query {
|
||||||
|
if *interaction == Interaction::Pressed {
|
||||||
|
match menu_button_action {
|
||||||
|
MainViewButtonAction::OpenMainMenu => {
|
||||||
|
game_state.set(AppState::Menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
|
pub mod loading;
|
||||||
pub mod main_menu;
|
pub mod main_menu;
|
||||||
pub mod main_view;
|
pub mod main_view;
|
Loading…
Add table
Reference in a new issue