Una prueba de mecanografía está diseñada para encontrar qué tan rápido se escribe en un período de tiempo determinado. Diseñaremos un juego de mecanografía usando JavaScript que presenta un desafío de mecanografía simple y encuentra el rendimiento de mecanografiar calculando los caracteres por minuto (CPM), las palabras por minuto (WPM) y la precisión de los caracteres escritos.
El juego muestra una serie de citas que deben escribirse en un límite de tiempo específico, lo más rápido posible. Una velocidad de escritura más alta mostraría un valor de WPM más alto. Los caracteres escritos incorrectamente se marcarán en consecuencia durante la escritura.
Primero crearemos el diseño HTML, le daremos estilo usando CSS y luego escribiremos la lógica en JavaScript.
El diseño HTML: El diseño HTML define la estructura del elemento que se mostraría en la página. Esto incluye:
- Porción de encabezado: esta sección muestra las estadísticas de la sesión de escritura actual. Esto incluye la visualización del tiempo restante, el número de errores, la precisión, WPM y CPM.
- Sección de cotización: esta sección muestra el texto actual que debe escribirse en el área de entrada.
- Área de entrada: esta sección contiene el área de entrada donde se debe escribir el texto.
- Botón de reinicio: este es el botón de reinicio que se mostrará una vez que se agote el tiempo y finalice el juego.
- Código:
html
<html lang="en"> <head> <title>Simple Speed Typer</title> <!-- link the CSS file here --> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div class="heading"> Simple Speed Typing </div> <div class="header"> <div class="wpm"> <div class="header_text">WPM</div> <div class="curr_wpm">100</div> </div> <div class="cpm"> <div class="header_text">CPM</div> <div class="curr_cpm">100</div> </div> <div class="errors"> <div class="header_text">Errors</div> <div class="curr_errors">0</div> </div> <div class="timer"> <div class="header_text">Time</div> <div class="curr_time">60s</div> </div> <div class="accuracy"> <div class="header_text">% Accuracy</div> <div class="curr_accuracy">100</div> </div> </div> <div class="quote"> Click on the area below to start the game. </div> <textarea class="input_area" placeholder="start typing here..." oninput="processCurrentText()" onfocus="startGame()"> </textarea> <button class="restart_btn" onclick="resetValues()"> Restart </button> </div> <!-- link the JavaScript file here --> <script src="game.js"> </script> </body> </html>
Nota: Cada una de las porciones está llena de datos ficticios para facilitar el estilo. El código HTML de lo anterior es el siguiente.
El estilo CSS: CSS se utiliza para diseñar las diferentes partes y hacerlas más atractivas visualmente.
- La parte del encabezado se muestra con el diseño flexible.
- A cada elemento se le asigna un relleno y un margen adecuados.
- El tamaño del texto de cada elemento es tal que el usuario puede leerlo fácilmente cuando juega.
- Se definen dos clases adicionales para indicar las letras que se escriben correctamente o incorrectamente. Estas clases se agregarán o eliminarán dinámicamente cuando sea necesario.
- Código:
html
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; }
El resultado del diseño HTML y el estilo CSS se vería así:
Lógica principal del juego: La lógica principal del juego se define en un archivo JavaScript. Hay varias funciones que trabajan juntas para ejecutar el juego.
Paso 1: Seleccionar todos los elementos y definir variables
Los elementos requeridos en el diseño HTML se seleccionan primero usando el método querySelector(). Se les asignan nombres de variables para que puedan accederse y modificarse fácilmente. Otras variables a las que se accedería a lo largo del programa también se definen al principio.
javascript
// define the time limit let TIME_LIMIT = 60; // define quotes to be used let 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 elements let 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;
Paso 2: Preparando el texto a mostrar
Se define una función updateQuote() que maneja las siguientes cosas:
- Obtener el texto
Se han utilizado comillas como el texto que debe escribirse para jugar el juego. Cada cotización se toma una por una de una array predefinida. Una variable realiza un seguimiento del índice de cotización actual y lo incrementa cada vez que se solicita uno nuevo. - División de los caracteres en elementos
Cada uno de los caracteres del texto se separa en una serie de elementos <span>. Esto hace posible cambiar individualmente el color de cada carácter dependiendo de si el usuario lo ha escrito correctamente. Estos elementos se agregan a una variable quote_text.
javascript
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; }
Paso 3: obtener el texto escrito actualmente por el usuario
Se define una función procesarTextoActual() que se invocará cada vez que el usuario escriba o cambie algo en el cuadro de entrada. Por lo tanto, se usa con el controlador de eventos oninput del cuadro de entrada. Esta función maneja las siguientes cosas:
- Obtener el valor actual del cuadro de entrada
La propiedad de valor del área de entrada se utiliza para obtener el texto actual escrito por el usuario. Esto se divide en una array de caracteres para comparar con el texto de la cita. Esto se almacena en curr_input_array. - Colorear los caracteres del texto de la cita
Los caracteres de la cita mostrada se colorean en ‘rojo’ o ‘verde’ dependiendo de si se ha escrito correctamente. Esto se hace seleccionando los elementos de intervalo de la cita que hemos creado anteriormente y recorriéndolos. Luego, el elemento ha aplicado las clases creadas anteriormente dependiendo de si coincide con el texto escrito. - Cálculo de errores y precisión
Cada vez que el usuario comete un error al teclear, la variable errores se incrementa. Esto se utiliza para calcular el valor de precisión dividiendo el número de caracteres escritos correctamente por el número total de caracteres escritos por el usuario.
- Pasar a la siguiente cita
Cuando la longitud del texto de entrada coincide con la longitud del texto de la cita, se llama a la función updateQuote() que cambia la cita y borra el área de entrada. El número de errores totales también se actualiza para ser utilizado para la próxima cotización.
javascript
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 = ""; } }
Paso 4: Iniciar un nuevo juego
Se define una función startGame() que se invocará cuando el usuario se centre en el cuadro de entrada. Por lo tanto, se usa con el controlador de eventos onfocus del cuadro de entrada. Esta función maneja las siguientes cosas:
- Restablecer todos los valores
Todos los valores se restablecen a sus valores predeterminados antes del inicio de un nuevo juego. Creamos una función diferente llamada resetValues() que maneja esto.
- Actualizar el texto de la cotización
Se prepara y se muestra un nuevo texto de la cotización llamando a la función updateQuote().
- Creación de un nuevo temporizador
Un temporizador realiza un seguimiento de la cantidad de segundos restantes y se los muestra al usuario. Se crea utilizando el método setInterval() que llama repetidamente a la función updateTimer() definida a continuación. Antes de crear un nuevo temporizador, la instancia del temporizador anterior se borra mediante clearInterval().
javascript
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"; }
Paso 5: Actualización del temporizador
Se define una función updateTimer() que se invocará cada segundo para realizar un seguimiento del tiempo. Esta función maneja las siguientes cosas:
- Actualizar los valores
de tiempo Se actualizan todas las variables que controlan el tiempo. El valor de timeLeft se reduce, el valor de timeElapsed se incrementa y el texto del temporizador se actualiza al tiempo restante actual. - Terminar el juego
Esta parte se activa cuando se alcanza el límite de tiempo. Llama a la función finishGame() definida a continuación, que finaliza el juego.
javascript
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(); } }
Paso 6: Terminar el juego
Se define una función finishGame() que será invocada cuando el juego tenga que ser terminado. Esta función maneja las siguientes cosas:
- Eliminación del temporizador
Se elimina la instancia del temporizador creada anteriormente. - Mostrar el texto y el botón de reinicio del juego
El texto citado que se muestra al usuario se cambia por uno que indica que el juego ha terminado. El botón ‘Reiniciar’ también se muestra configurando la propiedad de visualización en ‘bloquear’. - Cálculo del CPM y WPM de la sesión actual
- Los caracteres por minuto (CPM) se calculan dividiendo el número total de caracteres escritos por el tiempo transcurrido y luego multiplicando el resultado por 60. Se redondea para evitar puntos decimales.
- Las palabras por minuto (WPM) se calculan dividiendo el CPM por 5 y luego multiplicando el resultado por 60. El 5 denota el número promedio de caracteres por palabra. Se redondea para evitar puntos decimales.
javascript
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"; }
Demostración final
El juego ya está listo para jugar en cualquier navegador.
Código fuente: https://github.com/sayantanm19/js-simple-typing-game
Publicación traducida automáticamente
Artículo escrito por sayantanm19 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA