【ゲーム】JavaScript:42 ジョジョクイズ

 「💎 ジョジョクイズ ✨」は、『ジョジョの奇妙な冒険』に関する知識を4択で楽しみながら試せるクイズゲームです。全30問の中から毎回10問がランダムに出題され、正答率を競います。
アニメや原作ファンはもちろん、作品に興味がある人も気軽に楽しめる内容となっています。

遊び方・操作方法

手順内容
1. ゲーム開始「スタートだッ!」ボタンをクリックするとクイズスタート
2. 問題解答各問題ごとに4つの選択肢が表示され、好きな答えをクリック
3. 判定表示正解/不正解はその場で表示され、正答も表示される
4. 次の問題「次の問題 ➡️」ボタンで次のクイズへ(全10問繰り返し)
5. 終了&再挑戦10問終了後に正答率・正解数を確認、「タイトル画面に戻る」でいつでも再挑戦可

ルール

ルール項目内容
問題数全30問から毎回10問をランダム出題
選択肢各問題ごとに4つの選択肢を表示
解答方式選択肢ボタンをクリックするだけ
判定・正答表示正解/不正解&正答表示(セリフや演出も「ジョジョ」風)
終了と正答率10問終了時点で正答率・正解数表示。好きなだけ何度でも再挑戦可能

🎮ゲームプレイ

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

42 ジョジョクイズ

素材のダウンロード

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

効果音:魔王魂

jojo_quiz_title.pngjojo_quiz_bg.png

ゲーム画面イメージ

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

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=700">
  <title>💎 ジョジョクイズ ✨</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: 'Arial Black', 'BIZ UDPGothic', 'Arial', sans-serif;
      background-image: url('jojo_quiz_bg.png');
      background-size: cover;
      background-position: center;
      min-height: 100vh;
      color: #FFF8DC;
      display: flex; justify-content: center; align-items: center;
    }
    #quiz-container {
      background: linear-gradient(135deg, rgba(50,0,100,0.88) 75%, rgba(255,215,0,0.25) 100%);
      border: 5px solid #9B59B6;
      border-radius: 22px;
      width: 700px; max-width: 96vw;
      min-height: 540px;
      padding: 30px 40px 30px 40px;
      box-shadow: 0 0 28px 4px #32185d;
      text-align: center;
      position: relative;
      z-index: 1;
    }
    h1 {
      font-size: 2.5rem;
      color: #FFD700;
      margin-bottom: 16px;
      letter-spacing: 3px;
      text-shadow: 3px 3px 10px #8d44ad, 1px 1px 2px #000;
      font-family: 'Arial Black','BIZ UDPGothic', 'Arial', sans-serif;
    }
    #title-screen img {
      display: block;
      margin: 0 auto 16px auto;
      max-width: 72%;
      height: auto;
      border-radius: 14px;
      box-shadow: 0 4px 18px #322;
      border: 2px solid #FFD700;
    }
    .rules-title {
      text-align: center;
      font-weight: bold;
      font-size: 1.4rem;
      color: #FFD700;
      margin-top: 15px;
      text-shadow: 1px 1px 7px #8d44ad;
      letter-spacing: 1.5px;
    }
    .rules-body {
      text-align: left;
      margin: 0 10px 16px 10px;
      font-size: 1.12rem;
      line-height: 1.75;
      color: #FFF8DC;
      text-shadow: 0 1px 3px #32185d;
    }
    button {
      padding: 11px 38px;
      font-size: 1.18rem;
      border-radius: 8px;
      border: 2.5px solid #FFD700;
      margin: 15px 10px 0 10px;
      background: linear-gradient(90deg, #7D3C98 70%, #FFD700 100%);
      color: #fff;
      font-weight: bold;
      cursor: pointer;
      box-shadow: 1px 2px 5px #32185d;
      transition: background 0.2s, transform 0.1s;
    }
    button:hover {
      background: linear-gradient(90deg, #5B2C6F 75%, #F7DC6F 100%);
      transform: scale(1.03);
    }
    #choices-container button {
      background: linear-gradient(90deg, #884EA0 75%, #FFD700 100%);
      margin: 7px 0;
      font-size: 1.13rem;
      border-radius: 8px;
      border: 2px solid #FFD700;
      box-shadow: 0 1px 3px #32185d;
      color: #fff;
      font-weight: bold;
      text-shadow: 1px 1px 2px #000;
    }
    #choices-container button:hover {
      background: linear-gradient(90deg, #5B2C6F 80%, #F7DC6F 100%);
      color: #ffd;
    }
    #title-screen, #game-screen, #result-screen {
      display: none;
    }
    #title-screen.active, #game-screen.active, #result-screen.active {
      display: block;
    }
    #question-number { font-size: 1.18rem; margin-bottom: 6px; color: #FFD700; font-weight: bold; }
    #question-text { font-size: 1.5rem; margin: 22px 0 20px 0; letter-spacing: 1.5px;}
    #choices-container {
      display: flex; flex-direction: column;
      gap: 9px; margin-bottom: 20px;
    }
    #feedback {
      font-size: 1.28rem;
      font-weight: bold;
      background: linear-gradient(90deg, #8d44ad70 80%, #FFD70050 100%);
      border-radius: 9px;
      padding: 12px;
      min-height: 36px;
      margin-bottom: 13px;
      color: #FFD700;
      text-shadow: 1px 1px 4px #32185d, 0 1px #fff8;
      border: 2px solid #FFD700;
      display: none; /* ← 追加:最初は非表示 */
    }
    #result-message {
      font-size: 1.5rem;
      color: #FFD700;
      font-weight: bold;
      margin: 50px 0 25px 0;
      text-shadow: 2px 2px 8px #8d44ad, 1px 1px 3px #000a;
    }
    #return-button {
      display: block;
      margin: 0 auto;
      background: linear-gradient(90deg, #6C3483 80%, #FFD700 100%);
      font-size: 1.16rem;
      color: #fff;
      font-weight: bold;
      border: 2.5px solid #FFD700;
      box-shadow: 0 1px 6px #32185d;
    }
    #return-button:hover { background: linear-gradient(90deg, #5B2C6F 80%, #F7DC6F 100%); color: #ffd; }
    @media (max-width:780px) {
      #quiz-container { padding: 8px 3vw; min-width: 0; width: 99vw;}
      h1 { font-size: 1.7rem; }
    }
  </style>
</head>
<body>
  <div id="quiz-container">
    <h1>💎 ジョジョクイズ ✨</h1>
    <!-- タイトル画面 -->
    <div id="title-screen" class="active">
      <img src="jojo_quiz_title.png" alt="ジョジョクイズ タイトル画像">
      <div class="rules-title">🕶️ ルール説明 🕶️</div>
      <div class="rules-body">
        ・「ジョジョの奇妙な冒険」に関するクイズが全30問用意されています。<br>
        ・4つの選択肢から正しい答えを1つ選んでください。<br>
        ・<b>毎回ランダムで10問が出題されます!</b><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: "第3部の舞台はどこ?",choices: ["日本", "エジプト", "イタリア", "イギリス"],answer: "エジプト"},
      {q: "ジョセフ・ジョースターの名台詞は?",choices: ["だが断る", "やれやれだぜ", "波紋カッター", "『逃げるんだよォ!』"],answer: "『逃げるんだよォ!』"},
      {q: "東方仗助の髪型をけなしたらどうなる?",choices: ["許さない", "笑う", "泣く", "怒らない"],answer: "許さない"},
      {q: "第4部の舞台は?",choices: ["杜王町", "ロンドン", "カイロ", "ローマ"],answer: "杜王町"},
      {q: "吉良吉影の趣味は?",choices: ["サッカー", "殺人", "手の爪を切る", "手の美しさを愛でる"],answer: "手の美しさを愛でる"},
      {q: "岸辺露伴の職業は?",choices: ["画家", "医者", "漫画家", "教師"],answer: "漫画家"},
      {q: "ブチャラティのスタンド名は?",choices: ["スティッキィ・フィンガーズ", "ゴールド・エクスペリエンス", "キラークイーン", "キング・クリムゾン"],answer: "スティッキィ・フィンガーズ"},
      {q: "第5部の主人公の名前は?",choices: ["空条承太郎", "ジョルノ・ジョバァーナ", "ジョニー・ジョースター", "ジョセフ・ジョースター"],answer: "ジョルノ・ジョバァーナ"},
      {q: "ジョルノの夢は?",choices: ["ギャングスターになる", "金持ちになる", "王になる", "平和に暮らす"],answer: "ギャングスターになる"},
      {q: "パンナコッタ・フーゴのスタンドは?",choices: ["パープル・ヘイズ", "ホワイト・アルバム", "スパイス・ガール", "エアロスミス"],answer: "パープル・ヘイズ"},
      {q: "DIOが使う時を止めるスタンドの能力名は?",choices: ["キング・クリムゾン", "ザ・ワールド", "エコーズ", "シルバー・チャリオッツ"],answer: "ザ・ワールド"},
      {q: "ジョルノの父親は?",choices: ["ディオ", "ジョセフ", "ジョナサン", "カーズ"],answer: "ディオ"},
      {q: "第6部の舞台となる刑務所の名前は?",choices: ["グリーン・ドルフィン・ストリート刑務所", "ストーンフリー刑務所", "杜王刑務所", "ジョースター邸"],answer: "グリーン・ドルフィン・ストリート刑務所"},
      {q: "空条徐倫の母親の名前は?",choices: ["ホリー", "スージーQ", "エルメェス", "不明"],answer: "不明"},
      {q: "ウェザー・リポートの本名は?",choices: ["エンポリオ", "プッチ", "ドメニコ・プッチ", "ドメニコ・ヴェルサス"],answer: "ドメニコ・プッチ"},
      {q: "スティール・ボール・ランの舞台は?",choices: ["イギリス", "アメリカ", "イタリア", "日本"],answer: "アメリカ"},
      {q: "第7部の主人公ジョニーの苗字は?",choices: ["ジョースター", "ブランドー", "ジョバァーナ", "クジョウ"],answer: "ジョースター"},
      {q: "大統領ファニー・バレンタインのスタンド名は?",choices: ["ラブトレイン", "ザ・ワールド", "タスク", "D4C"],answer: "D4C"},
      {q: "第8部の主人公の愛称は?",choices: ["ジョウスケ", "ジョルノ", "ジョジョ", "ジョニー"],answer: "ジョウスケ"},
      {q: "東方定助のスタンドは?",choices: ["ナット・キング・コール", "ソフト&ウェット", "ラブ・デラックス", "パイズリー・パーク"],answer: "ソフト&ウェット"},
      {q: "第8部の舞台は?",choices: ["杜王町", "エジプト", "イギリス", "カイロ"],answer: "杜王町"},
      {q: "「メメタァ」という効果音が登場するのはどの部?",choices: ["1部", "2部", "3部", "4部"],answer: "1部"},
      {q: "ジョセフが修得した特殊能力は?",choices: ["波紋", "スタンド", "石仮面", "吸血"],answer: "波紋"},
      {q: "『だが断る』のセリフを言ったキャラは?",choices: ["東方仗助", "岸辺露伴", "空条承太郎", "ジョルノ・ジョバァーナ"],answer: "岸辺露伴"},
      {q: "花京院典明のスタンドは?",choices: ["ハイエロファントグリーン", "シルバー・チャリオッツ", "ザ・ワールド", "スタープラチナ"],answer: "ハイエロファントグリーン"},
      {q: "『ロードローラーだッ!』のセリフを叫んだのは?",choices: ["DIO", "ジョセフ", "ポルナレフ", "ジョルノ"],answer: "DIO"},
      {q: "スタープラチナの能力は?",choices: ["時を止める", "空間を操る", "物を治す", "心を読む"],answer: "時を止める"},
      {q: "ジョースター家に伝わる特徴的な体の模様は?",choices: ["星型のアザ", "涙ぼくろ", "縞模様", "Sマーク"],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, 10); // 10問だけ出題
      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}問 / 10`;
      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 = "✨ 正解ッ! これが『黄金の精神』だッ!";
        correctSE && correctSE.play();
        correctCount++;
      } else {
        feedback.textContent = `💀 不正解… 正解は「${correct}」だッ!`;
        incorrectSE && 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:#FFD700">${rate}%</span> だッ!<br>` +
        `(${correctCount} / ${quizList.length}問)`;
      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>

アルゴリズムの流れ

ステップ内容
① タイトル表示ルール・画像と「スタートだッ!」ボタンを表示
② ゲーム開始30問の中から10問をランダムで選出、初期化
③ 問題表示問題文・選択肢(シャッフル)を表示、回答ボタン生成
④ 回答選択選択肢クリックで正誤判定・即時メッセージ&正答表示、ボタンは無効化
⑤ 次の問題「次の問題 ➡️」ボタンで次のクイズへ(10問まで繰り返し)
⑥ 結果表示正答率・正解数を表示。「タイトル画面に戻る」ボタンで初期画面へ

主要な関数・命令の詳細解説

関数名役割・内容
shuffle(array)配列をFisher-Yatesアルゴリズムでランダムシャッフル(問題・選択肢順ランダム化に利用)
startGame()クイズリスト初期化、ランダム10問抽出、カウンタ初期化&画面遷移、showQuestion()呼出し
showQuestion()問題番号・本文・選択肢(ランダム)を描画、選択肢ボタン生成
selectAnswer(selected, correct)選択肢判定(正誤)、効果音再生、ボタン無効化、正答やメッセージ表示
nextQuestion()次の問題 or 終了画面遷移(endGame()呼出し)
endGame()ゲーム画面→結果画面遷移、正答率と正解数表示、再挑戦ボタン表示
toTitle()タイトル画面へ戻す(状態リセット)

関数の詳細解説

関数名具体的な処理内容
shuffle配列要素の順序をランダムに並べ替える。問題・選択肢を毎回異なる順に出題
startGame問題をシャッフルし10問に絞り込み、正解カウントや状態を初期化してクイズ開始
showQuestion現在の問題文・選択肢を画面描画、選択肢ボタンのonclickを設定
selectAnswer回答選択時、正誤判定・フィードバックメッセージ・効果音、次ボタン表示、選択肢無効化
nextQuestion問題インデックス進める→残りがあれば出題、なければendGame
endGameゲーム画面→結果画面切替、正答率・点数計算と表示、再挑戦ボタン出現
toTitle結果画面→タイトル画面へリセット

改造のポイント

ポイント解説
問題数や選択肢の追加questions配列を編集するだけで、簡単に出題内容・バリエーションを増やせます
サウンド・演出強化効果音や画像・アニメーション追加で臨場感UP
難易度選択問題の難易度タグ付け→出題難易度をユーザー選択で切り替えも可能
スコアランキングローカルストレージでランキング保存・表示を実装可能
タイムアタック回答制限時間や残り時間表示機能の追加
ヒント・解説の追加各問題に豆知識や解説文も表示できる
多言語化questionsデータを多言語切り替え対応でグローバル展開も

アドバイス

  • データ構造がシンプルなので、問題・画像・効果音の差し替えや新テーマのクイズ化も容易です。
  • 配列シャッフル・画面遷移・イベント管理のロジックはWebクイズの基本形!教材や練習用にもおすすめ。
  • 原作ファンに刺さる演出やセリフ追加で盛り上げるも良し。UI/UXやスマホ対応なども伸ばしやすいです。
  • JavaScript初学者にも改造・学習しやすい良サンプル。コードを触って自分好みのクイズにしてみましょう!