【ゲーム】JavaScript:43 ワンピースクイズ

 「🏴‍☠️ ワンピースクイズ」は、『ONE PIECE』の物語やキャラクターにまつわる知識を4択形式で楽しめるクイズゲームです。全30問の中からランダムで毎回10問が出題され、正答率を競う内容となっています。ワンピース好きはもちろん、作品をまだ読んだことのない方でも直感的に遊べます。

遊び方・操作方法

ステップ操作内容
1. ゲーム開始タイトル画面の「🏴‍☠️ スタート!」ボタンをクリック
2. 問題に答える各問題ごとに4つの選択肢が表示されるので、正解と思うボタンをクリック
3. 判定表示正解・不正解&正答が即座に表示
4. 次の問題「次の問題 ➡️」ボタンで次へ(全10問繰り返し)
5. 結果発表10問終了後、正答率と正解数が表示され「タイトル画面に戻る」ボタンで再挑戦可

ゲームのルール

ルール内容
問題数全30問から毎回10問をランダム出題
回答方式各問題ごとに4択ボタンをクリック
判定・解答表示回答後すぐに「正解」または「不正解」と正解が表示
結果発表10問終了時に正答率・正解数表示。何度でも再チャレンジできる
表示言語すべて日本語

🎮ゲームプレイ

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

43 ワンピースクイズ

素材のダウンロード

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

効果音:魔王魂

one_piece_quiz_title.pngjone_piece_quiz_bg.png

ゲーム画面イメージ

プログラム全体(one_piece_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('one_piece_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(0,40,80,0.85) 80%, rgba(255,215,0,0.13) 100%);
      border: 5px solid #FFD700;
      border-radius: 22px;
      width: 700px; max-width: 96vw;
      min-height: 540px;
      padding: 30px 40px 30px 40px;
      box-shadow: 0 0 28px 4px #083668;
      text-align: center;
      position: relative;
      z-index: 1;
    }
    h1 {
      font-size: 2.5rem;
      color: #FFD700;
      margin-bottom: 16px;
      letter-spacing: 3px;
      text-shadow: 2px 2px 8px #042f57, 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 #042f57;
      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 #042f57;
      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 #083668;
    }
    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, #155589 70%, #FFD700 100%);
      color: #fff;
      font-weight: bold;
      cursor: pointer;
      box-shadow: 1px 2px 5px #042f57;
      transition: background 0.2s, transform 0.1s;
    }
    button:hover {
      background: linear-gradient(90deg, #07345e 80%, #F7DC6F 100%);
      color: #FFD700;
      transform: scale(1.03);
    }
    #choices-container button {
      background: linear-gradient(90deg, #2578b8 75%, #FFD700 100%);
      margin: 7px 0;
      font-size: 1.13rem;
      border-radius: 8px;
      border: 2px solid #FFD700;
      box-shadow: 0 1px 3px #083668;
      color: #fff;
      font-weight: bold;
      text-shadow: 1px 1px 2px #000;
    }
    #choices-container button:hover {
      background: linear-gradient(90deg, #07345e 80%, #F7DC6F 100%);
      color: #FFD700;
    }
    #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, #042f57a0 80%, #FFD70050 100%);
      border-radius: 9px;
      padding: 12px;
      min-height: 36px;
      margin-bottom: 13px;
      color: #FFD700;
      text-shadow: 1px 1px 4px #083668, 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 #042f57, 1px 1px 3px #000a;
    }
    #return-button {
      display: block;
      margin: 0 auto;
      background: linear-gradient(90deg, #155589 80%, #FFD700 100%);
      font-size: 1.16rem;
      color: #fff;
      font-weight: bold;
      border: 2.5px solid #FFD700;
      box-shadow: 0 1px 6px #083668;
    }
    #return-button:hover { background: linear-gradient(90deg, #07345e 80%, #F7DC6F 100%); color: #FFD700; }
    @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="one_piece_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>
    <!-- 効果音 -->
    <audio id="correct-sound" src="maoudamashii-quiz_correct.mp3"></audio>
    <audio id="incorrect-sound" src="maoudamashii-quiz_incorrect.mp3"></audio>
  </div>
  <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: ["モンキー・D・ドラゴン", "ガープ", "サボ", "シャンクス"], answer: "モンキー・D・ドラゴン"},
      {q: "エースの本名は?", choices: ["ポートガス・D・エース", "ゴール・D・エース", "モンキー・D・エース", "エドワード・D・エース"], answer: "ポートガス・D・エース"},
      {q: "ルフィの“D”の意味は?", choices: ["意志", "運命", "夢", "友情"], answer: "意志"},
      {q: "ゾロの目は現在どちらが閉じている?", choices: ["左目", "右目", "両目", "どちらも開いている"], answer: "左目"},
      {q: "ワンピースが眠るとされる場所は?", choices: ["ラフテル", "マリージョア", "アラバスタ", "ドレスローザ"], answer: "ラフテル"},
      {q: "ナミの恩人であり養母の名前は?", choices: ["ベルメール", "ココロ", "オルガ", "ダダン"], answer: "ベルメール"},
      {q: "“ひとつなぎの大秘宝”の英語名は?", choices: ["One Piece", "Treasure", "Grand Line", "Gold Roger"], answer: "One Piece"},
      {q: "サンジの家族名は?", choices: ["ヴィンスモーク", "モンキー", "ドンキホーテ", "シャーロット"], answer: "ヴィンスモーク"},
      {q: "“四皇”に数えられる海賊は?", choices: ["シャンクス", "クロコダイル", "スモーカー", "ヒナ"], answer: "シャンクス"},
      {q: "“王下七武海”制度を作ったのは?", choices: ["世界政府", "革命軍", "四皇", "ドフラミンゴ"], answer: "世界政府"},
      {q: "“マリンフォード頂上戦争”で亡くなったキャラは?", choices: ["エースと白ひげ", "エースとサボ", "白ひげとカイドウ", "赤犬と青雉"], answer: "エースと白ひげ"},
      {q: "ウソップの異名は?", choices: ["狙撃の王様", "千人のウソップ", "海の戦士", "勇者ウソップ"], answer: "狙撃の王様"},
      {q: "ロビンの能力は?", choices: ["ハナハナの実", "メラメラの実", "ヒトヒトの実", "バラバラの実"], answer: "ハナハナの実"},
      {q: "“黒ひげ”の本名は?", choices: ["マーシャル・D・ティーチ", "エドワード・ニューゲート", "シャンクス", "ゴール・D・ロジャー"], answer: "マーシャル・D・ティーチ"},
      {q: "サボが所属する組織は?", choices: ["革命軍", "世界政府", "海軍本部", "四皇"], answer: "革命軍"},
      {q: "ルフィの懸賞金が初めてかかった金額は?", choices: ["3000万ベリー", "1億ベリー", "5000万ベリー", "5億ベリー"], answer: "3000万ベリー"},
      {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, 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 = "✨ 正解!“ひとつなぎの大正解”!";
        if (correctSE) {
          correctSE.currentTime = 0;
          correctSE.play();
        }
        correctCount++;
      } 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:#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問題抽出&初期化しクイズ開始、1問目を表示
showQuestion問題文と選択肢を表示、選択肢クリック時のイベント設定
selectAnswer正誤判定、正解ならカウントアップ、不正解時は正答を表示、ボタン全て無効化
nextQuestion次の問題または終了判定しendGame()呼び出し
endGame正答率・点数計算&表示、結果画面へ
toTitleタイトル画面に戻す処理

改造のポイント

ポイント解説
問題・選択肢追加questions配列を増やせば簡単に問題数拡張・カスタマイズ可能
BGM・効果音追加効果音用audioタグやBGM追加で臨場感UP
タイムアタック化回答ごとに制限時間や残り時間バーを追加することで緊張感演出
スコアランキング化ローカルストレージ利用で自己ランキング記録&表示可能
難易度切替問題ごとに難易度タグ追加→難易度別出題やフィルタも実装しやすい
デザイン強化画像・アイコン・アニメーション追加で「海賊感」や「冒険感」もUP
スマホ対応強化レスポンシブCSS調整で快適に
解説・豆知識問題ごとに補足解説・豆知識など追加して学習系クイズにもアレンジ可能

アドバイスコメント

  • 構造がシンプルで、問題・演出の拡張やテーマ変更が容易です。
  • JavaScript初学者の教材や、自作クイズ制作のたたき台にも最適です。
  • 原作ネタやセリフを随所に追加するとよりファンが楽しめる内容になります!
  • 問題はなるべく「原作のエピソード」「キャラクターの個性」が伝わるものにすると盛り上がります。
  • ぜひ自分だけの“グランドライン級”クイズゲームに改造してみてください!