/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var MazeCell = Container.expand(function () { var self = Container.call(this); self.isWall = false; self.isExit = false; self.gridX = 0; self.gridY = 0; self.setAsWall = function () { self.isWall = true; self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); }; self.setAsFloor = function () { self.isWall = false; self.attachAsset('floor', { anchorX: 0.5, anchorY: 0.5 }); }; self.setAsExit = function () { self.isExit = true; self.attachAsset('exit', { anchorX: 0.5, anchorY: 0.5 }); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.gridX = 0; self.gridY = 0; self.isMoving = false; self.moveToGrid = function (gridX, gridY) { if (self.isMoving) return; // Validate boundaries before moving if (gridX < 1 || gridX >= MAZE_COLS - 1 || gridY < 1 || gridY >= MAZE_ROWS - 1) { return; } self.isMoving = true; self.gridX = gridX; self.gridY = gridY; var mazeWidth = MAZE_COLS * CELL_SIZE; var mazeHeight = MAZE_ROWS * CELL_SIZE; var offsetX = (2048 - mazeWidth) / 2; var offsetY = (2732 - mazeHeight) / 2; var targetX = gridX * CELL_SIZE + CELL_SIZE / 2 + offsetX; var targetY = gridY * CELL_SIZE + CELL_SIZE / 2 + offsetY; tween(self, { x: targetX, y: targetY }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { self.isMoving = false; LK.getSound('move').play(); // Check if reached exit if (gridX === exitX && gridY === exitY) { completeLevel(); } } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1E1E1E }); /**** * Game Code ****/ // Game constants var CELL_SIZE = 80; var MAZE_COLS = 20; var MAZE_ROWS = 20; var MAX_LEVEL = 30; // Game variables var currentLevel = storage.currentLevel || 1; var player = null; var maze = []; var startX = 1; var startY = 1; var exitX = 18; var exitY = 18; var levelStartTime = Date.now(); var dragStartPos = null; var isGameComplete = false; // UI elements var levelText = new Text2('Level 1', { size: 80, fill: '#FFFFFF' }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); var timeText = new Text2('Time: 0s', { size: 60, fill: '#CCCCCC' }); timeText.anchor.set(0, 0); timeText.x = 50; timeText.y = 150; LK.gui.topLeft.addChild(timeText); // Maze layouts for each level - Progressive difficulty var mazeLevels = [ // Level 1 - Very easy, mostly empty [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], // Level 2 - Add some walls to create basic obstacles [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], // Level 3 - More complex with multiple obstacles [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]]; // Generate more complex maze layouts function generateMazeLayout(level) { if (level <= mazeLevels.length) { return mazeLevels[level - 1]; } // Generate procedural maze for higher levels var layout = []; for (var y = 0; y < MAZE_ROWS; y++) { layout[y] = []; for (var x = 0; x < MAZE_COLS; x++) { if (x === 0 || y === 0 || x === MAZE_COLS - 1 || y === MAZE_ROWS - 1) { layout[y][x] = 1; // Border walls } else if (x === startX && y === startY) { layout[y][x] = 0; // Start position } else if (x === exitX && y === exitY) { layout[y][x] = 0; // Exit position } else { // Progressive difficulty: increase wall density and complexity as level increases var baseComplexity = 0.1; // Base 10% wall density var levelMultiplier = Math.min(level * 0.05, 0.4); // Increase by 5% per level, max 40% var finalComplexity = baseComplexity + levelMultiplier; // Add pattern complexity for higher levels if (level >= 5) { // Create corridors and rooms for higher levels var isCorridorX = x % 4 === 0; var isCorridorY = y % 4 === 0; if (isCorridorX || isCorridorY) { layout[y][x] = Math.random() < finalComplexity * 0.3 ? 1 : 0; } else { layout[y][x] = Math.random() < finalComplexity ? 1 : 0; } } else { layout[y][x] = Math.random() < finalComplexity ? 1 : 0; } } } } // Ensure path from start to exit exists layout[startY][startX] = 0; layout[exitY][exitX] = 0; return layout; } function initializeMaze() { // Clear existing maze for (var i = 0; i < maze.length; i++) { for (var j = 0; j < maze[i].length; j++) { if (maze[i][j]) { maze[i][j].destroy(); } } } maze = []; // Get maze layout for current level var layout = generateMazeLayout(currentLevel); // Create maze for (var y = 0; y < MAZE_ROWS; y++) { maze[y] = []; for (var x = 0; x < MAZE_COLS; x++) { var cell = new MazeCell(); cell.gridX = x; cell.gridY = y; cell.x = x * CELL_SIZE + CELL_SIZE / 2; cell.y = y * CELL_SIZE + CELL_SIZE / 2; if (layout[y][x] === 1) { cell.setAsWall(); } else { cell.setAsFloor(); } // Set exit if (x === exitX && y === exitY) { cell.setAsExit(); } maze[y][x] = cell; game.addChild(cell); } } // Position maze in center of screen var mazeWidth = MAZE_COLS * CELL_SIZE; var mazeHeight = MAZE_ROWS * CELL_SIZE; var offsetX = (2048 - mazeWidth) / 2; var offsetY = (2732 - mazeHeight) / 2; for (var y = 0; y < MAZE_ROWS; y++) { for (var x = 0; x < MAZE_COLS; x++) { maze[y][x].x += offsetX; maze[y][x].y += offsetY; } } } function initializePlayer() { if (player) { player.destroy(); } player = new Player(); player.gridX = startX; player.gridY = startY; var mazeWidth = MAZE_COLS * CELL_SIZE; var mazeHeight = MAZE_ROWS * CELL_SIZE; var offsetX = (2048 - mazeWidth) / 2; var offsetY = (2732 - mazeHeight) / 2; player.x = startX * CELL_SIZE + CELL_SIZE / 2 + offsetX; player.y = startY * CELL_SIZE + CELL_SIZE / 2 + offsetY; game.addChild(player); } function canMoveTo(gridX, gridY) { if (gridX < 0 || gridX >= MAZE_COLS || gridY < 0 || gridY >= MAZE_ROWS) { return false; } if (gridX < 1 || gridX >= MAZE_COLS - 1 || gridY < 1 || gridY >= MAZE_ROWS - 1) { return false; } return !maze[gridY][gridX].isWall; } function movePlayer(deltaX, deltaY) { if (player.isMoving) return; // Try to move up to 2 steps, but stop at first wall var steps = 2; var validSteps = 0; for (var i = 1; i <= steps; i++) { var checkX = player.gridX + deltaX * i; var checkY = player.gridY + deltaY * i; // Strict boundary check to ensure player stays within valid maze bounds if (checkX < 1 || checkX >= MAZE_COLS - 1 || checkY < 1 || checkY >= MAZE_ROWS - 1) { break; } // Additional check to ensure we don't go outside maze grid if (checkX < 0 || checkX >= MAZE_COLS || checkY < 0 || checkY >= MAZE_ROWS) { break; } if (!canMoveTo(checkX, checkY)) { break; } validSteps = i; } // Move to the last valid position (at least 1 step if possible) if (validSteps > 0) { var newX = player.gridX + deltaX * validSteps; var newY = player.gridY + deltaY * validSteps; player.moveToGrid(newX, newY); } } function completeLevel() { LK.getSound('complete').play(); var completionTime = Math.floor((Date.now() - levelStartTime) / 1000); if (currentLevel >= MAX_LEVEL) { // Game completed isGameComplete = true; LK.getSound('win').play(); LK.showYouWin(); return; } // Next level currentLevel++; storage.currentLevel = currentLevel; LK.effects.flashScreen(0x4CAF50, 500); // Start next level after delay LK.setTimeout(function () { startLevel(); }, 1000); } function startLevel() { levelStartTime = Date.now(); levelText.setText('Level ' + currentLevel); // Adjust exit position based on level if (currentLevel <= 10) { exitX = 18; exitY = 18; } else if (currentLevel <= 20) { exitX = 18; exitY = 1; } else { exitX = 1; exitY = 18; } initializeMaze(); initializePlayer(); } function restartLevel() { levelStartTime = Date.now(); initializePlayer(); } // Touch controls function handleMove(x, y, obj) { if (!dragStartPos || player.isMoving) return; var deltaX = x - dragStartPos.x; var deltaY = y - dragStartPos.y; var threshold = 40; if (Math.abs(deltaX) > threshold || Math.abs(deltaY) > threshold) { if (Math.abs(deltaX) > Math.abs(deltaY)) { // Horizontal movement if (deltaX > 0) { movePlayer(1, 0); // Right } else { movePlayer(-1, 0); // Left } } else { // Vertical movement if (deltaY > 0) { movePlayer(0, 1); // Down } else { movePlayer(0, -1); // Up } } dragStartPos = null; } } game.move = handleMove; game.down = function (x, y, obj) { dragStartPos = { x: x, y: y }; }; game.up = function (x, y, obj) { dragStartPos = null; }; game.update = function () { // Update timer var currentTime = Math.floor((Date.now() - levelStartTime) / 1000); timeText.setText('Time: ' + currentTime + 's'); // Check for level restart (tap on player) if (player && !player.isMoving) { // Additional game logic can be added here } }; // Arrow key UI controls var arrowContainer = new Container(); arrowContainer.x = 2048 / 2; arrowContainer.y = 2732 - 200; LK.gui.addChild(arrowContainer); // Arrow button size and positions var ARROW_SIZE = 120; var ARROW_SPACING = 160; // Up arrow var upArrow = LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.8, tint: 0x4CAF50 }); upArrow.x = 0; upArrow.y = -ARROW_SPACING; upArrow.down = function (x, y, obj) { movePlayer(0, -1); // Move up }; arrowContainer.addChild(upArrow); // Down arrow var downArrow = LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.8, tint: 0x4CAF50 }); downArrow.x = 0; downArrow.y = ARROW_SPACING; downArrow.down = function (x, y, obj) { movePlayer(0, 1); // Move down }; arrowContainer.addChild(downArrow); // Left arrow var leftArrow = LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 1.5, tint: 0x4CAF50 }); leftArrow.x = -ARROW_SPACING; leftArrow.y = 0; leftArrow.down = function (x, y, obj) { movePlayer(-1, 0); // Move left }; arrowContainer.addChild(leftArrow); // Right arrow var rightArrow = LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 1.5, tint: 0x4CAF50 }); rightArrow.x = ARROW_SPACING; rightArrow.y = 0; rightArrow.down = function (x, y, obj) { movePlayer(1, 0); // Move right }; arrowContainer.addChild(rightArrow); // Arrow direction indicators using text var upText = new Text2('↑', { size: 80, fill: '#FFFFFF' }); upText.anchor.set(0.5, 0.5); upText.x = upArrow.x; upText.y = upArrow.y; arrowContainer.addChild(upText); var downText = new Text2('↓', { size: 80, fill: '#FFFFFF' }); downText.anchor.set(0.5, 0.5); downText.x = downArrow.x; downText.y = downArrow.y; arrowContainer.addChild(downText); var leftText = new Text2('←', { size: 80, fill: '#FFFFFF' }); leftText.anchor.set(0.5, 0.5); leftText.x = leftArrow.x; leftText.y = leftArrow.y; arrowContainer.addChild(leftText); var rightText = new Text2('→', { size: 80, fill: '#FFFFFF' }); rightText.anchor.set(0.5, 0.5); rightText.x = rightArrow.x; rightText.y = rightArrow.y; arrowContainer.addChild(rightText); // Initialize game startLevel();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var MazeCell = Container.expand(function () {
var self = Container.call(this);
self.isWall = false;
self.isExit = false;
self.gridX = 0;
self.gridY = 0;
self.setAsWall = function () {
self.isWall = true;
self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
};
self.setAsFloor = function () {
self.isWall = false;
self.attachAsset('floor', {
anchorX: 0.5,
anchorY: 0.5
});
};
self.setAsExit = function () {
self.isExit = true;
self.attachAsset('exit', {
anchorX: 0.5,
anchorY: 0.5
});
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.gridX = 0;
self.gridY = 0;
self.isMoving = false;
self.moveToGrid = function (gridX, gridY) {
if (self.isMoving) return;
// Validate boundaries before moving
if (gridX < 1 || gridX >= MAZE_COLS - 1 || gridY < 1 || gridY >= MAZE_ROWS - 1) {
return;
}
self.isMoving = true;
self.gridX = gridX;
self.gridY = gridY;
var mazeWidth = MAZE_COLS * CELL_SIZE;
var mazeHeight = MAZE_ROWS * CELL_SIZE;
var offsetX = (2048 - mazeWidth) / 2;
var offsetY = (2732 - mazeHeight) / 2;
var targetX = gridX * CELL_SIZE + CELL_SIZE / 2 + offsetX;
var targetY = gridY * CELL_SIZE + CELL_SIZE / 2 + offsetY;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isMoving = false;
LK.getSound('move').play();
// Check if reached exit
if (gridX === exitX && gridY === exitY) {
completeLevel();
}
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1E1E1E
});
/****
* Game Code
****/
// Game constants
var CELL_SIZE = 80;
var MAZE_COLS = 20;
var MAZE_ROWS = 20;
var MAX_LEVEL = 30;
// Game variables
var currentLevel = storage.currentLevel || 1;
var player = null;
var maze = [];
var startX = 1;
var startY = 1;
var exitX = 18;
var exitY = 18;
var levelStartTime = Date.now();
var dragStartPos = null;
var isGameComplete = false;
// UI elements
var levelText = new Text2('Level 1', {
size: 80,
fill: '#FFFFFF'
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var timeText = new Text2('Time: 0s', {
size: 60,
fill: '#CCCCCC'
});
timeText.anchor.set(0, 0);
timeText.x = 50;
timeText.y = 150;
LK.gui.topLeft.addChild(timeText);
// Maze layouts for each level - Progressive difficulty
var mazeLevels = [
// Level 1 - Very easy, mostly empty
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
// Level 2 - Add some walls to create basic obstacles
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
// Level 3 - More complex with multiple obstacles
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]];
// Generate more complex maze layouts
function generateMazeLayout(level) {
if (level <= mazeLevels.length) {
return mazeLevels[level - 1];
}
// Generate procedural maze for higher levels
var layout = [];
for (var y = 0; y < MAZE_ROWS; y++) {
layout[y] = [];
for (var x = 0; x < MAZE_COLS; x++) {
if (x === 0 || y === 0 || x === MAZE_COLS - 1 || y === MAZE_ROWS - 1) {
layout[y][x] = 1; // Border walls
} else if (x === startX && y === startY) {
layout[y][x] = 0; // Start position
} else if (x === exitX && y === exitY) {
layout[y][x] = 0; // Exit position
} else {
// Progressive difficulty: increase wall density and complexity as level increases
var baseComplexity = 0.1; // Base 10% wall density
var levelMultiplier = Math.min(level * 0.05, 0.4); // Increase by 5% per level, max 40%
var finalComplexity = baseComplexity + levelMultiplier;
// Add pattern complexity for higher levels
if (level >= 5) {
// Create corridors and rooms for higher levels
var isCorridorX = x % 4 === 0;
var isCorridorY = y % 4 === 0;
if (isCorridorX || isCorridorY) {
layout[y][x] = Math.random() < finalComplexity * 0.3 ? 1 : 0;
} else {
layout[y][x] = Math.random() < finalComplexity ? 1 : 0;
}
} else {
layout[y][x] = Math.random() < finalComplexity ? 1 : 0;
}
}
}
}
// Ensure path from start to exit exists
layout[startY][startX] = 0;
layout[exitY][exitX] = 0;
return layout;
}
function initializeMaze() {
// Clear existing maze
for (var i = 0; i < maze.length; i++) {
for (var j = 0; j < maze[i].length; j++) {
if (maze[i][j]) {
maze[i][j].destroy();
}
}
}
maze = [];
// Get maze layout for current level
var layout = generateMazeLayout(currentLevel);
// Create maze
for (var y = 0; y < MAZE_ROWS; y++) {
maze[y] = [];
for (var x = 0; x < MAZE_COLS; x++) {
var cell = new MazeCell();
cell.gridX = x;
cell.gridY = y;
cell.x = x * CELL_SIZE + CELL_SIZE / 2;
cell.y = y * CELL_SIZE + CELL_SIZE / 2;
if (layout[y][x] === 1) {
cell.setAsWall();
} else {
cell.setAsFloor();
}
// Set exit
if (x === exitX && y === exitY) {
cell.setAsExit();
}
maze[y][x] = cell;
game.addChild(cell);
}
}
// Position maze in center of screen
var mazeWidth = MAZE_COLS * CELL_SIZE;
var mazeHeight = MAZE_ROWS * CELL_SIZE;
var offsetX = (2048 - mazeWidth) / 2;
var offsetY = (2732 - mazeHeight) / 2;
for (var y = 0; y < MAZE_ROWS; y++) {
for (var x = 0; x < MAZE_COLS; x++) {
maze[y][x].x += offsetX;
maze[y][x].y += offsetY;
}
}
}
function initializePlayer() {
if (player) {
player.destroy();
}
player = new Player();
player.gridX = startX;
player.gridY = startY;
var mazeWidth = MAZE_COLS * CELL_SIZE;
var mazeHeight = MAZE_ROWS * CELL_SIZE;
var offsetX = (2048 - mazeWidth) / 2;
var offsetY = (2732 - mazeHeight) / 2;
player.x = startX * CELL_SIZE + CELL_SIZE / 2 + offsetX;
player.y = startY * CELL_SIZE + CELL_SIZE / 2 + offsetY;
game.addChild(player);
}
function canMoveTo(gridX, gridY) {
if (gridX < 0 || gridX >= MAZE_COLS || gridY < 0 || gridY >= MAZE_ROWS) {
return false;
}
if (gridX < 1 || gridX >= MAZE_COLS - 1 || gridY < 1 || gridY >= MAZE_ROWS - 1) {
return false;
}
return !maze[gridY][gridX].isWall;
}
function movePlayer(deltaX, deltaY) {
if (player.isMoving) return;
// Try to move up to 2 steps, but stop at first wall
var steps = 2;
var validSteps = 0;
for (var i = 1; i <= steps; i++) {
var checkX = player.gridX + deltaX * i;
var checkY = player.gridY + deltaY * i;
// Strict boundary check to ensure player stays within valid maze bounds
if (checkX < 1 || checkX >= MAZE_COLS - 1 || checkY < 1 || checkY >= MAZE_ROWS - 1) {
break;
}
// Additional check to ensure we don't go outside maze grid
if (checkX < 0 || checkX >= MAZE_COLS || checkY < 0 || checkY >= MAZE_ROWS) {
break;
}
if (!canMoveTo(checkX, checkY)) {
break;
}
validSteps = i;
}
// Move to the last valid position (at least 1 step if possible)
if (validSteps > 0) {
var newX = player.gridX + deltaX * validSteps;
var newY = player.gridY + deltaY * validSteps;
player.moveToGrid(newX, newY);
}
}
function completeLevel() {
LK.getSound('complete').play();
var completionTime = Math.floor((Date.now() - levelStartTime) / 1000);
if (currentLevel >= MAX_LEVEL) {
// Game completed
isGameComplete = true;
LK.getSound('win').play();
LK.showYouWin();
return;
}
// Next level
currentLevel++;
storage.currentLevel = currentLevel;
LK.effects.flashScreen(0x4CAF50, 500);
// Start next level after delay
LK.setTimeout(function () {
startLevel();
}, 1000);
}
function startLevel() {
levelStartTime = Date.now();
levelText.setText('Level ' + currentLevel);
// Adjust exit position based on level
if (currentLevel <= 10) {
exitX = 18;
exitY = 18;
} else if (currentLevel <= 20) {
exitX = 18;
exitY = 1;
} else {
exitX = 1;
exitY = 18;
}
initializeMaze();
initializePlayer();
}
function restartLevel() {
levelStartTime = Date.now();
initializePlayer();
}
// Touch controls
function handleMove(x, y, obj) {
if (!dragStartPos || player.isMoving) return;
var deltaX = x - dragStartPos.x;
var deltaY = y - dragStartPos.y;
var threshold = 40;
if (Math.abs(deltaX) > threshold || Math.abs(deltaY) > threshold) {
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Horizontal movement
if (deltaX > 0) {
movePlayer(1, 0); // Right
} else {
movePlayer(-1, 0); // Left
}
} else {
// Vertical movement
if (deltaY > 0) {
movePlayer(0, 1); // Down
} else {
movePlayer(0, -1); // Up
}
}
dragStartPos = null;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragStartPos = {
x: x,
y: y
};
};
game.up = function (x, y, obj) {
dragStartPos = null;
};
game.update = function () {
// Update timer
var currentTime = Math.floor((Date.now() - levelStartTime) / 1000);
timeText.setText('Time: ' + currentTime + 's');
// Check for level restart (tap on player)
if (player && !player.isMoving) {
// Additional game logic can be added here
}
};
// Arrow key UI controls
var arrowContainer = new Container();
arrowContainer.x = 2048 / 2;
arrowContainer.y = 2732 - 200;
LK.gui.addChild(arrowContainer);
// Arrow button size and positions
var ARROW_SIZE = 120;
var ARROW_SPACING = 160;
// Up arrow
var upArrow = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.8,
tint: 0x4CAF50
});
upArrow.x = 0;
upArrow.y = -ARROW_SPACING;
upArrow.down = function (x, y, obj) {
movePlayer(0, -1); // Move up
};
arrowContainer.addChild(upArrow);
// Down arrow
var downArrow = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.8,
tint: 0x4CAF50
});
downArrow.x = 0;
downArrow.y = ARROW_SPACING;
downArrow.down = function (x, y, obj) {
movePlayer(0, 1); // Move down
};
arrowContainer.addChild(downArrow);
// Left arrow
var leftArrow = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 1.5,
tint: 0x4CAF50
});
leftArrow.x = -ARROW_SPACING;
leftArrow.y = 0;
leftArrow.down = function (x, y, obj) {
movePlayer(-1, 0); // Move left
};
arrowContainer.addChild(leftArrow);
// Right arrow
var rightArrow = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 1.5,
tint: 0x4CAF50
});
rightArrow.x = ARROW_SPACING;
rightArrow.y = 0;
rightArrow.down = function (x, y, obj) {
movePlayer(1, 0); // Move right
};
arrowContainer.addChild(rightArrow);
// Arrow direction indicators using text
var upText = new Text2('↑', {
size: 80,
fill: '#FFFFFF'
});
upText.anchor.set(0.5, 0.5);
upText.x = upArrow.x;
upText.y = upArrow.y;
arrowContainer.addChild(upText);
var downText = new Text2('↓', {
size: 80,
fill: '#FFFFFF'
});
downText.anchor.set(0.5, 0.5);
downText.x = downArrow.x;
downText.y = downArrow.y;
arrowContainer.addChild(downText);
var leftText = new Text2('←', {
size: 80,
fill: '#FFFFFF'
});
leftText.anchor.set(0.5, 0.5);
leftText.x = leftArrow.x;
leftText.y = leftArrow.y;
arrowContainer.addChild(leftText);
var rightText = new Text2('→', {
size: 80,
fill: '#FFFFFF'
});
rightText.anchor.set(0.5, 0.5);
rightText.x = rightArrow.x;
rightText.y = rightArrow.y;
arrowContainer.addChild(rightText);
// Initialize game
startLevel();