マガジン

環境音を一つ足すだけで場面は変わるか:風・水・虫

遊びをつくる

執筆にClaudeを使用しています。

雨の窓辺にあるアップライトピアノと小さなリズムマシン。
記事のテーマをもとに制作したAI生成イメージ。実際のゲーム画面ではありません。

同じ草原の静止画を前に、無音、風の音、水の音、虫の音の4通りで眺める場面を考えてみます。絵は1枚も変わっていません。それでも「ここは広い」「ここは湿っている」「ここは夜だ」といった印象が、音によって動くのかどうか。この記事は、その問いを自分の手で確かめるための実験設計書です。 ゲームを作る人にとって、環境音は後回しにされがちな要素です。絵や操作が固まってから「雰囲気づけに何か足そう」となり、足した結果が本当に印象を変えたのかは確かめられないままになります。ここでは、ブラウザだけで動く小さな音源を用意し、数人に同じ画面を見て聞いてもらって印象を記録します。結果は書きません。実際にやれば、自分の画面と自分の聞き手での答えが出る形にしてあります。

この記事の目次
  1. この実験で確かめる問い
  2. 準備するもの
  3. 手順と記録の取り方
  4. 結果の読み方
  5. 起こりやすい誤り
  6. 次の行動
  7. 参考資料

この実験で確かめる問い

主な問いは「画面を変えずに環境音を一つ足すと、見た人が答える場所の印象は変わるか」です。副次的な問いを二つ置きます。

  • 変わるとして、風・水・虫のどれが、どの印象の軸(広さ、涼しさ、安心感、時間帯など)を動かすか。
  • 評価者が違っても、同じ方向に動くか。それとも音の受け取り方が割れるか。

ここで言う「印象」は、本人に言葉で答えてもらったものだけを指します。音が「効いたはず」という作り手の感覚は、記録に入れません。作り手は自分の音を知っているので、どうしても期待が混ざるためです。

準備するもの

必要なのは次の4つです。

  1. 固定する画面:自分のゲームのスクリーンショットか、静止画1枚。下のコードのキャンバスは背景色だけなので、そのままでは印象の手がかりが薄すぎます。画像を差し替えるか、画面の隣に置いてください。
  2. 音源:下のHTMLを1ファイルに保存してブラウザで開きます。外部ライブラリは不要です。ノイズや発振器から風・水・虫に聞こえる音を合成しています。
  3. 評価者:自分以外で3人以上。多いほど傾向が読みやすくなります。
  4. 記録用紙:後述の表を紙か表計算で用意します。
html
<!doctype html>
<meta charset="utf-8">
<canvas id="c" width="480" height="270" style="background:#567"></canvas>
<p><button data-m="none">無音</button> <button data-m="wind">風</button>
<button data-m="water">水</button> <button data-m="bug">虫</button></p>
<script>
const ctx = new AudioContext();
const master = ctx.createGain(); master.gain.value = 0.15; master.connect(ctx.destination);
let stop = () => {};
function noise() {
  const b = ctx.createBuffer(1, ctx.sampleRate * 2, ctx.sampleRate), d = b.getChannelData(0);
  for (let i = 0; i < d.length; i++) d[i] = Math.random() * 2 - 1;
  const s = ctx.createBufferSource(); s.buffer = b; s.loop = true; s.start(); return s;
}
function wind() {
  const n = noise(), f = ctx.createBiquadFilter(), g = ctx.createGain();
  const l = ctx.createOscillator(), lg = ctx.createGain();
  f.type = "lowpass"; f.frequency.value = 600; g.gain.value = 0.5;
  l.frequency.value = 0.2; lg.gain.value = 0.3; l.connect(lg); lg.connect(g.gain); l.start();
  n.connect(f); f.connect(g); g.connect(master);
  return () => { n.stop(); l.stop(); g.disconnect(); };
}
function water() {
  const n = noise(), f = ctx.createBiquadFilter(), g = ctx.createGain();
  f.type = "bandpass"; f.frequency.value = 1200; g.gain.value = 0.3;
  n.connect(f); f.connect(g); g.connect(master);
  const t = setInterval(() => {
    if (Math.random() > 0.4) return;
    const o = ctx.createOscillator(), e = ctx.createGain(), t0 = ctx.currentTime, p = 500 + Math.random() * 900;
    o.frequency.setValueAtTime(p, t0); o.frequency.exponentialRampToValueAtTime(p * 2, t0 + 0.08);
    e.gain.setValueAtTime(0.4, t0); e.gain.exponentialRampToValueAtTime(0.001, t0 + 0.1);
    o.connect(e); e.connect(master); o.start(); o.stop(t0 + 0.12);
  }, 250);
  return () => { n.stop(); clearInterval(t); g.disconnect(); };
}
function bug() {
  const o = ctx.createOscillator(), g = ctx.createGain(), l = ctx.createOscillator(), lg = ctx.createGain();
  o.frequency.value = 4200; g.gain.value = 0.1; l.frequency.value = 9; lg.gain.value = 0.1;
  l.connect(lg); lg.connect(g.gain); o.connect(g); g.connect(master); o.start(); l.start();
  return () => { o.stop(); l.stop(); g.disconnect(); };
}
document.querySelectorAll("button").forEach(b => b.onclick = () => {
  ctx.resume(); stop(); stop = ({ wind, water, bug }[b.dataset.m] || (() => () => {}))();
});
</script>

仕組みを短く説明します。風は、ホワイトノイズ(全帯域が均等に混ざった「サー」という音)を低い音だけ通すフィルターに通し、ゆっくりした揺らぎで音量を上下させています。水は、中域だけを通したノイズに、短く上がる高さの音をランダムに重ねて滴に見立てています。虫は、高い一定の音を1秒に9回ほど断続させたものです。いずれも簡易的な合成なので、本物の録音より作り物らしく聞こえます。その点も実験の条件として記録しておいてください。

手順と記録の取り方

事前に揃えること

最も大事なのは音量を揃えることです。音量が違うと、「音の種類」の効果と「音の大きさ」の効果が区別できなくなります。

  • 再生機器と本体の音量つまみは、全員・全条件で固定します。
  • 風・水・虫を順に鳴らし、「同じくらいの大きさ」に聞こえるまで、各関数の gain.value を調整します。測定器がなければ、耳で交互に聞き比べるのが現実的です。
  • 虫の高音は、小さめでも刺さって聞こえます。不快に感じる人が出ない範囲まで下げてください。

1人あたりの流れ

  1. 評価者に画像だけを見せ、音の種類は伝えません。「これから音が鳴ります。画面を見て、印象を答えてください」とだけ言います。
  2. 条件は4つ(無音、風、水、虫)に、無音をもう一度加えた計5回です。順番は人ごとに変えます。くじで決めるか、評価者ごとに一つずつずらすなど、先頭の条件が偏らないようにします。
  3. 各条件で30秒、画面を見ながら音を聞いてもらいます。
  4. 30秒後、画面を見たまま、次の順で答えてもらいます。まず自由記述の一言、次に尺度、最後に行動です。自由記述を先にするのは、尺度の言葉に引っ張られないようにするためです。

記録用紙

  • 一言、記入方法:この場所を一言で。自由記述、聞いた言葉のまま書き取る
  • 尺度、記入方法:広い―狭い、涼しい―暑い、安心―不安、静か―にぎやか を各1〜7で
  • 時間帯、記入方法:朝・昼・夕・夜のどれに感じるか
  • 行動、記入方法:その場所に立ったら最初に何をしたいか

単位は「評価者×条件」で1行です。3人なら15行、5人なら25行になります。評価者の人数と条件の実施順も、必ず用紙に残してください。

結果の読み方

集まった行を、次の順で見ていきます。

1. 無音の2回を比べる。 同じ評価者の無音1回目と2回目で、尺度が何点ずれたかを見ます。このずれが、この実験の「測定のゆらぎ」の目安になります。音あり条件と無音の差がこのずれと同程度なら、差とは見なさないほうが安全です。

2. 軸ごとに、無音からの差を見る。 風・水・虫それぞれについて、4つの尺度で無音より上がったか下がったかを人ごとに書き出します。評価者の多くが同じ方向に動いた軸があれば、その音はその軸に効いている可能性があります。

3. 自由記述の語を見る。 尺度が動いていなくても、「海」「川べり」「夏」など場所や季節を指す語が音の条件で増えていないかを確認します。

4. 判断の目安を決めておく。 たとえば次のように、事前に決めておくと読みやすくなります。

  • 尺度が同方向に動き、自由記述にも語の変化がある:その音は印象づくりに使える。
  • 尺度は動くが自由記述が変わらない:効果は弱めで、他の要素と組み合わせる前提で考える。
  • 評価者によって方向が割れる:音の受け取り方が人で違う。作品の想定プレイヤーに近い人で再度確かめる。
  • どの軸もゆらぎの範囲内:この音源、この音量、この画面の組み合わせでは差が出ていない。

人数が少ないため、ここで得られるのは「自分の画面と自分の聞き手での傾向」です。一般的な結論としては扱わないでください。

起こりやすい誤り

  • 音量の不一致:最も多い原因です。音の種類の差を見ているつもりで、大きさの差を見てしまいます。
  • 再生環境の違い:ヘッドホンとスマホの小さなスピーカーでは、低い風の音がほとんど聞こえません。環境を揃えるか、環境ごとに別の実験として扱います。
  • 自動再生の制限:ブラウザは、ユーザーの操作なしには音を鳴らさないことがあります。コードではボタンを押した時点で resume() を呼ぶ形にしています。自作ゲームに組み込むときも、最初のタップやクリック後に音を始める設計にします。
  • 先に説明してしまう:「これは風の音です」と伝えると、聞こえ方ではなく言葉への反応を測ることになります。
  • 作者自身が評価者になる:音の中身を知っているため、期待が印象に混ざります。作者は進行役に回り、記録だけを取ってください。
  • 画面を条件ごとに変える:一部でも絵が変わると、音の効果と分けられません。
  • 最初の条件が基準になる:順番を固定すると、1回目の印象が後の回答を引っ張ります。順番を回してください。

次の行動

まず上のHTMLを保存し、自分のゲーム画面の静止画を横に置いて、音量を揃えるところまで進めてみてください。そのうえで、身近な3人に5条件を聞き、記録用紙の行を埋めます。

音の素材を自作せずに感触だけ見たい場合は、公式作品「雨音のピアノ」の、雨音つきの自由演奏と雨音なしを聞き比べる方法もあります。雨音の聞こえ方や調整できる範囲は、作品を開いて確かめてください。

実験の結果から使う音が決まったら、アソバースへ投稿する作品に組み込めます。合成音ならファイル容量が小さく、音声ファイルを同梱する場合は、ZIP直下の index.html から相対パスで読み込む形にします。

参考資料

  • MDN Web Docs「Web Audio API」(AudioContext、BiquadFilterNode、GainNode、OscillatorNode の各解説)