The game as of artifact version 24, ready for local development with coding agents. - Source split from three large files into 52 small ones under src/sim, src/render and src/ui, joined in the order in src/manifest.json by build.py. The joined code is unchanged apart from comments; every headless suite gives the same output, and screenshots in both looks are pixel-identical to before. - Light tidying with no change in behaviour: one movement scan loop, shared hazard-stripe and belt shader helpers, unused code removed, a shared check helper for the test suites. - World files can be exported as an ordinary download outside claude.ai. - Tests: broken old scripts removed, experiments moved to tools/, test/run_all.py added. Tools: shot.py (repeatable screenshots), where.py, map.py. - Docs: AGENTS.md, CLAUDE.md, NOTES.md (the owner's to-do inbox), docs/PROJECT_MAP.md, DESIGN.md, TESTING.md, systems notes, the owner's requests and an agent log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K9kLmYADKSEjuwUN3rFxDA
47 lines
2.8 KiB
JavaScript
47 lines
2.8 KiB
JavaScript
// The title screen art.
|
|
// ---------- Title art ----------
|
|
const FONT5 = {
|
|
D: ['11110', '10001', '10001', '10001', '10001', '10001', '11110'], E: ['11111', '10000', '10000', '11110', '10000', '10000', '11111'],
|
|
P: ['11110', '10001', '10001', '11110', '10000', '10000', '10000'], G: ['01111', '10000', '10000', '10011', '10001', '10001', '01111'],
|
|
R: ['11110', '10001', '10001', '11110', '10100', '10010', '10001'], A: ['01110', '10001', '10001', '11111', '10001', '10001', '10001'],
|
|
I: ['11111', '00100', '00100', '00100', '00100', '00100', '11111'], N: ['10001', '11001', '10101', '10011', '10001', '10001', '10001'],
|
|
F: ['11111', '10000', '10000', '11110', '10000', '10000', '10000'], O: ['01110', '10001', '10001', '10001', '10001', '10001', '01110'],
|
|
U: ['10001', '10001', '10001', '10001', '10001', '10001', '01110'], Y: ['10001', '10001', '01010', '00100', '00100', '00100', '00100'],
|
|
};
|
|
const TITLE = { cells: [], grains: [], t: 0, raf: 0 };
|
|
function buildTitleCells() {
|
|
const lines = [['DEEPGRAIN', 6, 'hot'], ['FOUNDRY', 44, 'copper']];
|
|
for (const [word, y0, kind] of lines) {
|
|
const sc = 3, wpx = word.length * 6 * sc - sc;
|
|
const x0 = Math.round((320 - wpx) / 2);
|
|
[...word].forEach((ch, k) => {
|
|
const g = FONT5[ch];
|
|
for (let r = 0; r < 7; r++) for (let c = 0; c < 5; c++) if (g[r][c] === '1')
|
|
for (let a = 0; a < sc; a++) for (let b = 0; b < sc; b++) TITLE.cells.push({ x: x0 + (k * 6 + c) * sc + a, y: y0 + r * sc + b, kind, n: Math.random() });
|
|
});
|
|
}
|
|
}
|
|
function drawTitle() {
|
|
const c = $('titleart'); if (!c || $('title').hidden) { TITLE.raf = 0; return; }
|
|
const ctx = c.getContext('2d'); const t = (TITLE.t += 1);
|
|
const img = ctx.createImageData(320, 80), px = new Uint32Array(img.data.buffer);
|
|
px.fill(0x00000000);
|
|
for (const g of TITLE.cells) {
|
|
const w = 0.55 + 0.45 * Math.sin(t * 0.045 + g.x * 0.09 + g.n * 6);
|
|
let r, gg, b;
|
|
if (g.kind === 'hot') { const T = 1050 + w * 650 + g.n * 120; const i = glowIndex(T); r = GLOW_R[i]; gg = GLOW_G[i]; b = GLOW_B[i]; }
|
|
else { const v = (g.n - 0.5) * 30; r = 200 + v + w * 20; gg = 122 + v + w * 12; b = 76 + v; }
|
|
px[g.y * 320 + g.x] = 0xff000000 | (Math.max(0, Math.min(255, b)) << 16) | (Math.max(0, Math.min(255, gg)) << 8) | Math.max(0, Math.min(255, r));
|
|
}
|
|
// falling grains under the words
|
|
if (Math.random() < 0.6) TITLE.grains.push({ x: 60 + Math.random() * 200, y: 28, v: 0.3 + Math.random() * 0.4, hot: Math.random() < 0.6 });
|
|
for (let k = TITLE.grains.length - 1; k >= 0; k--) {
|
|
const g = TITLE.grains[k]; g.y += g.v; g.v += 0.02;
|
|
if (g.y > 79) { TITLE.grains.splice(k, 1); continue; }
|
|
if (g.y > 41 && g.y < 66 && px[(g.y | 0) * 320 + (g.x | 0)]) { TITLE.grains.splice(k, 1); continue; }
|
|
px[(g.y | 0) * 320 + (g.x | 0)] = g.hot ? 0xff3aa0ff : 0xff5a8cc8;
|
|
}
|
|
ctx.putImageData(img, 0, 0);
|
|
TITLE.raf = requestAnimationFrame(drawTitle);
|
|
}
|