Я разрабатываю игру на скорость набора текста с уровнями сложности (легкий, средний, сложный), в которой игра отслеживает скорость, точность и время набора текста. После переключения с простого на средний (или другие уровни), когда я нажимаю клавишу пробела для ввода следующего символа, образец текста неожиданно сбрасывается на новый набор слов.
Эта проблема возникает только при сбросе происходит после переключения сложности. Игра по сути перезапускается, как если бы это был новый сеанс, а также сбрасываются таймер и статистика набора текста.
Я не уверен, что вызывает такое поведение. Кто-нибудь сталкивался с чем-то подобным или есть какие-либо предложения по устранению этой проблемы?
Что я пробовал:
Я пробовал различные методы управления поведением сброса, включая условный сброс состояния игры в функции 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
Пробел вызывает перезагрузку игры после переключения на другие трудности в моей игре на скорость набора текста. ⇐ Javascript
Форум по Javascript
1737662463
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/word?number=${wordCount}&length=${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
Подробнее здесь: [url]https://stackoverflow.com/questions/79382403/spacebar-causes-the-game-to-reset-after-switching-to-other-difficulties-in-my-ty[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия