본문 바로가기
Effect

searchEffect07

by 코터틀 2022. 10. 27.
반응형

searchEffect07

2분 동안 CSS 속성을 많이 검색하면 점수가 올라갑니다.


HTML

배경음악을 컨트롤할 audio영역, 정답 입력 영역, 타이머, 시작 버튼, 정답 카운트 영역, 정답, 오답 영역과 최종 스코어를 표시해주는 영역을 작성합니다.

<main id="main">
    <div class="search__wrap">
        <div class="search__audio">
            <span class="play">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path
                        d="M15 6.3706C15 4.65827 12.9884 3.73774 11.6926 4.85712L8.36317 7.73321C7.99989 8.04704 7.53583 8.21972 7.05576 8.21973L5.49998 8.21974C4.11928 8.21975 3 9.33903 3 10.7197V14.0127C3 15.3934 4.11929 16.5127 5.5 16.5127H7.0558C7.53587 16.5127 7.99993 16.6854 8.36322 16.9992L11.6926 19.8753C12.9884 20.9947 15 20.0741 15 18.3618V12.3662V6.3706Z"
                        fill="#223547"
                        stroke="#223547"
                        stroke-width="1.5"
                    />
                    <path d="M18 15.3667C18.6279 14.531 19 13.4923 19 12.3667C19 11.2411 18.6279 10.2024 18 9.3667" stroke="#223547" stroke-width="1.5" stroke-linecap="round" />
                    <path d="M20 18.3667C21.2558 16.6954 22 14.6179 22 12.3667C22 10.1155 21.2558 8.03802 20 6.3667" stroke="#223547" stroke-width="1.5" stroke-linecap="round" />
                </svg>
            </span>
            <span class="stop">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path
                        d="M14 6.3706C14 4.65827 11.9884 3.73774 10.6926 4.85712L7.36317 7.73321C6.99989 8.04704 6.53583 8.21972 6.05576 8.21973L4.49998 8.21974C3.11928 8.21975 2 9.33903 2 10.7197V14.0127C2 15.3934 3.11929 16.5127 4.5 16.5127H6.0558C6.53587 16.5127 6.99993 16.6854 7.36322 16.9992L10.6926 19.8753C11.9884 20.9947 14 20.0741 14 18.3618V12.3662V6.3706Z"
                        fill="#223547"
                        stroke="#223547"
                        stroke-width="1.5"
                    />
                    <path d="M18 14.1215L22.2427 9.87891" stroke="#223547" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
                    <path d="M18 9.87894L22.2427 14.1216" stroke="#223547" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
                </svg>
            </span>
            <audio id="audio" src="../assets/music/music_audio07.mp3" loop="loop"></audio>
            <audio id="audio_complete" src="../assets/music/Success 2.mp3"></audio>
            <audio id="audio_fail" src="../assets/music/fail.mp3"></audio>
        </div>

        <span>CSS 속성 검색 이벤트</span>
        <h1><a href="searchEffect.html">2분 동안 CSS 속성 검색하기</a></h1>
        <p class="desc">
            2분 동안 CSS 속성을 많이 검색하면 점수가 올라갑니다.<br />
            힌트보기는 한번 이용할 수 있습니다.
        </p>

        <div class="time">
            <span>2:00</span>
        </div>

        <div class="search__box">
            <label for="search">검색하기</label>
            <input type="text" id="search" placeholder="CSS 속성을 입력해주세요!" />
            <div class="start">버튼을 누르면 게임이 시작됩니다.</div>
        </div>

        <div class="search__info center">
            <div>전체 속성 갯수 : <span class="num">0</span></div>
            <div>현재 정답 갯수 : <span class="count">0</span></div>
        </div>

        <div class="search__answers"></div>

        <div class="search__missAnswers"></div>

        <div class="search__list"></div>

        <div class="search__result">
            <div class="svg__wrap">
                <svg>
                    ...
                </svg>
                <div class="result"></div>
                <button class="restart">다시하기</button>
            </div>
        </div>
    </div>
</main>
<!-- //main -->

JAVASCRIPT

