【ゲーム】JavaScript:70 左右判断チャレンジ

 「左右判断チャレンジ」は、画面中央に表示される絵文字(矢印や手など)が「右」を示すか「左」を示すか瞬時に判断し、ボタンを押して答える反射神経+判断力ゲームです。制限時間(20秒)内にできるだけ多く正解を重ね、得点を競います。

遊び方・操作方法

  1. タイトル画面の「スタート」ボタンをクリック(または Enter/スペースキー)
  2. ゲーム画面で、中央に出る絵文字を見て、
    ・右向きなら「➡️ 右」ボタン
    ・左向きなら「⬅️ 左」ボタン
    を素早く押す
  3. 20秒の制限時間か、20問出題のうち先に終わった方まで挑戦
  4. 終了後に正解数と評価メッセージが表示され、タイトル画面に戻る

キー操作も可能

  • 左 ← / “a” → 左ボタン
  • 右 → / “d” → 右ボタン
  • Enter/スペース → スタート・戻る

ルール

  • 制限時間:20秒
  • 最大問題数:20問
  • 正答数をカウント
  • スコア
    ・15問以上 → 🎉 素晴らしい集中力!
    ・10~14問 → 👍 もう一息!
    ・それ未満 → がんばろう!
  • 制限時間内にすべて回答するか、20問終了でゲーム終了

🎮ゲームプレイ

以下のリンク先から実際にプレイできます。

70 左右判断チャレンジ

素材のダウンロード

以下のリンクから使用する素材をダウンロードできます。

left_right_judgement_title.pngleft_right_judgement_bg.png

ゲーム画面イメージ

