ガイドメニュー

Concentration - 開発ガイド

1. はじめに

このガイドは、「Concentration - 究極の音の記憶ゲーム」のアルゴリズムと技術を、プログラミング学習者向けにゼロからぶち抜く教科書だ。HTMLの基礎はスキップし、JavaScriptをガンガン使ったゲームロジック、演出、サウンド、データ管理に深く切り込む。20の個別ファイルで、カードめくり、シャッフルモード、コンボなど各機能を分解、合計数百ページ相当のボリュームで、初心者から中級者までが実践的にマスターできるぜ!さらに、各機能で使われる技術(トランジション、非同期処理、状態管理など)をサンプル付きで詳細解説。準備はいいか?世界一のゲーム開発者への道を突っ走るぜ!

目的

  • 神経衰弱ゲームの複雑なアルゴリズムを完全に理解。
  • アニメーション、サウンド、データ管理の実装を極める。
  • 機能間の干渉を防ぐ設計思想を体得。
  • バグ対策とデバッグでプロのスキルを磨く。

2. ゲーム概要とアルゴリズム

「Concentration」は、カードをめくってemoji(🔥⭐⚡など)を揃える神経衰弱ゲームだ。11サイズ(2×2~7×6)、通常/シャッフルモード、コンボ、音、保存機能を搭載し、目と耳で記憶を試す。ゲームは状態管理とイベント駆動で動き、JavaScriptの非同期処理やデータ構造をフル活用。以下、主要機能をガッツリ解説するぜ!

主要機能

  • カードめくり:2枚めくり、ペア判定、裏/表やマッチ状態を管理。3Dトランジションとemojiごとの音で直感的。
  • シャッフルモード:5n-1回試行(4,9,14…)で2枚告知、5n回(5,10,15…)で交換。表でも交換し、紫枠点滅+スライド+音で記憶を揺さぶる。
  • コンボ:連続正解で増加、2コンボ以上で「N COMBO!」表示+サウンド。「次正解で●コンボ!」でプレイヤーを煽る。
  • スコア:公式`(ペア数*10000) - (試行*100) - (時間*50) + (コンボ*1000)`で計算、サイズ・モードごとに保存。
  • サウンド:Web Audio APIでemojiごとの音(サイン波、ノコギリ波など)、コンボやクリア音を動的生成。
  • 保存:ローカルストレージでスコアをJSON管理、サイズ・モード別に独立。
  • 演出:カウントダウン、START!、MATCHED!、CLEARED!、勝利サウンドで盛り上げる。

アルゴリズムの基本

ゲームは以下の要素で成り立つ:

  • 状態管理:`cards`(全カード)、`flippedCards`(めくられたカード)、`comboCount`(コンボ数)、`shufflePair`(シャッフル対象)などの配列や変数で状態を追跡。
  • イベント駆動:クリック(めくり)、タイマー(スコア、カウントダウン)、試行数(シャッフル)でロジックをトリガー。
  • 非同期処理:`async/await`でアニメーション(めくり、シャッフルスライド)やサウンドのタイミングを制御。
  • 競合防止:`isGameActive`フラグでシャッフル中やクリア時の操作を無効化、機能間の干渉を排除。

各機能の詳細は、20のサブページ(`guide_*.html`)でアルゴリズム、コード、干渉回避をガッツリ掘り下げるぜ!

3. 機能別ガイド

各機能のアルゴリズム、ソースコード、干渉回避策を以下の個別ページで徹底解説。コードは`white-space: pre-wrap`で整形済み、改行・インデントがブラウザでバッチリ保持され、初心者でも読みやすい。各ページでは、機能の目的、手順、データ構造、制御フロー、競合防止策を詳細に説明し、学習者が実装を再現できるように設計だ。

これらのページで、ゲームの全機能を分解し、コードの意図や設計思想をガッツリ学べるぜ!

4. 技術詳細:主要機能の解説

ここでは、ゲームで使われる主要技術(トランジション、非同期処理、状態管理、イベント駆動、DOM操作、Web Audio API)を、メイン説明後にサンプルコード付きで詳細解説する。各技術がどう機能に組み込まれ、なぜ必要か、どう干渉を防ぐかをガッチリ説明だ!

4.1 CSSトランジション

概要:CSSトランジションは、カードめくりやオーバーレイ(MATCHED!など)の滑らかなアニメーションに使用。`transition`プロパティでプロパティ変化(例:`transform`)を時間指定で補間する。

ゲームでの使用

  • カードめくり:`transform: rotateY(180deg)`で3D回転、0.5秒で滑らかに。
  • オーバーレイ:`comboPulse`アニメーションで「N COMBO!」を脈動。
  • シャッフル:仮要素の`top`、`left`変化でスライド(JavaScript制御)。

