DirectSoundにはDirectDrawと同じようにラッパー関数があります。それを使えばある程度簡単に音が鳴らせれるので、2Dゲームサンプルに組み込んでみたいと思います。
「DSSamp.lzh」をダウンロードし、解凍すると次のファイルが作成されます。
(ファイルサイズが2.4M近くあるのでかなり重いです。ゴメンなさいm(__)m)
ファイルの種類 ファイル名 説明 WAVEファイル Welcome98.wav バック・ミュージックとして使用 YO.wav 自機のショット音として使用 ソースファイル dsutil.cpp MSSDKのDirectSoundサンプルについているラッパー関数 mySound.cpp DirectSound関係の関数を集めたもの(自作) ヘッダファイル dsutil.h dsutil.cppのヘッダファイル mySound.h mySound.cppのヘッダファイル(自作)
2Dゲームサンプルをビルドし、動く状態にします。その後、解凍した上記のファイルをプロジェクトのフォルダにコピーし、次のようにプログラムを修正してください。
1.リソースにWAVAファイルを追加する。
- 「Script1 リソース」を右クリックし、「インポート」を選択
- ファイルの種類を「Wavファイル」に変更し、2つのWAVEファイルを選択して インポートをクリック
- WAVEファイルを右クリックし、それぞれ名前を付ける
「BACK01」「SHOT01」2.プロジェクトの変更
プロジェクトにソースファイル、ヘッダファイルを追加する。
3.WinMain.cppの変更
WinMain.cppを次のように編集する。
- includeのあたりに次の行を追加
#include "mySound.h" - WinMain関数のDirectInput初期化の下に次の行を追加
/* Direct Sound Object の初期化 */ if ( !InitializeSound(hWnd) ) { OutputDebugString("InitializeSound ERROR\n"); return FALSE; }- WinProc関数のcase WM_DESTROY:内のDirectInput開放の上に次の行を追加
/* DirectSoundオブジェクトの開放 */
DSRelease();4.リンクファイルの追加
プロジェクトの設定で「dsound.lib」をリンクする。
5.確認
以上の設定を行い、ビルドすればexeファイルが出来上がる・・・はずです。実行をしても、何も変化はありません。しかし、DirectSoundの初期化と開放の処理を組み込んでいるので、エラーが出なければDirectSoundの組み込みは成功しています。
それではまずバック・ミュージックを鳴らしてみましょう。
スタート画面では音を鳴らさず、ゲーム開始時に音を鳴らし、ゲーム終了時に音を止めるようにプログラムを変更します。Game.cppを開き、次のように変更してください。1.includeのあたりに次の行を追加
#include "mySound.h" 2.GameInit関数に次の行を追加
// バックミュージックスタート
SoundPlayBackMusic();3.GameFrame関数の自機と敵のあたり判定を次のように編集
// 自機と敵のあたり判定
if (Jiki.Pos.x <= Enemy.Pos.x+(Enemy.Rect.right-Enemy.Rect.left)
&& Jiki.Pos.y <= Enemy.Pos.y+(Enemy.Rect.bottom-Enemy.Rect.top)
&& Jiki.Pos.x+(Jiki.Rect.right-Jiki.Rect.left) >= Enemy.Pos.x
&& Jiki.Pos.y+(Jiki.Rect.bottom-Jiki.Rect.top) >= Enemy.Pos.y)
{
/* バック・ミュージックを止める */
SoundStopBackMusic();
/* スタート画面に戻る */
g_FrameNo = 0;
}4.確認
以上の設定を行い、ビルドして実行してみてください。成功すると、ゲーム画面になった時にバック・ミュージックが流れるはずです。出だしの音が小さめなので、気持ち音量を上げておいてください。
今度は自機のショット音を鳴らしてみましょう。Aボタンを押すと100ミリ秒間隔で音を鳴らすようにします。
これもGame.cppを編集します。1.ローカルデータの宣言に次の行を追加
static DWORD shotTc; 2.GameInit関数に次の行を追加
shotTc = 0; 3.JikiMove関数に次の行を追加
// ショット音
if (dwInput&BUTTON_A && g_thisTickCount - shotTc >= 100 )
{
SoundPlayShot01();
shotTc = g_thisTickCount;
}4.動作確認
以上の設定を行い、ビルドして実行してみてください。成功すると、ゲーム画面になった時にAボタン(Aキー)を押すと、ショット音が出るはずです。スタート画面からゲームを開始するときにAボタンでSTARTを選びますが、すぐにゲームが始まってしまうため、いきなり音が出てしまいます。
SoundPlayBackMusic(),SoundStopBackMusic(),SoundPlayShot01()は全て
mySound.cppにある関数です。mySound.cppで使用するWAVEファイルの宣言、初期化などを行っています。
バックミュージックはループ再生、ショット音は普通に再生しています。
DirectX7実践プログラミングのDirectSoundの章で、宣言や再生方法などの説明が載ってますので詳しくはそちらをご覧下さい。
音を増やす場合、mySound.cppを編集します。リソース名などの宣言のほか、再生用、停止用の関数をそれぞれ作らなければなりません。
また、再生用、停止用の関数は外部プログラム(Game.cppなど)で使用するため、mySound.hでプロトタイプ宣言をする必要があります。
このプログラムはWAVEファイルをリソースとして取り込んでいます。その結果、プログラム実行時に全てのリソースを読み込むために起動時間がある程度かかってしまいます。
WAVEデータだけではなく、画像データもそうだと思いますが、本来はリソースとして取り込むのではなく、必要なときだけ読み込んで利用するようプログラムを変えたほうがいいのかもしれません。