メインコンテンツへスキップ
見出し画像

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ファイルを載せておきますので、よろしかったら見てみてあげてください。

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


     
     
    出版社のしがない社内SE。 ここでは主に趣味のプログラミングやゲーム制作について書いています。作ったゲームは https://koidemizu.github.io/ で公開しているのでよかったら遊んでください。 ゲーム大好きインドア派。

    あなたへのおすすめ