用Python和Pygame寫遊戲-從入門到精通(20)

發表於2015-12-20

聲音是遊戲中必要的元素之一,音效可以給予使用者良好的反饋體驗。賽車的時候可以聽到振奮人心的啟動時的引擎聲和剎車時輪胎摩擦聲,射擊遊戲中槍支彈藥的音效和吶喊助威的嗓音,無一不是讓人熱血沸騰的要因。

宛若電影,最初的電影史無聲的,而自從1927年第一部公認的有聲電影放映之後,人們的娛樂專案一下子豐富了好多;遊戲中也是啊,好的配音絕對可以給我們的作品增色不少。這幾次就是給我們的pygame作品中增加美妙的聲音的。

什麼是聲音?

又要開始講原理了啊,做遊戲真是什麼都要懂,物理數學美術心理學和程式設計等等等等,大家都不容易呀~~

聲音的本質是振動,通過各種介質傳播到我們的耳朵裡。基本任何物質都可以振動,比如說一旦我們敲打桌子,桌子表面會快速振動,推動附近的空氣一起振動,而這種振動會傳播(宛如水中扔一顆石子,水波會慢慢傳播一樣),這種振動最終進入我們的耳道,使得鼓膜振動,引起我們的聽覺。

振動的幅度(響度)越大,聽到的聲音也就越大,這個很好理解,我們越用力拍桌子,聲音也就越大(同時手也越疼——)。同時,振動的快慢(音調)也會直接影響我們對聲音高低的判斷,也就是平時說的高音和低音的差別,決定著個音調的要素每秒振動的次數,也就是頻率,單位是赫茲(Hz)。比如100Hz意味著這個振動在1秒內進行了100次。音色也是一個重要指標,敲打木頭和金屬聽到的聲音完全不同,是音色的作用,這個的要素是有振動波形的形狀來決定。

現實中很多聲音都是許多不同的聲音組合而來的。同時聲音在傳播的時候也會發生變化,最直接的就是隨著距離增大,響度會減小;而在不同的環境中,因為反射和混合,聲音的效果也完全不一樣。這些都要好好考慮,比如腳步聲,空曠的山谷中應該是“空谷足音”的效果,樓梯上則是比較短但是漸漸靠近的效果。甚至發聲物體的速度也會影響我們聽到的聲音,謂之“多普勒效應”……好麻煩!不過最後遊戲裡可能不是那麼符合現實的,比如說太空中發射導彈什麼,按說是聽不到聲音的,因為沒有介質傳播,不過為了效果好,我們也不在意了……

聲音的儲存

聲音完全是一種模擬的訊號,而我們的計算機只能儲存數字(二進位制)訊號,咋辦?數字化咯~

(以下說明摘錄修改自軒轅天數-絲竹的文章,表示感謝)

以最常見的WAV檔案為例,要把聲音記錄成WAV格式,電腦要先把聲音的波形“畫在一張座標紙上”。然後呢,電腦要看了“橫座標第一格處,波形圖的縱座標是多少啊?哦,差不多是500啊(僅僅是打比方,而且這個“差不多”很關鍵),那麼橫座標第二格呢?…”最後,電腦就得出來一大堆座標值。然後再經過一些其他後續工作,電腦就把這些座標值儲存下來了。

當要放音的時候,電腦要根據這些“座標值在座標紙上面畫點”,最後“用線把點連起來”,差不多就把原先的波形還原出來了。其實數字化錄音基本上就是這樣的原理。

電腦記錄波形時,用的座標紙格子越密,自然記錄下來的點就越多、越精確,將來還原出來的波形就越接近原始波形?上邊例子的橫座標軸格子密度就相當於取樣頻率(比如,44.1KHz),縱座標格子密度就相當於量化精度(比如,16BIT)。這就是“KHZ”、“BIT”的值越高,音樂的音質越好的原因。

這個世界上自然不僅僅有WAV這一種儲存聲音的檔案格式,宛若影象檔案格式中的BMP一樣,WAV是一種無壓縮的格式,體積最大;而OGG則好像PNG,是無損的壓縮,可以完全保持影象的本真,但是大小又比較小;常用的MP3,則是類似於JPG的有失真壓縮格式。

聲音處理

想要獲得聲音,最簡單的自然是錄製,不過有的時候比較困難,比如錄製心跳要很高昂的儀器,而錄製火山爆發的聲音實在過於……

這時候我們可以手動合成聲音,而錄製獲得的聲音還需要經過處理,比如淨化等,有很多軟體可以選擇,開源的Audacity就是一個很不錯的選擇。具體的這裡就不說了,一門大學問啊。

網上也有很多聲音素材可供下載,好的專業的素材都是賣錢的,哎這個世界什麼都是錢啊~~

Pygame中聲音的初始化

這次來不及舉一個實際例子放聲音了,先說一下初始化。

在pygame中,使用mixer模組來播放聲音,不過在實際播放之前,我們需要使用pygame.mixer.init函式來初始化一些引數,不過在有的平臺上,pygame.mixer.init會隨著pygame.init一起被初始化,pygame乾脆提供了一個pygame.mixer.pre_init()來進行最先的初始化工作,引數說明如下:

  • frequency – 聲音檔案的取樣率,儘管高取樣率可能會降低效能,但是再次的音效卡都可以輕鬆對應44.1KHz的聲音回放,所以就設這個值吧;
  • size – 量化精度
  • stereo – 立體聲效果,1:mono,2:stereo,具體請google,一般設2好了
  • buffer – 緩衝大小,2的倍數,設4096就差不多了吧

你可以像這樣初始化聲音:

這裡先用pre_init來設定了引數,然後在pygame.init中初始化所有的東西。

如果你需要重新設定聲音的引數,那麼你需要先執行pygame.mixer.quit然後再執行pygame.mixer.init,不過一般用不到吧……

相關文章