
【ゲーム】JavaScript:20 世界の国旗当てクイズ
「世界の国旗当てクイズ」は、画面に表示される国旗の絵文字を見て、4択の中から該当する国名を選ぶ知識クイズゲームです。全20カ国の中からランダムに10問出題され、正答率を競います。
遊び方・操作方法
- スタート:タイトル画面の「スタート」ボタンをクリック
- 問題:画面中央に国旗の絵文字が表示
- 選択:4つの国名ボタンからひとつをクリック
- フィードバック:正解なら「✅ 正解です!」、不正解なら「❌ 不正解… 正解は『〇〇』です。」と表示
- 次へ:フィードバック後に表示される「次の問題」ボタンをクリック
- 結果:10問回答後、正答率をパーセンテージで表示
- タイトルに戻る:結果画面の「タイトルに戻る」ボタンをクリック
ルール
- 全20カ国からランダムに10問を出題
- 各問題につき1回のみ選択可
- 回答後に正誤フィードバック表示
- 10問回答後、正答率(%)を表示
- 再挑戦したい場合はタイトル画面に戻って再スタート
🎮ゲームプレイ
以下のリンク先から実際にプレイできます。
20 世界の国旗当てクイズ
素材のダウンロード
以下のリンクから使用する素材をダウンロードできます。
world_flags_quiz_title.png | world_flags_quiz_bg.png |
---|---|
![]() | ![]() |
ゲーム画面イメージ

プログラム全文(world_flags_quiz.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🌏 世界の国旗当てクイズ 🌏</title>
<style>
/* 全体リセット */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background-color: #f4f4f9;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
text-align: center;
background-image: url('world_flags_quiz_bg.png');
background-size: cover;
background-position: center;
color: #fff;
}
/* クイズコンテナ */
#quiz-container {
background-color: rgba(0, 0, 0, 0.75);
padding: 30px;
border-radius: 10px;
width: 90%;
max-width: 600px;
height: 700px; /* 固定高さを指定して全画面と同じサイズに */
overflow-y: auto; /* 中身がはみ出す場合はスクロール */
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
/* メインタイトル */
#quiz-container > h1 {
font-size: 2.2rem;
color: #FFD700;
margin-bottom: 20px;
}
/* タイトル画面の画像 */
#title-screen img {
max-width: 80%;
height: auto;
margin-bottom: 20px;
}
/* 画面切り替え */
#title-screen,
#game-screen,
#result-screen {
display: none;
}
#title-screen.active,
#game-screen.active,
#result-screen.active {
display: block;
}
/* 問題番号 */
#question-number {
font-size: 1.2rem;
color: #FFD;
margin-bottom: 10px;
}
/* 国旗表示 */
#flag-display {
font-size: 6rem; /* 国旗を大きく */
margin: 20px 0;
}
/* Twemoji 画像サイズを合わせる */
#flag-display img {
width: 6rem;
height: auto;
}
/* 選択肢ボタン群 */
#choices-container {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 20px;
}
#choices-container button {
padding: 12px;
font-size: 1.1rem;
border: none;
border-radius: 5px;
background-color: #1E90FF;
color: #fff;
cursor: pointer;
transition: background-color 0.3s ease;
}
#choices-container button:hover {
background-color: #104E8B;
}
/* フィードバック&結果テキスト */
#feedback,
#result-message {
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 20px;
}
/* 各種ボタン */
#start-button,
#next-button,
#return-button {
padding: 10px 24px;
font-size: 1rem;
border: none;
border-radius: 5px;
background-color: #32CD32;
color: #fff;
cursor: pointer;
transition: background-color 0.3s ease;
margin-top: 10px;
}
#start-button:hover,
#next-button:hover,
#return-button:hover {
background-color: #228B22;
}
</style>
<!-- Twemoji API 読み込み -->
<script src="https://cdn.jsdelivr.net/npm/@twemoji/api@latest/dist/twemoji.min.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="quiz-container">
<!-- メインタイトル -->
<h1>🌏 世界の国旗当てクイズ 🌏</h1>
<!-- タイトル画面 -->
<div id="title-screen" class="active">
<img id="title-image" src="world_flags_quiz_title.png" alt="世界の国旗当てクイズ">
<p>表示される国旗(絵文字)に対応する国名を4択の中から選んでください。</p>
<p>全10問の正答率を競うクイズゲームです。</p>
<button id="start-button">スタート</button>
</div>
<!-- ゲーム画面 -->
<div id="game-screen">
<div id="question-number"></div>
<div id="flag-display"></div>
<div id="choices-container"></div>
<p id="feedback"></p>
<button id="next-button">次の問題 ➡️</button>
</div>
<!-- 結果画面 -->
<div id="result-screen">
<p id="result-message"></p>
<button id="return-button">タイトルに戻る</button>
</div>
</div>
<script>
// ──────────────────────────────────────────
// 国旗データ定義(全20カ国)
// ──────────────────────────────────────────
const flags = [
{ emoji: '🇯🇵', country: '日本' },
{ emoji: '🇺🇸', country: 'アメリカ合衆国' },
{ emoji: '🇫🇷', country: 'フランス' },
{ emoji: '🇩🇪', country: 'ドイツ' },
{ emoji: '🇬🇧', country: 'イギリス' },
{ emoji: '🇨🇦', country: 'カナダ' },
{ emoji: '🇮🇹', country: 'イタリア' },
{ emoji: '🇧🇷', country: 'ブラジル' },
{ emoji: '🇨🇳', country: '中国' },
{ emoji: '🇰🇷', country: '韓国' },
{ emoji: '🇷🇺', country: 'ロシア' },
{ emoji: '🇪🇸', country: 'スペイン' },
{ emoji: '🇲🇽', country: 'メキシコ' },
{ emoji: '🇦🇺', country: 'オーストラリア' },
{ emoji: '🇮🇳', country: 'インド' },
{ emoji: '🇹🇷', country: 'トルコ' },
{ emoji: '🇸🇦', country: 'サウジアラビア' },
{ emoji: '🇿🇦', country: '南アフリカ' },
{ emoji: '🇳🇿', country: 'ニュージーランド' },
{ emoji: '🇪🇬', country: 'エジプト' },
{ emoji: '🇸🇪', country: 'スウェーデン' },
{ emoji: '🇳🇴', country: 'ノルウェー' },
{ emoji: '🇫🇮', country: 'フィンランド' },
{ emoji: '🇳🇱', country: 'オランダ' },
{ emoji: '🇨🇭', country: 'スイス' },
{ emoji: '🇧🇪', country: 'ベルギー' },
{ emoji: '🇦🇷', country: 'アルゼンチン' },
{ emoji: '🇨🇱', country: 'チリ' },
{ emoji: '🇬🇷', country: 'ギリシャ' },
{ emoji: '🇵🇹', country: 'ポルトガル' }
];
let quizFlags = []; // 出題用フラグ一覧(10問)
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 startButton = document.getElementById('start-button');
const questionNumEl = document.getElementById('question-number');
const flagDisplay = document.getElementById('flag-display');
const choicesEl = document.getElementById('choices-container');
const feedbackEl = document.getElementById('feedback');
const nextButton = document.getElementById('next-button');
const resultMsgEl = document.getElementById('result-message');
const returnButton = document.getElementById('return-button');
// ── 配列シャッフル関数 (Fisher–Yates) ──
function shuffleArray(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() {
quizFlags = [...flags];
shuffleArray(quizFlags);
quizFlags = quizFlags.slice(0, 10); // 10問設定
currentQuestion = 0;
correctCount = 0;
titleScreen.classList.remove('active');
resultScreen.classList.remove('active');
gameScreen.classList.add('active');
showQuestion();
}
// ── 問題表示処理 ──
function showQuestion() {
const { emoji, country } = quizFlags[currentQuestion];
questionNumEl.textContent = `問題 ${currentQuestion + 1} / ${quizFlags.length}`;
flagDisplay.textContent = emoji;
twemoji.parse(flagDisplay, {
folder: 'svg',
ext: '.svg'
});
const choices = [country];
const others = flags.filter(f => f.country !== country);
shuffleArray(others);
for (let i = 0; i < 3; i++) {
choices.push(others[i].country);
}
shuffleArray(choices);
choicesEl.innerHTML = '';
choices.forEach(choice => {
const btn = document.createElement('button');
btn.textContent = choice;
btn.addEventListener('click', () => selectAnswer(choice, country));
choicesEl.appendChild(btn);
});
feedbackEl.textContent = '';
nextButton.style.display = 'none';
}
// ── 回答選択処理 ──
function selectAnswer(selected, correct) {
if (selected === correct) {
feedbackEl.textContent = '✅ 正解です!';
correctCount++;
} else {
feedbackEl.textContent = `❌ 不正解… 正解は「${correct}」です。`;
}
nextButton.style.display = 'inline-block';
}
// ── 次へ or 終了判定 ──
function nextQuestion() {
currentQuestion++;
if (currentQuestion < quizFlags.length) {
showQuestion();
} else {
endGame();
}
}
// ── 終了処理 ──
function endGame() {
gameScreen.classList.remove('active');
resultScreen.classList.add('active');
const accuracy = Math.round((correctCount / quizFlags.length) * 100);
resultMsgEl.textContent = `🎉 クイズ終了!あなたの正答率は ${accuracy}% です!`;
}
// ── イベントリスナー登録 ──
startButton.addEventListener('click', startGame);
nextButton.addEventListener('click', nextQuestion);
returnButton.addEventListener('click', () => {
resultScreen.classList.remove('active');
titleScreen.classList.add('active');
});
</script>
</body>
</html>
アルゴリズムの流れ
ステップ | 処理内容 | 主な関数/命令 |
---|---|---|
1. シャッフル&抽出 | flags 配列をシャッフルし、先頭10要素を quizFlags に設定 | shuffleArray() → slice(0,10) |
2. 問題表示 | 現在の国旗絵文字と正解文字列を取得し、選択肢(正解+ダミー3つ)を生成・シャッフル | showQuestion() |
3. 回答選択 | クリックした選択肢と正解を比較し、フィードバック表示・正解数カウント | selectAnswer() |
4. 次へ/終了 | 次の問題へ進む or 10問終了で正答率計算&結果画面表示 | nextQuestion() → endGame() |
5. 再スタート準備 | 結果画面の「タイトルに戻る」でタイトル画面へ復帰 | returnButton イベント |
関数・クラスの詳しい解説
名称 | 説明 |
---|---|
shuffleArray(array) | Fisher–Yates アルゴリズムで配列要素をランダムに並び替える |
startGame() | 問題配列の初期化、ステート変数リセット、画面切り替え、最初の問題表示 |
showQuestion() | 現在の問題データから国旗絵文字表示、4択ボタン生成、フィードバック・次へボタンの初期化 |
selectAnswer(sel, cor) | プレイヤーの選択と正解を比較し、フィードバック表示・正解数増加・次へボタン表示 |
nextQuestion() | 問題インデックスを進め、次問題表示か終了処理を実行 |
endGame() | ゲーム画面を隠し、正答率を計算して結果画面に表示 |
改造のポイント
- 出題数・選択肢数変更:
quizFlags.slice(0,10)
の数値、選択肢数(現在は3つのダミー)を変えて難易度調整 - 画像化対応:Twemoji の絵文字ではなく、国旗画像ファイルを利用するように
flagDisplay
部分を<img>
に変更 - 問題バリエーション追加:都市名や通貨当てなど別テーマのクイズに応用可能
- 制限時間導入:各問題にタイマーを設け、制限時間内に回答しないと不正解扱い
- スコアボード機能:
localStorage
へ正答率やクリア時間を保存し、ランキング表示画面を追加 - 音声フィードバック:正解/不正解時に効果音を再生し、臨場感をアップ
アドバイス:出題データを外部JSONに分割し、国旗や国名を動的にロードすると、問題の追加・修正が容易になります。また、スマホ対応としてタッチ操作やレスポンシブUIを強化すると幅広いユーザーに親しみやすくなります。