Campanie multi-stil — PR1 (T1-T8 + TD1-TD6)
Adauga al 6-lea stil de joc: campanie multi-stil care leaga puzzle-urile
in camere de stiluri diferite (clasic/terminal/arcade/chat/point in rotatie),
conectate prin coridoare cu usa, litera si stele.
Contract de montare (verificat la gate T1):
- gameCampaign: un <iframe srcdoc> per camera; camerele cheama parent.*
pe un nivel (merge si pe file://); template per stil cu sentinel __CFG__
injectat prin replace-functie (D1) + json.replace(/</g,'<') (D6)
- roomReady/roomError + timeout 4s -> skip cu 0 stele + cod eroare;
idx detinut de parinte, accepta nextRoom doar de la contentWindow activ (D5)
- parent.beep in mod campanie (un singur AudioContext, D2)
- resume prin safeStore try/catch (D3) + cheie djb2 peste CFG embedat (D11)
Builder:
- selector de stil per puzzle ("Auto (stil)") + optiunea Campanie multi-stil
- normalizePuzzle() la load + import (sursa unica pt forma puzzle, D8)
- blocare export+preview la 0 puzzle-uri; persist() guarded (D12)
- letter normalizat [A-Za-z0-9] + esc la SVG point (D13)
Design (DESIGN.md): tokens --c-*, intro poster, coridor "usa ca erou",
chrome unica sursa de progres, 5 usi CSS/SVG (normal/stuck/crescendo),
mod camera per motor, buget vertical mobil, baseline a11y.
Tooling: tests/smoke.mjs (Playwright, zero-dependente prin npx), TODOS.md,
sectiune ## Testing in CLAUDE.md. Demo-uri regenerate + exemplu-campanie.html.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,7 +96,7 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CFG = {"title":"Comoara ascunsa","player":"","color":"#6d28d9","story":"O comoara a fost ascunsa, iar singurul drum spre ea trece prin cateva incercari. Rezolva fiecare puzzle ca sa aduni literele cuvantului magic.","finalMessage":"Felicitari! Ai gasit comoara!","puzzles":[{"title":"Incalzirea","type":"free","question":"Cat fac 7 x 8?","answer":"56","tfAnswer":"Adevarat","choices":"","hint":"Tabla inmultirii cu 7.","letter":"D"},{"title":"Adevarat sau fals","type":"tf","question":"Romania are iesire la Marea Neagra.","answer":"","tfAnswer":"Adevarat","choices":"","hint":"","letter":"A"},{"title":"Alege raspunsul","type":"choice","question":"Care este capitala Frantei?","answer":"","tfAnswer":"Adevarat","choices":"*Paris\nLyon\nMarsilia","hint":"Turnul Eiffel.","letter":"R"}]};
|
||||
var CFG = {"title":"Comoara ascunsa","player":"","color":"#6d28d9","charName":"Alex","story":"O comoara a fost ascunsa, iar singurul drum spre ea trece prin cateva incercari.","finalMessage":"Felicitari! Ai gasit comoara!","puzzles":[{"title":"Incalzirea","type":"free","question":"Cat fac 7 x 8?","answer":"56","tfAnswer":"Adevarat","choices":"","hint":"Tabla inmultirii cu 7.","letter":"D","style":""},{"title":"Adevarat sau fals","type":"tf","question":"Romania are iesire la Marea Neagra.","answer":"","tfAnswer":"Adevarat","choices":"","hint":"","letter":"A","style":""},{"title":"Alege raspunsul","type":"choice","question":"Care este capitala Frantei?","answer":"","tfAnswer":"Adevarat","choices":"*Paris\nLyon\nMarsilia","hint":"Turnul Eiffel.","letter":"R","style":""}],"style":"classic"};
|
||||
document.documentElement.style.setProperty('--accent', CFG.color || '#6d28d9');
|
||||
document.documentElement.style.setProperty('--accent-light', 'color-mix(in srgb, ' + (CFG.color || '#6d28d9') + ' 40%, white)');
|
||||
|
||||
@@ -216,6 +216,11 @@ function check(given, expected) {
|
||||
function next() {
|
||||
idx++;
|
||||
if (idx < CFG.puzzles.length) { renderPuzzle(); return; }
|
||||
if(CFG._campaign){
|
||||
var L = ''; for(var ci=0;ci<CFG.puzzles.length;ci++){var lc=(CFG.puzzles[ci].letter||'').trim();if(lc)L+=lc.toUpperCase();}
|
||||
try{ parent.nextRoom({idx:CFG._campaign.idx, stars:totalStars, letter:L.charAt(0)}); }catch(e){}
|
||||
return;
|
||||
}
|
||||
show('sFinal');
|
||||
var max = CFG.puzzles.length * 3;
|
||||
el('finalStars').textContent = totalStars + ' / ' + max + ' \u2605';
|
||||
@@ -251,6 +256,7 @@ function confetti() {
|
||||
}
|
||||
|
||||
function beep(ok) {
|
||||
if(CFG._campaign){ try{ parent.beep(ok); }catch(e){} return; }
|
||||
try {
|
||||
var ctx = beep.ctx || (beep.ctx = new (window.AudioContext || window.webkitAudioContext)());
|
||||
var t = ctx.currentTime;
|
||||
@@ -265,6 +271,8 @@ function beep(ok) {
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
window.onerror = function(msg){ if(CFG._campaign){ try{ parent.roomError(CFG._campaign.idx, String(msg)); }catch(e){} } };
|
||||
if(CFG._campaign){ try{ parent.roomReady(CFG._campaign.idx); }catch(e){} }
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user