天天看點

【讀書筆記《Android遊戲程式設計之從零開始》】19.遊戲開發基礎(遊戲音樂與音效)

在一款遊戲中,除了華麗的界面 UI 直接吸引玩家外,另外重要的就是遊戲的背景音樂與音效;合适的背景音樂以及精彩的音效搭配會令整個遊戲上升一個檔次。

在 Android 中。常用于播放遊戲背景音樂的類是 MediaPlayer, 而用于遊戲音效的則是 SoundPool 類。

1. MediaPlayer

MediaPlayer 執行個體化不是 new 出來的,而是通過調用靜态方法得到的,這裡有幾種靜态方法:

create(Context context, Uri uri) 

作用:通過Uri建立一個多媒體播放器。

create(Context context, int resid)

作用:通過資源ID建立一個多媒體播放器

create(Context context, Uri uri, SurfaceHolder holder)

作用:通過Uri和指定 SurfaceHolder 【抽象類】 建立一個多媒體播放器

MediaPlayer 類常用的函數如下:

prepare()

作用:為同步播放音樂檔案做準備

start()

作用:播放音樂

pause()

作用:暫停音樂播放

stop()

作用:停止音樂播放

getCurrentPosition()

作用:傳回 Int, 得到目前播放音樂的時間點

 getDuration()

作用:傳回 Int,擷取播放的音樂檔案總時間長度

getVideoHeight()

作用:傳回 Int ,得到視訊的高度

getVideoWidth()

作用:傳回 Int,得到視訊的寬度

isLooping()

作用:傳回 boolean ,是否循環播放

isPlaying()

作用:傳回 boolean,是否正在播放

prepareAsync()

作用:無傳回值,準備異步

release()

作用:無傳回值,釋放 MediaPlayer  對象

reset()

作用:無傳回值,重置 MediaPlayer  對象

seekTo(int msec)

作用:無傳回值,指定音樂檔案播放的位置(以毫秒為機關的時間)

參數:跳轉時間(以毫秒為機關)

setAudioStreamType(int streamtype)

作用:無傳回值,指定流媒體的類型

setDataSource(String path)

作用:無傳回值,設定多媒體資料來源【根據路徑】

setDataSource(FileDescriptor fd, long offset, long length)

作用:無傳回值,設定多媒體資料來源【根據 FileDescriptor】

setDataSource(FileDescriptor fd)

setDataSource(Context context, Uri uri)

作用:無傳回值,設定多媒體資料來源【根據 Uri】

setDisplay(SurfaceHolder sh)

作用:無傳回值,設定用 SurfaceHolder 來顯示多媒體

setLooping(boolean looping)

作用:無傳回值,設定音樂是否循環播放

參數 :true 表示循環播放,false 表示不循環播放

setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)

作用:監聽事件,網絡流媒體的緩沖監聽

setOnCompletionListener(MediaPlayer.OnCompletionListener listener)

作用:監聽事件,網絡流媒體播放結束監聽

setOnErrorListener(MediaPlayer.OnErrorListener listener)

作用:監聽事件,設定錯誤資訊監聽

setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)

作用:監聽事件,視訊尺寸監聽

setScreenOnWhilePlaying(boolean screenOn)

作用:無傳回值,設定是否使用 SurfaceHolder 顯示

setVolume(float leftVolume, float rightVolume)

作用:無傳回值,設定音量

除此之外,音樂管理類 AutoManager 提供了擷取目前音樂大小以及最大音量等,其常用函數如下:

setStreamVolume(int streamType,int index,int flags)

作用:設定音量大小

第一個參數:音量類型(音樂的常量:AudioManager.STREAM_MUSIC)

第二個參數:音量大小

第三個參數:設定一個或多個辨別

getStreamVolume(int streamType)

作用:擷取目前音量大小

參數:擷取音量大小的類型

getStreamMaxVolume(int streamType)

作用:擷取目前音量最大值

Android OS 中,如果去按手機上調節音量的按鈕,會遇到兩種情況,一種是調整手機本身的鈴聲音量,另外一種是調整遊戲、軟體的音樂播放的音量。

在遊戲中的時候,預設調整的是手機的鈴聲音量,隻有在遊戲中有聲音播放的時候,才能去調整遊戲的音量。是以往遊戲中添加音樂時,需要使用如下函數:

Activity.setVolumeControlStream(int streamType)

作用:設定控制音量的類型

參數:音量類型(AudioManager.STREAM_MUSIC:媒體音量)

下面用一個簡單執行個體進行說明,先看下效果圖:

【讀書筆記《Android遊戲程式設計之從零開始》】19.遊戲開發基礎(遊戲音樂與音效)
【讀書筆記《Android遊戲程式設計之從零開始》】19.遊戲開發基礎(遊戲音樂與音效)

建立項目,遊戲架構為 SurfaceView 遊戲架構,修改 MySurfaceView 類如下:

 View Code

MainActivity 類修改如下:

<a></a>

2.SoundPool

