Tonyu System 2であほげーを作ろう - その7 サウンド関係

# 記事一覧

[第1回 設定とタイトル](https://qiita.com/hoge1e3/items/388bdb47f3d56ed0789f)
[第2回 メイン画面](https://qiita.com/hoge1e3/items/1a471a00b38576430f7e)
[第3回 ターゲットと敵と](https://qiita.com/hoge1e3/items/c5d8379db1304a2897fd/)
[第4回 スコア・時間など](https://qiita.com/hoge1e3/items/e2ab8fbe03469e933022)
[第5回 ゲームを公開する](https://qiita.com/hoge1e3/items/f7bd844fd9743073190e)
[第6回 Twitterにスコアを投稿](https://qiita.com/hoge1e3/items/821e5dd1f163d3d9f3c3/)
[第7回 サウンド関係](https://qiita.com/hoge1e3/items/a5b1726f6c95bbb4e852)
[第8回 物理エンジンなど](https://qiita.com/hoge1e3/items/b2a0df1d5aaba773310f)

# はじめに

[あほげー](http://ahoge.info)開催間近なので，どんどん追加します．
あとゲームに必要な要素といえば，音ですかね，ということで追加しました．

[今回のプログラムを開く](https://edit.tonyu.jp/index.html?fromPrjB=ahgtmpl0.08.zip)

2018/7/12訂正：このバージョンでは，サウンドの設定をOFFにしても，1プレイ後タイトルに戻ったときにサウンドの設定がONに戻ってしまう不具合があります．[最新バージョン](https://edit.tonyu.jp/index.html?fromPrjB=ahgtmpl0.11.zip)で修正しました（ゲーム内容が変わっちゃってますけど）．変更内容はこの記事の最後に説明しています．

# 音源の追加

まず，素材となる音を追加します．メニューから「ウィンドウ」→「音声リスト」を選び，音声ファイルを追加します．

<img width="194" alt="スクリーンショット 2018-07-03 18.49.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/127248/4c3f931d-e2c6-590c-d25c-0d6d61b7e133.png">

対応している音声ファイルは，スクリーンショットに書いてある通りです．

- MIDIについては[PicoAudio](https://github.com/cagpie/PicoAudio.js)を使って鳴らしています．
- mp3 を[ダウンロード版](https://www.tonyu.jp/Tonyu2DL.php)で利用する場合には[ffrmpeg](https://www.tonyu.jp/tonyu2/ffmpeg.html) を別途ダウンロードしてください．

<img width="487" alt="スクリーンショット 2018-07-03 18.49.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/127248/ab3c895a-18a4-184e-a47f-5ea9ac390777.png">

それぞれの音声ファイルには `$se_????` というグローバル変数が割り当てられます．

# BGMを鳴らすプログラム

Mainクラスで，ゲームスタート，クリア，ゲームオーバーになったときに[$sound.playBGM](https://edit.tonyu.jp/doc/T2MediaPlayer.playBGM.html) で音声をBGMとして再生します．第一引数に，さきほどの音声リストで追加したファイルに割り当てられた変数名`$se_????`を指定します．第2引数はループ再生をするかどうかを指定します．

~~~JS:Main
//中略
$sound.playBGM($se_bgm,true);//★ゲーム中に流れるBGM
while($state=="play") {
    //中略
}
switch($state) {
    case "gameover":
    $sound.playBGM($se_death);//★ゲームオーバーになったときのBGM
    new Label{text="ゲームオーバー",x=230,y=200,size=50};
    $mesg=$theme+"を"+$score+"個集めたところで"+$subTheme+"に阻まれて無念のリタイア．";
    break;
    case "clear":
    $sound.playBGM($se_fanfare);//★ゲームクリアしたときのBGM
    $mesg=$time+"秒かけて"+$theme+"を見事"+$score+"個集めきった．";
    new Label{text="クリア",x=230,y=200,size=50};
    break;
}
~~~

# 効果音を鳴らすプログラム

Playerクラスでは，プレイヤーがターゲットをとったときに効果音を鳴らしています．[$sound.playSE](https://edit.tonyu.jp/doc/T2MediaPlayer.playSE.html)メソッドで鳴らします．後ろについている`{rate=1+$score*0.1}`は， 再生速度を変化させるためのものです．rate=1 のときがもとのファイルと同じ速さです．ここでは，スコアが増えるにつれて速く再生させています．

~~~JS:Player

pad=new APad;
p=$pat_ahoge26+0;
while(true) {
    x+=pad.vx*5;
    y+=pad.vy*5;
    t=crashTo(Target);
    if (t) {
        //★ターゲットをとったときに効果音
        $sound.playSE($se_coin) {rate=1+$score*0.1};
        $score+=1;
        t.die();
        if ($score>=10) {
            $state="clear";
            break;
        }
    }
    e=crashTo(Enemy);
    if (e) {
        $state="gameover";
        die();
    }
    update();
}
~~~

# サウンドのON/OFFの設定

音を鳴らしたくない場合は[$sound.mute](https://edit.tonyu.jp/doc/T2MediaPlayer.html) をtrue に設定します．タイトル画面で切り替えられるようにしています．

~~~JS:Title
//前略
//Sound:ON  または Sound:OFF を表示するラベル
sb=new Label{text="Sound:ON",y=360,x=150,size=30};
//切り替えボタン
new Button{
    text="On↔Off",
    left=250,
    top=360,
    width=180,
    height=40,
    onClick=toggleSound
};
$sound.mute=false;
//中略
\toggleSound () {
    //サウンドがONならOFFに，OFFならONに
    $sound.mute=!$sound.mute;
    sb.text=$sound.mute ? "Sound:OFF": "Sound:ON";
    $sound.playSE($se_coin);//ONのときは鳴る
}
~~~

2018/7/12訂正：[最新バージョン](https://edit.tonyu.jp/index.html?fromPrjB=ahgtmpl0.11.zip)では，`$sound.mute=false;`はSetting クラスに移動しました．また，toggleSoundメソッド内の`sb.text=$sound.mute ? "Sound:OFF": "Sound:ON";`の行をボタン`sb`生成直後にも実行するようにしています．

# おまけ

[効果音を作成できるサイト](https://rawgit.com/hoge1e3/MezonetJS/master/parse.html)を作りました．使い方はまだ書いていませんが，サンプルを参考にしてください．

Last: [第8回 物理エンジンなど](https://qiita.com/hoge1e3/items/b2a0df1d5aaba773310f)