Player ui

This commit is contained in:
Rendo 2025-11-17 23:52:42 +05:00
commit d5bd76a3b7
6 changed files with 128 additions and 5 deletions

View file

@ -21,7 +21,9 @@ pub struct Damagable {
}
#[derive(Event)]
pub struct DamageableKilled(Option<Factions>);
pub struct DamageableKilled {
pub killed_faction: Option<Factions>,
}
impl Default for Damagable {
fn default() -> Self {
@ -58,7 +60,9 @@ pub fn broken_ships_cleanup(
for (entity, damagable, faction) in query {
if damagable.hp == 0 {
commands.get_entity(entity).unwrap().despawn();
commands.trigger(DamageableKilled(faction.cloned()));
commands.trigger(DamageableKilled {
killed_faction: faction.cloned(),
});
}
}
}

View file

@ -6,6 +6,7 @@ use crate::asteroid::AsteroidPlugin;
use crate::collision::CollisionPlugin;
use crate::damagable::DamagablePlugin;
use crate::projectile::ProjectilePlugin;
use crate::score::ScorePlugin;
use crate::ships::ShipsPlugin;
use crate::ui::UIPlugin;
use crate::velocity::VelocityPlugin;
@ -14,6 +15,7 @@ mod asteroid;
mod collision;
mod damagable;
mod projectile;
mod score;
mod ships;
mod ui;
mod velocity;
@ -58,6 +60,7 @@ fn main() {
ProjectilePlugin,
AsteroidPlugin,
UIPlugin,
ScorePlugin,
))
.add_systems(Startup, |mut commands: Commands| {
commands.spawn(Camera2d);

38
src/score.rs Normal file
View file

@ -0,0 +1,38 @@
use bevy::prelude::*;
use crate::{damagable::DamageableKilled, ships::Factions};
const ENEMY_REWARD: u64 = 10;
#[derive(Resource)]
pub struct Score {
pub score: u64,
pub max_score: u64,
}
pub struct ScorePlugin;
impl Plugin for ScorePlugin {
fn build(&self, app: &mut App) {
app.insert_resource(Score {
score: 0,
max_score: 0,
})
.add_observer(on_something_died);
}
}
pub fn on_something_died(killed: On<DamageableKilled>, mut score: ResMut<Score>) {
let Some(faction) = killed.killed_faction else {
return;
};
if faction != Factions::EnemyFaction {
return;
}
score.score += ENEMY_REWARD;
if score.max_score < score.score {
score.max_score = score.score;
}
}

View file

@ -6,7 +6,7 @@ pub mod enemy;
pub mod gun;
pub mod player;
#[derive(Component, Copy, Clone)]
#[derive(Component, Copy, Clone, PartialEq, Eq)]
pub enum Factions {
PlayerFaction,
EnemyFaction,
@ -39,7 +39,7 @@ impl Plugin for ShipsPlugin {
player::player_movement_system.run_if(in_state(GameState::Game)),
player::player_shooting_system.run_if(in_state(GameState::Game)),
gun::gun_shooting_system.run_if(in_state(GameState::Game)),
enemy::enemy_ai_system,
enemy::enemy_ai_system.run_if(in_state(GameState::Game)),
),
);
}

View file

@ -4,9 +4,11 @@ use crate::GameState;
use game_over::*;
use main_menu::*;
use player_interface::*;
mod game_over;
mod main_menu;
mod player_interface;
pub struct UIPlugin;
@ -14,6 +16,13 @@ impl Plugin for UIPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(GameState::InMenu), setup_menu)
.add_systems(Update, button_system.run_if(in_state(GameState::InMenu)))
.add_systems(OnExit(GameState::InMenu), cleanup_menu);
.add_systems(OnExit(GameState::InMenu), cleanup_menu)
.add_systems(OnEnter(GameState::Game), setup_player_interface)
.add_systems(
Update,
(update_player_health_display, update_player_score_display)
.run_if(in_state(GameState::Game)),
)
.add_systems(OnExit(GameState::Game), cleanup_player_interface);
}
}

View file

@ -0,0 +1,69 @@
use bevy::prelude::*;
use crate::{damagable::Damagable, score::Score, ships::player::PlayerMovement};
#[derive(Component)]
pub struct PlayerHealthDisplay;
#[derive(Component)]
pub struct PlayerScoreDisplay;
#[derive(Component)]
pub struct PlayerIntefrace;
pub fn setup_player_interface(mut commands: Commands) {
commands.spawn((
PlayerHealthDisplay,
Text::new("HP: 1"),
Node {
left: px(5),
top: px(5),
..default()
},
PlayerIntefrace,
));
commands.spawn((
PlayerScoreDisplay,
Text::new("Score: 0"),
Node {
left: px(5),
top: px(30),
..default()
},
PlayerIntefrace,
));
}
pub fn update_player_health_display(
text_query: Single<&mut Text, With<PlayerScoreDisplay>>,
score_query: Res<Score>,
) {
let mut text = text_query.into_inner();
let score = score_query.into_inner();
text.0 = "Score:".to_string() + (score.score).to_string().as_str();
}
pub fn update_player_score_display(
text_query: Single<&mut Text, With<PlayerHealthDisplay>>,
player_query: Single<&Damagable, With<PlayerMovement>>,
) {
let mut text = text_query.into_inner();
let player = player_query.into_inner();
text.0 = "Health:".to_string()
+ ((player.health() as f32) / (player.max_health() as f32))
.to_string()
.as_str();
}
pub fn cleanup_player_interface(
mut commands: Commands,
query: Query<Entity, With<PlayerIntefrace>>,
) {
for entity in query {
let Ok(mut interface) = commands.get_entity(entity) else {
continue;
};
interface.despawn();
}
}