jineecode

2020.12.01 본문

Review

2020.12.01

지니코딩 2020. 12. 1. 10:10

 

HTML

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <scrip
      src="https://kit.fontawesome.com/0eec6e2faf.js"
      crossorigin="anonymous"
    ></scrip>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" type="text/css" href="style.css" />
    <title>Typing Game</title>
  </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">게임을 불러오는 중</button>
    <script src="main.js"></script>
  </body>
</html>

CSS

* {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.header {
  width: 100%;
  background: #3b5999;
  color: white;
  text-align: center;
  padding: 1rem;
}

.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: white;
  border: none;
  margin-top: 3rem;
  cursor: pointer;
}

.loading {
  background: #ccc;
  cursor: not-allowed;
}

JS

 

1. word-input창을 가져온다.

const wordInput = document.querySelector('.word-input')
console.log(wordInput)

결과: <input type="text" class="word-input">

 

input창에 text를 가져오기 위해서는?

 

input이 되는 이벤트가 발생할 때마다 value를 불러주면 된다.

wordInput.addEventListener('event', 'function')

 

2. input 이벤트와 함께 value를 가져온다.

wordInput.addEventListener('input', ()=>{
  console.log(wordInput.value);
})

결과:

3. 주어진 Hello와 타이핑한 value가 같은 경우에 점수를 올려준다.

 3-1 획득 점수는 변수이기 때문에 score=0 을 걸어놓는다. 또한 score도 가져온다.

 3-2 주어진 단어 word-display도 DOM 해준다.

 3-3 word-display에 innerHTML을 넣어 담겨있는 값이 무엇인지 확인한다.

innerText는 공백미포.

let score = 0;
const wordInput = document.querySelector('.word-input')
const wordDisplay = document.querySelector('.word-display')
const scoreDisplay = document.querySelector('.score')
wordInput.addEventListener('input', ()=>{
  console.log(wordInput.value, wordDisplay.innerHTML);
  console.log(wordInput.value, wordDisplay.innerText);
})

결과:

 

4. 주어진 단어 Hello 와 입력될 value 값이 같아야 한다.

 

wordInput.addEventListener('input', ()=>{
  console.log(wordInput.value===wordDisplay.innerText);
})

결과:

 

5. 대소문자를 구별하지 않게 하기 위해 소문자 메서드를 사용한다.

wordInput.addEventListener('input', ()=>{
  // console.log(wordInput.value, wordDisplay.innerHTML);
  console.log(wordInput.value.toLowerCase() ===wordDisplay.innerText.toLowerCase());
})

결과: 

 

 

 

맞게 타이핑 했을 경우 스코어를 1점 증가시킨다.

 score++;

 

6. 본격적으로 조건문을 사용하자.

wordInput.addEventListener('input', ()=>{
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){
    score++;
    scoreDisplay.innerText = score;
  }
})

이때 맞는 타이핑을 쳤을 경우, value 값을 초기화 시켜야 함.

 

wordInput.value="";

 

 

최종 js

let score = 0;
const wordInput = document.querySelector('.word-input')
const wordDisplay = document.querySelector('.word-display')
const scoreDisplay = document.querySelector('.score')
// console.log(wordInput)


wordInput.addEventListener('input', ()=>{
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){
    score++;
    scoreDisplay.innerText = score;
    wordInput.value="";
  }
})

addEventListner에 담긴 함수를 따로 선언해서 코드가 깔끔하게 보이도록 한다.

 

wordInput.addEventListener('input', checkMatch)

function checkMatch() {
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){
    score++;
    scoreDisplay.innerText = score;
    wordInput.value="";
  }
}

 

 


이제 시작버튼을 눌렀을 때 카운트다운이 되도록 코드를 짜보자.

삼항 연산자 : (조건) ? 참일 경우 : 거짓일 경우

 

1. 시간에 따른 사용변수를 걸어준다.

9초부터 카운트다운 되게 할 것임.

let time = 9;

 

2. 삼항 연산자로 함수를 짠다.

0초보다 크게 되면 1초씩 감소하고,

그렇지 않으면 게임을 종료시킨다.

는 조건문

function countDown() {
  time > 0 ? time -- : isPlaying = false;
}

isPlaying은 기본 false로 설정.

let isPlaying = false;

 

이 함수를 1초마다 계속 실행시켜주는 인터벌 함수를 사용한다.

setInterval(countDown, 1000);

끌 때는 clearInterval을 사용하면 된다.

 

 

시간을 줄어들게 하려면 time 도 js로 불러와야 한다

const timeDisplay = document.querySelector('.time')
function countDown() {
  time > 0 ? time -- : isPlaying = false;
  timeDisplay.innerText = time;
}

 

3. interval 함수는 게임시작을 눌렀을 때 카운트 시작하게 만들고 싶다.

그러면 일단 button 을 가져온다.

const button = document.querySelector('.button')

함수를 만든다.

buttonChange('게임시작')
function buttonChange(text){
  button.innerText = text;
}

결과:

 

4. 조건문을 만든다.

function buttonChange(text){
  button.innerText = text;
  text === '게임시작' ? button.classList.remove('loading') : button.classList.add('loading')
}

text에 게임시작이면 loading을 삭제하고,

게임시작이 아니면 loading을 추가한다.

 

 

buttonChange('게임종료')

이렇게 되면 당연히 if문에서 false조건이 발생되므로 버튼이 바뀐다.

 

5. 

let timeInterval;
function run() {
  time= 7;
  timeInterval = setInterval(countDown, 1000);
}

time=7;

리셋시 time= 7; 부터 다시.

 

7초가 모두 끝났어도 setinterval은 돌아가고 있는 중이기 때문에 클리어 시켜줘야한다.

 

function countDown() {
  time > 0 ? time -- : isPlaying = false;
  if(!isPlaying){
    clearInterval(timeInterval)
  }
  timeDisplay.innerText = time;
}

 

지속해서 time=7; 이 반복되고 있는 상황이므로 

변수를 하나 만들어준다.

 

const GAME_TIME = 7;

 

처음에는

isPlaying = false;

상태이기 때문에

run을 했을 때

isPlaying = true;

로 시작해야 작동한다.

 

function run() {
  isPlaying = true;
  time= GAME_TIME;
  timeInterval = setInterval(countDown, 1000);
}

function countDown() {
  time > 0 ? time -- : isPlaying = false;
  if(!isPlaying){
    clearInterval(timeInterval)
  }
  timeDisplay.innerText = time;
}

isPlaying = true;

>>

카운트가 0이 되면 false가 되고

비로소 조건문이 동작한다.

 

 

6.

let words = [];
init();

function init(){
  getWords()
}

function getWords(){
  words = ['Hello', 'Banana', 'Apple', 'Cherry'];
}

전역변수에 words를 넣어두고, 함수로 단어를 불러온다.

 

event 함수를 init에 넣으면 조금 더 깔끔해진다.

 

init();

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

 

7.

//단어 불러오기
function getWords(){
  words = ['Hello', 'Banana', 'Apple', 'Cherry'];
  buttonChange('게임시작')
}

 getWords가 실행이 되면 buttonChange를 불러서 게임이 시작이 된다.

 

 

8. 게임이 실행 중인지 아닌지 확인하는 메서드 필요

let checkInterval;
function checkStatus(){
  if(!isPlaying && time === 0){
    buttonChange('게임시작...')
    clearInterval(checkInterval)
  }
}

플레이중이 아니고 time이 0초면 버튼이 다시 '게임시작...'이 되고 인터벌을 클리어해준다.

 

9. 게임이 실행되는 자리에도 checkInterval을 넣어준다.

function run() {
  isPlaying = true;
  time= GAME_TIME;
  timeInterval = setInterval(countDown, 1000);
  checkInterval = setInterval(checkStatus, 50);
}

 

10. 단어 일치 체크할 때 게임이 실행중이 아닌데 입력을 하면 return 시키는 조건문도 넣어준다.

function checkMatch() {
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){
    wordInput.value="";
    if(!isPlaying){
      return
    }
    score++;
    scoreDisplay.innerText = score;
    time = GAME_TIME;
  }
}

 

11. 랜덤한 숫자를 만들어서 단어가 랜덤하게 나오게 만드는 함수 추가.

 

//단어 일치 체크
function checkMatch() {
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){
    wordInput.value="";
    if(!isPlaying){
      return
    }
    score++;
    scoreDisplay.innerText = score;
    time = GAME_TIME;
    const randomIndex = Math.floor(Math.random() * words.length);
    wordDisplay.innerText = words[randomIndex]
  }
}

Math.floor: 소숫점 버리기

 wordDisplay.innerText = words[randomIndex] :

단어를 불러오는 함수의 배열(words = ['Hello', 'Banana', 'Apple', 'Cherry'];)을 이런 식으로 호출한다.

 

 

12. 게임 중일 때 버튼이 게임중으로 바뀌게 하는 코드 추가

// 게임 실행
function run() {
  isPlaying = true;
  time= GAME_TIME;
  timeInterval = setInterval(countDown, 1000);
  checkInterval = setInterval(checkStatus, 50);
  buttonChange('게임중');
}

 

13. 게임이 실행중이면 버튼이 클릭되지 않게 코드추가

// 게임 실행
function run() {
  if (isPlaying) {
    return;
  }
  isPlaying = true;
  time= GAME_TIME;
  timeInterval = setInterval(countDown, 1000);
  checkInterval = setInterval(checkStatus, 50);
  buttonChange('게임중');
}

 

 

14. 배열에 api 넣어주기

참조 사이트 : random-word-api.herokuapp.com/home

github.com/axios/axios

 

axios/axios

Promise based HTTP client for the browser and node.js - axios/axios

github.com

 

최종

const GAME_TIME = 7;
let score = 0;
let time = GAME_TIME;
let isPlaying = false;
let timeInterval;
let checkInterval;
let words = [];

const wordInput = document.querySelector('.word-input');
const wordDisplay = document.querySelector('.word-display');
const scoreDisplay = document.querySelector('.score');
const timeDisplay = document.querySelector('.time');
const button = document.querySelector('.button');

// console.log(wordInput)


init();

function init(){
  buttonChange('게임시작')
  getWords()
  wordInput.addEventListener('input', checkMatch)
}

// 게임 실행
function run() {
  if (isPlaying) {
    return;
  }
  isPlaying = true;
  time= GAME_TIME;
  timeInterval = setInterval(countDown, 1000);
  checkInterval = setInterval(checkStatus, 50);
  buttonChange('게임중');
}


function checkStatus(){
  if(!isPlaying && time === 0){
    buttonChange('게임시작...')
    clearInterval(checkInterval)
  }
}

//단어 불러오기
function getWords(){
  axios.get('https://random-word-api.herokuapp.com/word?number=100')
    .then(function (response) {
      response.data.forEach((word)=>{
        if(word.length < 10){
          words.push(word);
        }
      })

      // handle success
      words=response.data;
    })
    .catch(function (error) {
      // handle error
      console.log(error);
    })
 

  // words = ['Hello', 'Banana', 'Apple', 'Cherry'];
  buttonChange('게임시작')
}


//단어 일치 체크
function checkMatch() {
  if(wordInput.value.toLowerCase() === wordDisplay.innerText.toLowerCase()){
    wordInput.value="";
    if(!isPlaying){
      return
    }
    score++;
    scoreDisplay.innerText = score;
    time = GAME_TIME;
    // wordInput.focus();
    // scoreDisplay.innerText = 0;
    const randomIndex = Math.floor(Math.random() * words.length);
    wordDisplay.innerText = words[randomIndex]
  }
}


// 버튼을 눌렀을 때 실행되도록.
//setInterval(countDown, 1000);
// buttonChange('게임시작')



function countDown() {
  time > 0 ? time -- : isPlaying = false;
  if(!isPlaying){
    clearInterval(timeInterval)
  }
  timeDisplay.innerText = time;
}


function buttonChange(text){
  button.innerText = text;
  text === '게임시작' ? button.classList.remove('loading') : button.classList.add('loading')
}

// setInterval
// timeInterval
// clearInterval
// getWords

'Review' 카테고리의 다른 글

2020.12.04  (0) 2020.12.04
20.11.30  (0) 2020.11.30
20.11.14  (0) 2020.11.14
20.11.12  (0) 2020.11.12
Comments