プログラム全文(left_right_judgement.html)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>🖐️➡️⬅️ 左右判断チャレンジ 🖐️</title>
  <style>
    body {
      background: url('left_right_judgement_bg.png') no-repeat center center fixed;
      background-size: cover;
      margin: 0;
      font-family: 'Yu Gothic', 'Meiryo', 'Segoe UI', sans-serif;
      overflow-x: hidden;
    }
    .center-box {
      width: 800px;
      margin: 36px auto;
      background: rgba(255,255,255,0.96);
      border-radius: 18px;
      box-shadow: 0 4px 22px rgba(0,0,0,0.13);
      padding: 32px 28px 30px 28px;
      text-align: center;
      position: relative;
      min-height: 380px;
    }
    .title-img {
      display: block;
      margin: 0 auto 18px auto;
      max-width: 340px;
      height: auto;
    }
    h1 {
      font-size: 2rem;
      margin: 0 0 18px 0;
      text-align: center;
      letter-spacing: 2px;
    }
    h2 {
      font-size: 1.2rem;
      margin: 18px 0 6px 0;
      text-align: center;
      color: #202098;
    }
    .desc {
      text-align: left;
      margin: 0 auto 12px auto;
      max-width: 520px;
      color: #222;
      line-height: 1.7;
      background: rgba(240,240,240,0.90);
      padding: 10px 18px;
      border-radius: 10px;
    }
    .start-btn, .return-btn {
      margin: 24px auto 0 auto;
      display: block;
      font-size: 1.16rem;
      padding: 12px 40px;
      background: linear-gradient(90deg, #0034ce 50%, #fd9b0b 100%);
      color: #fff;
      border: none;
      border-radius: 32px;
      box-shadow: 0 2px 6px rgba(44,44,44,0.13);
      cursor: pointer;
      font-weight: bold;
      transition: background 0.18s, transform 0.08s;
    }
    .start-btn:hover, .return-btn:hover {
      background: linear-gradient(90deg, #fd9b0b 40%, #0034ce 100%);
      transform: scale(1.05);
    }
    .game-area {
      margin: 42px 0 18px 0;
    }
    .quiz-symbol {
      font-size: 5.2rem;
      padding: 14px 0 0 0;
      margin: 0 0 16px 0;
      text-shadow: 1px 1px 10px #2228;
      letter-spacing: 8px;
      display: block;
    }
    .quiz-instruct {
      font-size: 1.2rem;
      color: #1989e6;
      margin: 0 0 10px 0;
    }
    .ans-btns {
      margin: 30px 0 0 0;
      display: flex;
      justify-content: center;
      gap: 38px;
    }
    .ans-btn {
      font-size: 2rem;
      width: 160px;
      height: 60px;
      background: linear-gradient(90deg, #f9d423 10%, #fc913a 90%);
      border: none;
      color: #fff;
      border-radius: 15px;
      font-weight: bold;
      cursor: pointer;
      box-shadow: 0 2px 9px #9994;
      transition: background 0.14s, transform 0.08s;
    }
    .ans-btn:hover {
      background: linear-gradient(90deg, #fc913a 10%, #f9d423 90%);
      transform: scale(1.08);
    }
    .timer-bar-bg {
      width: 80%;
      background: #dde4fc;
      height: 22px;
      margin: 0 auto 18px auto;
      border-radius: 12px;
      box-shadow: 0 1px 8px #7294a8a9;
      overflow: hidden;
    }
    .timer-bar {
      background: #2f6fed;
      height: 100%;
      transition: width 0.1s;
    }
    .score-info {
      font-size: 1.14rem;
      margin: 12px 0 0 0;
      color: #19987a;
      letter-spacing: 2px;
    }
    .result-msg {
      font-size: 1.38rem;
      margin: 40px 0 16px 0;
      text-align: center;
      font-weight: bold;
      color: #c03636;
      background: #fff9;
      border-radius: 12px;
      padding: 18px 6px;
      box-shadow: 0 2px 16px rgba(0,0,0,0.13);
    }
  </style>
</head>
<body>
  <div class="center-box" id="main">
    <!-- タイトル/ゲーム/終了画面がここに -->
  </div>
  <script>
    // ==== クイズパターン ====(左右の手・矢印・顔などを混ぜてバリエーション多めに)
    const QUESTIONS = [
      {sym: "➡️", ans: "right", jp: "右"},
      {sym: "⬅️", ans: "left", jp: "左"},
      {sym: "🖐️", ans: Math.random()<0.5 ? "left" : "right", jp: "どちらか"}, // ランダム(たまに)
      {sym: "👉", ans: "right", jp: "右"},
      {sym: "👈", ans: "left", jp: "左"},
      {sym: "👋", ans: Math.random()<0.5 ? "left" : "right", jp: "どちらか"},
      {sym: "🦶➡️", ans: "right", jp: "右"},
      {sym: "🦶⬅️", ans: "left", jp: "左"},
      {sym: "🦾👉", ans: "right", jp: "右"},
      {sym: "🦿👈", ans: "left", jp: "左"},
      {sym: "🫲", ans: "left", jp: "左"},
      {sym: "🫱", ans: "right", jp: "右"},
    ];

    // ==== ゲーム管理用 ====
    let score = 0;
    let quizCnt = 0;
    const MAX_QUIZ = 20;
    const TIME_LIMIT = 20000; // 20秒
    let startTime = 0;
    let timer = null;

    // ==== タイトル画面 ====
    function showTitle() {
      clearInterval(timer);
      score = 0; quizCnt = 0;
      document.getElementById('main').innerHTML = `
        <img src="left_right_judgement_title.png" class="title-img" alt="タイトル画像">
        <h1>🖐️➡️⬅️ 左右判断チャレンジ 🖐️</h1>
        <h2>🎮 ルール説明 🎮</h2>
        <div class="desc">
          ・中央に「右・左・矢印・手」などの絵文字が出ます。<br>
          ・<b>「右」か「左」か</b>を素早くボタンで選択してください。<br>
          ・<b>制限時間20秒</b>で、できるだけ多く正解を目指そう!<br>
          ・集中力・反射神経・左右の判断力が鍛えられます!
        </div>
        <button class="start-btn" onclick="startGame()">スタート</button>
      `;
    }

    // ==== ゲーム開始 ====
    function startGame() {
      score = 0; quizCnt = 0;
      startTime = Date.now();
      nextQuiz();
      // タイマー(進行・バー表示)
      timer = setInterval(() => {
        let elapsed = Date.now() - startTime;
        if (elapsed > TIME_LIMIT) {
          clearInterval(timer);
          showResult();
        } else {
          updateTimerBar(elapsed);
        }
      }, 60);
    }

    // ==== クイズ出題 ====
    let nowQ = null;
    function nextQuiz() {
      quizCnt++;
      // ランダムに出題
      let q = QUESTIONS[Math.floor(Math.random() * QUESTIONS.length)];
      // ランダム手の時は左右を都度決定
      if (q.ans === "どちらか") {
        q.ans = Math.random() < 0.5 ? "left" : "right";
        q.jp = q.ans === "left" ? "左" : "右";
      }
      nowQ = q;
      document.getElementById('main').innerHTML = `
        <h1>🖐️➡️⬅️ 左右判断チャレンジ 🖐️</h1>
        <div class="timer-bar-bg">
          <div class="timer-bar" id="timerBar" style="width:100%"></div>
        </div>
        <div class="score-info">正解数:<b>${score}</b> 残り:${MAX_QUIZ-quizCnt+1}問</div>
        <div class="game-area">
          <span class="quiz-symbol">${q.sym}</span>
          <div class="quiz-instruct">右か左か、どちらかのボタンを押してください</div>
          <div class="ans-btns">
            <button class="ans-btn" onclick="checkAns('left')">⬅️ 左</button>
            <button class="ans-btn" onclick="checkAns('right')">➡️ 右</button>
          </div>
        </div>
      `;
    }

    // ==== タイマー進捗バー更新 ====
    function updateTimerBar(elapsed) {
      let w = Math.max(0, (1 - elapsed/TIME_LIMIT) * 100);
      let bar = document.getElementById('timerBar');
      if (bar) bar.style.width = w + "%";
    }

    // ==== 回答判定 ====
    function checkAns(ans) {
      if (!nowQ) return;
      if (ans === nowQ.ans) score++;
      if (quizCnt < MAX_QUIZ && Date.now() - startTime < TIME_LIMIT) {
        nextQuiz();
      } else {
        clearInterval(timer);
        showResult();
      }
    }

    // ==== 結果画面 ====
    function showResult() {
      let msg = `あなたの正解数は <b>${score}</b> 問でした!<br>`;
      msg += score >= 15 ? "🎉 素晴らしい集中力!" : (score >= 10 ? "👍 もう一息!" : "もう少しがんばろう!");
      document.getElementById('main').innerHTML = `
        <h1>🖐️➡️⬅️ 左右判断チャレンジ 🖐️</h1>
        <div class="result-msg">${msg}</div>
        <button class="return-btn" onclick="showTitle()">タイトル画面に戻る</button>
      `;
    }

    // ==== 初期表示 ====
    window.onload = showTitle;

    // ==== キーボード操作 ====
    document.addEventListener('keydown', function(e) {
      if (document.querySelector('.start-btn') && (e.key === "Enter" || e.key === " ")) startGame();
      if (document.querySelector('.return-btn') && (e.key === "Enter" || e.key === " ")) showTitle();
      if (document.querySelector('.ans-btn')) {
        if (e.key === "ArrowLeft" || e.key === "a") checkAns('left');
        if (e.key === "ArrowRight" || e.key === "d") checkAns('right');
      }
    });
  </script>
</body>
</html>

アルゴリズムの流れ

ステップ処理内容
1. showTitle()タイトル画面を描画(開始/ルール説明)
2. startGame()スコア・問題数リセット・開始時間記録・最初のクイズを出題・タイマー開始
3. nextQuiz()ランダムに問題を選択し、日本語説明付きで画面描画
4. updateTimerBar()経過時間に応じてタイマーバーの幅を変化
5. checkAns(ans)回答判定→スコア増加 or 継続 or 終了
6. showResult()結果画面描画(スコア+評価+タイトルへ戻る)

関数の詳細

関数名説明
showTitle()タイトル/ルール画面を描画。タイマーをクリアし、スコア・問題数をリセットします。
startGame()ゲームスタート処理。スコア・問題数初期化、開始時間記録、nextQuiz()とタイマーをセット。
nextQuiz()QUESTIONS配列からランダムに出題を選択。必要なら「どちらか」を左右いずれかに振り分けして、問題画面を描画。
updateTimerBar(t)引数に経過ミリ秒を受け取り、残り時間に応じた幅のタイマーバーをCSS幅として反映します。
checkAns(ans)ユーザー回答を判定。正解ならスコアインクリメントし、継続 or ゲーム終了を判断。
showResult()ゲーム終了時の結果画面を描画。スコアに応じた評価メッセージを表示し、タイトルへ戻るボタンを設置。

改造のポイント

  • 問題バリエーション拡充
    QUESTIONS配列に絵文字や文字列を追加すると、多彩な出題が可能に。
  • 難易度調整
    MAX_QUIZTIME_LIMITを変更して問題数・制限時間を調整
    ・「どちらか」ではなく確定問題の割合を変える
  • スコアリング強化
    ・連続正解コンボボーナスを加算
    ・正解ごとに残り時間を少し回復、アクション性をアップ
  • サウンド・演出
    ボタン押下音や正誤サウンド、CSSアニメーションを追加して爽快感を演出
  • レスポンシブ対応
    モバイルでも遊びやすいようにフォントサイズ・ボタンサイズの自動調整を導入

以上を参考に、ぜひオリジナリティあふれる改造にチャレンジしてみてください!