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