Skip to content

Commit

Permalink
✨ rack can be killed
Browse files Browse the repository at this point in the history
  • Loading branch information
fabienjuif committed Nov 5, 2023
1 parent 5a87f39 commit 0e59293
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 49 deletions.
46 changes: 41 additions & 5 deletions src/health_bar.rs → src/health.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,31 @@ pub const DEFAULT_HEALTH_COLOR: Color = Color::rgb(0.2, 0.8, 0.2);
pub struct Health {
pub value: f32,
pub max: f32,

pub add_health_bar: bool,
pub health_bar_size: Option<Vec2>,
pub health_bar_position: Option<Vec3>,
}

impl Health {
pub fn new(max: f32) -> Self {
Self { value: max, max }
Self {
value: max,
max,
add_health_bar: true,
health_bar_position: None,
health_bar_size: None,
}
}

pub fn with_health_bar_position(mut self, position: Vec3) -> Self {
self.health_bar_position = Some(position);
self
}

pub fn with_health_bar_size(mut self, size: Vec2) -> Self {
self.health_bar_size = Some(size);
self
}

pub fn hit(&mut self, value: f32) -> &Self {
Expand All @@ -37,7 +57,7 @@ pub struct HealthBar {
}

#[derive(Bundle)]
pub struct HealthBarBundle {
struct HealthBarBundle {
pub sprite: SpriteBundle,
pub health_bar: HealthBar,
}
Expand All @@ -63,11 +83,11 @@ impl HealthBarBundle {
}
}

pub struct HealthBarPlugin;
pub struct HealthPlugin;

impl Plugin for HealthBarPlugin {
impl Plugin for HealthPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
app.add_systems(PreUpdate, add_health_bars).add_systems(
PostUpdate,
(
update_health_bar_position,
Expand Down Expand Up @@ -120,3 +140,19 @@ fn update_health_bar_visual(
}
}
}

fn add_health_bars(mut commands: Commands, mut query_health: Query<(Entity, &mut Health)>) {
for (entity, mut health) in &mut query_health {
if health.add_health_bar {
health.add_health_bar = false;

commands.spawn(HealthBarBundle::new(
entity,
health
.health_bar_position
.unwrap_or(Vec3::new(0.0, 15.0, 0.1)),
health.health_bar_size.unwrap_or(Vec2::new(10.0, 5.0)),
));
}
}
}
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod common;
mod health_bar;
mod health;
mod minions;
mod player;
mod racks;
Expand All @@ -11,7 +11,7 @@ use bevy::{
DefaultPlugins,
};
use bevy_rapier2d::prelude::*;
use health_bar::HealthBarPlugin;
use health::HealthPlugin;
use minions::MinionsPlugin;
use player::LocalPlayerPlugin;
use racks::RacksPlugin;
Expand All @@ -32,7 +32,7 @@ fn main() {
TeamsPlugin,
MinionsPlugin,
RacksPlugin,
HealthBarPlugin,
HealthPlugin,
LocalPlayerPlugin,
))
// --- physics ---
Expand Down
24 changes: 8 additions & 16 deletions src/minions.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use crate::{
common::*,
health_bar::{Health, HealthBarBundle},
teams::Team,
};
use crate::{common::*, health::Health, teams::Team};
use bevy::{
prelude::*,
sprite::{Sprite, SpriteBundle},
Expand Down Expand Up @@ -30,12 +26,12 @@ impl Plugin for MinionsPlugin {
Update,
(
update_move_minions,
destroy_minions,
check_collisions_players,
check_collisions_minions,
decay_life,
),
);
)
.add_systems(PostUpdate, destroy_minions);
}
}

Expand All @@ -51,8 +47,8 @@ pub fn spawn_minion(commands: &mut Commands, transform: &Transform, team: Team)
..default()
},
transform: Transform::from_xyz(
transform.translation.x + rng.gen_range(-20.0..20.0),
transform.translation.y + rng.gen_range(-20.0..20.0),
transform.translation.x + rng.gen_range(-40.0..40.0),
transform.translation.y + rng.gen_range(-40.0..40.0),
0.0,
),
..default()
Expand All @@ -70,18 +66,14 @@ pub fn spawn_minion(commands: &mut Commands, transform: &Transform, team: Team)
bevy::time::TimerMode::Once,
),
},
Health::new(20.),
Health::new(20.)
.with_health_bar_position(Vec3::new(0.0, 15.0, 0.1))
.with_health_bar_size(Vec2::new(10.0, 5.0)),
Rewards { gold: REWARDS_GOLD },
team,
))
.id();

commands.spawn(HealthBarBundle::new(
entity,
Vec3::new(0.0, 15.0, 0.1),
Vec2::new(10.0, 5.0),
));

trace!("Spawning Minion: {:?}", entity);
}

Expand Down
35 changes: 16 additions & 19 deletions src/player.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::common::*;
use crate::health_bar::{Health, HealthBarBundle};
use crate::health::Health;
use crate::racks::{RackBundle, RACK_GOLD_VALUE};
use crate::teams::{Team, Teams};
use bevy::{
Expand Down Expand Up @@ -90,7 +90,7 @@ fn setup(mut commands: Commands, teams: Res<Teams>) {
let mut sword_cooldown = Timer::from_seconds(0.3, TimerMode::Once);
sword_cooldown.set_elapsed(sword_cooldown.duration());

let entity = commands
commands
.spawn((
SpriteBundle {
sprite: Sprite {
Expand All @@ -112,7 +112,9 @@ fn setup(mut commands: Commands, teams: Res<Teams>) {
sword: sword_cooldown,
},
},
Health::new(100.),
Health::new(100.)
.with_health_bar_position(Vec3::new(0.0, 40.0, 0.1))
.with_health_bar_size(Vec2::new(50.0, 5.0)),
Name("local_player".to_string()),
teams.get_expect("a".into()),
))
Expand All @@ -129,14 +131,7 @@ fn setup(mut commands: Commands, teams: Res<Teams>) {
},
Hand {},
));
})
.id();

commands.spawn(HealthBarBundle::new(
entity,
Vec3::new(0.0, 40.0, 0.1),
Vec2::new(50.0, 5.0),
));
});
}

fn setup_ui(mut commands: Commands, asset_server: Res<AssetServer>) {
Expand Down Expand Up @@ -255,7 +250,7 @@ fn check_collisions_sword(
// mut commands: Commands,
query_swords: Query<(Entity, &Sword)>,
mut query_player: Query<(&mut Player, &Team)>,
mut query_hit_entities: Query<(&Rewards, &Team, &mut Health)>,
mut query_hit_entities: Query<(Option<&Rewards>, &Team, &mut Health)>,
mut collision_events: EventReader<CollisionEvent>,
) {
for collision_event in collision_events.iter() {
Expand All @@ -275,18 +270,20 @@ fn check_collisions_sword(
} else {
query_hit_entities.get_mut(*e2).ok()
};
let (rewards, hit_team, mut health) = match health {
let (rewards_opt, hit_team, mut health) = match health {
None => continue,
Some(o) => o,
};

// hurt
health.hit(20.);

// player attached to this sword receive gold
if let Ok((mut player, team)) = query_player.get_mut(sword.entity) {
if team.id != hit_team.id {
player.gold += rewards.gold;
if health.hit(20.).is_dead() {
// player attached to this sword receive gold
if let Ok((mut player, team)) = query_player.get_mut(sword.entity) {
if let Some(rewards) = rewards_opt {
if team.id != hit_team.id {
player.gold += rewards.gold;
}
}
}
}
}
Expand Down
48 changes: 42 additions & 6 deletions src/racks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ use bevy::{
sprite::{Sprite, SpriteBundle},
time::{Time, Timer, TimerMode},
};
use bevy_rapier2d::prelude::*;

use crate::teams::{Team, Teams};
use crate::{
common::Rewards,
health::Health,
teams::{Team, Teams},
};

pub const RACK_GOLD_VALUE: f32 = 10.;

Expand All @@ -22,15 +27,22 @@ pub struct RackBundle {
pub sprite_bundle: SpriteBundle,
pub team: Team,
pub rack: Rack,
pub health: Health,
pub rewards: Rewards,
pub rigid_body: RigidBody,
pub collider: Collider,
pub events: ActiveEvents,
pub mass: ColliderMassProperties,
}

impl RackBundle {
pub fn new(team: Team, transform: Transform) -> Self {
let size = Vec2::new(20.0, 20.0);
RackBundle {
sprite_bundle: SpriteBundle {
sprite: Sprite {
color: team.color,
custom_size: Some(Vec2::new(20.0, 20.0)),
custom_size: Some(size),
..default()
},
transform,
Expand All @@ -40,10 +52,18 @@ impl RackBundle {
rack: Rack {
minion_spawning: false,
minion_spawned_count: 0,
minion_spawn_count: 10,
minion_spawn_count: 5,
minion_spawn_timer: Timer::from_seconds(3., TimerMode::Repeating),
minion_spawn_timer_q: Timer::from_seconds(0.2, TimerMode::Repeating),
},
health: Health::new(80.)
.with_health_bar_position(Vec3::new(0.0, 20.0, 0.0))
.with_health_bar_size(Vec2::new(size.x, 5.)),
rewards: Rewards { gold: 100. },
rigid_body: RigidBody::Dynamic,
collider: Collider::cuboid(size.x / 2., size.y / 2.),
events: ActiveEvents::COLLISION_EVENTS,
mass: ColliderMassProperties::Mass(0.),
}
}
}
Expand All @@ -52,12 +72,13 @@ pub struct RacksPlugin;

impl Plugin for RacksPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup_rack)
.add_systems(Update, spawn_minions);
app.add_systems(Startup, setup)
.add_systems(Update, spawn_minions)
.add_systems(PostUpdate, destroy);
}
}

fn setup_rack(mut commands: Commands, teams: Res<Teams>) {
fn setup(mut commands: Commands, teams: Res<Teams>) {
commands.spawn(RackBundle::new(
teams.get_expect("b".into()),
Transform::from_xyz(200.0, 200.0, 0.),
Expand Down Expand Up @@ -105,3 +126,18 @@ fn spawn_minions(
}
}
}

// TODO: maybe this system can be retrieve from health bar crate (give the type and insert it in the filter?)
fn destroy(mut commands: Commands, mut query: Query<(&Health, Entity), With<Rack>>) {
let mut kill = |entity| {
trace!("Unspawning Minion: {:?}", entity);
commands.entity(entity).despawn_recursive();
};

for (health, entity) in &mut query {
// just not enough health
if health.is_dead() {
kill(entity);
}
}
}

0 comments on commit 0e59293

Please sign in to comment.