Skip to content

Instantly share code, notes, and snippets.

@skejeton
Created May 29, 2021 20:59
Show Gist options
  • Save skejeton/55b7bda320aa8c104a8eb49ce076f5bb to your computer and use it in GitHub Desktop.
Save skejeton/55b7bda320aa8c104a8eb49ce076f5bb to your computer and use it in GitHub Desktop.
prtcls
#include "particle_system.h"
#include "camera.h"
#include <SDL2/SDL_render.h>
#include <stdint.h>
static int particle_rand(u32 *seed) {
return (((*seed = *seed * 214013L + 2531011L) >> 16) & 0x7fff);
}
/// Create partcile system
ParticleSystem particle_system_new() {
return (ParticleSystem) { .chunks = enty_new(sizeof(ParticleChunk)), .seed = 0 };
}
/// Summon random cluster of particles at a specified position
void particle_system_summon_random_cluster(ParticleSystem *self, Vec2 origin, usize density) {
ParticleChunk chunk = {
.particle_count = density,
.origin = origin,
.seed = particle_rand(&self->seed),
.lifetime = 1,
.life = 0
};
enty_insert(&self->chunks, &chunk);
}
/// Update chunk lifetimes
void particle_system_update(ParticleSystem *self, f64 delta) {
for (
usize i = enty_first_index(&self->chunks);
!enty_is_free(&self->chunks, i);
i = enty_advance_index(&self->chunks, i)
)
{
ParticleChunk *chunk = enty_get(&self->chunks, i);
chunk->life = fmin(chunk->lifetime, chunk->life + delta);
if (chunk->life >= chunk->lifetime) enty_free_index(&self->chunks, i);
}
}
/// Render particle system
void particle_system_draw(ParticleSystem *self, SDL_Renderer *renderer, Camera *camera) {
for (
usize i = enty_first_index(&self->chunks);
!enty_is_free(&self->chunks, i);
i = enty_advance_index(&self->chunks, i)
) {
ParticleChunk *chunk = enty_get(&self->chunks, i);
// Here's some magickery, we'll use seed in the chunk to determine properties of a particle
u32 current_seed = chunk->seed;
for (usize i = 0; i < chunk->particle_count; i += 1) {
f64 direction = (particle_rand(&current_seed)%1000/(f64)1000)*M_PI;
f64 sign = particle_rand(&current_seed)%2 == 0 ? -1 : 1;
f64 speed = (particle_rand(&current_seed)%100+10)*sign;
Vec2 xy = camera_displace_position(camera, (Vec2) {
1/chunk->life * cos(direction) * speed + chunk->origin.x,
1/chunk->life * sin(direction) * speed + chunk->origin.y
});
SDL_Rect dest = {
.x = xy.x,
.y = xy.y,
.w = 16,
.h = 16
};
SDL_SetRenderDrawColor(renderer, 255, 255, 255, (1.0-(chunk->life/chunk->lifetime))*255);
SDL_RenderFillRect(renderer, &dest);
}
}
}
/// Free stuff
void particle_system_drop(ParticleSystem self) {
enty_drop(&self.chunks);
}
#include "../deps/everything.h"
#include <SDL2/SDL_render.h>
#include "camera.h"
#include "vec2.h"
typedef struct ParticleChunk {
// The particles aren't actually stored, they will use a RNG with seed to render their positions
usize particle_count;
Vec2 origin;
u32 seed;
f64 life; // Length of life
f64 lifetime;
} ParticleChunk;
typedef struct ParticleSystem {
u32 seed;
Enty /*<ParticleChunk>*/ chunks;
} ParticleSystem;
/// Create partcile system
ParticleSystem particle_system_new();
/// Summon random cluster of particles at a specified position
void particle_system_summon_random_cluster(ParticleSystem *self, Vec2 origin, usize density);
/// Update chunk lifetimes
void particle_system_update(ParticleSystem *self, f64 delta);
/// Render particle system
void particle_system_draw(ParticleSystem *self, SDL_Renderer *renderer, Camera *camera);
/// Free stuff
void particle_system_drop(ParticleSystem self);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment