LoginSignup
2
3

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

Last updated at Posted at 2024-02-08

はじめ

普段勉強しているPythonでもゲームが作れるらしいのでやってみた。
使ったのは、ゲーム開発ライブラリ「Pygame」。
RPGでよく見る、キャラクターがテクテク歩くのを再現してみた。
pygame_man3.gif

キャラクターを表示させる

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

キャラクターを上下左右に動かす

矢印キーの入力でキャラクターを上下左右に動かしたいので、押されたキーを判別する。
pygame.key.get_pressed()でキーの入力を取得。
矢印キーはそれぞれ、K_LEFT K_RIGHT K_UP K_DOWNで書くので、if文をこんな感じにして

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

キャラクターの向きを変える

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

anime.png

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)を用意して、キャラクターの表示を配列に変更

muki = 0    #while文の外に書く
screen.fill(white)
screen.blit(anime[muki],(px,py))    #man→anime[muki]

矢印キーの入力を判断するif文の中で、向きを指定する変数を変えるようにすると、

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

アニメーションさせる

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

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

anime (2).png

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のまま。

ugoki = 0    #while文の外に書く
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は0と1を交互に表示して欲しいので「2で割った余り」にする。
(今回絵が2枚なので、「0,1」だが、絵の数が3枚なら「0,1,2」なので%3、、、みたいに増える)

screen.fill(white)
screen.blit(anime[muki][ugoki%2],(px,py))   #anime[muki]→anime[muki][ugoki%2]

完成!!!

pygame_man3.gif

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

完成したコード

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()

おわり

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

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

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3