-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdeathAnimation.cpp
More file actions
84 lines (65 loc) · 2.1 KB
/
Copy pathdeathAnimation.cpp
File metadata and controls
84 lines (65 loc) · 2.1 KB
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
#include "chomper/animations/deathAnimation.hpp"
#include "chomper/world_space.hpp"
#include <numbers>
namespace chomper::animation {
namespace {
constexpr auto easeOut(float t) {
return 1.f - ((1.f - t) * (1.f - t));
}
} // namespace
DeathAnimation::DeathAnimation(std::span<le::RenderInstance const> instances) {
m_segments.clear();
m_segments.reserve(instances.size());
m_quads.instances.clear();
m_quads.instances.reserve(instances.size());
m_quads.create(tileSize_v);
for (auto const& instance : instances) {
auto dir = m_random.next_float(0, 360);
auto lifetime = m_random.next_float(2, 5);
auto speed = m_random.next_float(300, 600);
auto rotSpeed = m_random.next_float(5.f, 20.f);
auto rad = dir * std::numbers::pi_v<float> / 180.f;
Segment seg;
seg.rotSpeed = rotSpeed;
seg.velocity = {std::cos(rad) * speed, std::sin(rad) * speed};
seg.remaining = lifetime;
seg.lifetime = lifetime;
m_quads.instances.emplace_back().tint = instance.tint;
m_quads.instances.back().transform = instance.transform;
m_segments.push_back(seg);
}
}
void DeathAnimation::tick(kvf::Seconds dt) {
assert(m_segments.size() == m_quads.instances.size());
auto animating = false;
for (std::size_t i = 0; i < m_segments.size(); i++) {
auto& seg = m_segments[i];
if (seg.remaining <= 0.f) {
continue;
}
seg.remaining -= dt.count();
auto t = std::clamp(1.f - (seg.remaining / seg.lifetime), 0.f, 1.f);
auto eased = 1.f - easeOut(t);
auto& quad = m_quads.instances.at(i);
quad.transform.position += seg.velocity * eased * dt.count();
if (worldSpace::isOutOfBounds(worldSpace::worldToGrid(quad.transform.position))) {
seg.velocity = -seg.velocity;
}
auto angle = dt.count() * eased * seg.rotSpeed;
quad.transform.orientation.rotate(angle);
if (t > 0.8f) {
auto scale = 1.f;
auto u = (t - 0.8f) / 0.2f; // 0 → 1
scale = 1.f - u; // 1 → 0
quad.transform.scale = {scale, scale};
}
if (t < 1.f) {
animating = true;
}
}
m_finished = !animating;
}
void DeathAnimation::draw(le::IRenderer& renderer) const {
m_quads.draw(renderer);
}
} // namespace chomper::animation