48 章

今回は音楽を付けてみましょう。

音楽は煉獄庭園さんの曲を利用させていただきました。

datフォルダのmusicフォルダに入っている曲を聞いてみて下さい。

oggファイルが開けない人はGOM Playerなどをインストールして聞いて下さい。

1面の曲っぽくはないですが、まぁこの辺は好きな曲に変更して下さい。

今回は

SetLoopPosSoundMemという関数を利用します。

PlaySoundMem関数でもループは出来ますが、曲というものは、大抵前奏があります。

ですから、ゲーム内でループ再生したいときで、曲のある部分までいって最初に戻る時、

曲の先頭まで戻ってしまっては都合が悪いときがあります。

それを解決してくれるのがこの関数で、指定したミリ秒位置がループが返って来る位置になります。

Audacityなどで曲のどの部分がループ位置になりそうか確認してみます。

例えばラスボス曲である0_1.oggのループになりそうな位置を拡大してみると



26.672秒つまり26672ミリ秒をループ位置に設定してやるとよさそうです。

--------------------------------------------------------------------

今回、そのエリアごとに保持すべき情報をもった構造体area_t型を用意しました。

その中にBGM系の変数の集合であるbgm_t型を用意しています。


---- struct.h に以下を追加 ----

//BGM情報(area_tで使用(48)
typedef struct{
        //BGMの再生フラグ、再生ハンドル、いつならすか再生種類番号をいれる、ループ位置
        int flag,handle,knd[2],loop_pos[2];
}bgm_t;

//そのエリアが持っている情報(48)
typedef struct{
        bgm_t bgm;
}area_t;


---- GV.h に以下を追加 ----

GLOBAL area_t area;//そのエリアで持っているデータ(48)


---- function.h に以下を追加 ----

        GLOBAL void delete_bgm();
        GLOBAL void bgm_main();


---- load.cpp 内の以下の部分を変更 ----

    ChangeVolumeSoundMem関数内の音量を適当に調整しました。詳しくは省略


bgm_tには

flag, handle, knd[2], loop_pos[2];

を用意しました。音楽の再生状態は以下のような0〜4の状態を順番に遷移します。

0:まだ再生されていない

1:通常BGMを再生している

2:通常BGMをとめている

3:ラスボスBGMを流している

4:ラスボスBGMを止めている

0はそのエリアのゲームが始まったばかりの状態です。この時データを読み込みます。

1でいつ再生するかはkndで設定します。サンプルでは種類0の再生の仕方ははじまってから60カウント後としています。

設定した種類ごとに再生するタイミングを変更したいので、今後music.cppで再生の仕方を増やしていきましょう。

2はラスボスにさしかかった状態です。通常BGMをとめ、データを削除し、ラスボス音楽データを読み込み待機します。

3で再生します。

4でとめますが、まだとめる処理はサンプルでも書いていません。

loop_posは先ほどいったループの位置です。ini関数内でセットします。

[0]は通常BGM、[1]はラスボスBGMの設定です。

また、load_bgm関数でパスを作成していますね。

0_0を1面の通常BGM

0_1を1面のラスボスBGM

1_0を2面の通常BGM

1_1を2面のラスボスBGM

としていけばこの関数の仕様を引き継いで拡張出来ます。


---- ini.cpp に以下を追加 ----

        memset(&area,0,sizeof(area_t));//(48)

        area.bgm.knd[0]=0;//通常BGMをどういうタイミングで再生するか、取り決めはmusic.cpp(48)
        area.bgm.knd[1]=0;//ボスBGMをどういうタイミングで再生するか、取り決めはmusic.cpp(48)
        area.bgm.loop_pos[0]=26672;//通常BGMのループ位置(48)
        area.bgm.loop_pos[1]=27010;//ボスBGMのループ位置(48)


---- GV.h に以下を追加 ----

GLOBAL area_t area;//そのエリアで持っているデータ(48)


---- function.h に以下を追加 ----

        GLOBAL void delete_bgm();
        GLOBAL void bgm_main();


