
【ゲーム】JavaScript:64 タイル記憶チャレンジ
「🧠 タイル記憶チャレンジ 🧠」は、6×5 のマス上にランダムに光るタイル(初期ヒントタイル)を一瞬だけ記憶し、その位置を正確に当てるメモリーゲームです。光ったタイルをすべてクリックで当てるまでのタイムを競います。
遊び方・操作方法
- スタートボタンをクリックするとゲーム開始。
- 盤面(6列×5行)のうち、ランダムで7枚のタイルが一瞬だけ「光る(黄色)」ので、位置を覚える。
- 光が消えたら、覚えたタイルを順番・順不同にクリックして当てる。
- すべて正解すればクリア。間違えると即リトライ(同じタイル配置で再挑戦)となる。
ルール
- 盤面サイズ:6列×5行(計30マス)
- ヒントタイル数:7枚(
HINT_CNT = 7
) - ヒント表示:開始後0.4秒後に1.35秒間光る
- 制限時間:なし(クリアタイムを計測)
- 間違い:不正解タイルをクリックするとすぐリトライ
- クリア:7枚すべてを当てた瞬間
🎮ゲームプレイ
以下のリンク先から実際にプレイできます。
64 タイル記憶チャレンジ
素材のダウンロード
以下のリンクから使用する素材をダウンロードできます。
tile_memory_challenge_title.png | tile_memory_challenge_bg.png |
---|---|
![]() | ![]() |
ゲーム画面イメージ

