pxl: 코드로 만드는 픽셀 아트
작은 .px.js 파일을 작성하면 pxl이 PNG와 확대된 미리보기 이미지를 생성합니다. DSL은 픽셀을 두 번 작성하지 않도록 설계되었습니다: 미러링, 자동 아웃라인, 팔레트 스왑 변형, 재사용 가능한 부품, 기본 도형, 브러시, 타일맵 등을 지원합니다. Node ≥ 22.18이 필요합니다. 설치 과정은 없습니다.
PXL은 node <이 스킬 디렉터리>/bin/pxl.js를 의미합니다.
워크플로우
art.px.js를 작성합니다. (아래 템플릿에서 시작하세요. 예제는examples/디렉터리에 있습니다.)- 작업 중인 것만 빌드합니다:
PXL build art.px.js --only slime,heart - 결과물을 확인합니다:
out/_preview/<name>.png파일을 읽습니다. (확대됨, 체크 무늬 = 투명, 모든 픽셀마다 격자, 8픽셀마다 더 어둡게 표시). 정확한 픽셀 수정이 필요하면PXL ascii art.px.js <name>을 사용합니다. (키 + x/y 눈금자 표시). 이미지보다 비용이 적게 듭니다. - 작은 수정(하나의
grid(x, y, ...)패치, 하나의 연산)으로 수정하고 다시 빌드합니다. 반복합니다. - 사용자가 지켜보길 원한다면: 백그라운드에서
PXL serve art.px.js를 시작하고 URL을 알려줍니다. 저장할 때마다 다시 빌드하고 편집된 에셋의 그리기 단계를 재생합니다. 또한 동일한out/파일을 작성하므로 평소처럼 미리보기를 계속 읽을 수 있습니다.
오류는 파일:줄:열, 에셋/레이어/연산 경로를 알려주고 수정을 제안합니다("'r'을 의미하셨나요?"). 하나의 에셋이 깨져도 다른 에셋의 빌드를 중단하지 않습니다.
템플릿
pal({ k: "#1b1630", g: "#8ccf63", G: "#4c8a44", t: "#2a5560", w: "#fff6e0", r: "#e2585e", R: "#a63a4c" })
ramps("ktGg", "kRr") // 어두운 -> 밝은 순서, shade()/light()를 구동
// 대칭: 왼쪽 절반을 쓰고, 미러링하고, 아웃라인을 그립니다.
sprite("slime", { mx: true, outline: "k" }, `
....ggg
..ggGGg
.ggGwGg
gggkwgg
gggkkgg
tgggggg
.tttttt`)
sprite("slime_red", { base: "slime", swap: { g: "r", G: "R" } }) // 변형: 1줄
sprite("_eye", "wk\nkk") // "_" = 부분, 내보내지 않음
sprite("chest", { w: 16, h: 12, outline: "k" },
rect(0, 3, 16, 9, "R"), rect(0, 0, 16, 4, "r"), stamp("_eye", 7, 4), shade([0, 9, 16, 3]))
scene("meadow", { w: 160, h: 96, bg: "w" },
layer("ground", { y: 64 }, rect(0, 0, 160, 32, "G"), noise(0, 0, 160, 32, "g", 0.1, 3)),
layer("props", stamp("slime", 40, 54), stamp("slime_red", 70, 54, { flip: "x" })),
layer("shadow", { shade: true }, poly([38, 64, 88, 64, 92, 67, 34, 67], "k"))) // 그림자 투사
sheet("chars", ["slime*", "chest"], { pad: 1 })
필수 사항
- 색상:
pal에서 가져온 한 문자 키,"#hex","."건너뛰기,"_"지우기. 기본 팔레트는 피코8(0-f)입니다. 다른 팔레트는use("sweetie16" | "db16" | "endesga32" | "gray8")를 사용하세요. - 항목은 순서대로 실행됩니다: 그리드 문자열 (0,0에 그려짐), 연산,
(c) => { c.rect(...) }함수,layer(...)들. 그 다음 미러 → 스왑 → 뒤집기 → 회전 → 아웃라인 (각 면 1픽셀씩 증가) → 자르기가 실행됩니다. - 도형:
px rect box line(…, width) hline vline circ ring ellipse poly fill wire text. - 톤:
dither grad noise,shade/light(영역, 단계, 밀도),recolor, 그리고 그림자와 광택을 위한shade:/light:레이어. 영역:[cx,cy,r],[x,y,w,h], 다각형, 또는 함수.clip(영역, ...항목)은 모든 항목을 제한합니다. (반쪽 도형, 경사면) - 재사용:
stamp tile pattern tilemap scatter. 이름은 그룹 또는 글로브 패턴이 될 수 있습니다. (group("rocks", ["rock_a", "rock_a", "rock_b"]),"tree_*"). 각 배치는 무작위로 선택되지만 재현 가능합니다. 복사본마다 다양성을 위해rflip,rswap,seed,reseed: true를 사용하세요. - 브러시:
scatter("_leaf*", x, y, w, h, 30, { on: "g", clip: true, rflip: "xy" })는 작은 부분 스프라이트로 텍스처를 칠하며, 주어진 색상에만 적용됩니다. - 애니메이션:
anim("cat", { outline: "k", fps: 10 }, grid, frame(), frame(grid(23, 0, "_K"))): 프레임은 공유 항목 또는base에 대한 패치입니다. 또는frames: 6+(c) => ... c.phase ...로 절차적 루프를 만듭니다. 애니메이션을 스탬프하면 씬이 애니메이션됩니다. (rdelay: true는 복사본을 비동기화하고,frame: n은 하나를 고정합니다)._preview/<name>.png(모든 프레임이 나란히 표시됨) 또는 프레임별로pxl ascii를 확인하세요. - 글로우:
glow("zgQ", { r: 6, strength: 0.5 })를 스프라이트/씬 본문에 직접 사용하면 해당 키의 모든 픽셀에 후광이 생깁니다. (불꽃, 포션, 달, 네온);ramp: 2대신 팔레트 내에서 유지됩니다. 글로우 효과를 주는 개체는 다른 것이 빛나지 않도록 고유 키를 부여하거나where로 제한하세요.
모든 옵션이 포함된 전체 API: reference.md. 동적 조명 (램프, 단단한 레이어에 의해 차단된 빛, 하늘 빛, 테라리아 스타일): 씬에 조명이 필요할 때만 lighting.md를 읽으세요.
토큰을 절약하고 더 나은 아트를 만드는 습관
- 대칭적인 것은 왼쪽 절반만 쓰고 (
mx)outline이 아웃라인을 그리도록 하세요. 둘 다 수동으로 그리지 마세요. - 색상 변경은
base+swap; 반복되는 세부 사항은_parts+stamp; 패밀리는group또는 루프를 사용하세요:for (let i = 1; i <= 3; i++) sprite("tree_" + i, ...). - 넓은 영역: 기본 도형,
grad,noise,pattern,tilemap. 절대 큰 수동 그리드를 사용하지 마세요. - 유기적인 텍스처 (잎, 풀, 돌, 녹): 2–3개의 작은 브러시 부분 +
on/clip이 있는scatter를 사용하세요. - 채우기 노이즈는 사용하지 마세요. 벽, 바닥, 회반죽에 "덜 평평하게" 만들기 위해
noise얼룩을 뿌리지 마세요. 무작위 점으로 읽히지, 재질로 읽히지 않습니다. 표면의 모든 자국에는 이름을 붙일 수 있는 원인이 있어야 하며, 그 원인이 놓일 위치에 있어야 합니다:- 건축된 구조물: 사이딩/판자 줄, 벽돌 또는 돌 코스(오프셋 조인트), 타일 이음매;
- 풍화: 처마와 선반 아래의 빗물 자국 줄무늬, 땅에서 위로 희미해지는 튄 흙, 금속 브래킷 아래로 흐르는 녹, 판자를 따라 벗겨지는 페인트;
- 이야기를 들려주는 어수선함: 포스터, 파이프, 통풍구, 모서리의 균열.
평평한 색상도 괜찮습니다. 깨끗한 벽은 점이 많은 벽보다 낫습니다.
noise는 재질 자체가 입상인 경우(자갈, 모래, 아스팔트, 타르 지붕, 거친 돌)에만 괜찮으며, 드물게 사용하세요. 각도로 그려진 얼굴(3/4 뷰)에서는 표시가 얼굴의 기울기를 따르도록 하세요.
- 조명:
ramps를 정의한 다음light/shade영역을 사용하세요. 부드러운 가장자리를 위해density: 0.5패스를 쌓으세요. 여러 개체에 걸친 그림자를 위해poly와 함께shade: true레이어를 사용하세요. - 기억하기 쉬운 키를 사용하세요. (
g/G밝은/어두운 녹색). 깔끔한 픽셀 아트 룩을 위해 재질당 2–4가지 음영을 유지하세요. - 반복 작업 중에는
--only로 빌드하세요. 전체 빌드는 모든 미리보기도 작성합니다.