7-2 スクリーン
同人誌について
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
説明と全体コード
「src/mymod/image/screen.py」の説明です。画面描画の基礎になる関数群です。
『Pygame』の例として紹介したプログラムでは、画面を作ったあと、スクリーンに直接描画をおこなっていました。この本で作るゲームでは、小さなバッファに描画をおこないます。そして、各フレームの最後に拡大してスクリーンに描画します。そうしたことをおこなうための関数群が、「screen.py」に入っています。
import pygame
from ..data.app import W, H, TITLE, IMAGE_ICON
buffer: pygame.Surface = pygame.Surface((W, H))
# ウィンドウの初期化
def init_win():
# 開始画面サイズの計算と画面の作成
d = pygame.display.get_desktop_sizes()[0]
scale = min(d[0] * 0.8 // W, d[1] * 0.8 // H) # 開始倍率
size = (W * scale, H * scale) # 開始画面サイズ
pygame.display.set_mode(size, pygame.RESIZABLE) # 画面作成
# ウィンドウの設定
pygame.display.set_caption(TITLE) # タイトルバー
icon = pygame.image.load(IMAGE_ICON)
pygame.display.set_icon(icon) # アイコン
# バッファ取得
def get_buffer() -> pygame.Surface:
return buffer
# 更新の前処理
def update_pre():
pygame.display.update() # 画面を更新
# 画面の消去
def clear():
buffer.fill(pygame.Color(0, 0, 0)) # 画面を塗りつぶす
# 更新の後処理
def update_post():
# 拡大率を計算して、バッファを拡大
win = pygame.display.get_window_size()
scale = min(win[0] / W, win[1] / H)
dst = (W * scale, H * scale)
scaled_buffer = pygame.transform.scale(buffer, dst)
# オフセット位置を計算して描画
offset = ((win[0] - dst[0]) / 2, (win[1] - dst[1]) / 2)
screen = pygame.display.get_surface()
screen.blit(scaled_buffer, offset)
pygame.display.flip() # 画面フリップ
インポート部分
インポート部分を示します。
import pygame
from ..data.app import W, H, TITLE, IMAGE_ICON
`data`パッケージから、横幅の`W`、高さの`H`、タイトルの`TITLE`、アイコン用画像のパスの`IMAGE_ICON`を読み込みます。
バッファの作成
このモジュールでは、ゲーム画面を作るために小さな`Surface`を作り、そこに描画をおこないます。そのために用いる`Surface`を作り、変数`buffer`に格納します。
buffer: pygame.Surface = pygame.Surface((W, H))
ウィンドウの初期化
次はウィンドウの初期化です。まずは画面作成の部分です。
# ウィンドウの初期化
def init_win():
# 開始画面サイズの計算と画面の作成
d = pygame.display.get_desktop_sizes()[0]
scale = min(d[0] * 0.8 // W, d[1] * 0.8 // H) # 開始倍率
size = (W * scale, H * scale) # 開始画面サイズ
pygame.display.set_mode(size, pygame.RESIZABLE) # 画面作成
`pygame.display.get_desktop_sizes()`関数でディスプレイのサイズを得ます。関数のあとに`[0]`を書いているのは、関数の戻り値のリストの0番目の要素(0番目のディスプレイ、主要なディスプレイ)を得ているためです。この値を変数`d`に代入します。
次に、ディスプレイの横幅`d[0]`の`0.8`倍を、ゲーム画面の横幅`W`で割って整数にします。また、ディスプレイの高さ`d[1]`の`0.8`倍を、ゲーム画面の高さ`H`で割って整数にします。そして`min()`関数を使い、2つの値の小さい方を得て、開始時の拡大率`scale`に代入します。
続いて、拡大率`scale`をもとに、開始画面サイズ`size`を計算します。そして`pygame.display.set_mode()`関数で画面を作成します。
画面作成では、`pygame.display.set_mode()`の第2引数に、`pygame.RESIZABLE`を設定します。第2引数には、いくつかの設定を`|`繋ぎで書けます。ここでは、リサイズ可能にする`pygame.RESIZABLE`のみを書きます。
リサイズ可能にしても、『Pygame』は描画サイズを自動で調整してくれません。そのため、自分で拡大描画する必要があります。
次は、ウィンドウの設定です。
# ウィンドウの設定
pygame.display.set_caption(TITLE) # タイトルバー
icon = pygame.image.load(IMAGE_ICON)
pygame.display.set_icon(icon) # アイコン
タイトルバーの文字を設定します。また、ウィンドウ左上用のアイコン画像(PNG画像)を読み込み、セットします。
バッファの取得、更新の前処理、画面の消
次は、バッファの取得、更新の前処理、画面の消去といった小さな処理の関数です。
処理自体はそれぞれ1行ですが、外部から抽象化して呼び出せるように関数化しています。
# バッファ取得
def get_buffer() -> pygame.Surface:
return buffer
# 更新の前処理
def update_pre():
pygame.display.update() # 画面を更新
# 画面の消去
def clear():
buffer.fill(pygame.Color(0, 0, 0)) # 画面を塗りつぶす
更新の後処理
最後は更新の後処理です。
# 更新の後処理
def update_post():
# 拡大率を計算して、バッファを拡大
win = pygame.display.get_window_size()
scale = min(win[0] / W, win[1] / H)
dst = (W * scale, H * scale)
scaled_buffer = pygame.transform.scale(buffer, dst)
# オフセット位置を計算して描画
offset = ((win[0] - dst[0]) / 2, (win[1] - dst[1]) / 2)
screen = pygame.display.get_surface()
screen.blit(scaled_buffer, offset)
pygame.display.flip() # 画面フリップ
ウィンドウのサイズから拡大率を計算して、サイズを拡大したバッファを作成します。そして、画面の中央に描画するようにオフセット位置を計算して、スクリーンへの描画をおこないます。
ウィンドウ サイズは`pygame.display.get_window_size()`関数で得ます。ウィンドウに内接する拡大率`scale`を計算して、拡大後のサイズ`dst`を求めます。このサイズ`dst`をもとに、バッファを拡大した`Surface`を、`pygame.transform.scale()`で得ます。
スクリーンの`Surface`は、`pygame.display.get_surface()`関数で得ます。『Pygame』のサンプルでは、`pygame.display.set_mode()`の戻り値でスクリーンを得ていましたが、こうした関数でも得られます。
次の内容については省略します。こちらは同人誌をご覧ください。
7-3 ユーティリティ
同人誌について
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
このnoteの記事と、Webページに一部抜粋版を掲載しています。
技術系同人誌など まとめページ
この記事が気に入ったらサポートをしてみませんか?