【ゲーム】JavaScript:73 ちいかわクイズ


 「🌟 ちいかわクイズ 🐰」は、人気キャラクター“ちいかわ”たちに関する全30問のクイズからランダムに5問を出題する知識検定ゲームです。プレイヤーは4択の選択肢から正解を選び、最後に正解率を表示。効果音やかわいいデザインで楽しく学べます。

遊び方と操作方法

  1. スタートボタンをクリックしてゲーム開始。
  2. 第1問~第5問まで、画面中央に表示される問題文を確認。
  3. 4つの選択肢ボタンをクリックして回答。
  4. 回答後に「正解」/「不正解」のフィードバックと効果音が再生。
  5. つぎの問題ボタンで次問へ進み、5問終了後に結果画面へ移行。
  6. 結果画面で正解率と正解数を確認し、タイトル画面に戻るで再挑戦可能。

ルール

  • 出題は全30問からランダムに5問抽出。
  • 各問題につき1回のみ回答可能。
  • 正解時には correct-sound、不正解時には incorrect-sound を再生。
  • 終了後、正解率(%)および正解数/問題数を表示。

🎮ゲームプレイ

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

73 ちいかわクイズ

素材のダウンロード

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

効果音:魔王魂

chiikawa_quiz_title.pngchiikawa_quiz_bg.png

ゲーム画面イメージ

