SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

レトロ風ゲームを作って学ぶPython入門

【作って学ぶPython】プログラムを書いて、モジュールやパッケージで整理しよう!

レトロ風ゲームを作って学ぶPython入門 第3回


  • X ポスト
  • このエントリーをはてなブックマークに追加

画像描画

 すでに画像の読み込みと描画は基本コードであつかっています。ここでは、画像の切り抜きと拡大をあつかいます。

 まずは、画像  を使って、プログラムを実行した時のスクリーンショットです。画像の一部を拡大して表示します。

スクリーンショット
スクリーンショット

 次にプログラムの例を示します。2Dゲームではよくある、タイル状の画像から一部を取り出す処理と、画像を拡大する処理です。

main.py
import pygame   # Pygameをインポート

pygame.init()   # Pygameを初期化
screen = pygame.display.set_mode((800, 600))    # 画面作成
running = True  # 実行継続フラグ

# 画像分割読み込み
def load(p, x, y, size):
    image = pygame.image.load(p)    # 画像読み込み

    u = 16  # 画像部品のピクセル単位
    sliced = pygame.Surface((u, u), pygame.SRCALPHA)    # Surface生成
    sliced.blit(image, (0, 0), (x * u, y * u, u, u))    # 一部を貼り付け

    scaled = pygame.transform.scale(sliced, (size, size))   # 拡大
    return scaled

image1 = load("chara.png", 0, 0, 256)   # 画像分割読み込み
image2 = load("chara.png", 1, 4, 384)   # 画像分割読み込み

while running:
    for event in pygame.event.get():    # イベント
        if event.type == pygame.QUIT:   # 種類がQUITなら
            running = False   # 終了

    screen.fill((0, 0, 0))  # 画面を塗りつぶす
    screen.blit(image1, (32, 32))   # 描画
    screen.blit(image2, (320, 64))  # 描画
    pygame.display.flip()   # 画面フリップ
pygame.quit()   # Pygameを終了

 画像の読み込みと、切り抜いて拡大する処理はload()関数にまとめています。load()関数の中では、次のようなことをおこなっています。

  1. 画像をSurfaceとして読み込む
  2. pygame.Surface()Surfaceを生成する
  3. 2のSurfaceに、1のSurfaceの一部をblit()関数で貼り付ける
  4. 2のSurfacepygame.transform.scale()で拡大する
  5. 拡大したSurfaceを戻り値として返す

 Pygameのいくつかの関数を使っているので、それぞれの処理の引数をまとめます。=で値が設定されているものは、初期値のある引数です。これらの引数は必須ではありません。リストとタプルは互換です。どちらで書いても構いません。

指定サイズのSurfaceオブジェクトを生成
pygame.Surface(
    size,       # 横幅と高さのタプル
    flags=0     # pygame.SRCALPHAなど
    ) -> Surface    # 戻り値:Surfaceオブジェクト
SurfaceオブジェクトにSurfaceオブジェクトを描画
描画先のSurfaceオブジェクト.blit(
    surface,    # 描画元のSurfaceオブジェクト
    dest,       # 描画先のX位置、Y位置のタプル
    area=None   # 描画元のX位置、Y位置、横幅、高さのタプル
    )
指定サイズに拡大縮小したSurfaceオブジェクトを得る
pygame.transform.scale(
    surface,    # Surfaceオブジェクト
    size        # 横幅と高さのタプル
    ) -> Surface    # 戻り値:Surfaceオブジェクト

 Pygameで画像を使ったゲームを作るなら、最低限これらの処理がおこなえれば問題ありません。

 定義したload()関数は、画像ファイルのパス、切り抜くX位置とY位置、拡大するサイズを引数にとります。こちらも引数をまとめておきます。

画像ファイルからSurfaceオブジェクトを得る
load(
    path,   # 画像ファイルのパス
    x,      # X方向に何番目のタイルかの整数
    y,      # Y方向に何番目のタイルかの整数
    size    # 拡大縮小する横幅と高さのタプル
    ) -> Surface    # Surfaceオブジェクト

図形描画

 Pygameは、pygame.drawの下に、いくつかの図形を描く関数を持っています。関数には、次のようなものがあります。各関数の引数の内容については、プログラムの例を示したあと掲載します。

 > 四角形、ポリゴン、円、楕円、円弧、線、複数線

 この中から、今回のゲーム開発で使う四角形の描画を取り上げます。実行したスクリーンショットと、プログラムの例です。

スクリーンショット
スクリーンショット
main.py
import pygame   # Pygame

pygame.init()   # Pygameを初期化
screen = pygame.display.set_mode((800, 600))    # 画面作成
running = True  # 実行継続フラグ

