🗃️javascript/프로젝트

(클론코딩)타이핑 게임

하얀성 2022. 12. 13. 13:05

<js>

// 사용변수
const GAME_TIME = 9;
let score = 0;
let time = GAME_TIME;
let isPlaying = false;  
let timeInterval; //시간 간격 변수
let checkInterval;
let words = [];

const wordInput = document.querySelector('.word-input');     // html 클래스들을 js의 상수들에 넣어서 행위제어.
const wordDisplay = document.querySelector('.word-display');
const scoreDisplay = document.querySelector('.score');
const timeDisplay = document.querySelector('.time');
const button = document.querySelector('.button');

init();

function init() {
  getWords()
  wordInput.addEventListener('input',checkMatch);
}

function run() {// onclick을 선언해서 만들어준 상태.
  if (isPlaying) {
    return;
  }
  isPlaying = true; // true 값으로 변경.
  time = GAME_TIME;
  wordInput.focus();
  scoreDisplay.innerText = 0;
  timeInterval = setInterval(countDown, 1000); // 반복문만 있으면 시간이 지연이 안되니 사이 시간 값을 부여.
  checkInterval = setInterval(checkStatus, 50);// 짧은 시간내에 상태를 점검.
  buttonChange('게임중');
}

function checkStatus() { // 커서가 input에 머무르는게 아니라 게임시작버튼에 계속 돌아가 있게끔해줌.
  if(!isPlaying && time === 0) {
    buttonChange("게임시작");
    clearInterval(checkInterval);
    }
}

// 단어 불러오기
function getWords(){
  .then(function (response) {
    response.data.forEach((word) => { // words의 각 word를 비교하여 규격에 맞는 단어만 words에 push

      if(word.length < 10){
        words.push(word);
      }
    })
    buttonChange('게임시작'); // 다 넣고나면 게임이 가능한 상태가 됨
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
}

//단어 일치 체크
function checkMatch (){ // input 발생하면
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){ //wordInput의 값을 소문자로 다 인식하여 안에 있던 값과 일치하면
    wordInput.value=""; // 값 초기화해야 점수가 이상하게 오르지 않음.
    if(!isPlaying) { // return을 통해 단어 타이핑을 맞추지 못한채로 시간이 흘러 게임이 끝난 경우, false를 줘서 게임 실행이 진 상태에서 다시 실행이 안되게끔 해주는것.  
      return; // return을 통해 밑의 명령어는 실행되지 않고 자동 종료됨.
    }
    score++;
    scoreDisplay.innerText = score; // score값 더해서 총합저장.
    time = GAME_TIME;
    const randomIndex = Math.floor(Math.random()* words.length); // 오타로 애먹은 부분. 상수에 난수 발생시켜서
    wordDisplay.innerText = words[randomIndex]; // 상수를 단어들의 배열값에 추가해서 단어가 랜덤으로 나오게끔해줌
  }
 
}

function countDown(){ // 카운트 다운 해줌.
  time > 0 ? time-- : isPlaying = false; // 카운트로 계속 줄여나가다가, 카운트가 0이 되면 false값을 줘라.

  if(!isPlaying){ // isPlaying이 false가 된다면 timeInterval을 종료시켜라.(run에서 true 였다가, 앞의 요인으로 false가 됨)
    clearInterval(timeInterval);
  }
  timeDisplay.innerText = time; //감소된 시간 값을 넣어서 창에 표시해줌.
}

function buttonChange(text){ // 게임시작 되면 loading class 삭제.
  button.innerText =  text;
  text === '게임시작' ? button.classList.remove('loading') : button.classList.add('loading') // 게임가능 상태? 불가상태면 loading이 렌더링.
}

<html>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Typing Game</title>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
  <div class="header">
    <h1>타이핑마스터!</h1>
  </div>
  <div class="word-display">
    Hello
  </div>
  <div class="word-input-box">
    <input type="text" class="word-input" />
  </div>
  <div class="game-info">
    <div>
      남은 시간: <span class="time">0</span>
    </div>
    <div>
      획득점수: <span class="score">0</span>
    </div>
  </div>
  <button class="button loading" onclick="run()">게임을 불러오는중...</button>
  <script src="js/main.js"></script>
</body>
</html>

<css>

* {
  margin: 0;
  padding: 0;
}

body {
  display: flex; /*  정렬을 위한 컨테이너. 기존 배경에 맞게 자동정렬*/
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.header {
  width: 100%;
  background: #3b5999;
  color: #fff;
  text-align: center;
  padding: 1rem; /* 다 16픽셀이 들어갈 수 있게끔 */
}

.word-display {
  margin-top: 3rem;
  font-size: 80px;
  color: #3b5999;
}
.word-input-box {
  margin-top: 2rem;
}
.word-input {
  padding: 0.5rem;
  width: 300px;
}
.game-info {
  margin-top: 2rem;
  font-size: 0.8rem;
  display: flex;
  justify-content: space-between;
  width: 200px;
}

.time, .score {
  font-size: 30px;
}

.button {
  width: 200px;
  height: 35px;
  background: #3b5999;
  color: #fff;
  border: none;
  margin-top: 3rem;
  cursor: pointer;
}
.loading {
  background: #ccc;
  cursor: not-allowed;
}

<결과>

랜덤 단어들이 나와서 그 단어에 맞게 타이핑하면 점수가 상승


 

<느낀점>

클래스와 querySelector를 이용한 html 접근. 

다양한 기본요소를 써서 복습에 효과적인 코드들. 

css도 다양하게 다뤄볼 수 있어 좋은 코드였다.

물론 API연동까지도 해볼수 있는! 복습 코드에 재격.

 

출처: https://youtu.be/_CsGSE5gwTA