Index HTML
Index HTML
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MegaPac: 3999 Rounds</title>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
background-color: #000;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
}
#game-container {
position: relative;
margin-top: 20px;
}
#game-board {
border: 2px solid #333;
background-color: #000;
}
#game-info {
display: flex;
justify-content: space-between;
width: 600px;
margin-bottom: 10px;
font-size: 18px;
}
#game-over, #level-complete {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
padding: 20px;
border-radius: 10px;
text-align: center;
display: none;
}
#level-complete h2 {
color: #0f0;
}
button {
background-color: #ff0;
color: #000;
border: none;
padding: 10px 20px;
font-size: 18px;
cursor: pointer;
border-radius: 5px;
margin-top: 10px;
}
button:hover {
background-color: #ff6;
}
</style>
</head>
<body>
<h1>MegaPac: 3999 Rounds</h1>
<div id="game-info">
<div>Level: <span id="level">1</span>/3999</div>
<div>Score: <span id="score">0</span></div>
<div>Lives: <span id="lives">3</span></div>
</div>
<div id="game-container">
<canvas id="game-board" width="600" height="600"></canvas>
<div id="game-over">
<h2>Game Over!</h2>
<p>Final Score: <span id="final-score">0</span></p>
<button id="restart-button">Play Again</button>
</div>
<div id="level-complete">
<h2>Level Complete!</h2>
<p>Preparing for level <span id="next-level">2</span>...</p>
</div>
</div>
<script>
// Game constants
const CELL_SIZE = 20;
const ROWS = 30;
const COLS = 30;
const TOTAL_LEVELS = 3999;
// Game variables
let canvas, ctx;
let player = { x: 1, y: 1, dir: 'right', nextDir: 'right' };
let ghosts = [];
let dots = [];
let walls = [];
let score = 0;
let lives = 3;
let level = 1;
let gameRunning = true;
let ghostSpeed = 3; // Lower is faster
let ghostSpeedCounter = 0;
// Colors for different levels
const LEVEL_COLORS = [
{ wall: '#00F', dot: '#FFF', player: '#FF0', ghost: '#F00' }, // Blue
{ wall: '#F0F', dot: '#FFF', player: '#FF0', ghost: '#0FF' }, // Purple
{ wall: '#0F0', dot: '#FFF', player: '#FF0', ghost: '#F0F' }, // Green
{ wall: '#FF0', dot: '#000', player: '#F00', ghost: '#00F' }, // Yellow
{ wall: '#F00', dot: '#FFF', player: '#FF0', ghost: '#0F0' }, // Red
];
// Initialize game
function init() {
canvas = document.getElementById('game-board');
ctx = canvas.getContext('2d');
// Event listeners
document.addEventListener('keydown', handleKeyPress);
document.getElementById('restart-button').addEventListener('click',
restartGame);
// Update UI
document.getElementById('level').textContent = level;
document.getElementById('score').textContent = score;
document.getElementById('lives').textContent = lives;
document.getElementById('next-level').textContent = level + 1;
}
// Vertical walls
for (let y = 4; y < ROWS - 2; y += 6) {
for (let x = 4; x < COLS - 2; x += 4) {
const length = Math.min(3, ROWS - 2 - y);
for (let i = 0; i < length; i++) {
walls.push({ x, y: y + i });
}
}
}
// Make sure player can always reach all areas (remove some walls)
for (let i = 0; i < 10; i++) {
const randomIndex = Math.floor(Math.random() * walls.length);
if (walls[randomIndex].x > 1 && walls[randomIndex].y > 1) {
walls.splice(randomIndex, 1);
}
}
}
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw dots
ctx.fillStyle = colors.dot;
dots.forEach(dot => {
ctx.beginPath();
ctx.arc(
dot.x * CELL_SIZE + CELL_SIZE / 2,
dot.y * CELL_SIZE + CELL_SIZE / 2,
CELL_SIZE / 6,
0,
Math.PI * 2
);
ctx.fill();
});
// Move player
movePlayer();
// Draw player
drawPlayer(colors.player);
requestAnimationFrame(gameLoop);
}
// Draw ghosts
function drawGhosts(color) {
ghosts.forEach(ghost => {
ctx.fillStyle = color;
// Ghost body
ctx.beginPath();
ctx.arc(
ghost.x * CELL_SIZE + CELL_SIZE / 2,
ghost.y * CELL_SIZE + CELL_SIZE / 3,
CELL_SIZE / 2 - 2,
Math.PI,
0,
false
);
// Ghost bottom
const startY = ghost.y * CELL_SIZE + CELL_SIZE / 3;
const endY = ghost.y * CELL_SIZE + CELL_SIZE;
// Wavy bottom
const waveWidth = CELL_SIZE / 4;
for (let i = 0; i < 3; i++) {
ctx.lineTo(
ghost.x * CELL_SIZE + CELL_SIZE - (i * waveWidth),
startY + (i % 2 === 0 ? waveWidth : 0)
);
}
ctx.closePath();
ctx.fill();
// Ghost eyes
ctx.fillStyle = '#FFF';
ctx.beginPath();
ctx.arc(
ghost.x * CELL_SIZE + CELL_SIZE / 2 - CELL_SIZE / 6,
ghost.y * CELL_SIZE + CELL_SIZE / 3,
CELL_SIZE / 6,
0,
Math.PI * 2
);
ctx.arc(
ghost.x * CELL_SIZE + CELL_SIZE / 2 + CELL_SIZE / 6,
ghost.y * CELL_SIZE + CELL_SIZE / 3,
CELL_SIZE / 6,
0,
Math.PI * 2
);
ctx.fill();
// Ghost pupils
ctx.fillStyle = '#00F';
ctx.beginPath();
let pupilOffsetX = 0;
let pupilOffsetY = 0;
switch (ghost.dir) {
case 'left':
pupilOffsetX = -CELL_SIZE / 12;
break;
case 'right':
pupilOffsetX = CELL_SIZE / 12;
break;
case 'up':
pupilOffsetY = -CELL_SIZE / 12;
break;
case 'down':
pupilOffsetY = CELL_SIZE / 12;
break;
}
ctx.arc(
ghost.x * CELL_SIZE + CELL_SIZE / 2 - CELL_SIZE / 6 +
pupilOffsetX,
ghost.y * CELL_SIZE + CELL_SIZE / 3 + pupilOffsetY,
CELL_SIZE / 10,
0,
Math.PI * 2
);
ctx.arc(
ghost.x * CELL_SIZE + CELL_SIZE / 2 + CELL_SIZE / 6 +
pupilOffsetX,
ghost.y * CELL_SIZE + CELL_SIZE / 3 + pupilOffsetY,
CELL_SIZE / 10,
0,
Math.PI * 2
);
ctx.fill();
});
}
if (!isWall(newX, newY)) {
player.x = newX;
player.y = newY;
// Move ghosts
function moveGhosts() {
ghostSpeedCounter++;
ghosts.forEach(ghost => {
if (ghostSpeedCounter % ghost.speed !== 0) return;
if (directions.length > 0) {
ghost.dir = directions[Math.floor(Math.random() *
directions.length)];
[newX, newY] = getNextPosition(ghost.x, ghost.y,
ghost.dir);
}
}
if (!isWall(newX, newY)) {
ghost.x = newX;
ghost.y = newY;
}
if (lives <= 0) {
gameOver();
} else {
// Reset player position
player.x = 1;
player.y = 1;
player.dir = 'right';
player.nextDir = 'right';
}
}
});
}
// Level complete
function levelComplete() {
if (level >= TOTAL_LEVELS) {
document.getElementById('level-complete').innerHTML = `
<h2>Congratulations!</h2>
<p>You've completed all 3999 levels!</p>
<p>Final Score: ${score}</p>
<button id="restart-button">Play Again</button>
`;
document.getElementById('restart-button').addEventListener('click',
restartGame);
} else {
level++;
document.getElementById('level').textContent = level;
document.getElementById('next-level').textContent = level + 1;
// Game over
function gameOver() {
document.getElementById('final-score').textContent = score;
document.getElementById('game-over').style.display = 'block';
gameRunning = false;
}
// Restart game
function restartGame() {
score = 0;
lives = 3;
level = 1;
ghostSpeed = 3;
document.getElementById('score').textContent = score;
document.getElementById('lives').textContent = lives;
document.getElementById('level').textContent = level;
document.getElementById('game-over').style.display = 'none';
document.getElementById('level-complete').style.display = 'none';
generateLevel();
gameRunning = true;
requestAnimationFrame(gameLoop);
}