-
Notifications
You must be signed in to change notification settings - Fork 0
/
Damagable.cpp
98 lines (94 loc) · 2.76 KB
/
Damagable.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "Damagable.hpp"
#include "Engine/util/Random.hpp"
#include "Engine/Factory.hpp"
#include "Level.hpp"
#include "Slayer.hpp"
Damagable::Damagable(engine::Scene* scene): SpriteNode(scene), m_health(10),
m_maxHealth(10), m_dead(false), m_hit(false), m_preCH(this), m_damage(2),
m_invulnTime(0) {
m_scene->OnContactPreSolve.AddHandler(&m_preCH);
static_cast<Level*>(scene)->IncEnemies();
}
Damagable::~Damagable() {
m_scene->OnContactPreSolve.RemoveHandler(&m_preCH);
static_cast<Level*>(m_scene)->DecEnemies();
}
void Damagable::OnUpdate(sf::Time interval) {
m_invulnTime-=interval.asSeconds();
if (m_hit) {
m_hit=false;
engine::util::RandomFloat r(0, 1);
const size_t c = static_cast<size_t>(2*(r()*10+1));
for (size_t i =0; i<c;i++) {
auto particle = engine::Factory::CreateChildFromFile("assets/scripts/blood_particle.json", m_scene);
auto pos = GetGlobalPosition();
particle->SetPosition(pos.x, pos.y);
if (particle->GetBody()) {
particle->GetBody()->SetLinearVelocity(b2Vec2(static_cast<float>(10*(r()-0.5f)), static_cast<float>(10*(r()-0.5f))));
}
}
}
if (m_health <= 0 && !m_dead) {
m_dead = true;
if (GetBody()) {
GetBody()->SetActive(false);
}
PlayAnimation("death");
if (GetAnimation()) {
GetAnimation()->OnOver = [this](){
Delete();
};
}
}
}
bool Damagable::initialize(Json::Value& root) {
if (!engine::SpriteNode::initialize(root)) {
return false;
}
m_health = m_maxHealth = root.get("health", 10.0f).asFloat();
m_damage = root.get("damage", 2.0f).asFloat();
return true;
}
void Damagable::Damage(float damage){
if (m_invulnTime > 0) return;
m_health-=damage;
if (damage > 0.1 || m_health < 0) {
m_hit = true;
}
if (m_health < 0 && !m_dead) {
m_deathSound->play();
} else {
m_hurtSound->play();
}
m_invulnTime = 0.1;
static_cast<Level*>(m_scene)->ChangeScore(damage/4);
UpdateHealthbar();
}
void Damagable::UpdateHealthbar() {
auto healthbar = GetChildByID("healthbar");
if (healthbar) {
auto health = healthbar->GetChildByID("health");
if (m_health < 0 ){
healthbar->SetActive(false);
} else {
auto orig = healthbar->GetSize();
float ratio = m_health/m_maxHealth;
orig.x = (orig.x -4)*ratio;
health->SetSize(orig);
}
}
}
void Damagable::ContactHandler::handle(b2Contact* c, const b2Manifold* manifold) {
void* udA = c->GetFixtureA()->GetBody()->GetUserData();
void* udB = c->GetFixtureB()->GetBody()->GetUserData();
Slayer* slayer = nullptr;
if (udA == m_enemy && udB == static_cast<Level*>(m_enemy->GetScene())->GetSlayer()) {
slayer = static_cast<Slayer*>(udB);
} else if (udB == m_enemy && udA == static_cast<Level*>(m_enemy->GetScene())->GetSlayer()) {
slayer = static_cast<Slayer*>(udA);
}
if (slayer) {
slayer->Damage(m_enemy->GetDamage());
c->SetEnabled(false);
}
}