PygameでRPG制作　ーーそれっぽい画面を作ってみよう③効果音を使ってみよう

この記事は、岩手県八幡平市のプログラミング教室「アクセルキャンプ」の公開教材です。
[アクセルキャンプ(フリースペースプラウド)のリンク](https://freespaceproud.com)
教材の作成依頼等も承っております。ご意見等は、リンク先の問い合わせ欄からお願いします。
教材の転用・利用等は自由です  


# 教室をアップデートしました。
みなさん、フリースペースproudに革命が起きました！なんと、電子レンジが導入されました！！料理するのが面倒なリッキーは、電子レンジ一つでできる系の料理が大好きです！最近はご飯も炊けるんですね。まさに文明のリッキー。  
  
# 今週の目標
前回のページで紹介できなかった、というか、紹介するのをすっかり忘れていた、矢印機能を追加して、その後でSEO(=Sound Effect = 効果音)の付け方を勉強していきます。いよいよゲームっぽくなってくるので、楽しくコードを書いていきましょう！

# 矢印機能
矢印に関して、画像のデータを用意することも可能ですが、今回は文字で矢印マークを出すだけにします(ひらがなで「みぎ」と変換すると出てきます)。前回は選択肢の文字を変更する処理をしたので、その近くを変更していけばなんか行けそうな気がするぞ？みたいな気がしませんか？

コードを良く見返して、選択肢の文字を作成している部分を探しましょう。

<前回までのコード>
```python
import pygame
from pygame.locals import *
import sys


def main():
    pygame.init()  # Pygameの初期化
    screen = pygame.display.set_mode((800, 600))  # 400 x 300の大きさの画面を作る
    pygame.display.set_caption("いけめんがつくったげえむ")  # 画面上部に表示するタイトルを設定

    rect_x = 20  # 長方形左上のｘ座標
    rect_y = 400  # 長方形左上のｘ座標
    rect_width = 800 - (rect_x * 2)  # 長方形の幅
    rect_height = 600 - (rect_y + 20)  # 長方形の高さ
    slyme_image = pygame.image.load("image/slyme.png")

    font = pygame.font.Font("font/DragonQuestFC.ttf", 30)

    action_number = 0  # 選択肢の番号
    white = (255, 255, 255)
    yellow = (255, 255, 0)

    while (1):
        colors = [white, white, white]
        colors[action_number] = yellow

        screen.fill((0, 0, 0))  # 画面を黒色に塗りつぶし
        screen.blit(slyme_image, (400 - (400 / 2), 0))

        pygame.draw.rect(screen, (255, 255, 255), Rect(rect_x, rect_y, rect_width, rect_height), 10)
        text = font.render("りっきーが　あらわれた！", True, (255, 255, 255))

        battle_text = font.render("たたかう", True, colors[0])
        spell_text = font.render("じゅもん", True, colors[1])
        run_text = font.render("にげる", True, colors[2])

        screen.blit(text, (40, 420))
        screen.blit(battle_text, (45, 450))
        screen.blit(spell_text, (45, 480))
        screen.blit(run_text, (45, 510))

        pygame.display.update()  # 画面を更新
        # イベント処理
        for event in pygame.event.get():
            if event.type == QUIT:  # 閉じるボタンが押されたら終了
                pygame.quit()  # Pygameの終了(画面閉じられる)
                sys.exit()

            elif event.type == KEYDOWN:
                if action_number == 2:
                    action_number = 0
                else:
                    action_number += 1


if __name__ == "__main__":
    main()

```
たたかう・にげる・じゅもん を探せば一目瞭然ですね。
```python
battle_text = font.render("たたかう", True, colors[0])
spell_text = font.render("じゅもん", True, colors[1])
run_text = font.render("にげる", True, colors[2])
```

やりかたはいくつかあるのですが、今回は以下の順番で処理していきます。
>①変数arrowを用意。初期値は"  "(全角スペース)が③つはいったリストにする
②arrow[action_number]の中身を"  "から"→"に変更する
③font.renderの部分で、「たたかう」等の文字とガッチャンコして表示する。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2732489/dc3d8496-907a-ef0f-f92d-ec199e5b6504.png)

どうでしょう、これで矢印がちゃんと表示されて、更に表示が見やすくなったと思います。

# ここで一つ修正  
今のこのコードでは、大きな問題があるの、分かりますか？そう、どのキーを押してもカーソルが下に移動してしまうのです。下矢印を押したら下、上矢印を押したら上に移動するようにするには、どうしたらいいでしょうか。

答えは簡単、押されたボタンによって、action_numberに対する変化を変えればいいのです。ボタンを押すのはイベントの一つですので、forループのところに改良を加えて行きましょう。

pygameでは、ボタンの種類を判別するための名前が決まっています。
上矢印(↑):K_UP
下矢印(↓):K_DOWN
これを使って、条件分岐で処理を書いていきます。

```python
for event in pygame.event.get():
    if event.type == QUIT:  # 閉じるボタンが押されたら終了
        pygame.quit()  # Pygameの終了(画面閉じられる)
        sys.exit()

    elif event.type == KEYDOWN:
        if event.key == K_UP:
            if action_number == 0:
                action_number = 2
            else:
                action_number -= 1
        elif event.key == K_DOWN:
            if action_number == 2:
                action_number = 0
            else:
                action_number += 1

```

上と下で、逆の処理をすればいいんですね。

# ちょっと立ち止まって考えてみよう。
先程の上キー機能の追加ですが、全てがaction_numberに関連した処理になっているのに気が付きますか？そういえば先程、矢印機能もaction_numberという変数を使って実装していましたね。

今回これらの変更が簡単にできたのは、設計段階で「action_number」という変数を軸に選択肢が挙動を変える仕組みにしていて、それがうまく行ったといえます。こうした設計をしていないと。余計に変数を作ったり、本来書かなくてもいい処理を書いたりしなくてはならず、結果として無駄に行の多い、質の悪い・読みにくいコードが出来上がってしまいます。こんな単純なゲームを書くときでも、キレイなコードを書くことを意識していると、上達もとても早いですので、普段から意識してみましょう。

# 効果音をつけよう！
まず、選択肢を変更したときに鳴らす効果音を用意しましょう。今回は[ここ](https://taira-komori.jpn.org/game01.html)のサイトから頂いてきました。

好きなサウンドをダウンロードできたら、プロジェクト内にsoundフォルダを追加して、その中にファイルを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2732489/bd7a4b71-798e-bfd0-946a-689f24411722.png)

以前imageフォルダの中にデータを入れたのを思い出しましょう。main.pyから見てselect_sound.mp3にたどり着くには、「soundフォルダの中のselect_sound.mp3」という風にガイドして上げればイッパツですね。

効果音を再生するには、以下のことを行う必要があります。
①pygame.mixerの初期化(書かなきゃいけないヤツ)
```python
pygame.mixer.init()
```
②効果音ファイルをロード
```python
pygame.mixer.music.load("効果音ファイルの場所")
```
③再生
引数として、何回繰り返し再生するかを指定します。
ここで-1と指定すると、無限ループになります。
```python
pygame.mixer.music.play(1)
```
あとはこれらをどこで定義するかですね。初期設定として定義できるものはメインループ前に書いたり、再生処理を最適な場所に書いたりですね。

ただ、ちょっとまってください。今はselect_sound.mp3しか使わないですが、今後、攻撃のサウンドや、呪文のサウンドを使うことを考えると、音声ファイルを引数として、関数化したほうがいいと思いますので、やってみましょう。
```python
import pygame
from pygame.locals import *
import sys

# 効果音を再生する関数
def sound_effect(sound):
    pygame.mixer.music.load(sound)
    pygame.mixer.music.play(1)


    /*中略*/
    # 効果音
    select_sound = "sound/select_sound.mp3"

    while (1):
        /*中略*/
        # イベント処理
        for event in pygame.event.get():
            if event.type == QUIT:  # 閉じるボタンが押されたら終了
                pygame.quit()  # Pygameの終了(画面閉じられる)
                sys.exit()

            elif event.type == KEYDOWN:
                if event.key == K_UP:
                    if action_number == 0:
                        action_number = 2
                    else:
                        action_number -= 1
                     
                    # 再生
                    sound_effect(select_sound)
                elif event.key == K_DOWN:
                    if action_number == 2:
                        action_number = 0
                    else:
                        action_number += 1
                    # 再生
                    sound_effect(select_sound)


if __name__ == "__main__":
    main()

```


***
# やってみよう！
原罪、音は一種類のみで、「ピコッ」という音しかしません。[ここ](https://taira-komori.jpn.org/game01.html)など、著作権フリーな音源を使って、「たたかう」「じゅもん」「にげる」のファイルをダウンロードして。それぞれ、たたかうを選択しているときにエンターキーを押すと対応する音が出る、という仕組みを作っていきましょう。ファイルを用意して、コードの配置をしていくわけですが、「あれ？エンターキーってどうやって判別する？」みたいな疑問が発生すると思います。ググりまくりましょう！

ではまた来週♪