見出し画像

pyxelのbltm3d(3D描画)を試してみる

かなーり間が空いてしまいましたが、またぼちぼちpyxelを触り始めたのでnoteも再開しようと思います。

今回は最近のアップデートで追加された3D描画(bltm3d)についてです。これは従来のタイルマップ描画命令であるbltmに対する3d版となります。
(イメージ描画のbltに対応するblt3dもあります。)

※気づいていなかったのですがpyxel公式のAPIリファレンスが分かりやすくなっていました。各命令の詳細は以下からご参照ください。

Pyxel API リファレンス
https://kitao.github.io/pyxel/web/api-reference/

早速今回作ったものを。下の画像のような3dマップと移動の仕組みです。

▲マップをbltm3dで、背景をbltで描画しています。

コードは以下の通りです。

import pyxel

pyxel.init(210, 250)
pyxel.load("assets.pyxres")

class App:
    def __init__(self):
        self.angle = 0
        self.pos_x = 800   # 初期座標X
        self.pos_y = 1000  # 初期座標Y
        pyxel.run(self.update, self.draw)

    def update(self):    
        if (pyxel.btn(pyxel.KEY_P) or pyxel.btn(pyxel.GAMEPAD1_BUTTON_A) or
           pyxel.btn(pyxel.GAMEPAD1_BUTTON_B)): # カメラを水平に回転させる(右回り)
            self.angle = (self.angle + 3) % 360  
        if (pyxel.btn(pyxel.KEY_O) or pyxel.btn(pyxel.GAMEPAD1_BUTTON_X) or 
            pyxel.btn(pyxel.GAMEPAD1_BUTTON_Y)): # カメラを水平に回転させる(左回り)
            self.angle = (self.angle - 3) % 360  
        if pyxel.btn(pyxel.KEY_W) or pyxel.btnp(pyxel.GAMEPAD1_BUTTON_DPAD_UP): # 前進
            self.pos_x += pyxel.sin(self.angle) * 2
            self.pos_y -= pyxel.cos(self.angle) * 2
        if pyxel.btn(pyxel.KEY_S) or pyxel.btnp(pyxel.GAMEPAD1_BUTTON_DPAD_DOWN): # 後退
            self.pos_x -= pyxel.sin(self.angle) * 2
            self.pos_y += pyxel.cos(self.angle) * 2        
        if pyxel.btn(pyxel.KEY_D) or pyxel.btnp(pyxel.GAMEPAD1_BUTTON_DPAD_RIGHT) : # 右平行移動
            self.pos_x += pyxel.cos(self.angle) * 2
            self.pos_y += pyxel.sin(self.angle) * 2
        if pyxel.btn(pyxel.KEY_A)  or pyxel.btnp(pyxel.GAMEPAD1_BUTTON_DPAD_LEFT): # 左平行移動
            self.pos_x -= pyxel.cos(self.angle) * 2
            self.pos_y -= pyxel.sin(self.angle) * 2          

        # 移動後にclampで範囲制限(マップ端が見えないように)
        self.pos_x = pyxel.clamp(self.pos_x, 180, 1840)
        self.pos_y = pyxel.clamp(self.pos_y, 470, 2100)                            

    def draw(self):
        pyxel.cls(0)
        
        # 背景をbltで描画
        bg_offset = int(self.angle / 360 *210) % 210
        pyxel.blt(0, -30, 1, bg_offset, 0, 210, 150)
        pyxel.blt(210 - bg_offset, -30, 1, 0, 0, 210, 150)

        # 床とbltm3dで描画
        pyxel.bltm3d(
            0, 0,        # 描画起点座標
            210, 250,    # 描画範囲(画面全体に描画)
            0,                 # タイルマップ番号
            (self.pos_x, self.pos_y, 10),      # カメラ位置:プレイヤー座標で高さ10
            (80, self.angle, 0),    # ちょっと見下ろし気味で水平方向に回転
            fov=60,            
        )

App()

バーチャルゲームパッドは検証していないのですが、キーボード操作なら問題なく動くと思います。
肝心のbltm3dは…いろいろ試して見た目はまぁまぁになったのですが、いまいち理解できていません…。それぞれのオプションの数値をいじって、挙動がどう変わるか実験してみるのがよさそうです。

素材ファイルも置いておきますので、良ければ使ってください。

今回はここまで。
読んでいただきありがとうございました。

いいなと思ったら応援しよう!

こいでみず ここまで読んでいただきありがとうございます!