サンプルコード:カードめくりのトランジション(`common.css`)。

.card-inner { width: 100%; height: 100%; transition: transform 0.5s; transform-style: preserve-3d; position: absolute; } .card.flipped .card-inner { transform: rotateY(180deg); }

仕組み:`transition: transform 0.5s`で`transform`変化を0.5秒で補間。`transform-style: preserve-3d`で3D空間を保持、`backface-visibility: hidden`で裏面を非表示。JavaScriptで`flipped`クラスをトグルし、アニメーションをトリガー。

干渉回避

  • `isGameActive`でシャッフル中やクリア時にクリックを無効、不要なトランジションを防止。
  • オーバーレイは独立した`div`(`matchOverlay`など)で、カードのアニメーションと層を分離。
  • 短いアニメーション時間(0.5~1秒)で、連続操作時の遅延を軽減。

4.2 非同期処理(async/await)

概要:`async/await`は、タイミング依存の処理(アニメーション、シャッフル、サウンド)を順序通りに制御。Promiseを使って非同期タスクを同期的に書ける。

ゲームでの使用

  • シャッフル:`executeShuffle`でスライドアニメーション(0.5秒)を待機後、DOM操作。
  • カードめくり:`checkMatch`でハズレ時の1秒待機(`setTimeout`)をPromise化。
  • カウントダウン:1秒ごとの数字更新を順序制御。

サンプルコード:シャッフルのスライド(`game.js`)。

