confetti
This commit is contained in:
124
app.js
124
app.js
@@ -92,23 +92,33 @@
|
|||||||
? confetti.create($("#confetti"), { resize: true, useWorker: true })
|
? 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) {
|
function celebrate(kind) {
|
||||||
|
bigBurst();
|
||||||
if (kind === "jackpot") {
|
if (kind === "jackpot") {
|
||||||
const end = Date.now() + 1400;
|
// pioggia prolungata extra per il jackpot
|
||||||
const colors = ["#ffd23f", "#ff9e00", "#ff2e88", "#00e5ff", "#ffffff"];
|
const end = Date.now() + 2600;
|
||||||
(function frame() {
|
(function frame() {
|
||||||
myConfetti({ particleCount: 6, angle: 60, spread: 70, origin: { x: 0 }, colors });
|
myConfetti({ particleCount: 12, angle: 60, spread: 80, origin: { x: 0 }, colors: CONFETTI_COLORS });
|
||||||
myConfetti({ particleCount: 6, angle: 120, spread: 70, origin: { x: 1 }, colors });
|
myConfetti({ particleCount: 12, angle: 120, spread: 80, origin: { x: 1 }, colors: CONFETTI_COLORS });
|
||||||
myConfetti({ particleCount: 4, spread: 120, startVelocity: 55, origin: { y: 0.3 }, colors });
|
myConfetti({ particleCount: 10, spread: 140, startVelocity: 60, origin: { y: 0.25 }, colors: CONFETTI_COLORS });
|
||||||
if (Date.now() < end) requestAnimationFrame(frame);
|
if (Date.now() < end) requestAnimationFrame(frame);
|
||||||
})();
|
})();
|
||||||
} else {
|
} else {
|
||||||
myConfetti({
|
// anche un reveal normale ha una seconda ondata
|
||||||
particleCount: 90,
|
setTimeout(() => {
|
||||||
spread: 80,
|
myConfetti({ particleCount: 120, spread: 100, startVelocity: 40, origin: { y: 0.5 }, colors: CONFETTI_COLORS });
|
||||||
origin: { y: 0.55 },
|
}, 220);
|
||||||
colors: ["#ffd23f", "#00e5ff", "#ff2e88", "#ffffff"],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +315,7 @@
|
|||||||
let cursor = 0;
|
let cursor = 0;
|
||||||
let auto = false;
|
let auto = false;
|
||||||
let busy = false;
|
let busy = false;
|
||||||
|
let leverArmed = false;
|
||||||
|
|
||||||
// scommettitori (TU + banco simulato)
|
// scommettitori (TU + banco simulato)
|
||||||
let players = [];
|
let players = [];
|
||||||
@@ -343,9 +354,11 @@
|
|||||||
setProgress();
|
setProgress();
|
||||||
$("#player-name").textContent = "—";
|
$("#player-name").textContent = "—";
|
||||||
$("#odds").innerHTML = "";
|
$("#odds").innerHTML = "";
|
||||||
mc("Si parte! Premi START 🎰");
|
mc("Tira giù la leva per far salire il primo! ⬇️");
|
||||||
$("#btn-primary").textContent = "START 🎰";
|
// il bottone principale serve solo per RIGIOCA a fine partita
|
||||||
$("#btn-primary").disabled = false;
|
$("#btn-primary").style.display = "none";
|
||||||
|
$("#btn-primary").onclick = onPrimary;
|
||||||
|
armLever(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Rendering ---------- */
|
/* ---------- Rendering ---------- */
|
||||||
@@ -488,6 +501,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
busy = true;
|
busy = true;
|
||||||
|
armLever(false);
|
||||||
Audio.init();
|
Audio.init();
|
||||||
Audio.resume();
|
Audio.resume();
|
||||||
|
|
||||||
@@ -505,12 +519,11 @@
|
|||||||
botsPlace(odds);
|
botsPlace(odds);
|
||||||
mc(`Tocca a ${person}! Dove finirà? 🎲`);
|
mc(`Tocca a ${person}! Dove finirà? 🎲`);
|
||||||
|
|
||||||
// leva + spin
|
// animazione leva + boost monete
|
||||||
$("#lever").classList.add("pull");
|
$("#lever").classList.add("pull");
|
||||||
setTimeout(() => $("#lever").classList.remove("pull"), 300);
|
setTimeout(() => $("#lever").classList.remove("pull"), 320);
|
||||||
if (window.__coinBoost) window.__coinBoost();
|
if (window.__coinBoost) window.__coinBoost();
|
||||||
|
|
||||||
$("#btn-primary").disabled = true;
|
|
||||||
await spinReel(roomId);
|
await spinReel(roomId);
|
||||||
|
|
||||||
// atterraggio
|
// atterraggio
|
||||||
@@ -544,13 +557,17 @@
|
|||||||
busy = false;
|
busy = false;
|
||||||
|
|
||||||
if (cursor >= revealQueue.length) {
|
if (cursor >= revealQueue.length) {
|
||||||
$("#btn-primary").textContent = "FINE 🏁";
|
setTimeout(endGame, 1100);
|
||||||
$("#btn-primary").disabled = false;
|
} else if (auto) {
|
||||||
setTimeout(endGame, 900);
|
setTimeout(nextTurn, 1400);
|
||||||
} else {
|
} else {
|
||||||
$("#btn-primary").textContent = "SPINNA! 🎰";
|
// riarma la leva per il prossimo giro
|
||||||
$("#btn-primary").disabled = false;
|
setTimeout(() => {
|
||||||
if (auto) setTimeout(nextTurn, 1400);
|
if (!busy && cursor < revealQueue.length && !auto) {
|
||||||
|
armLever(true);
|
||||||
|
mc("Tira di nuovo la leva! ⬇️");
|
||||||
|
}
|
||||||
|
}, 1300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,16 +580,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function endGame() {
|
function endGame() {
|
||||||
|
armLever(false);
|
||||||
const winner = players.slice().sort((a, b) => b.chips - a.chips)[0];
|
const winner = players.slice().sort((a, b) => b.chips - a.chips)[0];
|
||||||
const you = players.find((p) => p.you);
|
const you = players.find((p) => p.you);
|
||||||
mc(`🏁 Tutti sistemati! Vincitore scommesse: ${winner.name} (${winner.chips} gettoni).`);
|
mc(`🏁 Tutti sistemati! Vincitore scommesse: ${winner.name} (${winner.chips} gettoni).`);
|
||||||
log(`Fine. I tuoi gettoni: ${you.chips}. Miglior scommettitore: ${winner.name}.`, "win");
|
log(`Fine. I tuoi gettoni: ${you.chips}. Miglior scommettitore: ${winner.name}.`, "win");
|
||||||
|
Audio.fanfare();
|
||||||
celebrate("jackpot");
|
celebrate("jackpot");
|
||||||
|
$("#btn-primary").style.display = "";
|
||||||
$("#btn-primary").textContent = "RIGIOCA 🔁";
|
$("#btn-primary").textContent = "RIGIOCA 🔁";
|
||||||
$("#btn-primary").disabled = false;
|
$("#btn-primary").disabled = false;
|
||||||
$("#btn-primary").onclick = () => {
|
$("#btn-primary").onclick = () => {
|
||||||
newGame(false);
|
newGame(false);
|
||||||
$("#btn-primary").onclick = onPrimary;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,6 +603,52 @@
|
|||||||
.join("");
|
.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 ---------- */
|
/* ---------- Controlli ---------- */
|
||||||
function onPrimary() {
|
function onPrimary() {
|
||||||
if (busy) return;
|
if (busy) return;
|
||||||
@@ -595,18 +660,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function bindControls() {
|
function bindControls() {
|
||||||
|
bindLever();
|
||||||
$("#btn-primary").onclick = onPrimary;
|
$("#btn-primary").onclick = onPrimary;
|
||||||
$("#btn-auto").onclick = (e) => {
|
$("#btn-auto").onclick = (e) => {
|
||||||
auto = !auto;
|
auto = !auto;
|
||||||
e.currentTarget.classList.toggle("active", 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 = () => {
|
$("#btn-reroll").onclick = () => {
|
||||||
if (busy) return;
|
if (busy) return;
|
||||||
Audio.init();
|
Audio.init();
|
||||||
Audio.resume();
|
Audio.resume();
|
||||||
newGame(true);
|
newGame(true);
|
||||||
mc("Nuovo sorteggio pronto! 🎲 Premi START.");
|
mc("Nuovo sorteggio pronto! 🎲 Tira la leva ⬇️");
|
||||||
};
|
};
|
||||||
$("#btn-sound").onclick = (e) => {
|
$("#btn-sound").onclick = (e) => {
|
||||||
Audio.on = !Audio.on;
|
Audio.on = !Audio.on;
|
||||||
|
|||||||
Reference in New Issue
Block a user