プログラム全文(tile_memory_challenge.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>🧠 タイル記憶チャレンジ 🧠</title>
<style>
html, body {
margin: 0; padding: 0;
width: 100vw; height: 100vh;
font-family: 'Yu Gothic', 'Meiryo', sans-serif;
background: url('tile_memory_challenge_bg.png') no-repeat center center fixed;
background-size: cover;
}
body {
width: 100vw;
height: 100vh;
overflow: auto;
}
.container {
width: 800px;
margin: 40px auto;
background: rgba(255,255,255,0.96);
border-radius: 22px;
box-shadow: 0 4px 24px rgba(0,0,0,0.13);
padding-bottom: 32px;
min-height: 520px;
position: relative;
}
.title-img {
display: block;
margin: 20px auto 18px auto;
width: 340px;
max-width: 80%;
height: auto;
}
h1 {
text-align: center;
font-size: 2.1em;
margin: 0.6em 0 0.15em 0;
color: #1976d2;
text-shadow: 1px 1px 7px #fff;
letter-spacing: 0.04em;
}
.rule-section {
background: rgba(235,245,255,0.98);
border-radius: 14px;
margin: 28px 32px 14px 32px;
padding: 16px 24px;
box-shadow: 0 2px 8px #4d90fe22;
}
.rule-title {
text-align: center;
font-weight: bold;
font-size: 1.3em;
margin-bottom: 10px;
color: #1976d2;
}
.rule-text {
text-align: left;
font-size: 1.09em;
line-height: 1.65;
color: #174078;
letter-spacing: 0.01em;
}
.btn {
display: block;
margin: 28px auto 0 auto;
padding: 14px 50px;
font-size: 1.2em;
border: none;
border-radius: 28px;
background: linear-gradient(90deg, #87c9fa, #1565c0);
color: #fff;
font-weight: bold;
box-shadow: 0 2px 8px #1976d266;
cursor: pointer;
transition: background 0.2s;
}
.btn:hover { background: linear-gradient(90deg, #b7e4fe, #1976d2); }
.game-area {
width: 740px;
margin: 36px auto 0 auto;
background: rgba(240,248,255,0.96);
border-radius: 16px;
box-shadow: 0 1px 10px #1565c055;
display: flex;
flex-direction: column;
align-items: center;
min-height: 310px;
padding: 16px 0 20px 0;
user-select: none;
}
.info {
text-align: center;
color: #1976d2;
font-size: 1.19em;
margin: 5px 0 0 0;
}
.memory-board {
display: grid;
grid-template-columns: repeat(6, 54px);
grid-gap: 15px 18px;
justify-content: center;
margin-top: 26px;
margin-bottom: 10px;
}
.memory-tile {
width: 54px; height: 54px;
background: #fff;
border: 2.5px solid #1976d2;
border-radius: 14px;
box-shadow: 0 2px 8px #1976d266;
cursor: pointer;
font-size: 2.1em;
display: flex; align-items: center; justify-content: center;
transition: background 0.14s, border-color 0.14s;
user-select: none;
position: relative;
outline: none;
}
.memory-tile.selected {
background: #b2ebf2;
border-color: #00bcd4;
color: #006064;
}
.memory-tile.found {
background: #c8e6c9 !important;
border-color: #388e3c;
color: #388e3c;
box-shadow: 0 0 7px #81c78499;
cursor: default;
pointer-events: none;
animation: found-pop 0.45s;
}
.memory-tile.hint {
background: #ffd54f !important;
border-color: #ff9800;
color: #bf360c;
}
.memory-tile:active:not(.found):not(.hint) {
background: #e3f2fd;
transform: scale(0.96);
}
@keyframes found-pop {
0% { transform: scale(1);}
50% { transform: scale(1.13);}
100% { transform: scale(1);}
}
.message-box {
text-align: center;
background: rgba(235,245,255,0.98);
font-size: 1.7em;
color: #1976d2;
font-weight: bold;
border-radius: 16px;
box-shadow: 0 4px 24px #1976d233;
width: 80%;
max-width: 480px;
margin: 34px auto 0 auto;
padding: 32px 18px;
position: relative;
z-index: 2;
}
.center-btn { margin: 22px auto 0 auto; }
.timer-bar {
text-align: center;
font-size: 1.09em;
margin-top: 6px;
color: #e53935;
font-weight: bold;
letter-spacing: 0.08em;
}
@media (max-width: 900px) {
.container, .game-area { width: 98vw !important; min-width: 0; }
.memory-board { grid-template-columns: repeat(4, 17vw); grid-gap: 2vw; }
.memory-tile { width: 17vw; height: 17vw; font-size: 6vw;}
}
</style>
</head>
<body>
<div class="container" id="main-container"></div>
<script>
// =============================
// 🧠 タイル記憶チャレンジ
// =============================
const BOARD_W = 6, BOARD_H = 5; // 6x5の盤面
const TILE_CNT = BOARD_W * BOARD_H;
const HINT_CNT = 7; // 一度に記憶するタイルの数(レベルで増減可)
let hintTiles = [];
let foundTiles = [];
let selectedTiles = [];
let phase = "wait";
let startTime = 0;
let timerId = null;
let timeSec = 0;
// タイトル画面
function showTitleScreen() {
clearInterval(timerId);
document.getElementById('main-container').innerHTML = `
<h1>🧠 タイル記憶チャレンジ 🧠</h1>
<img src="tile_memory_challenge_title.png" class="title-img" alt="タイル記憶チャレンジ タイトル">
<div class="rule-section">
<div class="rule-title">🧠 遊び方・ルール 🧠</div>
<div class="rule-text">
・一瞬だけ光るタイルの位置を覚えよう!<br>
・すべて当てるまでクリック!<br>
・間違えたらやり直しです。<br>
・タイムも計測されます。
</div>
</div>
<button class="btn" id="start-btn">スタート</button>
`;
document.getElementById('start-btn').onclick = startGame;
}
// ゲーム開始
function startGame() {
// ヒントタイルランダム選出
let arr = Array.from({length: TILE_CNT}, (_,i)=>i);
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
hintTiles = arr.slice(0, HINT_CNT).sort((a,b)=>a-b); // 並びは小さい順
foundTiles = new Array(TILE_CNT).fill(false);
selectedTiles = [];
phase = "show";
timeSec = 0;
showGameScreen();
setTimeout(showHint, 400);
}
// ヒントを一瞬表示
function showHint() {
renderBoard(true);
setTimeout(()=>{
phase = "play";
startTime = Date.now();
timerId = setInterval(()=>{
timeSec = ((Date.now()-startTime)/1000).toFixed(1);
const tb = document.getElementById('timer-bar');
if(tb) tb.textContent = `タイム: ${timeSec} 秒`;
}, 100);
renderBoard(false);
}, 1350);
}
// ゲーム画面
function showGameScreen() {
document.getElementById('main-container').innerHTML = `
<h1>🧠 タイル記憶チャレンジ 🧠</h1>
<div class="game-area">
<div class="info">${phase==="play" ? "光っていたタイルの位置をすべて当てて!" : "これから光るタイルを覚えてください。"}</div>
<div class="timer-bar" id="timer-bar">タイム: ${timeSec} 秒</div>
<div class="memory-board" id="memory-board"></div>
</div>
`;
renderBoard(phase==="show");
}
// ボード描画
function renderBoard(hint=false) {
let html = "";
for(let i=0; i<TILE_CNT; i++) {
let cls = "memory-tile";
let disp = "";
if(hint && hintTiles.includes(i)) cls += " hint";
if(foundTiles[i]) cls += " found";
if(selectedTiles.includes(i) && !foundTiles[i]) cls += " selected";
html += `<div class="${cls}" id="tile${i}" onclick="pickTile(${i})">${disp}</div>`;
}
document.getElementById('memory-board').innerHTML = html;
}
// タイルクリック
function pickTile(idx) {
if(phase !== "play" || foundTiles[idx] || selectedTiles.includes(idx)) return;
selectedTiles.push(idx);
// 正解判定
if(hintTiles.includes(idx)) {
foundTiles[idx] = true;
renderBoard();
// 全て見つけたらクリア
if(foundTiles.filter(v=>v).length === HINT_CNT) {
clearInterval(timerId);
setTimeout(showEndScreen, 700);
return;
}
} else {
// 間違い→やり直し
phase = "fail";
renderBoard();
setTimeout(()=>{
showGameScreen();
setTimeout(showHint, 500);
}, 1100);
return;
}
renderBoard();
}
// 終了画面
function showEndScreen() {
document.getElementById('main-container').innerHTML = `
<h1>🧠 タイル記憶チャレンジ 🧠</h1>
<img src="tile_memory_challenge_title.png" class="title-img" alt="タイル記憶チャレンジ タイトル">
<div class="message-box">
🎉 すべてのタイルを当てました!<br>あなたのタイム:<b>${timeSec}</b> 秒
</div>
<button class="btn center-btn" id="back-title-btn">タイトル画面に戻る</button>
`;
document.getElementById('back-title-btn').onclick = showTitleScreen;
}
// グローバル
window.pickTile = pickTile;
// 初期表示
showTitleScreen();
</script>
</body>
</html>
アルゴリズムの流れ
ステップ | 関数 | 内容 |
---|---|---|
1 | showTitleScreen | タイトル画面の描画。ルールとスタートボタン設置。 |
2 | startGame | ヒントタイルをランダム選出して初期化→showGameScreen →showHint へ移行 |
3 | showHint | ヒント表示フェーズ。盤面に hint クラスを付与し1.35秒後に非表示フェーズへ |
4 | renderBoard | hint ・play ・found フェーズに応じたタイル描画 |
5 | pickTile | クリックイベント。正解なら foundTiles 更新、すべて当てれば showEndScreen 。不正解ならリトライ |
6 | showEndScreen | クリアタイム表示&タイトル戻りボタン設置 |
関数の詳細
関数名 | 役割 | 詳細 |
---|---|---|
showTitleScreen | タイトル画面の生成 | ルール説明・スタートボタンを表示。タイマー停止 |
startGame | ゲーム初期化&開始 | ヒントタイルをランダム抽出・配列初期化→画面構築→ヒント表示 |
showHint | ヒントフェーズ | renderBoard(true) で黄色背景にして一瞬表示→クリックフェーズ開始 |
renderBoard | ボード描画 | hint ・selected ・found 各クラスを付与し、DOMで再構築 |
pickTile | タイル選択処理 | 正誤判定 → 正解:foundTiles 更新 ➝ 全消去でクリア画面不正解:phase="fail" ➝ リトライ |
showEndScreen | 終了画面表示 | クリアタイム表示+タイトルへ戻るボタン設置 |
改造のポイント
- 難易度設定:
HINT_CNT
を増減してタイル枚数を調整。初級者は5枚、中級は7枚、上級は10枚など。 - 段階モード:ステージクリアごとに
HINT_CNT
を段階的に増やす「レベルアップ制」を実装。 - 演出強化:タイルが光る際のアニメーション(CSSトランジション強化)やサウンドエフェクトを追加すると没入感UP。
- タイムアタックランキング:
localStorage
に最速タイムを保存し、ベストスコアを表示するランキング画面を実装。 - レスポンシブ調整:スマホでの見やすさ・操作しやすさを考慮し、タイルサイズや間隔を動的に調整。
アドバイス
まずはコアロジック(タイルの選出→表示→クリック判定→クリア判定)の安定を優先。そのあと見た目・音・モード追加を進めると、段階的にクオリティを高めやすくなります!