Inventory screen and project organization

This commit is contained in:
Franklin 2023-11-15 08:01:14 -04:00
parent 494e99a548
commit b79bf00227
18 changed files with 184 additions and 92 deletions

View File

@ -1,15 +1,12 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use crate::{ use crate::{logic::core::player::{
logic::core::player::{
player_movement::{ player_movement::{
move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput, move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput,
}, },
player_values_state::PlayerValuesState, player_values_state::PlayerValuesState,
}, }, ui::game::game_ui_state::GameUiState};
ui::game::settings::SettingsScreenUIConfiguration,
};
use super::markers::player::Player; use super::markers::player::Player;
@ -28,7 +25,7 @@ pub fn capture_input(
With<Player>, With<Player>,
>, >,
time: Res<Time>, time: Res<Time>,
settings_screen_config: Res<SettingsScreenUIConfiguration>, game_ui_state: Res<GameUiState>,
player_values_state: Res<PlayerValuesState>, player_values_state: Res<PlayerValuesState>,
) { ) {
// Don't allocate on each frame. Instead Check if any of the inputs are being pressed and then allocate. // Don't allocate on each frame. Instead Check if any of the inputs are being pressed and then allocate.
@ -56,7 +53,7 @@ pub fn capture_input(
back: keyboard_input.pressed(KeyCode::S), back: keyboard_input.pressed(KeyCode::S),
sprint: keyboard_input.pressed(KeyCode::ShiftLeft), sprint: keyboard_input.pressed(KeyCode::ShiftLeft),
}; };
if settings_screen_config.settings_menu_shown { if game_ui_state.any_window() {
move_player( move_player(
PlayerMovementInput::default(), PlayerMovementInput::default(),
player_query, player_query,

View File

@ -0,0 +1,6 @@
use bevy::ecs::component::Component;
#[derive(Component)]
pub struct InventoryScreenUiMarker;

View File

@ -5,3 +5,5 @@ pub mod holdable;
pub mod interactable; pub mod interactable;
pub mod muzzle_flash; pub mod muzzle_flash;
pub mod player; pub mod player;
pub mod inventory_screen;
pub mod settings_screen;

View File

@ -0,0 +1,4 @@
use bevy::ecs::component::Component;
#[derive(Component)]
pub struct SettingsScreenMarker;

View File

@ -3,8 +3,7 @@ use bevy::{input::mouse::MouseMotion, prelude::*, window::CursorGrabMode};
use crate::{ use crate::{
comps::core::markers::{camera::MainCamera, player::Player}, comps::core::markers::{camera::MainCamera, player::Player},
ui::game::settings::SettingsScreenUIConfiguration, utils::rad_deg::radians_from_degrees, ui::game::game_ui_state::{GameUiState, GameUiWindow},
utils::rad_deg::radians_from_degrees,
}; };
use super::{player_movement::PlayerLinearXZState, player_values_state::PlayerValuesState}; use super::{player_movement::PlayerLinearXZState, player_values_state::PlayerValuesState};
@ -76,24 +75,37 @@ pub fn follow_cursor_with_camera(
keyboard_input: Res<Input<KeyCode>>, keyboard_input: Res<Input<KeyCode>>,
btn: Res<Input<MouseButton>>, btn: Res<Input<MouseButton>>,
time: Res<Time>, time: Res<Time>,
mut settings_screen_config: ResMut<SettingsScreenUIConfiguration>, mut game_ui_state: ResMut<GameUiState>,
player_values_state: Res<PlayerValuesState>, player_values_state: Res<PlayerValuesState>,
) { ) {
if let Ok(mut window) = primary_window.get_single_mut() { if let Ok(mut window) = primary_window.get_single_mut() {
if keyboard_input.just_pressed(KeyCode::Escape) { if keyboard_input.just_pressed(KeyCode::Escape) {
if settings_screen_config.settings_menu_shown { if game_ui_state.any_window() {
// Hide settings screen & Capture Cursor // Hide any UI screen & Capture Cursor
settings_screen_config.settings_menu_shown = false; game_ui_state.current_ui_window_shown = None;
window.cursor.grab_mode = CursorGrabMode::Locked; // use `Locked` mode to keep the cursor in one place window.cursor.grab_mode = CursorGrabMode::Locked; // use `Locked` mode to keep the cursor in one place
window.cursor.visible = false; // also hide the cursor window.cursor.visible = false; // also hide the cursor
} else { } else {
// Show Settings screen & Release Cursor // Show Settings screen & Release Cursor
settings_screen_config.settings_menu_shown = true; game_ui_state.current_ui_window_shown = Some(GameUiWindow::SettingsMenu);
window.cursor.grab_mode = CursorGrabMode::None; // Release cursor window.cursor.grab_mode = CursorGrabMode::None; // Release cursor
window.cursor.visible = true; // Show cursor window.cursor.visible = true; // Show cursor
} }
} }
if settings_screen_config.settings_menu_shown { else if keyboard_input.just_pressed(KeyCode::Tab) {
if game_ui_state.is_showing_window(GameUiWindow::InventoryMenu) {
// Hide the inventory screen only
game_ui_state.current_ui_window_shown = None;
window.cursor.grab_mode = CursorGrabMode::Locked; // use `Locked` mode to keep the cursor in one place
window.cursor.visible = false; // also hide the cursor
} else {
// Show Inventory screen & Release Cursor
game_ui_state.current_ui_window_shown = Some(GameUiWindow::InventoryMenu);
window.cursor.grab_mode = CursorGrabMode::None; // Release cursor
window.cursor.visible = true; // Show cursor
}
}
if game_ui_state.any_window() {
return; return;
} }

View File

@ -19,7 +19,7 @@ use crate::{
equipment::{Equipment, EquipmentChangeEvent}, equipment::{Equipment, EquipmentChangeEvent},
load_state::GameLoadState, load_state::GameLoadState,
}, },
ui::game::{hud::hud::HudState, settings::SettingsScreenUIConfiguration}, ui::game::{hud::hud::HudState, game_ui_state::GameUiState},
utils::{self, rad_deg::radians_from_degrees}, utils::{self, rad_deg::radians_from_degrees},
}; };
@ -28,7 +28,7 @@ pub struct CaptureHandUsageResourcesParams<'w> {
mouse_buttons: Res<'w, Input<MouseButton>>, mouse_buttons: Res<'w, Input<MouseButton>>,
keyboard_input: Res<'w, Input<KeyCode>>, keyboard_input: Res<'w, Input<KeyCode>>,
game_load_state: Res<'w, GameLoadState>, game_load_state: Res<'w, GameLoadState>,
settings_screen_config: Res<'w, SettingsScreenUIConfiguration>, game_ui_state: Res<'w, GameUiState>,
meshes: ResMut<'w, Assets<Mesh>>, meshes: ResMut<'w, Assets<Mesh>>,
materials: ResMut<'w, Assets<StandardMaterial>>, materials: ResMut<'w, Assets<StandardMaterial>>,
animation_clips: Res<'w, Assets<AnimationClip>>, animation_clips: Res<'w, Assets<AnimationClip>>,
@ -70,7 +70,7 @@ pub fn capture_hand_usage(
// Equipping gun // Equipping gun
// Validate player has primary item, and secondary item in inventory // Validate player has primary item, and secondary item in inventory
if !resources.settings_screen_config.settings_menu_shown { if !resources.game_ui_state.any_window() {
if resources.keyboard_input.just_pressed(KeyCode::Key1) { if resources.keyboard_input.just_pressed(KeyCode::Key1) {
if let Some(primary_item) = player_query.single().1.get_primary() { if let Some(primary_item) = player_query.single().1.get_primary() {
if let Some(primary_firearm) = primary_item.get_firearm() { if let Some(primary_firearm) = primary_item.get_firearm() {
@ -142,7 +142,7 @@ pub fn capture_hand_usage(
} else { } else {
// Player is not in a reload animation // Player is not in a reload animation
if resources.keyboard_input.just_pressed(KeyCode::R) if resources.keyboard_input.just_pressed(KeyCode::R)
&& !resources.settings_screen_config.settings_menu_shown && !resources.game_ui_state.any_window()
{ {
// Start reload animation // Start reload animation
for (animation_player_entity, mut animation_player) in for (animation_player_entity, mut animation_player) in
@ -172,7 +172,7 @@ pub fn capture_hand_usage(
} }
// AIMING IN/OUT // AIMING IN/OUT
if resources.mouse_buttons.pressed(MouseButton::Right) if resources.mouse_buttons.pressed(MouseButton::Right)
&& !resources.settings_screen_config.settings_menu_shown && !resources.game_ui_state.any_window()
{ {
let rotation_lerp_quat = hand_transform.rotation.lerp( let rotation_lerp_quat = hand_transform.rotation.lerp(
firearm_data.final_aimed_rotation, firearm_data.final_aimed_rotation,
@ -205,7 +205,7 @@ pub fn capture_hand_usage(
// SHOOTING & RECOIL // SHOOTING & RECOIL
if resources.mouse_buttons.pressed(MouseButton::Left) if resources.mouse_buttons.pressed(MouseButton::Left)
&& !resources.settings_screen_config.settings_menu_shown && !resources.game_ui_state.any_window()
{ {
if player_firing_info.full_auto_timer.finished() { if player_firing_info.full_auto_timer.finished() {
if magazine_data.rounds_shot < magazine_data.max_capacity { if magazine_data.rounds_shot < magazine_data.max_capacity {
@ -284,6 +284,7 @@ pub fn interact_action(
rapier_context: Res<RapierContext>, rapier_context: Res<RapierContext>,
mut hud_state: ResMut<HudState>, mut hud_state: ResMut<HudState>,
mut pickup_item_event_writer: EventWriter<PickupItemEvent>, mut pickup_item_event_writer: EventWriter<PickupItemEvent>,
game_ui_state: Res<GameUiState>,
) { ) {
for (player_entity, transform) in player_query.iter() { for (player_entity, transform) in player_query.iter() {
for global_transform in camera_query.iter() { for global_transform in camera_query.iter() {
@ -303,7 +304,7 @@ pub fn interact_action(
if interactable_entity == entity { if interactable_entity == entity {
hud_state.interaction_clue_shown = true; hud_state.interaction_clue_shown = true;
hud_state.interaction_clue_text = interactable.to_string(); hud_state.interaction_clue_text = interactable.to_string();
if keyboard_input.just_pressed(KeyCode::F) { if keyboard_input.just_pressed(KeyCode::F) && !game_ui_state.any_window() {
// TODO: Move this key to Controls state global // TODO: Move this key to Controls state global
match interactable { match interactable {
Interactable::Holdable => todo!(), Interactable::Holdable => todo!(),

View File

@ -0,0 +1,33 @@
use bevy::prelude::*;
#[derive(Debug, Reflect, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum GameUiWindow {
InventoryMenu,
EscapeMenu,
SettingsMenu,
}
#[derive(Resource, Reflect)]
#[reflect(Resource)]
pub struct GameUiState {
pub current_ui_window_shown: Option<GameUiWindow>,
pub fps_counter_enabled: bool,
}
impl Default for GameUiState {
fn default() -> Self {
Self { current_ui_window_shown: None, fps_counter_enabled: true }
}
}
impl GameUiState {
pub fn is_showing_window(&self, window: GameUiWindow) -> bool {
match self.current_ui_window_shown {
Some(current_ui_window) => window == current_ui_window,
None => false,
}
}
pub fn any_window(&self) -> bool {
self.current_ui_window_shown.is_some()
}
}

View File

@ -1,6 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::ui::game::settings::SettingsScreenUIConfiguration; use crate::ui::game::game_ui_state::GameUiState;
use super::hud::HudState; use super::hud::HudState;
@ -37,14 +37,14 @@ pub fn setup_interact_clue(mut commands: Commands) {
pub fn update_interact_clue( pub fn update_interact_clue(
//mut commands: Commands, //mut commands: Commands,
interact_clue: Res<HudState>, interact_clue: Res<HudState>,
settings_screen_config: Res<SettingsScreenUIConfiguration>, game_ui_state: Res<GameUiState>,
mut query: Query<(&mut Visibility, &mut Text), With<InteractClueHudMarker>>, mut query: Query<(&mut Visibility, &mut Text), With<InteractClueHudMarker>>,
) { ) {
if !settings_screen_config.is_changed() && !interact_clue.is_changed() { if !game_ui_state.is_changed() && !interact_clue.is_changed() {
return; return;
} }
for (mut vis, mut text) in query.iter_mut() { for (mut vis, mut text) in query.iter_mut() {
if settings_screen_config.settings_menu_shown { if game_ui_state.any_window() {
*vis = Visibility::Hidden; *vis = Visibility::Hidden;
return; return;
} }

View File

@ -1,3 +1,4 @@
pub mod hud; pub mod hud;
pub mod interact_clue; pub mod interact_clue;
pub mod plugin; pub mod plugin;
pub mod fps_counter;

View File

@ -2,7 +2,7 @@ use bevy::prelude::*;
use crate::ui::game::hud::hud::HudState; use crate::ui::game::hud::hud::HudState;
use super::interact_clue::{setup_interact_clue, update_interact_clue}; use super::{interact_clue::{setup_interact_clue, update_interact_clue}, fps_counter};
pub struct HudOverlayPlugin; pub struct HudOverlayPlugin;
@ -12,5 +12,7 @@ impl Plugin for HudOverlayPlugin {
app.register_type::<HudState>(); app.register_type::<HudState>();
app.add_systems(Startup, setup_interact_clue); app.add_systems(Startup, setup_interact_clue);
app.add_systems(Update, update_interact_clue); app.add_systems(Update, update_interact_clue);
app.add_systems(Startup, fps_counter::setup_fps_counter);
app.add_systems(Update,fps_counter::tick_fps_counter);
} }
} }

View File

@ -1,9 +1,79 @@
use bevy::prelude::*; use bevy::{prelude::*, ui::FocusPolicy};
use crate::{comps::core::markers::inventory_screen::InventoryScreenUiMarker, ui::game::game_ui_state::{GameUiState, GameUiWindow}};
//use crate::comps::core::events::loot_container::LootContainerEvent;
/// # Inventory Screen /// # Inventory Screen
/// Should contain player inventory and if player is looting something as well /// Should contain player inventory and if player is looting something as well
pub fn setup_inventory_screen(mut _commands: Commands) {} pub fn setup_inventory_screen(mut commands: Commands) {
// Background
let background_id = commands
.spawn((
NodeBundle {
style: Style {
display: Display::Flex,
width: Val::Percent(100.0),
height: Val::Percent(100.0),
justify_content: JustifyContent::Center,
padding: UiRect::percent(3.0, 3.0, 3.0, 3.0),
align_items: AlignItems::Center,
flex_direction: FlexDirection::Row,
..Default::default()
},
visibility: Visibility::Hidden,
background_color: BackgroundColor(Color::rgba(0.0, 0.0, 0.0, 0.9)),
focus_policy: FocusPolicy::Block,
..Default::default()
},
Name::new("Inventory Screen"),
))
.insert(InventoryScreenUiMarker).id();
// Left panel
let left_panel_id = commands.spawn(
NodeBundle {
style: Style {
display: Display::Flex,
width: Val::Percent(50.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
padding: UiRect::all(Val::Percent(5.0)),
flex_direction: FlexDirection::Column,
..Default::default()
},
..Default::default()
}
).set_parent(background_id).id();
// Right panel
let right_panel_id = commands.spawn(
NodeBundle {
style: Style {
display: Display::Flex,
width: Val::Percent(50.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
padding: UiRect::all(Val::Percent(5.0)),
flex_direction: FlexDirection::Column,
..Default::default()
},
..Default::default()
}
).set_parent(background_id).id();
pub fn update_inventory_screen(mut _commands: Commands) {} }
pub fn update_inventory_screen(
mut commands: Commands,
game_ui_state: Res<GameUiState>,
mut inventory_screen_query: Query<&mut Visibility, With<InventoryScreenUiMarker>>,
) {
for mut visibility in inventory_screen_query.iter_mut() {
if game_ui_state.is_showing_window(GameUiWindow::InventoryMenu) {
*visibility = Visibility::Visible;
} else {
*visibility = Visibility::Hidden;
}
}
}

View File

@ -1,7 +1,6 @@
//! Game UI means all the UI that will be part of the actual game //! Game UI means all the UI that will be part of the actual game
pub mod fps_counter;
pub mod hud; pub mod hud;
pub mod inventory; pub mod inventory;
pub mod plugin; pub mod plugin;
pub mod game_ui_state;
pub mod settings; pub mod settings;
pub mod settings_screen;

View File

@ -1,9 +1,7 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::ui::game::settings::GameConfiguration;
use super::{ use super::{
fps_counter, hud, inventory, settings::SettingsScreenUIConfiguration, settings_screen, hud, inventory, game_ui_state::GameUiState, settings,
}; };
pub struct MainGameUIPlugin; pub struct MainGameUIPlugin;
@ -12,23 +10,7 @@ impl Plugin for MainGameUIPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(hud::plugin::HudOverlayPlugin); app.add_plugins(hud::plugin::HudOverlayPlugin);
app.add_plugins(inventory::plugin::InventoryMenuPlugin); app.add_plugins(inventory::plugin::InventoryMenuPlugin);
app.insert_resource(GameConfiguration::default()); app.add_plugins(settings::plugin::SettingsMenuPlugin);
app.insert_resource(SettingsScreenUIConfiguration::default()); app.insert_resource(GameUiState::default());
app.add_systems(
Startup,
(
settings_screen::setup_settings_screen,
fps_counter::setup_fps_counter,
inventory::menu::setup_inventory_screen,
),
);
app.add_systems(
Update,
(
settings_screen::toggle_settings_screen,
settings_screen::handle_settings_button_click,
fps_counter::tick_fps_counter,
),
);
} }
} }

View File

@ -1,29 +0,0 @@
use bevy::prelude::*;
#[derive(Resource, Reflect)]
#[reflect(Resource)]
pub struct SettingsScreenUIConfiguration {
pub settings_menu_shown: bool,
}
impl Default for SettingsScreenUIConfiguration {
fn default() -> Self {
Self {
settings_menu_shown: false,
}
}
}
#[derive(Resource, Reflect)]
#[reflect(Resource)]
pub struct GameConfiguration {
pub fps_counter_enabled: bool,
}
impl Default for GameConfiguration {
fn default() -> Self {
Self {
fps_counter_enabled: true,
}
}
}

View File

@ -1,9 +1,6 @@
use bevy::{app::AppExit, prelude::*, ui::FocusPolicy}; use bevy::{app::AppExit, prelude::*, ui::FocusPolicy};
use super::settings::SettingsScreenUIConfiguration; use crate::{comps::core::markers::settings_screen::SettingsScreenMarker, ui::game::game_ui_state::{GameUiState, GameUiWindow}};
#[derive(Component)]
pub struct SettingsScreenMarker;
#[derive(Component)] #[derive(Component)]
pub enum SettingsScreenActions { pub enum SettingsScreenActions {
@ -95,14 +92,14 @@ pub fn setup_settings_screen(mut commands: Commands) {
} }
pub fn toggle_settings_screen( pub fn toggle_settings_screen(
settings: Res<SettingsScreenUIConfiguration>, game_ui_state: Res<GameUiState>,
mut settings_screen_query: Query<(&mut Visibility, &mut Style), With<SettingsScreenMarker>>, mut settings_screen_query: Query<(&mut Visibility, &mut Style), With<SettingsScreenMarker>>,
) { ) {
if settings.is_changed() { if game_ui_state.is_changed() {
for (mut settings_screen_visibility, mut settings_screen_style) in for (mut settings_screen_visibility, mut settings_screen_style) in
settings_screen_query.iter_mut() settings_screen_query.iter_mut()
{ {
if settings.settings_menu_shown { if game_ui_state.is_showing_window(GameUiWindow::SettingsMenu) {
*settings_screen_visibility = Visibility::Visible; *settings_screen_visibility = Visibility::Visible;
settings_screen_style.display = Display::Flex; settings_screen_style.display = Display::Flex;
} else { } else {
@ -116,7 +113,7 @@ pub fn toggle_settings_screen(
pub fn handle_settings_button_click( pub fn handle_settings_button_click(
query: Query<(&Interaction, &SettingsScreenActions), Changed<Interaction>>, query: Query<(&Interaction, &SettingsScreenActions), Changed<Interaction>>,
mut exit: EventWriter<AppExit>, mut exit: EventWriter<AppExit>,
mut settings: ResMut<SettingsScreenUIConfiguration>, mut game_ui_state: ResMut<GameUiState>,
mut mouse_buttons: ResMut<Input<MouseButton>>, mut mouse_buttons: ResMut<Input<MouseButton>>,
) { ) {
for (interaction, action) in query.iter() { for (interaction, action) in query.iter() {
@ -129,7 +126,7 @@ pub fn handle_settings_button_click(
} }
SettingsScreenActions::Resume => { SettingsScreenActions::Resume => {
// RESUME GAME // RESUME GAME
settings.settings_menu_shown = false; game_ui_state.current_ui_window_shown = None;
mouse_buttons.release(MouseButton::Left); mouse_buttons.release(MouseButton::Left);
} }
} }

View File

@ -0,0 +1,2 @@
pub mod plugin;
pub mod menu;

View File

@ -0,0 +1,13 @@
use bevy::app::{Plugin, Startup, Update};
use super::menu;
pub struct SettingsMenuPlugin;
impl Plugin for SettingsMenuPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_systems(Startup, menu::setup_settings_screen);
app.add_systems(Update, (menu::toggle_settings_screen, menu::handle_settings_button_click));
}
}