0% found this document useful (0 votes)
30 views11 pages

Index HTML

The document describes a web-based game titled 'MegaPac: 3999 Rounds', which features a player navigating through a maze while avoiding ghosts and collecting dots. The game includes various levels, with increasing difficulty and the ability to restart after a game over. It utilizes HTML, CSS, and JavaScript to create an interactive gaming experience with a canvas for rendering the game elements.

Uploaded by

umer Lone
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views11 pages

Index HTML

The document describes a web-based game titled 'MegaPac: 3999 Rounds', which features a player navigating through a maze while avoiding ghosts and collecting dots. The game includes various levels, with increasing difficulty and the ability to restart after a game over. It utilizes HTML, CSS, and JavaScript to create an interactive gaming experience with a canvas for rendering the game elements.

Uploaded by

umer Lone
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

<!

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;
}

#game-over h2, #level-complete h2 {


color: #f00;
font-size: 32px;
margin-bottom: 10px;
}

#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);

// Generate initial level


generateLevel();

// Start game loop


requestAnimationFrame(gameLoop);
}

// Generate a new level


function generateLevel() {
// Clear existing walls and dots
walls = [];
dots = [];
ghosts = [];

// Create border walls


for (let y = 0; y < ROWS; y++) {
for (let x = 0; x < COLS; x++) {
if (x === 0 || y === 0 || x === COLS - 1 || y === ROWS - 1) {
walls.push({ x, y });
}
}
}

// Create maze pattern (simplified for this example)


createMazePattern();

// Create dots in all empty spaces


for (let y = 1; y < ROWS - 1; y++) {
for (let x = 1; x < COLS - 1; x++) {
const isWall = walls.some(w => w.x === x && w.y === y);
if (!isWall) {
dots.push({ x, y });
}
}
}

// Place player at start position


player = { x: 1, y: 1, dir: 'right', nextDir: 'right' };

// Create ghosts (more ghosts as levels progress)


const ghostCount = Math.min(Math.floor(level / 10) + 1, 8);
for (let i = 0; i < ghostCount; i++) {
ghosts.push({
x: COLS - 2 - i,
y: ROWS - 2,
dir: ['up', 'down', 'left', 'right'][Math.floor(Math.random() *
4)],
speed: ghostSpeed
});
}

// Update UI
document.getElementById('level').textContent = level;
document.getElementById('score').textContent = score;
document.getElementById('lives').textContent = lives;
document.getElementById('next-level').textContent = level + 1;
}

// Create a simple maze pattern


function createMazePattern() {
// Horizontal walls
for (let x = 2; x < COLS - 2; x += 4) {
for (let y = 2; y < ROWS - 2; y += 6) {
const length = Math.min(3, COLS - 2 - x);
for (let i = 0; i < length; i++) {
walls.push({ x: x + i, y });
}
}
}

// 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);
}
}
}

// Main game loop


function gameLoop() {
if (!gameRunning) return;

// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);

// Get current level colors


const colors = LEVEL_COLORS[level % LEVEL_COLORS.length];
// Draw walls
ctx.fillStyle = colors.wall;
walls.forEach(wall => {
ctx.fillRect(wall.x * CELL_SIZE, wall.y * CELL_SIZE, CELL_SIZE,
CELL_SIZE);
});

// 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);

// Move and draw ghosts


moveGhosts();
drawGhosts(colors.ghost);

// Check for collisions


checkCollisions();

// Check for level completion


if (dots.length === 0) {
levelComplete();
}

requestAnimationFrame(gameLoop);
}

// Draw the player character


function drawPlayer(color) {
ctx.fillStyle = color;

// Calculate mouth angle based on direction


let startAngle, endAngle;
switch (player.dir) {
case 'right':
startAngle = 0.2 * Math.PI;
endAngle = 1.8 * Math.PI;
break;
case 'down':
startAngle = 0.7 * Math.PI;
endAngle = 1.3 * Math.PI;
break;
case 'left':
startAngle = 1.2 * Math.PI;
endAngle = 0.8 * Math.PI;
break;
case 'up':
startAngle = 1.7 * Math.PI;
endAngle = 0.3 * Math.PI;
break;
}

// Draw Pacman shape


ctx.beginPath();
ctx.arc(
player.x * CELL_SIZE + CELL_SIZE / 2,
player.y * CELL_SIZE + CELL_SIZE / 2,
CELL_SIZE / 2 - 2,
startAngle,
endAngle
);
ctx.lineTo(
player.x * CELL_SIZE + CELL_SIZE / 2,
player.y * CELL_SIZE + CELL_SIZE / 2
);
ctx.fill();
}

