코딩 공부/JAVASCRIPT

자바스크립트 게임 이펙트(Game Effect)01-(3)

천서리 2023. 5. 3. 22:21
QUOTE THE DAY

“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”

- 이글슨 (Eagleson)
반응형

게임 이펙트(Game Effect)란?

자바스크립트를 사용하여 구현된 게임에서의 이펙트는 일반적으로 다양한 애니메이션 기술과 그래픽 처리 기술을 사용하여 구현됩니다. 이를 통해 게임에 동적이고 생동감 있는 느낌을 부여할 수 있습니다.

 

 

 


추가 선택자

const musicRepeat = musicWrap.querySelector("#control-repeat");
const musicListBtn = musicWrap.querySelector("#control-list")
const musicList = musicWrap.querySelector(".music__list");
const musicListUl = musicWrap.querySelector(".music__list ul");
const musicListClose = musicWrap.querySelector(".music__list h3 .close");

 

 

 

반복 버튼 클릭

//반복 버튼 클릭
musicRepeat.addEventListener("click", () => {
    let getAttr = musicRepeat.getAttribute("class");

    switch(getAttr){
        case "repeat" :
            musicRepeat.setAttribute("class", "repeat_one");
            musicRepeat.setAttribute("title", "한곡 반복");
        break;
        case "repeat_one" :
            musicRepeat.setAttribute("class", "shuffle");
            musicRepeat.setAttribute("title", "랜덤 반복");
        break;
        case "shuffle" :
            musicRepeat.setAttribute("class", "repeat");
            musicRepeat.setAttribute("title", "전체 반복");
        break;
    }
});
  1. musicRepeat 요소에 클릭 이벤트 리스너를 등록합니다.
  2. 클릭 이벤트가 발생하면, musicRepeat 요소의 클래스 속성 값을 가져옵니다.
  3. switch 문을 이용하여 getAttr 변수에 할당된 클래스 값에 따라 다른 동작을 수행합니다.
  4. getAttr 값이 "repeat" 인 경우, musicRepeat 요소의 클래스 속성을 "repeat_one" 로 변경하고, 타이틀 속성 값을 "한곡 반복" 으로 변경합니다.
  5. getAttr 값이 "repeat_one" 인 경우, musicRepeat 요소의 클래스 속성을 "shuffle" 로 변경하고, 타이틀 속성 값을 "랜덤 반복" 으로 변경합니다.
  6. getAttr 값이 "shuffle" 인 경우, musicRepeat 요소의 클래스 속성을 "repeat" 로 변경하고, 타이틀 속성 값을 "전체 반복" 으로 변경합니다.

 

 

//오디오가 끝나면
musicAudio.addEventListener("ended", () => {
    let getAttr = musicRepeat.getAttribute("class");

    switch(getAttr){
        case "repeat" :
            nextMusic();
        break;
        case "repeat_one" :
            playMusic();
        break;
        case "shuffle" :
            let randomIndex = Math.floor(Math.random() * allMusic.length + 1);    //랜덤 인덱스 생성


            do {
                randomIndex = Math.floor(Math.random() * allMusic.length + 1);
            } while (musicIndex == randomIndex);
            
            musicIndex = randomIndex;   //현재 인덱스를 랜덤 인덱스로 변경

            loadMusic(musicIndex);
            playMusic();
        break;
    }
    playListMusic();
});
  1. musicAudio"라는 ID를 가진 오디오 요소가 종료될 때 발생하는 "ended" 이벤트에 대한 리스너를 등록합니다.
  2. musicRepeat"라는 ID를 가진 HTML 요소의 클래스를 가져와서 switch 문을 이용해 각각의 클래스에 맞는 동작을 수행합니다.
  3. "repeat" 클래스를 가진 경우, 다음 곡을 재생하는 nextMusic 함수를 호출합니다.
  4. repeat_one" 클래스를 가진 경우, 현재 곡을 다시 재생합니다.
  5. "shuffle" 클래스를 가진 경우, 랜덤 인덱스를 생성하고, 현재 인덱스와 다른 랜덤 인덱스를 얻을 때까지 랜덤 인덱스를 생성합니다.
  6. 랜덤 인덱스를 현재 인덱스로 설정하고, 해당 인덱스의 음악을 로드하고 재생합니다.
  7. playListMusic" 함수를 호출하여 플레이리스트에 있는 음악 정보를 업데이트합니다.

 

 

//뮤직 리스트 버튼
musicListBtn.addEventListener("click", () => {
    musicList.classList.add("show");
});

//뮤직 리스트 닫기 버튼
musicListClose.addEventListener("click", () => {
    musicList.classList.remove("show");
});

이벤트 리스너는 웹 페이지에서 발생하는 이벤트를 감지하고, 이벤트가 발생했을 때 원하는 동작을 수행할 수 있게 해줍니다.

여기서는 두 개의 이벤트 리스너가 등록되어 있습니다.

 

1. musicListBtn.addEventListener("click", () => { ... });

  • 뮤직 리스트 버튼(musicListBtn)을 클릭했을 때 발생하는 'click' 이벤트를 감지합니다.
  • 클릭 이벤트가 발생하면 화면에 보이는 뮤직 리스트(musicList) 요소에 'show' 클래스를 추가합니다.
  • 뮤직 리스트가 화면에 보이게 됩니다.

 

2. musicListClose.addEventListener("click", () => { ... });

  • 뮤직 리스트 닫기 버튼(musicListClose)을 클릭했을 때 발생하는 'click' 이벤트를 감지합니다.
  • 클릭 이벤트가 발생하면 뮤직 리스트(musicList) 요소에서 'show' 클래스를 제거합니다.
  • 뮤직 리스트가 화면에서 사라지게 됩니다.

 

 

