Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails以外の開発一般

Python3でPygame入門:チャプター1

更新情報

  • 2017/10/17: 初版公開
  • 2021/02/19: 細部を更新

はじめに

雑用バイトの片山です。最近よくポンコツと罵られています。

ミーハーなので、NEW GAME!!のね◯っちに影響されてゲームを作ってみようと思いました。僕のアタマではゲームエンジン作るとか無理なのでPygame使います。

以前もPygameをいじったような気がしますが、今回は簡単なお絵かきで終わらせない(予定)ように頑張ります。

Pygame入門

導入についてはやり方を忘れてしまったので省きます。

以前の記事では編集部からPython3では動かないと指摘がありましたが、原因は不明です。

僕はいつもどおりPython3(3.5.2)を使っていきます。

また、前回のようにグダグダのしょうもない感じで終わらないように今回はこちらのサイトを参考にしながら進めていきたいと思います。

編集部注

Pythonとパッケージ管理ツールpipをインストールしていれば、pip install pygameでpygameを導入できます。

Pygameの基本を確認

ひとまずは基本の確認からやっていきます。参考サイトのサンプルとほとんど同じですが。

# -*- coding: utf-8 -*-
import pygame
from pygame.locals import *
import sys

def main():
    pygame.init() # 初期化
    screen = pygame.display.set_mode((600, 400)) # ウィンドウサイズの指定
    pygame.display.set_caption("Pygame Test") # ウィンドウの上の方に出てくるアレの指定

    while(True):
        screen.fill((255,63,10,)) # 背景色の指定。RGBだと思う
        pygame.display.update() # 画面更新

        for event in pygame.event.get(): # 終了処理
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

if __name__ == "__main__":
    main()

背景画像を表示する

前回のように四角形描画とかのんびりやってしまうと残念な感じで終わってしまう未来が見えるので、飛ばし気味でいきます。

次は背景画像を表示してみます。コードのファイルと同じディレクトリにpygame_test.jpgを置きます。

# -*- coding: utf-8 -*-
import pygame
from pygame.locals import *
import sys

def main():
    pygame.init() # 初期化
    screen = pygame.display.set_mode((500, 637)) # ウィンドウサイズの指定
    """ 参考サイトのコードは以下の三行だけど上の一行でも動いた
    (w, h) = (500, 637)
    pygame.display.set_mode((w, h), 0, 32)
    screen = pygame.display.get_surface()
    """
    pygame.display.set_caption("Pygame Test") # ウィンドウの上の方に出てくるアレの指定
    bg = pygame.image.load("pygame_test.jpg").convert_alpha() # 背景画像の指定
    rect_bg = bg.get_rect() # 画像のサイズ取得??だと思われる

    while(True):
        screen.fill((0, 0, 0, 0)) # 背景色の指定。RGBのはず
        screen.blit(bg, rect_bg) # 背景画像の描画
        pygame.time.wait(30) # 更新間隔。多分ミリ秒
        pygame.display.update() # 画面更新

        for event in pygame.event.get(): # 終了処理
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()

if __name__ == "__main__":
    main()

pygame.display.setうんたらかんたらのところの引数が増えててなんのこっちゃと思って調べました。
Pygameドキュメントによるとpygame.display.set_mode((横サイズ, 縦サイズ), flags, depth)とのことです。
フラグはディスプレイがどうのこうの言っててよくわからないですが基本的には指定しないか0にしとけばいいみたいです。
depthはカラービット深度らしいです。基本的には指定しなくていいって書いてありました。

要はサイズだけ指定しとけば動くということで、実際に試したらまったく問題ありませんでした。

終了処理のところも追加されていて、エスケープキーで終了出来るようになりました。

また、コメントにも書いてありますが、参考サイトでは3行で書いてあった部分は、一行でもとりあえず動いたので書き方の問題なのかなと思います。

使った写真はこの前関西に旅行に行った時に、多分伏見の辺りで撮影した川です。

Whileブロックの中の順番はけっこう適当でも大丈夫ですが、一つだけ注意点があって、背景色の指定をした後に背景画像を描画しないと、写真が背景色に塗りつぶされてしまいます。(背景色指定しなくてもいいかも……)

間違えて順番を逆にしてしまったときの画像

