ガイドメニュー

サウンド:アルゴリズムと実装

「Concentration - 究極の音の記憶ゲーム」では、Web Audio APIを活用して、emojiごとのユニークなサウンドやゲームイベント(コンボ、シャッフル、クリアなど)の効果音を動的に生成します。サウンドは、プレイヤーの記憶を助け、ゲームの没入感を高める重要な要素です。このページでは、サウンド生成のアルゴリズム、ソースコード、仕組み、他の機能との干渉回避策を詳しく解説します。さらに、各波形(サイン波、三角波、ノコギリ波、矩形波)の特徴を、再生ボタンを通じて実際に聴きながら学べます。音を体感しながら、Web Audio APIの仕組みを理解しましょう。

アルゴリズム

目的:各emojiやゲームイベントに特有のサウンドを生成し、聴覚を通じてプレイヤーの体験を強化する。他の機能(カードめくり、シャッフル、コンボ)とスムーズに連携し、音の重複や競合を防ぐ。

手順

  1. サウンド定義:`soundMap`オブジェクトで、emojiごとに波形(例:サイン波)、周波数(例:600Hz)、再生時間(例:0.3秒)を定義。
  2. サウンド生成:`playWave`関数で、Web Audio APIの`AudioContext`を使用してオシレータを生成。指定の波形、周波数、音量、時間を設定し、即時再生。
  3. イベントトリガー:カードめくり(`flipCard`)、コンボ(`playComboSound`)、シャッフル(`playShuffleSound`)、クリア(`playVictorySound`)で適切なサウンドを再生。
  4. 音の多様性:21ペアのemojiに異なる音(サイン9、ノコギリ4、矩形4、三角4)を割り当て、記憶を補助。コンボ音は周波数を動的に増加(1000~2050Hz)。
  5. 競合防止:短い再生時間(0.3~0.5秒)で音の重複を軽減、独立した`AudioContext`でメモリ管理を最適化。

ソースコード

以下は、サウンド生成の主要コード(`common.js`)です。完全版は`common.js`を参照してください。コードは`white-space: pre-wrap`で整形済み、改行やインデントがブラウザで正確に表示されます。

function playWave(type, frequency, duration, volume = 0.2) { const ctx = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = ctx.createOscillator(); const gainNode = ctx.createGain(); oscillator.type = type; oscillator.frequency.setValueAtTime(frequency, ctx.currentTime); gainNode.gain.setValueAtTime(volume, ctx.currentTime); oscillator.connect(gainNode); gainNode.connect(ctx.destination); oscillator.start(); oscillator.stop(ctx.currentTime + duration); }

emojiごとのサウンドマッピング(`game.js`):21ペアにユニークな音を割り当て。

const soundMap = { "🔥": { type: "sine", frequency: 600, duration: 0.3 }, // 鋭いサイン波 "⭐": { type: "sine", frequency: 800, duration: 0.3 }, // 高めのサイン波 "⚡": { type: "sawtooth", frequency: 500, duration: 0.3 }, // 鋭いノコギリ波 "💧": { type: "sine", frequency: 400, duration: 0.4 }, // 柔らかいサイン波 // 他のemoji(略) "🌊": { type: "triangle", frequency: 450, duration: 0.4 } // 流れる三角波 };

コンボサウンド(`common.js`):コンボ数に応じて音程を増加。

function playComboSound(combo) { const frequency = 1000 + (combo - 1) * 50; // 1000Hz~2050Hz playWave("square", frequency, 0.2, 0.2); }

サウンドを体感する

波形ごとの音の特徴を理解するため、以下のボタンをクリックしてサウンドを聴いてみましょう。各波形は、音色の違いやゲーム内での役割を体感できます。

  • サイン波:滑らかで柔らかい音、🔥や💧に使用。記憶を優しく補助。
  • 三角波:柔らかだが角のある音、🌈や🌊に使用。温かみのある記憶補助。
  • ノコギリ波:鋭く力強い音、⚡や🌪️に使用。強い印象で記憶を強化。
  • 矩形波:パンチのあるデジタル音、🍊やコンボに使用。リズミカルで注目を集める。

解説

  • サイン波:純粋な単一周波数で、滑らかでクリアな音色。ゲームでは🔥(600Hz)や🌸(900Hz)に使用し、柔らかい印象を与えます。
  • 三角波:サイン波より角があり、温かみのある音色。🌈(700Hz)や☀️(800Hz)に使用、親しみやすい記憶補助に適します。
  • ノコギリ波:倍音が多く、鋭く力強い音色。⚡(500Hz)や🌟(600Hz)に使用、強い印象で記憶を刻みます。
  • 矩形波:デジタルでパンチのある音色。🍒(650Hz)やコンボ(1000~2050Hz)に使用、リズミカルで注目を引きつけます。

ボタンを押して音を聴き、波形の違いやゲーム内での効果を体感してください。これにより、音色の選択がプレイヤーの記憶にどう影響するかを理解できます。

機能の仕組み

データ構造

  • `soundMap`:emojiをキーとし、波形(`type`)、周波数(`frequency`)、再生時間(`duration`)をオブジェクトで管理。例:`{ "🔥": { type: "sine", frequency: 600, duration: 0.3 } }`。
  • `comboCount`:コンボサウンドの周波数を動的に計算(`1000 + (combo-1)*50`)。

制御フロー

  • 初期化:ゲーム開始時に`soundMap`を定義、21ペアの音を準備。
  • トリガー:`flipCard`でemojiの音、`playComboSound`でコンボ音、`playShuffleSound`でシャッフル音を再生。
  • 再生:`playWave`で`AudioContext`を生成、オシレータを設定、即再生・停止。
  • 終了:再生時間後にオシレータを停止、メモリを解放。

干渉回避の工夫

他の機能との競合を防ぐための対策を以下に示します:

  • カードめくりとの連携:サウンドは即時再生(0.3~0.4秒)、めくりアニメーション(0.5秒)と並行して問題なし。短い再生時間で重複を軽減。
  • シャッフルとの連携:シャッフル音(600Hz三角波、0.5秒)は交換アニメーションと同期、`isGameActive`でめくりをブロックし、タイミング競合を防止。
  • コンボとの連携:コンボ音(矩形波、0.2秒)は短く、連続正解でも混雑しない。周波数増加で音色の変化を明確化。
  • メモリ管理:各サウンドは独立した`AudioContext`インスタンスを使用、再生後に即破棄。長時間のサウンドは避け、メモリリークを防止。

学習ポイント

  • Web Audio APIの基礎:`AudioContext`、オシレータ、ゲインノードを使ったサウンド生成を理解。
  • 波形の特性:サイン、三角、ノコギリ、矩形波の音色を体感し、用途に応じた選択を学ぶ。
  • 動的サウンド:コンボ数に応じた周波数変化など、状況に応じたサウンド生成を習得。
  • パフォーマンス:短い再生時間や独立インスタンスで、音の重複やリソース消費を最小化する方法を学ぶ。