Skip to content

Commit

Permalink
πŸš‘ fix: screen change issue, word drop issue
Browse files Browse the repository at this point in the history
- 슀크린 변경이 정상적이지 μ•Šμ€ ν˜„μƒ μˆ˜μ •
- 단어가 λΉ„μ •μƒμ μœΌλ‘œ 좜λ ₯λ˜λŠ” ν˜„μƒ μˆ˜μ •
- μž¬μ‹œμž‘ μ‹œ κΈ°μ‘΄ 단어가 재좜λ ₯λ˜λŠ” ν˜„μƒ μˆ˜μ •
- drop λ©”μ†Œλ“œκ°€ μ˜λ„ν•œ μ‹œκ°„λ³΄λ‹€ 많이 ν˜ΈμΆœλ˜λŠ” ν˜„μƒ μˆ˜μ •
- 단어가 ν•œκΊΌλ²ˆμ— λ–¨μ–΄μ§€λŠ” ν˜„μƒ μˆ˜μ •
  • Loading branch information
itsmo1031 committed May 28, 2023
1 parent 370be81 commit 866f1aa
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 62 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Speech To Game

λ“€λ¦¬λŠ” 말을 νƒ€μ΄ν•‘ν•΄μ„œ μ—†μ• μž
μŒμ„± μΈμ‹λœ 단어듀을 νƒ€μ΄ν•‘ν•΄μ„œ μ—†μ• μž

## Requirements

- Chromium Browser (Firefox unsupported)
- Microphone (Need Auth)

## Assets

