diff --git a/game.js b/game.js index 70205fc..8bf36b3 100644 --- a/game.js +++ b/game.js @@ -28,10 +28,17 @@ const closeRulesBtn = document.getElementById('closeRulesBtn'); const menuLeaderboard = document.getElementById('menuLeaderboard'); const leaderboardContainer = document.getElementById('leaderboardContainer'); const closeLeaderboardBtn = document.getElementById('closeLeaderboardBtn'); +const fullscreenBtn = document.getElementById('fullscreenBtn'); + +// Fonction pour vérifier si on est en mode plein écran +function isFullscreen() { + return !!(document.fullscreenElement || document.webkitFullscreenElement || + document.mozFullScreenElement || document.msFullscreenElement); +} let usernameConfirmed = false; -const CELL_SIZE = 20; +const CELL_SIZE = 25; const COLS = 30; const ROWS = 30; @@ -360,8 +367,8 @@ class Pacman { ghost.vulnerableTimer = vulnerableTime; } - // Afficher l'indicateur de poursuite - if (pursuitIndicator) { + // Afficher l'indicateur de poursuite (sauf en mode plein écran) + if (pursuitIndicator && !isFullscreen()) { pursuitIndicator.style.display = 'block'; } @@ -1314,7 +1321,7 @@ function gameLoop() { ghost.vulnerableTimer = FRENZY_DURATION; } if (frenzyIndicator) frenzyIndicator.style.display = 'block'; - if (pursuitIndicator) pursuitIndicator.style.display = 'block'; + if (pursuitIndicator && !isFullscreen()) pursuitIndicator.style.display = 'block'; } } else { frenzyTimer--; @@ -1339,13 +1346,16 @@ function gameLoop() { pacman.update(); pacman.draw(); - // Mettre à jour l'indicateur de poursuite - if (pursuitIndicator && (cherryEatenTimer > 0 || frenzyModeActive)) { + // Mettre à jour l'indicateur de poursuite (masquer en mode plein écran) + if (isFullscreen() && pursuitIndicator) { + pursuitIndicator.style.display = 'none'; + } else if (pursuitIndicator && (cherryEatenTimer > 0 || frenzyModeActive) && !isFullscreen()) { const timer = frenzyModeActive ? frenzyTimer : cherryEatenTimer; const seconds = Math.ceil(timer / 60); if (pursuitTimerElement) { pursuitTimerElement.textContent = seconds; } + pursuitIndicator.style.display = 'block'; } else if (pursuitIndicator && !frenzyModeActive) { pursuitIndicator.style.display = 'none'; } @@ -1757,6 +1767,77 @@ function placeBonuses() { } } +// === REDIMENSIONNEMENT ADAPTATIF DU CANVAS === +function resizeCanvas() { + if (!gameWrapper || gameWrapper.style.display === 'none') { + return; // Ne pas redimensionner si le jeu n'est pas visible + } + + const container = document.querySelector('.container'); + const gameHeader = document.querySelector('.game-header'); + const gameInfo = document.querySelector('.game-info'); + const userInput = document.querySelector('.user-input-section'); + const powerUps = document.querySelector('.power-ups-display'); + const frenzyIndicator = document.querySelector('.frenzy-indicator'); + const pursuitIndicator = document.querySelector('.pursuit-indicator'); + const instructions = document.querySelector('.instructions'); + const leaderboard = document.querySelector('.game-leaderboard'); + + if (!container || !canvas) return; + + // Calculer l'espace disponible en hauteur + const windowHeight = window.innerHeight; + const windowWidth = window.innerWidth; + + // Hauteur des éléments autour du canvas + let usedHeight = 0; + if (gameHeader) usedHeight += gameHeader.offsetHeight + 20; + if (userInput && userInput.offsetHeight > 0) usedHeight += userInput.offsetHeight + 10; + if (gameInfo) usedHeight += gameInfo.offsetHeight + 20; + if (powerUps && powerUps.offsetHeight > 0) usedHeight += powerUps.offsetHeight + 10; + if (frenzyIndicator && frenzyIndicator.offsetHeight > 0 && frenzyIndicator.style.display !== 'none') { + usedHeight += frenzyIndicator.offsetHeight + 10; + } + if (pursuitIndicator && pursuitIndicator.offsetHeight > 0 && pursuitIndicator.style.display !== 'none') { + usedHeight += pursuitIndicator.offsetHeight + 10; + } + if (instructions) usedHeight += instructions.offsetHeight + 20; + + // Padding du container (30px top + 30px bottom) + usedHeight += 60; + + // Marges et espacement + usedHeight += 40; + + // Largeur disponible (en tenant compte du leaderboard à droite si visible) + let usedWidth = 0; + const containerPadding = 60; // 30px left + 30px right + const gaps = 60; // Espacement entre éléments + + if (leaderboard && window.innerWidth > 1200) { + const leaderboardRect = leaderboard.getBoundingClientRect(); + if (leaderboardRect.width > 0) { + usedWidth += leaderboardRect.width + 30; // + gap + } + } + usedWidth += containerPadding + gaps; + + const availableHeight = windowHeight - usedHeight; + const availableWidth = windowWidth - usedWidth; + + // La taille du canvas sera le minimum entre hauteur et largeur disponible + // Utilise 95% de l'espace disponible avec une taille minimale de 400px + const maxSize = Math.min(availableHeight, availableWidth); + const minSize = 400; + const canvasDisplaySize = Math.max(minSize, Math.min(maxSize * 0.95, 1200)); + + // Appliquer la taille au canvas via CSS + canvas.style.width = canvasDisplaySize + 'px'; + canvas.style.height = canvasDisplaySize + 'px'; + canvas.style.maxWidth = '100%'; + canvas.style.maxHeight = 'calc(100vh - ' + usedHeight + 'px)'; +} + function initGame() { resetUsernameInput(); // Réinitialiser le champ nom @@ -1822,6 +1903,10 @@ function initGame() { placeBonuses(); countDots(); updateGameLeaderboard(); + + // Redimensionner le canvas après l'initialisation + setTimeout(resizeCanvas, 100); + gameLoop(); } @@ -2267,7 +2352,11 @@ playBtn.addEventListener('click', () => { resetUsernameInput(); // Toujours initialiser le jeu quand on clique sur JOUER gameRunning = false; // S'assurer que le jeu est arrêté - initGame(); + // Attendre un peu pour que le DOM soit rendu avant de redimensionner + setTimeout(() => { + initGame(); + resizeCanvas(); + }, 50); }); // Retour au menu depuis le jeu @@ -2385,3 +2474,80 @@ function updateBestScore() { updateMenuLeaderboard(); updateBestScore(); +// Appeler au chargement, au redimensionnement et quand le jeu devient visible +window.addEventListener('resize', () => { + if (gameWrapper && gameWrapper.style.display !== 'none') { + resizeCanvas(); + } +}); + +// Redimensionner quand le jeu est affiché +if (gameWrapper) { + const observer = new MutationObserver(() => { + if (gameWrapper && gameWrapper.style.display !== 'none') { + // Attendre un peu pour que le DOM soit complètement rendu + setTimeout(resizeCanvas, 100); + } + }); + observer.observe(gameWrapper, { attributes: true, attributeFilter: ['style'] }); +} + +// === GESTION DU PLEIN ÉCRAN === +function toggleFullscreen() { + const gameWrapper = document.getElementById('gameWrapper'); + + if (!document.fullscreenElement && !document.webkitFullscreenElement && + !document.mozFullScreenElement && !document.msFullscreenElement) { + // Entrer en plein écran + if (gameWrapper.requestFullscreen) { + gameWrapper.requestFullscreen(); + } else if (gameWrapper.webkitRequestFullscreen) { + gameWrapper.webkitRequestFullscreen(); + } else if (gameWrapper.mozRequestFullScreen) { + gameWrapper.mozRequestFullScreen(); + } else if (gameWrapper.msRequestFullscreen) { + gameWrapper.msRequestFullscreen(); + } + } else { + // Quitter le plein écran + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } + } +} + +function updateFullscreenButton() { + const isFullscreenMode = document.fullscreenElement || document.webkitFullscreenElement || + document.mozFullScreenElement || document.msFullscreenElement; + + if (fullscreenBtn) { + fullscreenBtn.textContent = isFullscreenMode ? '✕ Sortir' : '⛶ Plein écran'; + fullscreenBtn.title = isFullscreenMode ? 'Quitter le plein écran' : 'Plein écran'; + } + + // Cacher l'indicateur de poursuite en mode plein écran + if (isFullscreenMode && pursuitIndicator) { + pursuitIndicator.style.display = 'none'; + } + + // Redimensionner le canvas après changement de mode plein écran + setTimeout(resizeCanvas, 100); +} + +// Ajouter l'event listener au bouton +if (fullscreenBtn) { + fullscreenBtn.addEventListener('click', toggleFullscreen); +} + +// Écouter les changements de mode plein écran +document.addEventListener('fullscreenchange', updateFullscreenButton); +document.addEventListener('webkitfullscreenchange', updateFullscreenButton); +document.addEventListener('mozfullscreenchange', updateFullscreenButton); +document.addEventListener('MSFullscreenChange', updateFullscreenButton); + diff --git a/index.html b/index.html index 709b1a1..70b7ccb 100644 --- a/index.html +++ b/index.html @@ -38,20 +38,21 @@

