Пробел вызывает перезагрузку игры после переключения на другие трудности в моей игре на скорость набора текста.Javascript

Форум по Javascript
Ответить
Anonymous
 Пробел вызывает перезагрузку игры после переключения на другие трудности в моей игре на скорость набора текста.

Сообщение Anonymous »

Я разрабатываю игру на скорость набора текста с уровнями сложности (легкий, средний, сложный), в которой игра отслеживает скорость, точность и время набора текста. После переключения с простого на средний (или другие уровни), когда я нажимаю клавишу пробела для ввода следующего символа, образец текста неожиданно сбрасывается на новый набор слов.
Эта проблема возникает только при сбросе происходит после переключения сложности. Игра по сути перезапускается, как если бы это был новый сеанс, а также сбрасываются таймер и статистика набора текста.
Я не уверен, что вызывает такое поведение. Кто-нибудь сталкивался с чем-то подобным или есть какие-либо предложения по устранению этой проблемы?
Что я пробовал:
Я пробовал различные методы управления поведением сброса, включая условный сброс состояния игры в функции resetGame(), ручное обновление и очистку переменных, связанных с игрой, а также обеспечение правильного управления значениями startTime, currentIndex и другими значениями при переключении между уровнями сложности. Я также попытался переместить логику пробела из события handleKeydown() в другую функцию, но проблема не устранена.
Что я ожидал:
Я ожидал, что при переключении с простого на средний уровень сложности (или других уровней) клавиша пробела будет работать как обычно и перемещаться по тексту, не вызывая перезагрузки игры или запуска таймера с нуля. После переключения сложности образец текста должен обновиться правильно, и ввод должен продолжаться плавно с нового текста без сброса.
Что произошло на самом деле:
Вместо этого после переключения сложности и нажатия клавиши пробела игра ведет себя так, как будто это новый сеанс, сбрасывая образец текста, скорость набора текста, таймер и текущий индекс персонажа. Игра перезапускается, как будто я только что открыл ее в первый раз после изменения сложности.
Script.js
document.addEventListener("DOMContentLoaded", async function () {
const timerDisplay = document.getElementById("timer");
const speedDisplay = document.getElementById("speed");
const accuracyDisplay = document.getElementById("accuracy");
const textDisplay = document.getElementById("text-display");
const retryButton = document.getElementById("retry-button");
const changeDifficultyButton = document.getElementById("change-difficulty");
const difficultyOptions = document.getElementById("difficulty-options");

let sampleText = await getWords();
let startTime, timerInterval;
let currentIndex = 0; // tracks the position of the current character the user is typing
let mistakesCounter = 0;
let currentDifficulty = "easy";

// Initialize game
textDisplay.innerHTML = sampleText
.split("")
.map((char) => `${char}`)
.join("");
initializeCursor();
highlightCurrentDifficulty();

// Event listeners
document.addEventListener("keydown", handleKeydown);
retryButton.addEventListener("click", resetGame);
changeDifficultyButton.addEventListener("click", toggleDifficultyOptions);
document.querySelectorAll("#difficulty-options button").forEach((button) => {
button.addEventListener("click", handleDifficultyChange);
});

// Functions

/*
* Upon key press
*/
function handleKeydown(event) {
// Start the timer on the first keypress
if (!startTime) {
startTime = new Date();
startTimer();
}

// Ignore all keys except Backspace
if (event.key.length > 1 && event.key !== "Backspace") return;

const spans = textDisplay.querySelectorAll("span");
if (event.key === "Backspace") {
handleBackspace(spans);
return;
}

// Prevent overflow
if (currentIndex >= sampleText.length) return;

const typedKey = event.key;
const expectedChar = sampleText[currentIndex];

if (typedKey === expectedChar) {
spans[currentIndex].classList.add("correct");
} else {
spans[currentIndex].classList.add("incorrect");
mistakesCounter++;
}

currentIndex++;
highlightCurrentCharacter(spans);

// Stop the timer when all characters are typed
if (currentIndex === sampleText.length) {
stopTimer();
displayTypingSpeed();
displayAccuracy();
}
}

/*
* Backspace Handler (Removes correct and incorrect text styling)
*/
function handleBackspace(spans) {
if (currentIndex > 0) {
spans[currentIndex].classList.remove("current");
currentIndex--;
spans[currentIndex].classList.remove("correct", "incorrect");
}
highlightCurrentCharacter(spans);
}

/*
* Initialize cursor (Place it at the start)
*/
function initializeCursor() {
const spans = textDisplay.querySelectorAll("span");
if (spans.length > 0) spans[0].classList.add("current");
}

/*
* Place cursor on the current letter
*/
function highlightCurrentCharacter(spans) {
spans.forEach((span) => span.classList.remove("current"));
if (currentIndex < spans.length) spans[currentIndex].classList.add("current");
}

/*
* Start Timer
*/
function startTimer() {
timerInterval = setInterval(() => {
const elapsedTime = new Date() - startTime;
const seconds = Math.floor(elapsedTime / 1000);
timerDisplay.textContent = seconds;
}, 1000);
}

/*
* Stop Timer
*/
function stopTimer() {
clearInterval(timerInterval);
}

/*
* Display typing speed (WPM)
*/
function displayTypingSpeed() {
if (!startTime) return;
const wordsTyped = sampleText.split(" ").length;
const timeInMinutes = (new Date() - startTime) / 1000 / 60;
const wpm = Math.floor(wordsTyped / timeInMinutes);
speedDisplay.textContent = wpm;
}

/*
* Display accuracy
*/
function displayAccuracy() {
const totalChars = sampleText.length;
if (totalChars === 0) {
accuracyDisplay.textContent = "100.00";
return;
}
const accuracy = (((totalChars - mistakesCounter) / totalChars) * 100).toFixed(2);
accuracyDisplay.textContent = accuracy;
}

/*
* API random word fetcher
*/
async function getWords(difficulty = "easy") {
try {
let wordLength, wordCount;
switch (difficulty) {
case "easy":
wordLength = 3;
wordCount = 20;
break;
case "medium":
wordLength = 5;
wordCount = 30;
break;
case "hard":
wordLength = 7;
wordCount = 40;
break;
default:
wordLength = 5;
wordCount = 30;
}

const response = await fetch(
`https://random-word-api.herokuapp.com/w ... wordLength}`
);
const words = await response.json();
return words.join(" ");
} catch (error) {
console.error("Error fetching words:", error);
return "Peter piper bit a pan of pickled pepper and the quick brown fox jumps over the moon.";
}
}

/*
* Reset Game
*/
async function resetGame() {
stopTimer();
timerDisplay.textContent = "0";
speedDisplay.textContent = "0";
accuracyDisplay.textContent = "0";
startTime = null;
currentIndex = 0;
mistakesCounter = 0;

sampleText = await getWords(currentDifficulty);
textDisplay.innerHTML = sampleText
.split("")
.map((char) => `${char}`)
.join("");

const spans = textDisplay.querySelectorAll("span");
spans.forEach((span) => {
span.classList.remove("correct", "incorrect", "current");
});

initializeCursor(); // Reset the cursor to the first character
}

/*
*
*/
function toggleDifficultyOptions() {
difficultyOptions.classList.toggle("active");
}

/*
*
*/
function handleDifficultyChange(e) {
const selectedDifficulty = e.target.getAttribute("data-difficulty");
currentDifficulty = selectedDifficulty;
resetGame();
difficultyOptions.classList.remove("active");
highlightCurrentDifficulty();
}

/*
*
*/
function highlightCurrentDifficulty() {
document.querySelectorAll("#difficulty-options button").forEach((button) => {
button.classList.remove("active-difficulty");
});

const currentDifficultyButton = document.querySelector(
`#difficulty-options button[data-difficulty="${currentDifficulty}"]`
);
if (currentDifficultyButton) {
currentDifficultyButton.classList.add("active-difficulty");
}
}
});