[Dino Character Sprites](https://arks.itch.io/dino-characters) by [ArksπŸ’’](https://twitter.com/ArksDigital)
- Game Sounds from [Pixabay](https://pixabay.com/sound-effects/)
- CSS framework [NES.css](https://nostalgic-css.github.io/NES.css/)
- [Neoλ‘₯κ·Όλͺ¨ Font](https://neodgm.dalgona.dev/)
1 change: 1 addition & 0 deletions css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ body {
right: 1rem;
bottom: 1rem;
animation: blink-20 2s step-end infinite;
display: inherit;
}

.input-animation {
Expand Down
172 changes: 112 additions & 60 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ let score = 0;
const scoreField = document.getElementById('score');
const bestScoreField = document.getElementById('best-score');
const finalScore = document.getElementById('final-score');
const inputDiv = document.getElementById('input-div');
const inputField = document.getElementById('input-field');
let dropping;
let dropWordTimeout;
let dropDelay;
let isGameOver = false;
// μŒμ„± 인식 κ²°κ³Όλ₯Ό μ €μž₯ν•  λ°°μ—΄
const speechWords = [];
let muted = localStorage.getItem('muted')
Expand Down Expand Up @@ -84,9 +87,8 @@ const addTimeout = (callback, delay) => {
};

const handleDropWords = () => {
const delay = Math.round(Math.random() * 5 * 1000);
const delay = Math.round(Math.random() * 7 * 1000);
dropWordTimeout = addTimeout(drop, delay);
dropDelay += delay;
};

const drop = () => {
Expand All @@ -97,11 +99,8 @@ const drop = () => {
const word = new Word(speechWords.splice(0, 1));
const dropWord = document.createElement('div');
dropWord.classList.add('word');
dropWord.style.animationDelay = `${dropDelay}s`;
if (word.posX + dropWord.offsetWidth > document.documentElement.clientWidth) {
console.log('over width');
word.posX = document.documentElement.clientWidth - dropWord.offsetWidth;
}
// console.log('current dropdelay: ' + dropDelay);
// dropWord.style.animationDelay = `${dropDelay}s`;
dropWord.style.whiteSpace = 'nowrap';
dropWord.style.animationTimingFunction = 'linear';
dropWord.innerText = word.value;
Expand All @@ -111,9 +110,10 @@ const drop = () => {
gameScreen.appendChild(dropWord);

const wordWidth = dropWord.offsetWidth; // ν…μŠ€νŠΈμ˜ μ‹€μ œ λ„ˆλΉ„ κ°€μ Έμ˜€κΈ°
if (word.posX + wordWidth > document.documentElement.clientWidth) {
const sectionWidth = document.getElementById('game-section').offsetWidth;
if (word.posX + wordWidth > sectionWidth) {
console.log('over width');
word.posX = document.documentElement.clientWidth - wordWidth;
word.posX = sectionWidth - wordWidth;
}
dropWord.style.left = `${word.posX}px`;
};
Expand All @@ -140,6 +140,7 @@ const handleInput = (event) => {

// λͺ¨λ“  νƒ€μž„μ•„μ›ƒ 클리어
const clearAllTimeouts = () => {
console.log('clear timeouts');
timeouts.forEach((timeoutId) => clearTimeout(timeoutId));
timeouts.length = 0;
};
Expand All @@ -156,30 +157,6 @@ const handleAnimationEnd = () => {
}
};

const gameOver = () => {
const inputDiv = document.getElementById('input-div');
console.log('Game Over');
document.getElementById('rec').classList.toggle('display-none');
stopRecognition();
toggleScreen('game-section', 'retry-section');
toggleScreen('header-game-left', 'header-retry-left');
window.addEventListener('keydown', handleRadio);
window.addEventListener('keyup', handleSelection);
endMusic.play();
bgm.pause();
bgm.currentTime = 0;
finalScore.innerText = score.toString().padStart(6, '0');
// ν˜„μž¬ 점수 μ΅œμ’… μ μˆ˜μ™€ 비ꡐ
if (isBestScore()) {
bestScore = score;
console.log('new record!');
localStorage.setItem('bestScore', score);
finalScore.parentNode.classList.add('best');
}
inputDiv.classList.toggle('display-none');
inputDiv.classList.toggle('input-animation');
};

const isBestScore = () => {
return !bestScore || score > parseInt(bestScore);
};
Expand All @@ -205,8 +182,7 @@ const clearScore = () => {

const handleGameStart = (event) => {
if (event.key === 'Enter') {
toggleScreen('title-section', 'game-section');
toggleScreen('header-main-left', 'header-game-left');
startMusic.play();
gameStart();
window.removeEventListener('keyup', handleGameStart);
}
Expand All @@ -223,32 +199,51 @@ const stopRecognition = () => {
};

const gameStart = () => {
const inputDiv = document.getElementById('input-div');
inputDiv.classList.toggle('display-none');
inputDiv.classList.toggle('input-animation');
const inputField = document.getElementById('input-field');
document.getElementById('input-div').addEventListener('animationend', () => {
inputField.focus();
document.getElementById('rec').classList.toggle('display-none');
dropping = setInterval(handleDropWords, 1000);
});
isGameOver = false;
dropDelay = 0;
switchToGame();
inputField.addEventListener('keyup', handleInput);
displayBestScore();
clearScore();
startRecognition();
startMusic.play().then(() => {
setTimeout(() => {
bgm.loop = true;
bgm.play();
}, 2500);
});

setTimeout(() => {
bgm.loop = true;
bgm.play();
}, 2500);
};

const gameOver = () => {
isGameOver = true;
inputField.removeEventListener('keyup', handleInput);
console.log('Game Over');
document.getElementById('rec').classList.toggle('display-none');
stopRecognition();
speechWords.length = 0;
switchToRetry();
window.addEventListener('keydown', handleRadio);
window.addEventListener('keyup', handleSelection);
endMusic.play();
bgm.pause();
bgm.currentTime = 0;
finalScore.innerText = score.toString().padStart(6, '0');
// ν˜„μž¬ 점수 μ΅œμ’… μ μˆ˜μ™€ 비ꡐ
if (isBestScore()) {
bestScore = score;
console.log('new record!');
localStorage.setItem('bestScore', score);
finalScore.parentNode.classList.add('best');
}
};

const toggleScreen = (fromScreen, toScreen) => {
const fs = document.getElementById(fromScreen);
const ts = document.getElementById(toScreen);
fs.classList.toggle('display-none');
ts.classList.toggle('display-none');
// input field의 μ• λ‹ˆλ©”μ΄μ…˜μ΄ λλ‚œ ν›„ λ™μž‘ (initμ‹œ 1회 μ„ μ–Έ)
const inputFieldSetup = () => {
inputDiv.addEventListener('animationend', () => {
inputField.value = '';
inputField.focus();
document.getElementById('rec').classList.remove('display-none');
dropping = setInterval(handleDropWords, 1000);
});
};

const playSelectSound = () => {
Expand Down Expand Up @@ -296,14 +291,11 @@ const handleSelection = (event) => {
const radioResult = document.querySelector(
'input[name="selection-radio"]:checked'
).value;
startMusic.play();
if (radioResult === 'retry') {
toggleScreen('retry-section', 'game-section');
toggleScreen('header-retry-left', 'header-game-left');
gameStart();
} else {
toggleScreen('retry-section', 'title-section');
toggleScreen('header-retry-left', 'header-main-left');
startMusic.play();
switchToMain();
window.addEventListener('keyup', handleGameStart);
}

Expand Down Expand Up @@ -341,8 +333,68 @@ const toggleVolumeIcon = () => {
volumeBtn.classList.toggle('fa-volume-xmark');
};

const hideAllScreen = () => {
// 헀더, 메인, μž…λ ₯창의 λͺ¨λ“  μš”μ†Œλ“€ μ„ μ–Έ
const headerSection = Array.from(
document.getElementById('header-left').children
);
const mainSection = Array.from(
document.getElementById('main-section').children
);
const inputSection = Array.from(
document.getElementById('input-section').children
);
// forEachλ¬Έ 싀행을 μœ„ν•΄ ν•œ λ³€μˆ˜μ— ν•©μΉ¨
const screens = headerSection.concat(mainSection.concat(inputSection));
const rec = document.getElementById('rec');
inputDiv.classList.remove('input-animation');
rec.classList.add('display-none');
screens.forEach((s) => {
s.classList.add('display-none');
});
};

const switchToMain = () => {
console.log('switching to main screen...');
hideAllScreen();
const mainHeader = document.getElementById('header-main-left');
const mainTitle = document.getElementById('title-section');
mainHeader.classList.remove('display-none');
mainTitle.classList.remove('display-none');
};

const switchToGame = () => {
console.log('switching to game screen...');
hideAllScreen();
const gameHeader = document.getElementById('header-game-left');
const gameMain = document.getElementById('game-section');
const gameInput = document.getElementById('input-div');

gameHeader.classList.remove('display-none');
gameMain.classList.remove('display-none');
gameInput.classList.remove('display-none');
inputDiv.classList.add('input-animation');
};

const switchToRetry = () => {
console.log('switching to retry screen...');
hideAllScreen();
const retryHeader = document.getElementById('header-retry-left');
const retryMain = document.getElementById('retry-section');

retryHeader.classList.remove('display-none');
retryMain.classList.remove('display-none');
};

const switchScreen = {
main: switchToMain,
game: switchToGame,
retry: switchToRetry,
};

const init = () => {
console.log('Initiated!');
inputFieldSetup();
if (!muted) {
console.log('music not muted. toggle volume icon');
toggleVolumeIcon(volumeBtn);
Expand Down

0 comments on commit 866f1aa

Please sign in to comment.