【ゲーム】JavaScript:67 図形カウントクイズ

 「🔵図形カウントクイズ」は、画面内に多数の円・三角・四角の図形がランダムに描画され、その中から「◯はいくつ?」「△はいくつ?」といった問題に素早く答える反射&計数クイズゲームです。
全5問を連続で解き、正答数と所要時間を競います。

遊び方・操作方法

  1. タイトル画面で「スタート」をクリック。
  2. 問題ごとに画面左上の「Q1:🔵円はいくつ?」のように出題されます。
  3. 白いキャンバス内にランダム配置された図形を数え、
    右下の入力欄に数値を入力して「回答」ボタンかEnterキーで送信。
  4. 正解/不正解のフィードバック後、自動的に次の問題へ。
  5. 5問クリア後、正答数とタイムが表示されます。

ルール

  • 全5問(QUESTION_CNT = 5)を連続で解答。
  • 問題ごとに20~25個の図形が配置される。
  • 正解したらスコア(正答数)が1増加。不正解でも次に進む。
  • 5問終了後にクリア画面へ。正答数と経過タイムを表示。

🎮ゲームプレイ

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

67 図形カウントクイズ

素材のダウンロード

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

shape_counting_quiz_title.pngshape_counting_quiz_bg.png

ゲーム画面イメージ

プログラム全文(shape_counting_quiz.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('shape_counting_quiz_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: 320px;
      padding: 16px 0 20px 0;
      user-select: none;
    }
    .info {
      text-align: center;
      color: #1976d2;
      font-size: 1.19em;
      margin: 5px 0 0 0;
    }
    .canvas-area {
      display: flex;
      justify-content: center;
      align-items: center;
      margin: 24px 0 18px 0;
      width: 420px; height: 260px;
      background: #fff;
      border-radius: 14px;
      border: 2.5px solid #90caf9;
      box-shadow: 0 1px 10px #1976d066;
      position: relative;
    }
    .question-bar {
      text-align: center;
      font-size: 1.25em;
      color: #e53935;
      font-weight: bold;
      margin: 10px 0 10px 0;
    }
    .input-area {
      margin-top: 12px;
      text-align: center;
    }
    .input-answer {
      font-size: 1.3em;
      padding: 6px 22px;
      border-radius: 10px;
      border: 2px solid #1976d2;
      width: 80px;
      text-align: center;
      margin-right: 10px;
      outline: none;
      margin-bottom: 8px;
    }
    .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; }
  </style>
