poku-pixel-fx 是做什麼的?
POKU Pixel FX 是一個韓文在地化的 TypeScript 開源分支/衍生專案,源自 PixelFX by Patch,以獨立儲存庫維護,未與 GitHub 網路分叉連結。上游 MIT 授權條款歸功於 Patch 與 Hugo Duprez;請在 LICENSE 與 NOTICE.md 中保留版權與歸屬聲明。
需要 Node.js 18 或更新版本;ffmpeg 為 GIF 與 MP4 預覽的選用項目。
像素藝術特效即程式碼。每個特效是一個檔案:src/fx/<category>/<name>.ts,會繪製到兩個緩衝區中:
色彩(像素:不透明、抖動或真正半透明)與光線(疊加發光)。不需圖像,因此特效可以即時播放、重新著色、鏡像、重新播種,並為任何引擎產出精靈表。
其方法來自 Hugo Duprez 的(如何使用 Claude 製作(好的)像素藝術特效):程式碼是黏土,相信你的眼睛,餵養你的參考素材。一次性的提示只能產出平庸的特效。你反覆渲染、檢視並精煉的草稿才能產出好的特效。
事前準備
- 請在包含
package.json與tools/render.mts的 Poku Pixel FX 檢出目錄中工作。若無此目錄,請在使用者選擇的專案或工作區中取得公開函式庫:git clone https://github.com/Stankjedi/poku-pixel-fx.git。技能檔案本身不包含特效函式庫。切勿使用他人的機器特定路徑。必要時使用npm ci安裝檢出目錄的依賴項;若已安裝則不要重複執行。 - 在使用工具或畫廊前,請執行
npm run build;編譯器會將執行時期模組輸出至build/,CLI 工具輸出至build-tools/。 - 驗證其運作:
node build-tools/tools/render.mjs fire/torch會寫入records/fire/torch/contact.png。用你的圖像閱讀工具開啟該 PNG 檔案。從現在起,這個聯絡表就是你檢視每個特效的方式。
1. 先尋找現有特效
node build-tools/tools/list.mjs <words> 會搜尋 ID、名稱、標籤與描述(例如 node build-tools/tools/list.mjs frost、node build-tools/tools/list.mjs slash loop)。docs/CATALOG.md 按類別列出所有特效。渲染候選特效並在選擇前先檢視它們。大多數的請求其實是帶有不同選項的現有特效:
palette:主要的色階,從暗到亮,以十六進位字串表示。可使用src/core/color.ts中的任何PAL色階(如 fire ember lava smoke dust ice water electric volt poison holy heal arcane shadow blood earth stone gold leaf wood metal bone neon cyber matrix candy night),或使用你自己的色階。藍色的火焰範例:{"palette": PAL.ice}。seed用於產生不同但效果相當的版本;flip用於朝左;angle用於旋轉;light(0..1+)用於調整發光強度;此外還有每個特效在其meta.options中自有的控制項(如大小、數量、半徑、文字、高度等)。- 嘗試不編輯程式碼就調整選項:
node build-tools/tools/render.mjs fire/torch --opts '{"palette":["#102","#215","#43a","#8cf","#fff"]}'。
2. 將特效放入遊戲中
使用 JS 或 TS 的 Canvas 或 WebGL 遊戲(純 canvas、Phaser、PixiJS、Kaplay、three.js):可直接使用程式碼。它沒有依賴項;請複製 src/core 與你需要的特效檔案,或依賴該儲存庫。
import { createFrame, clearFrame, createFx, composite } from "poku-pixel-fx"; // src/core/index.ts
import * as frostNova from "poku-pixel-fx/fx/ice/frost-nova"; // src/fx/ice/frost-nova.ts
const frame = createFrame(320, 180); // 遊戲的像素解析度;ox, oy 可隨攝影機滾動
const img = new ImageData(320, 180);
const fx = createFx(frostNova, { x: hero.x, y: hero.y, flip: hero.facing < 0 });
// 每個更新週期
fx.update(dt);
clearFrame(frame);
fx.draw(frame, "back"); // 在角色後方的內容
drawCharacters(); // 你自己的精靈,或自行將它們繪製到 frame.color 中
fx.draw(frame, "front");
composite(frame, img.data, background); // 將色彩疊加在背景之上,再加上光線;或傳入 null 表示透明
ctx.putImageData(img, 0, 0); // 然後使用 image-rendering: pixelated 將 canvas 放大
if (fx.done()) removeIt(); // 一次性特效會自行結束;fx.stop() 會將循環效果淡出
多個特效可以共享同一個 frame。在 WebGL 引擎中,可以每幀將合成的 RGBA 上傳到紋理,或一次將特效渲染到精靈表(如下所述)並像其他動畫一樣播放。
任何引擎(Godot、Unity、GameMaker、Defold、LÖVE、Bevy、Construct):匯出精靈表。node build-tools/tools/render.mjs ice/frost-nova --sheet 會寫入 records/ice/frost-nova/frost-nova.png(透明幀以網格排列)與 frost-nova.json(Aseprite 風格的幀資料,因此 Phaser 的圖集載入器、Godot 與 Unity 的 Aseprite 匯入器以及大多數工具都能讀取;meta.pokuFx 包含 fps、循環方式、幀大小、欄數與軸心)。將軸心設為 meta.pokuFx.pivot(特效的原點,例如腳部),使用最近鄰插值濾波且不壓縮匯入,並以 meta.pokuFx.fps 播放。發光效果已烘焙到精靈表中,成為帶有 alpha 的色彩,在暗色場景上會呈現疊加效果;對於亮色場景,請渲染一個重新著色的版本,或將特效保留在暗色圖層上。
若要匯出完整函式庫:node build-tools/tools/render.mjs <category> --sheet 會處理整個類別。
一個打擊需要背後的身體。 特效單獨看起來像貼紙。帶有角色的特效會攜帶一個 act:描述身體如何蓄力、何時定格、目標如何反應。無論遊戲如何建構,皆可使用此機制:
- 使用內建角色:以
createAct(slash, { x, y })取代createFx。透過act.update(dt)、act.draw(frame),並透過act.shake觸發畫面震動。在定格期間,角色會自行保持靜止。node build-tools/tools/act.mjs <id> --sheet可將整套動作烘焙成精靈表。 - 使用遊戲自有的角色:讀取 timing、
slash.act或精靈表 JSON 中的meta.pokuFx.act(包含windup、recovery、以及帶有t與freeze的hits)。在特效之前windup秒播放角色的攻擊動畫,並在每次命中時停止更新所有內容(特效與角色皆停),持續freeze秒。主機端的打擊定格機制適用於任何特效,無論是否帶有 act。
src/fx/moves/ 包含了從特效串聯而成的完整攻擊,從蓄力到回復:當有人要求一個招式而非單一特效時,請從此處開始。
3. 製作一個新的特效
請先閱讀 docs/AUTHORING.md:這是合約(meta、純特效的 draw(p, t, o) 或模擬特效的 create(o)、本地座標、無縫循環、結束時清空)、工具組、繪圖 API 與品質標準。也請閱讀 docs/QUALITY.md。將 shadow/spatial-severance 視為乾淨曲線與精煉粒子的參考,而非強加於所有特效的風格。新特效應在適當處使用共享的絲帶、軌跡尾跡、包絡線與路徑光照輔助工具。保持像素調色盤,並檢查原生大小的剪影、打擊時機、負空間與透明度。自動化測試無法保證藝術品質。
對於帶有打擊效果的特效,也請閱讀 docs/IMPACT_INTERACTIONS.md:撰寫一個接觸描述符(時間、本地點、法線、材質),並從中推導出形狀特定的反應與選用的場景回饋。檢視地面/目標反應、二次碰撞與穩定過程。不要對每個材質都加入相同的震盪環、石頭碎片或畫面震動。保留減少動畫與固定軸心透明匯出的選項。
然後:
- 用一句話說明,包含美術方向:它是什麼、如何移動、調色盤為何、時機如何。例如:「一個冰霜新星:晶體從腳部向外呈環狀噴發,中心有白色閃光,碎片旋轉飛出,地面結霜並逐漸消退。」
- 在函式庫中尋找參考:
node build-tools/tools/list.mjs <words>,然後閱讀兩三個最接近的特效檔案,借用它們的技巧(src/core/sim.ts中的Particles與Bits用於火花、煙霧與碎片、p.disc用於半透明體積、cycle用於無縫粒子、tileFbm捲動用於火焰與水)。以本地函式庫的參考作為品質標準;外部參考為選用,需要網路連線。 - 草稿。
node build-tools/tools/new.mjs <category>/<name>(若為循環效果則加上--loop)會產生一個可運作的檔案。當方向尚未確定時,請撰寫 3 到 5 個真正不同的草稿(<name>-a.ts到-e.ts),全部渲染(node build-tools/tools/render.mjs "<category>/<name>-*"),並在選擇前檢視每個聯絡表。如果使用者在場,向他們展示最強的兩三個(--gif可製作出可分享的動畫)。在渲染前,若曾修改原始檔案則需重新建置。 - 檢視、判斷、修正。渲染後開啟
records/<id>/contact.png,像個挑剔的像素藝術家一樣判斷。修正最糟的部分,再次渲染。至少三輪;一件代表作需要更多輪。--all顯示每一幀,--mp4以全速顯示動態。 - 若涉及角色,請編寫 act:加入
export const act(請見docs/AUTHORING.md中的「Acts」),包含 t = 0 之前的蓄力、釋放幀上的姿勢變化、接觸時的定格以及回復。node build-tools/tools/act.mjs <id>會顯示連續的 12 fps 步驟:根據這些步驟以及--mp4判斷動作,而不是根據聯絡表的取樣。 - 檢查。
node build-tools/tools/check.mjs <id>會偵測繪製超出畫布、一次性特效未在結束時清空、循環接縫、未設定種子的隨機性以及慢速幀;若是 act,則會偵測關鍵幀順序錯誤、未知的姿勢欄位以及手部瞬間移動。修正直到測試通過。刪除你未保留的草稿。
應觀察的重點與常見修正方式:
| 你看到的問題 | 修正方式 |
|---|---|
| 在 1 倍大小下看起來模糊不清 | 減少顏色數量、清晰的剪影、一個焦點、更大的形狀 |
| 斑點:形狀內出現孤立的噪點像素 | 減少噪點閾值、使用 at() 進行量化、小形狀上不要有噪點 |
| 漂浮感、沒有衝擊力 | 快進慢出(ease.outQuart/outExpo)、1 到 2 幀的白色英雄幀、縮短總時間 |
| 生硬或機械感 | 變化每個粒子(大小、速度、延遲、生命期)、加入次要動作(火花、煙霧、碎片) |
| 顏色褪色 | 減少發光(k 0.2 到 0.5)、更暗的邊緣階梯、白色僅保留在最亮的核心 |
| 缺乏立體感 | 光線來自一側:左上角更亮、右下角階梯更暗;在基底部使用更暗的色階 |
| 平滑漸層、向量感 | 色彩中使用硬色階;柔和感僅用於光線與半透明煙霧 |
| 應該是煙霧的地方出現棋盤格 | 使用 SMOKE、VAPOUR 或 DUST 粒子,或 p.disc:真正的半透明,頂部打光 |
| 循環效果出現接縫 | 使用 cycle、loopNoise(phase)、全單元 tileNoise 捲動、sin(phase * TAU * n) |
| 一次性特效突然消失 | 讓它縮小、透過抖動淡出或在 t = duration 前逐漸消散 |
| 很棒的特效但角色像死了一樣 | 為它加上 act:蓄力、釋放姿勢、接觸定格、目標反應、回復 |
| act 感覺沒有重量感 | 往攻擊相反方向蓄力、更長的定格(最多 0.2 秒)、更大的剪影變化、畫面震動 |
| 打擊時機不同步 | 將打擊關鍵幀對齊特效本身的常數,而不是你目測的時間 |
| 他握武器的姿勢不對 | 保持手肘彎曲、武器柄在胸前;揮舞時劍刃落後於手;手臂約延伸 15 像素且不拉伸,因此身體需位移 |
| 他的手臂交叉或姿勢看起來很平面 | 他面向我們的四分之三側:張開手臂時近手向左(fx < 0)、遠手向右,並加上 turn: 1;yaw 可以真正轉動他 |
方向性特效朝右,地面特效站立在 y = 0 上,角色特效包含 o.actor(一個 24 x 38 的內建角色遮罩與像素),且任何地方都不使用 Math.random。可以使用通用的動機圖案;切勿重現特定遊戲的精靈、角色或標誌。
4. 使用原生程式碼取代 JS
如果遊戲無法執行 JS,且精靈表不足以滿足需求(例如需要跟隨移動目標的特效,或需要在執行時期為每個實例設定不同顏色),則請移植該特效。純特效是時間的函數;模擬特效則是在 src/core/sim.ts 中逐步更新粒子。保留雙緩衝區的概念、用於抖動 alpha 的 4x4 Bayer 閾值以及調色盤色階查詢。請並排渲染 JS 原始版本與你的移植版本,以確認兩者相符。
核心、所有特效、畫廊與 CLI 皆為 TypeScript 原始碼。使用前請先建置;在建立或變更 .ts 特效後,請在渲染前重新建置。畫廊與 CLI 支援韓文與英文搜尋;韓文文字會回退到系統字型。如需引擎原生工作,請參閱 docs/NATIVE_MIGRATION.md;切勿聲稱已存在原生執行環境。
分享成果
當使用者要求公開分享時,請使用本地檢出目錄並執行 npm run build,接著執行 npm run share -- <category>/<effect>。該指令會在 records/share/ 新資料夾中渲染一張透明 PNG 與其 Poku JSON,驗證目前網站大小與動畫限制,並列印絕對檔案路徑與分享頁面。它不會發佈或登入。
開啟 https://poku-pixel-fx.stankjedi.chatgpt.site/shared,必要時使用 ChatGPT 登入,並遵循頁面上的上傳流程。在分享表單中同時選取相符的 PNG 與 JSON,填寫所需的標題與標籤,並在上傳器確認權利聲明後提交。對於多個作品,批次區塊接受相符的 PNG 與 JSON 檔名。使用使用者要求的作品,並遵循瀏覽器的上傳與確認規則。切勿偽造身份標頭、取得或複製憑證,或未經使用者確認即聲明其法律權利。在聲明已發佈之前,請檢查畫廊是否有成功訊息與結果條目。網站可能對每個帳戶實施配額限制。重新散佈軟體時,請保留 LICENSE、NOTICE 以及第三方的版權與許可聲明。