
【ゲーム】JavaScript:13 神経衰弱
「🧠 神経衰弱(メモリー)ゲーム 🧠」は、裏向きのカードをめくって同じ数字をペアにして取り除き、制限時間内にすべてのペアを見つける、一人用の記憶力ゲームです。
遊び方と操作方法
- 「▶️ ゲーム開始」ボタンを押すとカードがシャッフルされ、6×6 の盤面に裏向きで配置されます。
- カードを1枚クリックして表向きにめくり、続けてもう1枚をめくります。
・数字が一致すればそのペアは盤面から消え、スコアが+10 加算されます。
・不一致なら1秒後に自動で裏向きに戻ります。 - 残り時間は60秒。タイマーが0になるか、すべてのペアを見つけた時点でゲーム終了。
ルール
- 全26ペア(数字1~13×4スートから2枚ずつ)のカードがランダム配置。
- 同じ数字のペアを連続でめくると成功。
- ペア成功でスコア+10、失敗でペナルティはなし。
- 制限時間内にすべてのペアを揃えられればクリア、時間切れはゲームオーバー。
🎮ゲームプレイ
以下のリンク先から実際にプレイできます。
13 神経衰弱
素材のダウンロード
以下のリンクから使用する素材をダウンロードできます。
nervous_breakdownk_bg.png | nervous_breakdownk_start.png |
---|---|
![]() | ![]() |
ゲーム画面イメージ

