confetti
This commit is contained in:
124
app.js
124
app.js
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user