선택자와 사용할 변수를 선언, 함수를 사용해 searchList 선택자에 데이터값을 넣어줍니다. 게임을 시작하기 위해 스크립트를 작성합니다. 게임 시작하면 '게임 시작'버튼과 css 속성 리스트를 안보이게 숨깁니다.
그리고 다시 시작을 했을 때 화면에 출력된 정답과 오답리스트를 숨김처리합니다. 타이머 시간은 1초 단위로 카운트되도록 설정합니다. 시작 했을 때 음악이 재생되도록 설정하고 오디오 아이콘이 전환되도록 설정해줍니다.
다음은 인풋 체크하기 함수를 사용하여 input변수에 현재 입력값에 띄어쓰기나 대소문자에 상관없이 정답이 비교되도록 저장하고, 조건문을 사용하여 input창에 입력한 값이 일치하면 true를 반환하여 정답을 표시해주고, 맞춘 개수를 더해주며 인풋창을 초기화 시킵니다.
정답을 객체화 시키기 위해 기본값은 false로 설정합니다. 게임이 종료되면 오답을 보여주어야하므로, 정답으로 출력된값을 제외한 값을 searchMissAnswers 선택자에 저장합니다.
타이머를 시작하기 위해 1초씩 감소시키고, 타이머가 0이 된다면 0.5초의 딜레이를 주어 endQuiz 함수를 실행시킵니다.
시간을 표시하기 위해서 만약 0초가 되면 0:00을 return해주고, 아니라면 분과 초에 120을 60으로 나눈 값을 각각 저장하여 디스플레이 표시를 세팅해줍니다.
게임이 끝나면 input창 위에 시작하기 버튼을 재생성하고 하단에 오답을 출력합니다. 음악 종료, 시간 정지와 게임 종료 메시지와 점수를 출력합니다.
그리고 다시 시작하기를 설정하여주면 끝입니다. (너무 길어요..)

const cssProperty = [
    { num: 1, name: 'accent-color', desc: '특정 요소에 색상을 지정할 때 사용됩니다.' },
    { num: 2, name: 'align-content', desc: '콘텐츠 아이템의 상하관계 정렬 상태를 설정합니다.' },
    { num: 3, name: 'align-items', desc: '콘텐츠 아이템의 내부 상하관계 정렬 상태를 설정합니다.' },
    { num: 4, name: 'align-self', desc: '개별적인 콘텐츠 아이템의 정렬 상태를 설정합니다.' },
    { num: 5, name: 'all', desc: '요소의 속성을 초기화 또는 상속을 설정합니다.' },
    ...
];

const searchTime = document.querySelector('.time span');
const searchList = document.querySelector('.search__list');
const searchAnswers = document.querySelector('.search__answers');
const searchMissAnswers = document.querySelector('.search__missAnswers');
const searchStart = document.querySelector('.search__box .start');
const searchInput = document.querySelector('#search');
const searchAudio = document.querySelector('#audio');
const searchAudioComplete = document.querySelector('#audio_complete');
const searchAudioFail = document.querySelector('#audio_fail');
const searchAudioPlay = document.querySelector('.play');
const searchAudioPause = document.querySelector('.stop');
const searchInfo = document.querySelector('.search__info .num');
const searchCount = document.querySelector('.search__info .count');
const searchResultWrap = document.querySelector('.search__result');
const searchResult = document.querySelector('.search__result .result');
const searchRestart = document.querySelector('.search__result .restart');

let timeReamining = 120, // 남은시간
    score = 0, // 점수
    count = 0, // 정답 갯수
    answers = {}; // 새로운 정답

function updateList() {
    cssProperty.forEach((data) => {
        searchList.innerHTML += `<span>${data.num}. ${data.name} : ${data.desc}</span>`;
    });
}
// updateList();

