Pygameでキャラクターを動かしてみた


## はじめ
普段勉強しているPythonでもゲームが作れるらしいのでやってみた。
使ったのは、ゲーム開発ライブラリ「Pygame」。
RPGでよく見る、キャラクターがテクテク歩くのを再現してみた。
![pygame_man3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/19d9dc80-0453-ab93-b50a-3fcd200178ac.gif)
# キャラクターを表示させる

~~~python
import sys
import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((600, 400))

white = (255,255,255)

def main():
    
    px=100
    py=100
    
    man = pygame.image.load("man.png")
    man = pygame.transform.scale(man,(100,100))

    while True:
         
        screen.fill(white)
        screen.blit(man,(px,py))

        pygame.display.update() 
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

if __name__ == '__main__':
    main()
~~~


キャラクターは移動させたいので、(px,py)で位置指定。
ここまではキホンなので解説なしで。
こんな感じに用意したキャラクターが出てくれば○。

![スクリーンショット (67).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/31eb9d67-4c03-727b-65fd-1fdd19017998.png)

## キャラクターを上下左右に動かす
矢印キーの入力でキャラクターを上下左右に動かしたいので、押されたキーを判別する。
`pygame.key.get_pressed()`でキーの入力を取得。
矢印キーはそれぞれ、`K_LEFT` `K_RIGHT` `K_UP` `K_DOWN`で書くので、if文をこんな感じにして
~~~Python
pressed_keys =pygame.key.get_pressed()
        if pressed_keys[K_LEFT]:
            px -= 0.1
        elif pressed_keys[K_RIGHT]:
            px += 0.1
        elif pressed_keys[K_UP]:
            py -= 0.1
        elif pressed_keys[K_DOWN]:
            py += 0.1
~~~
押されている間、(px,py)の位置を変化させる。
矢印キーの入力でキャラクターが動くようになった。

![pygame_man.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/93343612-33eb-c1b8-da35-b2ef6e4c5265.gif)

## キャラクターの向きを変える
キャラクターがずっとこっちを見てるのは変なので、進行方向を向かせたい。
進行方向分の絵を用意して、配列に突っ込む。

![anime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/b1e99e0e-aaa0-f005-ee57-486afdc50713.png)

~~~Python
anime=[]
    
man = pygame.image.load("man.png")
man = pygame.transform.scale(man,(100,100))
anime.append(man)
    
man = pygame.image.load("man_back.png")
man = pygame.transform.scale(man,(100,100))
anime.append(man)
    
man = pygame.image.load("man_left.png")
man = pygame.transform.scale(man,(100,100))
anime.append(man)
    
man = pygame.image.load("man_right.png")
man = pygame.transform.scale(man,(100,100))
anime.append(man)
~~~
向きを指定するための適当な変数（ここではmuki）を用意して、キャラクターの表示を配列に変更
~~~Python
muki = 0    #while文の外に書く
~~~

~~~Python
screen.fill(white)
screen.blit(anime[muki],(px,py))    #man→anime[muki]
~~~

矢印キーの入力を判断するif文の中で、向きを指定する変数を変えるようにすると、
~~~Python
pressed_keys =pygame.key.get_pressed()
        if pressed_keys[K_LEFT]:
            px -= 0.1
            muki = 2   #追加
        elif pressed_keys[K_RIGHT]:
            px += 0.1
            muki = 3   #追加
        elif pressed_keys[K_UP]:
            py -= 0.1
            muki = 1   #追加
        elif pressed_keys[K_DOWN]:
            py += 0.1
            muki = 0   #追加
~~~
押されたキーによって、表示する配列の画像を変えられるようになった。
こんな感じで進行方向を向くのでなかなかそれっぽい。

![pygame_man2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/3c22f739-713b-9a02-e90c-594da2f0899c.gif)

## アニメーションさせる
アニメーションというと大げさかもしれないが、せっかくなら歩いているように見せたいので、横移動で腕を振ってみる。(なお、私の画力がそろそろ限界。。。)

animeの配列を二次元配列にして、この配列を作る。

