코딩 공부/JAVASCRIPT

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

천서리 2023. 4. 27. 22:17
QUOTE THE DAY

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

- 이글슨 (Eagleson)
반응형

게임 이펙트(Game Effect)란?

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

 

 

 

''


선택자

const musicWrap = document.querySelector(".music__wrap");
const musicName = musicWrap.querySelector(".music__control .title h3");
const musicArtist = musicWrap.querySelector(".music__control .title p");
const musicView = musicWrap.querySelector(".music__view .image img");
const musicAudio = musicWrap.querySelector("#main-audio");
const musicPlay = musicWrap.querySelector("#control-play");
const musicPrevBtn = musicWrap.querySelector("#control-prev");
const musicNextBtn = musicWrap.querySelector("#control-next");
const musicProgress = musicWrap.querySelector(".progress");
const musicProgressBar = musicWrap.querySelector(".progress .bar");
const musicProgressBarCurrent = musicWrap.querySelector(".progress .timer .current");
const musicProgressBarDuration = musicWrap.querySelector(".progress .timer .duration");

 

 

음악 재생

window.addEventListener("load", () => {
    loadMusic(musicIndex);
    console.log(musicIndex);
});
let musicIndex = 2     //현재 음악 인덱스
const loadMusic = (num) => {
    musicName.innerText = allMusic[num-1].name;             //뮤직 이름
    musicArtist.innerText = allMusic[num-1].artist;         //뮤직 아티스트
    musicView.src = `img/${allMusic[num-1].img}.png`;       //뮤직 이미지
    musicView.alt = allMusic[num-1].name;                   //뮤직 이미지 alt
    musicAudio.src =`audio/${allMusic[num-1].audio}.mp3`;   //뮤직 파일
}
  1. musicName.innerText: 음악의 이름을 나타내는 요소의 내부 텍스트를 변경합니다. innerText는 해당 요소의 내부 텍스트 값을 변경할 때 사용합니다. allMusic[num-1].name을 이용하여 num에 해당하는 인덱스의 뮤직 이름을 가져옵니다.
  2. musicArtist.innerText: 음악의 아티스트를 나타내는 요소의 내부 텍스트를 변경합니다. allMusic[num-1].artist를 이용하여 num에 해당하는 인덱스의 뮤직 아티스트를 가져옵니다.
  3. musicView.src: 음악 이미지 파일의 경로를 변경합니다. allMusic[num-1].img를 이용하여 num에 해당하는 인덱스의 뮤직 이미지 파일명을 가져옵니다. 그리고 img/.png를 붙여서 이미지 파일의 경로를 완성합니다.
  4. musicView.alt: 음악 이미지의 대체 텍스트를 변경합니다. allMusic[num-1].name을 이용하여 num에 해당하는 인덱스의 뮤직 이름을 가져옵니다.
  5. musicAudio.src: 음악 파일의 경로를 변경합니다. allMusic[num-1].audio를 이용하여 num에 해당하는 인덱스의 뮤직 파일명을 가져옵니다. 그리고 audio/.mp3를 붙여서 음악 파일의 경로를 완성합니다.

 

 

재생

const playMusic = () => {
    musicWrap.classList.add("paused");
    musicPlay.setAttribute("title", "정지");
    musicPlay.setAttribute("class", "stop");
    musicAudio.play();
}
  1. musicWrap.classList.add("paused"): musicWrap 요소에 paused 클래스를 추가합니다. paused 클래스는 CSS 스타일링을 통해 음악을 일시정지할 때 사용합니다.
  2. musicPlay.setAttribute("title", "정지"): musicPlay 요소의 title 속성 값을 "정지"로 변경합니다. title 속성은 해당 요소에 마우스를 올렸을 때 나타나는 툴팁의 내용을 나타냅니다.
  3. musicPlay.setAttribute("class", "stop"): musicPlay 요소의 class 속성 값을 "stop"으로 변경합니다. "stop" 클래스는 CSS 스타일링을 통해 정지 버튼을 나타낼 때 사용합니다.
  4. musicAudio.play(): musicAudio 요소의 play() 메서드를 호출하여 음악 파일을 재생합니다.

 

 

정지

const pauseMusic = () => {
    musicWrap.classList.remove("paused");
    musicPlay.setAttribute("title", "재생");
    musicPlay.setAttribute("class", "play");
    musicAudio.pause();
}
  1. musicWrap.classList.remove("paused"): musicWrap 요소에서 paused 클래스를 제거합니다. paused 클래스는 CSS 스타일링을 통해 음악을 일시정지할 때 사용합니다.
  2. musicPlay.setAttribute("title", "재생"): musicPlay 요소의 title 속성 값을 "재생"으로 변경합니다. title 속성은 해당 요소에 마우스를 올렸을 때 나타나는 툴팁의 내용을 나타냅니다.
  3. musicPlay.setAttribute("class", "play"): musicPlay 요소의 class 속성 값을 "play"으로 변경합니다. "play" 클래스는 CSS 스타일링을 통해 재생 버튼을 나타낼 때 사용합니다.
  4. musicAudio.pause(): musicAudio 요소의 pause() 메서드를 호출하여 음악 파일을 일시정지합니다.

 

 

이전곡 듣기

