ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
particles.cpp
Go to the documentation of this file.
1
8
10
11#include <algorithm>
12#include <cmath>
13
14#include "asw/modules/draw.h"
15#include "asw/modules/random.h"
16#include "asw/modules/util.h"
17
18namespace asw {
19
20ParticleEmitter::ParticleEmitter(const ParticleConfig& config, uint32_t maxParticles)
21 : config(config)
22 , particles(maxParticles)
23{
24}
25
27{
28 emission_rate = rate;
29}
30
31void ParticleEmitter::emit(uint32_t count)
32{
33 for (uint32_t i = 0; i < count; ++i) {
35 }
36}
37
39{
40 emitting = true;
41}
42
44{
45 emitting = false;
46}
47
49{
50 // Auto-emit
51 if (emitting && emission_rate > 0.0F) {
53 while (emission_accumulator >= 1.0F) {
56 }
57 }
58
59 // Update alive particles (swap-and-shrink)
60 for (uint32_t i = 0; i < alive_count;) {
61 auto& p = particles[i];
62 p.age += dt;
63
64 if (p.age >= p.lifetime) {
67 continue;
68 }
69
70 p.velocity += config.gravity * dt;
71 p.position += p.velocity * dt;
72 ++i;
73 }
74}
75
77{
78 draw_offset(Vec2<float>(0.0F, 0.0F));
79}
80
81void ParticleEmitter::draw(const Camera& camera)
82{
84}
85
87{
88 // Sentinel: the first textured particle always pushes its alpha, so the
89 // emitter never assumes what the shared texture was left at.
90 float last_alpha = -1.0F;
91
92 for (uint32_t i = 0; i < alive_count; ++i) {
93 const auto& p = particles[i];
94 // A zero lifetime would divide by zero, treat it as already over
95 const float t = p.lifetime > 0.0F ? std::min(p.age / p.lifetime, 1.0F) : 1.0F;
96
97 // Interpolate visuals
98 const float size = util::lerp(config.size_start, config.size_end, t);
100
101 if (config.texture != nullptr) {
102 const auto dest = Quad<float>(p.position.x - offset.x - (size / 2.0F),
103 p.position.y - offset.y - (size / 2.0F), size, size);
104
105 if (alpha != last_alpha) {
107 last_alpha = alpha;
108 }
109
111 } else {
112 auto color = config.color_start.lerp(config.color_end, t);
113 color.a = Color::to_channel(color.a * alpha);
114
115 draw::circle_fill(p.position - offset, size / 2.0F, color);
116 }
117 }
118
119 // Restore the default once per emitter instead of once per particle.
120 if (last_alpha >= 0.0F && last_alpha != 1.0F) {
122 }
123}
124
126{
127 return alive_count;
128}
129
131{
132 if (alive_count >= particles.size()) {
133 return;
134 }
135
136 auto& p = particles[alive_count];
137 p.position = transform.position;
138 p.age = 0.0F;
140 p.alive = true;
141
142 const float speed = random::between(config.speed_min, config.speed_max);
143 const float angle = random::between(config.angle_min, config.angle_max);
144 p.velocity = Vec2<float>::from_angle(angle, speed);
145
146 p.size = config.size_start;
147 p.rotation = 0.0F;
148
149 alive_count++;
150}
151
152} // namespace asw
2D camera that follows a target, stays inside the world and shakes.
Definition camera.h:21
Quad< float > get_view() const
Get the visible world area, including shake.
Definition camera.cpp:115
void draw() override
Draw alive particles. Positions are in screen space.
Definition particles.cpp:76
std::vector< Particle > particles
Definition particles.h:125
ParticleConfig config
Definition particles.h:124
uint32_t get_alive_count() const
Get the number of alive particles.
ParticleEmitter()=default
Create a default ParticleEmitter with no particles.
void emit(uint32_t count)
Emit a burst of particles at current position.
Definition particles.cpp:31
void set_emission_rate(float rate)
Set emission rate (particles per second), 0 to disable auto-emit.
Definition particles.cpp:26
void start()
Start continuous emission.
Definition particles.cpp:38
void draw_offset(const Vec2< float > &offset)
Definition particles.cpp:86
void update(float dt) override
Update particles.
Definition particles.cpp:48
void stop()
Stop continuous emission.
Definition particles.cpp:43
A 2D rectangle in space.
Definition geometry.h:504
Vec2< T > position
The position of the rectangle.
Definition geometry.h:725
A 2D vector in space.
Definition geometry.h:27
T y
The y component of the vector.
Definition geometry.h:280
T x
The x component of the vector.
Definition geometry.h:277
static Vec2 from_angle(T angle, T length=T(1))
Create a vector pointing at an angle.
Definition geometry.h:76
float alpha
Opacity of the object.
Definition game.h:96
asw::Quad< float > transform
The transform of the object.
Definition game.h:77
Routines for drawing sprites and primitives to the screen.
void circle_fill(const asw::Vec2< float > &position, float radius, asw::Color color)
Draw a filled circle.
Definition draw.cpp:647
void stretch_sprite(const asw::Texture &tex, const asw::Quad< float > &position)
Draw a sprite with the option to stretch it.
Definition draw.cpp:232
void set_alpha(const asw::Texture &texture, float alpha)
Set the alpha of a texture.
Definition draw.cpp:823
int between(int min, int max)
Generate a random integer between min and max.
Definition random.cpp:19
T lerp(const T &a, const T &b, float t)
Lerp between two values.
Definition util.h:73
Definition camera.cpp:16
Lightweight particle emitter system.
Random module for the ASW library.
static uint8_t to_channel(float value)
Round a 0-255 channel value and clamp it into range. Casting an out of range float straight to uint8_...
Definition color.h:25
Color lerp(const Color &color, float t) const
Mix towards another color, including alpha.
Definition color.h:152
uint8_t a
Definition color.h:33
Configuration for particle emitters.
Definition particles.h:24
Vec2< float > gravity
Definition particles.h:46
General utility functions.