mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-07-20 10:04:07 +00:00
75 lines
9.9 KiB
TypeScript
75 lines
9.9 KiB
TypeScript
|
import {Level, Palette, RawLevel, Upgrade} from "./types";
|
||
|
import _palette from "./palette.json";
|
||
|
import _rawLevelsList from "./levels.json";
|
||
|
import _appVersion from "./version.json";
|
||
|
import {rawUpgrades} from "./rawUpgrades";
|
||
|
|
||
|
const palette = _palette as Palette;
|
||
|
|
||
|
const rawLevelsList = _rawLevelsList as RawLevel[]
|
||
|
|
||
|
export const appVersion = _appVersion as string;
|
||
|
|
||
|
|
||
|
const randomPatterns = [`<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><path d='M3.25 10h13.5M10 3.25v13.5' stroke-width='1' stroke='white' fill='none'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='40' height='40'><path d='M11 6a5 5 0 01-5 5 5 5 0 01-5-5 5 5 0 015-5 5 5 0 015 5' stroke='none' fill='white'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='29' height='50.115'><path d='M14.498 16.858L0 8.488.002-8.257l14.5-8.374L29-8.26l-.002 16.745zm0 50.06L0 58.548l.002-16.745 14.5-8.373L29 41.8l-.002 16.744zM28.996 41.8l-14.498-8.37.002-16.744L29 8.312l14.498 8.37-.002 16.745zm-29 0l-14.498-8.37.002-16.744L0 8.312l14.498 8.37-.002 16.745z' stroke-width='1' stroke='white' fill='none'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='29' height='33.487'><path d='M29 20.928v14.813M14.5 12.56v16.745M29-2.559v6.744l-14.5 8.374L0 4.189v-6.745m29 6.742l14.5 8.37m0 16.745L29 20.928l-14.5 8.376L0 20.931l-14.5 8.376m0-16.744L0 4.189m0 31.487V20.931' stroke-width='1' stroke='white' fill='none'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='70' height='8'><path d='M-.02 22c8.373 0 11.938-4.695 16.32-9.662C20.785 7.258 25.728 2 35 2c9.272 0 14.215 5.258 18.7 10.338C58.082 17.305 61.647 22 70.02 22M-.02 14.002C8.353 14 11.918 9.306 16.3 4.339 20.785-.742 25.728-6 35-6 44.272-6 49.215-.742 53.7 4.339c4.382 4.967 7.947 9.661 16.32 9.664M70 6.004c-8.373-.001-11.918-4.698-16.3-9.665C49.215-8.742 44.272-14 35-14c-9.272 0-14.215 5.258-18.7 10.339C11.918 1.306 8.353 6-.02 6.002' stroke-width='1' stroke='white' fill='none'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='40' height='59.428'><path d='M0 70.975V47.881m20-1.692L8.535 52.808v13.239L20 72.667l11.465-6.62V52.808zm0-32.95l11.465-6.62V-6.619L20-13.24 8.535-6.619V6.619L20 13.24m8.535 4.927v13.238L40 38.024l11.465-6.62V18.166L40 11.546zM20 36.333L0 47.88m0 0v23.094m0 0l20 11.548 20-11.548V47.88m0 0L20 36.333m0 0l20 11.549M0 11.547l-11.465 6.619v13.239L0 38.025l11.465-6.62v-13.24L0 11.548v-23.094l20-11.547 20 11.547v23.094M20 36.333V13.24' stroke-width='1' stroke='white' fill='none'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='40' height='40'><path d='M27.26 5.415c-.55 0-.9.55-.65 1l2.45 4.75c.2.5.85.5 1.15.1l3.15-4.5c.3-.4 0-1.05-.55-1.1zM10.689 8.068c-.406-.051-.822.31-.778.748l.5 5.3c.05.5.6.8 1.05.5l4.55-3.05c.45-.3.4-.95-.05-1.15l-5.1-2.3a.605.605 0 0 0-.172-.048zM2.406 24.584a.635.635 0 0 0-.345.081l-4.75 2.4c-.45.2-.5.85-.1 1.15l4.45 3.15c.4.3 1 0 1.1-.5l.3-5.55c0-.412-.31-.712-.655-.73zm40 0a.635.635 0 0 0-.345.081l-4.75 2.4c-.45.2-.5.85-.1 1.15l4.45 3.15c.4.3 1 0 1.1-.5l.3-5.55c0-.412-.31-.712-.655-.73zm-22.17 3.108a.744.744 0 0 0-.675.723l.4 5.55c.05.5.6.8 1.05.5l4.45-2.95c.45-.25.4-.9-.05-1.15l-4.8-2.6a.702.702 0 0 0-.376-.073z' stroke='none' fill='white'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='50' height='33.333'><path d='M25 .806v2.79h.8V.806Zm0 4.465v2.791h.8v-2.79Zm-2.043 3.902-2.32 1.55.444.665 2.32-1.55-.443-.665zm4.885 0-.444.665 2.32 1.55.445-.665zM-.4 10.61v2.79h.8v-2.79zm50 0v2.79h.8v-2.79zm-30.356 1.042-2.32 1.55.443.666 2.322-1.55-.444-.666zm12.311 0-.444.665 2.32 1.55.445-.664zm3.783 2.566-.444.666 2.321 1.55.444-.666zm-19.852.025-2.32 1.55.444.665 2.32-1.55zm-15.886.77v2.79h.8v-2.79Zm50 0v2.79h.8v-2.79Zm-50 4.465v2.79h.8v-2.79h-.8Zm50 0v2.79h.8v-2.79h-.8zM2.442 23.379l-.444.665 2.32 1.55.445-.665zm45.115 0-2.32 1.55.443.666 2.322-1.55-.444-.666zM6.155 25.86l-.444.665 2.32 1.55.445-.665zm37.69 0-2.322 1.55.444.665 2.321-1.55-.444-.666zM9.937 28.424l-.444.665 2.32 1.55.445-.665-2.321-1.55zm30.11.003-2.321 1.55.444.666 2.321-1.55zM25 29.737v2.79h.8v-2.79z' stroke='none' fill='white'/></svg>`, `<svg xmlns='http://www.w3.org/2000/svg' width='20' height='40'><path d='M0 0v5.436c.385-.146.767.123 1.163.82.948 1.674 2.214 2.996 3.46 4.294C6.977 13.002 9.2 15.318 9.2 19.995c0 4.679-2.223 6.994-4.577 9.447-1.246 1.299-2.512 2.621-3.46 4.295-.396.698-.777.966-1.163.82V40h1.198v-.005c0-4.678 2.224-6.992 4.579-9.445 1.245-1.298 2.51-2.62 3.459-4.295.654-1.154 1.273-1.154 1.926 0
|
||
|
|
||
|
let attributed = 0
|
||
|
|
||
|
|
||
|
let levelIconHTMLCanvas = document.createElement('canvas')
|
||
|
const levelIconHTMLCanvasCtx = levelIconHTMLCanvas.getContext("2d", {
|
||
|
antialias: false,
|
||
|
alpha: true
|
||
|
}) as CanvasRenderingContext2D;
|
||
|
|
||
|
|
||
|
function levelIconHTML(bricks: string[], levelSize: number, levelName: string, color: string) {
|
||
|
const size = 40
|
||
|
const c = levelIconHTMLCanvas
|
||
|
const ctx = levelIconHTMLCanvasCtx
|
||
|
c.width = size
|
||
|
c.height = size
|
||
|
|
||
|
if (color) {
|
||
|
ctx.fillStyle = color
|
||
|
ctx.fillRect(0, 0, size, size)
|
||
|
} else {
|
||
|
ctx.clearRect(0, 0, size, size)
|
||
|
}
|
||
|
const pxSize = size / levelSize
|
||
|
for (let x = 0; x < levelSize; x++) {
|
||
|
for (let y = 0; y < levelSize; y++) {
|
||
|
const c = bricks[y * levelSize + x]
|
||
|
if (c) {
|
||
|
ctx.fillStyle = c
|
||
|
ctx.fillRect(Math.floor(pxSize * x), Math.floor(pxSize * y), Math.ceil(pxSize), Math.ceil(pxSize))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// I don't think many blind people will benefit for this but it's nice to have something to put in "alt"
|
||
|
return `<img alt="${levelName}" width="${size}" height="${size}" src="${c.toDataURL()}"/>`
|
||
|
}
|
||
|
|
||
|
export const icons = {}
|
||
|
|
||
|
export const allLevels = rawLevelsList.map(level => {
|
||
|
const bricks = level.bricks.split('').map(c => palette[c])
|
||
|
const icon = levelIconHTML(bricks, level.size, level.name, level.color)
|
||
|
icons[level.name] = icon
|
||
|
let svg = level.svg;
|
||
|
if (!level.color && !svg) {
|
||
|
svg = randomPatterns[attributed % randomPatterns.length]
|
||
|
attributed++
|
||
|
}
|
||
|
return {
|
||
|
...level,
|
||
|
bricks,
|
||
|
icon,
|
||
|
svg
|
||
|
}
|
||
|
|
||
|
}).filter(l => !l.name.startsWith('icon:')) as Level[]
|
||
|
|
||
|
|
||
|
export const upgrades = rawUpgrades.map(u => ({...u, icon: icons['icon:' + u.id]})) as Upgrade[]
|