# 図形の描画
def draw():
    col = (0, 255, 0)               # 色
    rect1 = ( 75, 50, 300, 500)     # 四角形1
    rect2 = (450, 50, 300, 500)     # 四角形2
    pygame.draw.rect(screen, col, rect1)    # 塗りつぶし
    pygame.draw.rect(screen, col, rect2, width = 5)     # 線描画

while running:
    for event in pygame.event.get():    # イベント
        if event.type == pygame.QUIT:   # 種類がQUITなら
            running = False   # 終了

    screen.fill((0, 0, 0))  # 画面を塗りつぶす
    draw()  # 図形の描画
    pygame.display.flip()   # 画面フリップ
pygame.quit()   # Pygameを終了

 図形の描画はdraw()関数にまとめています。

 draw()関数の中身を説明します。色を表す変数colは、RGBの値を持つタプルです。四角形を表す変数rect1rect2は、X位置、Y位置、横幅、高さの値を持つタプルです。

 最後は四角形の描画です。pygame.draw.rect()関数で四角形を2つ描いています。1つ目は塗りつぶしで、2つ目は線描画です。

 Pygameの図形描画の多くは、引数にwidthを指定しなければ塗りつぶし、widthを0より大きな数値で指定すると、その太さで線描画をおこないます。

pygameの図形描画の関数

 pygameの図形描画の関数は、四角形以外にも多くあります。そうした関数の引数の情報をまとめておきます。

 以降の関数で、=で値が設定されているものは、初期値のある引数です。これらの引数は必須ではありません。リストとタプルは互換です。どちらで書いても構いません。

 rectとある場所は、X位置、Y位置、横幅、高さのタプルか、pygame.Rectオブジェクトです(例:(20, 10, 200, 150)pygame.Rect(20, 10, 200, 150))。

 colorとある場所は、R、G、Bのタプルか、pygame.Colorオブジェクトです(例:(255, 255, 255)pygame.Color(255, 255, 255))。

四角形の描画
pygame.draw.rect(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    rect,       # 四角形
    width=0,    # 線の太さ
    border_radius=0,    # 角丸の指定
    border_top_left_radius=-1,      # 角丸 上左
    border_top_right_radius=-1,     # 角丸 上右
    border_bottom_left_radius=-1,   # 角丸 下左
    border_bottom_right_radius=-1   # 角丸 下右
    )
ポリゴンの描画
pygame.draw.polygon(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    points,     # 座標(x, y)のリスト、例: [(50, 50), (50, 70), (70, 50)]
    width=0     # 線の太さ
    )
真円の描画
pygame.draw.circle(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    center,     # 中心位置、例: (50, 70)
    radius,     # 半径
    width=0,    # 線の太さ
    draw_top_right=None,    # 四分割した円の上右側を描くか、真偽値
    draw_top_left=None,     # 四分割した円の上左側を描くか、真偽値
    draw_bottom_left=None,  # 四分割した円の下左側を描くか、真偽値
    draw_bottom_right=None  # 四分割した円の下右側を描くか、真偽値
    )
楕円の描画
pygame.draw.ellipse(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    rect,       # 四角形(この範囲に内接する楕円)
    width=0     # 線の太さ
    )

 次に示す円弧の描画では、角度はラジアンで指定します。ラジアンでは、pi * 2(パイの2倍)が1周になります。pifrom math import piでインポートできます。

円弧の描画
pygame.draw.arc(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    rect,       # 四角形(この範囲に内接する楕円)
    start_angle,    # 開始角度、ラジアン
    stop_angle,     # 終了角度、ラジアン
    width=1         # 線の太さ
    )
線の描画(アンチエイリアスなし)
pygame.draw.line(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    start_pos,  # 開始位置、例: (50, 70)
    end_pos,    # 終了位置、例: (70, 50)
    width=1     # 線の太さ
    )
線の描画(アンチエイリアスあり)
pygame.draw.aaline(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    start_pos,  # 開始位置、例: (50, 70)
    end_pos,    # 終了位置、例: (70, 50)
    blend=1     # 非推奨、ブレンドの有無
    )
複数線の描画(アンチエイリアスなし)
pygame.draw.lines(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    closed,     # 線を閉じるかの真偽値
    points,     # 座標のリスト、例: [(50, 50), (50, 70), (70, 50)]
    width=1     # 線の太さ
    )
複数線の描画(アンチエイリアスあり)
pygame.draw.aalines(
    surface,    # 描画対象のSurfaceオブジェクト
    color,      # 色
    closed,     # 線を閉じるかの真偽値
    points,     # 座標のリスト、例: [(50, 50), (50, 70), (70, 50)]
    blend=1     # 線の太さ
    )

次のページ
文字描画

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
レトロ風ゲームを作って学ぶPython入門連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/19457 2024/06/10 12:26

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング