/* ============================================================ TAB SHOOTER — Popup (Overlay) Controller Nutzt die geteilte engine.js. ============================================================ */ import { TabShooterGame, loadTabs, clamp } from "./engine.js"; const CANVAS_W = 420; const CANVAS_H = 600; // ---------- DOM ---------- const canvas = document.getElementById("game-canvas"); const screens = { start: document.getElementById("start-screen"), game: document.getElementById("game-screen"), gameover: document.getElementById("gameover-screen"), empty: document.getElementById("empty-screen"), }; const els = { hsValue: document.getElementById("hs-value"), hudScore: document.getElementById("hud-score"), hudLives: document.getElementById("hud-lives"), hudTabs: document.getElementById("hud-tabs"), hudPowerups: document.getElementById("hud-powerups"), resultTabs: document.getElementById("result-tabs"), resultScore: document.getElementById("result-score"), resultHighscore: document.getElementById("result-highscore"), newRecord: document.getElementById("new-record"), }; // ---------- STATE ---------- let game = null; let highscore = 0; let selectedScope = "current"; // Merke dir den Tab, von dem aus das Popup geöffnet wurde (den aktiven Tab // im zuletzt fokussierten Fenster). Wird dieser Tab geschlossen, reißt Chrome // auch das Popup mit sich -> Spiel beendet sich ohne Vorwarnung. Wir schließen // ihn daher per excludeTabId von der Zielliste aus. let openerTabId = null; chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { if (tabs && tabs[0]) openerTabId = tabs[0].id; }); // ---------- SCREEN HELPERS ---------- function showScreen(name) { Object.values(screens).forEach((s) => s.classList.remove("visible")); screens[name].classList.add("visible"); } // ---------- HIGHSCORE ---------- async function loadHighscore() { const data = await chrome.storage.local.get("highscore"); highscore = data.highscore || 0; els.hsValue.textContent = highscore; } async function saveHighscore(value) { await chrome.storage.local.set({ highscore: value }); highscore = value; } // ---------- HUD CALLBACKS ---------- const hudCallbacks = { onScore: (s) => (els.hudScore.textContent = s), onLives: (l) => (els.hudLives.textContent = "❤️".repeat(Math.max(0, l))), onTabs: (t) => (els.hudTabs.textContent = t), onPowerups: (g) => { let html = ""; if (g.shield > 0) html += "🛡️"; if (g.tripleShot > 0) html += "🔫"; if (g.rapidFire > 0) html += "⚡"; els.hudPowerups.innerHTML = html; }, onGameOver: ({ score }) => { const isNewRecord = score > highscore; if (isNewRecord) saveHighscore(score); els.resultTabs.textContent = game.tabsDestroyed; els.resultScore.textContent = score; els.resultHighscore.textContent = Math.max(highscore, score); els.newRecord.classList.toggle("hidden", !isNewRecord); showScreen("gameover"); }, }; // ---------- GAME START ---------- async function startNewGame() { // Den Opener-Tab (aktuellen Tab, der das Popup trägt) nie als Ziel zulassen, // da sein Schließen das Popup und damit das Spiel sofort beenden würde. const tabs = await loadTabs(selectedScope, openerTabId); if (tabs.length === 0) { showScreen("empty"); return; } showScreen("game"); els.hudScore.textContent = "0"; els.hudLives.textContent = "❤️❤️❤️"; els.hudTabs.textContent = tabs.length; els.hudPowerups.innerHTML = ""; game = new TabShooterGame(canvas, {}, hudCallbacks); await game.init(tabs); game.start(); } // ---------- EVENT WIRING ---------- document.querySelectorAll(".scope-btn").forEach((btn) => { btn.addEventListener("click", () => { document.querySelectorAll(".scope-btn").forEach((b) => b.classList.remove("active")); btn.classList.add("active"); selectedScope = btn.dataset.scope; }); }); document.getElementById("start-btn").addEventListener("click", startNewGame); document.getElementById("replay-btn").addEventListener("click", startNewGame); document.getElementById("menu-btn").addEventListener("click", () => { if (game) game.stop(); loadHighscore(); showScreen("start"); }); document.getElementById("empty-menu-btn").addEventListener("click", () => { loadHighscore(); showScreen("start"); }); // ---------- FULLSCREEN BUTTON ---------- document.getElementById("fullscreen-btn").addEventListener("click", async () => { // Open the fullscreen game in a new tab. The popup will close automatically. await chrome.tabs.create({ url: chrome.runtime.getURL("game.html") }); window.close(); }); // ---------- INIT ---------- loadHighscore();