Compare commits

...

2 Commits

2 changed files with 24 additions and 16 deletions

38
game.js
View File

@ -354,7 +354,7 @@ class Pacman {
cherryEatenTimer = Math.max(150, 300 - (level - 1) * 20); cherryEatenTimer = Math.max(150, 300 - (level - 1) * 20);
// Rendre tous les fantômes vulnérables // Rendre tous les fantômes vulnérables
const vulnerableTime = Math.max(180, 360 - (level - 1) * 30); const vulnerableTime = Math.max(60, 180 - (level - 1) * 15);
for (let ghost of ghosts) { for (let ghost of ghosts) {
ghost.isVulnerable = true; ghost.isVulnerable = true;
ghost.vulnerableTimer = vulnerableTime; ghost.vulnerableTimer = vulnerableTime;
@ -538,7 +538,7 @@ class Ghost {
} }
} }
this.moveInterval = Math.max(8, 20 - (level - 1) * 2); this.moveInterval = Math.max(5, 15 - (level - 1) * 1.5);
this.moveCounter++; this.moveCounter++;
@ -555,15 +555,20 @@ class Ghost {
// Fuir le joueur quand vulnérable // Fuir le joueur quand vulnérable
this.direction = this.getDirectionAwayFromPacman(possibleDirections); this.direction = this.getDirectionAwayFromPacman(possibleDirections);
} else { } else {
// Comportement selon le type // Tous les fantômes chassent le joueur (sauf patrouilleurs qui patrouillent si très loin)
if (this.type === GHOST_HUNTER) { if (this.type === GHOST_PATROL) {
this.direction = this.getDirectionToPacman(possibleDirections); const distance = Math.sqrt(
} else if (this.type === GHOST_PATROL) { Math.pow(pacman.x - this.x, 2) +
this.direction = this.getPatrolDirection(possibleDirections); Math.pow(pacman.y - this.y, 2)
} else if (this.type === GHOST_FAST || this.type === GHOST_INVISIBLE) { );
this.direction = this.getDirectionToPacman(possibleDirections); // Si proche, chasser, sinon patrouiller (seulement si très loin)
if (distance < 12) {
this.direction = this.getDirectionToPacman(possibleDirections);
} else {
this.direction = this.getPatrolDirection(possibleDirections);
}
} else { } else {
// Normal : toujours poursuivre // Tous les autres chassent directement
this.direction = this.getDirectionToPacman(possibleDirections); this.direction = this.getDirectionToPacman(possibleDirections);
} }
} }
@ -595,10 +600,13 @@ class Ghost {
let targetX = pacman.x; let targetX = pacman.x;
let targetY = pacman.y; let targetY = pacman.y;
// Prédiction améliorée pour tous les niveaux
const predictionSteps = level >= 3 ? 4 : 3;
// Si Pacman bouge, prédire où il sera // Si Pacman bouge, prédire où il sera
if (pacman.direction !== undefined) { if (pacman.direction !== undefined) {
const futureX = pacman.x + dx[pacman.direction] * 2; const futureX = pacman.x + dx[pacman.direction] * predictionSteps;
const futureY = pacman.y + dy[pacman.direction] * 2; const futureY = pacman.y + dy[pacman.direction] * predictionSteps;
if (futureX >= 0 && futureX < COLS && futureY >= 0 && futureY < ROWS) { if (futureX >= 0 && futureX < COLS && futureY >= 0 && futureY < ROWS) {
targetX = futureX; targetX = futureX;
targetY = futureY; targetY = futureY;
@ -612,10 +620,8 @@ class Ghost {
const oppositeDirection = (this.direction + 2) % 4; const oppositeDirection = (this.direction + 2) % 4;
for (let dir of possibleDirections) { for (let dir of possibleDirections) {
// Éviter la direction opposée sauf si c'est la seule option // Permettre le retour en arrière si c'est la meilleure direction
if (possibleDirections.length > 1 && dir === oppositeDirection) { // (pas de restriction pour une poursuite plus agressive)
continue;
}
const nextX = this.x + dx[dir]; const nextX = this.x + dx[dir];
const nextY = this.y + dy[dir]; const nextY = this.y + dy[dir];

View File

@ -19,6 +19,7 @@ body {
padding: 20px; padding: 20px;
position: relative; position: relative;
overflow-x: hidden; overflow-x: hidden;
cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='32' viewBox='0 0 36 32'%3E%3Cdefs%3E%3Cfilter id='glow'%3E%3CfeGaussianBlur stdDeviation='1.5' result='coloredBlur'/%3E%3CfeMerge%3E%3CfeMergeNode in='coloredBlur'/%3E%3CfeMergeNode in='SourceGraphic'/%3E%3C/feMerge%3E%3C/filter%3E%3ClinearGradient id='ghostGrad' x1='0%25' y1='0%25' x2='0%25' y2='100%25'%3E%3Cstop offset='0%25' style='stop-color:%23ff4444;stop-opacity:1' /%3E%3Cstop offset='100%25' style='stop-color:%23cc0000;stop-opacity:1' /%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M18 4 Q22 2 26 4 Q30 6 30 10 L30 20 Q30 24 28 26 Q26 28 24 28 Q22 30 20 28 Q18 30 16 28 Q14 30 12 28 Q10 30 8 28 Q6 30 4 28 Q2 26 2 22 L2 10 Q2 6 6 4 Q10 2 14 4 Q16 2 18 4 Z' fill='url(%23ghostGrad)' filter='url(%23glow)' stroke='%23ffffff' stroke-width='0.3'/%3E%3Cpath d='M8 22 Q6 24 8 26 Q9 24 8 22 M14 22 Q12 24 14 26 Q15 24 14 22 M20 22 Q18 24 20 26 Q21 24 20 22 M26 22 Q24 24 26 26 Q27 24 26 22' fill='url(%23ghostGrad)' filter='url(%23glow)'/%3E%3Ccircle cx='12' cy='10' r='3' fill='%23ffffff'/%3E%3Ccircle cx='24' cy='10' r='3' fill='%23ffffff'/%3E%3Ccircle cx='12' cy='10' r='1.8' fill='%23000000'/%3E%3Ccircle cx='24' cy='10' r='1.8' fill='%23000000'/%3E%3Cellipse cx='12.5' cy='9.5' rx='0.6' ry='0.8' fill='%23ffffff'/%3E%3Cellipse cx='24.5' cy='9.5' rx='0.6' ry='0.8' fill='%23ffffff'/%3E%3C/svg%3E") 18 16, auto;
} }
body::before { body::before {
@ -143,6 +144,7 @@ body::after {
height: 100%; height: 100%;
z-index: 1000; z-index: 1000;
overflow: hidden; overflow: hidden;
cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='32' viewBox='0 0 36 32'%3E%3Cdefs%3E%3Cfilter id='glow'%3E%3CfeGaussianBlur stdDeviation='1.5' result='coloredBlur'/%3E%3CfeMerge%3E%3CfeMergeNode in='coloredBlur'/%3E%3CfeMergeNode in='SourceGraphic'/%3E%3C/feMerge%3E%3C/filter%3E%3ClinearGradient id='ghostGrad' x1='0%25' y1='0%25' x2='0%25' y2='100%25'%3E%3Cstop offset='0%25' style='stop-color:%23ff4444;stop-opacity:1' /%3E%3Cstop offset='100%25' style='stop-color:%23cc0000;stop-opacity:1' /%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M18 4 Q22 2 26 4 Q30 6 30 10 L30 20 Q30 24 28 26 Q26 28 24 28 Q22 30 20 28 Q18 30 16 28 Q14 30 12 28 Q10 30 8 28 Q6 30 4 28 Q2 26 2 22 L2 10 Q2 6 6 4 Q10 2 14 4 Q16 2 18 4 Z' fill='url(%23ghostGrad)' filter='url(%23glow)' stroke='%23ffffff' stroke-width='0.3'/%3E%3Cpath d='M8 22 Q6 24 8 26 Q9 24 8 22 M14 22 Q12 24 14 26 Q15 24 14 22 M20 22 Q18 24 20 26 Q21 24 20 22 M26 22 Q24 24 26 26 Q27 24 26 22' fill='url(%23ghostGrad)' filter='url(%23glow)'/%3E%3Ccircle cx='12' cy='10' r='3' fill='%23ffffff'/%3E%3Ccircle cx='24' cy='10' r='3' fill='%23ffffff'/%3E%3Ccircle cx='12' cy='10' r='1.8' fill='%23000000'/%3E%3Ccircle cx='24' cy='10' r='1.8' fill='%23000000'/%3E%3Cellipse cx='12.5' cy='9.5' rx='0.6' ry='0.8' fill='%23ffffff'/%3E%3Cellipse cx='24.5' cy='9.5' rx='0.6' ry='0.8' fill='%23ffffff'/%3E%3C/svg%3E") 18 16, auto;
} }
/* === CANVAS ARRIERE-PLAN MENU === */ /* === CANVAS ARRIERE-PLAN MENU === */