Fix help manual layout: shrink tabs to fit panel, space implant rows
- 10+ tabs at fixed 108px overflowed the 920px panel; tabs now shrink to fit - Implant rows grew a rarity/cap sub-line but kept 20px spacing; now 26px with 10 rows per column (20 items/page, 5 pages for 82 items) - Bump asset cache to v=39; smoke test asserts tabs stay on-screen
This commit is contained in:
1 parent
f9552326c2
commit
d5b1828df4
5 files changed
+39
-32
No files matched your search
+21
-21
@@ -6,31 +6,31 @@
|
|||||||
<meta name="theme-color" content="#0a0305">
|
<meta name="theme-color" content="#0a0305">
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22><text y=%2252%22 x=%2250%22 text-anchor=%22middle%22 dominant-baseline=%22middle%22 font-size=%2252%22>🔪</text></svg>">
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22><text y=%2252%22 x=%2250%22 text-anchor=%22middle%22 dominant-baseline=%22middle%22 font-size=%2252%22>🔪</text></svg>">
|
||||||
<title>MEATSLICER</title>
|
<title>MEATSLICER</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=38">
|
<link rel="stylesheet" href="css/style.css?v=39">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="wrap">
|
<div id="wrap">
|
||||||
<canvas id="game" width="960" height="640"></canvas>
|
<canvas id="game" width="960" height="640"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<script src="js/utils.js?v=38"></script>
|
<script src="js/utils.js?v=39"></script>
|
||||||
<script src="js/state.js?v=38"></script>
|
<script src="js/state.js?v=39"></script>
|
||||||
<script src="js/input.js?v=38"></script>
|
<script src="js/input.js?v=39"></script>
|
||||||
<script src="js/sfx.js?v=38"></script>
|
<script src="js/sfx.js?v=39"></script>
|
||||||
<script src="js/sfxbank.js?v=38"></script>
|
<script src="js/sfxbank.js?v=39"></script>
|
||||||
<script src="js/audio.js?v=38"></script>
|
<script src="js/audio.js?v=39"></script>
|
||||||
<script src="js/sprites.js?v=38"></script>
|
<script src="js/sprites.js?v=39"></script>
|
||||||
<script src="js/particles.js?v=38"></script>
|
<script src="js/particles.js?v=39"></script>
|
||||||
<script src="js/weapons.js?v=38"></script>
|
<script src="js/weapons.js?v=39"></script>
|
||||||
<script src="js/bullets.js?v=38"></script>
|
<script src="js/bullets.js?v=39"></script>
|
||||||
<script src="js/pickups.js?v=38"></script>
|
<script src="js/pickups.js?v=39"></script>
|
||||||
<script src="js/items.js?v=38"></script>
|
<script src="js/items.js?v=39"></script>
|
||||||
<script src="js/perks.js?v=38"></script>
|
<script src="js/perks.js?v=39"></script>
|
||||||
<script src="js/enemies.js?v=38"></script>
|
<script src="js/enemies.js?v=39"></script>
|
||||||
<script src="js/bosses.js?v=38"></script>
|
<script src="js/bosses.js?v=39"></script>
|
||||||
<script src="js/rooms.js?v=38"></script>
|
<script src="js/rooms.js?v=39"></script>
|
||||||
<script src="js/player.js?v=38"></script>
|
<script src="js/player.js?v=39"></script>
|
||||||
<script src="js/hud.js?v=38"></script>
|
<script src="js/hud.js?v=39"></script>
|
||||||
<script src="js/help.js?v=38"></script>
|
<script src="js/help.js?v=39"></script>
|
||||||
<script src="js/main.js?v=38"></script>
|
<script src="js/main.js?v=39"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+9
-7
@@ -6,7 +6,7 @@ const HELP_BUTTON = { x: W - 104, y: 24, w: 80, h: 26 };
|
|||||||
|
|
||||||
// Implant pages are generated from the live ITEMS roster so the manual never
|
// Implant pages are generated from the live ITEMS roster so the manual never
|
||||||
// drifts from the game data; the count and page count are dynamic.
|
// drifts from the game data; the count and page count are dynamic.
|
||||||
const HELP_ITEM_PAGE_SIZE = 23;
|
const HELP_ITEM_PAGE_SIZE = 20;
|
||||||
const HELP_ITEM_PAGE_COUNT = Math.ceil(Object.keys(ITEMS).length / HELP_ITEM_PAGE_SIZE);
|
const HELP_ITEM_PAGE_COUNT = Math.ceil(Object.keys(ITEMS).length / HELP_ITEM_PAGE_SIZE);
|
||||||
const HELP_PAGES = [
|
const HELP_PAGES = [
|
||||||
{ title: 'CONTROLS' },
|
{ title: 'CONTROLS' },
|
||||||
@@ -24,7 +24,9 @@ function hfont(px, bold) { return (bold ? 'bold ' : '') + Math.round(px * HELP_S
|
|||||||
function helpPanelX() { return (W - HELP_PANEL.w) / 2; }
|
function helpPanelX() { return (W - HELP_PANEL.w) / 2; }
|
||||||
|
|
||||||
function helpTabRect(i) {
|
function helpTabRect(i) {
|
||||||
const tw = 108, gap = 6;
|
// tabs shrink to fit the panel width so a growing page count never overflows
|
||||||
|
const gap = 6;
|
||||||
|
const tw = Math.min(108, Math.floor((HELP_PANEL.w - 40 - (HELP_PAGES.length - 1) * gap) / HELP_PAGES.length));
|
||||||
const total = HELP_PAGES.length * tw + (HELP_PAGES.length - 1) * gap;
|
const total = HELP_PAGES.length * tw + (HELP_PAGES.length - 1) * gap;
|
||||||
return { x: W / 2 - total / 2 + i * (tw + gap), y: HELP_PANEL.y + 96, w: tw, h: 32 };
|
return { x: W / 2 - total / 2 + i * (tw + gap), y: HELP_PANEL.y + 96, w: tw, h: 32 };
|
||||||
}
|
}
|
||||||
@@ -199,16 +201,16 @@ function drawHelpItemList(ctx, px, py, page) {
|
|||||||
const pageEntries = entries.slice(page * HELP_ITEM_PAGE_SIZE, page * HELP_ITEM_PAGE_SIZE + HELP_ITEM_PAGE_SIZE);
|
const pageEntries = entries.slice(page * HELP_ITEM_PAGE_SIZE, page * HELP_ITEM_PAGE_SIZE + HELP_ITEM_PAGE_SIZE);
|
||||||
const colW = (HELP_PANEL.w - 80) / 2;
|
const colW = (HELP_PANEL.w - 80) / 2;
|
||||||
for (let i = 0; i < pageEntries.length; i++) {
|
for (let i = 0; i < pageEntries.length; i++) {
|
||||||
const col = Math.floor(i / 12), r = i % 12;
|
const col = Math.floor(i / 10), r = i % 10;
|
||||||
const lx = x + col * colW, ly = ty + r * 20;
|
const lx = x + col * colW, ly = ty + r * 26;
|
||||||
const [iid, item] = pageEntries[i];
|
const [iid, item] = pageEntries[i];
|
||||||
const rar = ITEM_RARITY[item.rarity];
|
const rar = ITEM_RARITY[item.rarity];
|
||||||
ctx.fillStyle = rar.color; ctx.font = hfont(8, true);
|
ctx.fillStyle = rar.color; ctx.font = hfont(8, true);
|
||||||
ctx.fillText(item.name.toUpperCase(), lx, ly);
|
ctx.fillText(item.name.toUpperCase(), lx, ly);
|
||||||
ctx.fillStyle = '#5f4d4d'; ctx.font = hfont(7, true);
|
ctx.fillStyle = '#5f4d4d'; ctx.font = hfont(7, true);
|
||||||
ctx.fillText(item.rarity.toUpperCase().slice(0, 3) + '·' + item.cap, lx, ly + 12);
|
ctx.fillText(item.rarity.toUpperCase().slice(0, 3) + '·' + item.cap, lx, ly + 13);
|
||||||
ctx.fillStyle = '#a08d84'; ctx.font = hfont(8, false);
|
ctx.fillStyle = '#a08d84'; ctx.font = hfont(8, false);
|
||||||
ctx.fillText(fit(item.desc.toUpperCase(), 34), lx + 52, ly + 12);
|
ctx.fillText(fit(item.desc.toUpperCase(), 30), lx + 56, ly + 13);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +312,7 @@ function drawPauseHelp(ctx) {
|
|||||||
color: active ? '#f1e4d5' : (hover ? '#cdbdb2' : '#7d6a68'),
|
color: active ? '#f1e4d5' : (hover ? '#cdbdb2' : '#7d6a68'),
|
||||||
accent: active ? '#4a9cad' : '#3c2f38',
|
accent: active ? '#4a9cad' : '#3c2f38',
|
||||||
fill: active ? 'rgba(24,15,22,0.95)' : 'rgba(12,7,11,0.85)',
|
fill: active ? 'rgba(24,15,22,0.95)' : 'rgba(12,7,11,0.85)',
|
||||||
font: hfont(8, true),
|
font: hfont(r.w < 100 ? 7 : 8, true),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ const SfxBank = {
|
|||||||
if (this.buffers.has(name) || this.pending.has(name) || this.failed.has(name)) return;
|
if (this.buffers.has(name) || this.pending.has(name) || this.failed.has(name)) return;
|
||||||
const file = this.FILES[name];
|
const file = this.FILES[name];
|
||||||
if (!file || !this.ctx || typeof fetch !== 'function') return;
|
if (!file || !this.ctx || typeof fetch !== 'function') return;
|
||||||
const job = fetch('/assets/sfx/' + encodeURIComponent(file) + '?v=38')
|
const job = fetch('/assets/sfx/' + encodeURIComponent(file) + '?v=39')
|
||||||
.then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.arrayBuffer(); })
|
.then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.arrayBuffer(); })
|
||||||
.then(bytes => this.ctx.decodeAudioData(bytes))
|
.then(bytes => this.ctx.decodeAudioData(bytes))
|
||||||
.then(buffer => this.buffers.set(name, this.trim(buffer)))
|
.then(buffer => this.buffers.set(name, this.trim(buffer)))
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ const Sprites = {
|
|||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = () => { this.imgs[name] = img; if (--pending === 0) G.imagesLoaded = true; };
|
img.onload = () => { this.imgs[name] = img; if (--pending === 0) G.imagesLoaded = true; };
|
||||||
img.onerror = () => { if (--pending === 0) G.imagesLoaded = true; };
|
img.onerror = () => { if (--pending === 0) G.imagesLoaded = true; };
|
||||||
img.src = 'assets/' + name + '.png?v=38';
|
img.src = 'assets/' + name + '.png?v=39';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -1014,8 +1014,13 @@ console.log('== item stickiness ramps with owned count ==');
|
|||||||
|
|
||||||
console.log('== help manual grows with the implant roster ==');
|
console.log('== help manual grows with the implant roster ==');
|
||||||
{
|
{
|
||||||
check('10 help pages (4 implant pages for 82 items)', ctx.HELP_PAGES.length === 10);
|
check('11 help pages (5 implant pages for 82 items)', ctx.HELP_PAGES.length === 11);
|
||||||
check('10 help renderers', ctx.HELP_RENDERERS.length === 10);
|
check('11 help renderers', ctx.HELP_RENDERERS.length === 11);
|
||||||
|
check('help tabs never overflow the panel', (() => {
|
||||||
|
const last = ctx.helpTabRect(ctx.HELP_PAGES.length - 1);
|
||||||
|
const first = ctx.helpTabRect(0);
|
||||||
|
return first.x >= 0 && last.x + last.w <= ctx.W;
|
||||||
|
})());
|
||||||
ctx.G.player = ctx.G.player || {};
|
ctx.G.player = ctx.G.player || {};
|
||||||
const fctx = fakeCtx();
|
const fctx = fakeCtx();
|
||||||
let renderOK = true;
|
let renderOK = true;
|
||||||
|
|||||||
Reference in new issue
Block a user