// 게임 시작하기
function startQuiz() {
    // 시작 버튼 없애기 & 속성 리스트 없애기
    searchStart.style.display = 'none';
    searchList.style.display = 'none';

    // 다시 시작할 때 기존 데이터 초기화
    searchAnswers.style.display = 'none';
    searchMissAnswers.style.display = 'none';

    // 시간 설정
    timeInterval = setInterval(reduceTime, 1000);

    // 뮤직 추가하기
    searchAudio.play();
    searchAudioPlay.style.display = 'block';
    searchAudioPause.style.display = 'none';

    // 총 속성 수
    searchInfo.textContent = cssProperty.length;

    // 정답 체크
    checkAnswers();
}

// 시작 후 음악 On/Off
searchAudioPlay.addEventListener('click', () => {
    searchAudioPlay.style.display = 'none';
    searchAudioPause.style.display = 'block';
    searchAudio.pause();
});
searchAudioPause.addEventListener('click', () => {
    searchAudioPlay.style.display = 'block';
    searchAudioPause.style.display = 'none';
    searchAudio.play();
});

// 인풋 체크하기
function checkInput() {
    let input = event.currentTarget.value.trim().toLowerCase();

    if (answers.hasOwnProperty(input) && !answers[input]) {
        answers[input] = true;

        // 정답 표시
        searchAnswers.style.display = 'block';
        searchAnswers.innerHTML += `<span>${input}</span>`;
        searchAudioComplete.play();

        // 점수 반영
        count++; // 정답 갯수 카운트++
        searchCount.textContent = count;

        // 정답 초기화
        searchInput.value = '';
    }
}

// 정답 체크하기 : 정답을 객체 파일로 만들기
function checkAnswers() {
    cssProperty.forEach((item) => {
        let answer = item.name.trim().toLocaleLowerCase();
        answers[answer] = false;
    });
    console.log(answers);
}

// 오답 보여주기
function missAnswers() {
    searchMissAnswers.style.display = 'block';

    cssProperty.forEach((item) => {
        let answer = item.name.trim().toLocaleLowerCase();
        if (!answers[answer]) {
            searchMissAnswers.innerHTML += `<span>${answer}</span>`;
        }
    });
}

// 시간 설정하기
function reduceTime() {
    timeReamining--;

    if (timeReamining == 0)
        setTimeout(() => {
            endQuiz();
        }, 500);

    searchTime.innerText = displayTime();
}

// 시간 표시하기
function displayTime() {
    if (timeReamining <= 0) {
        return '0:00';
    } else {
        let minutes = Math.floor(timeReamining / 60);
        let seconds = timeReamining % 60;

        // 초 단위가 한자리수 일 때 0을 추가
        if (seconds < 10) seconds = '0' + seconds;
        return minutes + ':' + seconds;
    }
}

// 게임 끝났을 때
function endQuiz() {
    // alert('게임이 끝낫습니다!!!');

    // 시작 버튼 만들기
    searchStart.style.display = 'block';
    searchStart.style.pointerEvents = 'none';

    // 오답 보여주기
    missAnswers();

    // 음악 끄기
    searchAudio.pause();
    searchAudioPlay.style.display = 'none';
    searchAudioPause.style.display = 'block';

    // 시간 정지
    clearInterval(timeInterval);

    // 메시지 출력
    searchResultWrap.classList.add('show');
    let point = Math.round((count / cssProperty.length) * 100);
    searchResult.innerHTML = `게임이 끝났습니다.<br>당신은 ${cssProperty.length}개중에 ${count}개를 맞추었습니다.<br>당신의 점수는 ${point}점 입니다.`;
}

// 다시 시작하기
function restart() {
    searchResultWrap.classList.remove('show');
    searchAudio.play();

    // 다시 시작할 때 기존 데이터 초기화
    searchAnswers.innerHTML = '';

    startQuiz();
    timeReamining = 120;
    count = 0;
    searchCount.innerText = '0';
}

// 버튼 이벤트
searchStart.addEventListener('click', startQuiz);
searchInput.addEventListener('input', checkInput);
searchRestart.addEventListener('click', restart);
반응형

'Effect' 카테고리의 다른 글

sliderEffect07  (5) 2022.10.27
searchEffect06  (1) 2022.10.19
sliderEffect06  (1) 2022.10.19
gameEffect03  (2) 2022.10.19
gameEffect02  (2) 2022.10.19

댓글


광고 준비중입니다.