101 lines
3.1 KiB
JavaScript
101 lines
3.1 KiB
JavaScript
/* ============================================================
|
|
DSP ARCADE — procedural pixel-art sprites
|
|
============================================================ */
|
|
(function () {
|
|
'use strict';
|
|
|
|
const cache = {};
|
|
|
|
function makeSprite(map, palette, scale = 1) {
|
|
const h = map.length;
|
|
const w = Math.max(...map.map(r => r.length));
|
|
const cv = document.createElement('canvas');
|
|
cv.width = w; cv.height = h;
|
|
const ctx = cv.getContext('2d');
|
|
for (let y = 0; y < h; y++) {
|
|
for (let x = 0; x < map[y].length; x++) {
|
|
const c = map[y][x];
|
|
if (c === '.' || c === ' ') continue;
|
|
ctx.fillStyle = palette[c] || '#fff';
|
|
ctx.fillRect(x, y, 1, 1);
|
|
}
|
|
}
|
|
if (scale > 1) {
|
|
const big = document.createElement('canvas');
|
|
big.width = w * scale; big.height = h * scale;
|
|
const bctx = big.getContext('2d');
|
|
bctx.imageSmoothingEnabled = false;
|
|
bctx.drawImage(cv, 0, 0, w * scale, h * scale);
|
|
return big;
|
|
}
|
|
return cv;
|
|
}
|
|
|
|
function sprite(map, palette, scale = 1, key) {
|
|
const k = key || JSON.stringify([map, palette, scale]);
|
|
if (!cache[k]) cache[k] = makeSprite(map, palette, scale);
|
|
return cache[k];
|
|
}
|
|
|
|
function draw(ctx, img, x, y) {
|
|
ctx.drawImage(img, Math.round(x - img.width / 2), Math.round(y - img.height / 2));
|
|
}
|
|
|
|
const SPRITES = {
|
|
ship: {
|
|
map: ['...W...','..WWW..','..WWW..','.WWWWWW','WWWWWWWW','W.W..W.W'],
|
|
palette: { W: '#e8f4ff' },
|
|
},
|
|
shipAlt: {
|
|
map: ['...C...','..CCC..','..CCC..','.CCCCCC','CCCCCCCC','C.C..C.C'],
|
|
palette: { C: '#7df9ff' },
|
|
},
|
|
invader1: {
|
|
map: ['..X...X..','...X.X...','..XXXXX..','.XX.X.XX.','XXXXXXXXX','X.XXXXX.X','X.X...X.X','...X.X...'],
|
|
palette: { X: '#7dff5e' },
|
|
},
|
|
invader2: {
|
|
map: ['...X.X...','..XXXXX..','.XXXXXXX.','XX.XXX.XX','XXXXXXXXX','..X...X..','.X.X.X.X.','X..X.X..X'],
|
|
palette: { X: '#ff7de9' },
|
|
},
|
|
invader3: {
|
|
map: ['..X...X..','.XXXXXXX.','XXXXXXXXX','XXX.X.XXX','XXXXXXXXX','.X.....X.','X..X.X..X','.X.....X.'],
|
|
palette: { X: '#ffe14d' },
|
|
},
|
|
ufo: {
|
|
map: ['...GGGG...','..GGGGGG..','.GGGGGGGG.','GGGRRRRGGG','GGGGGGGGGG','.G.G..G.G.'],
|
|
palette: { G: '#9d7dff', R: '#ff4d6d' },
|
|
},
|
|
heart: {
|
|
map: ['.XX.XX.','XXXXXXX','XXXXXXX','.XXXXX.','..XXX..','...X...'],
|
|
palette: { X: '#ff2d95' },
|
|
},
|
|
heartEmpty: {
|
|
map: ['.XX.XX.','X.....X','X.....X','.X...X.','..X.X..','...X...'],
|
|
palette: { X: '#5a2a5a' },
|
|
},
|
|
star: {
|
|
map: ['...X...','...X...','XXXXXXX','...X...','...X...'],
|
|
palette: { X: '#ffffff' },
|
|
},
|
|
pellet: {
|
|
map: ['XX','XX'],
|
|
palette: { X: '#ffe14d' },
|
|
},
|
|
bonusCell: {
|
|
map: ['.XXX.','X...X','X.X.X','X...X','.XXX.'],
|
|
palette: { X: '#ff9d2d' },
|
|
},
|
|
ghostCell: {
|
|
map: ['.XXX.','X...X','X.X.X','X...X','.XXX.'],
|
|
palette: { X: '#7df9ff' },
|
|
},
|
|
};
|
|
|
|
function get(name, scale = 1) {
|
|
const s = SPRITES[name];
|
|
return sprite(s.map, s.palette, scale, name + '_' + scale);
|
|
}
|
|
|
|
window.DSP_SPRITES = { get, sprite, draw, SPRITES };
|
|
})(); |