Add 1 files
Browse files- index.html +74 -48
index.html
CHANGED
|
@@ -149,6 +149,11 @@
|
|
| 149 |
background-color: #FFF;
|
| 150 |
transform: scale(1.1);
|
| 151 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
</style>
|
| 153 |
</head>
|
| 154 |
<body class="bg-gray-900 flex flex-col items-center justify-center min-h-screen">
|
|
@@ -190,6 +195,7 @@
|
|
| 190 |
let dotsRemaining = 0;
|
| 191 |
let powerPelletActive = false;
|
| 192 |
let powerPelletTimeout;
|
|
|
|
| 193 |
|
| 194 |
// Game elements
|
| 195 |
let pacman = {
|
|
@@ -201,7 +207,7 @@
|
|
| 201 |
};
|
| 202 |
|
| 203 |
const ghosts = [
|
| 204 |
-
{ name: 'blinky', x: 9, y:
|
| 205 |
{ name: 'pinky', x: 9, y: 9, element: null, direction: 'up', color: 'pink' },
|
| 206 |
{ name: 'inky', x: 8, y: 9, element: null, direction: 'right', color: 'cyan' },
|
| 207 |
{ name: 'clyde', x: 10, y: 9, element: null, direction: 'down', color: 'orange' }
|
|
@@ -242,6 +248,7 @@
|
|
| 242 |
dotsRemaining = 0;
|
| 243 |
powerPelletActive = false;
|
| 244 |
clearTimeout(powerPelletTimeout);
|
|
|
|
| 245 |
|
| 246 |
// Reset Pac-Man position
|
| 247 |
pacman.x = 9;
|
|
@@ -250,7 +257,7 @@
|
|
| 250 |
pacman.nextDirection = 'right';
|
| 251 |
|
| 252 |
// Reset ghosts positions
|
| 253 |
-
ghosts[0].x = 9; ghosts[0].y =
|
| 254 |
ghosts[1].x = 9; ghosts[1].y = 9; ghosts[1].direction = 'up';
|
| 255 |
ghosts[2].x = 8; ghosts[2].y = 9; ghosts[2].direction = 'right';
|
| 256 |
ghosts[3].x = 10; ghosts[3].y = 9; ghosts[3].direction = 'down';
|
|
@@ -551,16 +558,14 @@
|
|
| 551 |
if (Math.abs(pacman.x - ghost.x) < 0.8 && Math.abs(pacman.y - ghost.y) < 0.8) {
|
| 552 |
if (powerPelletActive) {
|
| 553 |
// Ghost is vulnerable - eat it
|
| 554 |
-
ghost.element.
|
| 555 |
-
ghost.element.style.backgroundColor = '#0000FF';
|
| 556 |
setTimeout(() => {
|
| 557 |
// Reset ghost position
|
| 558 |
ghost.x = 9;
|
| 559 |
ghost.y = 9;
|
| 560 |
ghost.element.style.left = `${ghost.x * cellSize}px`;
|
| 561 |
ghost.element.style.top = `${ghost.y * cellSize}px`;
|
| 562 |
-
ghost.element.
|
| 563 |
-
ghost.element.style.backgroundColor = '';
|
| 564 |
ghost.element.className = `ghost absolute ${ghost.name}`;
|
| 565 |
}, 1000);
|
| 566 |
|
|
@@ -585,7 +590,7 @@
|
|
| 585 |
|
| 586 |
ghosts.forEach(g => {
|
| 587 |
g.x = [9, 9, 8, 10][ghosts.indexOf(g)];
|
| 588 |
-
g.y = [
|
| 589 |
g.direction = ['left', 'up', 'right', 'down'][ghosts.indexOf(g)];
|
| 590 |
g.element.style.left = `${g.x * cellSize}px`;
|
| 591 |
g.element.style.top = `${g.y * cellSize}px`;
|
|
@@ -610,16 +615,14 @@
|
|
| 610 |
|
| 611 |
// Make ghosts vulnerable
|
| 612 |
ghosts.forEach(ghost => {
|
| 613 |
-
ghost.element.
|
| 614 |
-
ghost.element.style.backgroundColor = '#0000FF';
|
| 615 |
});
|
| 616 |
|
| 617 |
// Set timeout to deactivate power pellet
|
| 618 |
powerPelletTimeout = setTimeout(() => {
|
| 619 |
powerPelletActive = false;
|
| 620 |
ghosts.forEach(ghost => {
|
| 621 |
-
ghost.element.
|
| 622 |
-
ghost.element.style.backgroundColor = '';
|
| 623 |
ghost.element.className = `ghost absolute ${ghost.name}`;
|
| 624 |
});
|
| 625 |
}, 10000); // 10 seconds
|
|
@@ -637,7 +640,7 @@
|
|
| 637 |
};
|
| 638 |
|
| 639 |
// Filter out the opposite direction to prevent 180-degree turns
|
| 640 |
-
|
| 641 |
|
| 642 |
// Try to find a valid move
|
| 643 |
let newDirection = ghost.direction;
|
|
@@ -645,59 +648,73 @@
|
|
| 645 |
let newY = ghost.y;
|
| 646 |
|
| 647 |
// First try to keep moving in the same direction
|
|
|
|
|
|
|
| 648 |
switch (ghost.direction) {
|
| 649 |
case 'up':
|
| 650 |
if (isValidMove(ghost.x, ghost.y - 1)) {
|
| 651 |
newY--;
|
| 652 |
-
|
| 653 |
}
|
|
|
|
| 654 |
case 'down':
|
| 655 |
if (isValidMove(ghost.x, ghost.y + 1)) {
|
| 656 |
newY++;
|
| 657 |
-
|
| 658 |
}
|
|
|
|
| 659 |
case 'left':
|
| 660 |
if (isValidMove(ghost.x - 1, ghost.y)) {
|
| 661 |
newX--;
|
| 662 |
-
|
| 663 |
}
|
|
|
|
| 664 |
case 'right':
|
| 665 |
if (isValidMove(ghost.x + 1, ghost.y)) {
|
| 666 |
newX++;
|
| 667 |
-
|
| 668 |
}
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
|
| 681 |
-
|
| 682 |
-
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
| 688 |
-
|
| 689 |
-
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 700 |
}
|
|
|
|
|
|
|
| 701 |
}
|
| 702 |
|
| 703 |
// Handle tunnel
|
|
@@ -717,6 +734,15 @@
|
|
| 717 |
const leftPupil = ghost.element.querySelector('.eye:first-child .pupil');
|
| 718 |
const rightPupil = ghost.element.querySelector('.eye:last-child .pupil');
|
| 719 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
switch (ghost.direction) {
|
| 721 |
case 'up':
|
| 722 |
leftPupil.style.left = '2px';
|
|
@@ -785,7 +811,7 @@
|
|
| 785 |
gameRunning = true;
|
| 786 |
|
| 787 |
// Game loop
|
| 788 |
-
|
| 789 |
if (!gameRunning) {
|
| 790 |
clearInterval(gameLoop);
|
| 791 |
return;
|
|
|
|
| 149 |
background-color: #FFF;
|
| 150 |
transform: scale(1.1);
|
| 151 |
}
|
| 152 |
+
|
| 153 |
+
.vulnerable-ghost {
|
| 154 |
+
background-color: #0000FF !important;
|
| 155 |
+
opacity: 0.7 !important;
|
| 156 |
+
}
|
| 157 |
</style>
|
| 158 |
</head>
|
| 159 |
<body class="bg-gray-900 flex flex-col items-center justify-center min-h-screen">
|
|
|
|
| 195 |
let dotsRemaining = 0;
|
| 196 |
let powerPelletActive = false;
|
| 197 |
let powerPelletTimeout;
|
| 198 |
+
let gameLoop;
|
| 199 |
|
| 200 |
// Game elements
|
| 201 |
let pacman = {
|
|
|
|
| 207 |
};
|
| 208 |
|
| 209 |
const ghosts = [
|
| 210 |
+
{ name: 'blinky', x: 9, y: 7, element: null, direction: 'left', color: 'red' },
|
| 211 |
{ name: 'pinky', x: 9, y: 9, element: null, direction: 'up', color: 'pink' },
|
| 212 |
{ name: 'inky', x: 8, y: 9, element: null, direction: 'right', color: 'cyan' },
|
| 213 |
{ name: 'clyde', x: 10, y: 9, element: null, direction: 'down', color: 'orange' }
|
|
|
|
| 248 |
dotsRemaining = 0;
|
| 249 |
powerPelletActive = false;
|
| 250 |
clearTimeout(powerPelletTimeout);
|
| 251 |
+
clearInterval(gameLoop);
|
| 252 |
|
| 253 |
// Reset Pac-Man position
|
| 254 |
pacman.x = 9;
|
|
|
|
| 257 |
pacman.nextDirection = 'right';
|
| 258 |
|
| 259 |
// Reset ghosts positions
|
| 260 |
+
ghosts[0].x = 9; ghosts[0].y = 7; ghosts[0].direction = 'left';
|
| 261 |
ghosts[1].x = 9; ghosts[1].y = 9; ghosts[1].direction = 'up';
|
| 262 |
ghosts[2].x = 8; ghosts[2].y = 9; ghosts[2].direction = 'right';
|
| 263 |
ghosts[3].x = 10; ghosts[3].y = 9; ghosts[3].direction = 'down';
|
|
|
|
| 558 |
if (Math.abs(pacman.x - ghost.x) < 0.8 && Math.abs(pacman.y - ghost.y) < 0.8) {
|
| 559 |
if (powerPelletActive) {
|
| 560 |
// Ghost is vulnerable - eat it
|
| 561 |
+
ghost.element.classList.add('vulnerable-ghost');
|
|
|
|
| 562 |
setTimeout(() => {
|
| 563 |
// Reset ghost position
|
| 564 |
ghost.x = 9;
|
| 565 |
ghost.y = 9;
|
| 566 |
ghost.element.style.left = `${ghost.x * cellSize}px`;
|
| 567 |
ghost.element.style.top = `${ghost.y * cellSize}px`;
|
| 568 |
+
ghost.element.classList.remove('vulnerable-ghost');
|
|
|
|
| 569 |
ghost.element.className = `ghost absolute ${ghost.name}`;
|
| 570 |
}, 1000);
|
| 571 |
|
|
|
|
| 590 |
|
| 591 |
ghosts.forEach(g => {
|
| 592 |
g.x = [9, 9, 8, 10][ghosts.indexOf(g)];
|
| 593 |
+
g.y = [7, 9, 9, 9][ghosts.indexOf(g)];
|
| 594 |
g.direction = ['left', 'up', 'right', 'down'][ghosts.indexOf(g)];
|
| 595 |
g.element.style.left = `${g.x * cellSize}px`;
|
| 596 |
g.element.style.top = `${g.y * cellSize}px`;
|
|
|
|
| 615 |
|
| 616 |
// Make ghosts vulnerable
|
| 617 |
ghosts.forEach(ghost => {
|
| 618 |
+
ghost.element.classList.add('vulnerable-ghost');
|
|
|
|
| 619 |
});
|
| 620 |
|
| 621 |
// Set timeout to deactivate power pellet
|
| 622 |
powerPelletTimeout = setTimeout(() => {
|
| 623 |
powerPelletActive = false;
|
| 624 |
ghosts.forEach(ghost => {
|
| 625 |
+
ghost.element.classList.remove('vulnerable-ghost');
|
|
|
|
| 626 |
ghost.element.className = `ghost absolute ${ghost.name}`;
|
| 627 |
});
|
| 628 |
}, 10000); // 10 seconds
|
|
|
|
| 640 |
};
|
| 641 |
|
| 642 |
// Filter out the opposite direction to prevent 180-degree turns
|
| 643 |
+
let possibleDirections = directions.filter(dir => dir !== oppositeDirections[ghost.direction]);
|
| 644 |
|
| 645 |
// Try to find a valid move
|
| 646 |
let newDirection = ghost.direction;
|
|
|
|
| 648 |
let newY = ghost.y;
|
| 649 |
|
| 650 |
// First try to keep moving in the same direction
|
| 651 |
+
let moved = false;
|
| 652 |
+
|
| 653 |
switch (ghost.direction) {
|
| 654 |
case 'up':
|
| 655 |
if (isValidMove(ghost.x, ghost.y - 1)) {
|
| 656 |
newY--;
|
| 657 |
+
moved = true;
|
| 658 |
}
|
| 659 |
+
break;
|
| 660 |
case 'down':
|
| 661 |
if (isValidMove(ghost.x, ghost.y + 1)) {
|
| 662 |
newY++;
|
| 663 |
+
moved = true;
|
| 664 |
}
|
| 665 |
+
break;
|
| 666 |
case 'left':
|
| 667 |
if (isValidMove(ghost.x - 1, ghost.y)) {
|
| 668 |
newX--;
|
| 669 |
+
moved = true;
|
| 670 |
}
|
| 671 |
+
break;
|
| 672 |
case 'right':
|
| 673 |
if (isValidMove(ghost.x + 1, ghost.y)) {
|
| 674 |
newX++;
|
| 675 |
+
moved = true;
|
| 676 |
}
|
| 677 |
+
break;
|
| 678 |
+
}
|
| 679 |
+
|
| 680 |
+
// If current direction is blocked, try random other directions
|
| 681 |
+
if (!moved) {
|
| 682 |
+
// Shuffle possible directions
|
| 683 |
+
possibleDirections = possibleDirections.sort(() => Math.random() - 0.5);
|
| 684 |
+
|
| 685 |
+
for (const dir of possibleDirections) {
|
| 686 |
+
switch (dir) {
|
| 687 |
+
case 'up':
|
| 688 |
+
if (isValidMove(ghost.x, ghost.y - 1)) {
|
| 689 |
+
newDirection = 'up';
|
| 690 |
+
newY--;
|
| 691 |
+
moved = true;
|
| 692 |
+
break;
|
| 693 |
+
}
|
| 694 |
+
case 'down':
|
| 695 |
+
if (isValidMove(ghost.x, ghost.y + 1)) {
|
| 696 |
+
newDirection = 'down';
|
| 697 |
+
newY++;
|
| 698 |
+
moved = true;
|
| 699 |
+
break;
|
| 700 |
+
}
|
| 701 |
+
case 'left':
|
| 702 |
+
if (isValidMove(ghost.x - 1, ghost.y)) {
|
| 703 |
+
newDirection = 'left';
|
| 704 |
+
newX--;
|
| 705 |
+
moved = true;
|
| 706 |
+
break;
|
| 707 |
+
}
|
| 708 |
+
case 'right':
|
| 709 |
+
if (isValidMove(ghost.x + 1, ghost.y)) {
|
| 710 |
+
newDirection = 'right';
|
| 711 |
+
newX++;
|
| 712 |
+
moved = true;
|
| 713 |
+
break;
|
| 714 |
+
}
|
| 715 |
}
|
| 716 |
+
if (moved) break;
|
| 717 |
+
}
|
| 718 |
}
|
| 719 |
|
| 720 |
// Handle tunnel
|
|
|
|
| 734 |
const leftPupil = ghost.element.querySelector('.eye:first-child .pupil');
|
| 735 |
const rightPupil = ghost.element.querySelector('.eye:last-child .pupil');
|
| 736 |
|
| 737 |
+
leftPupil.style.left = '';
|
| 738 |
+
leftPupil.style.right = '';
|
| 739 |
+
leftPupil.style.top = '';
|
| 740 |
+
leftPupil.style.bottom = '';
|
| 741 |
+
rightPupil.style.left = '';
|
| 742 |
+
rightPupil.style.right = '';
|
| 743 |
+
rightPupil.style.top = '';
|
| 744 |
+
rightPupil.style.bottom = '';
|
| 745 |
+
|
| 746 |
switch (ghost.direction) {
|
| 747 |
case 'up':
|
| 748 |
leftPupil.style.left = '2px';
|
|
|
|
| 811 |
gameRunning = true;
|
| 812 |
|
| 813 |
// Game loop
|
| 814 |
+
gameLoop = setInterval(() => {
|
| 815 |
if (!gameRunning) {
|
| 816 |
clearInterval(gameLoop);
|
| 817 |
return;
|