このページではソースコードの一部分を簡単な解説をしています。
作成したゲームはコチラから
ソースコードはgithubにあります
概要
選択肢四つの中から大きい順にクリックして答えていくクイズゲームです。ジャンルを選びクリックするとクイズが始まります。サーバーサイドにはPHPを使用しデータベースから4つの選択肢をランダムに取得してクイズの作成とクライアント側から送られてきた回答の答え合わせをしています。クライアントサイドはJavaScriptを使用してクイズの表示、回答の送信などをしています。
サーバー側の記事は↓にあります。
サーバーからクイズを取得する
スタート画面でジャンルがクリックされるとクイズを取得するfetchQuiz関数が実行されます。FetchAPIを使用してFormDataをPOSTでリクエストしています。FormDataの中身はキー”genre”にはどのクイズのジャンルが選ばれたか 、キー”init”にはスタート画面でクイズを取得するのかゲームの途中でクイズを取得するのかをサーバーサイドで判定するのに使います。
// 問題取得
function fetchQuiz() {
const fd = new FormData();
fd.append("genre", genre);
fd.append("init", init);
return fetch("./quiz.php", {
method: "POST",
body: fd,
})
.then((response) => response.json())
.then((data) => {
return data;
})
.catch((error) => {
console.log(error);
return;
});
}クイズを表示する
showQuiz関数はサーバーから取得したクイズを表示する関数です。DOMを使用してウェブページとその要素にアクセスしてウェブ上にクイズを表示させています。
// 表示 function showQuiz() { document.getElementById("title").textContent = quiz; document.getElementById("number").textContent = <code>クリアまであと${number}問; fetchQuiz().then((data) => { Object.keys(data).forEach((key) => { const choices = document.createElement("p"); choices.className = "choices"; choices.textContent =${data[key]}; selection.appendChild(choices); }); }); }
回答を送信する
クイズの選択肢がクリックされるとcheckAnswer関数が実行されます。この関数はサーバーへ選択された答えを送信して判定された結果を受け取ります。サーバーからは正解、不正解、正解かつ1問クリア、正解かつ全問クリアの4つのうちどれかが返ってくるので、返ってきた値によってswitch文で分岐させて結果を表示する関数を使い分けています。
// 答え送信
function checkAnswer(answer, target) {
const fd = new FormData();
fd.append("answer", answer);
fetch("./quiz.php", {
method: "POST",
body: fd,
})
.then((response) => response.json())
.then((data) => {
switch (data.result) {
case "correct":
correct(data, target);
break;
case "incorrect":
incorrect(data);
break;
case "next":
next(data, target);
break;
case "clear":
clear(data, target);
break;
}
});
}回答結果を表示する
関数correctは正解だった場合に呼び出される関数です。DOMを使用して結果を表示させています。WebAnimationAPIを使い、結果によって文字の色や濃さを変えるアニメーションをさせています。
// 結果表示
// 正解
function correct(data, target) {
result.textContent = "正解";
const size = document.createElement("span");
size.className = "size";
size.textContent = data.size + unit;
target.appendChild(size);
size.animate({ opacity: [0, 1] }, { duration: 1000, fill: "forwards" });
result.animate(
{ opacity: [0, 1, 0, 1, 0, 1, 0], color: "red", offset: [0, 0.5] },
{ duration: 3000, fill: "forwards" }
);
} ソースコードはgithubにあります
最後までお読みいただきありがとうございました