// 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;

ctx.lineTo(ghost.x * CELL_SIZE + CELL_SIZE, startY);

// 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.lineTo(ghost.x * CELL_SIZE, endY);


for (let i = 0; i < 3; i++) {
ctx.lineTo(
ghost.x * CELL_SIZE + (i * waveWidth),
endY - (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();
});
}

// Move the player based on current direction


function movePlayer() {
// Try to change to nextDir if possible
if (player.dir !== player.nextDir) {
const [newX, newY] = getNextPosition(player.x, player.y,
player.nextDir);
if (!isWall(newX, newY)) {
player.dir = player.nextDir;
}
}

const [newX, newY] = getNextPosition(player.x, player.y, player.dir);

if (!isWall(newX, newY)) {
player.x = newX;
player.y = newY;

// Wrap around (teleport) if at tunnel


if (player.x < 0) player.x = COLS - 1;
if (player.x >= COLS) player.x = 0;

// Check for dot collection


checkDotCollection();
}
}

// Move ghosts
function moveGhosts() {
ghostSpeedCounter++;

ghosts.forEach(ghost => {
if (ghostSpeedCounter % ghost.speed !== 0) return;

// Try to continue in current direction


let [newX, newY] = getNextPosition(ghost.x, ghost.y, ghost.dir);

if (isWall(newX, newY) || Math.random() < 0.1) {


// Find possible directions
const directions = [];
if (!isWall(ghost.x, ghost.y - 1) && ghost.dir !== 'down')
directions.push('up');
if (!isWall(ghost.x, ghost.y + 1) && ghost.dir !== 'up')
directions.push('down');
if (!isWall(ghost.x - 1, ghost.y) && ghost.dir !== 'right')
directions.push('left');
if (!isWall(ghost.x + 1, ghost.y) && ghost.dir !== 'left')
directions.push('right');

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;
}

// Wrap around (teleport) if at tunnel


if (ghost.x < 0) ghost.x = COLS - 1;
if (ghost.x >= COLS) ghost.x = 0;
});
}

// Check for dot collection


function checkDotCollection() {
for (let i = dots.length - 1; i >= 0; i--) {
if (dots[i].x === player.x && dots[i].y === player.y) {
dots.splice(i, 1);
score += 10;
document.getElementById('score').textContent = score;
}
}
}

// Check for collisions with ghosts


function checkCollisions() {
ghosts.forEach(ghost => {
if (ghost.x === player.x && ghost.y === player.y) {
lives--;
document.getElementById('lives').textContent = lives;

if (lives <= 0) {
gameOver();
} else {
// Reset player position
player.x = 1;
player.y = 1;
player.dir = 'right';
player.nextDir = 'right';
}
}
});
}

// Get next position based on direction


function getNextPosition(x, y, dir) {
switch (dir) {
case 'up': return [x, y - 1];
case 'down': return [x, y + 1];
case 'left': return [x - 1, y];
case 'right': return [x + 1, y];
default: return [x, y];
}
}

// Check if a position is a wall


function isWall(x, y) {
return walls.some(wall => wall.x === x && wall.y === y);
}

// Handle keyboard input


function handleKeyPress(e) {
switch (e.key) {
case 'ArrowUp':
player.nextDir = 'up';
break;
case 'ArrowDown':
player.nextDir = 'down';
break;
case 'ArrowLeft':
player.nextDir = 'left';
break;
case 'ArrowRight':
player.nextDir = 'right';
break;
}
}

// 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;

// Increase ghost speed every 5 levels


if (level % 5 === 0) {
ghostSpeed = Math.max(1, ghostSpeed - 1);
}
}

// Show level complete screen


document.getElementById('level-complete').style.display = 'block';
gameRunning = false;

// After a delay, generate next level


setTimeout(() => {
document.getElementById('level-complete').style.display = 'none';
generateLevel();
gameRunning = true;
requestAnimationFrame(gameLoop);
}, 2000);
}

// 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);
}

// Start the game when the page loads


window.onload = init;
</script>
</body>
</html>

You might also like