見出し画像

pyxeleditorでサウンドを作る

Pythonのゲームエンジンpyxelでいろいろと遊んでいますが、サウンド系は手を出せないでいました。今回は以前の「【Python】波動を撃つ空手家【Pyxel】」で使用したファイルを改造して、BGMと効果音を作ってみます。

pyxeleditorのサウンド編集画面が以下になります。ここで音を作って、組み合わせたりしながらBGMや効果音を作っていきます。

画像1

左に鍵盤があり、クリックで音程を選択します。赤ドットは通常の音で、青ドットは休符です。
上のバーにはSOUND番号の切り替えと、SPEEDの変更、再生・停止・繰り返しボタンがあります。SPEEDは数字が小さいほど早くなります。
下にはTON・VOL・EFXの選択箇所があります。
TONはT・S・P・Nの4つが選択できます。それぞれTriangle・Square・Pulse・Noiseに対応していて音色が違うのですが、私の貧弱な表現力ではうまく書けませんでした……。Noiseはすごくわかりやすくて「ガザッ」て感じの、レトロゲームの爆発音みたいな感じです。
VOLは音量で0~7まで選択できます。
EFXは音のエフェクトです。N・S・V・Fの4つが選択でき、None・Slide・Vibrato・FadeOutに対応しています。これまたうまく書けそうにないので止めておきます……。なんか音が変わる感じです。

画像2

次はミュージックの編集画面です。サウンド編集画面で作ったサウンドを組み合わせて曲にします。上の部分ではMUSICの番号選択と、再生・停止・繰り返しボタンがあります。チャンネルはCH0~CH3まであり、同時に4音まで鳴らせるみたいですが、ちょっとまだ使いこなせていないです。

さて、こうして作ったBGMや効果音をコードの中に取り込んでいきます。
まずは、ミュージックを鳴らすコードです。

pyxel.playm(0, loop=True)

第一引数はミュージックの番号で、loopはその名の通りループ設定でTrueかFalseを選択できます。BGMのループ処理をupdate関数の中などで使うと毎フレームごとに音が鳴ってしまうので以下のようにして、一度だけ実行するようにします。

if self.music_flug == False:
         pyxel.playm(0, loop=True)
         self.music_flug = True

次はサウンドを鳴らす場合です。

pyxel.play(1,10,loop=False)

第一引数は使用チャンネル、第二はサウンド番号、第三がループ設定です。使用チャンネルについては、今回はミュージックでCH0を使用しているので、CH1を選択します。

サウンドを取り込んだコード全文は以下の通りです。

# -*- coding: utf-8 -*-

import pyxel

class App:
   def __init__(self): 
       self.move_r = 0 
       self.move_l = 0 
       self.atk_flug = 0 
       self.up_flug = 0 
       self.atk_count = 0 
       self.Player = Player(15, 19) 
       self.Hadou = []
       self.music_flug = False
       
       pyxel.init(64,35)

       pyxel.load('assets/sf.pyxres')
       
       pyxel.run(self.update, self.draw)
       
   def update(self):
       #BGM_Ctr
       if self.music_flug == False:
         pyxel.playm(0, loop=True)
         self.music_flug = True
       
       if pyxel.btnp(pyxel.KEY_Q):
           pyxel.quit()
           
       #Attack_action    
       if self.atk_flug == 0: 
           #Hado
           if pyxel.btnp(pyxel.KEY_SPACE): 
               if (self.move_r == 0 )and(self.move_l == 0):
                   if len(self.Hadou) < 1: 
                       self.atk_flug = 1
                       self.atk_count = 1
                       pyxel.play(1,10,loop=False)
                       new_Hadou = Hadou(self.Player.player_x + 8,
                                         self.Player.player_y + 3)
                       self.Hadou.append(new_Hadou)
           #Syoryu
           if pyxel.btnp(pyxel.KEY_V): 
               if (self.move_r == 0 )and(self.move_l == 0):
                   self.atk_flug = 1
                   self.atk_count = 1
                   self.up_flug = 1
                   pyxel.play(1,11,loop=False)
           #Move_right        
           if pyxel.btn(pyxel.KEY_RIGHT): 
               if self.Player.player_x < 51:
                   self.move_r = 1
                   self.Player.update(self.Player.player_x + 0.5,
                                    self.Player.player_y)
           else:
               self.move_r = 0
           #Move_left
           if pyxel.btn(pyxel.KEY_LEFT): 
               if self.Player.player_x > 0:
                   self.move_l = 1
                   self.Player.update(self.Player.player_x - 0.5,
                                            self.Player.player_y)
           else:
               self.move_l = 0
       else: 
           self.atk_count = self.atk_count + 1 
           if self.atk_count > 18: 
               self.atk_flug = 0
               self.atk_count = 0
               self.up_flug = 0
               
       #Hadou_move
       if len(self.Hadou) >= 1: 
           if self.Hadou[0].hadou_x < 70:
               x = self.Hadou[0].hadou_x + 1.5
               y = self.Hadou[0].hadou_y
               self.Hadou[0].update(x, y)
           else:
               del self.Hadou[0]

   def draw(self):
       pyxel.cls(13)
       
       #Draw tilemap
       pyxel.bltm(0,0,0,0,0,8,5)
       
       #Draw_player
       if self.move_r == 1:
           pyxel.blt(self.Player.player_x,self.Player.player_y,
                     0,0,16,16,16,3)
       elif self.move_l == 1:
           pyxel.blt(self.Player.player_x,self.Player.player_y,
                     0,16,16,16,16,3)
       elif self.atk_flug == 1:
           #Draw_upper
           if self.up_flug == 1:
               if self.atk_count < 9:
                   s = self.atk_count + 2
                   pyxel.blt(self.Player.player_x+0.1,self.Player.player_y-s,
                             0,0,32,16,20,3)
               else:
                   s = 18 - self.atk_count
                   pyxel.blt(self.Player.player_x,self.Player.player_y-s,
                             0,16,32,16,20,3)
           else:
               pyxel.blt(self.Player.player_x,self.Player.player_y,
                         0,16,0,16,16,3)
       else:
           pyxel.blt(self.Player.player_x,self.Player.player_y,0,0,0,16,16,3)
       
       #Draw_hadou
       if len(self.Hadou) >= 1:
           pyxel.blt(self.Hadou[0].hadou_x,self.Hadou[0].hadou_y,
                     0,32,0,8,8,3)
       
       
       
class Player:
   def __init__(self, x, y):
       self.player_x = x
       self.player_y = y
   def update(self, x, y):
       self.player_x = x
       self.player_y = y
       
class Hadou:
   def __init__(self, x, y):
       self.hadou_x = x
       self.hadou_y = y
   def update(self, x, y):
       self.hadou_x = x
       self.hadou_y = y

       
App()

音は載せられないですがとりあえずこれで完成です。背景は「朱雀城」っぽくして、波動と昇竜を打てるようにしました。

画像3

今回使ったpyxresファイルを載せておきますので、よろしかったら見てみてあげてください。

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


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