🧠 記憶力トレーニングゲーム
瞬間記憶力を鍛えよう!数字を見て覚えて入力するだけ
ゲームの流れ
1️⃣ 数字が表示されます
2️⃣ 数字を記憶します
3️⃣ 数字が消えたら入力します
4️⃣ 正解すると難易度アップ!
ゲーム終了!
レベル 1 まで到達しました
記憶力ゲーム構築の完全ガイド
シンプルだけど奥が深い、段階的な実装方法
シンプルなゲームこそ、設計が重要
- コアループ: 「見る→記憶→入力→判定」の4ステップを繰り返す
- 難易度曲線: 3問ごとに桁数+1、5問ごとに表示時間-0.5秒
- ターゲット: スマホでサクッと遊べる1プレイ3-5分
- モチベーション: スコアとレベルで達成感を演出
💡 ポイント: 最初から完璧を目指さない。MVPを作って遊びながら改善していくのが成功の鍵。
シンプルなゲームにはシンプルな技術を
- Vanilla JSで十分: フレームワーク不要。純粋なJavaScriptで軽量に
- Reactを使う場合: useState でゲーム状態を管理するとシンプル
- バックエンド不要: スコアはlocalStorageに保存
- デプロイ: GitHub PagesやNetlifyで無料公開可能
<!DOCTYPE html>
<html>
<head>
<title>記憶力ゲーム</title>
<style>
/* CSSをここに */
</style>
</head>
<body>
<div id="gameContainer">
<div id="stats">
<span>レベル: <span id="level">1</span></span>
<span>スコア: <span id="score">0</span></span>
</div>
<div id="numberDisplay"></div>
<input type="text" id="userInput">
<button onclick="checkAnswer()">回答</button>
</div>
<script>
// JavaScriptをここに
</script>
</body>
</html>
ゲームの心臓部分を作る
// 指定桁数のランダムな数字を生成
function generateNumber(digits) {
let number = '';
for (let i = 0; i < digits; i++) {
number += Math.floor(Math.random() * 10);
}
return number;
}
// 使用例
const randomNum = generateNumber(3); // "745"など
function showNumber() {
const number = generateNumber(currentDigits);
currentNumber = number;
// 数字を表示
document.getElementById('numberDisplay').textContent = number;
document.getElementById('numberDisplay').style.display = 'block';
// 指定時間後に非表示
setTimeout(() => {
document.getElementById('numberDisplay').style.display = 'none';
document.getElementById('userInput').style.display = 'block';
document.getElementById('userInput').focus(); // 入力欄にフォーカス
}, displayTime);
}
function checkAnswer() {
const userInput = document.getElementById('userInput').value;
if (userInput === currentNumber) {
// 正解処理
score += currentLevel * 10;
showFeedback('正解!', true);
levelUp();
} else {
// 不正解処理
showFeedback('不正解...正解は ' + currentNumber, false);
gameOver();
}
}
function showFeedback(message, isCorrect) {
const feedback = document.getElementById('feedback');
feedback.textContent = message;
feedback.className = isCorrect ? 'correct' : 'incorrect';
}
💡 UX改善: 入力欄でEnterキーを押しても回答できるようにすると快適です。
段階的に難しくしてプレイヤーを飽きさせない
function levelUp() {
currentLevel++;
// 3問ごとに桁数を増やす
if (currentLevel % 3 === 0) {
currentDigits++;
}
// 5問ごとに表示時間を短くする(最低1秒まで)
if (currentLevel % 5 === 0 && displayTime > 1000) {
displayTime -= 500; // 0.5秒短縮
}
updateUI();
showNextNumber();
}
function updateUI() {
document.getElementById('level').textContent = currentLevel;
document.getElementById('score').textContent = score;
document.getElementById('digits').textContent = currentDigits;
}
- バランス調整: テストプレイして「ちょうど良い難しさ」を探る
- 難易度パターン例:
- レベル1-3: 3桁、3秒
- レベル4-6: 4桁、3秒
- レベル7-9: 5桁、2.5秒
- レベル10-12: 6桁、2秒
- 上限設定: 桁数は10桁、表示時間は1秒を下限に
💡 バリエーション: 難易度モード(Easy/Normal/Hard)を追加して、プレイヤーが選べるようにするのも◎
ハイスコアを記録してリプレイ性を高める
// ハイスコアを保存
function saveHighScore() {
const highScore = localStorage.getItem('memoryGameHighScore') || 0;
if (score > highScore) {
localStorage.setItem('memoryGameHighScore', score);
showNewRecord(); // 新記録の演出
}
}
// ハイスコアを取得
function getHighScore() {
return localStorage.getItem('memoryGameHighScore') || 0;
}
// ゲーム終了時に呼び出し
function gameOver() {
saveHighScore();
displayResults();
}
// スコア履歴を保存(配列で複数保存)
function saveScoreHistory() {
const history = JSON.parse(
localStorage.getItem('scoreHistory') || '[]'
);
history.push({
score: score,
level: currentLevel,
date: new Date().toISOString()
});
// 最新10件のみ保持
const recentHistory = history.slice(-10);
localStorage.setItem('scoreHistory', JSON.stringify(recentHistory));
}
- 表示する情報: 最高スコア、到達レベル、プレイ日時
- ランキング表示: 過去のスコアをソートして上位5件表示
- リセット機能: 「記録をクリア」ボタンも用意
💡 発展: バックエンドを用意すれば、全ユーザーの世界ランキングも実装可能!
見た目と体験を向上させる
/* CSS */
@keyframes fadeIn {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes fadeOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(1.2);
}
}
.number-display {
animation: fadeIn 0.3s ease-out;
}
.number-display.hiding {
animation: fadeOut 0.3s ease-out;
}
/* JavaScript */
function hideNumber() {
const display = document.getElementById('numberDisplay');
display.classList.add('hiding');
setTimeout(() => {
display.style.display = 'none';
display.classList.remove('hiding');
}, 300);
}
/* CSS */
@keyframes celebrate {
0%, 100% { transform: scale(1); }
25% { transform: scale(1.2) rotate(-5deg); }
75% { transform: scale(1.2) rotate(5deg); }
}
.correct-feedback {
animation: celebrate 0.5s ease-in-out;
color: #10b981;
font-size: 48px;
font-weight: bold;
}
/* JavaScript */
function showCorrectAnimation() {
const feedback = document.getElementById('feedback');
feedback.textContent = '🎉 正解!';
feedback.className = 'correct-feedback';
// パーティクルエフェクト(オプション)
createConfetti();
}
- カウントダウン: 数字表示前に「3...2...1...」のカウント
- 入力フィードバック: 正解時は緑、不正解時は赤に光る
- レベルアップ演出: 「Level Up!」の大きな表示とサウンド
- プログレスバー: 表示時間の残り時間をバーで可視化
💡 Web Audio API: 正解音・不正解音を追加するとゲーム感がさらにアップ!
スマホでも快適にプレイできるように
/* スマホ向けの調整 */
@media (max-width: 768px) {
.number-display {
font-size: 48px; /* PCは72px */
letter-spacing: 5px;
}
.user-input {
font-size: 24px;
width: 90%;
max-width: 300px;
}
.button {
width: 100%;
max-width: 300px;
padding: 15px;
font-size: 18px;
}
/* タッチしやすいボタンサイズ */
.game-button {
min-height: 48px; /* Appleのガイドライン */
min-width: 48px;
}
}
/* 横向き対応 */
@media (max-width: 768px) and (orientation: landscape) {
.game-container {
padding: 10px;
}
.stats {
font-size: 14px;
}
}
- 入力方法: スマホでは数字キーボードを自動表示
- タッチ対応: ボタンのタップエリアを十分に確保
- 画面サイズ: 小さい画面でも全体が見えるレイアウト
- 縦横対応: 横向きでもプレイできる設計
<input type="tel" inputmode="numeric" pattern="[0-9]*" id="userInput" >
基本機能ができたら、さらに面白くする要素を追加
- 難易度選択: Easy(表示4秒)/ Normal(3秒)/ Hard(2秒)
- モード追加:
- 「エンドレスモード」: ミス3回までOK
- 「タイムアタック」: 60秒で何問解けるか
- 「サバイバル」: 表示時間が徐々に短くなる
- 統計機能: 正答率、平均レベル、プレイ回数を表示
- シェア機能: Twitter/LINEでスコアをシェア
function shareToTwitter() {
const text = `記憶力ゲームでレベル${currentLevel}、スコア${score}点を達成しました!`;
const url = 'https://yourgame.com';
const hashtags = '記憶力ゲーム,脳トレ';
const twitterUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}&hashtags=${hashtags}`;
window.open(twitterUrl, '_blank', 'width=550,height=420');
}
// ゲームオーバー画面にボタンを追加
<button onclick="shareToTwitter()">
🐦 Twitterでシェア
</button>
function saveGameStats() {
const stats = JSON.parse(
localStorage.getItem('gameStats') ||
'{"totalGames":0,"totalScore":0,"maxLevel":0,"correctAnswers":0,"totalAnswers":0}'
);
stats.totalGames++;
stats.totalScore += score;
stats.maxLevel = Math.max(stats.maxLevel, currentLevel);
stats.totalAnswers += currentLevel - 1;
stats.correctAnswers += currentLevel - 1; // 不正解で終わるから-1
localStorage.setItem('gameStats', JSON.stringify(stats));
}
function displayStats() {
const stats = JSON.parse(localStorage.getItem('gameStats') || '{}');
const accuracy = ((stats.correctAnswers / stats.totalAnswers) * 100).toFixed(1);
const avgScore = (stats.totalScore / stats.totalGames).toFixed(0);
console.log(`正答率: ${accuracy}%`);
console.log(`平均スコア: ${avgScore}点`);
console.log(`最高到達レベル: ${stats.maxLevel}`);
}
💡 アイデア: 連続正解ボーナス、コンボシステム、アイテム機能(ヒント・時間延長)なども面白い!
軽快に動作するゲームを目指す
- タイマーの管理: setTimeoutのIDを保存して、必要時にclearTimeout
- イベントリスナー: 不要になったら removeEventListener で削除
- メモリリーク対策: ゲーム終了時にリセット処理を忘れずに
- 画像最適化: アイコンはSVGかWebP形式で軽量化
let displayTimeout = null;
function showNumber() {
// 前のタイマーをクリア
if (displayTimeout) {
clearTimeout(displayTimeout);
}
const number = generateNumber(currentDigits);
currentNumber = number;
document.getElementById('numberDisplay').textContent = number;
displayTimeout = setTimeout(() => {
hideNumber();
displayTimeout = null;
}, displayTime);
}
// ゲームリセット時
function resetGame() {
if (displayTimeout) {
clearTimeout(displayTimeout);
displayTimeout = null;
}
// その他のリセット処理...
}
let isProcessing = false;
function checkAnswer() {
if (isProcessing) return; // 連続実行を防ぐ
isProcessing = true;
const userInput = document.getElementById('userInput').value;
if (userInput === currentNumber) {
showCorrectFeedback();
setTimeout(() => {
levelUp();
isProcessing = false;
}, 1000);
} else {
showIncorrectFeedback();
setTimeout(() => {
gameOver();
isProcessing = false;
}, 2000);
}
}
💡 デバッグ: Chrome DevToolsのPerformanceタブで、処理が重い部分を特定して最適化しましょう。
実際にユーザーに遊んでもらい改善する
- GitHub Pagesで公開: リポジトリの設定から簡単にデプロイ
- Netlifyで公開: ドラッグ&ドロップで即座にデプロイ
- SNSで告知: Twitter、はてブで拡散
- フィードバック収集: Google Formでアンケート設置
# 1. GitHubにリポジトリを作成 # 2. ローカルでファイルを準備 git init git add . git commit -m "Initial commit" git branch -M main git remote add origin https://github.com/yourname/memory-game.git git push -u origin main # 3. GitHub上で Settings → Pages → Source を "main" に設定 # 4. 数分後に https://yourname.github.io/memory-game/ で公開される
- A/Bテスト: 表示時間のパターンを変えて反応を見る
- アナリティクス: Google Analyticsで離脱率を分析
- バグ報告: お問い合わせフォームやGitHub Issuesを用意
- 継続的改善: 週1回のペースでアップデート
💡 マネタイズ: 広告収益(Google AdSense)や、プレミアム機能の有料化も検討できます。
もっと面白くするための追加要素
- マルチプレイ対戦: WebSocketで友達と対戦
- AI対戦: AIプレイヤーと競争
- バリエーション:
- 文字バージョン(ランダムなアルファベット)
- 色パターン記憶
- 位置記憶(神経衰弱風)
- 音階記憶
- 教育向け: 九九の暗記、英単語記憶など学習要素を追加
- アクセシビリティ: 音声読み上げ、カラーブラインド対応
- PWA化: オフラインでもプレイ可能に
{
"name": "記憶力トレーニングゲーム",
"short_name": "記憶ゲーム",
"description": "瞬間記憶力を鍛えるゲーム",
"start_url": "/",
"display": "standalone",
"background_color": "#667eea",
"theme_color": "#667eea",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
💡 最後に: 完璧を目指すより、まず公開して反応を見る。ユーザーの声が最高の開発指針になります!
