見出し画像

pyxelの作曲ツールを使ってみる(2)

前回は音楽ファイルのjsonを作るところまでできたので、今回は実際にpyxelアプリケーションに組み込む部分を書いていこうと思います。

前回のnoteはこちら↓

8bit BGM Generatorに関するfrenchbreadさんのnoteはこちら↓

さて、それでは今作っているサンドボックスゲームにBGMを付けてみましょう。
データ読み込みのコードは以下のような感じ。

#音楽データの読み込み
with open(f"assets/music.json", "rt",encoding="utf-8") as fin:
    self.music = json.loads(fin.read())

今回はassetsフォルダにmusic.jsonを置いて読み込ませています。これでまずself.musicに音楽ファイルの中身が入りました。

再生するときは以下のようにします。

 #再生
 if pyxel.play_pos(0) is None:
     for ch, sound in enumerate(self.music):
         pyxel.sound(ch).set(*sound)
         pyxel.play(ch, ch, loop=True)       

実行サンプルのplay.pyからほぼコピペなのですが、これで動きます。
ここまでやるとアプリの実行時に作ったBGMが流れるようになりました。

さて、ここで1つ実験をしてみます。
再生をするコードの直下にこんなコードを付け足します。

pyxel.stop(0)
pyxel.stop(1)
pyxel.stop(2)
pyxel.stop(3)

これは音楽を止めるpyxelの命令です。pyxelでは同時に鳴らせる音は4音と決まっているので、音楽のチャンネルは0~3です。
このコードを足すと何も聞こえなくなります。
では以下のようにしてみるとどうでしょうか。

 #pyxel .stop(0)
pyxel.stop(1)
pyxel.stop(2)
pyxel.stop(3)

チャンネル0だけコメントアウトしました。という事は「チャンネル0だけ止まっていない」ので「チャンネル0だけ鳴っている」ことになります。

このようにして各チャンネルを単独にして鳴らしてみると、メロディ・ドラム・ベースと別れて鳴っていることが分かります。
そしてチャンネル3では何も鳴っていないことも分かります。
なので、チャンネル3を使って効果音を鳴らしてみましょう。

▲エディタを使って効果音を作成。
単純な「ピッ」という音。カーソルが動いたときに鳴らします。

では実装するのですがここで注意点。
.pyxresファイルはself.musicに入れた音楽データをpyxel.soundでセットした後に読み込む必要があります。
これはpyxel.sound(ch).set(*sound)の命令でサウンドデータが上書きされるためです。なので全体を繋げると以下のような順番になります。

        #音楽データの読み込み
        with open(f"assets/music.json", "rt",encoding="utf-8") as fin:
            self.music = json.loads(fin.read())
        #再生
        if pyxel.play_pos(0) is None:
            for ch, sound in enumerate(self.music):                
                pyxel.sound(ch).set(*sound)
                pyxel.play(ch, ch, loop=True)        

        # リソースの読み込み
        pyxel.load("assets/assets.pyxres")        

実際に効果音を鳴らすタイミングでは以下の命令を使います。

pyxel.play(3,0)

実行してみるとBGMが流れつつ、カーソルが動いた際には効果音が鳴っていることが分かります。
↓のページで動くのでよろしければご覧ください。

これでBGM+効果音の実装ができました。
ただ、今まであまり気にしていなかった問題も出てきてしまいました。
それは「処理落ち」です。ゲームではあるあるの話ですが、今までは無音だったこともあり気になりませんでした。ただ、今回BGMを付けたのでオブジェクトを大量に作ったりして処理が圧迫されると音がプツプツ途切れてしまいます。きれいに流すためには処理低減について考えなければいけなさそうです。(※今回はオブジェクトの同時処理数を制限してお茶を濁しています…。)

今回はここまで。
読んでいただきありがとうございました。

ここまで読んでいただきありがとうございます!