プログラム全体(chiikawa_quiz.html)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=800">
  <title>🌟 ちいかわクイズ 🐰</title>
  <style>
    /* ===== スクロールバー非表示 ===== */
    html, body {
      overflow: auto;
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    body {
      background: url('chiikawa_quiz_bg.png') center/cover no-repeat;
      min-height: 100vh;
      font-family: 'BIZ UDPGothic', 'Rounded Mplus 1c', 'Arial', sans-serif;
      color: #463b2b;
      display: flex; justify-content: center; align-items: center;
    }
    #quiz-container {
      width: 800px; max-width: 98vw;
      min-height: 520px;
      background: rgba(255, 255, 245, 0.92);
      border: 5px solid #ffe8ad;
      border-radius: 34px;
      box-shadow: 0 0 36px #f8deb3a0;
      padding: 34px 42px 34px 42px;
      box-sizing: border-box;
      text-align: center;
      position: relative;
      z-index: 2;
      margin: 40px 0;
    }
    h1 {
      font-size: 2.5rem;
      letter-spacing: 2px;
      margin-bottom: 16px;
      color: #ffbe78;
      text-shadow: 2px 3px 10px #fffbe0, 1px 1px 2px #ffc;
      font-family: 'BIZ UDPGothic', 'Rounded Mplus 1c', 'Arial', sans-serif;
    }
    /* タイトル画像 */
    #title-screen img {
      display: block;
      margin: 0 auto 16px auto;
      max-width: 60%;
      height: auto;
      border-radius: 16px;
      box-shadow: 0 2px 14px #f8b07b40;
      border: 2px solid #ffe1c2;
      background: #fffbed;
    }
    /* ルール説明 */
    .rules-title {
      text-align: center;
      font-weight: bold;
      font-size: 1.3rem;
      color: #fff;
      background: linear-gradient(90deg, #ffdc9a 65%, #ffeac0 100%);
      border-radius: 13px;
      margin-top: 15px;
      margin-bottom: 7px;
      letter-spacing: 1.2px;
      text-shadow: 1px 1px 5px #fbeec9;
      padding: 7px 0 7px 0;
    }
    .rules-body {
      text-align: left;
      margin: 0 10px 18px 10px;
      font-size: 1.1rem;
      line-height: 1.8;
      color: #4b390f;
      background: #fff9e3bb;
      border-radius: 8px;
      padding: 13px 20px 13px 18px;
      box-shadow: 0 0 8px #ffefb570;
    }
    /* ボタン共通 */
    button {
      padding: 12px 42px;
      font-size: 1.19rem;
      border-radius: 18px;
      border: 2.5px solid #ffcd90;
      margin: 19px 10px 0 10px;
      background: linear-gradient(90deg, #ffecd6 70%, #ffe1b0 100%);
      color: #8b6b35;
      font-weight: bold;
      cursor: pointer;
      box-shadow: 1px 3px 8px #ffdca860;
      transition: background 0.2s, transform 0.08s;
      outline: none;
    }
    button:active, button:focus {
      outline: 2.5px solid #ffdc9a;
    }
    button:hover {
      background: linear-gradient(90deg, #fff7e2 80%, #ffefc7 100%);
      transform: scale(1.04);
      color: #d9a34d;
    }
    /* 選択肢ボタン */
    #choices-container button {
      background: linear-gradient(90deg, #fff5d6 80%, #ffe4be 100%);
      margin: 8px 0;
      font-size: 1.13rem;
      border-radius: 18px;
      border: 2px solid #ffdca1;
      box-shadow: 0 1px 5px #ffedb670;
      color: #7b540b;
      text-shadow: 1px 1px 2px #fffbe8;
      /* ▼ 追加: 幅を揃えて親の90%、最小・最大幅指定 */
      width: 90%;
      max-width: 680px;
      min-width: 220px;
      display: block;
      margin-left: auto;
      margin-right: auto;
    }
    #choices-container button:hover {
      background: linear-gradient(90deg, #fff8e7 100%, #fff4c7 100%);
      color: #bb7b1e;
    }
    /* 画面切り替え */
    #title-screen, #game-screen, #result-screen {
      display: none;
    }
    #title-screen.active, #game-screen.active, #result-screen.active {
      display: block;
    }
    /* ゲーム本体画面 */
    #question-number {
      font-size: 1.17rem;
      margin-bottom: 6px;
      color: #f0b749;
      font-weight: bold;
    }
    #question-text {
      font-size: 1.45rem;
      margin: 22px 0 20px 0;
      letter-spacing: 1.2px;
    }
    #choices-container {
      display: flex; flex-direction: column;
      gap: 9px; margin-bottom: 16px;
      align-items: center;
    }
    #feedback {
      font-size: 1.20rem;
      font-weight: bold;
      background: linear-gradient(90deg, #ffeac3bb 80%, #ffefdbbb 100%);
      border-radius: 11px;
      padding: 12px 0;
      min-height: 36px;
      margin-bottom: 15px;
      color: #eb8937;
      border: 2px solid #ffdca1;
      display: none;
      text-shadow: 1px 1px 4px #fffbe0, 0 1px #ffeac1;
    }
    /* 結果画面 */
    #result-message {
      font-size: 1.45rem;
      color: #fdc465;
      font-weight: bold;
      margin: 46px 0 28px 0;
      text-shadow: 2px 2px 7px #ffe6b7, 1px 1px 3px #fffad5a0;
    }
    #return-button {
      display: block;
      margin: 0 auto;
      background: linear-gradient(90deg, #ffeac0 90%, #ffefa9 100%);
      font-size: 1.17rem;
      color: #865d2c;
      font-weight: bold;
      border: 2.5px solid #ffe0a2;
      box-shadow: 0 1px 8px #fff5c270;
    }
    #return-button:hover {
      background: linear-gradient(90deg, #fff6e5 100%, #fffbe2 100%);
      color: #b18a39;
    }
    @media (max-width:830px) {
      #quiz-container { width: 99vw; padding: 8px 2vw; min-width: 0;}
      h1 { font-size: 1.5rem; }
      #choices-container button { max-width: 99vw; }
    }
  </style>
</head>
<body>
  <div id="quiz-container">
    <h1>🌟 ちいかわクイズ 🐰</h1>
    <!-- タイトル画面 -->
    <div id="title-screen" class="active">
      <img src="chiikawa_quiz_title.png" alt="ちいかわクイズ タイトル画像">
      <div class="rules-title">🎀 ルール説明 🎀</div>
      <div class="rules-body">
        ・「ちいかわ」に関するクイズが全30問あります。<br>
        ・4つの選択肢から正しい答えを1つ選んでください。<br>
        ・<b>毎回ランダムで5問が出題されます!</b><br>
        ・終了時に正解率が表示されます。<br>
        ・正解・不正解で音が鳴るよ。<br>
        ・メッセージや問題は全て日本語です。<br>
        ・やさしい気持ちで楽しんでね!<br>
      </div>
      <button id="start-button">🍯 スタート!</button>
    </div>
    <!-- ゲーム画面 -->
    <div id="game-screen">
      <div id="question-number"></div>
      <div id="question-text"></div>
      <div id="choices-container"></div>
      <div id="feedback"></div>
      <button id="next-button" style="display:none;">つぎの問題 ➡️</button>
    </div>
    <!-- 結果画面 -->
    <div id="result-screen">
      <div id="result-message"></div>
      <button id="return-button" style="display:none;">🏠 タイトル画面に戻る</button>
    </div>
  </div>
  <!-- 効果音 -->
  <audio id="correct-sound" src="maoudamashii-quiz_correct.mp3"></audio>
  <audio id="incorrect-sound" src="maoudamashii-quiz_incorrect.mp3"></audio>

  <script>
  window.onload = function() {
    // ================== ちいかわクイズ30問 ==================
    const questions = [
      {q: "ちいかわの好物は?",choices: ["プリン", "草むしりの報酬", "チョコ", "ラーメン"],answer: "草むしりの報酬"},
      {q: "うさぎの口ぐせは?",choices: ["ヤハ", "フッ", "ウフフ", "パワー"],answer: "ヤハ"},
      {q: "ちいかわの体色は?",choices: ["白", "ピンク", "灰色", "茶色"],answer: "白"},
      {q: "ハチワレの好きな食べ物は?",choices: ["おにぎり", "ハンバーグ", "サンドイッチ", "うどん"],answer: "おにぎり"},
      {q: "うさぎの耳はどんな形?",choices: ["長くて立っている", "丸い", "折れている", "短い"],answer: "長くて立っている"},
      {q: "くりまんじゅうの好きなお酒は?",choices: ["日本酒", "ビール", "ワイン", "焼酎"],answer: "ビール"},
      {q: "モモンガがよく言う言葉は?",choices: ["うっきー!", "キャハッ", "プルル", "アハハ"],answer: "キャハッ"},
      {q: "ハチワレの特徴は?",choices: ["額が八の字", "黒い斑点", "青いリボン", "赤い鼻"],answer: "額が八の字"},
      {q: "ラッコの得意なことは?",choices: ["道具作り", "歌", "走ること", "ダンス"],answer: "道具作り"},
      {q: "うさぎの性格は?",choices: ["元気で自由", "大人しい", "しっかり者", "臆病"],answer: "元気で自由"},
      {q: "ちいかわがよく泣く理由は?",choices: ["怖がり", "痛いから", "うれしいから", "怒られて"],answer: "怖がり"},
      {q: "ハチワレの声優は?",choices: ["田中誠人", "小澤亜李", "青木遥", "内田真礼"],answer: "田中誠人"},
      {q: "くりまんじゅうの特徴は?",choices: ["大きな体", "背が低い", "赤い服", "ヒゲ"],answer: "大きな体"},
      {q: "ちいかわの趣味は?",choices: ["草むしり", "ダンス", "読書", "料理"],answer: "草むしり"},
      {q: "ハチワレがやってみたいことは?",choices: ["大きな家に住む", "バク転", "アイドル", "宇宙旅行"],answer: "バク転"},
      {q: "ちいかわの鳴き声は?",choices: ["ぴえん", "にゃー", "わん", "ぺん"],answer: "ぴえん"},
      {q: "うさぎの好きな遊びは?",choices: ["ドッヂボール", "かけっこ", "縄跳び", "かくれんぼ"],answer: "ドッヂボール"},
      {q: "ハチワレの好きな色は?",choices: ["青", "赤", "緑", "黄"],answer: "青"},
      {q: "ちいかわが苦手なものは?",choices: ["モンスター", "高いところ", "水", "虫"],answer: "モンスター"},
      {q: "うさぎの体色は?",choices: ["ピンク", "白", "グレー", "オレンジ"],answer: "白"},
      {q: "ハチワレの性格は?",choices: ["前向き", "おくびょう", "怒りっぽい", "まじめ"],answer: "前向き"},
      {q: "くりまんじゅうがよく食べているものは?",choices: ["おでん", "焼きそば", "ピザ", "からあげ"],answer: "おでん"},
      {q: "モモンガの性格は?",choices: ["甘えん坊", "おとなしい", "しっかり者", "怖がり"],answer: "甘えん坊"},
      {q: "ラッコの特技は?",choices: ["道具作り", "ジャンプ", "絵", "ピアノ"],answer: "道具作り"},
      {q: "くりまんじゅうの好きな場所は?",choices: ["居酒屋", "公園", "川辺", "カフェ"],answer: "居酒屋"},
      {q: "ちいかわたちが住む世界は?",choices: ["草原", "海辺", "町", "山"],answer: "草原"},
      {q: "うさぎの好きな言葉は?",choices: ["ヤハ", "ウフフ", "アハ", "ワハ"],answer: "ヤハ"},
      {q: "ハチワレの特技は?",choices: ["前向き", "草むしり", "歌", "泳ぐ"],answer: "前向き"},
      {q: "ちいかわの口ぐせは?",choices: ["ぴえん", "ふぇ", "にゃ", "うぅ"],answer: "ぴえん"},
      {q: "ラッコの好きな食べ物は?",choices: ["貝", "ピザ", "たこ焼き", "ラーメン"],answer: "貝"},
    ];
    let quizList = [];
    let currentQuestion = 0;
    let correctCount = 0;

    // ===== DOM要素の取得 =====
    const titleScreen  = document.getElementById('title-screen');
    const gameScreen   = document.getElementById('game-screen');
    const resultScreen = document.getElementById('result-screen');
    const startBtn     = document.getElementById('start-button');
    const questionNum  = document.getElementById('question-number');
    const questionText = document.getElementById('question-text');
    const choicesBox   = document.getElementById('choices-container');
    const feedback     = document.getElementById('feedback');
    const nextBtn      = document.getElementById('next-button');
    const resultMsg    = document.getElementById('result-message');
    const returnBtn    = document.getElementById('return-button');
    const correctSE    = document.getElementById('correct-sound');
    const incorrectSE  = document.getElementById('incorrect-sound');

    // ===== シャッフル関数 =====
    function shuffle(array) {
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
      }
    }

    // ===== ゲーム開始 =====
    function startGame() {
      quizList = [...questions];
      shuffle(quizList);
      quizList = quizList.slice(0, 5);  // 5問抽出
      currentQuestion = 0;
      correctCount = 0;
      titleScreen.classList.remove('active');
      resultScreen.classList.remove('active');
      gameScreen.classList.add('active');
      showQuestion();
    }

    // ===== 問題表示 =====
    function showQuestion() {
      let qData = quizList[currentQuestion];
      questionNum.textContent = `第${currentQuestion + 1}問 / 5`;
      questionText.textContent = qData.q;
      let choices = [...qData.choices];
      shuffle(choices);
      choicesBox.innerHTML = '';
      choices.forEach(choice => {
        let btn = document.createElement('button');
        btn.textContent = choice;
        btn.onclick = () => selectAnswer(choice, qData.answer);
        choicesBox.appendChild(btn);
      });
      feedback.style.display = "none";
      feedback.textContent = '';
      nextBtn.style.display = 'none';
    }

    // ===== 回答選択処理 =====
    function selectAnswer(selected, correct) {
      document.querySelectorAll('#choices-container button').forEach(b=>b.disabled=true);
      if (selected === correct) {
        feedback.textContent = "🌸 正解だよ!えらい!";
        correctCount++;
        if(correctSE) { correctSE.currentTime = 0; correctSE.play(); }
      } else {
        feedback.textContent = `💦 不正解… 正解は「${correct}」だよ`;
        if(incorrectSE) { incorrectSE.currentTime = 0; incorrectSE.play(); }
      }
      feedback.style.display = "block";
      nextBtn.style.display = "inline-block";
    }

    // ===== 次の問題へ =====
    function nextQuestion() {
      currentQuestion++;
      if (currentQuestion < quizList.length) {
        showQuestion();
      } else {
        endGame();
      }
    }

    // ===== 終了画面 =====
    function endGame() {
      gameScreen.classList.remove('active');
      resultScreen.classList.add('active');
      let rate = Math.round((correctCount / quizList.length) * 100);
      resultMsg.innerHTML =
        `✨ クイズ終了!あなたの正解率は <span style="color:#ffbe78">${rate}%</span> だよ!<br>` +
        `(${correctCount} / ${quizList.length}問)<br><br>` +
        "おつかれさま!また挑戦してね🐰";
      returnBtn.style.display = 'block';
    }

    // ===== タイトルに戻る =====
    function toTitle() {
      resultScreen.classList.remove('active');
      titleScreen.classList.add('active');
      returnBtn.style.display = 'none';
    }

    // ===== イベント登録 =====
    startBtn.addEventListener('click', startGame);
    nextBtn.addEventListener('click', nextQuestion);
    returnBtn.addEventListener('click', toTitle);

    // ===== 初期画面表示 =====
    titleScreen.classList.add('active');
    gameScreen.classList.remove('active');
    resultScreen.classList.remove('active');
  }
  </script>
</body>
</html>

アルゴリズムの流れ

ステップ内容関連関数
1. データ準備全30問の問題配列 questions を定義
2. シャッフル配列をランダム順に入れ替えshuffle(array)
3. 問題抽出上位5要素を quizList に格納spliceslice
4. タイトル→開始タイトル画面非表示、ゲーム画面表示、変数初期化startGame()
5. 問題表示現在の問題を画面に描画、選択肢を動的に生成showQuestion()
6. 回答判定選択したボタンのテキストと正解比較、フィードバック表示selectAnswer()
7. 音声再生正誤に応じた correctSE.play() / incorrectSE.play() 再生
8. 次問 or 終了5問未満なら次問、5問終了時は結果画面へnextQuestion(), endGame()
9. 結果表示正解率と正解数を計算し、結果メッセージを整形表示endGame()
10. タイトル復帰タイトル画面に戻るtoTitle()

関数の解説

関数名引数戻り値内容
shuffle(array)array (配列)なしFisher–Yates法で配列をインプレースシャッフル。
startGame()なしなし問題リスト生成、画面切替、変数初期化、最初の問題表示。
showQuestion()なしなし現在の質問情報をDOMに反映。選択肢ボタンを動的生成しクリックイベント付与。
selectAnswer(sel, ans)sel (選択文字列), ans (正解文字列)なし選択と正解の比較、フィードバック/効果音処理、次へボタン表示。
nextQuestion()なしなし問題番号インクリメント。次問 or 結果画面判定。
endGame()なしなし正解率計算、結果テキスト生成、画面切替。
toTitle()なしなし結果画面非表示、タイトル画面表示。

改造のポイント

  • 問題数や抽出数の変更questions の要素数や slice(0,5) の数字を調整可能。
  • UIカスタマイズ: CSS でボタン色やフォントを変更し、オリジナルデザインに。
  • 効果音の差し替えcorrect-sound, incorrect-sound の src 属性を別音源に差し替え。
  • 多言語対応: 問題文やボタン文言をオブジェクト化し、言語切替機能を実装。
  • 問題追加・カテゴリー分け: 問題データ構造を {q,choices,answer,category} として拡張し、回によってカテゴリを絞り込む機能を追加。

アドバイス
 まずは問題数や選択肢の数を少し変えて動作を確認し、その後に音声ファイルや画面演出を追加するとステップごとに機能を把握しやすくなります。