Python 用復古遊戲引擎 Pyxel 的新版本 3.0 已經發布了。從 2018 年公開至今已過 8 年,距離 2.0 發布也約莫 3 年。終於迎來了重大版本升級。
不知不覺間,GitHub 星號數 也已經超過 1.8 萬了。這也是多虧了大家的支持。真的非常感謝。
Pyxel 3.0 的亮點是,新增了復古 3D 遊戲引擎功能「Pyxel Cube」。這次就來介紹 Pyxel Cube 的特色與使用方式。

另外,如果你是因為這篇文章才第一次認識 Pyxel,也請一併參考先前的介紹文章。
Pyxel Cube 是 Pyxel 3.0 新增的子模組,用來輕鬆製作復古 3D 遊戲。只要在 Python 中匯入 pyxel.cube 即可使用。
Pyxel Cube 的主要功能如下:
最大的重點是,它可以在保有傳統 2D 版 Pyxel 程式碼的同時,加入 3D 功能。
即使是一直對 3D 程式設計感到卻步的人,也希望能透過 Pyxel Cube,逐步熟悉 3D 功能。
直到現在,Pyxel 一直聚焦於我認為屬於 「復古」 的、以 2D 為主的遊戲主機,也就是大致到超級任天堂那個年代。
雖然也曾多次考慮支援 3D,但因為會增加製作成本,可能會失去 Pyxel「輕鬆上手、隨手創作」的優點,所以一直沒有採用。
然而,距離 PlayStation 2 發售已經過了 26 年。當年的低多邊形 3D,如今也被稱作 「復古 3D」 了。

取自 PyCon JP 2026 主題演講
因此,為了紀念 Pyxel 3.0,我決定重新挑戰實現復古 3D 功能。
若是完整功能的 3D 引擎,已經有 Unity 和 Unreal Engine;但在 Pyxel 中,我們選擇將功能聚焦在 「那個時代的 3D」,以能像 2D 一樣輕鬆製作的形式來呈現。
這是使用 Pyxel Cube 製作的遊戲實際執行畫面。點擊圖片即可直接在瀏覽器中遊玩。

雖然是 3D,但依然是固定的 16 色(使用者可擴充)。也不能使用半透明,還需要像過去那樣透過抖動(棋盤格)等技巧來表現,是一個非常受限的 3D(笑)。
接下來說明 Pyxel Cube 的基本概念與使用方式。
在 Pyxel Cube 中,會以稱為 節點 的單位來組合要放置在 3D 空間中的物件。透過以父子關係連接節點,子節點會跟隨父節點的位置一起移動。這就是 節點樹。

Pyxel Cube 的基本開發流程如下:
pyxel.cube要定義節點,只要繼承 Node 類別,並撰寫更新處理與繪圖處理即可。例如,若要定義一個旋轉的方塊節點,可以這樣寫:
import pyxel
from pyxel.cube import Mat4, Node, Vec3
class Box(Node):
def on_update(self):
# 讓方塊旋轉
self.transform = Mat4.from_euler(Vec3(0, pyxel.frame_count, 0))
def on_draw(self):
# 繪製方塊
self.box(Mat4.IDENTITY, Vec3(16, 16, 16), 11)
更詳細的使用說明,請參考官方的 Pyxel Cube 指南 以及 使用方式影片。
以下介紹 Pyxel Cube 的主要功能。點擊各圖片即可在瀏覽器中試玩範例。
方塊、球體等都可以像 2D 版 Pyxel 一樣,只要呼叫簡單的繪圖指令就能顯示。
將繪製線段的指令拿來比較 2D 與 3D,會像下面這樣:
pyxel.line(0, 0, 30, 20, 8) # 2D
self.line(Vec3(0, 0, 0), Vec3(30, 20, 0), 8) # 3D(節點內)
此外,也可以指定頂點來建立自訂形狀。附帶的範例中,透過變形頂點來繪製雷射與不定形史萊姆。

可以讀取將外型與零件動作整合在一起的檔案,進行模型繪製與動作播放。
這個範例會依照按下的按鍵,切換瞪羚的動作。

Pyxel Cube 內建獨立的物理引擎,可以進行沿著牆面移動角色、或多個物體運動的模擬等處理。
以下範例中,讓球體撞向堆疊起來的物體,並透過物理演算重現其崩塌的樣子。

Pyxel Cube 各項功能的範例,可以從這個頁面查看,也可以直接在瀏覽器中執行。
建議大家先看看這些內容,應該就能大致掌握整體氛圍。
Pyxel Cube 中,3D 模型與動作資料使用 GLB 格式。
GLB 格式資料可以用各種 3D 製作工具建立,不過在 Pyxel 中,我們推薦使用 Blockbench。
使用 Blockbench 實際製作資料的方法,可以在 Pyxel Cube 指南或這段說明影片中確認。
建立好的 GLB 檔案,可以像下面這樣在 Python 程式中讀取,並加入節點樹:
from pyxel.cube import Mesh, Node
scene = Node()
model = Node.from_mesh(Mesh.from_glb("assets/character.glb"))
scene.add_child(model)
Pyxel 3.0 的新功能 Pyxel Cube,大家覺得如何呢?這是不同於過去 Pyxel 的、全新的 3D 挑戰。希望大家也能一起享受這份樂趣。
最後還是一樣,Pyxel 目前仍以 GitHub 星號數作為小小的鼓勵,持續免費開發中。
如果你覺得 Pyxel Cube 不錯,也歡迎到 GitHub 點星支持我們!
另外再補充一個小資訊。只有 3KB 可用,但能只靠 URL 分享遊戲的遊戲引擎「Playload」,前陣子也已經公開。如果有興趣,也請看看Playload 的介紹文章。