player can take damage

This commit is contained in:
2025-04-02 11:33:01 +08:00
parent f967b1b0da
commit 4652bc4563
8 changed files with 120 additions and 50 deletions

View File

@@ -1,31 +1,14 @@
use crate::{
GameState, heads::HEAD_COUNT, keys::KeySpawn, player::head_id_to_str, sounds::PlaySound,
GameState,
heads::HEAD_COUNT,
hitpoints::{Hitpoints, Kill},
keys::KeySpawn,
player::head_id_to_str,
tb_entities::EnemySpawn,
};
use bevy::prelude::*;
use std::collections::HashMap;
#[derive(Event, Reflect)]
pub struct Hit {
pub damage: u32,
}
#[derive(Component, Reflect)]
pub struct Hitpoints {
max: i32,
current: i32,
}
impl Hitpoints {
fn new(v: i32) -> Self {
Self { max: v, current: v }
}
pub fn health(&self) -> f32 {
self.current as f32 / self.max as f32
}
}
#[derive(Component)]
pub struct NpcHead(pub usize);
@@ -33,7 +16,7 @@ pub fn plugin(app: &mut App) {
app.add_systems(OnEnter(GameState::Playing), init);
}
fn init(mut commands: Commands, query: Query<(Entity, &EnemySpawn), Without<Hitpoints>>) {
fn init(mut commands: Commands, query: Query<(Entity, &EnemySpawn)>) {
let mut names: HashMap<String, usize> = HashMap::default();
for i in 0..HEAD_COUNT {
names.insert(head_id_to_str(i).to_string(), i);
@@ -43,32 +26,22 @@ fn init(mut commands: Commands, query: Query<(Entity, &EnemySpawn), Without<Hitp
commands
.entity(e)
.insert((Hitpoints::new(100), NpcHead(id)))
.observe(on_hit);
.observe(on_kill);
}
}
fn on_hit(
trigger: Trigger<Hit>,
fn on_kill(
trigger: Trigger<Kill>,
mut commands: Commands,
mut query: Query<(&mut Hitpoints, &Transform, &EnemySpawn)>,
query: Query<(&Transform, &EnemySpawn)>,
) {
let Hit { damage } = trigger.event();
let Ok((mut hp, transform, enemy)) = query.get_mut(trigger.entity()) else {
let Ok((transform, enemy)) = query.get(trigger.entity()) else {
return;
};
commands.trigger(PlaySound::Hit);
commands.entity(trigger.entity()).despawn_recursive();
hp.current = hp.current.saturating_sub(*damage as i32);
info!("npc hp changed: {} [{}]", hp.current, trigger.entity());
if hp.current <= 0 {
commands.entity(trigger.entity()).despawn_recursive();
if !enemy.key.is_empty() {
commands.trigger(KeySpawn(transform.translation, enemy.key.clone()));
}
if !enemy.key.is_empty() {
commands.trigger(KeySpawn(transform.translation, enemy.key.clone()));
}
}