</head>
<body>
  <div class="container" id="main-container"></div>
  <script>
    // ==========================================
    // 🔵 図形カウントクイズ
    // ==========================================
    const SHAPES = [
      { name: "円", emoji: "🔵", draw: drawCircle },
      { name: "三角", emoji: "🔺", draw: drawTriangle },
      { name: "四角", emoji: "🟥", draw: drawSquare }
    ];
    const QUESTION_CNT = 5;
    let shapeObjects = [];
    let currentQ = 0;
    let questionShape = null;
    let answerCount = 0;
    let correctCount = 0;
    let startTime = 0;

    // タイトル画面
    function showTitleScreen() {
      document.getElementById('main-container').innerHTML = `
        <h1>🔵 図形カウントクイズ 🔺</h1>
        <img src="shape_counting_quiz_title.png" class="title-img" alt="図形カウントクイズ タイトル">
        <div class="rule-section">
          <div class="rule-title">🔵 遊び方・ルール 🔺</div>
          <div class="rule-text">
            ・画面の中にいろいろな図形が表示されます。<br>
            ・「円はいくつ?」「三角はいくつ?」などのクイズに、素早く正確に答えましょう!<br>
            ・全${QUESTION_CNT}問連続チャレンジ、得点とタイムも競えます。
          </div>
        </div>
        <button class="btn" id="start-btn">スタート</button>
      `;
      document.getElementById('start-btn').onclick = startGame;
    }

    // ゲーム開始
    function startGame() {
      currentQ = 0;
      correctCount = 0;
      startTime = Date.now();
      nextQuestion();
    }

    // 問題出題
    function nextQuestion() {
      if (currentQ >= QUESTION_CNT) {
        showEndScreen();
        return;
      }
      shapeObjects = [];
      // 図形をランダムに20~25個配置
      let totalShapes = 20 + Math.floor(Math.random()*6);
      let shapeCounts = [0,0,0];
      for(let i=0;i<totalShapes;i++) {
        let t = Math.floor(Math.random()*SHAPES.length);
        shapeObjects.push({type: t, x: Math.random()*370+20, y: Math.random()*190+30, size: Math.random()*22+24});
        shapeCounts[t]++;
      }
      // 出題する図形を決定
      questionShape = Math.floor(Math.random()*SHAPES.length);
      answerCount = shapeCounts[questionShape];
      renderGameScreen();
      currentQ++;
    }

    // ゲーム画面
    function renderGameScreen() {
      document.getElementById('main-container').innerHTML = `
        <h1>🔵 図形カウントクイズ 🔺</h1>
        <div class="game-area">
          <div class="question-bar">Q${currentQ}:${SHAPES[questionShape].emoji}「${SHAPES[questionShape].name}」はいくつ?</div>
          <div class="canvas-area"><canvas id="shapecanvas" width="420" height="260"></canvas></div>
          <div class="input-area">
            <input type="number" class="input-answer" id="input-answer" min="0" autofocus>
            <button class="btn" id="answer-btn">回答</button>
          </div>
          <div class="info">※他の図形も混じっています。正確に数えてね!</div>
        </div>
      `;
      drawCanvasShapes();
      document.getElementById('answer-btn').onclick = checkAnswer;
      document.getElementById('input-answer').onkeydown = function(e){
        if(e.key === "Enter") checkAnswer();
      };
      setTimeout(()=>document.getElementById('input-answer').focus(),100);
    }

    // 図形をCanvasで描画
    function drawCanvasShapes() {
      const ctx = document.getElementById('shapecanvas').getContext('2d');
      ctx.clearRect(0,0,420,260);
      for(const obj of shapeObjects) {
        SHAPES[obj.type].draw(ctx, obj.x, obj.y, obj.size);
      }
    }
    // 円描画
    function drawCircle(ctx, x, y, r) {
      ctx.beginPath();
      ctx.arc(x, y, r, 0, Math.PI*2, false);
      ctx.fillStyle = "#2196f3";
      ctx.globalAlpha = 0.8;
      ctx.fill();
      ctx.globalAlpha = 1;
    }
    // 三角描画
    function drawTriangle(ctx, x, y, size) {
      ctx.beginPath();
      ctx.moveTo(x, y - size);
      ctx.lineTo(x - size, y + size);
      ctx.lineTo(x + size, y + size);
      ctx.closePath();
      ctx.fillStyle = "#f44336";
      ctx.globalAlpha = 0.8;
      ctx.fill();
      ctx.globalAlpha = 1;
    }
    // 四角描画
    function drawSquare(ctx, x, y, size) {
      ctx.beginPath();
      ctx.rect(x-size, y-size, size*2, size*2);
      ctx.fillStyle = "#fbc02d";
      ctx.globalAlpha = 0.8;
      ctx.fill();
      ctx.globalAlpha = 1;
    }

    // 回答チェック
    function checkAnswer() {
      let v = parseInt(document.getElementById('input-answer').value);
      if(isNaN(v)) return;
      if(v === answerCount) {
        correctCount++;
        showFeedback(true);
      } else {
        showFeedback(false);
      }
    }

    // フィードバック
    function showFeedback(isCorrect) {
      document.querySelector('.input-area').innerHTML = `<span style="font-size:1.3em;color:${isCorrect ? "#388e3c" : "#d32f2f"};">${isCorrect ? "正解!" : "不正解..."}</span>`;
      setTimeout(nextQuestion, 1100);
    }

    // 終了画面
    function showEndScreen() {
      let timeSec = ((Date.now()-startTime)/1000).toFixed(1);
      document.getElementById('main-container').innerHTML = `
        <h1>🔵 図形カウントクイズ 🔺</h1>
        <img src="shape_counting_quiz_title.png" class="title-img" alt="図形カウントクイズ タイトル">
        <div class="message-box">
          🎉 クイズ終了!<br>
          正解数:${correctCount} / ${QUESTION_CNT}<br>
          タイム:${timeSec} 秒
        </div>
        <button class="btn center-btn" id="back-title-btn">タイトル画面に戻る</button>
      `;
      document.getElementById('back-title-btn').onclick = showTitleScreen;
    }

    // 初期表示
    showTitleScreen();
  </script>
</body>
</html>

アルゴリズムの流れ

No.処理内容関数/箇所
1タイトル画面表示showTitleScreen()
2「スタート」押下 → ゲーム開始準備startGame()
3問題数/正答数/開始時刻のリセットstartGame()
4図形オブジェクト+正解カウント生成nextQuestion()
5Canvas上に図形を描画drawCanvasShapes()
6プレイヤー回答の入力受付checkAnswer()
7正誤判定 → フィードバックshowFeedback()
8問題数を超えたら終了画面へshowEndScreen()

関数・命令の詳細解説

関数名説明
showTitleScreen()タイトル&ルール欄をHTML生成し、クリックイベントを登録
startGame()問題番号と正答数を初期化し、最初の出題を行う
nextQuestion()図形オブジェクトの配列をランダム生成し、出題形状と正解数を決定する
renderGameScreen()問題文、Canvas領域、入力欄をHTMLにセット
drawCanvasShapes()Canvas APIで各図形をクリア→描画(drawCircle等を呼び出し)
drawCircle円を描画(ctx.arc + fill
drawTriangle三角形を描画(ctx.moveToctx.lineTofill
drawSquare四角形を描画(ctx.rectfill
checkAnswer()入力欄の値を取得・数値化し、answerCountと比較
showFeedback()正誤メッセージを一時的に表示 → 次の問題
showEndScreen()結果画面(正答数・タイム)をHTML生成し、「タイトルへ戻る」を登録

改造のポイント

  • 難易度調整QUESTION_CNT を増減、図形数レンジ(20〜25個)を変えると難易度に幅が出ます。
  • 図形追加SHAPES 配列に星形や五角形などを追加してバラエティアップ。
  • タイムアタック:各問題の制限時間を設け、選択肢を複数にしてクリック式にするなど改良可能。
  • ユーザーデータ保存localStorageでベストスコア&タイムを保存してリーダーボード化。
  • モバイル対応:キー入力の代わりにタップUIを用意すればタブレット・スマホでも遊びやすくなります。
  • エフェクト強化:正解時のアニメーションやサウンドを追加して盛り上げを。

以上を参考に、自分なりのアレンジを加え、オリジナルの「図形カウントクイズ」を作ってみてください!