← Back to Blog Apr 23, 2026 · 01:00 PM · 7 min read

Pac-Man Sound Effects: Add Waka-Waka and Ghost Eaten Sounds

This is the final part of our Pac-Man series. In Part 5 we added level progression. Now we bring the game to life with sound effects. We will use the Web Audio API to generate sounds programmatically — no audio files needed.

Why Web Audio API?

Step 1: Set Up the Audio Context

The Web Audio API needs an AudioContext. We create it on the first user interaction (click or keypress) to comply with browser autoplay policies.

let audioCtx = null;

function initAudio() {
  if (!audioCtx) {
    audioCtx = new (window.AudioContext
      || window.webkitAudioContext)();
  }
}

// Call initAudio() on first keydown or click
document.addEventListener('keydown', initAudio,
  { once: true });
document.addEventListener('click', initAudio,
  { once: true });
Tip: Browsers block audio until the user interacts with the page. Always create your AudioContext inside a user event handler to avoid the "autoplay policy" error.

Step 2: Waka-Waka (Chomp Sound)

The iconic Pac-Man chomp is a short oscillating tone. We alternate between two pitches to create the "waka-waka" effect.

let wakaToggle = false;

function playWaka() {
  if (!audioCtx) return;
  const osc = audioCtx.createOscillator();
  const gain = audioCtx.createGain();

  osc.connect(gain);
  gain.connect(audioCtx.destination);

  // Alternate between two frequencies
  osc.frequency.value = wakaToggle ? 260 : 330;
  osc.type = 'square';
  wakaToggle = !wakaToggle;

  gain.gain.setValueAtTime(0.15, audioCtx.currentTime);
  gain.gain.exponentialRampToValueAtTime(
    0.001, audioCtx.currentTime + 0.08);

  osc.start(audioCtx.currentTime);
  osc.stop(audioCtx.currentTime + 0.08);
}

// Call playWaka() in movePacman() when eating a dot

Step 3: Ghost Eaten Sound

When Pac-Man eats a frightened ghost, play a rising sweep tone. This feels rewarding and distinct from the chomp.

function playGhostEaten() {
  if (!audioCtx) return;
  const osc = audioCtx.createOscillator();
  const gain = audioCtx.createGain();

  osc.connect(gain);
  gain.connect(audioCtx.destination);

  osc.type = 'sawtooth';
  osc.frequency.setValueAtTime(200,
    audioCtx.currentTime);
  osc.frequency.exponentialRampToValueAtTime(
    800, audioCtx.currentTime + 0.3);

  gain.gain.setValueAtTime(0.2, audioCtx.currentTime);
  gain.gain.exponentialRampToValueAtTime(
    0.001, audioCtx.currentTime + 0.3);

  osc.start(audioCtx.currentTime);
  osc.stop(audioCtx.currentTime + 0.3);
}

Step 4: Power Pellet Siren

During frightened mode, play a looping low-frequency siren. This creates tension and tells the player power mode is active.

let sirenOsc = null;
let sirenGain = null;

function startSiren() {
  if (!audioCtx || sirenOsc) return;

  sirenOsc = audioCtx.createOscillator();
  sirenGain = audioCtx.createGain();

  sirenOsc.connect(sirenGain);
  sirenGain.connect(audioCtx.destination);

  sirenOsc.type = 'sine';
  sirenOsc.frequency.value = 120;
  sirenGain.gain.value = 0.08;

  // Wobble the frequency for siren effect
  const lfo = audioCtx.createOscillator();
  const lfoGain = audioCtx.createGain();
  lfo.frequency.value = 4; // 4 Hz wobble
  lfoGain.gain.value = 30; // pitch range
  lfo.connect(lfoGain);
  lfoGain.connect(sirenOsc.frequency);
  lfo.start();

  sirenOsc.start();
}

function stopSiren() {
  if (sirenOsc) {
    sirenOsc.stop();
    sirenOsc = null;
    sirenGain = null;
  }
}

// startSiren() when power mode activates
// stopSiren() when power mode ends

Step 5: Death Sound

When Pac-Man gets caught, play a descending tone that feels like deflation — a classic game over sound.

function playDeath() {
  if (!audioCtx) return;
  const osc = audioCtx.createOscillator();
  const gain = audioCtx.createGain();

  osc.connect(gain);
  gain.connect(audioCtx.destination);

  osc.type = 'sine';
  osc.frequency.setValueAtTime(600,
    audioCtx.currentTime);
  osc.frequency.exponentialRampToValueAtTime(
    80, audioCtx.currentTime + 0.8);

  gain.gain.setValueAtTime(0.25,
    audioCtx.currentTime);
  gain.gain.exponentialRampToValueAtTime(
    0.001, audioCtx.currentTime + 0.8);

  osc.start(audioCtx.currentTime);
  osc.stop(audioCtx.currentTime + 0.8);
}

Step 6: Level Start Jingle

Play a short ascending melody when a new level starts. Three quick notes that build excitement.

function playLevelStart() {
  if (!audioCtx) return;
  const notes = [330, 440, 550];
  const dur = 0.12;

  notes.forEach((freq, i) => {
    const osc = audioCtx.createOscillator();
    const gain = audioCtx.createGain();
    osc.connect(gain);
    gain.connect(audioCtx.destination);

    osc.type = 'square';
    osc.frequency.value = freq;

    const t = audioCtx.currentTime + i * dur;
    gain.gain.setValueAtTime(0.15, t);
    gain.gain.exponentialRampToValueAtTime(
      0.001, t + dur);

    osc.start(t);
    osc.stop(t + dur);
  });
}
Tip: Keep sound effects short (under 300ms for actions, under 1s for events). Long sounds overlap and create audio mud. The Web Audio API handles timing precisely, so short sounds feel crisp.

Step 7: Wire Everything Together

Add sound calls to the appropriate places in your game code.

// In movePacman():
if (tile === 2) {
  score += SCORE_DOT;
  dotsLeft--;
  map[ny][nx] = 0;
  playWaka();  // chomp sound
}
if (tile === 3) {
  score += SCORE_PELLET;
  dotsLeft--;
  map[ny][nx] = 0;
  activatePowerMode();
  startSiren();  // power mode siren
}

// In checkGhostCollision():
if (frightened) {
  // ... eat ghost logic
  playGhostEaten();  // rising sweep
} else {
  playDeath();  // descending tone
  onPacmanCaught();
}

// In updateFrightened():
if (elapsed > FRIGHTENED_DURATION) {
  frightened = false;
  stopSiren();  // stop power siren
}

// In showLevelTransition():
playLevelStart();  // ascending jingle

Series Complete!

Congratulations — you have built a complete Pac-Man game from scratch! Over 6 parts we covered:

From here, you can keep adding features: mobile swipe controls, a start screen, animations, or even multiplayer. The foundation is solid — have fun building on it.

More Articles

📈
Tutorial Pac-Man Levels: Speed Up Ghosts Each Level Tutorial · Apr 23, 2026 · 12:00 PM
💊
Tutorial Pac-Man Power Pellet Mode: Ghosts Turn Blue Tutorial · Apr 23, 2026 · 11:00 AM
👻
Tutorial Pac-Man Ghost Chase AI: Make Ghosts Hunt the Player Tutorial · Apr 23, 2026 · 10:00 AM
← Back to Blog