티스토리 뷰

728x90

 

영타 연습 게임

 

영타를 연습할 수 있는 웹 게임입니다. 기능은 심플합니다. 페이지 로드시 저장되어있는 영어 글귀들이 랜덤하게 전시되고 게임을 시작하면 됩니다. 따로 시작버튼은 존재하지 않으며 아무 키나 입력하면 시작됩니다.

 

주요 기능

 

  • 오탈자 검수 기능

 오탈자가 발생할 경우 mistakes 카운트 1이 증가하고, 해당 문자가 붉은색으로 바뀌어 틀렸다는 것을 알려줍니다.

 

  • 타이머 기능

제한시간 1분의 타이머 기능을 구현하였습니다. 게임 종료 조건은 타이머의 종료 또는 모든 문장 입력입니다.

 

  • 타수 디스플레이

cpm과 wpm 수치를 실시간으로 갱신하여 사용자의 타수를 확인할 수 있습니다.

 

  • 다시하기 버튼

try again 버튼을 구현하여 언제든 다시 시작할 수 있습니다.

 

 

소스 코드

 

전체 소스는 https://github.com/wonseok22/ToyProjects/tree/main/typingGame 를 참고하세요

 

        const typingText = document.querySelector(".typing__text p")
        const inputField = document.querySelector(".input__field")
        const typingMistake = document.querySelector(".mistake span")
        const typingTime = document.querySelector(".time span b");
        const typingWpm = document.querySelector(".wpm span");
        const typingCpm = document.querySelector(".cpm span");
        const typingAgain = document.querySelector(".again");


        let charIndex = 0;
        let mistakes = 0;
        let timer, maxTime = 60, timeLeft = maxTime;
        let isTyping = 0;


        function randomParagraph(){
            //let randIndex = Math.floor(Math.random() * paragraphs.length)   //랜덤으로 나오게
            typingText.innerHTML = "";
            paragraphs[0].split("").forEach(span => {   //글씨 쪼개기
                let spanTag = `<span>${span}</span>`;
                typingText.innerHTML += spanTag;
            })  
            document.addEventListener("keydown", () => inputField.focus());
            typingText.addEventListener("click", () => inputField.focus())
        }   
        
        function initTyping(){ // 키 타이핑할 경우
            const characters = typingText.querySelectorAll("span");
            let typedChar = inputField.value.split("")[charIndex]

            if(charIndex < characters.length-1 && timeLeft > 0) { // 게임이 종료되지 않은 경우에만
                if(!isTyping){  // 처음 눌렀을때만 작동 (타이머)
                isTyping = true
                timer = setInterval(initTimer,1000)
                }
                if(typedChar == null) { //지우기를 눌렀을때 
                    charIndex--; 
                    if(characters[charIndex].classList.contains("incorrect")){ // 틀린거 지우면 mistakes 감소
                        mistakes--;
                    }
                    characters[charIndex].classList.remove("correct", "incorrect")
                }else { // 글자를 입력한 상황
                    if(characters[charIndex].innerText === typedChar){
                    characters[charIndex].classList.add("correct")
                    }else {
                        mistakes++;
                        characters[charIndex].classList.add("incorrect")
                    }
                    charIndex++;
                }

                // 입력할 글자 하이라이트를 위한 작업
                characters.forEach(span => span.classList.remove("active")); //지나간 부분 active를 다 지우고
                characters[charIndex].classList.add("active")  //해당 부분에 active를 추가
                
                // 타이핑마다 mistakes 갱신
                typingMistake.innerText = mistakes;
                
                // 타자율 wpm과 cpm 계산
                let wpm = Math.round((((charIndex - mistakes)/5) / (maxTime - timeLeft)) * 60);
                wpm = wpm < 0 || !wpm || wpm == Infinity ? 0 : wpm;
                typingWpm.innerText = wpm;
                typingCpm.innerText = charIndex - mistakes;
            } else {
                // 게임이 종료된 경우 타이머 종료
                clearInterval(timer)
                inputField.value = "";
            }
        }
        function initTimer(){ // 시간 1초씩 감소
            if(timeLeft > 0){
                timeLeft --;
                typingTime.innerText = timeLeft;
            }  else{
                clearInterval(timer)
            }
        }
        function resetGame(){ // 게임 종료 및 try again 버튼 클릭 시 리셋
            randomParagraph()
            charIndex = mistakes = isTyping = 0;
            timer, maxTime = 60
            clearInterval(timer)
            inputField.value = "";
            timeLeft = maxTime;
            typingWpm.innerText = 0;
            typingCpm.innerText = 0;
            typingTime.innerText = timeLeft
            typingMistake.innerText = 0
        }
        // 단어 랜덤 선택
        randomParagraph();

        // 키 입력 시
        typingAgain.addEventListener("click", resetGame)
        inputField.addEventListener("input", initTyping);
320x100
댓글
© 2022 WonSeok, All rights reserved