「Concentration - 究極の音の記憶ゲーム」では、Web Audio APIを活用して、emojiごとのユニークなサウンドやゲームイベント(コンボ、シャッフル、クリアなど)の効果音を動的に生成します。サウンドは、プレイヤーの記憶を助け、ゲームの没入感を高める重要な要素です。このページでは、サウンド生成のアルゴリズム、ソースコード、仕組み、他の機能との干渉回避策を詳しく解説します。さらに、各波形(サイン波、三角波、ノコギリ波、矩形波)の特徴を、再生ボタンを通じて実際に聴きながら学べます。音を体感しながら、Web Audio APIの仕組みを理解しましょう。
アルゴリズム
目的:各emojiやゲームイベントに特有のサウンドを生成し、聴覚を通じてプレイヤーの体験を強化する。他の機能(カードめくり、シャッフル、コンボ)とスムーズに連携し、音の重複や競合を防ぐ。
手順:
- サウンド定義:`soundMap`オブジェクトで、emojiごとに波形(例:サイン波)、周波数(例:600Hz)、再生時間(例:0.3秒)を定義。
- サウンド生成:`playWave`関数で、Web Audio APIの`AudioContext`を使用してオシレータを生成。指定の波形、周波数、音量、時間を設定し、即時再生。
- イベントトリガー:カードめくり(`flipCard`)、コンボ(`playComboSound`)、シャッフル(`playShuffleSound`)、クリア(`playVictorySound`)で適切なサウンドを再生。
- 音の多様性:21ペアのemojiに異なる音(サイン9、ノコギリ4、矩形4、三角4)を割り当て、記憶を補助。コンボ音は周波数を動的に増加(1000~2050Hz)。
- 競合防止:短い再生時間(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`、オシレータ、ゲインノードを使ったサウンド生成を理解。
- 波形の特性:サイン、三角、ノコギリ、矩形波の音色を体感し、用途に応じた選択を学ぶ。
- 動的サウンド:コンボ数に応じた周波数変化など、状況に応じたサウンド生成を習得。
- パフォーマンス:短い再生時間や独立インスタンスで、音の重複やリソース消費を最小化する方法を学ぶ。