SDL2 遊戲開發日記(四)
加入音樂和音效
使用SDL_Mixer庫,支援的音頻格式有wav,mp3,ogg,flac,midi等。
使用單例模式對SDL_Mixer作個簡單的封裝。實作加載,播放
聲音播放類
#pragma once
#include <map>
#include <SDL_mixer.h>
#include <string>
using namespace std;
typedef map<string, Mix_Music*> MusicsMap;
typedef map<string, Mix_Chunk*> SoundsMap;
#define theSounds GameSound::Instance()
class GameSound{
private:
//已加載過的聲音清單
MusicsMap mMusics;
//已加載過的音效清單
SoundsMap mSounds;
GameSound(const GameSound &){}
void operator=(const GameSound &){}
GameSound(){
}
public:
static GameSound &Instance(){
static GameSound instance;
return instance;
}
~GameSound(){
}
//釋放所有聲音。在Mix_Quit前調用
void ReleaseAllSounds(){
if (Mix_PlayingMusic()){
Mix_HaltMusic();
}
Mix_HaltChannel(-1);
MusicsMap::iterator iter = mMusics.begin();
while (iter != mMusics.end()){
Mix_FreeMusic(iter->second);
iter++;
}
mMusics.clear();
SoundsMap::iterator soundsIter = mSounds.begin();
while (soundsIter != mSounds.begin()){
Mix_FreeChunk(soundsIter->second);
soundsIter++;
}
mSounds.clear();
}
//加載音樂
Mix_Music* LoadMusic(string fileName);
//加載音效
Mix_Chunk* LoadSound(string fileName);
//播放音效
bool PlaySoundEffect(string fileName,int loops);
//播放音樂
//通過檔案名查找是否已經加載。
//fileName 檔案名
//loops,循環次數,-1為一直循環播放
bool PlayMusic(string fileName,int loops);
//暫停
void PauseMusic(){
if (Mix_PlayingMusic()){
Mix_PauseMusic();
}
}
//繼續播放
void ResumeMusic(){
if (Mix_PausedMusic()){
Mix_ResumeMusic();
}
}
//停止播放
void StopMusic(){
if (Mix_PlayingMusic()){
Mix_HaltMusic();
}
}
//把聲音從已加載過的清單中删除
void DeleteMusic(string fileName){
MusicsMap::iterator iter = mMusics.find(fileName);
if (iter != mMusics.end()){
Mix_FreeMusic(iter->second);
mMusics.erase(iter);
}
}
void DeleteSound(string fileName){
SoundsMap::iterator iter = mSounds.find(fileName);
if (iter != mSounds.end()){
Mix_FreeChunk(iter->second);
mSounds.erase(iter);
}
}
};
//GameSound.cpp
#include "stdafx.h"
#include "SDLGame.h"
#include "GameSound.h"
Mix_Music* GameSound::LoadMusic(string fileName){
Mix_Music *music = NULL;
MusicsMap::iterator iter = mMusics.find(fileName);
if (iter != mMusics.end()){
music = iter->second;
return music;
}
else{
music = Mix_LoadMUS((theGame.GetResourcePath() + fileName).c_str());
if (music != NULL){
mMusics.insert(std::make_pair(fileName, music));
}
else{
return NULL;
}
}
return music;
}
//
Mix_Chunk* GameSound::LoadSound(string fileName){
Mix_Chunk *chunk = NULL;
SoundsMap::iterator iter = mSounds.find(fileName);
if (iter != mSounds.end()){
chunk = iter->second;
return chunk;
}
chunk = Mix_LoadWAV((theGame.GetResourcePath() + fileName).c_str());
if (chunk != NULL){
mSounds.insert(std::make_pair(fileName, chunk));
}
else{
return NULL;
}
return chunk;
}
bool GameSound::PlaySoundEffect(string fileName, int loops){
Mix_Chunk *chunk = LoadSound(fileName);
if (chunk == NULL)
return false;
Mix_PlayChannel(-1, chunk, loops);
return true;
}
bool GameSound::PlayMusic(string fileName,int loops){
Mix_Music *music = LoadMusic(fileName);
if (music == NULL)
return false;
if (Mix_PlayingMusic()){
Mix_HaltMusic();
}
Mix_PlayMusic(music, loops);
return true;
}
測試播放
//加載音樂
theSounds.LoadMusic("background.mp3");
theSounds.LoadSound("delete.wav");
theSounds.PlayMusic("background.mp3", -1);