generated from 2ndbeam/bevy-template
ui: Beginning of UI-related stuff
- UiRoot component - WindowSize resource and update_window_size system - UiInventory and UiInventorySlot components - UiInventory now shows player inventory slots
This commit is contained in:
parent
5f59e02788
commit
ab993be476
6 changed files with 183 additions and 10 deletions
|
|
@ -1,12 +1,17 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
pub mod item;
|
||||
pub mod ui;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Inventory {
|
||||
pub size: UVec2,
|
||||
}
|
||||
|
||||
/// Marker that this inventory will show up when UI is built
|
||||
#[derive(Component)]
|
||||
pub struct ActiveInventory;
|
||||
|
||||
impl Inventory {
|
||||
pub fn new(size: UVec2) -> Self {
|
||||
Self { size }
|
||||
|
|
|
|||
93
src/inventory/ui.rs
Normal file
93
src/inventory/ui.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::{inventory::{ActiveInventory, Inventory}, ui::{UiRoot, WindowSize}};
|
||||
|
||||
const UI_SLOT_ASSET_PATH: &'static str = "sprites/ui/inventory_slot.png";
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Node)]
|
||||
pub struct UiInventory;
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Node, ImageNode)]
|
||||
pub struct UiInventorySlot(UVec2);
|
||||
|
||||
fn ui_inventory_bundle(inventory: &Inventory, window_size: &Res<WindowSize>) -> impl Bundle {
|
||||
let window_ratio = window_size.aspect_ratio();
|
||||
let (width, height) = {
|
||||
if window_ratio >= 1. {
|
||||
(auto(), percent(100))
|
||||
} else {
|
||||
(percent(100), auto())
|
||||
}
|
||||
};
|
||||
(
|
||||
UiInventory,
|
||||
Node {
|
||||
align_self: AlignSelf::Center,
|
||||
align_content: AlignContent::Center,
|
||||
display: Display::Grid,
|
||||
width,
|
||||
height,
|
||||
aspect_ratio: Some(inventory.size.x as f32 / inventory.size.y as f32),
|
||||
grid_auto_columns: vec![GridTrack::percent(100. / inventory.size.x as f32)],
|
||||
grid_auto_rows: vec![GridTrack::percent(100. / inventory.size.y as f32)],
|
||||
..default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn inventory_slot_bundle(x: u32, y: u32, width: u32, height: u32, image: Handle<Image>) -> impl Bundle {
|
||||
(
|
||||
UiInventorySlot(UVec2::new(x, y)),
|
||||
ImageNode {
|
||||
image,
|
||||
image_mode: NodeImageMode::Stretch,
|
||||
..default()
|
||||
},
|
||||
Node {
|
||||
width: percent(100.),
|
||||
height: percent(100.),
|
||||
grid_column: GridPlacement::start(x as i16 + 1),
|
||||
grid_row: GridPlacement::start(y as i16 + 1),
|
||||
..default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn setup_ui_inventory(
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
inventory_query: Query<(&Inventory, Option<&Children>), With<ActiveInventory>>,
|
||||
root_query: Query<Entity, With<UiRoot>>,
|
||||
window_size: Res<WindowSize>,
|
||||
) {
|
||||
let Ok(root) = root_query.single() else {
|
||||
error!("Query contains more than one UiRoot");
|
||||
return;
|
||||
};
|
||||
let ui_slot_image: Handle<Image> = asset_server.load(UI_SLOT_ASSET_PATH);
|
||||
for (inventory, _children) in inventory_query {
|
||||
let inventory_entity = commands.spawn(ui_inventory_bundle(inventory, &window_size))
|
||||
.with_children(|commands| {
|
||||
for x in 0..inventory.size.x {
|
||||
for y in 0..inventory.size.y {
|
||||
commands.spawn(inventory_slot_bundle(x, y, inventory.size.x, inventory.size.y, ui_slot_image.clone()));
|
||||
}
|
||||
}
|
||||
}).id();
|
||||
commands.entity(root).add_child(inventory_entity);
|
||||
|
||||
// for simplicity we'll show only first inventory
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_ui_inventory(
|
||||
mut commands: Commands,
|
||||
inventory_query: Query<Entity, With<UiInventory>>,
|
||||
) {
|
||||
for entity in inventory_query {
|
||||
commands.entity(entity).despawn();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue