16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptで国旗クイズを作ってみる

Last updated at Posted at 2017-12-31

国旗クイズを作ってみました。
約200カ国あるので、知らない国が多くて難易度高いです。

#工夫したところ
国旗データはJSON形式にして、jQueryのgetJSONで読み込むようにしています。
覚えるために、正解しないと次の問題に進めないようにしました。

#ハマったところ
$.getJSONを実行しても何の反応もなく困りましたが、調べたらJSONファイルの構文エラーが原因でした。
JSONの構文チェック大事。

難易度を選択時にon("click")イベントが何度も実行されました。off("click")してから次のイベントを実行しないといけないようです。

#今後やりたいこと
操作性の向上。ボタン押した感とか。
サーバにアップして実機で見ると少し遅かったので、速度も上げたい。
解答時の演出。正解時のアニメーションとか効果音とか。
難易度の調整。
見た目の調整。

##ブラッシュアップしました
2018.1.2追記
ボタン押した感。解答時の演出、効果音。見た目の調整。

2018.1.7追記
難易度を設定。JSとCSSを外部ファイル化。

#動作サンプル
[自サイトにアップしました。](http://www.i-keita.com/flag_quiz/index.html)

#コードサンプル(JavaScript)

$(function(){

	// 国旗データを読み込む
	function getFlagData() {
		return $.getJSON("flag.json", function(data){});
	}

	// 難易度 デフォルト
	var level = "1";

	// クイズ処理(イベント毎に実行したいので関数化)
	function drawFlag(level) {

		getFlagData().done(function(data){

			// 難易度調整 国旗データから該当の難易度のみ抽出
			if (level == "2") {
				data = data.filter(function(v){
					return v.level == level || v.level == "1";
				});
			} else if (level == "3") {
				data = data.filter(function(v){
					return v.level == level || v.level == "2";
				});
			} else {
				data = data.filter(function(v){
					return v.level == "1";
				});
			}

			// 国旗をランダムに一つ選択する(正解)
			var q = Math.floor(Math.random() * data.length);

			// 国旗を表示
			$("#flag").html('<img src="flag_png/flag' + data[q]["id"] + '.png" />');
			var c = data[q]["id"];

			// 国旗データをシャッフルする
			var a = [];
			for (i = data.length - 1; i >= 0; i--) {
				// 0~iのランダムな数値を取得
				var rand = Math.floor(Math.random() * (i+1));

				// 配列の数値を入れ替える
				[data[i], data[rand]] = [data[rand], data[i]]
			}

			// シャッフルした国旗データから先頭の3つを取得
			for (i = 0; i < 3; i++) {
				a.push(data[i]);
			}

			// 正解が含まれているか確認し、選択肢を4つにする
			var d = false;
			for (i = 0; i < a.length; i++) {
				if (a[i]["id"] == c) {
					d = true;
				}
			}
			// 含まれていればランダムに一つ追加
			if (d == true) {
				a.push(data[3]);
			// 含まれていなければ正解を追加
			} else {
				for (i = 0; i < data.length; i++) {
					if (data[i]["id"] == c) {
						a.push(data[i]);
					}
				}
			}

			// 選択肢をシャッフルする
			for (i = a.length - 1; i >= 0; i--) {
				// 0~iのランダムな数値を取得
				var rand = Math.floor(Math.random() * (i+1));

				// 配列の数値を入れ替える
				[a[i], a[rand]] = [a[rand], a[i]]
			}

			// 選択肢を表示
			for (i = 0; i < a.length; i++) {
				$("#answer").append('<li id="li' + (i+1) + '"><a id="' + a[i]["id"] + '" href="#">' + a[i]["name"] + '</a></li>');
			}

			// 回答を選択時の処理
			$("#answer a").on("click", function(){

				// 正解すると次の問題へ
				if (this.id == c) {
					// 効果音
					var audio_o = new Audio("img/audio_o.mp3");
					audio_o.play();

					// ボタン変更
					$(this).css("background","url(img/answer_o.png) no-repeat center");
					$(this).css("background-size","contain");

					// 少し時間を置いてから実行
					setTimeout(function(){
						$("#answer").empty();
						$("#level a").off("click");  // イベントをオフにしないと何度もクリックイベントが実行されるので要注意
						drawFlag(level);
					}, 250);

				// 不正解だと選択肢を削る
				} else {
					// 効果音
					var audio_x = new Audio("img/audio_x.mp3");
					audio_x.play();

					// ボタン変更
					$(this).css("background","url(img/answer_x.png) no-repeat center");
					$(this).css("background-size","contain");
				}
			});

			// レベル選択
			$("#level a").on("click", function(){
				switch(this.id) {
					case 'level1':
						level = "1";
						$("#level1").addClass("active");
						$("#level2").removeClass("active");
						$("#level3").removeClass("active");
						break;
					case 'level2':
						level = "2";
						$("#level2").addClass("active");
						$("#level1").removeClass("active");
						$("#level3").removeClass("active");
						break;
					case 'level3':
						level = "3";
						$("#level3").addClass("active");
						$("#level1").removeClass("active");
						$("#level2").removeClass("active");
						break;
					default:
						level = "1";
						break;
				}

				$("#answer").empty();
				$("#level a").off("click");  // イベントをオフにしないと何度もクリックイベントが実行されるので要注意
				drawFlag(level);
			});

		});
	}

	drawFlag(level);


	// 難易度メニュー トグル
	$("#level dd").hide();
	$("#level dt").click(function(){
		$("#level").children("dd").slideToggle("fast");
	});
	$("#level dd").click(function(){
		$("#level dd").hide();
	});


});

#コードサンプル(HTML)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>国旗クイズ</title>
<link rel="stylesheet" href="flag.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="flag.js"></script>
</head>
<body>
<div id="content">
<dl id="level">
<dt>難易度</dt>
<dd><a id="level1" href="#" class="active">初級</a></dd>
<dd><a id="level2" href="#">中級</a></dd>
<dd><a id="level3" href="#">上級</a></dd>
</dl>
<div id="flag"></div>
<ul id="answer">
</ul>
</div>
</body>
</html>

#コードサンプル(JSON)

[
{
	"id":"093",
	"name":"日本",
	"level":"1"
}
]
16
14
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?