//뮤직 리스트 구현하기
for(let i=0; i<allMusic.length; i++){
    let li = `
        <li data-index="${i+1}">
            <span class="img">
                <img class="img" src="img/${allMusic[i].img}.png" alt="${allMusic[i].name}">
            </span>
            <span class="title">
                <strong>${allMusic[i].name}</strong>
                <em>${allMusic[i].artist}</em>
                <audio class="${allMusic[i].audio}" src="audio/${allMusic[i].audio}.mp3"></audio>
            </span>
            <span class="audio-duration" id="${allMusic[i].audio}">3:40</span>
        </li>
    `;

    // musicListUl.innerHTML += li;
    musicListUl.insertAdjacentHTML("beforeend", li);

    //리스트에 음악 시간 불러오기
    let liAudioDuration = musicListUl.querySelector(`#${allMusic[i].audio}`);   //리스트에서 시간을 표시할 선택자
    let liAudio = musicListUl.querySelector(`.${allMusic[i].audio}`);            //리스트에서 오디오 파일 선택
    liAudio.addEventListener("loadeddata", () => {
        let audioDuration = liAudio.duration;
        // console.log(audioDuration)
        let totalMin = Math.floor(audioDuration / 60);
        let totalSec = Math.floor(audioDuration % 60);
        if(totalSec < 10) totalSec = `0${totalSec}`;
        liAudioDuration.innerText = `${totalMin}:${totalSec}`;
        liAudioDuration.setAttribute("data-duration", `${totalMin}:${totalSec}`);
    });
}
  1. for문을 이용하여 allMusic 배열의 길이만큼 반복하여 각 음악의 정보를 리스트 요소(li)에 추가합니다.
  2. data-index 속성을 이용하여 각 음악의 인덱스 값을 저장합니다.
  3. li 변수에는 문자열 템플릿을 이용하여 음악 리스트에 표시할 HTML 코드를 작성합니다.
  4. span 요소를 이용하여 음악 제목, 아티스트, 앨범 아트 이미지, 오디오 태그, 음악 길이 등을 표시합니다.
  5. insertAdjacentHTML() 메서드를 이용하여 ul 요소에 li 요소를 추가합니다.
  6. 리스트에 음악의 시간을 불러오기 위해, li 변수에서 오디오 요소를 선택하고, 이를 이용하여 음악의 길이를 계산합니다.
  7. loadeddata 이벤트를 사용하여 오디오 요소가 로드되었을 때 이벤트 리스너가 실행되도록 합니다.
  8. 오디오의 길이를 계산하여 분:초 형식으로 변환하여 li 요소의 시간을 표시합니다.
  9. totalSec이 10보다 작으면 0을 붙여 2자리 숫자로 만들어줍니다. 그리고 이를 li 요소의 data-duration 속성 값으로 추가합니다.

 

 

 

//뮤직리스트를 클릭하면 재생
function playListMusic(){
    const musicListAll = musicListUl.querySelectorAll("li");    //뮤직 리스트 목록
    
    for(let i=0; i<musicListAll.length; i++){
        let audioTag = musicListAll[i].querySelector(".audio-duration");

        musicListAll[i].setAttribute("onclick", "clicked(this)");

        if(musicListAll[i].classList.contains("playing")){
            musicListAll[i].classList.remove("playing");
            let dataAudioDuration = audioTag.getAttribute("data-duration");
            audioTag.innerText = dataAudioDuration;
        }

        if(musicListAll[i].getAttribute("data-index") == musicIndex){
            musicListAll[i].classList.add("playing");
            audioTag.innerText = "재생중";
        }
    }
}
playListMusic();
  1. musicListUl에서 모든 li 요소를 선택하여 musicListAll에 저장합니다.
  2. for문을 이용하여 모든 li 요소에 대해 아래의 작업을 수행합니다.
  3. li 요소에 onclick 이벤트를 추가합니다. 이때, 클릭한 요소를 clicked() 함수에 인자로 전달합니다.
  4. 현재 재생 중인 음악을 나타내는 playing 클래스가 있는 경우, 해당 클래스를 제거하고, 음악의 길이를 data-duration 속성 값으로 대체합니다.
  5. 클릭한 음악의 인덱스와 현재 재생 중인 음악의 인덱스를 비교하여 일치하는 경우, 해당 li 요소에 playing 클래스를 추가하고, 음악 길이를 "재생중"으로 대체합니다.

 

 

//뮤직 리스트를 클릭하면
function clicked(el){
    let getIndex = el.getAttribute("data-index");
    // alert(getIndex);
    musicIndex = getIndex;
    loadMusic(musicIndex);
    playMusic();
    playListMusic();
}
  1. clicked() 함수는 클릭한 요소의 data-index 속성 값을 가져와서 musicIndex 변수에 저장합니다.
  2. loadMusic() 함수를 호출하여 선택한 음악을 로드하고, playMusic() 함수를 호출하여 해당 음악을 재생합니다.
  3. playListMusic() 함수를 호출하여 현재 재생 중인 음악을 표시하기 위해 뮤직 리스트 목록을 업데이트합니다.

따라서, 이 코드는 뮤직 리스트에서 음악을 클릭하면 clicked() 함수를 호출하여 선택한 음악을 로드하고 재생하고, 현재 재생 중인 음악을 표시하기 위해 playListMusic() 함수를 호출합니다.

반응형
Adventure Time - BMO