Some product links are affiliate links which means
if you something we'll receive a small commission.
Youtube Link
html
<!DOCTYPE html>
<html>
<head>
<title>typing practice game</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div id="game-container">
<div id="score">Score: <span id="score-value">0</span></div>
<div id="time">Time: <span id="time-value">60</span></div>
<div id="word-container"></div>
</div>
<div id="btn-container" class="btn-container">
<div class="inner">
<strong id="result-score" class="result_score"></strong>
<button type="button" id="restart_button" class="restart_button">restart</button>
</div>
</div>
<div id="input-container">
<input type="text" id="user-input" placeholder="" autofocus autocomplete="false" />
</div>
<script src="./index.js"></script>
</body>
</html>
css
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
font-family: "dilo world", sans-serif;
padding: 0;
margin: 0;
background: no-repeat url("./assets/sea.jpg") 0 0 / cover;
}
#game-container {
position: relative;
width: 100vw;
height: 100vh;
border: 1px solid #000;
overflow: hidden;
}
#score {
position: relative;
width: 200px;
text-align: center;
font-size: 40px;
color: #333;
margin: 50px auto 0;
padding: 10px 0;
border-radius: 6px;
border: 4px solid rgba(0, 0, 0, 0.3);
background-color: rgba(255, 255, 255, 0.4);
z-index: 10;
}
#time {
font-size: 28px;
padding: 20px;
text-align: center;
}
#word-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.word {
position: absolute;
left: 0;
top: 100%;
font-weight: 500;
font-size: 24px;
font-family: "machine gunk", sans-serif;
}
#input-container {
position: absolute;
left: 50%;
bottom: 50px;
transform: translateX(-50%);
display: flex;
justify-content: center;
}
#user-input {
padding: 10px;
width: 200px;
font-size: 24px;
border: 3px solid #ccc;
border-radius: 6px;
background-color: #fff;
font-family: "machine gunk", sans-serif;
}
#user-input.wrong {
border-color: red;
}
#user-input.correct {
border-color: greenyellow;
}
#user-input:focus {
outline: none;
}
.btn-container {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.4);
}
.inner {
border: 10px;
background-color: #eddfc1;
padding: 40px;
text-align: center;
border-radius: 20px;
border: 10px solid rgb(226, 180, 89);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.result_score {
display: block;
font-size: 50px;
color: rgb(193, 121, 19);
}
.restart_button {
font-size: 40px;
background-color: rgb(244, 169, 78);
padding: 10px 20px;
color: #fff;
margin-top: 20px;
border-radius: 100px;
font-family: "machine gunk", sans-serif;
border: 0;
}
js
const words = [
"apple",
"avocado",
"banana",
"blackberry",
"blueberry",
"cherry",
"cherry",
"coconut",
"grape",
"kiwi",
"lemon",
"lime",
"mango",
"melon",
"orange",
"papaya",
"peach",
"pear",
"persimmon",
"pineapple",
"plum",
"strawberry",
"tangerine",
"tomato",
"watermelon",
];
const wordContainer = document.getElementById("word-container");
const scoreValue = document.getElementById("score-value");
const userInput = document.getElementById("user-input");
const resultScore = document.getElementById("result-score");
const btnContainer = document.getElementById("btn-container");
const restartButton = document.getElementById("restart_button");
const timeValue = document.getElementById("time-value");
let score = 0;
let gameTimer, timeTimer;
let wordSpeed = 1;
let wordInterval = 2000;
let playTime = 60;
let remainingTime = playTime;
function createWord() {
const word = document.createElement("div");
word.classList.add("word");
word.innerText = words[Math.floor(Math.random() * words.length)];
word.style.left = Math.random() * (wordContainer.offsetWidth - 200 - word.offsetWidth) + 100 + "px";
wordContainer.appendChild(word);
const bottom = wordContainer.offsetHeight - word.offsetHeight - 150;
const animation = word.animate([{ top: "0px" }, { top: bottom + "px" }], {
duration: 20000 / wordSpeed,
easing: "linear",
fill: "forwards",
});
animation.onfinish = function () {
word.textContent = "";
word.style.width = "70px";
word.style.height = "50px";
word.style.background = 'no-repeat url("./assets/drop.png") 0 0 / cover';
setTimeout(() => {
word.remove();
}, 500);
};
}
function startGame() {
remainingTime = playTime;
score = 0;
wordSpeed = 1;
timeValue.innerText = playTime;
scoreValue.innerText = score;
userInput.value = "";
wordContainer.innerHTML = "";
userInput.disabled = false;
userInput.focus();
btnContainer.style.display = "none";
gameTimer = setInterval(function () {
createWord();
}, wordInterval);
setTimeout(function () {
endGame();
}, 60000);
timeTimer = setInterval(decreaseTime, 1000);
}
function endGame() {
clearInterval(gameTimer);
clearInterval(timeTimer);
wordContainer.innerText = "";
userInput.disabled = true;
userInput.blur();
btnContainer.style.display = "flex";
resultScore.innerText = `Score : ${score}`;
}
function checkWord() {
const enteredWord = userInput.value.trim().toLowerCase();
const wordElements = document.querySelectorAll(".word");
let isFind = false;
for (let i = 0; i < wordElements.length; i++) {
const wordElement = wordElements[i];
if (wordElement.innerText.toLowerCase() === enteredWord) {
isFind = true;
userInput.classList.add("correct");
setTimeout(() => {
userInput.classList.remove("correct");
}, 500);
wordElement.textContent = "";
wordElement.style.width = "150px";
wordElement.style.height = "150px";
wordElement.style.transform = "translate(-50px , -50px)";
wordElement.style.background = 'no-repeat url("./assets/pop.gif") 0 0 / cover';
setTimeout(() => {
wordElement.remove();
}, 300);
score++;
scoreValue.innerText = score;
userInput.value = "";
if (score % 10 === 0) {
wordSpeed += 1;
clearInterval(gameTimer);
wordInterval -= 100;
createWord();
gameTimer = setInterval(function () {
createWord();
}, wordInterval);
}
break;
}
}
if (!isFind) {
userInput.classList.add("wrong");
setTimeout(() => {
userInput.classList.remove("wrong");
}, 500);
}
}
userInput.addEventListener("keydown", function (event) {
if (event.key === "Enter") {
checkWord();
userInput.value = "";
}
});
startGame();
function decreaseTime() {
remainingTime--;
timeValue.innerText = remainingTime;
if (remainingTime === 0) {
endGame();
}
}
restartButton.addEventListener("click", () => {
startGame();
});