プログラム全文(nervous_breakdown.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>🧠 神経衰弱 🧠</title>
<style>
/* =====================
全体レイアウト & 背景
===================== */
body {
margin: 0;
padding: 0;
font-family: 'Verdana', sans-serif;
background: url('nervous_breakdownk_bg.png') no-repeat center center fixed;
background-size: cover;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
}
/* =====================
共通見出しスタイル
===================== */
h1, h2 {
background: rgba(0,0,0,0.7);
padding: 10px 20px;
border-radius: 8px;
text-shadow: 2px 2px 6px #000;
}
h1 {
font-size: 3rem;
margin: 20px 0;
}
h2 {
font-size: 1.8rem;
margin: 10px 0;
}
/* =====================
ホーム画面スタイル
===================== */
#home-screen {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
width: 100%;
}
#home-screen img {
width: 300px;
height: auto;
margin-bottom: 20px;
border: 4px solid rgba(255,255,255,0.8);
border-radius: 8px;
}
#home-screen p {
background: rgba(0,0,0,0.8);
padding: 12px 24px;
border-radius: 6px;
font-size: 1.8rem; /* フォントサイズ大きく */
color: #fff;
text-shadow: 1px 1px 4px #000;
margin-bottom: 20px;
}
/* =====================
ゲーム画面スタイル
===================== */
#game-screen {
display: none;
flex-direction: column;
align-items: center;
flex: 1;
width: 100%;
}
#game-screen.active {
display: flex;
}
#controls {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
/* タイマー & スコア表示 */
#timer, #score {
background: rgba(0,0,0,0.7);
padding: 8px 16px;
border-radius: 6px;
font-size: 1.4rem;
text-shadow: 1px 1px 4px #000;
}
/* ゲームメッセージエリア */
#gameMessage {
background: rgba(255,0,0,0.8);
padding: 10px 20px;
border-radius: 6px;
font-size: 1.4rem;
text-shadow: 1px 1px 4px #000;
margin: 10px 0;
display: none;
}
/* =====================
ボード & カード配置
===================== */
#game-board {
display: grid;
grid-template-columns: repeat(6, 100px);
gap: 15px;
justify-content: center;
margin-bottom: 20px;
}
.card {
position: relative;
width: 100px;
height: 140px;
perspective: 1000px;
cursor: pointer;
}
.card-inner {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: transform 0.5s;
}
.flipped .card-inner {
transform: rotateY(180deg);
}
.front, .back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.front {
background: #fff;
color: #333;
font-size: 1.6rem;
font-weight: bold;
transform: rotateY(180deg);
line-height: 1.2;
}
.front .suit {
font-size: 2rem;
margin-bottom: 5px;
}
/* 裏面の可視性を高める */
.back {
background: rgba(0,102,204,0.8) url('') no-repeat center/cover;
border: 2px solid rgba(255,255,255,0.8);
}
/* =====================
ボタンスタイル
===================== */
button {
padding: 12px 24px;
margin: 5px;
font-size: 1.2rem;
font-weight: bold;
color: #fff;
background: #2d89ef;
border: none;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
transition: background 0.3s, transform 0.2s;
cursor: pointer;
}
button:hover {
background: #1b5fa7;
transform: scale(1.05);
}
</style>
</head>
<body>
<!-- ホーム画面 -->
<div id="home-screen">
<img src="nervous_breakdownk_start.png" alt="スタート画面"/>
<h1>🧠 神経衰弱ゲーム 🧠</h1>
<p>同じ数字のカードをめくってペアを作ろう!</p>
<button onclick="startGame()">▶️ ゲーム開始</button>
</div>
<!-- ゲーム画面 -->
<div id="game-screen">
<h1>🧠 神経衰弱 🧠</h1>
<div id="controls">
<div id="timer">⏱ 残り時間: 60秒</div>
<div id="score">⭐️ スコア: 0</div>
</div>
<div id="gameMessage"></div>
<div id="game-board"></div>
<button onclick="goHome()">🏠 タイトルに戻る</button>
</div>
<script>
// --- 要素取得 ---
const homeScreen = document.getElementById('home-screen');
const gameScreen = document.getElementById('game-screen');
const board = document.getElementById('game-board');
const timerDisp = document.getElementById('timer');
const scoreDisp = document.getElementById('score');
const messageArea = document.getElementById('gameMessage');
// --- ゲーム変数 ---
const suits = ['♠️','♥️','♦️','♣️'];
const numbers = [...Array(13).keys()].map(n=>n+1);
let deck = [];
let firstCard = null;
let lockBoard = false;
let timer = null;
let timeLeft = 60;
let score = 0;
let countdownId = null;
/**
* ゲーム開始時
*/
function startGame() {
// ホーム→ゲーム画面
homeScreen.style.display = 'none';
gameScreen.classList.add('active');
initGame();
startTimer();
}
/**
* タイトルに戻る
*/
function goHome() {
clearInterval(timer);
clearInterval(countdownId);
gameScreen.classList.remove('active');
homeScreen.style.display = 'flex';
}
/**
* 初期化
*/
function initGame() {
board.innerHTML = '';
firstCard = null;
lockBoard = false;
timeLeft = 60;
score = 0;
scoreDisp.textContent = `⭐️ スコア: ${score}`;
messageArea.style.display = 'none';
// デッキ生成:各数字ペアに違う2つのマークを割り当て
deck = [];
numbers.forEach(n => {
const copy = suits.slice();
// ランダムに2つのスートを選択
for (let i=0; i<2; i++) {
const idx = Math.floor(Math.random()*copy.length);
deck.push({ value: n, suit: copy.splice(idx,1)[0] });
}
});
// シャッフル
deck.sort(() => 0.5 - Math.random());
// カード配置
deck.forEach(cardData => {
const card = document.createElement('div');
card.className = 'card';
card.dataset.value = cardData.value;
card.dataset.suit = cardData.suit;
const inner = document.createElement('div');
inner.className = 'card-inner';
const front = document.createElement('div');
front.className = 'front';
// マーク + 数字
const s = document.createElement('div');
s.className = 'suit';
s.textContent = cardData.suit;
const v = document.createElement('div');
v.textContent = cardData.value;
front.append(s, v);
const back = document.createElement('div');
back.className = 'back';
inner.append(front, back);
card.append(inner);
card.addEventListener('click', flipCard);
board.append(card);
});
timerDisp.textContent = `⏱ 残り時間: ${timeLeft}秒`;
}
/**
* タイマー開始
*/
function startTimer() {
clearInterval(timer);
timer = setInterval(() => {
timeLeft--;
timerDisp.textContent = `⏱ 残り時間: ${timeLeft}秒`;
if (timeLeft <= 0) {
clearInterval(timer);
showGameOver('⏰ 時間切れ!ゲームオーバー!');
}
}, 1000);
}
/**
* カードをめくる
*/
function flipCard() {
if (lockBoard || this === firstCard) return;
this.classList.add('flipped');
if (!firstCard) {
firstCard = this;
return;
}
// 2枚目比較
const a = this.dataset.value, b = firstCard.dataset.value;
if (a === b) {
setTimeout(() => {
this.classList.add('hidden');
firstCard.classList.add('hidden');
score += 10;
scoreDisp.textContent = `⭐️ スコア: ${score}`;
resetBoard();
checkWin();
}, 500);
} else {
lockBoard = true;
setTimeout(() => {
this.classList.remove('flipped');
firstCard.classList.remove('flipped');
resetBoard();
}, 1000);
}
}
/**
* リセット
*/
function resetBoard() {
[ firstCard, lockBoard ] = [ null, false ];
}
/**
* クリア判定
*/
function checkWin() {
const hiddenCount = document.querySelectorAll('.card.hidden').length;
if (hiddenCount === deck.length) {
clearInterval(timer);
showGameOver(`🎉 クリア!おめでとう!スコア: ${score}`);
}
}
/**
* ゲームオーバー/クリアメッセージ & 10秒後タイトルへ
*/
function showGameOver(text) {
let cnt = 10;
messageArea.style.display = 'block';
messageArea.textContent = `${text} ${cnt}秒後にタイトルへ戻ります`;
countdownId = setInterval(() => {
cnt--;
if (cnt > 0) {
messageArea.textContent = `${text} ${cnt}秒後にタイトルへ戻ります`;
} else {
clearInterval(countdownId);
goHome();
}
}, 1000);
}
</script>
</body>
</html>
アルゴリズムの流れ
ステップ | 関数/命令 | 内容 |
---|---|---|
ゲーム開始 | startGame() | ホーム画面非表示・ゲーム画面表示・initGame() ・startTimer() 呼び出し |
タイトルに戻る | goHome() | タイマー・カウントダウン停止・画面切り替え |
初期化 | initGame() | デッキ生成・シャッフル・カード配置・変数リセット・UI 初期状態更新 |
タイマー開始 | startTimer() | 1 秒ごとに timeLeft-- → タイマー表示更新 → 0 秒で showGameOver() 呼び出し |
カードめくり | flipCard() | カード裏→表面に回転アニメ → 1枚目 or 2枚目を区別 → 成否で処理分岐 |
ボード状態リセット | resetBoard() | firstCard と lockBoard をクリア |
クリア判定 | checkWin() | 全カードが hidden クラス付きか確認 → クリアなら showGameOver() 呼び出し |
ゲームオーバー表示 | showGameOver(text) | メッセージ表示 → 10秒後に goHome() でタイトル画面に自動遷移 |
関数の役割
関数名 | 役割 |
---|---|
startGame() | タイトル→ゲーム画面への切換え、初期化&タイマー開始 |
goHome() | ゲーム中断してホーム画面に戻す(タイマー・カウント停止) |
initGame() | カードデータ生成(各数字2枚×4スート)→シャッフル→盤面にカード要素を配置 |
startTimer() | 制限時間のカウントダウン管理。0秒でゲームオーバー |
flipCard() | ユーザークリックでカードをめくるロジック。ペア判定→成功/失敗処理 |
resetBoard() | 1ペア処理後または失敗後に内部状態をクリア |
checkWin() | すべてのペアが揃ったかを確認し、クリア時に結果表示 |
showGameOver() | クリア/ゲームオーバー共通の演出。メッセージを出し、数秒後に自動でタイトルに戻す |
改造のポイント
- 難易度調整:カード枚数(例:4×4、8×8)、制限時間を変えて難易度アップ/ダウン。
- テーマ切替:トランプ以外のイラスト(動物、キャラクターなど)のカードに差し替え。
- スコア機能拡張:ペア発見までの時間でボーナス、連続正解ボーナスやハイスコア保存機能を追加。
- サウンドエフェクト:めくり音、ペア成功音、失敗音などで遊び心を演出。
- マルチプレイヤーモード:複数人で交互にめくり合う対戦モードを実装。
- 視覚効果:カードのゆれアニメ、クリアアニメーション、背景エフェクトでさらに華やかに。
この基本実装をベースに、ぜひオリジナル要素を盛り込んで、楽しい「神経衰弱」アプリを完成させてください!