mirror of
https://github.com/NohamR/Pocket-Bird.git
synced 2026-05-26 04:07:24 +00:00
Add layer tags and tufted titmouse
This commit is contained in:
137
birb.js
137
birb.js
@@ -182,32 +182,31 @@ const styles = `
|
|||||||
}
|
}
|
||||||
|
|
||||||
#${FIELD_GUIDE_ID} {
|
#${FIELD_GUIDE_ID} {
|
||||||
width: 230px;
|
width: 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.birb-grid-content {
|
.birb-grid-content {
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: space-between;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.birb-grid-item {
|
.birb-grid-item {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 6px;
|
margin-top: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.birb-grid-item-locked {
|
|
||||||
filter: grayscale(100%);
|
|
||||||
cursor: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.birb-grid-item canvas {
|
.birb-grid-item canvas {
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
transform: scale(2);
|
transform: scale(2);
|
||||||
@@ -220,6 +219,15 @@ const styles = `
|
|||||||
background: rgba(255, 221, 177, 0.5);
|
background: rgba(255, 221, 177, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.birb-grid-item-locked {
|
||||||
|
cursor: auto;
|
||||||
|
filter: grayscale(100%) sepia(30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.birb-grid-item-locked canvas {
|
||||||
|
filter: contrast(90%);
|
||||||
|
}
|
||||||
|
|
||||||
.birb-field-guide-description {
|
.birb-field-guide-description {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -250,18 +258,33 @@ const styles = `
|
|||||||
class Layer {
|
class Layer {
|
||||||
/**
|
/**
|
||||||
* @param {string[][]} pixels
|
* @param {string[][]} pixels
|
||||||
|
* @param {string} [tag]
|
||||||
*/
|
*/
|
||||||
constructor(pixels) {
|
constructor(pixels, tag="default") {
|
||||||
this.pixels = pixels;
|
this.pixels = pixels;
|
||||||
|
this.tag = tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Frame {
|
class Frame {
|
||||||
|
|
||||||
|
#pixelsByTag = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Layer[]} layers
|
* @param {Layer[]} layers
|
||||||
*/
|
*/
|
||||||
constructor(layers) {
|
constructor(layers) {
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
let tags = new Set();
|
||||||
|
for (let layer of layers) {
|
||||||
|
tags.add(layer.tag);
|
||||||
|
}
|
||||||
|
tags.add("default");
|
||||||
|
for (let tag of tags) {
|
||||||
let maxHeight = layers.reduce((max, layer) => Math.max(max, layer.pixels.length), 0);
|
let maxHeight = layers.reduce((max, layer) => Math.max(max, layer.pixels.length), 0);
|
||||||
|
if (layers[0].tag !== "default") {
|
||||||
|
throw new Error("First layer must have the 'default' tag");
|
||||||
|
}
|
||||||
this.pixels = layers[0].pixels.map(row => row.slice());
|
this.pixels = layers[0].pixels.map(row => row.slice());
|
||||||
// Pad from top with transparent pixels
|
// Pad from top with transparent pixels
|
||||||
while (this.pixels.length < maxHeight) {
|
while (this.pixels.length < maxHeight) {
|
||||||
@@ -269,6 +292,7 @@ class Frame {
|
|||||||
}
|
}
|
||||||
// Combine layers
|
// Combine layers
|
||||||
for (let i = 1; i < layers.length; i++) {
|
for (let i = 1; i < layers.length; i++) {
|
||||||
|
if (layers[i].tag === "default" || layers[i].tag === tag) {
|
||||||
let layerPixels = layers[i].pixels;
|
let layerPixels = layers[i].pixels;
|
||||||
let topMargin = maxHeight - layerPixels.length;
|
let topMargin = maxHeight - layerPixels.length;
|
||||||
for (let y = 0; y < layerPixels.length; y++) {
|
for (let y = 0; y < layerPixels.length; y++) {
|
||||||
@@ -277,6 +301,9 @@ class Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
this.#pixelsByTag[tag] = this.pixels.map(row => row.slice());
|
||||||
|
}
|
||||||
// Surround non-transparent pixels with border
|
// Surround non-transparent pixels with border
|
||||||
// for (let y = 0; y < this.pixels.length; y++) {
|
// for (let y = 0; y < this.pixels.length; y++) {
|
||||||
// for (let x = 0; x < this.pixels[y].length; x++) {
|
// for (let x = 0; x < this.pixels[y].length; x++) {
|
||||||
@@ -287,30 +314,39 @@ class Frame {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
hasAdjacent(x, y) {
|
/**
|
||||||
for (let i = -1; i <= 1; i++) {
|
* @param {string} [tag]
|
||||||
for (let j = -1; j <= 1; j++) {
|
* @returns {string[][]}
|
||||||
if (i === 0 && j === 0) {
|
*/
|
||||||
continue;
|
getPixels(tag="default") {
|
||||||
}
|
return this.#pixelsByTag[tag] ?? this.#pixelsByTag["default"];
|
||||||
if (this.pixels[y + i] && this.pixels[y + i][x + j] && this.pixels[y + i][x + j] !== TRANSPARENT && this.pixels[y + i][x + j] !== BORDER) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hasAdjacent(x, y) {
|
||||||
|
// for (let i = -1; i <= 1; i++) {
|
||||||
|
// for (let j = -1; j <= 1; j++) {
|
||||||
|
// if (i === 0 && j === 0) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (this.#pixels[y + i] && this.#pixels[y + i][x + j] && this.#pixels[y + i][x + j] !== TRANSPARENT && this.#pixels[y + i][x + j] !== BORDER) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {CanvasRenderingContext2D} ctx
|
* @param {CanvasRenderingContext2D} ctx
|
||||||
* @param {number} direction
|
* @param {number} direction
|
||||||
* @param {BirdType} [theme]
|
* @param {BirdType} [theme]
|
||||||
*/
|
*/
|
||||||
draw(ctx, direction, theme) {
|
draw(ctx, direction, theme) {
|
||||||
for (let y = 0; y < this.pixels.length; y++) {
|
const pixels = this.getPixels(theme?.tags[0]);
|
||||||
const row = this.pixels[y];
|
for (let y = 0; y < pixels.length; y++) {
|
||||||
for (let x = 0; x < this.pixels[y].length; x++) {
|
const row = pixels[y];
|
||||||
const cell = direction === Directions.LEFT ? row[x] : row[this.pixels[y].length - x - 1];
|
for (let x = 0; x < pixels[y].length; x++) {
|
||||||
|
const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1];
|
||||||
ctx.fillStyle = theme?.colors[cell] ?? cell;
|
ctx.fillStyle = theme?.colors[cell] ?? cell;
|
||||||
ctx.fillRect(x * CANVAS_PIXEL_SIZE, y * CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE);
|
ctx.fillRect(x * CANVAS_PIXEL_SIZE, y * CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE);
|
||||||
};
|
};
|
||||||
@@ -400,8 +436,9 @@ class BirdType {
|
|||||||
* @param {string} name
|
* @param {string} name
|
||||||
* @param {string} description
|
* @param {string} description
|
||||||
* @param {Record<string, string>} colors
|
* @param {Record<string, string>} colors
|
||||||
|
* @param {string[]} [tags]
|
||||||
*/
|
*/
|
||||||
constructor(name, description, colors) {
|
constructor(name, description, colors, tags=[]) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
const defaultColors = {
|
const defaultColors = {
|
||||||
@@ -414,6 +451,7 @@ class BirdType {
|
|||||||
[FEATHER_SPINE]: "#373737",
|
[FEATHER_SPINE]: "#373737",
|
||||||
};
|
};
|
||||||
this.colors = { ...defaultColors, ...colors };
|
this.colors = { ...defaultColors, ...colors };
|
||||||
|
this.tags = tags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,6 +478,17 @@ const species = {
|
|||||||
[WING]: "#e3cabd",
|
[WING]: "#e3cabd",
|
||||||
[WING_EDGE]: "#9b8b82",
|
[WING_EDGE]: "#9b8b82",
|
||||||
}),
|
}),
|
||||||
|
tuftedTitmouse: new BirdType("Tufted Titmouse",
|
||||||
|
"Native to the eastern United States, full of personality, and my wife's favorite bird.", {
|
||||||
|
[BEAK]: "#000000",
|
||||||
|
[FOOT]: "#af8e75",
|
||||||
|
[EYE]: "#000000",
|
||||||
|
[FACE]: "#c7cad7",
|
||||||
|
[BELLY]: "#e4e5eb",
|
||||||
|
[UNDERBELLY]: "#d7cfcb",
|
||||||
|
[WING]: "#b1b5c5",
|
||||||
|
[WING_EDGE]: "#9d9fa9",
|
||||||
|
}, ["tuft"]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -451,7 +500,7 @@ const Directions = {
|
|||||||
const SPRITE_WIDTH = 32;
|
const SPRITE_WIDTH = 32;
|
||||||
const DECORATIONS_SPRITE_WIDTH = 48;
|
const DECORATIONS_SPRITE_WIDTH = 48;
|
||||||
const FEATHER_SPRITE_WIDTH = 32;
|
const FEATHER_SPRITE_WIDTH = 32;
|
||||||
const SPRITE_SHEET_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAAgCAYAAACy9KU0AAAAAXNSR0IArs4c6QAABBdJREFUeJztnL9LHEEUx79zWkgk3RFwTRvsDKS5KpWpbDSVVQgkjSCYKkfIHyDBIhAhIAiBkOoqsUmVVDbaBFKkkLTxhHBgEQM28aU4Z53d25lddXfm1vt+4Ni5X/vm9t77znfm9hYghBBCCCGEEOIJFboDhOQhImJ7TinFHK4x/PJILiEFQMd+PD0NANg+PEy0ffSBEBIIOWcximQxigbaLnEqK/5iFMne7KzIyspAu+r4pFrGQ3eAFCOr0HyN/I+np/Gq2UTr4cOBtnYhPtjf3cWrZjNuk/rTCN0Bkk96GqK3vkf/UAKwfXiIN71e4rE3vZ5X8SNkZDGnIebWhwCZU7C92dn45msKltUHn7FJtdABFUQyCNEP7UB8oad5pgsx3YePaWC6D1x8JiOHiPQXP42tz9ihHYDZh1ACHFr8SflwBCmIiMj+/fvx/db3715HYHMdKJQDMAuf7oMQj+iRV7sfOgBCrk+hUcyW8KM2CtIBEFIuuUWkiy5db7oWfRQiBZDUCeZrcZwnIpri83wreUyVUhAR8zWVHFyXAIqI8Eslw0BadGwDNkliFSCX+ADA8y2JD3JVYjAMAkhIUcwUXFrvxu1OOwrRncqYGlNy9E9KqTenA2pMRlC3pvDhRf8APnvXxeflBuY3zwBcHOQqxGAYBJCQgohSKiE6N5WpMSXzm2f4vNwoRYSsO8gTAAA4OT6K21rlXVbzMgIhItKYTI4caQHU8TvtKBGXQkQ8Ii7hMeuCeTmI1QEppZTr515TfICkG8riKi7l7G93QAC1+KRjp91Q1v6YAKRknOJjwNSzUOjf8O/vPMLK7y9xGwCeHn/KfG36C/n56w+Ai2laUYZBAAmxsbTezU3mKtd+bPGNmLXIc2cnzwsWpztzA89NLHzFg9UD3Lt7O/O9Wni+bczoffUDXnIapuMPCOBBtgC6+kEbTMoiT4A67QhL61102lFV+WZ1X+ciVIs8v/L1gE535jCxMAOsHmQ+nxYe4Ho+VAuPptOOriSAhJTBx5kn1kHQg/gA6Oe4Lf/rQq4DAvrTmrQLOvlxAgBovt63vfciyBWFx+XAgAsXlkXZAkhImt5aS1bGtwEkp1s+xAeAuAbgurigQmdCp0VAi08Wzdf7pZ0lHVoACcmjt9aKE80QI1/5ZhUh85fhYc7/S/0Vo7fWcr62TPEx44cSQEJqgOhZQFqItAgNcx3krgHpX6POP4hVhKosfB0bgFMEKT5kBFHfNmb6SW8RohuBcRkI2X77UgDEN32/qstEpC5D4YzPS1WQEUbQd0TyYPWg0pr0SlbxZ92vWoBCxSekLui60LcbURPpYrdtqxSgkPEJqQuSQeg+uSh8HpBeh3FtqyR0fELqQN3WPi91VnLuzir88KHjE0LK5z8tFuzphqiPOAAAAABJRU5ErkJggg==";
|
const SPRITE_SHEET_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWAAAAAgCAYAAAAsTqKUAAAAAXNSR0IArs4c6QAABKFJREFUeJztnL9rHEccxd+cXRwx7o6AVmmNOhncXOVKqdycXKkKgQiBQSBXOYz/AGFUBGIIGIQCIdVVQo2rqHJjNQYXKYTb6AzhwIUVUGN9U9zN3uze7OzpvDuze/s+cOzsj7vv7O7M+76d3VuAEEIIIYQQQgghpHRU6AoQkoeISNY6pRTbMKktbLwkl5ACqGM/Xl0FABxfXCTKPupACCFBkAmbUSSbUTRTdolzUfE3o0jerq+L7O7OlMuOT0iZ3A5dATIfNqHx5fwer67iWaeD7sOHM2XtQn1w9uYNnnU6cZmQutMKXQGST/oyXE99u79QAnh8cYEXo1Fi2YvRyKv4E0IainkZbk59CLA5BPF2fT3++BqCsNXBZ2xCyoQOeE7EQoh6aAfqCz3MYbpQ0336GAZJ14E33whpGCIyvvljTH3GDu0AzTqESkChkx8hRUMHMSciImf378fz3ffvvTowcxw4lAM0ha+J7jMt/E08BoQEQTsv7X7pAJuFcdxFz4aqA9tAw7CNfzaxATR53wkAQLYPYxH2G7gCCYAUT+5NOH2ilVKJj7mubKqSAJSB79gkPNuH0xEY37F1s9N1qHIbrEp/rQPOP2KY4ms0PuhlImJuU0qDMOuQWg4RkSo3RLJcHO2EbWshE0AeaYG19VcyS+aJdImv5mgndsKYbFtow3DV4WhHJU4qhZiQcEzMUDy/dTCMy4N+BBFZmj66ckvJxy9SyL44HXDrTgT1zQp+fxoBAH76dYjXT1p49OoawPQgl+GG8xLA9qGYQyF0w4SEQ5RSCdFdVlZuKXn06hqvn7QKEeGvcsCXnz7G5UE/0t/LDnYDgRQRad2JEsvSCUDH1xl2kTiELMLWwVAG/YjtDBCX8Jq6wH45S6YDVkop18C5Kb5A0g3bWMSlXv83nEkAWnzTsdNu2PZ7bABkEa5ONqTdO1W6DADtXljxrUgCcIqvAbteBnO9De23b7/H7r9/xWUA+PHTn9Zt0yfkwz+fAUyHKealCgmAEABo907VVHhPvbefqiaAvG20+/UZ34hZi37urKQeWL862ZhZ1+6d4sHeOe59d9f6XS28716u6d8aB7zhMISOP5MAzu0JwFUPXgaRuhIyAdjIE+BBP8LWwRAluvRM9z0R4UocpzwWfh/w1ckG2r01YO/cuj4tvMDXXYdo4dUM+tFCCYCQOlIV4dX8sfZDpgnyIL4Axn08q//XhVwHDIwv69Mu+PLvSwBA5/lZ1nenQRYUXpcDB6Yu3EbRCYAQkmS035Xd28cAksMNPsQXgLgMWF1ccG4FbSKoxddG5/lZYc8Fh04AhBA3o/1u3NEMMfbV3zJF2Hwyqsr9fy4BBsYiONrvOrctUnzN+KESACGk8oi+Ck4LcR3+AJI7BqyfRpjsSKYIlyl8OjYAZxKg+BLSONS7l2vjTp8hxEuB8UINOf7l5/itTOZ8WS/cSL3QwxmfL/0gpLEIxo5YHuydL89b42ziZ5svW4BDxSeE1AOtC/qzFJqQFrusaZkCHDI+IaQeiIXQdXIx93PAehzWNS2T0PEJIdWnbvd+bvSvtNwfK3HnQ8cnhJCi+R9t4o1zEu5PTgAAAABJRU5ErkJggg==";
|
||||||
const DECORATIONS_SPRITE_SHEET_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAPNJREFUaIHtmTESgzAMBHWZDC+gp0vP/x9Bn44+L6BRmrhJA4csM05uGzfY1s1JxggzIYQQQgghxEnATnB3zwikAICKiXq4BE/uwaxvn/UPb3BnNwFg27Ky0w6vzRp8S4mkIbQD3wzzFJofdTMkYJgn89czFADGKSSiSgphfFBjTaoIKC4cHWvSxIFMmjiQSYoDLUlxoCVywOwHHWjpROop1IL/vsxty2oYO77M1QggSvcpJAFXE66BPfa+2C4v4j2yi7z7FJKAq6FrwN3TO3MMlAAAKO3F2sVZTiu2N9p9CnUv4FR7PbMG2BQ69SJL/kVA8QauAnHUj36BVwAAAABJRU5ErkJggg==";
|
const DECORATIONS_SPRITE_SHEET_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAPNJREFUaIHtmTESgzAMBHWZDC+gp0vP/x9Bn44+L6BRmrhJA4csM05uGzfY1s1JxggzIYQQQgghxEnATnB3zwikAICKiXq4BE/uwaxvn/UPb3BnNwFg27Ky0w6vzRp8S4mkIbQD3wzzFJofdTMkYJgn89czFADGKSSiSgphfFBjTaoIKC4cHWvSxIFMmjiQSYoDLUlxoCVywOwHHWjpROop1IL/vsxty2oYO77M1QggSvcpJAFXE66BPfa+2C4v4j2yi7z7FJKAq6FrwN3TO3MMlAAAKO3F2sVZTiu2N9p9CnUv4FR7PbMG2BQ69SJL/kVA8QauAnHUj36BVwAAAABJRU5ErkJggg==";
|
||||||
const FEATHER_SPRITE_SHEET_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAARhJREFUWIXtlbENwjAQRf8hSiZIRQ+9WQNRUFIAKzACBSsAA1Ag1mAABqCCBomG3hQQ9OMEx4ZDNH5SikSJ3/fZ5wCJRCKRSPwZ0RzMWmtLAhGvQyUAi9mXP/aFaGjJRQQiguHihMvcFMJUVUYlAMuHixPGy4en1WmVQqgHYHkuZjiEj6a2/LjtYzTY0eiZbgC37Mxh1UN3sn/dr6cCz/LHB/DJj9s+2oMdbtdz6TtfFwQHcMvOInfmQNjsgchNWLXmdfK6gyioAu/6uKrsm1kWLAciKuCuey5nYuXAh234bdmZ6INIUw4E/Ix49xtjCmXfzLL8nY/ktdgnAKwxxgIoXIyqmAOwvIqfiN0ALNd21HYBO9XXGMAdnZTYyHWzWjQAAAAASUVORK5CYII=";
|
const FEATHER_SPRITE_SHEET_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAARhJREFUWIXtlbENwjAQRf8hSiZIRQ+9WQNRUFIAKzACBSsAA1Ag1mAABqCCBomG3hQQ9OMEx4ZDNH5SikSJ3/fZ5wCJRCKRSPwZ0RzMWmtLAhGvQyUAi9mXP/aFaGjJRQQiguHihMvcFMJUVUYlAMuHixPGy4en1WmVQqgHYHkuZjiEj6a2/LjtYzTY0eiZbgC37Mxh1UN3sn/dr6cCz/LHB/DJj9s+2oMdbtdz6TtfFwQHcMvOInfmQNjsgchNWLXmdfK6gyioAu/6uKrsm1kWLAciKuCuey5nYuXAh234bdmZ6INIUw4E/Ix49xtjCmXfzLL8nY/ktdgnAKwxxgIoXIyqmAOwvIqfiN0ALNd21HYBO9XXGMAdnZTYyHWzWjQAAAAASUVORK5CYII=";
|
||||||
|
|
||||||
@@ -523,9 +572,11 @@ Promise.all([loadSpritesheetPixels(SPRITE_SHEET_URI), loadSpritesheetPixels(DECO
|
|||||||
heartTwo: new Layer(getLayer(SPRITE_SHEET, 3)),
|
heartTwo: new Layer(getLayer(SPRITE_SHEET, 3)),
|
||||||
heartThree: new Layer(getLayer(SPRITE_SHEET, 4)),
|
heartThree: new Layer(getLayer(SPRITE_SHEET, 4)),
|
||||||
heartFour: new Layer(getLayer(SPRITE_SHEET, 5)),
|
heartFour: new Layer(getLayer(SPRITE_SHEET, 5)),
|
||||||
wingsUp: new Layer(getLayer(SPRITE_SHEET, 6)),
|
tuftBase: new Layer(getLayer(SPRITE_SHEET, 6), "tuft"),
|
||||||
wingsDown: new Layer(getLayer(SPRITE_SHEET, 7)),
|
tuftDown: new Layer(getLayer(SPRITE_SHEET, 7), "tuft"),
|
||||||
happyEye: new Layer(getLayer(SPRITE_SHEET, 8)),
|
wingsUp: new Layer(getLayer(SPRITE_SHEET, 8)),
|
||||||
|
wingsDown: new Layer(getLayer(SPRITE_SHEET, 9)),
|
||||||
|
happyEye: new Layer(getLayer(SPRITE_SHEET, 10)),
|
||||||
};
|
};
|
||||||
|
|
||||||
const decorationLayers = {
|
const decorationLayers = {
|
||||||
@@ -537,14 +588,14 @@ Promise.all([loadSpritesheetPixels(SPRITE_SHEET_URI), loadSpritesheetPixels(DECO
|
|||||||
};
|
};
|
||||||
|
|
||||||
const birbFrames = {
|
const birbFrames = {
|
||||||
base: new Frame([layers.base]),
|
base: new Frame([layers.base, layers.tuftBase]),
|
||||||
headDown: new Frame([layers.down]),
|
headDown: new Frame([layers.down, layers.tuftDown]),
|
||||||
wingsDown: new Frame([layers.base, layers.wingsDown]),
|
wingsDown: new Frame([layers.base, layers.tuftBase, layers.wingsDown]),
|
||||||
wingsUp: new Frame([layers.down, layers.wingsUp]),
|
wingsUp: new Frame([layers.down, layers.tuftDown, layers.wingsUp]),
|
||||||
heartOne: new Frame([layers.base, layers.happyEye, layers.heartOne]),
|
heartOne: new Frame([layers.base, layers.tuftBase, layers.happyEye, layers.heartOne]),
|
||||||
heartTwo: new Frame([layers.base, layers.happyEye, layers.heartTwo]),
|
heartTwo: new Frame([layers.base, layers.tuftBase, layers.happyEye, layers.heartTwo]),
|
||||||
heartThree: new Frame([layers.base, layers.happyEye, layers.heartThree]),
|
heartThree: new Frame([layers.base, layers.tuftBase, layers.happyEye, layers.heartThree]),
|
||||||
heartFour: new Frame([layers.base, layers.happyEye, layers.heartFour]),
|
heartFour: new Frame([layers.base, layers.tuftBase, layers.happyEye, layers.heartFour]),
|
||||||
};
|
};
|
||||||
|
|
||||||
const decorationFrames = {
|
const decorationFrames = {
|
||||||
@@ -644,8 +695,8 @@ Promise.all([loadSpritesheetPixels(SPRITE_SHEET_URI), loadSpritesheetPixels(DECO
|
|||||||
let focusedElement = null;
|
let focusedElement = null;
|
||||||
let timeOfLastAction = Date.now();
|
let timeOfLastAction = Date.now();
|
||||||
let petStack = [];
|
let petStack = [];
|
||||||
let currentTheme = "bluebird";
|
let currentTheme = "tuftedTitmouse";
|
||||||
let unlockedThemes = ["bluebird"];
|
let unlockedThemes = ["tuftedTitmouse"];
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (window !== window.top) {
|
if (window !== window.top) {
|
||||||
@@ -657,7 +708,7 @@ Promise.all([loadSpritesheetPixels(SPRITE_SHEET_URI), loadSpritesheetPixels(DECO
|
|||||||
document.head.appendChild(styleElement);
|
document.head.appendChild(styleElement);
|
||||||
|
|
||||||
canvas.id = "birb";
|
canvas.id = "birb";
|
||||||
canvas.width = birbFrames.base.pixels[0].length * CANVAS_PIXEL_SIZE;
|
canvas.width = birbFrames.base.getPixels()[0].length * CANVAS_PIXEL_SIZE;
|
||||||
canvas.height = SPRITE_HEIGHT * CANVAS_PIXEL_SIZE;
|
canvas.height = SPRITE_HEIGHT * CANVAS_PIXEL_SIZE;
|
||||||
document.body.appendChild(canvas);
|
document.body.appendChild(canvas);
|
||||||
|
|
||||||
@@ -830,6 +881,10 @@ Promise.all([loadSpritesheetPixels(SPRITE_SHEET_URI), loadSpritesheetPixels(DECO
|
|||||||
featherCanvas.addEventListener("click", () => {
|
featherCanvas.addEventListener("click", () => {
|
||||||
unlockBird(birdType);
|
unlockBird(birdType);
|
||||||
removeFeather();
|
removeFeather();
|
||||||
|
if (document.querySelector("#" + FIELD_GUIDE_ID)) {
|
||||||
|
removeFieldGuide();
|
||||||
|
insertFieldGuide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user