From 4b28f80bcb67763fb1d845c5636ed55499a9224f Mon Sep 17 00:00:00 2001 From: demenik Date: Mon, 1 Dec 2025 13:42:19 +0100 Subject: [PATCH 1/8] feat: Add shop logic and popup UI (#34). Update config tests and defaults --- assets/config.json | 2 ++ src/features/config/components.rs | 4 +++ src/features/inventory/components.rs | 10 +++++- src/features/mod.rs | 2 ++ src/features/shop/components.rs | 51 ++++++++++++++++++++++++++ src/features/shop/mod.rs | 10 ++++++ src/features/shop/ui/mod.rs | 3 ++ src/features/shop/ui/shop.rs | 54 ++++++++++++++++++++++++++++ src/main.rs | 1 + tests/config.rs | 5 ++- 10 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/features/shop/components.rs create mode 100644 src/features/shop/mod.rs create mode 100644 src/features/shop/ui/mod.rs create mode 100644 src/features/shop/ui/shop.rs diff --git a/assets/config.json b/assets/config.json index 0eb9d0b..56bc933 100644 --- a/assets/config.json +++ b/assets/config.json @@ -2,6 +2,8 @@ "grid_width": 12, "grid_height": 4, "pom_speed": 1.5, + "shovel_base_price": 10, + "shovel_rate": 0.5, "berry_seeds": [ { "name": "Normale Samen", diff --git a/src/features/config/components.rs b/src/features/config/components.rs index 5319dbe..6533682 100644 --- a/src/features/config/components.rs +++ b/src/features/config/components.rs @@ -7,6 +7,8 @@ pub struct GameConfig { pub grid_width: u32, pub grid_height: u32, pub pom_speed: f32, + pub shovel_base_price: u32, + pub shovel_rate: f32, pub berry_seeds: Vec, } @@ -25,6 +27,8 @@ impl Default for GameConfig { grid_width: 12, grid_height: 4, pom_speed: 1.5, + shovel_base_price: 10, + shovel_rate: 0.2, berry_seeds: vec![ BerrySeedConfig { name: "Normale Samen".to_string(), diff --git a/src/features/inventory/components.rs b/src/features/inventory/components.rs index 0008095..63ca0d9 100644 --- a/src/features/inventory/components.rs +++ b/src/features/inventory/components.rs @@ -4,12 +4,14 @@ use crate::{features::config::components::BerrySeedConfig, prelude::*}; pub enum ItemType { Berry, BerrySeed { name: String }, + Shovel, } impl ItemType { pub fn singular(&self, game_config: &GameConfig) -> String { match self { ItemType::Berry => "Beere".into(), + ItemType::Shovel => "Schaufel".into(), ItemType::BerrySeed { name } => { let seed_config = game_config.berry_seeds.iter().find(|s| s.name == *name); seed_config @@ -22,6 +24,7 @@ impl ItemType { pub fn plural(&self, game_config: &GameConfig) -> String { match self { ItemType::Berry => "Beeren".into(), + ItemType::Shovel => "Schaufeln".into(), ItemType::BerrySeed { name } => { let seed_config = game_config.berry_seeds.iter().find(|s| s.name == *name); seed_config @@ -36,6 +39,7 @@ impl ItemType { ItemType::Berry => { "Von Pflanzen erntbar. Kann im Shop zum Einkaufen benutzt werden.".into() } + ItemType::Shovel => "Schaltet ein neues Feld im Garten frei.".into(), ItemType::BerrySeed { name } => { let seed_config = game_config.berry_seeds.iter().find(|s| s.name == *name); if let Some(s) = seed_config { @@ -57,7 +61,7 @@ impl ItemType { pub fn get_seed_config<'a>(&self, game_config: &'a GameConfig) -> Option<&'a BerrySeedConfig> { match self { - ItemType::Berry => None, + ItemType::Berry | ItemType::Shovel => None, ItemType::BerrySeed { name } => { game_config.berry_seeds.iter().find(|s| s.name == *name) } @@ -70,6 +74,10 @@ impl ItemType { name: "Berry".into(), aseprite: asset_server.load("berry.aseprite"), }, + ItemType::Shovel => AseSlice { + name: "Berry".into(), + aseprite: asset_server.load("berry.aseprite"), + }, ItemType::BerrySeed { name } => { let seed_config = game_config.berry_seeds.iter().find(|s| s.name == *name); if let Some(s) = seed_config { diff --git a/src/features/mod.rs b/src/features/mod.rs index 76983e4..5ef139a 100644 --- a/src/features/mod.rs +++ b/src/features/mod.rs @@ -8,6 +8,7 @@ pub mod inventory; pub mod phase; pub mod pom; pub mod savegame; +pub mod shop; pub mod start_screen; pub mod ui; @@ -20,5 +21,6 @@ pub use inventory::InventoryPlugin; pub use phase::PhasePlugin; pub use pom::PomPlugin; pub use savegame::SavegamePlugin; +pub use shop::ShopPlugin; pub use start_screen::StartScreenPlugin; pub use ui::UiPlugin; diff --git a/src/features/shop/components.rs b/src/features/shop/components.rs new file mode 100644 index 0000000..0b5d762 --- /dev/null +++ b/src/features/shop/components.rs @@ -0,0 +1,51 @@ +use crate::prelude::*; + +#[derive(Component)] +pub enum RootMarker { + Shop, +} + +#[derive(Component)] +pub enum ButtonType { + ShopClose, +} + +#[derive(Clone)] +pub struct ShopOffer { + pub item: ItemStack, + pub cost: u32, +} + +impl ShopOffer { + pub fn list_all(game_config: &GameConfig, tile_count: u32) -> Vec { + let mut offers = Vec::new(); + + for seed in &game_config.berry_seeds { + offers.push(ShopOffer { + item: ItemStack { + item_type: ItemType::BerrySeed { + name: seed.name.clone(), + }, + amount: 1, + }, + cost: seed.cost, + }); + } + + let mut shovel_cost = game_config.shovel_base_price as f32; + for _ in 0..=tile_count { + shovel_cost = shovel_cost + (game_config.shovel_rate * shovel_cost); + shovel_cost = shovel_cost.ceil(); + } + + offers.push(ShopOffer { + item: ItemStack { + item_type: ItemType::Shovel, + amount: 1, + }, + cost: shovel_cost as u32, + }); + + offers + } +} diff --git a/src/features/shop/mod.rs b/src/features/shop/mod.rs new file mode 100644 index 0000000..9f2a0f8 --- /dev/null +++ b/src/features/shop/mod.rs @@ -0,0 +1,10 @@ +use crate::prelude::*; + +pub mod components; +pub mod ui; + +pub struct ShopPlugin; + +impl Plugin for ShopPlugin { + fn build(&self, app: &mut App) {} +} diff --git a/src/features/shop/ui/mod.rs b/src/features/shop/ui/mod.rs new file mode 100644 index 0000000..1ba9936 --- /dev/null +++ b/src/features/shop/ui/mod.rs @@ -0,0 +1,3 @@ +pub mod shop; + +pub use shop::open_shop; diff --git a/src/features/shop/ui/shop.rs b/src/features/shop/ui/shop.rs new file mode 100644 index 0000000..5dbafea --- /dev/null +++ b/src/features/shop/ui/shop.rs @@ -0,0 +1,54 @@ +use super::super::components::*; +use crate::prelude::*; + +pub fn open_shop(commands: &mut Commands) { + commands + .spawn(( + RootMarker::Shop, + Node { + position_type: PositionType::Absolute, + width: percent(100), + height: percent(100), + ..Node::center() + }, + ZIndex(1), + BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)), + GlobalTransform::default(), + )) + .with_children(|parent| { + parent + .spawn(( + Node { + width: px(700), + padding: UiRect::all(px(20.0)), + ..Node::vstack(px(20)) + }, + BackgroundColor(Color::srgb(0.2, 0.2, 0.2)), + BorderRadius::all(px(10.0)), + )) + .with_children(|parent| { + parent.spawn(( + Node { + justify_content: JustifyContent::SpaceBetween, + ..Node::hstack(px(20)) + }, + children![ + text("Shop", 40.0, Color::WHITE), + pill_button( + ButtonType::ShopClose, + ButtonVariant::Destructive, + Node { + width: px(40), + height: px(40), + ..default() + }, + "X", + 24.0 + ), + ], + )); + + parent.spawn(Node::vstack(px(10))).with_children(|_| {}); + }); + }); +} diff --git a/src/main.rs b/src/main.rs index 3fb1b5e..d9b2558 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ fn main() { features::SavegamePlugin, features::UiPlugin, features::InventoryPlugin, + features::ShopPlugin, )) .insert_resource(config) .run(); diff --git a/tests/config.rs b/tests/config.rs index 3401dbe..90b2dc6 100644 --- a/tests/config.rs +++ b/tests/config.rs @@ -22,7 +22,10 @@ fn test_load_valid_config() { r#"{ "grid_width": 10, "grid_height": 5, - "pom_speed": 2.0 + "pom_speed": 2.0, + "shovel_base_price": 10, + "shovel_rate": 0.2, + "berry_seeds": [] }"#, ); From 7a608516eb1693c781d62644680e7693593bc049 Mon Sep 17 00:00:00 2001 From: demenik Date: Mon, 1 Dec 2025 13:57:31 +0100 Subject: [PATCH 2/8] feat: Add shop button to HUD (#34) --- src/features/hud/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/features/hud/mod.rs b/src/features/hud/mod.rs index 6091430..1f0f2d8 100644 --- a/src/features/hud/mod.rs +++ b/src/features/hud/mod.rs @@ -1,6 +1,6 @@ -use crate::features::inventory; use crate::features::phase::components::TimerSettings; use crate::features::savegame::messages::SavegameDumpMessage; +use crate::features::{inventory, shop}; use crate::prelude::*; use components::*; use ui::*; @@ -41,6 +41,16 @@ fn setup(mut commands: Commands) { children![ text_with_component(TextType::Phase, "...", 16.0, Color::WHITE), text_with_component(TextType::Timer, "...", 16.0, Color::WHITE), + button( + shop::components::ButtonType::ShopOpen, + ButtonVariant::Secondary, + Node { + padding: UiRect::all(px(10)), + ..default() + }, + "Shop", + 16.0 + ), button( inventory::components::ButtonType::InventoryOpen, ButtonVariant::Secondary, From f908192c0ee69c5bea62b22adc1f9d3a52cf6a10 Mon Sep 17 00:00:00 2001 From: demenik Date: Mon, 1 Dec 2025 14:26:16 +0100 Subject: [PATCH 3/8] fix: Improve button/pill_button UI element to allow any child --- src/features/hud/mod.rs | 9 +-- src/features/hud/ui/settings.rs | 9 +-- src/features/hud/ui/timer_settings.rs | 6 +- src/features/inventory/ui/inventory.rs | 9 ++- src/features/savegame/ui/load.rs | 107 ++++++++++++------------- src/features/shop/ui/shop.rs | 3 +- src/features/start_screen/mod.rs | 9 +-- src/features/ui/ui/button.rs | 28 ++++--- 8 files changed, 86 insertions(+), 94 deletions(-) diff --git a/src/features/hud/mod.rs b/src/features/hud/mod.rs index 1f0f2d8..5e0dbdb 100644 --- a/src/features/hud/mod.rs +++ b/src/features/hud/mod.rs @@ -48,8 +48,7 @@ fn setup(mut commands: Commands) { padding: UiRect::all(px(10)), ..default() }, - "Shop", - 16.0 + |color| text("Shop", 16.0, color) ), button( inventory::components::ButtonType::InventoryOpen, @@ -58,8 +57,7 @@ fn setup(mut commands: Commands) { padding: UiRect::all(px(10)), ..default() }, - "Inventar", - 16.0 + |color| text("Inventar", 16.0, color) ), button( ButtonType::SettingsOpen, @@ -68,8 +66,7 @@ fn setup(mut commands: Commands) { padding: UiRect::all(px(10)), ..default() }, - "Einstellungen", - 16.0 + |color| text("Einstellungen", 16.0, color) ) ], )); diff --git a/src/features/hud/ui/settings.rs b/src/features/hud/ui/settings.rs index f2b16f5..cb82cc4 100644 --- a/src/features/hud/ui/settings.rs +++ b/src/features/hud/ui/settings.rs @@ -43,8 +43,7 @@ pub fn open_settings(commands: &mut Commands) { height: px(40), ..default() }, - "X", - 24.0 + |color| text("X", 24.0, color) ), ], )); @@ -59,8 +58,7 @@ pub fn open_settings(commands: &mut Commands) { padding: UiRect::all(px(10)), ..default() }, - "Spiel verlassen", - 24.0, + |color| text("Spiel verlassen", 24.0, color) )); parent.spawn(button( @@ -70,8 +68,7 @@ pub fn open_settings(commands: &mut Commands) { padding: UiRect::all(px(10)), ..default() }, - "Spiel speichern", - 24.0, + |color| text("Spiel speichern", 24.0, color) )); parent.spawn(( diff --git a/src/features/hud/ui/timer_settings.rs b/src/features/hud/ui/timer_settings.rs index 49fce78..136b391 100644 --- a/src/features/hud/ui/timer_settings.rs +++ b/src/features/hud/ui/timer_settings.rs @@ -29,8 +29,7 @@ fn timer_settings_part(input: SettingsTimerInput, amount: u32) -> impl Bundle { width: percent(100), ..default() }, - "+", - 12.0 + |color| text("+", 12.0, color) ), text_with_component(input.clone(), "--", 24.0, Color::WHITE), button( @@ -43,8 +42,7 @@ fn timer_settings_part(input: SettingsTimerInput, amount: u32) -> impl Bundle { width: percent(100), ..default() }, - "-", - 12.0 + |color| text("-", 12.0, color) ), ], ) diff --git a/src/features/inventory/ui/inventory.rs b/src/features/inventory/ui/inventory.rs index 6daa1f7..50ed085 100644 --- a/src/features/inventory/ui/inventory.rs +++ b/src/features/inventory/ui/inventory.rs @@ -2,7 +2,11 @@ use super::super::components::{ButtonType, RootMarker}; use crate::prelude::GameConfig; use crate::{features::inventory::ui::list_itemstack, prelude::*}; -pub fn open_inventory(commands: &mut Commands, items: Query<&ItemStack>, game_config: &Res) { +pub fn open_inventory( + commands: &mut Commands, + items: Query<&ItemStack>, + game_config: &Res, +) { commands .spawn(( RootMarker::Inventory, @@ -44,8 +48,7 @@ pub fn open_inventory(commands: &mut Commands, items: Query<&ItemStack>, game_co height: px(40), ..default() }, - "X", - 24.0 + |color| text("X", 24.0, color) ), ], )); diff --git a/src/features/savegame/ui/load.rs b/src/features/savegame/ui/load.rs index 2df621b..2a111c4 100644 --- a/src/features/savegame/ui/load.rs +++ b/src/features/savegame/ui/load.rs @@ -47,8 +47,7 @@ pub fn spawn_load_popup(commands: &mut Commands) { height: px(40), ..default() }, - "X", - 24.0 + |color| text("X", 24.0, color) ) ], )); @@ -64,63 +63,61 @@ pub fn spawn_load_popup(commands: &mut Commands) { }) .with_children(|parent| { for savegame in SavegamePath::list() { - parent.spawn(( - Button, - ButtonType::SavegameLoad { - savegame_path: savegame.path.clone(), - }, - ButtonVariant::Secondary, - Node { - width: percent(100), - height: px(80), - flex_direction: FlexDirection::Row, - column_gap: px(10.0), - padding: UiRect::horizontal(px(10.0)), - ..Node::center() - }, - BackgroundColor(ButtonVariant::Secondary.normal_background()), - BorderRadius::all(px(10)), - children![ - ( + parent.spawn( + button( + ButtonType::SavegameLoad { savegame_path: savegame.path.clone() }, + ButtonVariant::Secondary, + Node { + width: percent(100), + padding: UiRect::all(px(10)), + ..Node::center() + }, + |color| ( Node { width: percent(100), - height: percent(100), - flex_direction: FlexDirection::Column, - justify_content: JustifyContent::Center, - ..default() + align_items: AlignItems::Center, + ..Node::hstack(px(10)) }, - children![ - text( - format!("Spielstand {}", savegame.index + 1), - 24.0, - Color::WHITE - ), - text( - format!( - "Beeren: {}, Fokusphasen abgeschlossen: {}", - savegame.total_berries, - savegame.completed_focus + children![( + Node { + width: percent(100), + height: percent(100), + flex_direction: FlexDirection::Column, + justify_content: JustifyContent::Center, + ..default() + }, + children![ + text( + format!("Spielstand {}", savegame.index + 1), + 24.0, + color ), - 18.0, - Color::WHITE, - ), - ] - ), - pill_button( - ButtonType::SavegameDelete { - savegame_path: savegame.path.clone() - }, - ButtonVariant::Destructive, - Node { - width: px(40), - height: px(40), - ..default() - }, - "X", - 24.0 - ), - ], - )); + text( + format!( + "Beeren: {}, Fokusphasen abgeschlossen: {}", + savegame.total_berries, + savegame.completed_focus + ), + 18.0, + Color::WHITE, + ), + ] + ), + pill_button( + ButtonType::SavegameDelete { + savegame_path: savegame.path.clone() + }, + ButtonVariant::Destructive, + Node { + width: px(40), + height: px(40), + ..default() + }, + |color| text("X", 24.0, color) + )] + ) + ), + ); } }); }); diff --git a/src/features/shop/ui/shop.rs b/src/features/shop/ui/shop.rs index 5dbafea..7054405 100644 --- a/src/features/shop/ui/shop.rs +++ b/src/features/shop/ui/shop.rs @@ -42,8 +42,7 @@ pub fn open_shop(commands: &mut Commands) { height: px(40), ..default() }, - "X", - 24.0 + |color| text("X", 24.0, color) ), ], )); diff --git a/src/features/start_screen/mod.rs b/src/features/start_screen/mod.rs index afcfdff..89483c2 100644 --- a/src/features/start_screen/mod.rs +++ b/src/features/start_screen/mod.rs @@ -34,8 +34,7 @@ fn setup(mut commands: Commands) { padding: UiRect::all(px(10)), ..default() }, - "Spiel laden", - 33.0 + |color| text("Spiel laden", 33.0, color) ), button( ButtonType::NewGame, @@ -45,8 +44,7 @@ fn setup(mut commands: Commands) { padding: UiRect::all(px(10)), ..default() }, - "Neues Spiel", - 33.0, + |color| text("Neues Spiel", 33.0, color) ), button( ButtonType::Settings, @@ -56,8 +54,7 @@ fn setup(mut commands: Commands) { padding: UiRect::all(px(10)), ..default() }, - "Einstellungen", - 33.0 + |color| text("Einstellungen", 33.0, color) ), ], )); diff --git a/src/features/ui/ui/button.rs b/src/features/ui/ui/button.rs index 3ce229a..9d51dca 100644 --- a/src/features/ui/ui/button.rs +++ b/src/features/ui/ui/button.rs @@ -1,14 +1,15 @@ - - use crate::prelude::*; -pub fn button( +pub fn button( button_type: impl Component, variant: ButtonVariant, mut node: Node, - title: impl Into, - font_size: f32, -) -> impl Bundle { + child: C, +) -> impl Bundle +where + C: FnOnce(Color) -> R, + R: Bundle, +{ node.justify_content = JustifyContent::Center; node.align_items = AlignItems::Center; @@ -19,17 +20,20 @@ pub fn button( node, BackgroundColor(variant.normal_background()), BorderRadius::all(px(10)), - children![text(title, font_size, variant.text_color())], + children![child(variant.text_color())], ) } -pub fn pill_button( +pub fn pill_button( button_type: impl Component, variant: ButtonVariant, mut node: Node, - title: impl Into, - font_size: f32, -) -> impl Bundle { + child: C, +) -> impl Bundle +where + C: FnOnce(Color) -> R, + R: Bundle, +{ node.justify_content = JustifyContent::Center; node.align_items = AlignItems::Center; @@ -40,7 +44,7 @@ pub fn pill_button( node, BackgroundColor(variant.normal_background()), BorderRadius::MAX, - children![text(title, font_size, variant.text_color())], + children![child(variant.text_color())], ) } From 9842fe16d6482b228b9d34a0f41496b6024da110 Mon Sep 17 00:00:00 2001 From: demenik Date: Mon, 1 Dec 2025 15:13:48 +0100 Subject: [PATCH 4/8] feat: Display shop offers (#34) --- src/features/inventory/components.rs | 8 +++-- src/features/inventory/mod.rs | 3 +- src/features/inventory/ui/inventory.rs | 3 +- src/features/inventory/ui/item.rs | 13 ++++--- src/features/shop/components.rs | 2 ++ src/features/shop/mod.rs | 33 +++++++++++++++++- src/features/shop/ui/mod.rs | 2 ++ src/features/shop/ui/offer.rs | 47 ++++++++++++++++++++++++++ src/features/shop/ui/shop.rs | 17 ++++++++-- 9 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 src/features/shop/ui/offer.rs diff --git a/src/features/inventory/components.rs b/src/features/inventory/components.rs index 63ca0d9..bd06a93 100644 --- a/src/features/inventory/components.rs +++ b/src/features/inventory/components.rs @@ -39,7 +39,7 @@ impl ItemType { ItemType::Berry => { "Von Pflanzen erntbar. Kann im Shop zum Einkaufen benutzt werden.".into() } - ItemType::Shovel => "Schaltet ein neues Feld im Garten frei.".into(), + ItemType::Shovel => "Im Shop kaufbar. Schaltet ein neues Feld im Garten frei. Preis steigt bei jedem Kauf!".into(), ItemType::BerrySeed { name } => { let seed_config = game_config.berry_seeds.iter().find(|s| s.name == *name); if let Some(s) = seed_config { @@ -68,7 +68,11 @@ impl ItemType { } } - pub fn get_sprite(&self, asset_server: Res, game_config: &GameConfig) -> AseSlice { + pub fn get_sprite( + &self, + asset_server: &Res, + game_config: &GameConfig, + ) -> AseSlice { match self { ItemType::Berry => AseSlice { name: "Berry".into(), diff --git a/src/features/inventory/mod.rs b/src/features/inventory/mod.rs index 2915d40..5e91a71 100644 --- a/src/features/inventory/mod.rs +++ b/src/features/inventory/mod.rs @@ -20,12 +20,13 @@ fn buttons( itemstack_query: Query<&ItemStack>, root_query: Query<(Entity, &RootMarker)>, game_config: Res, + asset_server: Res, ) { for (interaction, button_type) in &mut interaction_query { match *interaction { Interaction::Pressed => match button_type { ButtonType::InventoryOpen => { - open_inventory(&mut commands, itemstack_query, &game_config); + open_inventory(&mut commands, itemstack_query, &game_config, &asset_server); } ButtonType::InventoryClose => { for (entity, root) in root_query.iter() { diff --git a/src/features/inventory/ui/inventory.rs b/src/features/inventory/ui/inventory.rs index 50ed085..f045e65 100644 --- a/src/features/inventory/ui/inventory.rs +++ b/src/features/inventory/ui/inventory.rs @@ -6,6 +6,7 @@ pub fn open_inventory( commands: &mut Commands, items: Query<&ItemStack>, game_config: &Res, + asset_server: &Res, ) { commands .spawn(( @@ -61,7 +62,7 @@ pub fn open_inventory( }) .with_children(|parent| { for itemstack in items.iter() { - parent.spawn(list_itemstack(itemstack, game_config)); + parent.spawn(list_itemstack(itemstack, game_config, asset_server)); } }); }); diff --git a/src/features/inventory/ui/item.rs b/src/features/inventory/ui/item.rs index 3e6c0cc..39a9f0a 100644 --- a/src/features/inventory/ui/item.rs +++ b/src/features/inventory/ui/item.rs @@ -1,6 +1,10 @@ use crate::prelude::*; -pub fn list_itemstack(itemstack: &ItemStack, game_config: &GameConfig) -> impl Bundle { +pub fn list_itemstack( + itemstack: &ItemStack, + game_config: &GameConfig, + asset_server: &Res, +) -> impl Bundle { let name = match itemstack.amount { 1 => itemstack.item_type.singular(game_config), _ => itemstack.item_type.plural(game_config), @@ -8,21 +12,22 @@ pub fn list_itemstack(itemstack: &ItemStack, game_config: &GameConfig) -> impl B ( Node { + width: percent(100), padding: UiRect::all(px(4)), ..Node::hstack(px(8)) }, - BackgroundColor(ButtonVariant::Secondary.normal_background()), BorderRadius::all(px(10)), children![ ( - // Placeholder for icon Node { height: percent(100), aspect_ratio: Some(1.0), ..default() }, BackgroundColor(ButtonVariant::Secondary.hover_background()), - BorderRadius::all(px(10)) + BorderRadius::all(px(10)), + itemstack.item_type.get_sprite(asset_server, game_config), + ImageNode::default() ), ( Node { diff --git a/src/features/shop/components.rs b/src/features/shop/components.rs index 0b5d762..ee71abc 100644 --- a/src/features/shop/components.rs +++ b/src/features/shop/components.rs @@ -7,7 +7,9 @@ pub enum RootMarker { #[derive(Component)] pub enum ButtonType { + ShopOpen, ShopClose, + ShopBuyItem(ShopOffer), } #[derive(Clone)] diff --git a/src/features/shop/mod.rs b/src/features/shop/mod.rs index 9f2a0f8..ed45ebb 100644 --- a/src/features/shop/mod.rs +++ b/src/features/shop/mod.rs @@ -1,4 +1,6 @@ use crate::prelude::*; +use components::*; +use ui::open_shop; pub mod components; pub mod ui; @@ -6,5 +8,34 @@ pub mod ui; pub struct ShopPlugin; impl Plugin for ShopPlugin { - fn build(&self, app: &mut App) {} + fn build(&self, app: &mut App) { + app.add_systems(Update, buttons.run_if(in_state(AppState::GameScreen))); + } +} + +fn buttons( + mut commands: Commands, + mut interaction_query: Query<(&Interaction, &ButtonType), (Changed, With