ドットインストールを参考にしてます。
https://dotinstall.com/
※プレミアム会員のみ閲覧可能
完成イメージ
実装したい要件の整理
- 初期画面:
- UI設定。
- 画面をクリックするとタイマー起動+クイズが出現
- UI設定。
- クイズ画面:
- タイマー稼働。
- 正解数、誤答数の表示
- ランダムにクイズを出題。
- 正解すると次のクイズがランダム表示
- タイマー稼働。
- 結果画面
- 正解数等、成績を表示
- リプレイの選択肢を表示
- 正解数等、成績を表示
ソースコード(body要素のみ表示/CSSは省略)
<p id="target">Click To Start</p>
<p class="info">
Letter count: <span id="score">0</span>,
Miss count: <span id="miss">0</span>
Timer left: <span id="timer">0</span>
</p>
<script type="text/javascript">
'use strict';
{
// 初期値の設定
const words = [
"apple",
"sky",
"blue",
"middle",
"set"
];
// Math.floor() → 引数の結果の小数点以下を切り捨てる
// Math.random()関数は、0以上、1未満の範囲で浮動小数点の擬似乱数を返す。
let word;
let loc;
let score;
let miss;
// 3000ミリ秒と設定
const timeLimit = 3 * 1000;
// ゲーム開始時刻を保持
let startTime;
// ゲームが始まっているかどうか変数で
let isPlaying = false;
// 各要素の取得
const target = document.getElementById('target');
const scoreLabel = document.getElementById('score');
const missLabel = document.getElementById('miss');
const timerLabel = document.getElementById('timer');
function updateTarget(){
let placeholder = '';
for (let i = 0; i < loc; i++) {
placeholder += '_';
}
target.textContent = placeholder + word.substring(loc);
}
function showResult(){
// 条件演算子を使用
const accuracy = score + miss === 0 ? 0 : score / (score+miss) * 100;
// テンプレートリテラルで、結果を表示させる
alert(`${score} letters, ${miss} misses, ${accuracy.toFixed(2)}% accuracy!`)
}
function updateTimer(){
// ゲーム開始時刻 + 制限時間 - 現在の時刻
const timeLeft = startTime + timeLimit - Date.now();
// 小数点以下を2桁まで表示
timerLabel.textContent = (timeLeft / 1000).toFixed(2);
// setTimeout関数を定義。10ミリ秒毎に、updateTimer関数を呼ぶ。
const timeoutId = setTimeout(() => {
updateTimer();
}, 10);
// 解除したいタイマのID。 IDはsetTimeout()の返値によって取得できる。
if (timeLeft < 0) {
isPlaying = false;
clearTimeout(timeoutId);
// alert処理を100ミリ秒後に遅らせる。
setTimeout(() => {
showResult();
},100);
timerLabel.textContent = "0.00";
target.textContent = "Click to Replay"
}
}
window.addEventListener('click', () => {
if(isPlaying === true){
return;
}
isPlaying = true;
loc = 0;
score = 0;
miss = 0;
scoreLabel.textContent = score;
missLabel.textContent = miss;
word = words[Math.floor(Math.random() * words.length)];
updateTarget();
// 基準日から経過ミリ秒を計算
startTime = Date.now();
updateTimer();
});
// キーボードから入力された値を取得
window.addEventListener('keyup', e => {
if(isPlaying !== true){
return;
}
if (e.key === word[loc]) {
loc++;
// locの数がwordの文字数を超えたタイミングで
if(loc === word.length){
word= words[Math.floor(Math.random() * words.length)];
loc = 0;
}
score++;
scoreLabel.textContent = score;
// updateTarget関数を呼び出す
updateTarget();
} else {
miss++;
missLabel.textContent = miss;
}
});
}
</script>