Files
Pocket-Bird/src/hats.js
Idrees Hassan 2773538a6c Add cowboy hat
2026-01-18 22:41:37 -05:00

111 lines
2.9 KiB
JavaScript

import Layer from "./animation/layer.js";
import { PALETTE } from "./animation/sprites.js";
import { getLayerPixels } from "./shared.js";
const HAT_WIDTH = 12;
export const HAT = {
NONE: "none",
TOP_HAT: "top-hat",
VIKING_HELMET: "viking-helmet",
COWBOY_HAT: "cowboy-hat",
};
/**
* @param {string[][]} spriteSheet
* @returns {{ base: Layer[], down: Layer[] }}
*/
export function createHatLayers(spriteSheet) {
const hatLayers = {
base: [],
down: []
};
for (let i = 0; i < Object.keys(HAT).length; i++) {
const hatName = Object.keys(HAT)[i];
if (hatName === 'NONE') {
continue;
}
const index = i - 1;
const hatKey = HAT[hatName];
const hatLayer = buildHatLayer(spriteSheet, hatKey, index, false);
const downHatLayer = buildHatLayer(spriteSheet, hatKey, index, false, 1);
hatLayers.base.push(hatLayer);
hatLayers.down.push(downHatLayer);
}
return hatLayers;
}
/**
* @param {string[][]} spriteSheet
* @param {string} hatName
* @param {number} hatIndex
* @param {boolean} [outlineBottom=false]
* @param {number} [yOffset=0]
* @returns {Layer}
*/
function buildHatLayer(spriteSheet, hatName, hatIndex, outlineBottom = false, yOffset = 0) {
const LEFT_PADDING = 6;
const RIGHT_PADDING = 14;
const TOP_PADDING = 5 + yOffset;
const BOTTOM_PADDING = Math.max(0, 15 - yOffset);
const hatPixels = getLayerPixels(spriteSheet, hatIndex, HAT_WIDTH);
const paddedHatPixels = [];
// Top padding
for (let y = 0; y < TOP_PADDING; y++) {
paddedHatPixels.push(Array(hatPixels[0].length + LEFT_PADDING + RIGHT_PADDING)
.fill(PALETTE.TRANSPARENT)
);
}
// Left and right padding
for (let y = 0; y < hatPixels.length; y++) {
const row = [];
for (let x = 0; x < LEFT_PADDING; x++) {
row.push(PALETTE.TRANSPARENT);
}
for (let x = 0; x < hatPixels[y].length; x++) {
row.push(hatPixels[y][x]);
}
for (let x = 0; x < RIGHT_PADDING; x++) {
row.push(PALETTE.TRANSPARENT);
}
paddedHatPixels.push(row);
}
// Bottom padding
for (let y = 0; y < BOTTOM_PADDING; y++) {
paddedHatPixels.push(Array(hatPixels[0].length + LEFT_PADDING + RIGHT_PADDING)
.fill(PALETTE.TRANSPARENT)
);
}
// Add outline
let neighborOffsets = [
[-1, 0],
[1, 0],
[0, -1],
[-1, -1],
[1, -1],
];
if (outlineBottom) {
neighborOffsets.push([0, 1], [-1, 1], [1, 1]);
}
for (let y = 0; y < paddedHatPixels.length; y++) {
for (let x = 0; x < paddedHatPixels[y].length; x++) {
const pixel = paddedHatPixels[y][x];
if (pixel !== PALETTE.TRANSPARENT && pixel !== PALETTE.BORDER) {
for (let [dx, dy] of neighborOffsets) {
const newX = x + dx;
const newY = y + dy;
if (newY >= 0 && newY < paddedHatPixels.length && newX >= 0 && newX < paddedHatPixels[newY].length && paddedHatPixels[newY][newX] === PALETTE.TRANSPARENT) {
paddedHatPixels[newY][newX] = PALETTE.BORDER;
}
}
}
}
}
return new Layer(paddedHatPixels, hatName);
}