首页/技术开发/内容

游戏音乐与音效的播放

技术开发2022-07-19 阅读()
MCI_OPEN_ELEMENT,

    (DWORD)(LPVOID) &mciOpenParms)

    return (dwReturn);

    // The device opened successfully; get the device ID.

    wDeviceID = mciOpenParms.wDeviceID;

    // Check if the output port is the MIDI mapper.

    mciStatusParms.dwItem = MCI_SEQ_STATUS_PORT;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,

        MCI_STATUS_ITEM, (DWORD)(LPVOID) &mciStatusParms))

        {

            mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

            return (dwReturn);

        }

        // 为了达成重复播放的目的,必须让我们的程式能够接收到

        // MM_MCINOTIFY的讯息,这个函示呼叫的方式,就是传递

        // WM_PLAY讯息给装置,叫他开始播放。

        mciPlayParms.dwCallback = (DWORD) hwnd;

        if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY,

        (DWORD)(LPVOID) &mciPlayParms))

        {

            mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

            return (dwReturn);

        }

    return (0L);

};

播放MIDI的方式有两种,第一种是利用字串命令硬体动作,第二种是传递讯息的方式,我们采用第二种,原因很清楚了,必须透过讯息的传递,我们才能得知音乐是否播放完毕了。

接下来我们看看Cmidi::Replay是怎麽一回事:

void CMidi::Replay()

{

        mciSendCommand(wDeviceID, MCI_SEEK,MCI_SEEK_TO_START, NULL);

        mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);

}

真是不可思议地简单呀,函示里面只包含两条呼叫,第一条呼叫送讯息给装置,叫他把MIDI的播放指标移到最开头的部份,也就是MCI_SEEK_TO_START,

作法就像移动档案指标一样。接着第二条指令光看也明白,就是叫他继续播放就是了,而且别忘了MCI_NOTIFY,当下次播放完毕,还是得用讯息通知我们的程式。

最後看一下Cmidi::Stop()的作法:

void CMidi::Stop()

{

    mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

}

越来越单纯了,里面只有包含一个函示呼叫,其中的讯息叁数MCI_CLOSE,就是结束整个音乐的播放。当你结束播放以後,要播放另一首音乐,很简单,再次呼叫Cmidi::Play()即可。

整个类别的使用方法大致上是这样的:首先配置一个实际的CMidi物件给程式,只要在全域的地方下条指令 CMidi midi;即可,尔後midi就是真实的物件了。在场景初始化的部份呼叫midi.Play(hwnd,"ff3celes.mid");,输入正确的MIDI档名即可。此处我播放的是太空战士三代的音乐,只是示范一下,当然这首音乐确实很棒就是了。而在讯息回圈里面,我们必须定义一个讯息:

case MM_MCINOTIFY:

    midi.Replay();

    break;

在音乐播放完毕以後,我们的讯息回圈会收到MM_MCINOTIFY这个讯息,这时候如同我们前面所言,呼叫Cmidi::Replay()即可。而当场景更换,要重新一首新的音乐,或是程式结束的时候,就是呼叫Cmidi::Stop()的时机。因为一个场景同时间只会存在一首音乐,所以我们的类别表现良好,不用担心。

第1页  第2页 

……

相关阅读