Health for entities

This commit is contained in:
Rendo 2026-04-30 21:58:56 +05:00
commit 3e3fd85acc
7 changed files with 136 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
assets/sprites/sun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

126
src/health.rs Normal file
View file

@ -0,0 +1,126 @@
use bevy::prelude::*;
use std::ops::{Add,Sub,AddAssign,SubAssign};
pub struct HealthPlugin;
impl Plugin for HealthPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PostUpdate, despawn_killed)
.add_observer(recieve_damage);
}
}
/// Component that holds health information of damageable entity
#[derive(Component)]
pub struct Health{
health: u32,
max_health: u32,
}
impl Default for Health {
/// Create entity with minimum hp to not despawn immediatly
fn default() -> Self {
Self { health: 1, max_health: 1 }
}
}
impl Add<u32> for Health {
type Output = u32;
fn add(self, rhs: u32) -> Self::Output {
if u32::MAX - self.health < rhs {
u32::MAX
}
else {
self.health + rhs
}
}
}
impl Sub<u32> for Health {
type Output = u32;
fn sub(self, rhs: u32) -> Self::Output {
if self.health < rhs {
0
}
else {
self.health - rhs
}
}
}
impl AddAssign<u32> for Health {
fn add_assign(&mut self, rhs: u32) {
if u32::MAX - self.health < rhs {
self.health = u32::MAX;
}
else {
self.health += rhs;
}
}
}
impl SubAssign<u32> for Health {
fn sub_assign(&mut self, rhs: u32) {
if self.health < rhs {
self.health = 0;
}
else {
self.health -= rhs;
}
}
}
impl Health {
/// Create new health component with set health and max health
pub fn new(health: u32, max_health: u32) -> Self {
Self {
health,
max_health
}
}
/// Create new health from max health
pub fn new_full(max_health: u32) -> Self {
Self {
health: max_health,
max_health
}
}
}
/// Event sent on an vulnerable entity to damage it.
#[derive(EntityEvent)]
pub struct Damage{
entity: Entity,
damage: u32
}
/// Marks entity to recieve [`Damage`] events.
#[derive(Component)]
#[require(Health)]
pub struct Vulnerable;
/// Marks entity to not despawn when health drops to zero.
#[derive(Component)]
#[require(Health)]
pub struct Unkillable;
/// Despawn all killable entites with health equal to zero
pub fn despawn_killed(mut commands: Commands, query: Query<(Entity, &Health), Without<Unkillable>>) {
for (entity, health) in query {
if health.health == 0 {
commands.entity(entity).despawn();
}
}
}
/// Process damage event for vulnerable entities
pub fn recieve_damage(event: On<Damage>, mut query: Query<&mut Health, With<Vulnerable>>) {
let Ok(mut health) = query.get_mut(event.entity) else {
return;
};
*health -= event.damage;
}

0
src/level/mod.rs Normal file
View file

View file

@ -1,3 +1,12 @@
use bevy::prelude::*;
use crate::health::HealthPlugin;
mod plant;
mod zombie;
mod health;
mod level;
fn main() {
println!("Hello, world!");
App::new().add_plugins(DefaultPlugins).add_plugins(HealthPlugin).run();
}

0
src/plant/mod.rs Normal file
View file

0
src/zombie/mod.rs Normal file
View file