2026-06-11

효과음 파일 0개 — Web Audio로 소리 합성하기

리빌드 내내 외부 에셋을 0으로 유지했으니, 효과음도 예외일 수 없었다.
오디오 파일은 한 개도 없다.
모든 소리는 Web Audio API로 그 자리에서 합성한다.

기본 도구는 단 둘이다.
오실레이터(파형을 내는 발진기)와 게인(음량).
여기에 시작 주파수, 길이, 파형 종류, 그리고 끝으로 갈수록 음량을 0에 수렴시키는 엔벨로프를 얹으면 짧은 효과음 하나가 된다.
이 한 함수를 돌려쓴다.

function blip(freq, dur, type, gain = 0.15, slide = 0) {
  const o = c.createOscillator();
  const g = c.createGain();
  o.type = type;
  o.frequency.setValueAtTime(freq, c.currentTime);
  g.gain.setValueAtTime(gain, c.currentTime);
  g.gain.exponentialRampToValueAtTime(0.0001, c.currentTime + dur);
  o.connect(g).connect(c.destination);
  o.start(); o.stop(c.currentTime + dur);
}

점프는 낮은 사인파, 피격은 거친 톱니파로 음색을 갈랐다.
제일 마음에 드는 디테일은 수집음이다.
콤보가 쌓일수록 음 높이가 올라간다.

export const playCollect = (combo: number) =>
  blip(520 + Math.min(combo, 24) * 40, 0.18, "triangle", 0.18, 120);

520 + min(combo,24)*40Hz.
한 개 주울 땐 520Hz, 콤보가 붙을수록 한 칸씩 높아져 상한에서 멈춘다.
연속으로 줍다 보면 음이 또르르 올라가는데, 이 상승감이 콤보 자체보다 더 짜릿했다.
같은 사운드를 반복 재생했다면 절대 안 나왔을 쾌감이다.

브라우저 환경 체크도 챙겼다. windowAudioContext가 없으면 모든 함수가 조용히 no-op으로 빠진다.
SSR이나 미지원 환경에서 터지지 않게 하기 위해서다.

여기까지가 리빌드 개발기다.
결론은 단순하다 — 외부 에셋 없이도, 코드만으로 충분히 귀엽고 손맛 나는 게임을 만들 수 있었다.

직접 플레이해보기 →