背景画像の上にキャラクターを描画する

今度は背景画像に加えてキャラクターを描画してみたいと思います。

ね◯っちみたいに絵を書くほどの気合は無いのでいらすとやから適当なものを持ってきました。

「ボタン電池を誤飲しそうな赤ちゃん」というタイトルにやられて赤ちゃんのpngデータを拝借しました。

# -*- coding: utf-8 -*-
import pygame
from pygame.locals import *
import sys

def main():
    pygame.init() # 初期化
    (w, h) = (500, 637)
    (x, y) = (w/2, h/2)
    pygame.display.set_mode((w, h), 0, 32)
    screen = pygame.display.get_surface()
    pygame.display.set_caption("Pygame Test") # ウィンドウの上の方に出てくるアレの指定
    bg = pygame.image.load("pygame_test.jpg").convert_alpha() # 背景画像の指定
    rect_bg = bg.get_rect() # 画像のサイズ取得??だと思われる
    player = pygame.image.load("baby.png").convert_alpha() # キャラ画像の指定
    rect_player = player.get_rect() # 謎
    rect_player.center = (x, y) # キャラ座標

    while(True):
        screen.fill((0, 0, 0, 0)) # 背景色の指定。RGBのはず
        screen.blit(bg, rect_bg) # 背景画像の描画
        screen.blit(player, rect_player) # キャラの描画
        pygame.time.wait(30) # 更新間隔。多分ミリ秒
        pygame.display.update() # 画面更新

        for event in pygame.event.get(): # 終了処理
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()

if __name__ == "__main__":
    main()

ボタン電池を誤飲しそうな赤ちゃんが川の真ん中に出現しました。
サイズのことは突っ込まないで下さい。

こちらもWhile内の描画順番だけは気をつけます。背景色塗りつぶし(または背景色指定なし) -> 背景画像の描画 ->
キャラ画像の描画
の順番じゃないとちゃんとできません。

キャラを動かす

なんとなく感覚が掴めてきましたのでキャラを動かしてみたいと思います。

恐らくrect_player.centerでキャラの表示位置を変えられるので、whileループの中に、画面更新のたびに座標の値が動く仕組みと、動いたx、yの値をrect_player.centerに代入してあげる仕組みを作ってあげれば良いのかなと。

# -*- coding: utf-8 -*-
import pygame
from pygame.locals import *
import sys

def main():
    pygame.init() # 初期化
    (w, h) = (500, 637)
    (x, y) = (w/2, h/2)
    pygame.display.set_mode((w, h), 0, 32)
    screen = pygame.display.get_surface()
    pygame.display.set_caption("Pygame Test") # ウィンドウの上の方に出てくるアレの指定
    bg = pygame.image.load("pygame_test.jpg").convert_alpha() # 背景画像の指定
    rect_bg = bg.get_rect() # 画像のサイズ取得??だと思われる
    player = pygame.image.load("baby.png").convert_alpha() # キャラ画像の指定
    rect_player = player.get_rect() # 謎
    rect_player.center = (x, y) # キャラ座標

    while(True):
        screen.fill((0, 0, 0, 0)) # 背景色の指定。RGBのはず
        screen.blit(bg, rect_bg) # 背景画像の描画
        screen.blit(player, rect_player) # キャラの描画
        pygame.time.wait(10) # 更新間隔。多分ミリ秒
        pygame.display.update() # 画面更新
        x += 1 # 画面更新毎にx座標を+1
        y += 1 # 画面更新毎にy座標を+1
        rect_player.center = (x, y)
        if x > w: # 端まで来たら座標を0にリセット
            x = 0
        if y > h: # 同上
            y = 0

        for event in pygame.event.get(): # 終了処理
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()

if __name__ == "__main__":
    main()

↓大体こんな感じで動きます。ボタン電池を誤飲しそうな赤ちゃんはサイズを調整しました。

sake

GIFの枚数少なめにしてしまったのでとてもシュールな動きに見えます。

おわりに

前のPygame記事(黒歴史)に比べたら遥かにマシな感じになった気がするのでこの辺で一旦区切ることにします。

関連記事

用務員バイトの日記:Pygameで遊んでみる

未経験大学生によるPython入門日誌-第1話


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。