Add pause/resume controls and score popup
This commit is contained in:
48
main.js
48
main.js
@@ -29,6 +29,8 @@
|
||||
const gameOverEl = document.getElementById("game-over");
|
||||
const finalScoreEl = document.getElementById("final-score");
|
||||
const restartBtn = document.getElementById("restart-btn");
|
||||
const pauseBtn = document.getElementById("pause-btn");
|
||||
const pauseOverlay = document.getElementById("pause-overlay");
|
||||
|
||||
let width = sceneEl.clientWidth;
|
||||
let height = sceneEl.clientHeight;
|
||||
@@ -86,6 +88,7 @@
|
||||
let spawnTimer = null;
|
||||
let score = 0;
|
||||
let gameOver = false;
|
||||
let isPaused = false;
|
||||
|
||||
const chain = {
|
||||
active: false,
|
||||
@@ -131,6 +134,13 @@
|
||||
spawnTimer = setInterval(spawnBall, config.spawnIntervalMs);
|
||||
};
|
||||
|
||||
const stopSpawner = () => {
|
||||
if (spawnTimer) {
|
||||
clearInterval(spawnTimer);
|
||||
spawnTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
const cleanupBall = (ball) => {
|
||||
if (ball.plugin && ball.plugin.entryCheckId) {
|
||||
clearTimeout(ball.plugin.entryCheckId);
|
||||
@@ -141,14 +151,19 @@
|
||||
const triggerGameOver = () => {
|
||||
if (gameOver) return;
|
||||
gameOver = true;
|
||||
isPaused = false;
|
||||
resetChainVisuals();
|
||||
if (spawnTimer) clearInterval(spawnTimer);
|
||||
stopSpawner();
|
||||
Runner.stop(runner);
|
||||
pauseOverlay.classList.remove("visible");
|
||||
pauseBtn.textContent = "Pause";
|
||||
finalScoreEl.textContent = score;
|
||||
gameOverEl.classList.add("visible");
|
||||
};
|
||||
|
||||
const restartGame = () => {
|
||||
gameOver = false;
|
||||
isPaused = false;
|
||||
score = 0;
|
||||
resetChainVisuals();
|
||||
balls.forEach((ball) => {
|
||||
@@ -157,7 +172,10 @@
|
||||
});
|
||||
balls.length = 0;
|
||||
gameOverEl.classList.remove("visible");
|
||||
pauseOverlay.classList.remove("visible");
|
||||
pauseBtn.textContent = "Pause";
|
||||
updateHud();
|
||||
Runner.run(runner, engine);
|
||||
startSpawner();
|
||||
};
|
||||
|
||||
@@ -166,6 +184,22 @@
|
||||
body.render.strokeStyle = on ? "#f8fafc" : "#0b1222";
|
||||
};
|
||||
|
||||
const setPaused = (state) => {
|
||||
if (gameOver) return;
|
||||
if (state === isPaused) return;
|
||||
isPaused = state;
|
||||
pauseBtn.textContent = isPaused ? "Resume" : "Pause";
|
||||
pauseOverlay.classList.toggle("visible", isPaused);
|
||||
if (isPaused) {
|
||||
resetChainVisuals();
|
||||
stopSpawner();
|
||||
Runner.stop(runner);
|
||||
} else {
|
||||
startSpawner();
|
||||
Runner.run(runner, engine);
|
||||
}
|
||||
};
|
||||
|
||||
const resetChainVisuals = () => {
|
||||
chain.bodies.forEach((b) => setHighlight(b, false));
|
||||
chain.constraints.forEach((c) => World.remove(world, c));
|
||||
@@ -220,7 +254,7 @@
|
||||
};
|
||||
|
||||
const finishChain = (releasePoint) => {
|
||||
if (!chain.active || gameOver) return;
|
||||
if (!chain.active || gameOver || isPaused) return;
|
||||
if (chain.bodies.length >= config.minChain) {
|
||||
const gain = 10 * Math.pow(chain.bodies.length, 2);
|
||||
score += gain;
|
||||
@@ -264,7 +298,7 @@
|
||||
};
|
||||
|
||||
const handlePointerDown = (evt) => {
|
||||
if (gameOver) return;
|
||||
if (gameOver || isPaused) return;
|
||||
const point = getPointerPosition(evt);
|
||||
const body = pickBody(point);
|
||||
if (!body) return;
|
||||
@@ -279,7 +313,7 @@
|
||||
|
||||
const handlePointerMove = (evt) => {
|
||||
if (!chain.active) return;
|
||||
if (gameOver) return;
|
||||
if (gameOver || isPaused) return;
|
||||
const point = getPointerPosition(evt);
|
||||
chain.pointer = point;
|
||||
const body = pickBody(point);
|
||||
@@ -407,6 +441,12 @@
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
restartBtn.addEventListener("click", restartGame);
|
||||
pauseBtn.addEventListener("click", () => setPaused(!isPaused));
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") {
|
||||
setPaused(!isPaused);
|
||||
}
|
||||
});
|
||||
buildLegend();
|
||||
updateHud();
|
||||
startSpawner();
|
||||
|
||||
Reference in New Issue
Block a user