/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Ghost = Container.expand(function () { var self = Container.call(this); var ghostGraphics = self.attachAsset('ghost', { anchorX: 0.5, anchorY: 0.5 }); // Ghost properties self.speed = 5; self.vulnerable = false; self.direction = { x: 0, y: 0 }; self.targetPosition = { x: 0, y: 0 }; self.moving = false; // Direction constants self.DIRECTIONS = [{ x: 0, y: -1 }, // Up { x: 1, y: 0 }, // Right { x: 0, y: 1 }, // Down { x: -1, y: 0 } // Left ]; // Method to make ghost vulnerable when Pac-Man eats a power pellet self.makeVulnerable = function (duration) { self.vulnerable = true; ghostGraphics.tint = 0x0000FF; // Blue when vulnerable // Reset vulnerability after duration LK.setTimeout(function () { self.vulnerable = false; ghostGraphics.tint = 0xFFFFFF; // Reset tint }, duration); }; // Update ghost movement self.update = function () { if (self.moving) { // Move towards target position var dx = self.targetPosition.x - self.x; var dy = self.targetPosition.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.speed) { // Reached target, stop moving self.x = self.targetPosition.x; self.y = self.targetPosition.y; self.moving = false; } else { // Continue moving towards target self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } } }; // Method to move in a specific direction if possible self.moveInDirection = function (dirIndex) { if (dirIndex >= 0 && dirIndex < self.DIRECTIONS.length) { var dir = self.DIRECTIONS[dirIndex]; // Set direction and target position self.direction = dir; self.targetPosition = { x: self.x + dir.x * TILE_SIZE, y: self.y + dir.y * TILE_SIZE }; // Check if the move is valid (no wall) var canMove = !isWallAtPosition(self.targetPosition.x, self.targetPosition.y); if (canMove) { self.moving = true; return true; } } return false; }; return self; }); var Pacman = Container.expand(function () { var self = Container.call(this); var pacmanGraphics = self.attachAsset('pacman', { anchorX: 0.5, anchorY: 0.5 }); // Pacman properties self.speed = 4; // Slightly slower than ghost self.direction = { x: 0, y: 0 }; self.active = true; // Direction constants self.DIRECTIONS = [{ x: 0, y: -1 }, // Up { x: 1, y: 0 }, // Right { x: 0, y: 1 }, // Down { x: -1, y: 0 } // Left ]; // Update pacman movement - simple AI self.update = function () { if (!self.active) { return; } // Only change direction occasionally to make movement more predictable if (LK.ticks % 30 === 0) { // Get ghost position var ghost = player; // Simple AI: Try to move away from ghost var dx = self.x - ghost.x; var dy = self.y - ghost.y; // Check if ghost is vulnerable var avoidGhost = !ghost.vulnerable; // Decide direction based on ghost position var possibleDirs = []; // Check each direction for walls for (var i = 0; i < self.DIRECTIONS.length; i++) { var dir = self.DIRECTIONS[i]; var newX = self.x + dir.x * TILE_SIZE; var newY = self.y + dir.y * TILE_SIZE; if (!isWallAtPosition(newX, newY)) { possibleDirs.push({ dirIndex: i, value: (avoidGhost ? 1 : -1) * (dir.x * dx + dir.y * dy) }); } } // Sort directions by value (highest value first) possibleDirs.sort(function (a, b) { return b.value - a.value; }); // Choose a direction if possible if (possibleDirs.length > 0) { // 70% chance to pick the best direction, 30% chance to pick a random valid direction var dirIndex = Math.random() < 0.7 ? possibleDirs[0].dirIndex : possibleDirs[Math.floor(Math.random() * possibleDirs.length)].dirIndex; self.direction = self.DIRECTIONS[dirIndex]; // Set rotation based on direction if (self.direction.x === 1) { pacmanGraphics.rotation = 0; } else if (self.direction.x === -1) { pacmanGraphics.rotation = Math.PI; } else if (self.direction.y === 1) { pacmanGraphics.rotation = Math.PI / 2; } else if (self.direction.y === -1) { pacmanGraphics.rotation = -Math.PI / 2; } } } // Move in current direction if possible var newX = self.x + self.direction.x * self.speed; var newY = self.y + self.direction.y * self.speed; if (!isWallAtPosition(newX, newY)) { self.x = newX; self.y = newY; } else { // Hit wall, stop and change direction next update self.direction = { x: 0, y: 0 }; } }; return self; }); var Pellet = Container.expand(function () { var self = Container.call(this); var pelletGraphics = self.attachAsset('pellet', { anchorX: 0.5, anchorY: 0.5 }); self.isPellet = true; return self; }); var PowerPellet = Container.expand(function () { var self = Container.call(this); var powerPelletGraphics = self.attachAsset('powerPellet', { anchorX: 0.5, anchorY: 0.5 }); self.isPowerPellet = true; // Power pellet animation - pulsing effect self.update = function () { var scale = 0.9 + 0.2 * Math.sin(LK.ticks / 10); powerPelletGraphics.scale.set(scale, scale); }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); self.isWall = true; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Blue wall // Yellow Pac-Man // Pink ghost // Game constants var TILE_SIZE = 48; var GRID_WIDTH = 21; var GRID_HEIGHT = 27; var MAZE_X_OFFSET = (2048 - GRID_WIDTH * TILE_SIZE) / 2; var MAZE_Y_OFFSET = (2732 - GRID_HEIGHT * TILE_SIZE) / 2; // Game variables var player; var pacmans = []; var walls = []; var pellets = []; var powerPellets = []; var level = 1; var pelletsCollected = 0; var pacmansEaten = 0; var lives = 3; var powerMode = false; var powerModeTimeout; // UI elements var scoreTxt; var levelTxt; var livesTxt; // Game grid - 0: empty, 1: wall, 2: pellet, 3: power pellet, 4: pacman spawn, 5: ghost spawn var levelLayouts = [ // Level 1 - Simple maze [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1], [1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1], [1, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2, 1], [1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 1, 1, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 1], [1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1], [1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1], [1, 2, 2, 2, 2, 2, 1, 2, 2, 5, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1], [0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 2, 1], [1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 2, 1], [0, 0, 0, 0, 0, 2, 0, 0, 1, 4, 1, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0], [1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 2, 1], [0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 2, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1], [1, 3, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1], [1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 1], [1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]]; // Initialize the game level function initLevel() { // Clear existing entities clearLevel(); // Create walls, pellets, power pellets, and pacman based on the level layout var layout = levelLayouts[level - 1] || levelLayouts[0]; for (var y = 0; y < layout.length; y++) { for (var x = 0; x < layout[y].length; x++) { var xPos = MAZE_X_OFFSET + x * TILE_SIZE + TILE_SIZE / 2; var yPos = MAZE_Y_OFFSET + y * TILE_SIZE + TILE_SIZE / 2; switch (layout[y][x]) { case 1: // Wall var wall = new Wall(); wall.x = xPos; wall.y = yPos; game.addChild(wall); walls.push(wall); break; case 2: // Pellet var pellet = new Pellet(); pellet.x = xPos; pellet.y = yPos; game.addChild(pellet); pellets.push(pellet); break; case 3: // Power Pellet var powerPellet = new PowerPellet(); powerPellet.x = xPos; powerPellet.y = yPos; game.addChild(powerPellet); powerPellets.push(powerPellet); break; case 4: // Pacman spawn var pacman = new Pacman(); pacman.x = xPos; pacman.y = yPos; game.addChild(pacman); pacmans.push(pacman); break; case 5: // Ghost spawn (player) player = new Ghost(); player.x = xPos; player.y = yPos; game.addChild(player); break; } } } // Make sure we have at least one Pacman if (pacmans.length === 0) { var pacman = new Pacman(); pacman.x = MAZE_X_OFFSET + GRID_WIDTH / 2 * TILE_SIZE; pacman.y = MAZE_Y_OFFSET + GRID_HEIGHT / 2 * TILE_SIZE; game.addChild(pacman); pacmans.push(pacman); } // Update UI updateUI(); // Play background music LK.playMusic('gameMusic'); } // Clear all game entities function clearLevel() { // Remove all entities for (var i = 0; i < walls.length; i++) { walls[i].destroy(); } walls = []; for (var i = 0; i < pellets.length; i++) { pellets[i].destroy(); } pellets = []; for (var i = 0; i < powerPellets.length; i++) { powerPellets[i].destroy(); } powerPellets = []; for (var i = 0; i < pacmans.length; i++) { pacmans[i].destroy(); } pacmans = []; if (player) { player.destroy(); player = null; } } // Initialize UI elements function initUI() { // Score text scoreTxt = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); // Level text levelTxt = new Text2('Level: 1', { size: 70, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); // Lives text livesTxt = new Text2('Lives: 3', { size: 70, fill: 0xFFFFFF }); livesTxt.anchor.set(1, 0); LK.gui.topRight.addChild(livesTxt); // Position the UI elements scoreTxt.x = -scoreTxt.width - 20; scoreTxt.y = 20; levelTxt.y = 20; livesTxt.x = -20; livesTxt.y = scoreTxt.y + scoreTxt.height + 10; } // Update UI elements function updateUI() { scoreTxt.setText('Score: ' + LK.getScore()); levelTxt.setText('Level: ' + level); livesTxt.setText('Lives: ' + lives); } // Utility function to check if a position has a wall function isWallAtPosition(x, y) { for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var dx = Math.abs(wall.x - x); var dy = Math.abs(wall.y - y); if (dx < TILE_SIZE / 2 && dy < TILE_SIZE / 2) { return true; } } return false; } // Handle player movement function handleMove(x, y, obj) { if (!player) { return; } // Calculate the direction the player wants to move var targetX = x; var targetY = y; // Get the current tile position of the player var currentTileX = Math.floor((player.x - MAZE_X_OFFSET) / TILE_SIZE); var currentTileY = Math.floor((player.y - MAZE_Y_OFFSET) / TILE_SIZE); // Calculate the target tile position var targetTileX = Math.floor((targetX - MAZE_X_OFFSET) / TILE_SIZE); var targetTileY = Math.floor((targetY - MAZE_Y_OFFSET) / TILE_SIZE); // Determine the direction to move (only allow cardinal directions) var dx = targetTileX - currentTileX; var dy = targetTileY - currentTileY; // Find the dominant direction if (Math.abs(dx) > Math.abs(dy)) { // Move horizontally player.moveInDirection(dx > 0 ? 1 : 3); } else { // Move vertically player.moveInDirection(dy > 0 ? 2 : 0); } } // Handle player activation of power mode function activatePowerMode() { // Clear any existing power mode timeout if (powerModeTimeout) { LK.clearTimeout(powerModeTimeout); } powerMode = true; player.makeVulnerable(5000); // Make player vulnerable for 5 seconds // Play power up sound LK.getSound('powerUp').play(); // Set timeout to end power mode powerModeTimeout = LK.setTimeout(function () { powerMode = false; }, 5000); } // Handle player death function playerDeath() { // Play death sound LK.getSound('death').play(); // Decrement lives lives--; updateUI(); // Check if game over if (lives <= 0) { LK.showGameOver(); return; } // Reset player position var layout = levelLayouts[level - 1] || levelLayouts[0]; for (var y = 0; y < layout.length; y++) { for (var x = 0; x < layout[y].length; x++) { if (layout[y][x] === 5) { // Ghost spawn player.x = MAZE_X_OFFSET + x * TILE_SIZE + TILE_SIZE / 2; player.y = MAZE_Y_OFFSET + y * TILE_SIZE + TILE_SIZE / 2; player.moving = false; player.direction = { x: 0, y: 0 }; player.vulnerable = false; break; } } } // Flash the screen LK.effects.flashScreen(0xFF0000, 500); } // Handle eating a Pacman function eatPacman(pacman) { var pacmanIndex = pacmans.indexOf(pacman); if (pacmanIndex !== -1) { // Play eat sound LK.getSound('eat').play(); // Remove pacman pacman.destroy(); pacmans.splice(pacmanIndex, 1); // Increase score LK.setScore(LK.getScore() + 200); pacmansEaten++; updateUI(); // Check for level completion if (pacmans.length === 0) { levelComplete(); } } } // Handle level completion function levelComplete() { // Increase level level++; // Flash the screen LK.effects.flashScreen(0x00FF00, 500); // Initialize the next level LK.setTimeout(function () { initLevel(); }, 1000); } // Initialize the game function initGame() { // Initialize game variables level = 1; pelletsCollected = 0; pacmansEaten = 0; lives = 3; powerMode = false; LK.setScore(0); // Initialize UI initUI(); // Initialize the level initLevel(); } // Touch/mouse events game.down = function (x, y, obj) { handleMove(x, y, obj); }; game.move = function (x, y, obj) { // No continuous movement handling needed }; // Main game update function game.update = function () { if (!player) { return; } // Check for collisions with pellets for (var i = pellets.length - 1; i >= 0; i--) { var pellet = pellets[i]; if (player.intersects(pellet)) { // Remove pellet pellet.destroy(); pellets.splice(i, 1); // Increase score LK.setScore(LK.getScore() + 10); pelletsCollected++; updateUI(); } } // Check for collisions with power pellets for (var i = powerPellets.length - 1; i >= 0; i--) { var powerPellet = powerPellets[i]; if (player.intersects(powerPellet)) { // Remove power pellet powerPellet.destroy(); powerPellets.splice(i, 1); // Activate power mode (Pacman hunts ghost) activatePowerMode(); // Increase score LK.setScore(LK.getScore() + 50); updateUI(); } } // Check for collisions with Pacmans for (var i = pacmans.length - 1; i >= 0; i--) { var pacman = pacmans[i]; if (player.intersects(pacman)) { if (player.vulnerable) { // Ghost is vulnerable, player dies playerDeath(); } else { // Ghost eats Pacman eatPacman(pacman); } } } }; // Initialize the game on startup initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ghost = Container.expand(function () {
var self = Container.call(this);
var ghostGraphics = self.attachAsset('ghost', {
anchorX: 0.5,
anchorY: 0.5
});
// Ghost properties
self.speed = 5;
self.vulnerable = false;
self.direction = {
x: 0,
y: 0
};
self.targetPosition = {
x: 0,
y: 0
};
self.moving = false;
// Direction constants
self.DIRECTIONS = [{
x: 0,
y: -1
},
// Up
{
x: 1,
y: 0
},
// Right
{
x: 0,
y: 1
},
// Down
{
x: -1,
y: 0
} // Left
];
// Method to make ghost vulnerable when Pac-Man eats a power pellet
self.makeVulnerable = function (duration) {
self.vulnerable = true;
ghostGraphics.tint = 0x0000FF; // Blue when vulnerable
// Reset vulnerability after duration
LK.setTimeout(function () {
self.vulnerable = false;
ghostGraphics.tint = 0xFFFFFF; // Reset tint
}, duration);
};
// Update ghost movement
self.update = function () {
if (self.moving) {
// Move towards target position
var dx = self.targetPosition.x - self.x;
var dy = self.targetPosition.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.speed) {
// Reached target, stop moving
self.x = self.targetPosition.x;
self.y = self.targetPosition.y;
self.moving = false;
} else {
// Continue moving towards target
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
};
// Method to move in a specific direction if possible
self.moveInDirection = function (dirIndex) {
if (dirIndex >= 0 && dirIndex < self.DIRECTIONS.length) {
var dir = self.DIRECTIONS[dirIndex];
// Set direction and target position
self.direction = dir;
self.targetPosition = {
x: self.x + dir.x * TILE_SIZE,
y: self.y + dir.y * TILE_SIZE
};
// Check if the move is valid (no wall)
var canMove = !isWallAtPosition(self.targetPosition.x, self.targetPosition.y);
if (canMove) {
self.moving = true;
return true;
}
}
return false;
};
return self;
});
var Pacman = Container.expand(function () {
var self = Container.call(this);
var pacmanGraphics = self.attachAsset('pacman', {
anchorX: 0.5,
anchorY: 0.5
});
// Pacman properties
self.speed = 4; // Slightly slower than ghost
self.direction = {
x: 0,
y: 0
};
self.active = true;
// Direction constants
self.DIRECTIONS = [{
x: 0,
y: -1
},
// Up
{
x: 1,
y: 0
},
// Right
{
x: 0,
y: 1
},
// Down
{
x: -1,
y: 0
} // Left
];
// Update pacman movement - simple AI
self.update = function () {
if (!self.active) {
return;
}
// Only change direction occasionally to make movement more predictable
if (LK.ticks % 30 === 0) {
// Get ghost position
var ghost = player;
// Simple AI: Try to move away from ghost
var dx = self.x - ghost.x;
var dy = self.y - ghost.y;
// Check if ghost is vulnerable
var avoidGhost = !ghost.vulnerable;
// Decide direction based on ghost position
var possibleDirs = [];
// Check each direction for walls
for (var i = 0; i < self.DIRECTIONS.length; i++) {
var dir = self.DIRECTIONS[i];
var newX = self.x + dir.x * TILE_SIZE;
var newY = self.y + dir.y * TILE_SIZE;
if (!isWallAtPosition(newX, newY)) {
possibleDirs.push({
dirIndex: i,
value: (avoidGhost ? 1 : -1) * (dir.x * dx + dir.y * dy)
});
}
}
// Sort directions by value (highest value first)
possibleDirs.sort(function (a, b) {
return b.value - a.value;
});
// Choose a direction if possible
if (possibleDirs.length > 0) {
// 70% chance to pick the best direction, 30% chance to pick a random valid direction
var dirIndex = Math.random() < 0.7 ? possibleDirs[0].dirIndex : possibleDirs[Math.floor(Math.random() * possibleDirs.length)].dirIndex;
self.direction = self.DIRECTIONS[dirIndex];
// Set rotation based on direction
if (self.direction.x === 1) {
pacmanGraphics.rotation = 0;
} else if (self.direction.x === -1) {
pacmanGraphics.rotation = Math.PI;
} else if (self.direction.y === 1) {
pacmanGraphics.rotation = Math.PI / 2;
} else if (self.direction.y === -1) {
pacmanGraphics.rotation = -Math.PI / 2;
}
}
}
// Move in current direction if possible
var newX = self.x + self.direction.x * self.speed;
var newY = self.y + self.direction.y * self.speed;
if (!isWallAtPosition(newX, newY)) {
self.x = newX;
self.y = newY;
} else {
// Hit wall, stop and change direction next update
self.direction = {
x: 0,
y: 0
};
}
};
return self;
});
var Pellet = Container.expand(function () {
var self = Container.call(this);
var pelletGraphics = self.attachAsset('pellet', {
anchorX: 0.5,
anchorY: 0.5
});
self.isPellet = true;
return self;
});
var PowerPellet = Container.expand(function () {
var self = Container.call(this);
var powerPelletGraphics = self.attachAsset('powerPellet', {
anchorX: 0.5,
anchorY: 0.5
});
self.isPowerPellet = true;
// Power pellet animation - pulsing effect
self.update = function () {
var scale = 0.9 + 0.2 * Math.sin(LK.ticks / 10);
powerPelletGraphics.scale.set(scale, scale);
};
return self;
});
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
self.isWall = true;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Blue wall
// Yellow Pac-Man
// Pink ghost
// Game constants
var TILE_SIZE = 48;
var GRID_WIDTH = 21;
var GRID_HEIGHT = 27;
var MAZE_X_OFFSET = (2048 - GRID_WIDTH * TILE_SIZE) / 2;
var MAZE_Y_OFFSET = (2732 - GRID_HEIGHT * TILE_SIZE) / 2;
// Game variables
var player;
var pacmans = [];
var walls = [];
var pellets = [];
var powerPellets = [];
var level = 1;
var pelletsCollected = 0;
var pacmansEaten = 0;
var lives = 3;
var powerMode = false;
var powerModeTimeout;
// UI elements
var scoreTxt;
var levelTxt;
var livesTxt;
// Game grid - 0: empty, 1: wall, 2: pellet, 3: power pellet, 4: pacman spawn, 5: ghost spawn
var levelLayouts = [
// Level 1 - Simple maze
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1], [1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1], [1, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2, 1], [1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 1, 1, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 1], [1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1], [1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1], [1, 2, 2, 2, 2, 2, 1, 2, 2, 5, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1], [0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 2, 1], [1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 2, 1], [0, 0, 0, 0, 0, 2, 0, 0, 1, 4, 1, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0], [1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 2, 1], [0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 2, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1], [1, 3, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1], [1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 1], [1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]];
// Initialize the game level
function initLevel() {
// Clear existing entities
clearLevel();
// Create walls, pellets, power pellets, and pacman based on the level layout
var layout = levelLayouts[level - 1] || levelLayouts[0];
for (var y = 0; y < layout.length; y++) {
for (var x = 0; x < layout[y].length; x++) {
var xPos = MAZE_X_OFFSET + x * TILE_SIZE + TILE_SIZE / 2;
var yPos = MAZE_Y_OFFSET + y * TILE_SIZE + TILE_SIZE / 2;
switch (layout[y][x]) {
case 1:
// Wall
var wall = new Wall();
wall.x = xPos;
wall.y = yPos;
game.addChild(wall);
walls.push(wall);
break;
case 2:
// Pellet
var pellet = new Pellet();
pellet.x = xPos;
pellet.y = yPos;
game.addChild(pellet);
pellets.push(pellet);
break;
case 3:
// Power Pellet
var powerPellet = new PowerPellet();
powerPellet.x = xPos;
powerPellet.y = yPos;
game.addChild(powerPellet);
powerPellets.push(powerPellet);
break;
case 4:
// Pacman spawn
var pacman = new Pacman();
pacman.x = xPos;
pacman.y = yPos;
game.addChild(pacman);
pacmans.push(pacman);
break;
case 5:
// Ghost spawn (player)
player = new Ghost();
player.x = xPos;
player.y = yPos;
game.addChild(player);
break;
}
}
}
// Make sure we have at least one Pacman
if (pacmans.length === 0) {
var pacman = new Pacman();
pacman.x = MAZE_X_OFFSET + GRID_WIDTH / 2 * TILE_SIZE;
pacman.y = MAZE_Y_OFFSET + GRID_HEIGHT / 2 * TILE_SIZE;
game.addChild(pacman);
pacmans.push(pacman);
}
// Update UI
updateUI();
// Play background music
LK.playMusic('gameMusic');
}
// Clear all game entities
function clearLevel() {
// Remove all entities
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
for (var i = 0; i < pellets.length; i++) {
pellets[i].destroy();
}
pellets = [];
for (var i = 0; i < powerPellets.length; i++) {
powerPellets[i].destroy();
}
powerPellets = [];
for (var i = 0; i < pacmans.length; i++) {
pacmans[i].destroy();
}
pacmans = [];
if (player) {
player.destroy();
player = null;
}
}
// Initialize UI elements
function initUI() {
// Score text
scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
// Level text
levelTxt = new Text2('Level: 1', {
size: 70,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
// Lives text
livesTxt = new Text2('Lives: 3', {
size: 70,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(livesTxt);
// Position the UI elements
scoreTxt.x = -scoreTxt.width - 20;
scoreTxt.y = 20;
levelTxt.y = 20;
livesTxt.x = -20;
livesTxt.y = scoreTxt.y + scoreTxt.height + 10;
}
// Update UI elements
function updateUI() {
scoreTxt.setText('Score: ' + LK.getScore());
levelTxt.setText('Level: ' + level);
livesTxt.setText('Lives: ' + lives);
}
// Utility function to check if a position has a wall
function isWallAtPosition(x, y) {
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
var dx = Math.abs(wall.x - x);
var dy = Math.abs(wall.y - y);
if (dx < TILE_SIZE / 2 && dy < TILE_SIZE / 2) {
return true;
}
}
return false;
}
// Handle player movement
function handleMove(x, y, obj) {
if (!player) {
return;
}
// Calculate the direction the player wants to move
var targetX = x;
var targetY = y;
// Get the current tile position of the player
var currentTileX = Math.floor((player.x - MAZE_X_OFFSET) / TILE_SIZE);
var currentTileY = Math.floor((player.y - MAZE_Y_OFFSET) / TILE_SIZE);
// Calculate the target tile position
var targetTileX = Math.floor((targetX - MAZE_X_OFFSET) / TILE_SIZE);
var targetTileY = Math.floor((targetY - MAZE_Y_OFFSET) / TILE_SIZE);
// Determine the direction to move (only allow cardinal directions)
var dx = targetTileX - currentTileX;
var dy = targetTileY - currentTileY;
// Find the dominant direction
if (Math.abs(dx) > Math.abs(dy)) {
// Move horizontally
player.moveInDirection(dx > 0 ? 1 : 3);
} else {
// Move vertically
player.moveInDirection(dy > 0 ? 2 : 0);
}
}
// Handle player activation of power mode
function activatePowerMode() {
// Clear any existing power mode timeout
if (powerModeTimeout) {
LK.clearTimeout(powerModeTimeout);
}
powerMode = true;
player.makeVulnerable(5000); // Make player vulnerable for 5 seconds
// Play power up sound
LK.getSound('powerUp').play();
// Set timeout to end power mode
powerModeTimeout = LK.setTimeout(function () {
powerMode = false;
}, 5000);
}
// Handle player death
function playerDeath() {
// Play death sound
LK.getSound('death').play();
// Decrement lives
lives--;
updateUI();
// Check if game over
if (lives <= 0) {
LK.showGameOver();
return;
}
// Reset player position
var layout = levelLayouts[level - 1] || levelLayouts[0];
for (var y = 0; y < layout.length; y++) {
for (var x = 0; x < layout[y].length; x++) {
if (layout[y][x] === 5) {
// Ghost spawn
player.x = MAZE_X_OFFSET + x * TILE_SIZE + TILE_SIZE / 2;
player.y = MAZE_Y_OFFSET + y * TILE_SIZE + TILE_SIZE / 2;
player.moving = false;
player.direction = {
x: 0,
y: 0
};
player.vulnerable = false;
break;
}
}
}
// Flash the screen
LK.effects.flashScreen(0xFF0000, 500);
}
// Handle eating a Pacman
function eatPacman(pacman) {
var pacmanIndex = pacmans.indexOf(pacman);
if (pacmanIndex !== -1) {
// Play eat sound
LK.getSound('eat').play();
// Remove pacman
pacman.destroy();
pacmans.splice(pacmanIndex, 1);
// Increase score
LK.setScore(LK.getScore() + 200);
pacmansEaten++;
updateUI();
// Check for level completion
if (pacmans.length === 0) {
levelComplete();
}
}
}
// Handle level completion
function levelComplete() {
// Increase level
level++;
// Flash the screen
LK.effects.flashScreen(0x00FF00, 500);
// Initialize the next level
LK.setTimeout(function () {
initLevel();
}, 1000);
}
// Initialize the game
function initGame() {
// Initialize game variables
level = 1;
pelletsCollected = 0;
pacmansEaten = 0;
lives = 3;
powerMode = false;
LK.setScore(0);
// Initialize UI
initUI();
// Initialize the level
initLevel();
}
// Touch/mouse events
game.down = function (x, y, obj) {
handleMove(x, y, obj);
};
game.move = function (x, y, obj) {
// No continuous movement handling needed
};
// Main game update function
game.update = function () {
if (!player) {
return;
}
// Check for collisions with pellets
for (var i = pellets.length - 1; i >= 0; i--) {
var pellet = pellets[i];
if (player.intersects(pellet)) {
// Remove pellet
pellet.destroy();
pellets.splice(i, 1);
// Increase score
LK.setScore(LK.getScore() + 10);
pelletsCollected++;
updateUI();
}
}
// Check for collisions with power pellets
for (var i = powerPellets.length - 1; i >= 0; i--) {
var powerPellet = powerPellets[i];
if (player.intersects(powerPellet)) {
// Remove power pellet
powerPellet.destroy();
powerPellets.splice(i, 1);
// Activate power mode (Pacman hunts ghost)
activatePowerMode();
// Increase score
LK.setScore(LK.getScore() + 50);
updateUI();
}
}
// Check for collisions with Pacmans
for (var i = pacmans.length - 1; i >= 0; i--) {
var pacman = pacmans[i];
if (player.intersects(pacman)) {
if (player.vulnerable) {
// Ghost is vulnerable, player dies
playerDeath();
} else {
// Ghost eats Pacman
eatPacman(pacman);
}
}
}
};
// Initialize the game on startup
initGame();