Tutorial 06: Particle Systems
Working with particle systems and the particle editor.
Overview
This tutorial covers the HGE particle system, which enables effects like fire, smoke, explosions, sparkles, and magic spells. You'll learn to use the particle editor and integrate effects into your game.
Prerequisites
- Basic HGE application structure
- Texture loading and sprite rendering
- Particle Editor tool
The Particle System
HGE's particle system uses these components:
- hgeParticleSystem — Manages and renders particles
- hgeParticleSystemInfo — Stores effect parameters
- Particle Editor — Visual design tool
Creating Effects
Step 1: Design in the Editor
Open the particle editor and create your effect:
- Load a particle texture (small sprite for each particle)
- Adjust emission, movement, and appearance
- Test and refine
- Save as .psi file
Step 2: Load in Your Game
hgeSprite *sprParticle;
hgeParticleSystem *ps;
void LoadParticles()
{
// Load the particle sprite
HTEXTURE tex = hge->Texture_Load("particles.png");
sprParticle = new hgeSprite(tex, 0, 0, 32, 32);
sprParticle->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD);
sprParticle->SetHotSpot(16, 16);
// Create particle system from .psi file
ps = new hgeParticleSystem("effects/fire.psi", sprParticle);
}
Step 3: Update and Render
bool FrameFunc()
{
float dt = hge->Timer_GetDelta();
// Update particle positions
ps->Update(dt);
// Move emitter to follow something
float mx, my;
hge->Input_GetMousePos(&mx, &my);
ps->MoveTo(mx, my);
return false;
}
bool RenderFunc()
{
hge->Gfx_BeginScene();
hge->Gfx_Clear(0);
// Render all particles
ps->Render();
hge->Gfx_EndScene();
return false;
}
Effect Triggering
Continuous Effects
For ongoing effects like torch fire:
// The system emits continuously by default
ps->Fire(); // Start emission
Burst Effects
For one-shot effects like explosions:
// Stop continuous emission
ps->Stop(false); // false = let existing particles finish
// Trigger bursts manually
void Explode(float x, float y)
{
ps->MoveTo(x, y);
ps->Fire(); // Emit burst
}
Multiple Particle Systems
For different effects, create multiple systems:
hgeParticleSystem *psFire;
hgeParticleSystem *psSmoke;
hgeParticleSystem *psExplosion;
void LoadEffects()
{
psFire = new hgeParticleSystem("effects/fire.psi", sprFireParticle);
psSmoke = new hgeParticleSystem("effects/smoke.psi", sprSmokeParticle);
psExplosion = new hgeParticleSystem("effects/explosion.psi", sprExplosionParticle);
}
void UpdateEffects(float dt)
{
psFire->Update(dt);
psSmoke->Update(dt);
psExplosion->Update(dt);
}
void RenderEffects()
{
psFire->Render();
psSmoke->Render();
psExplosion->Render();
}
Performance Tips
- Limit particle count — Don't exceed a few thousand active particles
- Use simple textures — Small, simple particle sprites render faster
- Reuse systems — Move and retrigger rather than create new instances
- Cull off-screen — Don't update systems that aren't visible
Complete Example
#include <hge.h>
#include <hgeparticle.h>
HGE *hge = 0;
hgeSprite *sprParticle;
hgeParticleSystem *ps;
bool FrameFunc()
{
float dt = hge->Timer_GetDelta();
// Update particles
ps->Update(dt);
// Follow mouse
float mx, my;
hge->Input_GetMousePos(&mx, &my);
ps->MoveTo(mx, my);
// Click to restart
if (hge->Input_KeyDown(HGEK_LBUTTON))
ps->Fire();
return hge->Input_GetKeyState(HGEK_ESCAPE);
}
bool RenderFunc()
{
hge->Gfx_BeginScene();
hge->Gfx_Clear(0);
ps->Render();
hge->Gfx_EndScene();
return false;
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_SCREENWIDTH, 800);
hge->System_SetState(HGE_SCREENHEIGHT, 600);
hge->System_SetState(HGE_TITLE, "Tutorial 06 - Particles");
if (hge->System_Initiate())
{
HTEXTURE tex = hge->Texture_Load("particle.png");
sprParticle = new hgeSprite(tex, 0, 0, 32, 32);
sprParticle->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD);
sprParticle->SetHotSpot(16, 16);
ps = new hgeParticleSystem("trail.psi", sprParticle);
ps->Fire();
hge->System_Start();
delete ps;
delete sprParticle;
hge->Texture_Free(tex);
}
hge->System_Shutdown();
hge->Release();
return 0;
}