/****
* 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(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,580 @@
-/****
+/****
+* 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
-});
\ No newline at end of file
+});
+
+/****
+* 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();
\ No newline at end of file