personalisation du personnage
This commit is contained in:
248
game.js
248
game.js
@ -13,6 +13,9 @@ const finalScoreElement = document.getElementById('finalScore');
|
||||
const finalLevelElement = document.getElementById('finalLevel');
|
||||
const overlayRestartBtn = document.getElementById('overlayRestartBtn');
|
||||
const confirmUsernameBtn = document.getElementById('confirmUsernameBtn');
|
||||
const gameOverUsernameInput = document.getElementById('gameOverUsername');
|
||||
const saveScoreBtn = document.getElementById('saveScoreBtn');
|
||||
const scoreSavedMsg = document.getElementById('scoreSavedMsg');
|
||||
|
||||
// === GESTION DU MENU ===
|
||||
const mainMenu = document.getElementById('mainMenu');
|
||||
@ -29,6 +32,12 @@ const menuLeaderboard = document.getElementById('menuLeaderboard');
|
||||
const leaderboardContainer = document.getElementById('leaderboardContainer');
|
||||
const closeLeaderboardBtn = document.getElementById('closeLeaderboardBtn');
|
||||
const fullscreenBtn = document.getElementById('fullscreenBtn');
|
||||
const customizeBtn = document.getElementById('customizeBtn');
|
||||
const customizeModal = document.getElementById('customizeModal');
|
||||
const closeCustomizeBtn = document.getElementById('closeCustomizeBtn');
|
||||
const saveCustomizeBtn = document.getElementById('saveCustomizeBtn');
|
||||
const playerPreviewCanvas = document.getElementById('playerPreviewCanvas');
|
||||
const colorOptions = document.querySelectorAll('.color-option');
|
||||
|
||||
// Fonction pour vérifier si on est en mode plein écran
|
||||
function isFullscreen() {
|
||||
@ -37,6 +46,10 @@ function isFullscreen() {
|
||||
}
|
||||
|
||||
let usernameConfirmed = false;
|
||||
let gameOverUsername = null;
|
||||
|
||||
// Personnalisation du joueur
|
||||
let playerColor = localStorage.getItem('playerColor') || 'rainbow';
|
||||
|
||||
const CELL_SIZE = 25;
|
||||
const COLS = 30;
|
||||
@ -240,7 +253,7 @@ let traps = [];
|
||||
let specialZones = [];
|
||||
|
||||
class Pacman {
|
||||
constructor() {
|
||||
constructor(color = null) {
|
||||
this.x = 14;
|
||||
this.y = 23;
|
||||
this.direction = 0;
|
||||
@ -252,6 +265,7 @@ class Pacman {
|
||||
this.pixelX = this.x * CELL_SIZE + CELL_SIZE / 2;
|
||||
this.pixelY = this.y * CELL_SIZE + CELL_SIZE / 2;
|
||||
this.colorAnimation = 0;
|
||||
this.color = color || playerColor;
|
||||
}
|
||||
|
||||
update() {
|
||||
@ -456,8 +470,22 @@ class Pacman {
|
||||
const rotation = [Math.PI * 1.5, 0, Math.PI * 0.5, Math.PI];
|
||||
ctx.rotate(rotation[this.direction]);
|
||||
|
||||
const hue = (this.colorAnimation * 180 / Math.PI) % 360;
|
||||
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
|
||||
// Utiliser la couleur personnalisée
|
||||
if (this.color === 'rainbow') {
|
||||
const hue = (this.colorAnimation * 180 / Math.PI) % 360;
|
||||
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
|
||||
} else {
|
||||
const colorMap = {
|
||||
'yellow': '#ffd700',
|
||||
'red': '#ff4444',
|
||||
'blue': '#4444ff',
|
||||
'green': '#44ff44',
|
||||
'purple': '#aa44ff',
|
||||
'orange': '#ff8844',
|
||||
'pink': '#ff44aa'
|
||||
};
|
||||
ctx.fillStyle = colorMap[this.color] || '#ffd700';
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
@ -1237,7 +1265,7 @@ function checkCollisions() {
|
||||
gameRunning = false;
|
||||
statusElement.textContent = 'Game Over !';
|
||||
showGameOver();
|
||||
saveScore();
|
||||
// Le score sera sauvegardé quand l'utilisateur clique sur "Sauvegarder"
|
||||
} else {
|
||||
restartCurrentLevel();
|
||||
}
|
||||
@ -1954,9 +1982,15 @@ function getScores() {
|
||||
return scoresJson ? JSON.parse(scoresJson) : [];
|
||||
}
|
||||
|
||||
function saveScore() {
|
||||
function saveScore(usernameForScore = null) {
|
||||
let username;
|
||||
if (!usernameConfirmed) {
|
||||
|
||||
// Priorité au nom passé en paramètre, puis au nom du Game Over, puis au nom confirmé, sinon "Anonyme"
|
||||
if (usernameForScore) {
|
||||
username = usernameForScore.trim() || 'Anonyme';
|
||||
} else if (gameOverUsername) {
|
||||
username = gameOverUsername.trim() || 'Anonyme';
|
||||
} else if (!usernameConfirmed) {
|
||||
username = 'Anonyme';
|
||||
} else {
|
||||
username = usernameInput.value.trim() || 'Anonyme';
|
||||
@ -2127,6 +2161,21 @@ usernameInput.addEventListener('keypress', (e) => {
|
||||
function showGameOver() {
|
||||
finalScoreElement.textContent = score;
|
||||
finalLevelElement.textContent = level;
|
||||
|
||||
// Réinitialiser le champ de nom et cacher le message
|
||||
if (gameOverUsernameInput) {
|
||||
gameOverUsernameInput.value = usernameInput.value.trim() || '';
|
||||
gameOverUsernameInput.disabled = false;
|
||||
gameOverUsernameInput.focus();
|
||||
}
|
||||
if (saveScoreBtn) {
|
||||
saveScoreBtn.disabled = false;
|
||||
}
|
||||
if (scoreSavedMsg) {
|
||||
scoreSavedMsg.style.display = 'none';
|
||||
}
|
||||
gameOverUsername = null; // Réinitialiser
|
||||
|
||||
gameOverlay.classList.add('active');
|
||||
restartBtn.style.display = 'block';
|
||||
}
|
||||
@ -2135,7 +2184,39 @@ function hideGameOver() {
|
||||
gameOverlay.classList.remove('active');
|
||||
}
|
||||
|
||||
// Sauvegarder le score avec le nom du Game Over
|
||||
if (saveScoreBtn && gameOverUsernameInput) {
|
||||
saveScoreBtn.addEventListener('click', () => {
|
||||
const username = gameOverUsernameInput.value.trim();
|
||||
if (username.length === 0) {
|
||||
alert('Veuillez entrer un nom d\'utilisateur !');
|
||||
gameOverUsernameInput.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
gameOverUsername = username;
|
||||
saveScore(username);
|
||||
|
||||
// Afficher le message de confirmation
|
||||
if (scoreSavedMsg) {
|
||||
scoreSavedMsg.style.display = 'block';
|
||||
}
|
||||
|
||||
// Désactiver le champ et le bouton
|
||||
gameOverUsernameInput.disabled = true;
|
||||
saveScoreBtn.disabled = true;
|
||||
});
|
||||
|
||||
// Permettre de sauvegarder avec la touche Entrée
|
||||
gameOverUsernameInput.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter' && !saveScoreBtn.disabled) {
|
||||
saveScoreBtn.click();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
overlayRestartBtn.addEventListener('click', () => {
|
||||
hideGameOver();
|
||||
initGame();
|
||||
});
|
||||
|
||||
@ -2404,6 +2485,161 @@ if (rulesModal) {
|
||||
});
|
||||
}
|
||||
|
||||
// === GESTION DU MODAL DE PERSONNALISATION ===
|
||||
let selectedColor = playerColor;
|
||||
|
||||
// Ouvrir le modal de personnalisation
|
||||
if (customizeBtn) {
|
||||
customizeBtn.addEventListener('click', () => {
|
||||
if (customizeModal) {
|
||||
customizeModal.style.display = 'flex';
|
||||
selectedColor = playerColor;
|
||||
updateColorSelection();
|
||||
updatePlayerPreview();
|
||||
startPreviewAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fermer le modal de personnalisation
|
||||
if (closeCustomizeBtn) {
|
||||
closeCustomizeBtn.addEventListener('click', () => {
|
||||
if (customizeModal) {
|
||||
customizeModal.style.display = 'none';
|
||||
stopPreviewAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fermer en cliquant en dehors du modal
|
||||
if (customizeModal) {
|
||||
customizeModal.addEventListener('click', (e) => {
|
||||
if (e.target === customizeModal) {
|
||||
customizeModal.style.display = 'none';
|
||||
stopPreviewAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Gérer la sélection de couleur
|
||||
if (colorOptions) {
|
||||
colorOptions.forEach(option => {
|
||||
option.addEventListener('click', () => {
|
||||
selectedColor = option.getAttribute('data-color');
|
||||
updateColorSelection();
|
||||
updatePlayerPreview();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Mettre à jour la sélection visuelle
|
||||
function updateColorSelection() {
|
||||
if (colorOptions) {
|
||||
colorOptions.forEach(option => {
|
||||
if (option.getAttribute('data-color') === selectedColor) {
|
||||
option.classList.add('active');
|
||||
} else {
|
||||
option.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Prévisualisation du joueur
|
||||
let previewAnimationId = null;
|
||||
function startPreviewAnimation() {
|
||||
if (!playerPreviewCanvas) return;
|
||||
|
||||
let angle = 0;
|
||||
let mouthOpen = true;
|
||||
|
||||
function animate() {
|
||||
if (!playerPreviewCanvas) return;
|
||||
const ctx = playerPreviewCanvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, playerPreviewCanvas.width, playerPreviewCanvas.height);
|
||||
|
||||
// Fond
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillRect(0, 0, playerPreviewCanvas.width, playerPreviewCanvas.height);
|
||||
|
||||
// Dessiner le joueur au centre
|
||||
ctx.save();
|
||||
ctx.translate(playerPreviewCanvas.width / 2, playerPreviewCanvas.height / 2);
|
||||
|
||||
// Couleur
|
||||
if (selectedColor === 'rainbow') {
|
||||
angle += 0.05;
|
||||
const hue = (angle * 180 / Math.PI) % 360;
|
||||
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
|
||||
} else {
|
||||
const colorMap = {
|
||||
'yellow': '#ffd700',
|
||||
'red': '#ff4444',
|
||||
'blue': '#4444ff',
|
||||
'green': '#44ff44',
|
||||
'purple': '#aa44ff',
|
||||
'orange': '#ff8844',
|
||||
'pink': '#ff44aa'
|
||||
};
|
||||
ctx.fillStyle = colorMap[selectedColor] || '#ffd700';
|
||||
}
|
||||
|
||||
// Animation de la bouche
|
||||
if (Math.floor(angle * 5) % 2 === 0) {
|
||||
mouthOpen = !mouthOpen;
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
const radius = 40;
|
||||
if (mouthOpen) {
|
||||
ctx.arc(0, 0, radius, 0.2, Math.PI * 2 - 0.2);
|
||||
} else {
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2);
|
||||
}
|
||||
ctx.lineTo(0, 0);
|
||||
ctx.fill();
|
||||
|
||||
ctx.restore();
|
||||
|
||||
previewAnimationId = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
animate();
|
||||
}
|
||||
|
||||
function stopPreviewAnimation() {
|
||||
if (previewAnimationId) {
|
||||
cancelAnimationFrame(previewAnimationId);
|
||||
previewAnimationId = null;
|
||||
}
|
||||
}
|
||||
|
||||
function updatePlayerPreview() {
|
||||
// L'animation se mettra à jour automatiquement car elle utilise selectedColor
|
||||
}
|
||||
|
||||
// Sauvegarder la personnalisation
|
||||
if (saveCustomizeBtn) {
|
||||
saveCustomizeBtn.addEventListener('click', () => {
|
||||
playerColor = selectedColor;
|
||||
localStorage.setItem('playerColor', playerColor);
|
||||
|
||||
// Mettre à jour le joueur actuel si le jeu est en cours
|
||||
if (pacman) {
|
||||
pacman.color = playerColor;
|
||||
}
|
||||
|
||||
// Fermer le modal
|
||||
if (customizeModal) {
|
||||
customizeModal.style.display = 'none';
|
||||
stopPreviewAnimation();
|
||||
}
|
||||
|
||||
// Message de confirmation
|
||||
alert('Personnalisation sauvegardée !');
|
||||
});
|
||||
}
|
||||
|
||||
// Fermer le classement dans le jeu
|
||||
if (closeLeaderboardBtn) {
|
||||
closeLeaderboardBtn.addEventListener('click', () => {
|
||||
|
||||
Reference in New Issue
Block a user