Стили.CSS
body {
font-family: "Poppins", sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f9;
color: #33333369;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
}

h1 {
font-size: 3.5rem;
font-weight: 600;
color: #000000;
margin-bottom: 20px;
}

#text-display {
font-size: 2.5rem;
line-height: 1.8;
text-align: center;
text-justify: inter-word;
color: #33333361;
margin: 20px 0;
max-width: 1500px;
padding: 0 30px;
white-space: pre-wrap;
}

/* Stats Container */
.stats {
display: flex;
justify-content: center;
gap: 30px;
margin-top: 20px;
}

.stats p {
font-size: 1.2rem;
font-weight: 600;
color: #555;
}

.stats span {
color: #2c3e50;
font-weight: 700;
}

/* Cursor and Highlight Styles */
.current {
border-left: 3px solid #000000;
animation: blink 0.7s infinite;
}

.correct {
color: #000000db;
font-size: 2.7rem;
}

.incorrect {
background-color: rgba(255, 0, 0, 0.359);
color: #db2612;
text-decoration: line-through;
}

/* Blinking Cursor Animation */
@keyframes blink {
0%,
100% {
border-left-color: transparent;
}
50% {
border-left-color: #000102ab;
}
}

#controls {
position: relative;
display: inline-block;
margin-top: 20px;
text-align: center;
}

#controls button {
padding: 12px 24px;
margin-top: 10px;
font-size: 2.5rem;
font-weight: 600;
background-color: #f4f4f9;
color: #333;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.6s ease;
}

#controls button:hover {
color: #000;
transform: translateY(-5px);
}

#controls button:active {
transform: translateY(0);
}

#difficulty-options {
display: flex;
gap: 10px;
justify-content: center;
margin-top: 10px;
opacity: 0;
transform: translateY(-10px);
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
pointer-events: none;
}

#difficulty-options.active {
opacity: 1;
transform: translateY(0);
pointer-events: all;
}

#difficulty-options button {
font-size: 1.5rem;
padding: 5px 10px;
border: none;
border-radius: 5px;
background-color: #f4f4f9;
color: #333;
cursor: pointer;
transition: all 0.3s ease;
}

#difficulty-options button.active-difficulty {
background-color: #13111134;
color: rgb(0, 0, 0);
}

#difficulty-options button:hover {
background-color: #ddd;
color: #000;
}

/* Caret style */
#change-difficulty .caret {
display: inline-block;
transition: transform 0.3s ease;
}

#change-difficulty .caret.down {
transform: rotate(90deg);
}

index.html





Speed Typing Test





TypeIt

Time: 0s
Speed: 0 WPM
Accuracy: 0%

> Retry
> Change Difficulty

Easy
Medium
Hard









Подробнее здесь: https://stackoverflow.com/questions/793 ... s-in-my-ty
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»