Skip to content

Commit

Permalink
check bounds when getting tile
Browse files Browse the repository at this point in the history
  • Loading branch information
leomcelroy committed Jul 20, 2022
1 parent 4fceb9b commit 51fdc61
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 62 deletions.
133 changes: 73 additions & 60 deletions api/thumbnail/[name].js
Original file line number Diff line number Diff line change
@@ -1,83 +1,96 @@
import * as gridEngine from "../../engine/engine.js";
import { palette } from "../../palette.js";
// import fetch from 'node-fetch';
import { readFileSync } from 'fs';
import path from 'path';

async function drawGame(game) {
function drawGame(name) {

// const url = `https://raw.githubusercontent.com/hackclub/sprig/main/games/${game}.js`;
// const src = await fetch(url).then(x => x.text());
const url = `https://raw.githubusercontent.com/hackclub/sprig/main/games/${name}.js`;

const file = path.join(process.cwd(), 'games', `${game}.js`);
const file = path.join(process.cwd(), '../../games', `${name}.js`);
const src = readFileSync(file, 'utf8');

let screen, bitmaps;
const setScreenSize = (w, h) => screen = {
data: new Uint8Array(w*h*4),
width: w
};
const { api, state } = gridEngine.init({
palette,
setBitmaps: bm => bitmaps = bm,
setScreenSize,
drawText: () => {}
});
api.setScreenSize = setScreenSize;
api.afterInput = () => {};
api.onInput = () => {};

try {
new Function(...Object.keys(api), src)(...Object.values(api));

if (!screen) throw new Error("never set screen size");
if (!bitmaps) throw new Error("never set legend");
} catch(e) {
console.error(`couldn't run ${game}: ${e}`);
return {};
}
// have src

screen.data.fill(255);
drawTiles(state, api, screen, bitmaps);

return { name: game, image: screen, url };
// get legend
let legend = src.match(/setLegend\(([\s\S]*?)\)/)[1];

// const getVariable = name => legend.match(/name(.*?)['"](.*?)['"]/)[2];

function blitSprite(screen, sprite, tx, ty) {
const [_, { imageData: { data: bitmap } }] = sprite;
for (let x = 0; x < 16; x++)
for (let y = 0; y < 16; y++) {
const sx = tx*16 + x;
const sy = ty*16 + y;
const reconstructedLegend = {};

if (bitmap[(y*16 + x)*4 + 3] < 255) continue;
// for (let i = 0; i < legend.length; i++) {

// }

screen.data[(sy*screen.width + sx)*4 + 0] = bitmap[(y*16 + x)*4 + 0];
screen.data[(sy*screen.width + sx)*4 + 1] = bitmap[(y*16 + x)*4 + 1];
screen.data[(sy*screen.width + sx)*4 + 2] = bitmap[(y*16 + x)*4 + 2];
screen.data[(sy*screen.width + sx)*4 + 3] = bitmap[(y*16 + x)*4 + 3];
}
}
let lastKey = "";
legend.split(",").forEach(x => {
console.log(x);
if (x.includes("[")) {
lastKey = x.replace("[", "").trim();
} else {
const value = x.match(/bitmap`([\s\S]*?)`/);
console.log(value);
if (value) reconstructedLegend[lastKey] = value;
}
})

function drawTiles(state, api, screen, bitmaps) {
const { dimensions, legend } = state;
const { width, height, maxTileDim } = dimensions;
console.log(reconstructedLegend);

const grid = api.getGrid();
// replace every [ thing ,
// with const | let thing = "newThing" | 'newThing'

for (const cell of grid) {
const zOrder = legend.map(x => x[0]);
cell.sort((a, b) => zOrder.indexOf(a.type) - zOrder.indexOf(b.type));
// console.log(legend);
// get first map
const firstMap = src.match(/[^t]map`([\s\S]*?)`/)[1];
// draw first map
// console.log(firstMap);

for (const { x, y, type } of cell) {
blitSprite(screen, bitmaps.find(x => x[0] == type), x, y);
}
}
}
const image = {
data: new Uint8Array(120*168),
width: 128
};

return { name, image, url };
}

const test = drawGame("tolls");
console.log(test);

export default async function handler(request, response) {
const { name } = request.query;
const data = await drawGame(name);
const data = drawGame(name);
return response.status(200).json(data);
}


function blitSprite(screen, sprite, tx, ty) {
const [_, { imageData: { data: bitmap } }] = sprite;
for (let x = 0; x < 16; x++)
for (let y = 0; y < 16; y++) {
const sx = tx*16 + x;
const sy = ty*16 + y;

if (bitmap[(y*16 + x)*4 + 3] < 255) continue;

screen.data[(sy*screen.width + sx)*4 + 0] = bitmap[(y*16 + x)*4 + 0];
screen.data[(sy*screen.width + sx)*4 + 1] = bitmap[(y*16 + x)*4 + 1];
screen.data[(sy*screen.width + sx)*4 + 2] = bitmap[(y*16 + x)*4 + 2];
screen.data[(sy*screen.width + sx)*4 + 3] = bitmap[(y*16 + x)*4 + 3];
}
}

function drawTiles(state, api, screen, bitmaps) {
const { dimensions, legend } = state;
const { width, height, maxTileDim } = dimensions;

const grid = api.getGrid();

for (const cell of grid) {
const zOrder = legend.map(x => x[0]);
cell.sort((a, b) => zOrder.indexOf(a.type) - zOrder.indexOf(b.type));

for (const { x, y, type } of cell) {
blitSprite(screen, bitmaps.find(x => x[0] == type), x, y);
}
}
}
9 changes: 7 additions & 2 deletions engine/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,12 @@ export function init({ palette, setBitmaps, setScreenSize, drawText }) {
}

function getTile(x, y) {
return getGrid()[state.dimensions.width*y+x] || [];
return y >= 0
&& y < state.dimensions.height
&& x >= 0
&& y < state.dimensions.width
? (getGrid()[state.dimensions.width*y+x] || [])
: [];
}

function hasDuplicates(array) {
Expand Down Expand Up @@ -545,7 +550,7 @@ export function init({ palette, setBitmaps, setScreenSize, drawText }) {
setSolids,
setPushables,
map: _makeTag(text => text), // No-op for now, here for editor support
bitmap: _makeTag(text => ({
bitmap: _makeTag(text => ({ // TODO: make this no-op and store bitmap somewhere else
text,
imageData: bitmapTextToImageData(text, palette)
})),
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
Expand Down

0 comments on commit 51fdc61

Please sign in to comment.