この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
「第3章 Pythonの基本的な文法」は省略します。こちらは同人誌をご覧ください。
ここからしばらくは『Pygame』の基本的な使い方を学んでいきます。
『Pygame』の基本的な使い方を学びます。コンピューター ゲームとして必要な処理を1つずつ見ていきます。
基本的には、ドキュメントに書いてあるとおりです。パッケージやモジュールの細かな仕様は、それぞれのドキュメントにあります。数がかなりあるので、この本では必要なことを抜粋して説明します。
Pygame Front Page — pygame documentation
https://www.pygame.org/docs/index.html
まずは『Pygame』でプログラムを書くときの基本的な構造です。「example_pygame/basic.py」を示します。
import pygame
pygame.init() # Pygameを初期化screen = pygame.display.set_mode((800, 600)) # 画面作成image = pygame.image.load("image/icon.png") # 画像読み込みclock = pygame.time.Clock() # 時計作成running = True # 実行継続フラグ
while running: pygame.display.update() # 画面を更新 screen.fill(pygame.Color(0, 0, 0)) # 画面を塗りつぶす
for event in pygame.event.get(): # イベント if event.type == pygame.QUIT: running = False # 終了
screen.blit(image, (32, 32)) # 描画
pygame.display.flip() # 画面フリップ delta = clock.tick(60) # 60fps制限 print(delta)pygame.quit() # Pygameを終了
まずは、import pygame
で『Pygame』を読み込みます。そして、pygame.init()
で初期化をしたあとに処理をおこないます。終了時にはpygame.quit()
を実行します。
import pygame
# 初期化pygame.init()
# pygameを利用したさまざまな処理
# 終了pygame.quit()
ウィンドウの作成はpygame.display.set_mode()
でおこないます。第1引数でウィンドウの描画領域のサイズを指定します。サイズは、横幅と高さのタプルやリストで指定します。
第2引数には、ウィンドウを制御するフラグを|
で繋いで複数書けます。いくつかのフラグを掲載します。他にはOpenGLを利用する際の設定などもあります。
第2引数のフラグ
フラグ | 説明 |
---|---|
pygame.FULLSCREEN |
フルスクリーン(モニターの解像度を変える) |
pygame.RESIZABLE |
ウィンドウのリサイズを可能にする |
pygame.NOFRAME |
枠なし |
pygame.SCALED |
デスクトップに収まるように整数倍で自動スケール |
pygame.SHOWN |
表示(デフォルト) |
pygame.HIDDEN |
非表示 |
pygame.FULLSCREEN
は注意が必要です。モニターの解像度を、描画サイズと同じに変更します。そのため、ウィンドウやアイコンのレイアウトが崩れます。少し使いにくい機能です。
ウィンドウの準備をしたあとは、while
文でループを回します。このループは、pygame.event.get()
で得たevent.type
がpygame.QUIT
だった場合に抜けます。ループを抜けてpygame.quit()
しないと、ウィンドウの×ボタンを押しても、ウィンドウが閉じないので注意が必要です。
screen = pygame.display.set_mode((800, 600)) # 画面作成running = True # 実行継続フラグ
while running: for event in pygame.event.get(): # イベント if event.type == pygame.QUIT: running = False # 終了pygame.quit() # Pygameを終了
画像はpygame.image.load()
で読み込めます。読み込んだ画像はSurface
(pygame.Surface
)というオブジェクトになります。描画領域を表すscreen
もSurface
です。
Surface
への描画はblit()
関数でおこないます。第1引数は描画するSurface
オブジェクト、第2引数はXY位置のタプルやリストです。
image = pygame.image.load("image/icon.png") # 画像読み込みscreen.blit(image, (32, 32)) # 描画
描画の基本ループを示します。pygame.display.update()
で画面を更新します。そのあと描画をおこないます。最後にpygame.display.flip()
で画面をフリップします。
while running: pygame.display.update() # 画面を更新 screen.fill(pygame.Color(0, 0, 0)) # 画面を塗りつぶす screen.blit(image, (32, 32)) # 描画 pygame.display.flip() # 画面フリップ
フリップ(入れ替える)という処理は、ゲームでよくおこなわれます。
フリップの処理では、描画面Aと描画面Bを用意します。そして、ディスプレイに描画面Aを表示します。その裏では描画面Bの書き換えをおこないます。描画面Bのへの描画が完了したら、ディスプレイに描画面Bを表示します。
こうした入れ替えを毎フレームごとにおこないます(フレームとは、アニメーションの1コマのことです)。この方法では、描画途中の状態を見せないで済むので表示が乱れません。
フリップ
描画面A | 描画面B |
---|---|
ディスプレイに表示 | 書き換え処理 |
↓ | ↓ |
書き換え処理 | ディスプレイに表示 |
↓ | ↓ |
ディスプレイに表示 | 書き換え処理 |
もう1つ、clock.tick()
の処理も触れておきます。こちらは、描画処理の間隔を調整するためのものです。clock.tick(60)
のように引数を指定すると、60
FPS(Frame Per Second)よりも短い時間で再描画しないように、描画の間隔を制限します。
「1000/60=16.666...」なので、前の描画から16.66ミリ秒以上時間を空けて、次の描画をおこないます。この命令は60FPSを保証するものではなく、60FPSよりも速く描画しないようにするためのものです。この処理により、マシンの負荷が減ります。
clock.tick()
の戻り値は、前回の実行からの経過時間(ミリ秒)です。
clock = pygame.time.Clock() # 時計作成
while running: delta = clock.tick(60) # 60fps制限 print(delta)
clock.tick()
を利用して、描画がカクカクなるようなら、clock.tick()
の処理を取り除くときれいになることがあります。clock.tick()
の処理は必須ではありません。
pygame.time
にはClock
クラスだけでなく関数もあります。pygame.time.get_ticks()
関数は、pygame.init()
からの経過時間(ミリ秒)を得ます。
『Pygame』では、関数の引数の多くで、color
やrect
が要求されます。color
はpygame.Color
オブジェクト、あるいは(r, g, b)
のタプルやリストです。rect
はpygame.Rect
オブジェクト、あるいは(x, y, width, height)
のタプルやリストです。
『Pygame』では、必ずオブジェクトを書く必要はなく、タプルやリストで短く書くこともできます。
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)