天天看點

世嘉MD遊戲開發【十三】:音樂和音效

世嘉MD遊戲開發【十三】:音樂和音效

要是能為自己的遊戲添加上動人的背景音樂和音效,無疑能提升不少遊戲體驗,不至于讓玩家感覺毫無代入感。

今天我來講一下世嘉MD遊戲開發怎麼運用音樂和音效。

我自己也是慢慢摸索的,說的不全面也是情理之中的,但是能滿足最基本的需求。

世嘉MD的音頻通道有4個通道,背景音樂預設用第一個通道,音效最好是用2,3, 4這三個通道,我一開始不懂音頻播放原理,播放音效的時候總是把音樂覆寫掉,後來才摸索出來,原來要活用聲音通道才行。

代碼裡定義的聲音通道如下:

#define  SOUND_PCM_CH1  Z80_DRV_CH0_SFT

#define  SOUND_PCM_CH2  Z80_DRV_CH1_SFT

#define  SOUND_PCM_CH3  Z80_DRV_CH2_SFT

#define  SOUND_PCM_CH4  Z80_DRV_CH3_SFT
           

用的時候也很簡單,背景音樂不需要事先設定,先來說一下怎麼設定音效吧,主要是下面的這個函數:

/**
 *  \簡介
 *      為XGM音樂播放器驅動程式聲明一個新的PCM示例(最大值 = 255)。
 *      小于64的數保留用于音樂,大于等于64的用于SFX音效
 *      是以,如果要聲明新的SFX PCM音效,請使用id>= 64
 *
 *  \參數 id
 *      不允許id為0
 *      1-63用于音樂
 *      64-255用于音效
 *
 *  \參數 sample
 *      //我也不懂啥意思
 *      Sample address, should be 256 bytes boundary aligned
 *      //看懂這一句就可以了,SGDK自動給你處理
 *      SGDK automatically align sample resource as needed
 *
 *  \參數 len
 *      //size必須是256的整數倍
 *      Size of sample in bytes, should be a multiple of 256
 *      //不用擔心,SGDK自動給你處理
 *      SGDK automatically adjust resource size as needed
 *      用sizeof()擷取音效的長度
 */
void XGM_setPCM(const u8 id, const u8 *sample, const u32 len);
           

播放音樂就很簡單了,用如下函數:

void XGM_startPlay(const u8 *song);
           

播放音效的時候用以下函數:

/**
 *  \簡介
 *      在指定的聲道上播放PCM音頻,僅用于XGM音樂驅動.
 *      如果目前聲道正在播放PCM音頻,則比較樣本的優先級,根據優先級确定是否替換播放新的音效
 *      注意:音樂使用通道1,最好用通道2-4播放音效
 *
 *  \參數 id
 *      Sample id (set #XGM_setPCM method)
 *
 *  \參數 priority
 *      值的範圍是0-15,0優先級最低,15優先級最高。

 *  \參數 channel
 *      #SOUND_PCM_CH1  = channel 1 (通常用于音樂)
 *      #SOUND_PCM_CH2  = channel 2
 *      #SOUND_PCM_CH3  = channel 3
 *      #SOUND_PCM_CH4  = channel 4
 */
void XGM_startPlayPCM(const u8 id, const u8 priority, const u16 channel);
           

SGDK的資源檔案都是要事先寫在一個.res檔案中的,詳情見:SGDK\bin\rescomp.txt,裡面定義了各種資源的書寫規則,要嚴格按照規則寫,不然會報錯。是以我們用到的聲音檔案我是這麼處理的,我把所有資源都放到res目錄裡,建立resources.res檔案,在裡面寫上如下代碼:

XGM music "GTR Attack!.vgm" 0

WAV sound1 "sound1.wav" 5
WAV sound2 "sound2.wav" 5
WAV sound3 "sound3.wav" 5
WAV sound4 "sound4.wav" 5
           

這樣就算聲明了一個XGM格式的音樂,叫music。

聲明了一個WAV格式的音樂,叫sound1,依次類推。

邏輯部分的代碼如下:

/*
    播放背景音樂的同時還可以播放音效
*/

#include <genesis.h>
#include <vdp.h>
#include "resources.h"

//用來标記音樂是否播放了
bool startPlay = FALSE;

//按鍵輸入事件,前面有講過
void inputHandle(u16 joy, u16 changed, u16 state)
{
    //changed & state & BUTTON_START 意思就是剛按下的時候,不是連發的那種,隻觸發一次
    //START鍵播放或者暫停音樂
    if (changed & state & BUTTON_START)
    {
        if (startPlay == FALSE)
        {
            XGM_startPlay(music);
            startPlay = TRUE;
        }
        else if (startPlay)
        {
            if (XGM_isPlaying())
                XGM_pausePlay();
            else
                XGM_resumePlay();
        }
    }

    //ABCX鍵分别播放對應的音效
    if (changed & state & BUTTON_A)
    {
        XGM_startPlayPCM(64, 1, SOUND_PCM_CH2);
    }
    if (changed & state & BUTTON_B)
    {
        XGM_startPlayPCM(65, 2, SOUND_PCM_CH3);
    }
    if (changed & state & BUTTON_C)
    {
        XGM_startPlayPCM(66, 3, SOUND_PCM_CH4);
    }
    if (changed & state & BUTTON_X)
    {
        XGM_startPlayPCM(67, 4, SOUND_PCM_CH2);
    }
}

int main()
{
    VDP_drawText("Music & Sound", 0, 0);

    { //設定音效的ID
        XGM_setPCM(64, sound1, sizeof(sound1));
        XGM_setPCM(65, sound2, sizeof(sound2));
        XGM_setPCM(66, sound3, sizeof(sound3));
        XGM_setPCM(67, sound4, sizeof(sound4));
    }

    JOY_setEventHandler(inputHandle);

    while (TRUE)
    {
        VDP_waitVSync();
    }
    return 0;
}
           

至于XGM音樂檔案(.vgm格式)從何而來呢,我推薦大家一個制作這種音樂的軟體,叫做DefleMask,有興趣的可以去研究一下,這就是另一個知識領域了。

電腦端可以看到工程檔案的下載下傳入口,大家可以自行下載下傳工程檔案。

繼續閱讀