BGM(1/2)

 BGMのファイルを用意し、ゲームのプログラムがあるフォルダに置き、プログラム中で開いて「鳴らせ」と命令すれば鳴ります。

 1.BGMのファイルを開く
 2.BGMを鳴らす

BGMを鳴らす命令

 効果音と同様、本講座ではBGMを鳴らすのにsnd命令を使いません。snd命令でMIDIファイルの音楽を鳴らそうとすると、「鳴らせ」と命令してから実際に鳴り出すまでの間、プログラムが止まってしまうからです。
 ではHMM.DLLで追加されたDirectMusic(DirectXでMIDIファイルを扱うためのコンポーネント)用の命令を使うかというと、残念ながら私の環境ではうまく鳴ってくれません。
 ここではmci命令を使います。これはsnd命令と同様、HSPの標準機能ですが、ゲームが途中で止まってしまったりしません。一口にmci命令といってもいろいろなコマンドがあるのですが、ここでは基本的な4つだけを使います。

mci "open ファイル名 alias エイリアス"
 MIDIファイルを開いて、エイリアスをつけます。エイリアスというのは別名のことです。以降、どの音楽であるかはエイリアスで指定します。
 開いたファイルはプログラム終了時に自動的に閉じます。

mci "set エイリアス time format milliseconds"
 時間指定を行うmci命令において、時間の単位をミリ秒に設定します。

mci "play エイリアス from ポジション"
 エイリアスで指定した音楽を鳴らします。ポジションは再生開始位置を指定します。単位はsetコマンドで指定したもの(この場合、ミリ秒)となります。from 0なら、0ミリ秒目から(つまり先頭から)鳴らします。

mci "stop エイリアス"
 音楽を止めます。

 1.BGMのファイルを開く

「プログラム起動時の初期設定」に以下を追加します。
    ; BGMファイルを開く
    repeat 3
        i=cnt+1
        mci "open samplebgm"+i+".mid alias abogadrobgm"+i
        mci "set abogadrobgm"+i+" time format milliseconds"
    loop
    mci "open bossbgm.mid alias bossbgm"
    mci "set bossbgm time format milliseconds"
    mci "open endbgm.mid alias endbgm"
    mci "set endbgm time format milliseconds"
    bgmname=""
 samplebgm1.mid(abogadrobgm1)〜samplebgm3.mid(abogadrobgm3)が各ステージの通常戦、bossbgm.mid(bossbgm)がボス戦、endbgm.mid(endbgm)がエンディングの音楽です。
 変数bgmnameは、今どの音楽を鳴らしているかを識別するために該当するエイリアスを入れます。何も鳴らしていない時には""(ヌル)を入れます。

 2.BGMを鳴らす

 音楽を鳴らす時には、playコマンドを実行するとともに、曲名(エイリアス)をbgmnameに入れます。
 音楽を止める時には、bgmnameがヌルであれば止めず、ヌルでなければ該当する曲を止めます。止めたらbgmnameをヌルにします。音楽を止める処理はサブルーチンにします。
        ;BGMの演奏を終了する
    *BGM_Stop
        if bgmname!"" {
            mci "stop "+bgmname
            bgmname=""
        }
        return

(1)通常戦の音楽を鳴らす
 ステージが始まったら、通常戦の音楽を鳴らします。
    ; ステージスタート時の初期設定
    ; BGMを鳴らす。
    mci "play abogadrobgm"+stageno+" from 0"
    bgmname="abogadrobgm"+stageno

(2)ボス戦の音楽を鳴らす
 ボス登場時にボス戦の音楽を鳴らします。mappntが4096の時にボス戦となります。この時、通常戦の音楽は止めますが、演奏を終了してから鳴らすまでに1、2秒空けた方がよいとされています。そこで、ボス登場の2秒前に止めます。mappntはメインループ1回で2ずつ増えます。await 16としていますからメインループ1回を処理するのにかかる時間は16ミリ秒です。するとmappntが4096-(2000/16*2)=3846の時に止めればよいということになります。
    ; ボス登場の2秒前にBGMを止める。
    if mappnt=3846 { gosub *BGM_Stop }

    ; ボス登場時、ボス用BGMを鳴らす。
    if (playerf!0)&(mappnt=4096) {
        mci "play bossbgm from 0"
        bgmname="bossbgm"
    }

(3)ステージクリアしたら音楽を止める
 ボスを倒したら音楽を止めます。
    ; 敵が爆発中の処理
    repeat 10
        if enemyf.cnt=3 {
            eplcnt.cnt=eplcnt.cnt+1
            k=enekind.cnt
                ・
                ・
                ・
            if (eneclass.k=2)&(eplcnt.cnt=300) {
                enemyf.cnt=0
                gosub *BGM_Stop
                ・
                ・
                ・
            }
        }
    loop

(4)ゲームオーバーになったら音楽を止める
 残機数が0になったら音楽を止めます。
    ; 自機爆発中の処理
    if playerf=3 {
        ・
        ・
        ・
        if nplayer=0 {
            ・
            ・
            ・
            gosub *BGM_Stop
        }
        ・
        ・
        ・
    }

(5)エンディングの音楽を流す
 エンディング画面になって2秒後に音楽を流します。キー入力されてタイトル画面に戻る時に音楽を止めます。
        ; エンディング
    *Ending
            ・
            ・
            ・
        endingcnt=0
        gosub *In_Key
        repeat
            await 16
            if endingcnt=125 {
                mci "play endbgm from 0"
                bgmname="endbgm"
            }
            gosub *In_Key
            if (pckey=0)&(ckey=1) {
                gosub *BGM_Stop
                break
            }
            endingcnt=endingcnt+1
        loop
        return


※お詫びと訂正
「敵が爆発中の処理」にバグがありました。お詫びして訂正します。
(誤)

	; 敵が爆発中の処理
	repeat 10
		if enemyf.cnt=3 {
			eplcnt.cnt=eplcnt.cnt+1
			k=enekind.cnt
			if (eneclass.k!2)&(eplcnt.cnt=15) { enemyf.cnt=0 }
			if (eneclass.k=2)&(eplcnt.cnt=300) {
				enemyf.cnt=0
				gosub *BGM_Stop
				stageno=stageno+1
				if stageno<=3 {
					goto *Stage_Start
				}
				else {
					gosub *Ending
					goto *Game_Start
				}
			}
		}
	loop
(正)
	; 敵が爆発中の処理
	f=0
	repeat 10
		if enemyf.cnt=3 {
			eplcnt.cnt=eplcnt.cnt+1
			k=enekind.cnt
			if (eneclass.k!2)&(eplcnt.cnt=15) { enemyf.cnt=0 }
			if (eneclass.k=2)&(eplcnt.cnt=300) {
				enemyf.cnt=0
				gosub *BGM_Stop
				stageno=stageno+1
				if stageno<=3 {
					f=1
					break
				}
				else {
					gosub *Ending
					f=2
					break
				}
			}
		}
	loop
	if f=1 { goto *Stage_Start }
	if f=2 { goto *Game_Start }
 repeat文からgotoで抜けてはいけません。breakで抜けましょう。(^_^;)


[目次へ][前へ][次へ] inserted by FC2 system