async function executeShuffle() { isGameActive = false; shuffleOverlay.style.display = "block"; playShuffleSound(); setTimeout(() => shuffleOverlay.style.display = "none", 1000); if (shufflePair.length === 2) { const [card1, card2] = shufflePair; if (!card1.classList.contains("matched") && !card2.classList.contains("matched")) { const card1Rect = card1.getBoundingClientRect(); const tempCard1 = card1.cloneNode(true); tempCard1.style.position = "absolute"; tempCard1.style.top = `${card1Rect.top}px`; tempCard1.style.left = `${card1Rect.left}px`; tempCard1.style.transition = "all 0.5s ease"; document.body.appendChild(tempCard1); await new Promise(resolve => setTimeout(() => { tempCard1.style.top = `${card2Rect.top}px`; tempCard1.style.left = `${card2Rect.left}px`; setTimeout(resolve, 500); }, 100)); // カード交換処理(略) tempCard1.remove(); } } shufflePair = []; isGameActive = true; }

仕組み:`await new Promise`でスライド(0.5秒)を待機、DOM操作を確実な順序で実行。`isGameActive`をトグルし、他の非同期処理(めくりなど)をブロック。

干渉回避

  • `isGameActive`でシャッフル中のめくりを無効、同時実行を防止。
  • 短い待機時間(0.5~1秒)で、連続シャッフルの遅延を回避。
  • Promiseチェーンをシンプルに保ち、複雑な依存関係を排除。

4.3 状態管理

概要:状態管理は、ゲームの進行状況(カード状態、試行数、コンボなど)を追跡。グローバル変数や配列でデータを保持、更新。

ゲームでの使用

  • カード状態:`cards`(全カード)、`flippedCards`(めくられたカード)、`matchedPairs`(ペア数)。
  • シャッフル:`shufflePair`で告知済みカードを管理。
  • ゲーム進行:`attempts`(試行数)、`comboCount`(コンボ)、`isGameActive`(操作可否)。

サンプルコード:カード状態の初期化(`game.js`)。

function createBoard() { gameBoard.innerHTML = ""; cards = []; flippedCards = []; matchedPairs = 0; attempts = 0; comboCount = 0; shufflePair = []; isGameActive = true; // カード生成処理(略) }

仕組み:`createBoard`で状態をリセット、`cards`にDOM要素を格納、`flippedCards`でめくり状態を追跡。`isGameActive`で全体の制御を一元化。

干渉回避

  • 状態はグローバル変数で一元管理、関数間で共有し不整合を防止。
  • `flippedCards`は最大2要素、溢れを防ぐチェックを`flipCard`に実装。
  • `isGameActive`でシャッフルやクリア時の状態変更をブロック。

4.4 イベント駆動

概要:イベント駆動は、ユーザー操作(クリック)やシステムイベント(タイマー)をトリガーにロジックを実行。`addEventListener`でハンドラを登録。

ゲームでの使用

  • クリック:カードめくり(`flipCard`)、開始/リセットボタン。
  • タイマー:スコア更新(`startTimer`)、カウントダウン、シャッフル告知/交換。

サンプルコード:カードクリック(`game.js`)。

shuffledSymbols.forEach((symbol, index) => { const card = document.createElement("div"); card.classList.add("card"); card.dataset.symbol = symbol; // DOM構築(略) card.addEventListener("click", () => flipCard(card)); gameBoard.appendChild(card); cards.push(card); });

仕組み:`addEventListener`で各カードに`flipCard`をバインド、クリックごとに状態を更新。`startTimer`は`setInterval`で毎秒スコアを更新。

干渉回避

  • `isGameActive`で無効なクリックをブロック、シャッフルやクリア時の誤操作を防止。
  • イベントハンドラは単一責任(例:`flipCard`はめくりのみ)、複雑なロジックを分離。
  • タイマーは`clearInterval`で終了時クリア、メモリリークを回避。

4.5 DOM操作

概要:DOM操作は、カード生成、状態変更(`classList`)、シャッフル交換(`insertBefore`)に使用。`document`や要素のメソッドで動的にUIを更新。

ゲームでの使用

  • カード生成:`createBoard`でグリッド構築。
  • 状態変更:`flipped`や`matched`クラスでめくりやペア状態を反映。
  • シャッフル:`insertBefore`でカード位置を交換。

サンプルコード:シャッフル交換(`game.js`)。

const parent = gameBoard; const card1Next = card1.nextSibling; const card2Next = card2.nextSibling; if (card1Index < card2Index) { parent.insertBefore(card2, card1Next); parent.insertBefore(card1, card2Next || null); } else { parent.insertBefore(card1, card2Next); parent.insertBefore(card2, card1Next || null); }

仕組み:`insertBefore`で単一スワップ、インデックス順を考慮して正確な交換。`classList`で状態を動的に更新、UIを即反映。

干渉回避

  • `isGameActive`でシャッフル中のDOM操作を制限、めくりとの競合を防止。
  • 仮要素(スライド用)は`remove`で即削除、DOMの肥大化を回避。
  • インデックスを動的に取得(`Array.from`)、ずれを防止。

4.6 Web Audio API

概要:Web Audio APIは、動的サウンド生成に使用。`AudioContext`でオシレータを制御、波形(サイン、ノコギリなど)や周波数を指定。

ゲームでの使用

  • emojiごとの音:21ペアにユニークな音(例:🔥は600Hzサイン波)。
  • コンボ:1000~2050Hz矩形波で音程増加。
  • シャッフル:600Hz三角波で交換を強調。

サンプルコード:サウンド生成(`common.js`)。

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); }

仕組み:`AudioContext`でオシレータを生成、`type`(波形)、`frequency`(周波数)、`duration`(継続時間)を設定。`gainNode`で音量を制御、即再生・停止。

干渉回避

  • 短い音(0.3~0.5秒)で重複を軽減、同時再生でも聞き分け可能。
  • 各音は独立した`AudioContext`インスタンス、メモリ管理を簡潔に。
  • サウンドはUI操作(めくり、シャッフル)と並行、タイミング競合なし。

5. 学習者へのアドバイス

このゲームは、プログラミングの核心スキルをガッツリ鍛える教材だ。20のサブページ(`guide_*.html`)で、カードめくり、シャッフル、コンボなどのアルゴリズムを分解し、コード、仕組み、干渉回避を学べる。以下、学習を最大化するコツだぜ!

学習のコツ

  • 1機能ずつ実装:カードめくりから始め、動作確認しながら進む。`guide_cardflip.html`のコードを写経して理解。
  • デバッグを活用:Chrome DevToolsで`console.log`やブレークポイントを使い、状態(`flippedCards`など)を追跡。
  • コードを改造:シャッフルの告知タイミングを3試行に変えたり、コンボ音をカスタムして、創造力を試す。
  • サブページを深掘り:各機能の干渉回避策(例:`isGameActive`の使い方)を読み、設計思想を吸収。

次のステップ

  • 新モード:時間制限モードやランダム障害モードを追加。`guide_combo.html`のロジックを応用。
  • マルチプレイヤー:WebSocketでオンライン対戦を実装、状態同期を学ぶ。
  • AI対戦:ミニマックス法で賢い対戦相手を開発、アルゴリズムを強化。
  • カスタマイズ:カードに画像やグラデーションを適用、UIを自分好みに。

技術を極める:このガイドの技術詳細(トランジション、非同期処理など)は、ゲーム開発の基礎を超える応用例だ。サンプルコードを試し、他のプロジェクト(例:アニメーション付きクイズアプリ)に活かせ。コードを書き、壊し、学びながら、君だけのゲームを創り上げろ!世界一の開発者への道は、ここからだぜ!

ゲームに戻る 遊び方に戻る