The setup became a wizard: one decision per screen, tap advances
"the mode setup is really overwhelming now" — three posters plus a sub-row plus player tiles plus court meters was a wall. Discussed, Oliver picked the wizard with tap-advance over next-buttons and the accordion: PICK A GAME (three posters, now 148px tall — alone on a screen they get to be posters), then the mode's own second step only when it has one (classic: DIFFICULTY chips stacked tall; zombie tennis: ARCADE and THE TOURNAMENT as full posters; gore skips straight through), then MATCH SETUP holding player + court + SERVE UP with the mode riding the summary footer. Tapping selects AND advances — one decision per screen is the wizard's whole promise, and a NEXT under a single row of choices is a second tap for nothing. Back walks the chain the way it came (who-and-where returns to the second step only when the mode has one). Every step comes up pre-selected from last time, so a returning player is three taps from serving. Three new stages on the intro's existing data-stage switcher; splash Enter goes to 'mode' now. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e4c917e23d
commit
65be60b139
2 files changed
+45
-21
No files matched your search
+17
-4
@@ -92,9 +92,12 @@ const banner = (card, cls, on) => {
|
||||
return b;
|
||||
};
|
||||
const pickMode = id => { pickedMode = id; try { localStorage.setItem('mode', id); } catch {} };
|
||||
// TAP ADVANCES. Each screen's tap both selects and moves on — the wizard's whole promise is one
|
||||
// decision per screen, and a NEXT button under a single row of choices is a second tap for nothing.
|
||||
function buildSub() {
|
||||
modeSub.innerHTML = '';
|
||||
const t = topOf(pickedMode);
|
||||
document.getElementById('subTitle').textContent = t.diffs ? 'DIFFICULTY' : (t.name || '');
|
||||
if (t.diffs) for (const d of DIFFS) {
|
||||
const b = document.createElement('button');
|
||||
b.className = 'chip' + (d.id === pickedDiff ? ' on' : '');
|
||||
@@ -104,15 +107,17 @@ function buildSub() {
|
||||
try { localStorage.setItem('diff', d.id); } catch {}
|
||||
for (const el of modeSub.children) el.classList.toggle('on', el === b);
|
||||
summary();
|
||||
go('setup');
|
||||
});
|
||||
modeSub.appendChild(b);
|
||||
}
|
||||
else if (t.kids) for (const id of t.kids) {
|
||||
const b = banner(modeOf(id), 'mode sm', id === pickedMode);
|
||||
const b = banner(modeOf(id), 'mode', id === pickedMode);
|
||||
b.addEventListener('click', () => {
|
||||
pickMode(id);
|
||||
for (const el of modeSub.children) el.classList.toggle('on', el === b);
|
||||
summary();
|
||||
go('setup');
|
||||
});
|
||||
modeSub.appendChild(b);
|
||||
}
|
||||
@@ -125,6 +130,7 @@ for (const t of MENU) {
|
||||
for (const el of modeList.children) el.classList.toggle('on', el === b);
|
||||
buildSub();
|
||||
summary();
|
||||
go(t.diffs || t.kids ? 'modesub' : 'setup');
|
||||
});
|
||||
modeList.appendChild(b);
|
||||
}
|
||||
@@ -232,7 +238,7 @@ const openStats = () => {
|
||||
for (const el of document.getElementById('stModes').children) el.classList.toggle('on', el.dataset.m === stMode);
|
||||
stats.drawStats(stPeriod, SPRV, stMode); go('stats');
|
||||
};
|
||||
document.getElementById('mStart').addEventListener('click', () => go('setup'));
|
||||
document.getElementById('mStart').addEventListener('click', () => go('mode'));
|
||||
document.getElementById('mStats').addEventListener('click', openStats);
|
||||
document.getElementById('mRanks').addEventListener('click', () => { go('ranks'); stats.drawRanks(); });
|
||||
|
||||
@@ -281,8 +287,15 @@ nbName.addEventListener('keydown', e => { if (e.key === 'Enter') document.getEle
|
||||
// ZOMBIE TENNIS did nothing at all. A default parameter only applies to `undefined`, and a click
|
||||
// handler always passes something.
|
||||
document.getElementById('cStart').addEventListener('click', () => start());
|
||||
for (const id of ['sBack', 'stBack', 'rkBack', 'scBack'])
|
||||
for (const id of ['mBack', 'stBack', 'rkBack', 'scBack'])
|
||||
document.getElementById(id).addEventListener('click', () => go('splash'));
|
||||
// the wizard walks back the way it came: who-and-where returns to the mode's own second step when
|
||||
// it has one, the second step returns to the posters
|
||||
document.getElementById('subBack').addEventListener('click', () => go('mode'));
|
||||
document.getElementById('sBack').addEventListener('click', () => {
|
||||
const t = topOf(pickedMode);
|
||||
go(t.diffs || t.kids ? 'modesub' : 'mode');
|
||||
});
|
||||
document.getElementById('bsBack').addEventListener('click', () => go('secret'));
|
||||
|
||||
// ---- THE BACK ROOM: five taps in the TOP-LEFT CORNER of the splash (#hot, an invisible box in
|
||||
@@ -410,7 +423,7 @@ addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape') return go('splash');
|
||||
if (stage === 'splash') {
|
||||
if (!loaded()) return; // the boot bar hides the buttons; a key must not walk past it
|
||||
if (e.key === 'Enter' || e.key === ' ') go('setup');
|
||||
if (e.key === 'Enter' || e.key === ' ') go('mode');
|
||||
else if (e.key === 's' || e.key === 'S') openStats();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user