---- load.cpp 内の以下の部分を変更 ----

    ChangeVolumeSoundMem関数内の音量を適当に調整しました。詳しくは省略


---- music.cpp に以下を追加 ----

void load_bgm(int flag){
        char str[64];
        sprintf(str,"../dat/music/%d_%d.ogg",stage,flag);
        area.bgm.handle=LoadSoundMem(str);
}

void delete_bgm(){
        DeleteSoundMem(area.bgm.handle);
}

void bgm_main(){
        if(area.bgm.flag==0){//最初に読み込む
                load_bgm(0);
                SetLoopPosSoundMem( area.bgm.loop_pos[0], area.bgm.handle );//ループ位置セット
                area.bgm.flag=1;
        }
        if(area.bgm.flag==1){//種類に応じて再生をはじめる
                switch(area.bgm.knd[0]){
                        case 0://再生種類0なら
                                if(stage_count==60){//はじまって60カウント後に再生
                                        PlaySoundMem(area.bgm.handle,DX_PLAYTYPE_LOOP);
                                        area.bgm.flag=2;
                                }
                                break;
                        default:
                                break;
                }
        }
        if(area.bgm.flag==2){//ボス出現時に読み込む
                if(stage_count==boss.appear_count[1]){//ラスボスが現れたら読み込む
                        StopSoundMem(area.bgm.handle);
                        delete_bgm();
                        load_bgm(1);
                        SetLoopPosSoundMem( area.bgm.loop_pos[1], area.bgm.handle );//ループ位置セット
                        area.bgm.flag=3;
                }
        }
        if(area.bgm.flag==3){
                switch(area.bgm.knd[0]){
                        case 0://再生種類0なら
                                if(stage_count==boss.appear_count[1]){//ラスボスが現れたら再生
                                        PlaySoundMem(area.bgm.handle,DX_PLAYTYPE_LOOP);
                                        area.bgm.flag=4;
                                }
                                break;
                        default:
                                break;
                }
        }
}


---- main.cpp に以下赤字部を追加 ----

                        case 100://通常処理
                                                 enter_func_tm("最初");
                                calc_ch();       enter_func_tm("キャラ計算");
                                ch_move();       enter_func_tm("キャラ移動");
                                cshot_main();    enter_func_tm("自機ショットメイン");
                                enemy_main();    enter_func_tm("敵処理メイン");
                                boss_shot_main();enter_func_tm("ボスショットメイン");
                                shot_main();     enter_func_tm("ショットメイン");
                                out_main();      enter_func_tm("当たり判定");
                                effect_main();   enter_func_tm("エフェクトメイン");
                                calc_main();     enter_func_tm("計算メイン");
                                graph_main();    enter_func_tm("描画メイン");
                                bgm_main();      enter_func_tm("BGMメイン");
                                if(boss.flag==0)
                                        stage_count++;
                                break;
                        default:
                                printfDx("不明なfunc_state\n");
                                break;



実行結果

音が鳴るかどうかの違いなので目に見える違いはありません。



※練習してみよう※

このプロジェクトを実行し、ボス戦でわざとのんびりしてBGMを聞いてみて下さい。どこでループしているかわかるでしょうか。

この曲は煉獄庭園さんの曲で「裏桜華-CODE:桜樺-」という曲です。

http://www.rengoku-teien.com/mp3_wahuu.html

ダウンロードして、自分で曲を編集し、きっちり継ぎ目がわからないように編集、設定出来るかやってみて下さい。



※管理人から一言※

龍神録では容量の都合上、この「裏桜華-CODE:桜樺-」は仕方なく短くしてループしてあります。

しかしこの曲は4分以上あり、前半も後半もとてもよい曲です。

龍神録を何回かプレイしてくださった方は、全部聞いてみると「あれ、この曲にこんな部分あったんだ」みたいに思っていただけるかもしれません。

是非よい曲なので、もしよければ最初から最後まで聞いてみて下さい。

- Remical Soft -