見出し画像

Pyxelでpyxresを経由せず画像ファイルを扱う


Pyxel?

PyxelはPython用の国産ゲームエンジンです。Pico8やTIC-80といったレトロ風のファンタジーコンソールに近い感覚でありながら、自由度が高いのが特徴です。

画像ファイルを読み込みたい

Pyxelで画像を扱う場合、多くは付属のエディタで作成したマルチメディアデータを.pyxres形式で保存し、loadメソッドで読み込んで使用します。

付属のペイントツール

標準で使えるスプライトシートは、256x256が3枚です。昔の環境をイメージして使いたい場合や、制約を楽しんで制作したい時は、とても良い仕様です。
しかしながら、Pyxelでゲームを作っていますと、時々「もっと自由に画像を使いたい」と思うことがあります。「では、UnityやGodotを使えば良いじゃないか」というご指摘もあるでしょう。ただPyxelは、必要最小限の仕様さえ頭に入れて仕舞えば、あとは自由にプログラムを組んでゲームを作れるという利点があります。このシンプルなエンジンを使って、もっと大きなゲームを作ってみたいという気持ちもあるわけです。

Imageクラス

Pyxel には「ユーザーを混乱させる可能性がある」「使うために専門の知識が必要」などの理由から、このリファレンスには記載していない「上級者向け API」があります。

Pyxel

PyxelのAPIを確認すると、Imageクラスが存在します。Pyxelは、このImageクラスをbltで描画できますから、画像ごとにImageクラスのインスタンスを作成する方式で画像リソースを管理すれば、より普通のゲームエンジンに近い感覚でリソースを扱えます。

 self.img = pyxel.Image(82, 64)
 self.img.load(x=0, y=0, filename="assets/images/sample.png")

 pyxel.blt(0, 0, self.img, 0, 0, self.img.width, self.img.height)

外部画像を扱うオブジェクトの基底クラス

外部画像を効率的に扱うため、オブジェクトの基底クラスを作成しました。

import pyxel

class ImageObject:
    class Pos:
        def __init__(self, x: float, y: float) -> None:
            self.x = x
            self.y = y

    def __init__(self, path: str, x: float=0, y: float=0, colkey=-1) -> None:
        """
        ImageObjectのコンストラクタ

        Parameters:
        path (str): 画像ファイルのパス
        x (float): オブジェクトの初期X座標
        y (float): オブジェクトの初期Y座標
        colkey (int): 透過色のパレット番号(デフォルトは-1)
        """
        self.set_pos(x, y)
        self.set_image(path)
        self.set_colkey(colkey)

    def get_pos(self) -> Pos:
        return self.Pos(self.x, self.y)

    def set_pos(self, x: float=None, y: float=None) -> None:
        """
        オブジェクトの座標を設定する

        Parameters:
        x (float): X座標
        y (float): Y座標
        """
        self.x = self.x if x is None else x
        self.y = self.y if y is None else y

    def set_colkey(self, colkey: int):
        '''
        画像の透過色を指定する

        colkey (int): 透過色のパレット番号
        '''
        self.colkey = colkey if colkey > -1 else None

    def move(self, dx: float=0, dy: float=0) -> None:
        '''
        オブジェクトの座標を移動する

        Parameters:
        dx (float): X座標の変位
        dy (float): Y座標の変位
        '''
        self.x += dx
        self.y += dy

    def set_image(self, path: str) -> None:
        """
        画像を設定する

        Parameters:
        path (str): 画像ファイルのパス
        """
        self.img: pyxel.Image = pyxel.Image.from_image(filename=f"assets/images/{path}")
        self.width = self.img.width
        self.height = self.img.height

    def update(self) -> None:
        """
        オブジェクトの更新処理(必要に応じてオーバーライド)
        """
        pass

    def draw(self) -> None:
        """
        オブジェクトを描画する

        Parameters:
        colkey (float): 透明色キー(デフォルトはなし)
        """
        pyxel.blt(self.x, self.y, self.img, 0, 0, self.width, self.height, colkey=self.colkey)


# Pyxelの初期化
pyxel.init(160, 120, caption="ImageObject Example")

# ImageObjectのインスタンスを作成
# 外部画像ファイルのパスを適切に指定してください
image_object = ImageObject("path_to_image.png", 50, 50)

def update():
    """
    ゲームの更新処理
    """
    image_object.update()

def draw():
    """
    ゲームの描画処理
    """
    pyxel.cls(0)  # 画面をクリア
    image_object.draw()  # ImageObjectを描画

# Pyxelアプリケーションの開始
pyxel.run(update, draw)
  • pyxel.Image.from_imageの使用:

    • pyxelの裏仕様を利用して、外部画像ファイルをロードしています。この機能が今後のpyxelのバージョンでサポートされなくなる可能性がある点に注意が必要です。

  • 座標設定と画像設定メソッドの追加:

    • set_posメソッドで座標を設定し、set_imageメソッドで画像を設定しています。これにより、クラスの再利用性が向上します。

  • 更新と描画メソッドの分離:

    • updateメソッドをオーバーライド可能な形で定義し、必要に応じてオブジェクトの状態を更新できます。

    • drawメソッドはpyxel.bltを使用して画像を描画します。

  • 透明色キーの扱い:

    • colkeyパラメータを追加し、透明色キーを設定できるようにしました。デフォルトはなし(None)です。

参考


この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?