game audio

Game audio and visual effects โ€” Web Audio API, particles, and post-processing

๐Ÿ“˜ gamedev-academy · Part 11 of 15 · Module 4 · Polish
A free, step-by-step course on buying, selling & trading domains. View the full series →
Game audio and visual effects โ€” Web Audio API, particles, and post-processing
Key takeaways
  • Web Audio API gives you low-latency sound playback with pitch variation โ€” essential for satisfying game feel.
  • A particle system is just an array of short-lived objects with position, velocity, and lifetime โ€” simple but visually powerful.
  • Screen shake is the highest-impact juice effect: a decaying random camera offset on every hit or explosion.

Understanding game audio is the foundation of this guide. Below we break it down step by step so you can act with confidence.

Audio and visual effects are what transform a functional game into a feel-good game. A subtle screen shake on impact, particles on an explosion, and a satisfying sound effect make gameplay addictive.

This lesson covers the Web Audio API, particle systems, screen shake, and post-processing techniques.

Game Audio: Web Audio API for game sound

The Web Audio API gives you low-latency sound playback, spatial audio, and effects. Create an audio context and load sounds as buffers:

๐Ÿ”ฌ Demo: Sound manager with Web Audio API
class SoundManager {
  constructor() {
    this.ctx = new AudioContext();
    this.sounds = new Map();
    this.masterGain = this.ctx.createGain();
    this.masterGain.connect(this.ctx.destination);
  }

  async load(name, url) {
    const res = await fetch(url);
    const buf = await res.arrayBuffer();
    const audio = await this.ctx.decodeAudioData(buf);
    this.sounds.set(name, audio);
  }

  play(name, volume = 1, pitch = 1) {
    const buf = this.sounds.get(name);
    if (!buf) return;
    const source = this.ctx.createBufferSource();
    const gain = this.ctx.createGain();
    source.buffer = buf;
    source.playbackRate.value = pitch;
    gain.gain.value = volume;
    source.connect(gain).connect(this.masterGain);
    source.start();
  }

  // Randomize pitch for variety
  playSfx(name) {
    this.play(name, 0.8, 0.9 + Math.random() * 0.2);
  }
}

// Usage
const audio = new SoundManager();
await audio.load('hit', '/sounds/hit.wav');
await audio.load('explosion', '/sounds/explosion.wav');
audio.playSfx('hit');

Particle systems

Particles are small, short-lived objects that simulate explosions, sparks, smoke, and trails:

๐Ÿ”ฌ Demo: Canvas 2D particle system
class Particle {
  constructor(x, y, color) {
    this.x = x; this.y = y;
    const angle = Math.random() * Math.PI * 2;
    const speed = 50 + Math.random() * 200;
    this.vx = Math.cos(angle) * speed;
    this.vy = Math.sin(angle) * speed;
    this.life = 0.5 + Math.random() * 0.5;
    this.maxLife = this.life;
    this.size = 2 + Math.random() * 4;
    this.color = color;
  }

  update(dt) {
    this.x += this.vx * dt;
    this.y += this.vy * dt;
    this.vy += 300 * dt; // gravity
    this.life -= dt;
  }

  draw(ctx) {
    const alpha = this.life / this.maxLife;
    ctx.globalAlpha = alpha;
    ctx.fillStyle = this.color;
    ctx.fillRect(this.x - this.size/2, this.y - this.size/2, this.size, this.size);
    ctx.globalAlpha = 1;
  }

  get dead() { return this.life <= 0; }
}

class ParticleSystem {
  constructor() { this.particles = []; }

  emit(x, y, count, color = '#e94560') {
    for (let i = 0; i < count; i++)
      this.particles.push(new Particle(x, y, color));
  }

  update(dt) {
    this.particles.forEach(p => p.update(dt));
    this.particles = this.particles.filter(p => !p.dead);
  }

  draw(ctx) { this.particles.forEach(p => p.draw(ctx)); }
}

// Usage: particles.emit(enemy.x, enemy.y, 30, '#ff6600');

Screen shake and juice

Screen shake communicates impact. Apply a decaying random offset to the camera:

๐Ÿ”ฌ Demo: Screen shake system
const shake = { intensity: 0, decay: 5, offsetX: 0, offsetY: 0 };

function triggerShake(intensity) {
  shake.intensity = intensity;
}

function updateShake(dt) {
  if (shake.intensity > 0.1) {
    shake.offsetX = (Math.random() - 0.5) * shake.intensity;
    shake.offsetY = (Math.random() - 0.5) * shake.intensity;
    shake.intensity *= Math.pow(0.1, dt); // exponential decay
  } else {
    shake.offsetX = 0;
    shake.offsetY = 0;
    shake.intensity = 0;
  }
}

// In render:
ctx.save();
ctx.translate(shake.offsetX, shake.offsetY);
renderGame();
ctx.restore();

// On hit: triggerShake(15);

When evaluating game audio, start with the fundamentals: what problem it solves, who it serves, and how it compares to the alternatives buyers consider first.

Start with the fundamentals. Define who you are serving, the single outcome you want, and the budget you are comfortable committing before you compare any options.

A practical rule is to favour clarity over cleverness. The choice that is easiest to understand, spell, remember and act on tends to win over the long run.

Context changes the answer. What is optimal for a fast-moving startup is rarely optimal for an established brand, so weigh your own stage, market and ambitions.

Avoid the common mistakes: rushing the decision, copying competitors blindly, and ignoring the total cost of ownership beyond the very first year of use.

Think in terms of trade-offs rather than a single perfect answer. Every option trades memorability, cost, reach and flexibility in a slightly different mix.

Document your reasoning. Writing down why you chose one path makes it far easier to revisit the decision later and to explain it to partners and investors.

Test with real people. A quick check with a handful of your actual customers will surface problems that no amount of internal debate ever reveals.

Plan for growth. The option that fits today should still make sense when your audience, catalogue or team is several times larger than it is right now.

Finally, revisit the decision periodically. Markets, tools and best practices move quickly, and a choice that was ideal last year may deserve a fresh look today.

When evaluating game audio, start with the fundamentals: what problem it solves, who it serves, and how it compares to the alternatives buyers consider first.

Start with the fundamentals. Define who you are serving, the single outcome you want, and the budget you are comfortable committing before you compare any options.

A practical rule is to favour clarity over cleverness. The choice that is easiest to understand, spell, remember and act on tends to win over the long run.

Context changes the answer. What is optimal for a fast-moving startup is rarely optimal for an established brand, so weigh your own stage, market and ambitions.

Avoid the common mistakes: rushing the decision, copying competitors blindly, and ignoring the total cost of ownership beyond the very first year of use.

Think in terms of trade-offs rather than a single perfect answer. Every option trades memorability, cost, reach and flexibility in a slightly different mix.

Document your reasoning. Writing down why you chose one path makes it far easier to revisit the decision later and to explain it to partners and investors.

Test with real people. A quick check with a handful of your actual customers will surface problems that no amount of internal debate ever reveals.

Explore Crypto Trading

Cryptocurrency trading is one of the fastest-growing financial markets โ€” open 24/7, globally accessible, and full of opportunity for those who learn the fundamentals first.

  • Trade spot, futures & copy-trading on one platform
  • Start with as little as $10 โ€” practice risk-free on the testnet
  • Built-in TradingView charts, grid bots & DCA tools

Free Crypto Trading Academy → ยท Domain Trading Academy →

Frequently asked questions

Why not just use HTML Audio elements?

HTML Audio elements have high latency (50-200ms), cannot play the same sound overlapping, and lack spatial audio. Web Audio API has sub-10ms latency, unlimited concurrent playback, and built-in effects like reverb and panning.

How many particles can I have before performance suffers?

Canvas 2D handles 5000-10000 simple particles at 60 FPS. For more, use WebGL instanced rendering or a GPU particle system. Most game effects need 20-200 particles, well within budget.

Free Courses โ€” Learn New Skills

No sign-up · No fees · Learn at your own pace

Start Trading

Trade crypto and premium domains โ€” digital assets with real opportunities.

Find your name on Atom

DominantBrand curates the best premium, brandable names from Atom.com — the marketplace with a free AI appraisal, a USPTO trademark check, and secure escrow. Every listing even ships with a designed logo.

Browse Domains