From 9c188a4dd93f2e26a2fcc42aff874e4603fcf69c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 30 Aug 2022 18:12:24 -0400 Subject: [PATCH] Ingame health UI (#50) * ui setup * health component * issues with ui texture atlas * working health indicator * player lose health --- assets/tilesheet/bandit_hideout.ase | Bin 2221 -> 2428 bytes assets/tilesheet/bandit_hideout.png | Bin 2897 -> 3180 bytes assets/tilesheet/heart.ase | Bin 0 -> 587 bytes assets/tilesheet/heart.png | Bin 0 -> 150 bytes src/app.rs | 7 +++- src/assets.rs | 2 +- src/attack.rs | 7 +++- src/main.rs | 1 + src/player/inventory.rs | 7 ++-- src/player/mod.rs | 23 +++++++++-- src/screens/components/health.rs | 58 ++++++++++++++++++++++++++++ src/screens/components/inventory.rs | 7 ++++ src/screens/components/mod.rs | 14 +++++++ src/screens/ingame.rs | 35 +++++++++++++++++ src/screens/mod.rs | 28 ++++++++++++++ src/screens/state.rs | 18 +++++++++ src/screens/utils.rs | 13 +++++++ src/spritesheet_constants.rs | 7 ++++ 18 files changed, 215 insertions(+), 12 deletions(-) create mode 100644 assets/tilesheet/heart.ase create mode 100644 assets/tilesheet/heart.png create mode 100644 src/screens/components/health.rs create mode 100644 src/screens/components/inventory.rs create mode 100644 src/screens/components/mod.rs create mode 100644 src/screens/ingame.rs create mode 100644 src/screens/mod.rs create mode 100644 src/screens/state.rs create mode 100644 src/screens/utils.rs diff --git a/assets/tilesheet/bandit_hideout.ase b/assets/tilesheet/bandit_hideout.ase index 281c32d1fb4a1e79f2d39ea655bf903ab11c86bb..f3ef0b8f51a6bb85b2fe7908d5c84ae283a0dd4e 100644 GIT binary patch delta 1961 zcmV;a2Uhs45&RMYdksgx7ZEfFO7NlwqY!gg%r3!Qh&!u9y%@>C4gQEx%nyPXWD{A5Sr8e6 zkqrq5(L@9h<3bLC2^c{U4C+A;f)^9;VE%%3Uhlk4&6`)Rs=I2sYkKMnkM6F2S5;m8 zK3zYi=a*Vu$W)W&sZ4FpB=fDm5s?^WKc8pKCBClt8e?){I?F9~SykcY%27G@qiBqq*WJQa+I3$wZufQeUM@stx28gCkRo4;<2h)Hx~S5IF&^=Jmh zRul^l(4@>K zf=km%{UpkMLT!LgjG8beL*rPC3bgJruEUzvnD&z({UO%1X6)_bBrtJ)-52vU$KF0p z7A7V}rm-v5`Q*FXJ7dMf#KmP?v-Y#5)#m}vSy(PH%5tB#fk|8XN!yrz=r+J7MhW9q z8<`A^V=>Bs$y7-BS0Nv+98_vy58P?V4n*ZGKPf{N~0Gm!{h_ z$?B~^)Y|tysC@qD9pbj>c1^N=yKTN;GBCdm^Kc9=+68`*i)t2(W0n%}+`!*cx z4AsAHZoWbgB9li<(O;D*GO5}Rk%?|&&&1`KsYlFgeqiELerorB{Lt71X*)XGD~BWo zWjC*9x>5fq=L26RFvn9SkaqseC)I)xi}ZWn&=0u%82lQOf&Jfq{DoFC(c=1=lpgAw zrhY!|GJe0zQI{@XVdG*-2iacR*yJ+qnvP?a3lHf>*h#!}W7KXj~u>wpunqLSF!7*yx&GGFxG1qO-RtOc z?F$&Y&`k6;R%IfsJ@Yj9-fE3ZY-5(Kzq^bF$iw9K8N2lHii@dj+_JqEh>eLYMz&{* zDCv59#(9@AwzW34Pg*b5%_K=yo7dS*$z?rRXCBlCEAJP7`yqLUT5I~qwqAtxxXhVS z9()F5YloDFw)5nn*9xDsCMg@!7?|KWeYx0}*vi^?(AX@^Jdtm4{S)dnRg+BMI$`aM zYhb(&IdjPed8+uZUMUZk51HV#go3Q7SSOg;If~!6GBJVABU{QD zEu>uTlREQIAq&{eB`sPiop-+ZkaKTUEl+g z%G%D^I~FZ86WjC4QO8tzp65~?v^qUCF!$(l5ctr4Ps^d-cFun6O>0B7vT3$plKppI z{#zVo+eI>v;qVQl-h`q3xNwYb(b)l1jYrt?5txiuQ3ArtyqNB7&V$;JfhM;^KL z_RGdpVxrHx*pKx2+_iqlkMA=u*O{k7{nW3=kM2uMIMbQXx?Gv)<>~7+TEA)C=dw@x zI_+nF=*RQZwJLWXb8BQ%Kcsw3>tfnwjtR^Orm+j>6UlF5a&F^XF*Y4Ju$mhl!?>l7 zUDVIjOSfFyP1ma5=bVq;$J7s7>}R&uH#FT8A459_;-be3*QAo)cFqfXjvMFjvqwHw zU@mh!H&$@hGwL~f)c!WgwqA?f59%IUQm4Cr$8%eLdw*_tym$95Tk)~i;`2Mz;#^0) zGTl*cKC+P88=DvMH2e&o$q!n1^({4f=p!|=^jTqW4C(rFlQPO~Uf1748#+#^Um62N zEHPZ^f%_tSx+ z>g$7xxm`SUqNq2mg_Finw(lYN`pdL`!?%t)>a0_?_WSy6Wy_X#{@(5wb7`u-*uFF9 z;uF8O+X60gys9vvaYY8yxN;J&q;O4Bx}0;ZB)U;z$G!MUq$>AlW5eR7mPf%-fRAyFz_|q v{x<5|oeL}%NCO`j#|6^BmlR$Y@Vf()3-UO#Z>8`91KrS{6kh)WolVL=n_2-1 delta 1752 zcmV;}1}FLa60H#etq73#wDX#MotoFL>Q#4Dch~gP4<21zuRh;@uj>wvwqX#S@v@mD$9%{Z2q^l>Ky`6&L%umg|g@3-ehnu|wcO5>x%ei3b93Qg>gq z$_ese<0Tf(JovD2;>?RDf^p))Sz8FeiPv87gcB#!-qh}rzHKzbNp!wzjL#o`Fau#5 ziiHortehv)gg|juQ#KDZzi7vQ$H9{m&VNNUXB^wdYNj}`?w_u)#Ygt|%LG3$!s563 z$VthM#RvyZO7Xn|chRiF9_^D93nwJp#OTR$>YgvMj7rzznq_S6cuVd1`kxXnU5{&) zF^)mh=6Bz#{QMZ-;%`$$yWx3#F;(Sl&4CA;^y|VdN@?8<(*xgS6ABmHQaOv_D zb>iZmIVUfC^S1&?oFs&Q0-l5EJiLjqAIwlpdi`puZ)=w;^Xya0YVF{2aLwZrxQ>qP z4>6_qVRZ96h3 zwSRDFxrPxUgNIE~Uzbzlr0zaMPIQ@iPF&uZde}_T11CQ9=k_gsmwXrG?H=r^ZIT#} z-MF6VLiJ6a2fm!Z8BaNZyz?J@P|p~#KwtZYeZZw-&}*Dbq<{P2XWGn6gWGGi{7`+G z_W88K`1>+PT)KRPwTmeqAU)eiaPhmQ``F>ahix5#-Kp(i{v03FE>MQccLB7GePey> zk9+2<+eg(pAz=M~9j3Ccb&d~!>pDeF;5?{0Zk-bx16>y;K4@8PzjfsoZCsevI_g~a z0@^M#C;Axca$<`;^E~+7YKxpmK1yG4X; zK0bclrH&M9}n%${y95WY} zV_MQ<8C!jSu8!WOtv)wScz=!1KP#MePW1jw`Vi-Hh&aJC&L;l8m5CGhKC)2HC?Vmp zPTDL(fn30K_r^{&Tz{mrS0L}{Hy0J^Ie=athX*IY&Lf|=Dh54Z^zeewcYzMXR#)nC zd~cP|oJj94o3^R#eV$8wz{dRC#Mz^tL7+oDt%rJlsn0Fjn_@$?e*a>@N%r4e`QJjZ zablVi=A%t$3?rqb_EBd$YcbX}wM*k^Q$Ju=E=GeqBNw~}zoq*ws^{9J zSI+LHx$5hj)6sQI^>D>~COzNKe3N|)K9>Zt$sNvE;y*NKmuRXAm z%d0z9@;v+wpGgl`dFgevc=SEBu=+_Ma1Z(Vdy^{2Zd}(tLo3}Uv=5B~MI>?35p*7G zc?s5d uo33q6B%4e9_L&oIZZz#PcbngF;iXEueSq&euF{WB{kGa{3jYJ1G4?qNSclF4 diff --git a/assets/tilesheet/bandit_hideout.png b/assets/tilesheet/bandit_hideout.png index fe8cbb5c4a6a2cb4ec555e54b78f4d1489f338ad..7fafc2bf216f2133e63d79786cc4b740a279ddeb 100644 GIT binary patch delta 3176 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 diff --git a/assets/tilesheet/heart.ase b/assets/tilesheet/heart.ase new file mode 100644 index 0000000000000000000000000000000000000000..f6a93ed3f1ed4ecc6e910974d5ce539c12393a52 GIT binary patch literal 587 zcmcJMPbfoi9Ke6GnOz)|3#q-3?6kcREvren7^NMCR+zEcJ4__`Q_@n{Wm?LgDK0xG z%1!Mca#2e;s5KPARk$dV=kwC6+pC>8!AUO z*t{Bs?vNFF+_li|bU>GD0@?;6&=*5Q+UmxG=W}Ly7|XydF5& z7KM9uJIwY3U}iQ2V{08SI%-oDb}?vQSX+)I*noW638$K5dWof!Od1KKjx@T6qKF)= zMOCRF0Y7rgXmKLMhRUp&Bt6Uz38F-F`lm<6CApWIVo7_X6Dq&|XH2{>wUskp9KURz zyt~R9T4g(?nDwh>**~=6l$C>}%&zg_QXltO%FgDyO5;`fROR|jB;IcnmgJ1%8V!Z literal 0 HcmV?d00001 diff --git a/assets/tilesheet/heart.png b/assets/tilesheet/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5ad94e209f5e9f5a9589d3923badd7cfaa3878 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqv7RoDAre!Q6BHOE{v$Q*{q7GXvil*==sSFRK78V(@hJb6Mw<&;$Spvoh`g literal 0 HcmV?d00001 diff --git a/src/app.rs b/src/app.rs index 32963fd..18661eb 100644 --- a/src/app.rs +++ b/src/app.rs @@ -18,7 +18,8 @@ use super::{ }; use crate::{ ability::AbilityPlugin, ai::AIPlugin, attack::AttackPlugin, enviro::EnviroPlugin, - item::ItemPlugin, map::MapPlugin, room::RoomPlugin, weapon::WeaponPlugin, + item::ItemPlugin, map::MapPlugin, room::RoomPlugin, screens::ScreensPlugin, + weapon::WeaponPlugin, }; pub fn app() { @@ -34,6 +35,7 @@ pub fn app() { app.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) .insert_resource(ImageSettings::default_nearest()) + .insert_resource(Msaa { samples: 1 }) .insert_resource(window_descriptor); // .insert_resource(LogSettings { // level: bevy::log::Level::DEBUG, @@ -59,7 +61,8 @@ pub fn app() { .add_plugin(HealthBarPlugin) .add_plugin(EnviroPlugin) .add_plugin(WeaponPlugin) - .add_plugin(GridPlugin); + .add_plugin(GridPlugin) + .add_plugin(ScreensPlugin); app.run(); } diff --git a/src/assets.rs b/src/assets.rs index 23de52f..c9fd980 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -10,7 +10,7 @@ use crate::{ }; #[derive(Deref)] -pub struct SpriteSheet(Handle); +pub struct SpriteSheet(pub Handle); #[derive(Debug, Deref)] pub struct PrefabData(pub HashMap); diff --git a/src/attack.rs b/src/attack.rs index ad95f8c..f1b6d47 100644 --- a/src/attack.rs +++ b/src/attack.rs @@ -4,6 +4,7 @@ use serde::Deserialize; use crate::{ enemy::DamageEnemyEvent, grid::{CellType, Grid}, + player::DamagePlayerEvent, utils::{ok_or_continue, variant_eq, Dir}, }; @@ -69,7 +70,8 @@ impl Plugin for AttackPlugin { fn process_attack( mut events: EventReader, - mut writer: EventWriter, + mut enemy_writer: EventWriter, + mut player_writer: EventWriter, grid: Res, ) { for AttackEvent { @@ -86,10 +88,11 @@ fn process_attack( match cell_entity { CellType::Enemy(entity) => { - writer.send(DamageEnemyEvent { entity: *entity }); + enemy_writer.send(DamageEnemyEvent { entity: *entity }); }, CellType::Player(entity) => { info!("player hit!"); + player_writer.send(DamagePlayerEvent { entity: *entity }); }, _ => {}, } diff --git a/src/main.rs b/src/main.rs index 31b4389..a763018 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ mod movement; mod player; mod prefab; mod room; +mod screens; mod spritesheet_constants; mod ui; mod utils; diff --git a/src/player/inventory.rs b/src/player/inventory.rs index 994b1d1..7e422a0 100644 --- a/src/player/inventory.rs +++ b/src/player/inventory.rs @@ -3,11 +3,12 @@ use bevy_bobs::prefab::PrefabId; #[derive(Component)] pub struct Inventory { - pub weapon: PrefabId, + pub weapon_primary: PrefabId, + pub weapon_secondary: PrefabId, pub armor: PrefabId, pub ability: PrefabId, - pub slots: Vec, - capactiy: u32, + // pub slots: Vec, + // capactiy: u32, } impl Inventory {} diff --git a/src/player/mod.rs b/src/player/mod.rs index e9c855b..6a9346b 100644 --- a/src/player/mod.rs +++ b/src/player/mod.rs @@ -61,6 +61,10 @@ pub struct SpawnPlayerEvent { pub prefab_id: PrefabId, } +pub struct DamagePlayerEvent { + pub entity: Entity, +} + pub struct PlayerPlugin; impl Plugin for PlayerPlugin { @@ -70,6 +74,7 @@ impl Plugin for PlayerPlugin { .add_loopless_state(PlayerState::Move) .add_event::() .add_event::() + .add_event::() .add_system(controller.run_in_state(GameState::PlayerInput)) .add_system( move_controller @@ -87,6 +92,7 @@ impl Plugin for PlayerPlugin { .add_enter_system(GameState::PlayerInput, on_turn_start) .add_exit_system(GameState::PlayerInput, reset_on_turn_end) .add_system(spawn) + .add_system(take_damage) .add_system(update_move_indicator.run_in_state(GameState::PlayerInput)) .add_system(spawn_from_ldtk); } @@ -128,10 +134,6 @@ fn spawn( ..default() }, texture_atlas: asset_sheet.clone(), - transform: Transform { - translation: to_world_coords(spawn_pos).extend(BEING_LAYER), - ..default() - }, ..default() }) .insert(Player) @@ -349,3 +351,16 @@ fn spawn_from_ldtk( } } } + +fn take_damage( + mut cmd: Commands, + mut events: EventReader, + mut query: Query<(&mut Health, &GridEntity)>, +) { + for DamagePlayerEvent { entity } in events.iter() { + let (mut health, grid_entity) = query.get_mut(*entity).unwrap(); + + health.take(1); + if health.is_zero() {} + } +} diff --git a/src/screens/components/health.rs b/src/screens/components/health.rs new file mode 100644 index 0000000..206a1df --- /dev/null +++ b/src/screens/components/health.rs @@ -0,0 +1,58 @@ +use std::thread::current; + +use autodefault::*; +use bevy::prelude::*; +use bevy_bobs::component::health::Health; + +use crate::{ + assets::SpriteSheet, player::Player, screens::utils::FONT_PATH, + spritesheet_constants::SpriteIndex, utils::ok_or_return, +}; + +#[derive(Component)] +struct HealthNode; + +pub struct HealthPlugin; + +impl Plugin for HealthPlugin { + fn build(&self, app: &mut App) { + app.add_system(update); + } +} + +#[autodefault] +#[allow(non_snake_case)] +pub fn HealthBar(cmd: &mut ChildBuilder) -> Entity { + cmd.spawn() + .insert(HealthNode) + .insert_bundle(NodeBundle { + style: Style { + display: Display::Flex, + }, + }) + .id() +} + +#[autodefault] +fn update( + mut cmd: Commands, + mut player_query: Query<&Health, With>, + mut ui_query: Query<(Entity, &mut HealthNode), Without>, + asset_server: Res, +) { + let health = ok_or_return!(player_query.get_single()); + + // TODO kinda inefficnet to despawn all health nodes and respawn every frame + for (entity, mut health_node) in ui_query.iter_mut() { + cmd.entity(entity).despawn_descendants(); + + for i in 0..health.current() { + cmd.entity(entity).with_children(|parent| { + parent.spawn().insert_bundle(ImageBundle { + image: UiImage(asset_server.load("tilesheet/heart.png")), + style: Style {}, + }); + }); + } + } +} diff --git a/src/screens/components/inventory.rs b/src/screens/components/inventory.rs new file mode 100644 index 0000000..b6b33ba --- /dev/null +++ b/src/screens/components/inventory.rs @@ -0,0 +1,7 @@ +use bevy::prelude::*; + +pub struct InventoryPlugin; + +impl Plugin for InventoryPlugin { + fn build(&self, app: &mut App) {} +} diff --git a/src/screens/components/mod.rs b/src/screens/components/mod.rs new file mode 100644 index 0000000..337ae11 --- /dev/null +++ b/src/screens/components/mod.rs @@ -0,0 +1,14 @@ +pub mod health; +pub mod inventory; + +use bevy::prelude::*; + +use self::{health::HealthPlugin, inventory::InventoryPlugin}; + +pub struct ComponentPlugin; + +impl Plugin for ComponentPlugin { + fn build(&self, app: &mut App) { + app.add_plugin(InventoryPlugin).add_plugin(HealthPlugin); + } +} diff --git a/src/screens/ingame.rs b/src/screens/ingame.rs new file mode 100644 index 0000000..163142c --- /dev/null +++ b/src/screens/ingame.rs @@ -0,0 +1,35 @@ +use autodefault::*; +use bevy::prelude::*; +use iyes_loopless::prelude::*; + +use super::{ + components::health::HealthBar, + state::ScreenState, + utils::{destroy_ui, UIRoot}, +}; +use crate::{assets::SpriteSheet, spritesheet_constants::SpriteIndex}; + +pub struct IngamePlugin; + +impl Plugin for IngamePlugin { + fn build(&self, app: &mut App) { + app.add_enter_system(ScreenState::Ingame, render_ui) + .add_exit_system(ScreenState::Ingame, destroy_ui); + } +} + +#[autodefault] +fn render_ui(mut cmd: Commands) { + cmd.spawn() + .insert(UIRoot) + .insert_bundle(NodeBundle { + color: UiColor(Color::NONE), + style: Style { + align_self: AlignSelf::FlexEnd, + // justify_content: JustifyContent::Center, + }, + }) + .with_children(|mut parent| { + HealthBar(&mut parent); + }); +} diff --git a/src/screens/mod.rs b/src/screens/mod.rs new file mode 100644 index 0000000..e58f208 --- /dev/null +++ b/src/screens/mod.rs @@ -0,0 +1,28 @@ +mod components; +mod ingame; +mod state; +mod utils; + +use bevy::prelude::*; +use iyes_loopless::state::NextState; + +use self::{ + components::ComponentPlugin, + ingame::IngamePlugin, + state::{ScreenState, StatePlugin}, +}; + +pub struct ScreensPlugin; + +impl Plugin for ScreensPlugin { + fn build(&self, app: &mut App) { + app.add_plugin(StatePlugin) + .add_plugin(IngamePlugin) + .add_plugin(ComponentPlugin) + .add_startup_system(debug); + } +} + +fn debug(mut cmd: Commands) { + cmd.insert_resource(NextState(ScreenState::Ingame)); +} diff --git a/src/screens/state.rs b/src/screens/state.rs new file mode 100644 index 0000000..ea59cb4 --- /dev/null +++ b/src/screens/state.rs @@ -0,0 +1,18 @@ +use bevy::prelude::*; +use iyes_loopless::prelude::*; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ScreenState { + MainMenu, + Settings, + LevelSelect, + Ingame, +} + +pub struct StatePlugin; + +impl Plugin for StatePlugin { + fn build(&self, app: &mut App) { + app.add_loopless_state(ScreenState::MainMenu); + } +} diff --git a/src/screens/utils.rs b/src/screens/utils.rs new file mode 100644 index 0000000..da64a08 --- /dev/null +++ b/src/screens/utils.rs @@ -0,0 +1,13 @@ +use bevy::prelude::*; + +pub const FONT_PATH: &str = "fonts/arcadeclassic.ttf"; + +/// Marker component for the root node of each screen +#[derive(Component)] +pub struct UIRoot; + +/// Clean up UI when switching screens +pub fn destroy_ui(mut cmd: Commands, query: Query>) { + let e = query.single(); + cmd.entity(e).despawn_recursive(); +} diff --git a/src/spritesheet_constants.rs b/src/spritesheet_constants.rs index 354dc35..59e6b9a 100644 --- a/src/spritesheet_constants.rs +++ b/src/spritesheet_constants.rs @@ -20,6 +20,13 @@ pub enum SpriteIndex { // MoveIndicatorN = sprite!(5, 10), // MoveIndicatorS = sprite!(6, 10), // MoveIndicatorE = sprite!(7, 10), + ItemSlotBg = sprite!(0, 11), + WeaponSlot = sprite!(1, 11), + ArmorSlot = sprite!(2, 11), + AbilitySlot = sprite!(3, 11), + + HeartFull = sprite!(0, 12), + HeartEmpty = sprite!(0, 13), } // ui