const prevMusic = () => {
    // musicIndex--;
    // if(musicIndex == 0)musicIndex = allMusic.length;

    musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;  //삼항연산자로 사용 가능

    loadMusic(musicIndex);
    playMusic();
}
  1. musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;: 삼항 연산자를 이용하여 musicIndex 값을 이전 값으로 변경합니다. 만약 musicIndex 값이 1이라면 musicIndex 값을 allMusic 배열의 마지막 인덱스 값으로 변경하고, 그렇지 않으면 musicIndex 값을 1 감소시킵니다. 이렇게 변경된 musicIndex 값을 loadMusic 함수에 전달하여 해당 음악 정보를 화면에 출력하고, playMusic 함수를 호출하여 음악을 재생합니다.
  2. loadMusic(musicIndex): musicIndex 값을 전달하여 해당 음악 정보를 loadMusic 함수를 통해 화면에 출력합니다.
  3. playMusic(): 이전 음악 정보가 출력된 후에는 playMusic 함수를 호출하여 음악을 자동으로 재생합니다.

 

 

다음곡 듣기

const nextMusic = () => {
    // musicIndex++;
    // if(musicIndex == allMusic.length+1)musicIndex = 1;
    
    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;  //삼항연산자로 사용 가능

    loadMusic(musicIndex);
    playMusic();
}
  1. musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;: 삼항 연산자를 이용하여 musicIndex 값을 다음 값으로 변경합니다. 만약 musicIndex 값이 allMusic 배열의 마지막 인덱스와 동일하다면 musicIndex 값을 1로 변경하고, 그렇지 않으면 musicIndex 값을 1 증가시킵니다. 이렇게 변경된 musicIndex 값을 loadMusic 함수에 전달하여 해당 음악 정보를 화면에 출력하고, playMusic 함수를 호출하여 음악을 재생합니다.
  2. loadMusic(musicIndex): musicIndex 값을 전달하여 해당 음악 정보를 loadMusic 함수를 통해 화면에 출력합니다.
  3. playMusic(): 다음 음악 정보가 출력된 후에는 playMusic 함수를 호출하여 음악을 자동으로 재생합니다.

 

 

뮤직 진행바 

//뮤직 진행바
musicAudio.addEventListener("timeupdate", e => {
    console.log(e);
    const currentTime = e.target.currentTime;                       //현재 재생되는 시간
    const duration = e.target.duration;                             //오디오의 총 길이
    let progressWidth = (currentTime/duration) * 100;                        //전체길이에서 현재 진행되는 시간을 백분위 단위로 나누는    

    musicProgressBar.style.width = `${progressWidth}%`;

    //전체 시간
    musicAudio.addEventListener("loadeddata", () => {
        let audioDuration = musicAudio.duration;
        let totalMin = Math.floor(audioDuration / 60);
        let totalSec = Math.floor(audioDuration % 60);
        if(totalSec < 10) totalSec = `0${totalSec}`;
        musicProgressBarDuration.innerText = `${totalMin}:${totalSec}`;
    });

    //진행 시간
    let currentMin = Math.floor(currentTime / 60);
    let currentSec = Math.floor(currentTime % 60);
    if(currentSec < 10) currentSec = `0${currentSec}`;
    musicProgressBarCurrent.innerText = `${currentMin}:${currentSec}`;
});
  1. 현재 재생 중인 음악의 재생 시간인 currentTime과 총 길이인 duration을 구합니다. 그리고 currentTimeduration으로 나눈 후 100을 곱해 현재 음악의 재생 진행 상태를 계산합니다.
  2. 계산된 값을 musicProgressBar의 스타일 속성 width에 적용하면, 뮤직 진행바의 길이가 현재 음악의 재생 진행 상태에 맞게 변경됩니다.
  3. loadeddata" 이벤트를 등록하여 뮤직 오디오가 로드되면, 오디오의 총 길이를 계산하여 musicProgressBarDuration 요소에 표시합니다.
  4. 현재 음악의 재생 시간인 currentMincurrentSec를 구하여 musicProgressBarCurrent 요소에 표시합니다.

 

 

진행 버튼 클릭

//진행 버튼 클릭
musicProgress.addEventListener("click", (e) =>{
    let progressWidth = musicProgress.clientWidth;  //진행바 전체 길이
    let clickOffsetX = e.offsetX;                   //진행바를 기준으로 측정되는 X좌표 값
    let songDuration = musicAudio.duration;         //오디오 전체 길이

    //백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꿈
    musicAudio.currentTime = (clickOffsetX/progressWidth) * songDuration;
});

 

musicProgress 요소에 click 이벤트를 추가하여 클릭하면 실행되도록 합니다.

이벤트 핸들러 함수에서는 musicProgress 요소의 전체 길이(clientWidth)와 클릭한 지점의 X 좌표 값(e.offsetX)을 이용하여 클릭한 지점의 백분위(clickOffsetX/progressWidth)를 계산합니다.

이 값을 오디오의 총 길이(musicAudio.duration)에 곱하여 클릭한 지점에 해당하는 재생 시간으로 설정합니다.

이렇게 하면 사용자가 원하는 지점으로 진행바를 이동하여 재생을 이어나갈 수 있습니다.

 

 

 

플레이 버튼 클릭

musicPlay.addEventListener("click", () => {
    const isMusicPaused = musicWrap.classList.contains("paused");   //음악 재생중
    isMusicPaused ? pauseMusic() : playMusic();
});
  1. musicWrap.classList.contains("paused")musicWrap 요소의 class 속성에 "paused"라는 클래스가 있는지 확인하여, 있다면 true, 없다면 false를 반환합니다.
  2. isMusicPaused 변수에 이 값을 저장한 뒤, isMusicPausedtrue이면 pauseMusic() 함수를 실행하고, false이면 playMusic() 함수를 실행합니다.

 

 

반응형
Adventure Time - BMO