
【ゲーム】JavaScript:57 記号タップ順チャレンジ
「⭐ 記号タップ順チャレンジ ⭐」は、画面に並んだ複数の記号がランダムな順番で光るのを覚え、その順番どおりにタップしていく記憶力&反射神経テストゲームです。クリアするたびに記号の数(レベル)が増え、最大レベル10まで挑戦可能。シンプルながらも繰り返すほど記憶力が鍛えられます。
遊び方・操作方法
- タイトル画面で「スタート」をタップするとレベル1がスタート。
- 画面に並んだ記号(★ ● ▲ ■ …)が、ランダムな順番で“光る”(色が変わる)ので順番をよく覚えます。
- 光った順序どおりに記号をタップ。正解すると次の記号へ、すべて正解するとレベルクリア!
- レベルが上がるごとに記号が1つずつ増え、記憶負荷がアップ。
- タップを間違えるとゲーム終了画面へ。到達レベルが表示されます。
- レベル10をクリアするとゲームクリア!
ルール
- 初期レベルは1。レベルnnでは記号nn個を使う。
- 記号は重複せずランダム選出。
- 光る順番もランダム。その順番通りにタップしないと終了。
- 正答し続けるとレベルが上昇。レベル10達成でエンディング。
- 途中で間違えると「到達レベル」が表示され、タイトル画面へ戻れます。
🎮ゲームプレイ
以下のリンク先から実際にプレイできます。
57 記号タップ順チャレンジ
素材のダウンロード
以下のリンクから使用する素材をダウンロードできます。
symbol_tap_title.png | symbol_tap_bg.png |
---|---|
![]() | ![]() |
ゲーム画面イメージ

プログラム全文(symbol_tap.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('symbol_tap_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.94);
border-radius: 22px;
box-shadow: 0 4px 24px rgba(0,0,0,0.13);
padding-bottom: 32px;
min-height: 600px;
position: relative;
}
.title-img {
display: block;
margin: 20px auto 18px auto;
width: 400px;
max-width: 80%;
height: auto;
}
h1 {
text-align: center;
font-size: 2.1em;
margin: 0.6em 0 0.15em 0;
color: #e7b200;
text-shadow: 1px 1px 7px #fff;
letter-spacing: 0.04em;
}
.rule-section {
background: rgba(255,245,210,0.98);
border-radius: 14px;
margin: 28px 32px 14px 32px;
padding: 16px 24px;
box-shadow: 0 2px 8px #e7b20033;
}
.rule-title {
text-align: center;
font-weight: bold;
font-size: 1.3em;
margin-bottom: 10px;
color: #e7b200;
}
.rule-text {
text-align: left;
font-size: 1.08em;
line-height: 1.65;
color: #ad8907;
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, #ffe259, #e7b200);
color: #684e00;
font-weight: bold;
box-shadow: 0 2px 8px #e7b20055;
cursor: pointer;
transition: background 0.2s;
}
.btn:hover { background: linear-gradient(90deg, #ffe98a, #ad8907); }
.game-area {
width: 700px;
margin: 30px auto 0 auto;
background: rgba(250,240,200,0.92);
border-radius: 18px;
box-shadow: 0 2px 14px #8884;
min-height: 280px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
padding: 28px 10px 38px 10px;
position: relative;
user-select: none;
}
.symbol-btn {
width: 90px; height: 90px;
margin: 18px;
border-radius: 20px;
border: 3px solid #e7b200;
background: #fffbe5;
font-size: 2.6em;
font-weight: bold;
color: #bfa400;
box-shadow: 0 3px 12px #e7b20033;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.11s, box-shadow 0.11s, color 0.11s;
cursor: pointer;
outline: none;
position: relative;
}
.symbol-btn.active {
background: #ffe259;
color: #ff9100;
box-shadow: 0 0 30px #ffe25988;
}
.status-bar {
text-align: center;
margin: 14px auto 0 auto;
font-size: 1.1em;
font-weight: bold;
background: rgba(255,255,220,0.96);
color: #e7b200;
width: 380px;
border-radius: 12px;
box-shadow: 0 1px 7px #e7b20044;
padding: 10px;
letter-spacing: 0.05em;
}
.message-box {
text-align: center;
background: rgba(255,245,210,0.98);
font-size: 2em;
color: #e7b200;
font-weight: bold;
border-radius: 16px;
box-shadow: 0 4px 24px #ffe25933;
width: 80%;
max-width: 480px;
margin: 40px auto 0 auto;
padding: 38px 18px;
position: relative;
z-index: 2;
}
.center-btn { margin: 24px auto 0 auto; }
@media (max-width: 900px) {
.container, .game-area { width: 98vw !important; min-width: 0; }
.game-area { flex-direction: column; align-items: center;}
.symbol-btn { margin: 10px;}
}
</style>
</head>
<body>
<div class="container" id="main-container"></div>
<script>
// --- ゲーム状態変数 ---
const SYMBOLS = ["★", "●", "▲", "■", "♥", "◆", "♠", "☀", "☁", "♣"];
let level = 1;
let indices = [];
let seqOrder = [];
let userStep = 0;
let acceptingInput = false;
const MAX_LEVEL = 10;
// タイトル画面
function showTitleScreen() {
document.getElementById('main-container').innerHTML = `
<h1>⭐ 記号タップ順チャレンジ ⭐</h1>
<img src="symbol_tap_title.png" class="title-img" alt="記号タップ順チャレンジ タイトル">
<div class="rule-section">
<div class="rule-title">🎲 遊び方・ルール 🎲</div>
<div class="rule-text">
・画面にいくつかの記号が並びます。<br>
・最初に記号が<span style="color:#e7b200;font-weight:bold;">ランダムな順番</span>で光るので、よく覚えてください。<br>
・光った順番どおりに記号をタップしましょう。<br>
・正しい順で全部押すとレベルアップ!間違えるとゲーム終了です。<br>
・レベルが上がるごとに記号が1つ増えます。<br>
・<b>レベル10</b>をクリアするとゲームクリアです!
</div>
</div>
<button class="btn" id="start-btn">スタート</button>
`;
document.getElementById('start-btn').onclick = ()=>startGame(1);
}
// ゲーム開始
function startGame(startLevel) {
level = startLevel;
startRound();
}
// ラウンド開始
function startRound() {
indices = [];
userStep = 0;
acceptingInput = false;
// 記号をランダムにlevel数だけ選ぶ(重複なし)
let used = [];
while(indices.length < level){
let idx = Math.floor(Math.random()*SYMBOLS.length);
if (!used.includes(idx)) {
indices.push(idx);
used.push(idx);
}
}
// 光らせる順番もランダム
seqOrder = [];
let indicesCopy = indices.slice();
while(seqOrder.length < indices.length) {
let i = Math.floor(Math.random() * indicesCopy.length);
seqOrder.push(indicesCopy[i]);
indicesCopy.splice(i, 1);
}
showGameScreen();
setTimeout(()=>showSequence(0), 1000);
}
// ゲーム画面表示
function showGameScreen(msg) {
document.getElementById('main-container').innerHTML = `
<h1>⭐ 記号タップ順チャレンジ ⭐</h1>
<div class="game-area" id="game-area"></div>
<div class="status-bar" id="status-bar">${msg ? msg : `レベル ${level}:覚えてください!`}</div>
`;
drawSymbols();
}
// 記号を並べる
function drawSymbols() {
const area = document.getElementById('game-area');
area.innerHTML = '';
// 今回使う記号だけ配置
for (let i = 0; i < indices.length; i++) {
const idx = indices[i];
const btn = document.createElement('div');
btn.className = 'symbol-btn';
btn.textContent = SYMBOLS[idx];
btn.dataset.idx = idx;
btn.onclick = () => handleUserInput(idx, btn);
area.appendChild(btn);
}
}
// 記号がランダムな順で光るアニメ
function showSequence(n) {
acceptingInput = false;
const area = document.getElementById('game-area');
const btns = Array.from(area.getElementsByClassName('symbol-btn'));
if (n >= seqOrder.length) {
// 入力受付へ
acceptingInput = true;
document.getElementById('status-bar').innerHTML = `順番にタップしてください`;
return;
}
// 光らせる記号を特定
let idxToFlash = seqOrder[n];
for (let i = 0; i < btns.length; i++) {
if (parseInt(btns[i].dataset.idx) === idxToFlash) {
btns[i].classList.add('active');
playTone(n);
setTimeout(()=>btns[i].classList.remove('active'), 450);
}
}
setTimeout(()=>showSequence(n+1), 650);
}
// プレイヤーが記号を押した時
function handleUserInput(idx, btn) {
if (!acceptingInput) return;
// 今回押すべきidxか?(光った順と一致するか)
if (idx === seqOrder[userStep]) {
// 成功: 点滅
btn.classList.add('active');
playTone(userStep);
setTimeout(()=>btn.classList.remove('active'), 250);
userStep++;
if (userStep === seqOrder.length) {
acceptingInput = false;
if (level === MAX_LEVEL) {
showClearScreen();
} else {
showGameScreen(`<span style="color:#0a9a2b;">クリア!次はレベル${level+1}に挑戦</span>`);
setTimeout(()=>{level++;startRound();}, 1500);
}
}
} else {
// 失敗
acceptingInput = false;
btn.style.background = "#ff8a65";
showEndScreen();
}
}
// ゲームクリア画面
function showClearScreen() {
document.getElementById('main-container').innerHTML = `
<h1>⭐ 記号タップ順チャレンジ ⭐</h1>
<img src="symbol_tap_title.png" class="title-img" alt="記号タップ順チャレンジ タイトル">
<div class="message-box">
🎉おめでとう!ゲームクリア!🎉<br>
<span style="font-size:1.2em;color:#e7b200;">全${MAX_LEVEL}レベル達成!</span>
</div>
<button class="btn center-btn" id="back-title-btn">タイトル画面に戻る</button>
`;
document.getElementById('back-title-btn').onclick = showTitleScreen;
}
// ゲームオーバー画面
function showEndScreen() {
document.getElementById('main-container').innerHTML = `
<h1>⭐ 記号タップ順チャレンジ ⭐</h1>
<img src="symbol_tap_title.png" class="title-img" alt="記号タップ順チャレンジ タイトル">
<div class="message-box">
ゲーム終了!<br>
<span style="font-size:1.2em;color:#e7b200;">到達レベル:${level}</span>
</div>
<button class="btn center-btn" id="back-title-btn">タイトル画面に戻る</button>
`;
document.getElementById('back-title-btn').onclick = showTitleScreen;
}
// シンプルな効果音
function playTone(n) {
try {
const ctx = new(window.AudioContext||window.webkitAudioContext)();
const o = ctx.createOscillator();
const g = ctx.createGain();
o.type = "triangle";
o.frequency.value = 440 + 80 * n;
g.gain.value = 0.08;
o.connect(g);
g.connect(ctx.destination);
o.start();
g.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.19);
o.stop(ctx.currentTime + 0.19);
setTimeout(()=>ctx.close(), 220);
} catch(e) {}
}
// 初期表示
showTitleScreen();
</script>
</body>
</html>
アルゴリズムの流れ
手順 | 処理内容 |
---|---|
1 | showTitleScreen() でタイトル画面を描画 |
2 | 「スタート」押下 → startGame(1) → startRound() で初期レベルラウンド開始 |
3 | startRound() で記号リスト(重複なしランダム)とシーケンス順を生成 |
4 | showGameScreen() でゲームエリアとステータスバーを描画 |
5 | showSequence(0) で順番どおりに記号を光らせ、終わったら acceptingInput=true |
6 | ユーザーのタップは handleUserInput() で受け、正誤を判定 |
7 | 正解なら次へ、すべて正解ならレベルアップ or クリア画面 |
8 | 不正解なら showEndScreen() で到達レベル表示のゲームオーバー |
関数の詳細
関数名 | 機能概要 | 詳細説明 |
---|---|---|
showTitleScreen() | タイトル画面の描画 | ルール説明&「スタート」ボタン設置。ゲーム状態はクリア済でもリセット。 |
startGame(startLevel) | ゲーム開始/レベル設定 | 引数で開始レベルを受け取り、startRound() を呼び出す |
startRound() | ラウンド初期化 | レベル数だけ異なる記号をランダム選出し、光らせる順序をシャッフルして生成 |
showGameScreen(msg) | ゲーム画面再描画 | ゲームエリア(記号ボタン)とステータスバー(レベル or メッセージ)を描画 |
drawSymbols() | 記号ボタンを動的生成 | indices 配列に基づき、.symbol-btn 要素を並べてクリックハンドラを付与 |
showSequence(n) | 記号の光らせ演出(シーケンス再生) | 配列 seqOrder の n 番目の記号ボタンに active クラスを付与し、次の再生を再帰的にスケジュール |
handleUserInput(idx,btn) | プレイヤーのタップ処理 | 正解なら次ステップへ、不正解なら背景色を変更してゲームオーバー画面へ |
showClearScreen() | 全レベルクリア時のエンディング表示 | クリアメッセージとタイトル戻りボタンを描画 |
showEndScreen() | 不正解時のゲームオーバー表示 | 到達レベルを表示するメッセージとタイトル戻りボタンを描画 |
playTone(n) | シーケンス再生・タップフィードバック用簡易効果音 | Web Audio API で三角波オシレーターを生成し、番号 n に応じたピッチで短時間再生 |
改造のポイント
- 記号バリエーション:★●▲■以外の絵文字やカラー記号を追加し、視覚的変化をつける。
- ヒント機能:光らせる順序の一部だけ小さく順番番号を表示して難易度調整。
- 難易度選択:記号数だけでなく光るスピードや待ち時間を変化させるモード追加。
- ランキング機能:到達レベルやクリアタイムを
localStorage
に保存し、ハイスコア一覧を表示。 - 音楽・演出強化:BGMやヒット時のアニメーションで演出を充実させ、没入感をアップ。
アドバイス
まずは記憶チャレンジのコアルールを安定させたうえで、ランキングや難易度モードを段階的に追加すると、プレイヤーの継続率が高まります。視覚的・聴覚的なフィードバックを強化すれば、リズムゲームのように楽しめる要素が生まれます!