Winnie The Pooh Bear 자바스크립트 게임 이펙트 _음악 재생

배움기록/JAVASCRIPT

자바스크립트 게임 이펙트 _음악 재생

코딩은 처음이라 2023. 4. 27. 21:26

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90
반응형

자바스크립트 게임 이펙트 _음악 재생

 

 

 

💜 게임 이펙트

코드 보기 / 완성 화면

 

 

HTML

<!-- 뮤직 플레이어 -->
<div class="music__wrap">
    <div class="music__inner">
        <div class="music__header">
            <span class="left"></span>
            <h2>music</h2>
            <span class="right"></span>
        </div>
        <div class="music__contents">
            <div class="music__view">
                <div class="image">
                    <img src="../game/img/music_view01.png" alt="">
                </div>
            </div>
            <div class="music__control">
                <div class="title">
                    <h3>노래 제목</h3>
                    <p>작가 이름</p>
                </div>
                <div class="progress">
                    <div class="bar">
                        <audio id="main-audio" src="audio/music_audio01.mp3"></audio>
                    </div>
                    <div class="timer">
                        <span class="currnet">0:00</span>
                        <span class="duration">3:55</span>
                    </div>
                </div>
                <div class="control">
                    <span>
                        <i class="repeat" id="control-repeat" title="전체 반복"></i>
                    </span>
                    <span>
                        <i class="prev" id="control-prev" title="이전곡 재생"></i>
                    </span>
                    <span>
                        <i class="play" id="control-play" title="재생"></i>
                    </span>
                    <span>
                        <i class="next" id="control-next" title="다음곡 재생"></i>
                    </span>
                    <span>
                        <i class="list" id="control-list" title="재생 목록"></i>
                    </span>
                    <!-- <span class="repeat_one">한곡반복</span>
                    <span class="shuffle">랜던 반복</span>
                    <span class="stop">정지 반복</span> -->
                </div>
            </div>
        </div>
        <div class="music__footer"></div>
    </div>
</div>
<!-- //뮤직 플레이어 -->

뮤직 플레이어 구역을 추가해줬습니다.

 

js

const allMusic = [
    {
        name: "1. Who Do You Think I Think You Are",
        artist: "Mini Vandals",
        img: "music_view01",
        audio: "music_audio01"
    }, {
        name: "2. The Monuments and Tunnels in Goa and Hampi",
        artist: "Bail Bonds",
        img: "music_view02",
        audio: "music_audio02"
    }, {
        name: "3. We Cruisin'",
        artist: "Otis McDonald",
        img: "music_view03",
        audio: "music_audio03"
    }, {
        name: "4. Forever Young",
        artist: "Otis McDonald",
        img: "music_view04",
        audio: "music_audio04"
    }, {
        name: "5. Ice & Fire",
        artist: "King Canyon",
        img: "music_view05",
        audio: "music_audio05"
    }, {
        name: "6. Emotional Mess",
        artist: "Amy Lynn & the Honey Men",
        img: "music_view06",
        audio: "music_audio06"
    }, {
        name: "7. The Last Goodbye",
        artist: "Telecasted",
        img: "music_view07",
        audio: "music_audio07"
    }, {
        name: "8. Big River",
        artist: "Telecasted",
        img: "music_view08",
        audio: "music_audio08"
    }, {
        name: "9. The Urban Groove",
        artist: "Hanu Dixit",
        img: "music_view09",
        audio: "music_audio09"
    }, {
        name: "10. The Monuments and Tunnels in Goa and Hampi",
        artist: "Bail Bonds",
        img: "music_view10",
        audio: "music_audio10"
    }
];

music.js파일을 따로 만들어 작업했습니다.

노래제목과 아티스트, 이미지, 음악을 배열로 저장해줬습니다.

 

선택자

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 musicProgressBar = musicWrap.querySelector(".progress .bar");
const musicProgress = musicWrap.querySelector(".progress");
const musicProgressCurrent = musicWrap.querySelector(".progress .timer .currnet");
const musicProgressDuration = musicWrap.querySelector(".progress .timer .duration");

사용할 선택자를 하나씩 만들어줬습니다.

 

 

음악 재생 , 정지 , 이전, 다음

 let musicIndex = 1;         //현재 음악 인덱스

//음악 재생
const loadMusic = (num) => {
    musicName.innerText = allMusic[num-1].name;                   //뮤직 이름
    musicArtist.innerText = allMusic[num-1].artist;               //아티스트 이름
    musicView.src = `../game/img/${allMusic[num-1].img}.png`;     //뮤직 이미지
    musicView.alt = allMusic[num-1].name;                         //뮤직 이미지 alt
    musicAudio.src = `audio/${allMusic[num-1].audio}.mp3`;        //뮤직 파일
}
//재생
const playMusic = () => {
    musicWrap.classList.add("paused");
    musicPlay.setAttribute("title", "정지");
    musicPlay.setAttribute("class", "stop");
    musicAudio.play();
};

