jineecode
2020.12.01 본문
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
최종
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 |