fromCharCodeとkeyCodeで、タイピングのcharacterを取得し、予め用意された配列とマッチするか判定しています。マッチしていれば、位置文字ずつ”_”に文字を変換し、残りの文字をsubstring()で取得します。タイマーは、setTimeout()で1000ミリ秒ごとに減らしていき、0になったら、alert()を表示させます。
リフェレンス
fromCharCode() Method:converts Unicode values into characters.
Note: This is a static method of the String object, and the syntax is always String.fromCharCode().
substring():extracts the characters from a string, between two specified indices, and returns the new sub string.
setTimeout():calls a function or evaluates an expression after a specified number of milliseconds.
Tip: 1000 ms = 1 second.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>タイピングゲーム</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { padding-top: 40; font-family: 'Courier New', sans-serif; text-align: center; } #target { font-size: 48px; letter-spacing: 3px; } .info { color: #ccc; } </style> </head> <body> <p id="target"></p> <p class="info"> Letters count: <span id="score"></span> Miss count: <span id="miss"></span> Remaining Time: <span id="timer"></span> </p> <script> (function(){ 'use strict'; var words = [ 'java', 'python', 'ruby', 'go', 'c', 'javascript', 'cobol', 'php', ]; var currentWord; var currentLocation; var score; var miss; var timer; var target = document.getElementById('target'); var scoreLabel = document.getElementById('score'); var missLabel = document.getElementById('miss'); var timerLabel = document.getElementById('timer'); var isStarted; var timerId; function init(){ currentWord = 'click to start'; currentLocation = 0; score = 0; miss = 0; timer = 7; target.innerHTML = currentWord; scoreLabel.innerHTML = score; missLabel.innerHTML = miss; timerLabel.innerHTML = timer; isStarted = false; } init(); function updateTimer(){ timerId = setTimeout(function(){ timer--; timerLabel.innerHTML = timer; if (timer <= 0){ // alert('game over'); var accuracy = (score + miss) === 0 ? '0.00' : (score / (score + miss) * 100).toFixed(2); alert(score + ' letters, ' + miss + ' miss!' + accuracy + ' % accuracy'); clearTimeout(TimerId); init(); return; } updateTimer(); }, 1000); } function setTarget(){ currentWord = words[Math.floor(Math.random()* words.length)]; target.innerHTML = currentWord; currentLocation = 0; } window.addEventListener('click', function() { if (!isStarted){ isStarted = true; setTarget(); updateTimer(); } }); window.addEventListener('keyup', function(e) { if (!isStarted){ return; } if (String.fromCharCode(e.keyCode) === currentWord[currentLocation].toUpperCase()){ currentLocation++; var placeholder = ''; for (var i = 0; i < currentLocation; i++){ placeholder += '_'; } target.innerHTML = placeholder + currentWord.substring(currentLocation); score++; scoreLabel.innerHTML = score; if (currentLocation === currentWord.length){ setTarget(); } } else { miss++; missLabel.innerHTML = miss; } }); })(); </script> </body> </html>