見出し画像

4-1 Pygameの基本的な処理

同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで288ページの本になります。ぜひ、こちらもご購入ください(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`は注意が必要です。モニターの解像度を、描画サイズと同じに変更します。そのため、ウィンドウやアイコンのレイアウトが崩れます。少し使いにくい機能です。

 ウィンドウの準備をしたあとは、`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コマのことです)。この方法では、描画途中の状態を見せないで済むので表示が乱れません。

フリップ


時計

 もう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で288ページの本になります。ぜひ、こちらもご購入ください(2024-03-10:ver1.0.3 に更新)。

 このnoteの記事と、Webページに一部抜粋版を掲載しています。

 技術系同人誌など まとめページ


いいなと思ったら応援しよう!