Создайте игру для теста скорости набора текста с помощью JavaScript
Тест на набор текста предназначен для определения того, насколько быстро человек печатает за заданный промежуток времени. Мы будем разрабатывать игру с набором текста с использованием JavaScript, которая представляет собой простую задачу набора текста и определяет производительность набора путем расчета символов в минуту (CPM), слов в минуту (WPM) и точности набранных символов.
Игра показывает серию цитат, которые необходимо ввести в указанный срок и как можно быстрее. Чем выше скорость набора текста, тем выше значение WPM. Неправильно набранные символы будут соответствующим образом отмечены во время набора.
Сначала мы создадим HTML-макет, стилизуем его с помощью CSS, а затем напишем логику на JavaScript.
Макет HTML: макет HTML определяет структуру элементов, которые будут отображаться на странице. Это включает:
- Заголовок: в этом разделе отображается статистика текущего сеанса набора текста. Это включает отображение оставшегося времени, количества ошибок, точности, WPM и CPM.
- Раздел цитат: в этом разделе отображается текущий текст, который необходимо ввести в область ввода.
- Область ввода: этот раздел содержит область ввода, в которой необходимо ввести текст.
- Кнопка перезапуска: это кнопка перезапуска, которая будет отображаться, когда время истечет и игра закончится.
- Код:
<htmllang="en"><head><title>Simple Speed Typer</title><!-- link the CSS file here --><linkrel="stylesheet"href="style.css"></head><body><divclass="container"><divclass="heading">Simple Speed Typing</div><divclass="header"><divclass="wpm"><divclass="header_text">WPM</div><divclass="curr_wpm">100</div></div><divclass="cpm"><divclass="header_text">CPM</div><divclass="curr_cpm">100</div></div><divclass="errors"><divclass="header_text">Errors</div><divclass="curr_errors">0</div></div><divclass="timer"><divclass="header_text">Time</div><divclass="curr_time">60s</div></div><divclass="accuracy"><divclass="header_text">% Accuracy</div><divclass="curr_accuracy">100</div></div></div><divclass="quote">Click on the area below to start the game.</div><textareaclass="input_area"placeholder="start typing here..."oninput="processCurrentText()"onfocus="startGame()"></textarea><buttonclass="restart_btn"onclick="resetValues()">Restart</button></div><!-- link the JavaScript file here --><scriptsrc="game.js"></script></body></html>
Примечание. Каждая часть заполнена фиктивными данными, чтобы упростить стилизацию. HTML-код вышеизложенного выглядит следующим образом.
Стили CSS: CSS используется для стилизации различных частей и придания им большей визуальной привлекательности.
- Часть заголовка отображается с использованием гибкого макета.
- Каждому элементу даны соответствующие отступы и поля.
- Размер текста каждого элемента таков, что он легко читается пользователем во время игры.
- Два дополнительных класса определены для обозначения букв, которые набираются правильно или неправильно. Эти классы будут динамически добавляться или удаляться при необходимости.
- Код:
body {background-color: #fe9801;color: black;text-align: center;}.container {display: flex;flex-direction: column;align-items: center;}.heading {margin-bottom: 20px;font-size: 3rem;color: black;}.header {display: flex;align-items: center;}.timer, .errors, .accuracy,.cpm, .wpm {background-color: #ccda46;height: 60px;width: 70px;margin: 8px;padding: 12px;border-radius: 20%;box-shadow: black 5px 8px 5px;}.cpm, .wpm {display: none;}.header_text {text-transform: uppercase;font-size: 0.6rem;font-weight: 600;}.curr_time, .curr_errors,.curr_accuracy, .curr_cpm,.curr_wpm {font-size: 2.75rem;}.quote {background-color: #ccda46;font-size: 1.5rem;margin: 10px;padding: 25px;box-shadow: black 5px 8px 5px;}.input_area {background-color: #f5f5c6;height: 80px;width: 40%;font-size: 1.5rem;font-weight: 600;margin: 15px;padding: 20px;border: 0px;box-shadow: black 5px 8px 5px;}.restart_btn {display: none;background-color: #326765;font-size: 1.5rem;padding: 10px;border: 0px;box-shadow: black 5px 8px 5px;}.incorrect_char {color: red;text-decoration: underline;}.correct_char {color: darkgreen;}
Результат макета HTML и стиля CSS будет выглядеть следующим образом: 
Основная логика игры: Основная логика игры определяется в файле JavaScript. Есть несколько функций, которые работают вместе для запуска игры.
Шаг 1. Выбор всех элементов и определение переменных
Необходимые элементы в макете HTML сначала выбираются с помощью метода querySelector() Им присваиваются имена переменных, чтобы к ним можно было легко получить доступ и изменить. Другие переменные, к которым будет осуществляться доступ во всей программе, также определены в начале.
// define the time limitlet TIME_LIMIT = 60; // define quotes to be usedlet quotes_array = [ "Push yourself, because no one else is going to do it for you." , "Failure is the condiment that gives success its flavor." , "Wake up with determination. Go to bed with satisfaction." , "It's going to be hard, but hard does not mean impossible." , "Learning never exhausts the mind." , "The only way to do great work is to love what you do."]; // selecting required elementslet timer_text = document.querySelector( ".curr_time" );let accuracy_text = document.querySelector( ".curr_accuracy" );let error_text = document.querySelector( ".curr_errors" );let cpm_text = document.querySelector( ".curr_cpm" );let wpm_text = document.querySelector( ".curr_wpm" );let quote_text = document.querySelector( ".quote" );let input_area = document.querySelector( ".input_area" );let restart_btn = document.querySelector( ".restart_btn" );let cpm_group = document.querySelector( ".cpm" );let wpm_group = document.querySelector( ".wpm" );let error_group = document.querySelector( ".errors" );let accuracy_group = document.querySelector( ".accuracy" ); let timeLeft = TIME_LIMIT;let timeElapsed = 0;let total_errors = 0;let errors = 0;let accuracy = 0;let characterTyped = 0;let current_quote = "" ;let quoteNo = 0;let timer = null ; |
Шаг 2: Подготовка текста для отображения
Определена функция updateQuote() которая обрабатывает следующие вещи:
- Получение текста
Цитаты использовались в качестве текста, который нужно набирать, чтобы играть в игру. Каждая цитата берется одна за другой из предопределенного массива. Переменная отслеживает текущий индекс котировки и увеличивает его при каждом запросе нового. - Разбиение персонажей на элементы
Каждый из символов в тексте разделен на серию элементов<span>. Это позволяет индивидуально изменять цвет каждого символа в зависимости от того, правильно ли он набран пользователем. Эти элементы добавляются к переменнойquote_text.
function updateQuote() { quote_text.textContent = null ; current_quote = quotes_array[quoteNo]; // separate each character and make an element // out of each of them to individually style them current_quote.split( '' ).forEach(char => { const charSpan = document.createElement( 'span' ) charSpan.innerText = char quote_text.appendChild(charSpan) }) // roll over to the first quote if (quoteNo < quotes_array.length - 1) quoteNo++; else quoteNo = 0;} |
Шаг 3. Получение пользователем текста, набранного в данный момент.
Определена функция processCurrentText() которая будет вызываться всякий раз, когда пользователь вводит или изменяет что-либо в поле ввода. Следовательно, он используется с oninput события oninput поля ввода. Эта функция обрабатывает следующие вещи:
- Получение текущего значения поля ввода
Свойствоvalueобласти ввода используется для получения текущего текста, вводимого пользователем. Он разбивается на массив символов для сравнения с текстом цитаты. Это хранится вcurr_input_array. - Раскрашивание символов текста цитаты
Символы отображаемой цитаты окрашиваются в красный или зеленый цвет в зависимости от того, правильно ли она набрана. Для этого нужно выбрать элементы диапазона цитаты, которую мы создали ранее, и просмотреть их в цикле. Затем элемент применил классы, созданные выше, в зависимости от того, соответствует ли он набранному тексту. - Расчет погрешностей и точности
Каждый раз, когда пользователь делает ошибку во время набора текста,errorsувеличивается. Это используется для расчета значения точности путем деления количества правильно набранных символов на общее количество символов, набранных пользователем. - Переход к следующей цитате
Когда длина вводимого текста совпадает с длиной текста цитаты,updateQuote()которая изменяет цитату и очищает область ввода. Количество общих ошибок также обновляется для использования в следующей расценке.
function processCurrentText() { // get current input text and split it curr_input = input_area.value; curr_input_array = curr_input.split(""); // increment total characters typed characterTyped++; errors = 0; quoteSpanArray = quote_text.querySelectorAll("span"); quoteSpanArray.forEach((char, index) => { let typedChar = curr_input_array[index] // character not currently typed if (typedChar == null) { char.classList.remove("correct_char"); char.classList.remove("incorrect_char"); // correct character } else if (typedChar === char.innerText) { char.classList.add("correct_char"); char.classList.remove("incorrect_char"); // incorrect character } else { char.classList.add("incorrect_char"); char.classList.remove("correct_char"); // increment number of errors errors++; } }); // display the number of errors error_text.textContent = total_errors + errors; // update accuracy text let correctCharacters = (characterTyped - (total_errors + errors)); let accuracyVal = ((correctCharacters / characterTyped) * 100); accuracy_text.textContent = Math.round(accuracyVal); // if current text is completely typed // irrespective of errors if (curr_input.length == current_quote.length) { updateQuote(); // update total errors total_errors += errors; // clear the input area input_area.value = ""; }} |
Шаг 4: Запуск новой игры
Определена функция startGame() которая будет вызываться, когда пользователь фокусируется на поле ввода. Следовательно, он используется с onfocus событий onfocus поля ввода. Эта функция обрабатывает следующие вещи:
- Сбросить все значения
Все значения сбрасываются до значений по умолчанию перед началом новой игры. Мы создаем другую функцию с именемresetValues()которая этим занимается. - Обновить текст цитаты
Новый текст цитаты подготавливается и отображается путем вызова функцииupdateQuote(). - Создание нового таймера
Таймер отслеживает количество оставшихся секунд и отображает его пользователю. Он создается с помощьюsetInterval()который многократно вызываетupdateTimer()определенную ниже. Перед созданием нового таймера предыдущий экземпляр таймера очищается с помощьюclearInterval().
function startGame() { resetValues(); updateQuote(); // clear old and start a new timer clearInterval(timer); timer = setInterval(updateTimer, 1000);} function resetValues() { timeLeft = TIME_LIMIT; timeElapsed = 0; errors = 0; total_errors = 0; accuracy = 0; characterTyped = 0; quoteNo = 0; input_area.disabled = false ; input_area.value = "" ; quote_text.textContent = 'Click on the area below to start the game.' ; accuracy_text.textContent = 100; timer_text.textContent = timeLeft + 's' ; error_text.textContent = 0; restart_btn.style.display = "none" ; cpm_group.style.display = "none" ; wpm_group.style.display = "none" ;} |
Шаг 5: Обновление таймера
Определена функция updateTimer() которая будет вызываться каждую секунду для отслеживания времени. Эта функция обрабатывает следующие вещи:
- Обновите значения времени
Все переменные, которые отслеживают время, обновляются. ЗначениеtimeLeftуменьшается,timeElapsedувеличивается, а текст таймера обновляется до текущего оставшегося времени. - Завершение игры
Эта часть запускается при достижении лимита времени. Он вызываетfinishGame()определенную ниже, которая завершает игру.
function updateTimer() { if (timeLeft > 0) { // decrease the current time left timeLeft--; // increase the time elapsed timeElapsed++; // update the timer text timer_text.textContent = timeLeft + "s" ; } else { // finish the game finishGame(); }} |
Шаг 6: завершение игры
Определена функция finishGame() которая будет вызываться, когда игра должна быть завершена. Эта функция обрабатывает следующие вещи:
- Удаление таймера
Созданный ранее экземпляр таймера удаляется. - Отображение текста и кнопки перезапуска игры
Цитируемый текст, отображаемый для пользователя, изменяется на текст, указывающий на то, что игра окончена. Кнопка «Перезагрузка» также отображается, если для свойства display установлено значение «block». - Расчет CPM и WPM текущего сеанса
- Число символов в минуту (CPM) рассчитывается путем деления общего количества набранных символов на прошедшее время и последующего умножения результата на 60. Оно округляется во избежание запятой.
- Количество слов в минуту (WPM) рассчитывается путем деления CPM на 5 и последующего умножения результата на 60. 5 обозначает среднее количество символов в слове. Оно округлено, чтобы не было десятичных знаков.
function finishGame() { // stop the timer clearInterval(timer); // disable the input area input_area.disabled = true ; // show finishing text quote_text.textContent = "Click on restart to start a new game." ; // display restart button restart_btn.style.display = "block" ; // calculate cpm and wpm cpm = Math.round(((characterTyped / timeElapsed) * 60)); wpm = Math.round((((characterTyped / 5) / timeElapsed) * 60)); // update cpm and wpm text cpm_text.textContent = cpm; wpm_text.textContent = wpm; // display the cpm and wpm cpm_group.style.display = "block" ; wpm_group.style.display = "block" ;} |
Заключительная демонстрация
Теперь игра готова к игре в любом браузере.

Исходный код: https://github.com/sayantanm19/js-simple-typing-game