This commit is contained in:
2026-07-02 13:30:15 +02:00
parent e0f9dd8da3
commit c7911f670a

124
app.js
View File

@@ -92,23 +92,33 @@
? confetti.create($("#confetti"), { resize: true, useWorker: true })
: () => {};
const CONFETTI_COLORS = ["#ffd23f", "#ff9e00", "#ff2e88", "#00e5ff", "#29e08a", "#ffffff"];
function bigBurst() {
// esplosione centrale abbondante
myConfetti({ particleCount: 220, spread: 110, startVelocity: 48, origin: { y: 0.55 }, colors: CONFETTI_COLORS });
myConfetti({ particleCount: 140, spread: 130, startVelocity: 40, decay: 0.92, scalar: 1.1, origin: { y: 0.6 }, colors: CONFETTI_COLORS });
// due cannoni laterali
myConfetti({ particleCount: 80, angle: 60, spread: 75, origin: { x: 0, y: 0.7 }, colors: CONFETTI_COLORS });
myConfetti({ particleCount: 80, angle: 120, spread: 75, origin: { x: 1, y: 0.7 }, colors: CONFETTI_COLORS });
}
function celebrate(kind) {
bigBurst();
if (kind === "jackpot") {
const end = Date.now() + 1400;
const colors = ["#ffd23f", "#ff9e00", "#ff2e88", "#00e5ff", "#ffffff"];
// pioggia prolungata extra per il jackpot
const end = Date.now() + 2600;
(function frame() {
myConfetti({ particleCount: 6, angle: 60, spread: 70, origin: { x: 0 }, colors });
myConfetti({ particleCount: 6, angle: 120, spread: 70, origin: { x: 1 }, colors });
myConfetti({ particleCount: 4, spread: 120, startVelocity: 55, origin: { y: 0.3 }, colors });
myConfetti({ particleCount: 12, angle: 60, spread: 80, origin: { x: 0 }, colors: CONFETTI_COLORS });
myConfetti({ particleCount: 12, angle: 120, spread: 80, origin: { x: 1 }, colors: CONFETTI_COLORS });
myConfetti({ particleCount: 10, spread: 140, startVelocity: 60, origin: { y: 0.25 }, colors: CONFETTI_COLORS });
if (Date.now() < end) requestAnimationFrame(frame);
})();
} else {
myConfetti({
particleCount: 90,
spread: 80,
origin: { y: 0.55 },
colors: ["#ffd23f", "#00e5ff", "#ff2e88", "#ffffff"],
});
// anche un reveal normale ha una seconda ondata
setTimeout(() => {
myConfetti({ particleCount: 120, spread: 100, startVelocity: 40, origin: { y: 0.5 }, colors: CONFETTI_COLORS });
}, 220);
}
}
@@ -305,6 +315,7 @@
let cursor = 0;
let auto = false;
let busy = false;
let leverArmed = false;
// scommettitori (TU + banco simulato)
let players = [];
@@ -343,9 +354,11 @@
setProgress();
$("#player-name").textContent = "—";
$("#odds").innerHTML = "";
mc("Si parte! Premi START 🎰");
$("#btn-primary").textContent = "START 🎰";
$("#btn-primary").disabled = false;
mc("Tira giù la leva per far salire il primo! ⬇️");
// il bottone principale serve solo per RIGIOCA a fine partita
$("#btn-primary").style.display = "none";
$("#btn-primary").onclick = onPrimary;
armLever(true);
}
/* ---------- Rendering ---------- */
@@ -488,6 +501,7 @@
return;
}
busy = true;
armLever(false);
Audio.init();
Audio.resume();
@@ -505,12 +519,11 @@
botsPlace(odds);
mc(`Tocca a ${person}! Dove finirà? 🎲`);
// leva + spin
// animazione leva + boost monete
$("#lever").classList.add("pull");
setTimeout(() => $("#lever").classList.remove("pull"), 300);
setTimeout(() => $("#lever").classList.remove("pull"), 320);
if (window.__coinBoost) window.__coinBoost();
$("#btn-primary").disabled = true;
await spinReel(roomId);
// atterraggio
@@ -544,13 +557,17 @@
busy = false;
if (cursor >= revealQueue.length) {
$("#btn-primary").textContent = "FINE 🏁";
$("#btn-primary").disabled = false;
setTimeout(endGame, 900);
setTimeout(endGame, 1100);
} else if (auto) {
setTimeout(nextTurn, 1400);
} else {
$("#btn-primary").textContent = "SPINNA! 🎰";
$("#btn-primary").disabled = false;
if (auto) setTimeout(nextTurn, 1400);
// riarma la leva per il prossimo giro
setTimeout(() => {
if (!busy && cursor < revealQueue.length && !auto) {
armLever(true);
mc("Tira di nuovo la leva! ⬇️");
}
}, 1300);
}
}
@@ -563,16 +580,18 @@
}
function endGame() {
armLever(false);
const winner = players.slice().sort((a, b) => b.chips - a.chips)[0];
const you = players.find((p) => p.you);
mc(`🏁 Tutti sistemati! Vincitore scommesse: ${winner.name} (${winner.chips} gettoni).`);
log(`Fine. I tuoi gettoni: ${you.chips}. Miglior scommettitore: ${winner.name}.`, "win");
Audio.fanfare();
celebrate("jackpot");
$("#btn-primary").style.display = "";
$("#btn-primary").textContent = "RIGIOCA 🔁";
$("#btn-primary").disabled = false;
$("#btn-primary").onclick = () => {
newGame(false);
$("#btn-primary").onclick = onPrimary;
};
}
@@ -584,6 +603,52 @@
.join("");
}
/* ---------- Leva (trigger dei giri) ---------- */
function armLever(on) {
leverArmed = on;
const lever = $("#lever");
lever.classList.toggle("armed", on);
}
function pullAndSpin() {
if (!leverArmed || busy) return;
armLever(false);
nextTurn();
}
function bindLever() {
const lever = $("#lever");
let dragging = false;
let startY = 0;
lever.addEventListener("pointerdown", (e) => {
if (!leverArmed || busy) return;
dragging = true;
startY = e.clientY;
try {
lever.setPointerCapture(e.pointerId);
} catch (err) {}
e.preventDefault();
});
lever.addEventListener("pointermove", (e) => {
if (!dragging) return;
const dy = Math.max(0, Math.min(70, e.clientY - startY));
lever.style.transform = `rotate(${(dy / 70) * 28}deg)`;
});
const release = (e) => {
if (!dragging) return;
dragging = false;
const dy = Math.max(0, e.clientY - startY);
lever.style.transform = "";
// tap secco (dy piccolo) oppure tirata piena => parte; tirata a metà => annulla
if (dy < 8 || dy >= 26) pullAndSpin();
};
lever.addEventListener("pointerup", release);
lever.addEventListener("pointercancel", () => {
dragging = false;
$("#lever").style.transform = "";
});
}
/* ---------- Controlli ---------- */
function onPrimary() {
if (busy) return;
@@ -595,18 +660,25 @@
}
function bindControls() {
bindLever();
$("#btn-primary").onclick = onPrimary;
$("#btn-auto").onclick = (e) => {
auto = !auto;
e.currentTarget.classList.toggle("active", auto);
if (auto && !busy && cursor < revealQueue.length) nextTurn();
if (auto) {
armLever(false);
if (!busy && cursor < revealQueue.length) nextTurn();
} else if (!busy && cursor < revealQueue.length) {
armLever(true);
mc("Tira la leva! ⬇️");
}
};
$("#btn-reroll").onclick = () => {
if (busy) return;
Audio.init();
Audio.resume();
newGame(true);
mc("Nuovo sorteggio pronto! 🎲 Premi START.");
mc("Nuovo sorteggio pronto! 🎲 Tira la leva ⬇️");
};
$("#btn-sound").onclick = (e) => {
Audio.on = !Audio.on;