diff --git a/src/damagable.rs b/src/damagable.rs new file mode 100644 index 0000000..16b721e --- /dev/null +++ b/src/damagable.rs @@ -0,0 +1,17 @@ +use bevy::prelude::*; + +#[derive(Component)] +pub struct Damagable { + hp: u32, + max_hp: u32, +} + +impl Damagable { + pub fn new(max_hp: u32) -> Damagable { + Damagable { max_hp, hp: max_hp } + } + + pub fn damage(&mut self, amount: u32) { + self.hp = u32::clamp(self.hp - amount, 0, self.max_hp) + } +} diff --git a/src/main.rs b/src/main.rs index 85bb5fb..587a4aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,9 @@ use crate::movable::MovablePlugin; use crate::ships::ShipsPlugin; mod collision; +mod damagable; mod movable; +mod projectile; mod ships; fn main() { diff --git a/src/projectile.rs b/src/projectile.rs new file mode 100644 index 0000000..c68fc94 --- /dev/null +++ b/src/projectile.rs @@ -0,0 +1,44 @@ +use bevy::prelude::*; + +use crate::{ + collision::{Collided, Collider}, + damagable::Damagable, +}; + +#[derive(Component)] +pub struct Projectile { + damage: u32, +} + +impl Projectile { + pub fn new(damage: u32) -> Projectile { + Projectile { damage } + } +} + +pub fn spawn_projectile(commands: &mut Commands, sprite: Handle, damage: u32) { + commands + .spawn(( + Projectile::new(damage), + Sprite::from(sprite), + Collider::new(8.), + Transform::from_xyz(0., 0., 0.), + )) + .observe(observe_collision); +} +pub fn observe_collision( + collision: On, + mut commands: Commands, + projectile_query: Query<&Projectile>, + mut collision_query: Query<&mut Damagable>, +) { + let Ok(projectile) = projectile_query.get(collision.entity) else { + return; + }; + let Ok(mut collided) = collision_query.get_mut(collision.with) else { + return; + }; + + collided.damage(projectile.damage); + commands.get_entity(collision.entity).unwrap().despawn(); +} diff --git a/src/ships/enemy.rs b/src/ships/enemy.rs index 735dde1..141abf2 100644 --- a/src/ships/enemy.rs +++ b/src/ships/enemy.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; -use crate::{collision::Collider, movable::Movable}; +use crate::{collision::Collider, damagable::Damagable, movable::Movable}; #[derive(Component)] pub struct Enemy; @@ -12,5 +12,6 @@ pub fn spawn_enemy(commands: &mut Commands, sprite: Handle, at: Vec2) { Movable::new(500., f32::to_radians(360.)), Sprite::from(sprite), Transform::from_xyz(at.x, at.y, 0.), + Damagable::new(10), )); } diff --git a/src/ships/mod.rs b/src/ships/mod.rs index ba5e6df..a34077c 100644 --- a/src/ships/mod.rs +++ b/src/ships/mod.rs @@ -1,5 +1,7 @@ use bevy::prelude::*; +use crate::projectile::spawn_projectile; + pub mod enemy; pub mod player; @@ -16,9 +18,11 @@ impl Plugin for ShipsPlugin { fn startup(mut commands: Commands, asset_server: Res) { let player_sprite: Handle = asset_server.load("player.png"); let enemy_sprite: Handle = asset_server.load("enemy.png"); + let projectile: Handle = asset_server.load("projectile.png"); commands.spawn(Camera2d); player::spawn_player(&mut commands, player_sprite, Vec2::new(0., 0.)); enemy::spawn_enemy(&mut commands, enemy_sprite.clone(), Vec2::new(100., 100.)); + spawn_projectile(&mut commands, projectile, 1); } diff --git a/src/ships/player.rs b/src/ships/player.rs index d961b85..89c5ab1 100644 --- a/src/ships/player.rs +++ b/src/ships/player.rs @@ -1,4 +1,4 @@ -use crate::{collision::Collider, movable::Movable}; +use crate::{collision::Collider, damagable::Damagable, movable::Movable}; use bevy::prelude::*; #[derive(Component)] @@ -13,6 +13,7 @@ pub fn spawn_player(commands: &mut Commands, sprite: Handle, at: Vec2) { Movable::new(500., f32::to_radians(360.)), Sprite::from(sprite), Transform::from_xyz(at.x, at.y, 0.), + Damagable::new(10), )); }