//정지
const pauseMusic = () => {
    musicWrap.classList.remove("paused");
    musicPlay.setAttribute("title", "재생");
    musicPlay.setAttribute("class", "play");
    musicAudio.pause();
}

//이전 곡 듣기
const prevMusic = () => {
    musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;

    loadMusic(musicIndex);
    playMusic();
}   

//다음 곡 듣기
const nextMusic = () => {
    //1 2 3 4 5 6 7 8 9 1
    // musicIndex++;
    // if(musicIndex == 9) musicIndex == 1;
    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;

    loadMusic(musicIndex);
    playMusic();
}

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

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

//플레이 버튼 클릭
musicPlay.addEventListener("click", () => {
    const isMusicPaused = musicWrap.classList.contains("paused");    //음악 재생중
    isMusicPaused ? pauseMusic() : playMusic();
});

//이전곡 버튼 클릭
musicPrevBtn.addEventListener("click", () => {
    prevMusic();
});

//다음곡 버튼 클릭
musicNextBtn.addEventListener("click", () => {
    nextMusic();
});

window.addEventListener("load", () => {
    loadMusic(musicIndex);
});

loadMusic 함수 : 해당 번호에 해당하는 음악 정보를 로드하고, 텍스트 이미지 및 오디오 파일을 해당 정보와 일치하도록 설정합니다.

playMusic 함수 : 음악 재생 버튼이 클릭되면, 해당 클래스를 추가해 재생 버튼을 일시 중지 버튼으로 변경하고

musicAudio.paly()함수를 호출해 음악을 재생합니다.

pauseMusic 함수 : 일시 중지 버튼이 클릭되면, 해당 클래스를 제거하여 일시 중지 버튼을 재생 버튼으로 변경하고, musicAudi.pause()를 호출해 음악을 일시 중지 합니다.

prevMusic 함수 : 이전 곡 버튼이 클릭되면, musicIndex 를 감소히켜 이전 곡을 로드하고, loadMusic 및 playMusic 함수를 호출해 해당 음악을 재생합니다.

nextMusic 함수 : 다음 곡 버튼이 클릭되면, musicIndex 를 증가시켜 다음 곡을 로드하고 loadMusic 및 playMusic함수를 호출하여 해당 음악을 재생합니다.

 

musicProgress 이벤트 리스너 : 사용자가 진행 바를 클릭하면, 클릭된 위치의 X 좌표를 측정하고, 전체 길이를 나눈 후, 이를 현재 재생 값으로 변환해 musicAudio.cureentTime값을 설정합니다.

musicPlay, musicPrevBtn, musicNextBtn 이벤트 리스너: 해당 버튼이 클릭되면, isMusicPaused변수를 사용해 음악이 현재 일시 중지 중인지 확인하고, pauseMusic 또는 palyMusic 함수를 호출해 해당 동작을 수행합니다.

 

window , load 이벤트 리스너: 웹 페이지가 로드될 때, 첫 번째 음악을 로드하고 재생을 시작합니다.

 

//뮤직 진행바
musicAudio.addEventListener("timeupdate", e => {
    console.log(e);

    const currentTime = e.target.currentTime; // 현재 재생되는 시간
    const duration = e.target.duration;     //오디오의 총 길이
    let progrssWidth = (currentTime/duration) * 100;                      //전체 길이에서 현재 진행되는 시간을 백분위로 나누면

    // console.log(progrssWidth);

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

    // 전체 시간
    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}`;
        musicProgressDuration.innerText = `${totalMin}:${totalSec}`;
    });

    //진행 시간
    let currentMin = Math.floor(currentTime / 60);
    let currentSec = Math.floor(currentTime % 60);
    if(currentSec < 10) currentSec = `0${currentSec}`;
    musicProgressCurrent.innerText = `${currentMin}:${currentSec}`;

});

musicAidio 변수는 HTML 의 audio요소입니다.

이 요소에 timeupdate 이벤트가 발생하면 e 객체를 전달받습니다.

e.target.currentTime 은 현재 재생되고 있는 뮤직 파일의 시간을 나태냅ㄴ디ㅏ.

e.target.duration 은 뮤직 파일의 총 길이를 나타냅니다.

 

이 정보를 사용해 progressWidth  변수에 현재 뮤직 파일의 재생 시간이 총 길이에 대한 백분율로 계산됩니다.

이 값을 musicProgressBar요소의 너비로 설정해 뮤직 플레이어UI의 진행바를 업데이트 합니다.

 

loadeddata 이벤트를 사용해 뮤직 파일의 전체 길이를 가져와 totalMin과 totalSec 변수에 저장,

이 값을 사용해 musicProgressDuration 요소에 뮤직 파일의 전체 시간을 업데이트 합니다.

 

currentMin 과 currentSec 변수에 현재 뮤직 파일의 재생 시간을 분:초 형식으로 계산하고, 이 값을 사용해 musicProgressCurrent 요소에 뮤직 파일의 현재 시간을 업데이트 합니다.

반응형