Pyxel 画面のエフェクト

画像メモリへのアクセス機能で画面のデータを加工する

 Pyxel のバージョン1.9.13で追加された,画像メモリへのアクセス機能を使うと画面全体を揺らすような効果をかけることができます。

 「背景のタイルマップ」+「イメージや図形」などが重なった状態でデータの参照や更新ができます。既存のpget()とpset()を使って同様のことができますが,GithubのIssuesによればよりオーバーヘッドが少ないインターフェイスとのことです。

<画面を揺らす例>
 

 

構文

ptr1 = pyxel.tilemap(0).data_ptr()
ptr2 = pyxel.screen.data_ptr()

data_ptr()で表示色のリストが取得できます(横方向に1列につながったデータ)。
tilemapで呼べばタイルマップの生データ,screenで呼べば画面の生データのようなので,今回はscreenを使います。


<画面データにアクセスするループの例>

screen_ptr = pyxel.screen.data_ptr()

for j in range(pyxel.height):
    for i in range(pyxel.width):
        screen_ptr[  j * pyxel.width +  i  ] = color

 ※color は表示色番号

  

画面を揺らすプログラム

 画面のデータ横一列分を,ずらしてコピーしてから,元の位置に上書きする例です。(こういった処理の典型的な書き方は未調査のため力技です)
 

import pyxel
pyxel.init(128, 128)
pyxel.load("platformer.pyxres")

screen_ptr = pyxel.screen.data_ptr()

def wave_screen(col):
    for j in range(pyxel.height):
        s = j * pyxel.width
        e = s + pyxel.width
        data = [col]*pyxel.width;
        gap = int(10 * pyxel.sin((pyxel.frame_count +j)*4))
        if gap < 0 :
            data[0:gap] = screen_ptr[s-gap:e]
        else :
            data[gap:] = screen_ptr[s:e-gap]

        screen_ptr[s:e] = data

    return

def update():

    return

def draw():
    pyxel.cls(0)
    pyxel.bltm(0,0, 0, 0,128, 128,128)
    pyxel.bltm(0,0, 0, 0,0,   128,128,2)
    pyxel.blt(30, 112, 0, 0, 16, 8, 8, 2)

    pyxel.text(10,10,"before effect",7)
    wave_screen(0)
    pyxel.text(10,20,"after effect",7)
    return

pyxel.run(update, draw)

実行結果

 

13_bitmap_font.py の例

 画面全体だけではなく,範囲指定でも処理ができます。詳しい使い方は,公式サンプルの 13_bitmap_font.py のソースを見てください。

抜粋

    def __init__(self, bdf_filename):
        self.fonts = self._parse_bdf(bdf_filename)
        self.screen_ptr = pyxel.screen.data_ptr()
        self.screen_width = pyxel.width

    def _draw_font(self, x, y, font, color):
        font_width, font_height, bitmap = font
        screen_ptr = self.screen_ptr
        screen_width = self.screen_width
        for j in range(font_height):
            for i in range(font_width):
                if (bitmap[j] >> i) & 1:
                    screen_ptr[(y + j) * screen_width + x + i] = color

・screen_ptr に pyxel.screen.data_ptr() でリストを取得

・screen_ptr[(y + j) * screen_width + x + i] = color
 画面幅分の位置を変えることで各行のデータにアクセスしています。
 i を1ずつ増やして1ドットごと色を置くか判定して color を書き込んでいます。




  

関連記事

kinutani.hateblo.jp