HOWTO · Pygame

Pygame の surface.blit() 関数

Surface.blit() が Pygame サーフェス間でピクセルをコピーし、結果を配置し、コピー元の領域を選択する方法を学びます。

このページの内容

Surface.blit() は、コピー元の Surface からコピー先の Surface へピクセルをコピーします。Pygame のディスプレイでは、画面がコピー先のサーフェスです。画面外のサーフェスに描画して、その結果を画面に配置することもできます。以下の短い操作例では引数を説明し、最後のセクションではそれらを完全なウィンドウとイベントループの中に組み込みます。

これらの例は、ピクセルのコピーと配置に焦点を当てています。ブレンディングは示しません。セットアップの手順については、最小構成の Pygame ウィンドウの例を参照してください。ここでの例は、ウィンドウの作成ではなく、サーフェス間の描画に焦点を当てています。

Surface.blit() が一方のサーフェスをもう一方に描画する仕組み

ピクセルを受け取るサーフェスに対して blit() を呼び出します。第 1 引数はコピー元のサーフェスで、第 2 引数はコピー先の位置、つまりコピー元が描画される左上の隅を指定します。たとえば、destination.blit(source, (20, 30)) は、コピー先の x 座標 20、y 座標 30 の位置にコピー元を配置します。2 要素のタプルは、その位置を表す明確な方法です。

このメソッドは、省略可能なコピー元領域と特殊フラグの値も受け付けます。コピー元領域は、コピー元サーフェスの左上の隅から測った矩形で、コピーする部分を選択します。省略すると、コピー元サーフェス全体が使用されます。特殊フラグは、ブレンド操作などの Pygame の blit 操作を選択します。これらはコピー先の位置やコピー元領域の引数とは独立しており、ここでの例ではデフォルトのままにしています。

呼び出しの形は destination.blit(source, destination_position, source_area=None, special_flags=0) です。blit() メソッドは、コピー先で影響を受ける領域を表す矩形を返します。これは、ディスプレイの一部だけを更新する場合に役立ちます。コピー先の位置がコピー先サーフェスの外側にある場合、重なる部分だけが描画されることがあります。

コピー元領域を指定して Surface.blit() を使う

pygame.Surface((width, height)) でサーフェスを作成し、(200, 100, 100) のような RGB カラータプルで塗りつぶします。選択したコピー元領域をコピーするには、第 3 引数として (x, y, width, height) の形式の矩形を渡します。たとえば、(0, 0, 10, 5) は、コピー元の左上の隅から始まる 10 × 5 の矩形を選択します。コピーされたピクセルは、第 2 引数として渡したコピー先の位置から始まります。

画面外のサーフェスに描画した後は、イベントループの中でそのサーフェスをディスプレイに描画します。pygame.display.flip() を呼び出す前に、フレームごとにディスプレイをクリアするか再描画してください。そうしないと、前のフレームの内容が残って見えることがあります。図は、コピー元の領域を別のサーフェスにコピーするという考え方を示しています。

Pygame の Blit 関数

完全な Pygame の例を実行する

次のプログラムは、ウィンドウを作成し、2 つのサーフェスを塗りつぶし、一方から選択した領域をもう一方にコピーし、閉じる前に結果を 60 フレーム描画します。この例では音声を使用しないため、初期化するのはディスプレイサブシステムだけです。実行に使う Python 環境に Pygame をインストールしてください。閉じるまで開いたままになるウィンドウにするには、range(60) を while running に置き換えます。提供された実行では、Pygame の起動メッセージと、以下に示すコピー確認が出力されました。

import sys
import warnings

warnings.filterwarnings(
    "ignore",
    message="Your system is avx2 capable but pygame was not built with support for it.*",
    category=RuntimeWarning,
)

import pygame

pygame.display.init()
screen = pygame.display.set_mode((640, 480), pygame.RESIZABLE)
pygame.display.set_caption("Surface.blit() example")
clock = pygame.time.Clock()

destination = pygame.Surface((100, 100))
destination.fill((200, 100, 100))

source = pygame.Surface((30, 30))
source.fill((100, 200, 100))

# Copy a 10-by-5 region from source to destination at (10, 10).
destination.blit(source, (10, 10), (0, 0, 10, 5))
print("Copied a 10-by-5 source area to (10, 10).")

running = True
for _ in range(60):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if not running:
        break

    screen.fill((20, 20, 20))
    screen.blit(destination, (10, 10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()
pygame 2.6.1 (SDL 2.26.5, Python 3.14.7)
Hello from the pygame community. https://www.pygame.org/contribute.html
Copied a 10-by-5 source area to (10, 10).