天天看點

SDL2 遊戲開發日記(四)SDL2 遊戲開發日記(四)

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);
           

繼續閱讀