OULVIC

+
-
- - +
+ + -
-
-
Score: 0
-
Niveau: 1
-
Vies:
+
+
+
Score: 0
+
Niveau: 1
+
Vies:
Pastilles: 0
-
Prêt à jouer
-
+
Prêt à jouer
+
@@ -63,7 +64,7 @@ - +
@@ -75,8 +76,8 @@
-
-

Utilisez les flèches directionnelles pour déplacer Oulvic

+
+

Utilisez les flèches directionnelles pour déplacer Oulvic

@@ -97,20 +98,20 @@

🏆 Classement

-
+ +
- + + diff --git a/style.css b/style.css index e199f1c..da3bd5a 100644 --- a/style.css +++ b/style.css @@ -323,6 +323,26 @@ body::after { transform: translateX(-3px); } +.fullscreen-btn { + padding: 10px 20px; + font-size: 0.7em; + font-family: 'Press Start 2P', cursive; + background: rgba(255, 255, 255, 0.1); + color: #ffd700; + border: 2px solid #ffd700; + border-radius: 10px; + cursor: pointer; + transition: all 0.3s; + line-height: 1.2; + white-space: nowrap; +} + +.fullscreen-btn:hover { + background: rgba(255, 215, 0, 0.2); + transform: scale(1.1); + box-shadow: 0 0 10px rgba(255, 215, 0, 0.5); +} + /* === MODAL CLASSEMENT === */ .leaderboard-modal { position: fixed; @@ -695,6 +715,14 @@ h1 { 0 0 40px rgba(255, 215, 0, 0.3), inset 0 0 60px rgba(0, 0, 255, 0.1); animation: canvasGlow 3s ease-in-out infinite alternate; + max-width: 100%; + max-height: 90vh; + width: auto; + height: auto; + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; } /* === INPUT UTILISATEUR === */