avatar to main merge
I have completed the character creation screen on the avatar branch and am preparing to merge it into main.
This commit is contained in:
159
scripts/generate-character-sprites.mjs
Normal file
159
scripts/generate-character-sprites.mjs
Normal file
@@ -0,0 +1,159 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { PNG } from "pngjs";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const root = path.resolve(__dirname, "..");
|
||||
const publicDir = path.join(root, "public");
|
||||
|
||||
const W = 32;
|
||||
const H = 48;
|
||||
|
||||
const RED = [255, 0, 0];
|
||||
const DARK_RED = [51, 0, 0];
|
||||
const WHITE = [255, 255, 255];
|
||||
const MAGENTA = [255, 0, 255];
|
||||
|
||||
function createCanvas() {
|
||||
return new PNG({ width: W, height: H });
|
||||
}
|
||||
|
||||
function setPixel(png, x, y, [r, g, b], alpha = 255) {
|
||||
if (x < 0 || y < 0 || x >= W || y >= H) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = (W * y + x) << 2;
|
||||
png.data[index] = r;
|
||||
png.data[index + 1] = g;
|
||||
png.data[index + 2] = b;
|
||||
png.data[index + 3] = alpha;
|
||||
}
|
||||
|
||||
function fillRect(png, x, y, width, height, color, alpha = 255) {
|
||||
for (let row = 0; row < height; row += 1) {
|
||||
for (let col = 0; col < width; col += 1) {
|
||||
setPixel(png, x + col, y + row, color, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeSprite(relativePath, png) {
|
||||
const filePath = path.join(publicDir, relativePath);
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, PNG.sync.write(png));
|
||||
console.log(`wrote ${relativePath}`);
|
||||
}
|
||||
|
||||
function drawSkin() {
|
||||
const png = createCanvas();
|
||||
fillRect(png, 11, 6, 10, 10, RED);
|
||||
fillRect(png, 10, 16, 12, 14, RED);
|
||||
fillRect(png, 8, 30, 6, 12, RED);
|
||||
fillRect(png, 18, 30, 6, 12, RED);
|
||||
fillRect(png, 6, 18, 4, 10, RED);
|
||||
fillRect(png, 22, 18, 4, 10, RED);
|
||||
fillRect(png, 12, 8, 8, 2, DARK_RED);
|
||||
writeSprite("character/skin/skin-1.png", png);
|
||||
}
|
||||
|
||||
function drawPantsVariant(index, widthOffset) {
|
||||
const png = createCanvas();
|
||||
fillRect(png, 8 + widthOffset, 28, 7 - widthOffset, 14, RED);
|
||||
fillRect(png, 17, 28, 7 - widthOffset, 14, RED);
|
||||
if (index === 2) {
|
||||
fillRect(png, 8, 26, 16, 4, RED);
|
||||
}
|
||||
if (index === 3) {
|
||||
fillRect(png, 7, 24, 18, 6, RED);
|
||||
}
|
||||
writeSprite(`character/pants/pants-${index}.png`, png);
|
||||
}
|
||||
|
||||
function drawShoesVariant(index) {
|
||||
const png = createCanvas();
|
||||
fillRect(png, 6, 40, 8, 4, RED);
|
||||
fillRect(png, 18, 40, 8, 4, RED);
|
||||
if (index >= 2) {
|
||||
fillRect(png, 5, 42, 10, 2, DARK_RED);
|
||||
fillRect(png, 17, 42, 10, 2, DARK_RED);
|
||||
}
|
||||
if (index === 3) {
|
||||
fillRect(png, 4, 38, 12, 3, RED);
|
||||
fillRect(png, 16, 38, 12, 3, RED);
|
||||
}
|
||||
writeSprite(`character/shoes/shoes-${index}.png`, png);
|
||||
}
|
||||
|
||||
function drawTorsoVariant(index) {
|
||||
const png = createCanvas();
|
||||
fillRect(png, 9, 16, 14, 14, RED);
|
||||
if (index >= 2) {
|
||||
fillRect(png, 7, 18, 3, 10, RED);
|
||||
fillRect(png, 22, 18, 3, 10, RED);
|
||||
}
|
||||
if (index >= 3) {
|
||||
fillRect(png, 11, 18, 10, 8, DARK_RED);
|
||||
}
|
||||
if (index === 4) {
|
||||
fillRect(png, 10, 14, 12, 4, RED);
|
||||
}
|
||||
writeSprite(`character/torso/torso-${index}.png`, png);
|
||||
}
|
||||
|
||||
function drawEyesVariant(index) {
|
||||
const png = createCanvas();
|
||||
fillRect(png, 12, 10, 3, 3, index === 1 ? RED : WHITE);
|
||||
fillRect(png, 17, 10, 3, 3, index === 1 ? RED : WHITE);
|
||||
fillRect(png, 13, 11, 1, 1, MAGENTA);
|
||||
fillRect(png, 18, 11, 1, 1, MAGENTA);
|
||||
if (index === 2) {
|
||||
fillRect(png, 11, 9, 5, 5, WHITE);
|
||||
fillRect(png, 16, 9, 5, 5, WHITE);
|
||||
fillRect(png, 13, 11, 2, 2, RED);
|
||||
fillRect(png, 18, 11, 2, 2, RED);
|
||||
}
|
||||
writeSprite(`character/eyes/eyes-${index}.png`, png);
|
||||
}
|
||||
|
||||
function drawHeadVariant(index) {
|
||||
const png = createCanvas();
|
||||
const y = index <= 3 ? 4 : 2;
|
||||
fillRect(png, 10, y, 12, index >= 5 ? 12 : 10, RED);
|
||||
if (index === 2) {
|
||||
fillRect(png, 8, y + 2, 3, 3, RED);
|
||||
fillRect(png, 21, y + 2, 3, 3, RED);
|
||||
}
|
||||
if (index === 3) {
|
||||
fillRect(png, 9, y - 1, 14, 3, RED);
|
||||
}
|
||||
if (index >= 4) {
|
||||
fillRect(png, 11, y + 1, 10, 4, DARK_RED);
|
||||
}
|
||||
if (index >= 6) {
|
||||
fillRect(png, 9, y - 2, 14, 4, RED);
|
||||
}
|
||||
if (index === 7) {
|
||||
fillRect(png, 7, y, 4, 8, RED);
|
||||
fillRect(png, 21, y, 4, 8, RED);
|
||||
}
|
||||
writeSprite(`character/head/head-${index}.png`, png);
|
||||
}
|
||||
|
||||
drawSkin();
|
||||
for (let index = 1; index <= 3; index += 1) {
|
||||
drawPantsVariant(index, index - 1);
|
||||
drawShoesVariant(index);
|
||||
}
|
||||
for (let index = 1; index <= 4; index += 1) {
|
||||
drawTorsoVariant(index);
|
||||
}
|
||||
for (let index = 1; index <= 2; index += 1) {
|
||||
drawEyesVariant(index);
|
||||
}
|
||||
for (let index = 1; index <= 7; index += 1) {
|
||||
drawHeadVariant(index);
|
||||
}
|
||||
|
||||
console.log("Character sprites generated.");
|
||||
Reference in New Issue
Block a user