Szabo Ivan c168da359e implement complete frontend:
- add lobby, game, leaderboard, results pages
- add scripts: storage, lobby, game, drawing, scoring, countries
- add styles: main, lobby, game
- unify header/footer across all pages
- show lobby name in lobby view
- remove clear board from leaderboard
2026-05-05 13:01:14 +02:00

159 lines
4.1 KiB
JavaScript

// game.js — round management, timer, submit
const TOTAL_ROUNDS = 3;
const ROUND_DURATION = 60; // seconds
let roundCountries = [];
let currentRound = 0;
let scores = [];
let timerInterval = null;
let timeLeft = ROUND_DURATION;
// ── DOM refs
const elCountryName = document.getElementById("country-name");
const elCountryHint = document.getElementById("country-hint");
const elRoundNum = document.getElementById("round-num");
const elTimerNum = document.getElementById("timer-num");
const elTimerBar = document.getElementById("timer-bar");
const elBtnClear = document.getElementById("btn-clear");
const elBtnSubmit = document.getElementById("btn-submit");
const elCanvas = document.getElementById("draw-canvas");
// ── Init
async function initGame() {
await Countries.loadCountries();
roundCountries = Countries.getRandomCountries(TOTAL_ROUNDS);
currentRound = 0;
scores = [];
startRound();
}
// ── Round
function startRound() {
const country = roundCountries[currentRound];
// Update UI
elRoundNum.textContent = currentRound + 1;
elCountryName.textContent = country.name;
elCountryHint.textContent = country.hint || "";
// Round pips
if (typeof window.updateRoundPips === "function") {
window.updateRoundPips(currentRound + 1);
}
// Reset canvas placeholder
document.getElementById("canvas-wrap")?.classList.remove("has-drawing");
// Cities on canvas
Drawing.clear();
Drawing.setCities(country.cities || []);
// Timer
timeLeft = ROUND_DURATION;
updateTimerUI();
clearInterval(timerInterval);
timerInterval = setInterval(tickTimer, 1000);
// Button state
elBtnSubmit.disabled = false;
elBtnSubmit.textContent = currentRound < TOTAL_ROUNDS - 1
? "Submit & Next Round →"
: "Submit & See Results →";
}
function tickTimer() {
timeLeft--;
updateTimerUI();
if (timeLeft <= 0) {
clearInterval(timerInterval);
submitRound(true); // auto-submit
}
}
function updateTimerUI() {
elTimerNum.textContent = timeLeft;
const pct = (timeLeft / ROUND_DURATION) * 100;
elTimerBar.style.width = pct + "%";
// Colour shift
if (timeLeft <= 10) {
elTimerBar.style.background = "#e05c5c";
elTimerNum.style.color = "#e05c5c";
} else if (timeLeft <= 20) {
elTimerBar.style.background = "#f0b429";
elTimerNum.style.color = "#f0b429";
} else {
elTimerBar.style.background = "";
elTimerNum.style.color = "";
}
}
function submitRound(auto = false) {
clearInterval(timerInterval);
elBtnSubmit.disabled = true;
const points = Drawing.getPoints();
const score = Scoring.calculateScore(points);
scores.push(score);
// Update sidebar score row
if (typeof window.updateScoreDisplay === "function") {
window.updateScoreDisplay(currentRound, score);
}
// Flash score feedback
showScoreFeedback(score);
const delay = auto ? 400 : 1200;
setTimeout(() => {
if (currentRound < TOTAL_ROUNDS - 1) {
currentRound++;
startRound();
} else {
finishGame();
}
}, delay);
}
function showScoreFeedback(score) {
const grade = Scoring.getGrade(score);
const el = document.getElementById("score-feedback");
el.textContent = `${score}% ${grade.label}`;
el.style.color = grade.color;
el.style.opacity = "1";
el.style.transform = "translateY(0)";
setTimeout(() => {
el.style.opacity = "0";
el.style.transform = "translateY(-10px)";
}, 900);
}
function finishGame() {
const totalScore = scores.reduce((a, b) => a + b, 0);
const state = {
currentRound: TOTAL_ROUNDS,
scores,
totalScore,
countries: roundCountries.map(c => c.name),
};
Storage.saveGameState(state);
// Save to leaderboard
Storage.saveLeaderboard({
name: Storage.getPlayerName(),
totalScore,
scores,
date: new Date().toISOString(),
});
location.href = "results.html";
}
// ── Events
elBtnClear.addEventListener("click", () => Drawing.clear());
elBtnSubmit.addEventListener("click", () => submitRound(false));
// ── Boot
window.addEventListener("DOMContentLoaded", initGame);