SoundPool也能播放一些音樂檔案,它和MediaPlayer 之間最大的差別是SoundPool 隻能播放小的檔案。

Sound 類的構造函數如下:

SoundPool(int maxStreams,int streamType,int srcQuality)

作用:執行個體化一個SoundPool 執行個體

第一個參數:允許同時播放的聲音最大值

第二個參數:聲音類型

第三個參數:聲音的品質

SoundPool 類中常用的函數如下:

int load(Context context,int resId,int priority)

作用:加載音樂檔案,傳回音樂ID(音樂流檔案資料)

第一個參數:Context 執行個體

第二個參數:音樂檔案 Id

第三個參數:辨別優先考慮的聲音。目前使用沒有任何效果,隻是具備了相容性價值

int paly(int soundID,float leftVolume,float rightVolume,int priority,int loop,float rate)

作用:音樂播放,播放失敗傳回0,正常傳回非0值

第一個參數:加載後得到音樂檔案ID

第二個參數:音量的左聲道,範圍:0.0 ~ 1.0

第三個參數:音量的右聲道,範圍:0.0 ~ 1.0

第四個參數:音樂流的優先級,0是最低優先級

第五個參數:音樂的播放次數,-1表示無限循環,0表示正常一次,大于0則表示循環次數

第六個參數:播放速率,取值範圍:0.5 ~ 2.0,1.0 表示正常播放

pause(int streamID)

參數:音樂檔案加載後的流ID

stop(int streamID)

作用:結束音樂播放

作用:釋放SoundPool 的資源

setLoop(int streamID,int loop)

作用:設定循環次數

第一個參數:音樂檔案加載後的流ID

第二個參數:循環次數

setRate(int streamID,float rate)

作用:設定播放速率

第二個參數:速率值

setVolume(int streamID,float leftVolume,float rightVolume)

第二個參數:左聲道音量

第三個參數:右聲道音量

setPriority(int streamID,int priority)

作用:設定流的優先級

第二個參數:優先級值

照例通過執行個體來詳細講解如何使用 SoundPool 。

加載的音樂檔案:

【讀書筆記《Android遊戲程式設計之從零開始》】19.遊戲開發基礎(遊戲音樂與音效)

整個項目的流程很簡單,通過判斷使用者的按鍵,播放不同的音樂;但是如果音樂檔案過大,但是運作項目時會報出如下錯誤:

【讀書筆記《Android遊戲程式設計之從零開始》】19.遊戲開發基礎(遊戲音樂與音效)

錯誤對應的程式代碼是加載長音樂檔案生成其資料ID的一行,出現此錯誤的原因如下:

利用 SoundPool 播放音樂檔案,首先都會對需要播放的音樂檔案通過函數 int load(Context context,int resId,int priority) 進行加載,并且生成對應的音樂資料ID;其生成的資料 ID(int 值)就是整個音樂檔案的所有資料,而如果音樂檔案過大,其中的音樂流資料檔案也遠遠超過了int 的最大值,是以當程式加載此音樂檔案生成對應的資料ID時,會報超過最大值的異常。

3.MediaPlayer 與 SoundPool 優劣分析

3.1 使用MediaPlayer 的優缺點

(1)缺點

資源占用量較高、延遲時間較長、不支援多個音頻同時播放等。

除此之外使用 MediaPlayer 進行播放音樂時,尤其是在快速連續播放聲音(比如連續猛點按鈕)時,會非常明顯的出現1~3秒左右的延遲;當然此問題可以使用MediaPlayer.seekTo() 這個方法來解決。

(2)優點

支援很大的音樂檔案播放,而且不會同 SoundPool 一樣需要加載準備一段時間,MediaPlayer 能及時播放音樂。

3.2 使用SoundPool 的優缺點

①最大隻能申請1M的記憶體空間,這就意味着使用者隻能使用一些很短的聲音片段,而不能用它來播放歌曲或者遊戲背景音樂。

②SoundPool 提供了 pause 和 stop 方法,但建議最好不要輕易使用這些方法,因為它們可能會導緻莫名其妙的終止。

③使用SoundPool 時音頻格式建議使用OGG格式。如果使用WAV格式的音頻檔案,在播放的情況下有時會出現異常關閉的情況。

④在使用SoundPool 播放音樂檔案的時候,如果在構造中就調用播放函數進行播放音樂,其效果則是沒有聲音!不是因為函數沒有執行,而是SoundPool 需要加載準備時間!當然這個準備時間也很短,不會影響使用,隻是程式一運作播放剛開始會沒有聲音罷了。

支援多個音樂檔案同時播放。

通過以上分析可以明顯知道,在Android 遊戲開發中,遊戲背景音樂使用MediaPlayer 肯定比使用SoundPool 要合适;而遊戲音效的播放采用SoundPool 則更好,畢竟遊戲中肯定會出現多個音效同時進行播放額情況。

本文轉自葉超Luka部落格園部落格,原文連結:http://www.cnblogs.com/yc-755909659/p/4187155.html,如需轉載請自行聯系原作者

下一篇: 這個社會啊