![anime (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/d2837502-66ea-9eb1-5371-ba9d156ec550.png)

~~~Python
anime=[[0],[0],[0,0],[0,0]]
    
man = pygame.image.load("man.png")
man = pygame.transform.scale(man,(100,100))
anime[0][0]=man
    
man = pygame.image.load("man_back.png")
man = pygame.transform.scale(man,(100,100))
anime[1][0]=man
    
man = pygame.image.load("man_left.png")
man = pygame.transform.scale(man,(100,100))
anime[2][0]=man
    
man = pygame.image.load("man_right.png")
man = pygame.transform.scale(man,(100,100))
anime[3][0]=man
    
man = pygame.image.load("man_left2.png")
man = pygame.transform.scale(man,(100,100))
anime[2][1]=man
    
man = pygame.image.load("man_right2.png")
man = pygame.transform.scale(man,(100,100))
anime[3][1]=man
~~~

ugoki変数を作って、左右移動で増え続けるように。上下移動は0のまま。
~~~Python
ugoki = 0    #while文の外に書く
~~~

~~~Python
pressed_keys =pygame.key.get_pressed()
        if pressed_keys[K_LEFT]:
            px -= 0.1
            muki = 2
            ugoki += 1   #追加
        elif pressed_keys[K_RIGHT]:
            px += 0.1
            muki = 3
            ugoki += 1   #追加
        elif pressed_keys[K_UP]:
            py -= 0.1
            muki = 1
            ugoki = 0   #追加
        elif pressed_keys[K_DOWN]:
            py += 0.1
            muki = 0
            ugoki = 0   #追加
~~~

表示を二次元配列に変更。
ugokiは０と１を交互に表示して欲しいので「２で割った余り」にする。
（今回絵が2枚なので、「0,1」だが、絵の数が3枚なら「0,1,2」なので%3、、、みたいに増える）
~~~Python
screen.fill(white)
screen.blit(anime[muki][ugoki%2],(px,py))   #anime[muki]→anime[muki][ugoki%2]
~~~

**完成！！！**

![pygame_man3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492627/19d9dc80-0453-ab93-b50a-3fcd200178ac.gif)

違和感があるのは私の画力のせいなので、、、、
ちゃんとした絵を用意したり、動きを２枚だけではなくもっとなめらかに動くように数を用意すれば、良い感じになるはずです。

## 完成したコード
~~~Python
import sys
import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((600, 400))

white = (255,255,255)

def main():
    
    px=100
    py=100
    
    anime=[[0],[0],[0,0],[0,0]]
    
    man = pygame.image.load("man.png")
    man = pygame.transform.scale(man,(100,100))
    anime[0][0]=man
    
    man = pygame.image.load("man_back.png")
    man = pygame.transform.scale(man,(100,100))
    anime[1][0]=man
    
    man = pygame.image.load("man_left.png")
    man = pygame.transform.scale(man,(100,100))
    anime[2][0]=man
    
    man = pygame.image.load("man_right.png")
    man = pygame.transform.scale(man,(100,100))
    anime[3][0]=man
    
    man = pygame.image.load("man_left2.png")
    man = pygame.transform.scale(man,(100,100))
    anime[2][1]=man
    
    man = pygame.image.load("man_right2.png")
    man = pygame.transform.scale(man,(100,100))
    anime[3][1]=man
    
    muki = 0
    ugoki = 0

    while True:
         
        screen.fill(white)
        screen.blit(anime[muki][ugoki%2],(px,py))

        pygame.display.update() 
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
                
        pressed_keys =pygame.key.get_pressed()
        if pressed_keys[K_LEFT]:
            px -= 0.1
            muki = 2
            ugoki += 1
        elif pressed_keys[K_RIGHT]:
            px += 0.1
            muki = 3
            ugoki += 1
        elif pressed_keys[K_UP]:
            py -= 0.1
            muki = 1
            ugoki = 0
        elif pressed_keys[K_DOWN]:
            py += 0.1
            muki = 0
            ugoki = 0

if __name__ == '__main__':
    main()
~~~

## おわり
初心者にもわかりやすいように書いてみましたが、どうだったでしょうか。

良い感じの動きに見えるようには画力が欲しいところですね、、、