Diorama Pixel:會動的像素藝術微縮場景
你要打造一個小地方:一個攤位、一座碼頭、一塊花園或一個門口,從固定等距攝影機觀看,以像素藝術繪製:整個畫面以 320 x 240 解析度渲染,並以最近鄰插值放大,每個表面透過 8 x 8 Bayer 矩陣量化為一組簡短柔和色調,材質帶有程序化紋理(木板紋、茅草線條、石頭、點狀草地、斑駁水面),地面的邊緣融入白色頁面,陽光投射柔和陰影,一或兩個微小人物循環執行一個明確動作。examples/ 中的三個場景就是範例,你將以相同格式撰寫。
這個技能是三個系列之一。diorama 繪製向量 SVG 插圖(UI 場景、線條藝術、空狀態、主題);diorama-worlds 渲染詳細的三維場景,包含關節人物和四種表面質感。當使用者想要像素、抖色、復古或 16 位元風格,或一個必須保持小型且無依賴的像素場景時,請使用此技能。
你只需撰寫一個東西:場景,即 .js 檔案。核心 (kit/pixel.js) 和頁面 (kit/page.html) 是固定的。絕不要編輯它們,不要貼上修改過的副本,也不要重新撰寫核心提供的功能(攝影機、光線、陰影、紋理、抖色、地面、人物骨架、樹木和灌木、一個在畫面外休眠的時鐘、指標)。
以下列出的每個檔案都位於此技能的文件夾中。將場景和建置後的頁面寫入使用者的工作目錄,並透過此文件夾的相對路徑從該目錄執行腳本。
1. 概念
在任何程式碼之前,用一行文字寫下概念:
名稱。 這個地方以及裡面有什麼。人物執行的一個動作,以及還有什麼會動。指標和點擊的作用。
選擇一個有故事和用途的地方:市場攤位、碼頭、麵包店門口、社區菜園、公車站、屋頂花園。一個動作支撐整個場景(綁花束、釣魚、澆水、揉麵),包含預備動作和停頓,以及兩三個圍繞它的安靜循環(布料、水、葉子、旗幟)。然後用四行寫出零件清單:地面(區域:草地、鋪石、水面、沙地、土壤、小徑)、結構(什麼站立著:攤位、棚子、圍欄)、人物(誰、在哪裡、面向何方、做什麼)、生命(什麼在搖曳、浮動或閃爍)。一個場景約有 10–25 個物件。如果清單讀起來很薄弱,場景也會如此。
當有人可以詢問時,提供兩到三個概念,然後等待。如果沒有人可以詢問,選擇靜止畫面最強的那一個,並說明原因。
2. 建置
- 閱讀
references/art-direction.md:色調、材質、抖色、地面邊緣、人物比例、如何讓畫面讀起來像像素微縮場景而非模糊渲染。 - 閱讀
references/scene-api.md:每個基本型、材質、輔助函式以及 tick 約定。不要閱讀kit/pixel.js在其索引註解以下的部分。 - 閱讀最接近的範例:
examples/flower-stall.js(鋪石和草地、條紋遮陽篷、兩個人物、三角旗)、examples/pier.js(水面和岸邊、坐著拿釣竿的人物、小船、茅草棚)或examples/allotment.js(土壤、磚徑、高架苗床、園丁澆水、稻草人)。 - 撰寫
<name>.js:一個Pixel.scene({ … })包含name、title、means(一句話,最多 140 字元)、hint(懸停什麼、點擊什麼)、duration、still、ground、可選的materials、build(P)回傳parts(其中parts.hot,每個熱區命名)以及tick(ctx)根據ctx.t/ctx.q擺放所有物體。 - 建置:
node <skill>/scripts/build.mjs <name>.js會寫出pixel-<name>.html,一個完全自包含的頁面,無任何網路請求。
3. 檢查
node <skill>/scripts/validate.mjs <name>.js pixel-<name>.html:檢查宣告、時鐘、自包含性、無 URL、核心位元組完全一致、大小預算以及指標。修正每個FAIL。npm ci --ignore-scripts --prefix <skill>執行一次,然後node <skill>/scripts/look.mjs <name>.js <outdir>。它會在無頭 Chromium 中開啟頁面(封鎖網路),並寫出<name>-look.json,包含靜止畫面、循環中的四個時刻、懸停、按壓以及行動版檢視,並檢查填色、動態、循環接縫、點擊選取、懸停、按壓、減少動態效果、框架成本以及行動裝置溢出。框架成本以場景的框架預算(24 fps 時為 41.7 ms)為基準;--throttle 4以四倍慢的 CPU 檢視,模擬 CI 執行器或手機。CHROME_PATH可選擇瀏覽器;否則使用已安裝的 Chrome 或 Chromium。- 開啟 PNG 並檢視。 通過檢查並不代表畫面好看。針對靜止畫面問問:這個動作在這麼小的尺寸下能看清楚嗎(手、工具、正在處理的東西)?有沒有人躲在柱子或屋頂後面?每個表面是否顯示其材質?地面是否在每一側都融入頁面,沒有任何東西被畫面邊界切斷?地面上的陰影是否與太陽位置一致?然後修正場景,而不是核心,並再次檢視。
不要交付驗證器拒絕的頁面。如果你沒有開啟圖片,不要聲稱檢視已完成。如果沒有瀏覽器,請直接說明,並以「檢視未驗證」的狀態交付。
4. 交付
按照使用者要求的方式提供 pixel-<name>.html(檔案,或者如果你可以發布的話提供 artifact)。然後,每項一行:概念;靜止秒數及其原因;大小(約 50 KB,無依賴);如何嵌入(references/scene-api.md,「嵌入」:一個 <canvas>,核心和場景在兩個 <script> 標籤中加上 Pixel.mount,或其中的 React 元件);你無法驗證的任何事項。
5. 調整
當使用者要求變更時,只編輯 <name>.js,建置,驗證並再次檢視。
常見問題
| 如果你發現自己這樣做 | 請改為這樣做 |
|---|---|
| 使用 three.js、WebGL 或圖片檔 | 沒有這些東西:核心在 2D Canvas 上光柵化實體;使用 P.box、P.cyl、P.ball、P.wedge、P.line |
撰寫 requestAnimationFrame、setTimeout 或 Math.random | 在 tick 中根據 ctx.t / ctx.q 擺放所有物體;使用 P.hash(i, j) 取得固定的變化性 |
position.x += speed * dt | 使用來自 P.phase(t, period) 的位置,讓靜止畫面和循環接縫都精確 |
| 人物躲在櫃檯、柱子或屋頂後面 | 移動他們、降低櫃檯、升高屋頂:攝影機是固定的,他們是故事的核心 |
| 手臂看起來與身體融為一體 | 使用前臂伸出的姿勢(P.pose(p, 'work' / 'hold')),雙手握住帶有自己顏色的物品 |
| 一棵樹用一個大球表示 | 使用 P.tree 和 P.bush:圓形陰影的葉簇集群 |
| 大表面使用純色 | 使用紋理材質:'wood'、'thatch'、'stone'、'paving'、'leaf'、'cloth',或使用帶有 tex 的色階 |
| 地面末端出現硬邊 | 地面是 ground: { rx, rz, wobble, fade }:它已經會融入;絕不要添加板子或基座 |
| 場景比它的地面還寬 | 將所有東西保持在 rx 和 rz 之內;畫面範圍配合地面 |
| 內部寬度超過 480 像素 | 320 x 240 才是這個風格;更多像素看起來像渲染而非像素藝術 |
編輯 kit/pixel.js 來讓場景運作 | 是場景錯了;修改場景 |
參考資料
references/scene-api.md:宣告、P(基本型、材質、人物、姿勢、樹木、雜訊)、tick 上下文和指標、執行期和嵌入。references/art-direction.md:色調和色階、材質和紋理、抖色、地面邊緣、光線和陰影、像素比例的人物、構圖。