/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var DoorRenderer = Container.expand(function () {
	var self = Container.call(this);
	self.doors = [];
	self.createDoor = function (x, y, roomNumber) {
		var doorContainer = new Container();
		// Door frame - made bigger and more prominent
		var frame = LK.getAsset('door_frame', {
			anchorX: 0.5,
			anchorY: 1.0,
			width: 80,
			height: 100
		});
		frame.tint = 0x4a2c2a;
		doorContainer.addChild(frame);
		// Door panel - made more prominent
		var panel = LK.getAsset('door', {
			anchorX: 0.5,
			anchorY: 1.0,
			y: -8,
			width: 72,
			height: 80
		});
		panel.tint = 0x8b4513;
		doorContainer.addChild(panel);
		// Door handle
		var handle = LK.getAsset('door_handle', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 25,
			y: -40
		});
		handle.tint = 0xffd700;
		doorContainer.addChild(handle);
		// Door nameplate with dimensions
		var nameplate = LK.getAsset('door_nameplate', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 0,
			y: -65
		});
		nameplate.tint = 0xc0c0c0;
		doorContainer.addChild(nameplate);
		// Room number text
		var numberText = new Text2(roomNumber.toString(), {
			size: 20,
			fill: 0x000000
		});
		numberText.anchor.set(0.5, 0.5);
		numberText.x = 0;
		numberText.y = -72;
		doorContainer.addChild(numberText);
		// Dimension text on nameplate
		var dimensionText = new Text2('80x100', {
			size: 12,
			fill: 0x000000
		});
		dimensionText.anchor.set(0.5, 0.5);
		dimensionText.x = 0;
		dimensionText.y = -58;
		doorContainer.addChild(dimensionText);
		doorContainer.x = x;
		doorContainer.y = y;
		return doorContainer;
	};
	return self;
});
var MazeGenerator = Container.expand(function () {
	var self = Container.call(this);
	self.generate = function (width, height) {
		var maze = {
			width: width,
			height: height,
			grid: [],
			startX: 1,
			startY: 1,
			endX: width - 2,
			endY: height - 2,
			rooms: [],
			currentRoom: 0
		};
		// Initialize maze with walls
		for (var y = 0; y < height; y++) {
			maze.grid[y] = [];
			for (var x = 0; x < width; x++) {
				maze.grid[y][x] = 1; // Wall
			}
		}
		// Create linear sequence of rooms like Doors game
		self.createLinearRooms(maze);
		// Ensure start and end are open
		maze.grid[maze.startY][maze.startX] = 0;
		maze.grid[maze.endY][maze.endX] = 2; // Exit
		return maze;
	};
	self.createLinearRooms = function (maze) {
		// Create linear path with unique room shapes - only one way forward
		var roomTypes = ['hallway', 'lshaped', 'library', 'bedroom'];
		var currentX = 5;
		var currentY = 5;
		var connectionWidth = 2;
		maze.rooms = [];
		var roomNumber = 1;
		// Create 100 rooms in a linear sequence
		for (var i = 0; i < 100; i++) {
			var roomType = roomTypes[i % 4]; // Cycle through room types
			var room = self.createRoomByType(maze, roomType, currentX, currentY, roomNumber);
			if (room) {
				maze.rooms.push(room);
				// Connect to next room if not the last one
				if (i < 99) {
					var nextRoomX = currentX + room.width + connectionWidth + 3;
					var nextRoomY = currentY;
					// Ensure next room fits, otherwise move to next row
					if (nextRoomX + 8 >= maze.width) {
						nextRoomX = 5;
						nextRoomY = currentY + 10; // Move down for next row
					}
					// Create connection hallway
					self.createConnection(maze, room, nextRoomX, nextRoomY);
					currentX = nextRoomX;
					currentY = nextRoomY;
				}
				roomNumber++;
			}
		}
		// Set start in first room
		if (maze.rooms.length > 0) {
			maze.startX = maze.rooms[0].x + 1;
			maze.startY = maze.rooms[0].y + 1;
			// Set exit in last room
			var lastRoom = maze.rooms[maze.rooms.length - 1];
			maze.endX = lastRoom.x + lastRoom.width - 2;
			maze.endY = lastRoom.y + lastRoom.height - 2;
		}
	};
	self.createRoomByType = function (maze, roomType, startX, startY, roomNumber) {
		var room = null;
		switch (roomType) {
			case 'hallway':
				room = self.createHallway(maze, startX, startY, roomNumber);
				break;
			case 'lshaped':
				room = self.createLShaped(maze, startX, startY, roomNumber);
				break;
			case 'library':
				room = self.createLibrary(maze, startX, startY, roomNumber);
				break;
			case 'bedroom':
				room = self.createBedroom(maze, startX, startY, roomNumber);
				break;
		}
		return room;
	};
	self.createHallway = function (maze, startX, startY, roomNumber) {
		var width = 8;
		var height = 3;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear hallway area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				maze.grid[y][x] = 0;
			}
		}
		// Add shelves along the walls using raycasting approach
		// Place shelves on the top and bottom walls
		for (var x = startX + 1; x < startX + width - 1; x += 2) {
			// Top wall shelves
			if (startY > 0 && maze.grid[startY - 1][x] === 1) {
				maze.grid[startY][x] = 4; // Shelf marker
			}
			// Bottom wall shelves
			if (startY + height < maze.height && maze.grid[startY + height][x] === 1) {
				maze.grid[startY + height - 1][x] = 4; // Shelf marker
			}
		}
		// Add desks in the middle area
		if (startX + 3 < maze.width && startY + 1 < maze.height) {
			maze.grid[startY + 1][startX + 3] = 7; // Desk marker
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'hallway'
		};
	};
	self.createLShaped = function (maze, startX, startY, roomNumber) {
		var width = 6;
		var height = 6;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear L-shaped area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				// Create L shape - full first 4 rows, then only first 3 columns
				if (y < startY + 4 || x < startX + 3) {
					maze.grid[y][x] = 0;
				}
			}
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'lshaped'
		};
	};
	self.createLibrary = function (maze, startX, startY, roomNumber) {
		var width = 7;
		var height = 5;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear library area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				maze.grid[y][x] = 0;
			}
		}
		// Add book shelves along the walls
		for (var x = startX + 1; x < startX + width - 1; x += 2) {
			if (startY + 1 < maze.height) {
				maze.grid[startY + 1][x] = 4; // Shelf marker
			}
			if (startY + 3 < maze.height) {
				maze.grid[startY + 3][x] = 4; // Shelf marker
			}
		}
		// Add reading desk in center
		if (startY + 2 < maze.height && startX + 3 < maze.width) {
			maze.grid[startY + 2][startX + 3] = 7; // Desk marker
		}
		// Add small paintings on walls
		if (startY + 1 < maze.height && startX + 1 < maze.width) {
			maze.grid[startY + 1][startX + 1] = 6; // Painting marker
		}
		if (startY + 3 < maze.height && startX + 5 < maze.width) {
			maze.grid[startY + 3][startX + 5] = 6; // Painting marker
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'library'
		};
	};
	self.createBedroom = function (maze, startX, startY, roomNumber) {
		var width = 5;
		var height = 5;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear bedroom area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				maze.grid[y][x] = 0;
			}
		}
		// Add beds along the walls
		if (startY + 1 < maze.height && startX + 1 < maze.width) {
			maze.grid[startY + 1][startX + 1] = 5; // Bed marker
		}
		if (startY + 1 < maze.height && startX + 3 < maze.width) {
			maze.grid[startY + 1][startX + 3] = 5; // Bed marker
		}
		// Add desk between beds
		if (startY + 3 < maze.height && startX + 2 < maze.width) {
			maze.grid[startY + 3][startX + 2] = 7; // Desk marker
		}
		// Add small paintings on walls
		if (startY + 2 < maze.height && startX + 1 < maze.width) {
			maze.grid[startY + 2][startX + 1] = 6; // Painting marker
		}
		if (startY + 2 < maze.height && startX + 3 < maze.width) {
			maze.grid[startY + 2][startX + 3] = 6; // Painting marker
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'bedroom'
		};
	};
	self.createConnection = function (maze, fromRoom, toX, toY) {
		var fromX = fromRoom.x + fromRoom.width;
		var fromY = fromRoom.y + Math.floor(fromRoom.height / 2);
		var toConnectX = toX - 1;
		var toConnectY = toY + 1;
		// Create horizontal connection
		var currentX = fromX;
		while (currentX < toConnectX && currentX < maze.width) {
			if (fromY >= 0 && fromY < maze.height && currentX >= 0) {
				maze.grid[fromY][currentX] = 0;
			}
			currentX++;
		}
		// Place door at connection end with room number
		if (toConnectX >= 0 && toConnectX < maze.width && fromY >= 0 && fromY < maze.height) {
			maze.grid[fromY][toConnectX] = 3; // Door
			// Store door number for rendering
			if (!maze.doorNumbers) maze.doorNumbers = {};
			maze.doorNumbers[fromY + '_' + toConnectX] = fromRoom.number + 1;
		}
	};
	return self;
});
var Minimap = Container.expand(function () {
	var self = Container.call(this);
	self.cellSize = 8;
	self.mapCells = [];
	self.playerDot = null;
	self.setup = function (maze) {
		// Clear existing map
		for (var i = 0; i < self.mapCells.length; i++) {
			self.mapCells[i].destroy();
		}
		self.mapCells = [];
		if (self.playerDot) {
			self.playerDot.destroy();
		}
		// Create minimap cells
		for (var y = 0; y < maze.height; y++) {
			for (var x = 0; x < maze.width; x++) {
				var cell = null;
				if (maze.grid[y][x] === 1) {
					// Wall
					cell = LK.getAsset('wall', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x444444;
				} else if (maze.grid[y][x] === 2) {
					// Exit
					cell = LK.getAsset('exit', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x00FF00;
				} else if (maze.grid[y][x] === 3) {
					// Door
					cell = LK.getAsset('door', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x654321;
				} else {
					// Open path
					cell = LK.getAsset('floor', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x888888;
				}
				if (cell) {
					cell.x = x * self.cellSize;
					cell.y = y * self.cellSize;
					self.addChild(cell);
					self.mapCells.push(cell);
				}
			}
		}
		// Create player dot
		self.playerDot = LK.getAsset('player', {
			width: self.cellSize,
			height: self.cellSize,
			anchorX: 0.5,
			anchorY: 0.5
		});
		self.addChild(self.playerDot);
	};
	self.updatePlayer = function (playerX, playerY) {
		if (self.playerDot) {
			self.playerDot.x = playerX * self.cellSize;
			self.playerDot.y = playerY * self.cellSize;
		}
	};
	return self;
});
var RaycastRenderer = Container.expand(function () {
	var self = Container.call(this);
	self.fov = Math.PI / 3; // 60 degrees field of view
	self.rayCount = 256; // Number of rays to cast (expanded for full screen)
	self.maxDistance = 15; // Reduced max distance
	self.wallHeight = 300;
	self.walls = [];
	self.render = function (playerX, playerY, playerAngle, maze) {
		// Initialize walls array if needed
		if (self.walls.length === 0) {
			for (var i = 0; i < self.rayCount; i++) {
				var wall = LK.getAsset('raycast_wall', {
					width: 8,
					height: self.wallHeight,
					anchorX: 0,
					anchorY: 0.5
				});
				wall.x = i * 8;
				wall.y = 2732 / 2;
				wall.visible = false;
				self.addChild(wall);
				self.walls.push(wall);
			}
		}
		var angleStep = self.fov / self.rayCount;
		var rayAngle = playerAngle - self.fov / 2;
		for (var i = 0; i < self.rayCount; i++) {
			var rayResult = self.castRay(playerX, playerY, rayAngle, maze);
			var wall = self.walls[i];
			if (rayResult.distance < self.maxDistance) {
				// Calculate wall height based on distance
				var wallHeight = self.wallHeight / rayResult.distance;
				if (wallHeight > 600) wallHeight = 600; // Cap wall height
				// Update existing wall segment
				wall.height = wallHeight;
				wall.visible = true;
				// Add depth shading and color based on object type
				var shade = Math.max(0.2, 1 - rayResult.distance / self.maxDistance);
				var baseColor = 0x8B4513; // Default wall color
				if (rayResult.type === 3) baseColor = 0x4a2c2a; // Door color - darker brown for better visibility
				else if (rayResult.type === 4) baseColor = 0x654321; // Shelf color
				else if (rayResult.type === 5) baseColor = 0x800080; // Bed color
				else if (rayResult.type === 6) baseColor = 0xFFD700; // Painting color
				else if (rayResult.type === 7) baseColor = 0x8b4513; // Desk color
				wall.tint = self.interpolateColor(0x000000, baseColor, shade);
			} else {
				wall.visible = false;
			}
			rayAngle += angleStep;
		}
	};
	self.castRay = function (x, y, angle, maze) {
		var dx = Math.cos(angle) * 0.1;
		var dy = Math.sin(angle) * 0.1;
		var distance = 0;
		var stepSize = 0.1;
		var maxSteps = 200; // Prevent infinite loops
		var steps = 0;
		var hitType = 0; // Track what we hit
		while (distance < self.maxDistance && steps < maxSteps) {
			x += dx;
			y += dy;
			distance += stepSize;
			steps++;
			var mapX = Math.floor(x);
			var mapY = Math.floor(y);
			if (mapX < 0 || mapX >= maze.width || mapY < 0 || mapY >= maze.height) {
				return {
					distance: distance,
					type: 1
				};
			}
			var cellType = maze.grid[mapY][mapX];
			if (cellType === 1) {
				return {
					distance: distance,
					type: 1
				};
			}
			// Check for doors
			if (cellType === 3) {
				// Door
				return {
					distance: distance,
					type: 3
				};
			}
			// Check for furniture objects
			if (cellType === 4) {
				// Shelf
				return {
					distance: distance,
					type: 4
				};
			}
			if (cellType === 5) {
				// Bed
				return {
					distance: distance,
					type: 5
				};
			}
			if (cellType === 6) {
				// Painting
				return {
					distance: distance,
					type: 6
				};
			}
			if (cellType === 7) {
				// Desk
				return {
					distance: distance,
					type: 7
				};
			}
		}
		return {
			distance: self.maxDistance,
			type: 0
		};
	};
	self.interpolateColor = function (color1, color2, factor) {
		var r1 = color1 >> 16 & 0xFF;
		var g1 = color1 >> 8 & 0xFF;
		var b1 = color1 & 0xFF;
		var r2 = color2 >> 16 & 0xFF;
		var g2 = color2 >> 8 & 0xFF;
		var b2 = color2 & 0xFF;
		var r = Math.floor(r1 + (r2 - r1) * factor);
		var g = Math.floor(g1 + (g2 - g1) * factor);
		var b = Math.floor(b1 + (b2 - b1) * factor);
		return r << 16 | g << 8 | b;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000,
	name: 'Maze Runner',
	description: 'Navigate through a first-person maze with unique room types including hallways, libraries, and bedrooms. Find doors to progress through 100 rooms and reach the exit!',
	tags: ['maze', 'first-person', '3d', 'adventure', 'puzzle', 'exploration', 'rooms', 'doors', 'navigation']
});
/**** 
* Game Code
****/ 
// Game variables - Reset all values on new game
var currentLevel = 1;
var playerX = 1.5;
var playerY = 1.5;
var playerAngle = 0;
var moveSpeed = 0.05; // Reduced movement speed
var turnSpeed = 0.04; // Reduced turn speed
var maze = null;
var mazeGenerator = new MazeGenerator();
var raycastRenderer = new RaycastRenderer();
var minimap = new Minimap();
var roomsCompleted = 0; // Reset room counter
var doorColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var breadcrumbs = [];
var breadcrumbContainer = new Container();
// Touch controls
var touchStartX = 0;
var touchStartY = 0;
var isTouching = false;
var moveForward = false;
var moveBackward = false;
var turnLeft = false;
var turnRight = false;
// UI elements
var levelText = new Text2('Level: ' + currentLevel, {
	size: 60,
	fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var instructionText = new Text2('Find the exit!', {
	size: 40,
	fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 80;
LK.gui.top.addChild(instructionText);
var roomText = new Text2('Room 1', {
	size: 50,
	fill: 0xFFFF00
});
roomText.anchor.set(0.5, 0);
roomText.y = 140;
LK.gui.top.addChild(roomText);
var roomCounterText = new Text2('Rooms: ' + roomsCompleted + '/100', {
	size: 40,
	fill: 0xFFFFFF
});
roomCounterText.anchor.set(0.5, 0);
roomCounterText.y = 200;
LK.gui.top.addChild(roomCounterText);
// Compass UI
var compassBg = LK.getAsset('compass_bg', {
	anchorX: 0.5,
	anchorY: 0.5
});
LK.gui.topRight.addChild(compassBg);
compassBg.x = -80;
compassBg.y = 80;
var compassNeedle = LK.getAsset('compass_needle', {
	anchorX: 0.5,
	anchorY: 1.0
});
compassBg.addChild(compassNeedle);
// Direction labels
var northLabel = new Text2('N', {
	size: 20,
	fill: 0xFFFFFF
});
northLabel.anchor.set(0.5, 0.5);
northLabel.x = 0;
northLabel.y = -40;
compassBg.addChild(northLabel);
var southLabel = new Text2('S', {
	size: 20,
	fill: 0xFFFFFF
});
southLabel.anchor.set(0.5, 0.5);
southLabel.x = 0;
southLabel.y = 40;
compassBg.addChild(southLabel);
var eastLabel = new Text2('E', {
	size: 20,
	fill: 0xFFFFFF
});
eastLabel.anchor.set(0.5, 0.5);
eastLabel.x = 40;
eastLabel.y = 0;
compassBg.addChild(eastLabel);
var westLabel = new Text2('W', {
	size: 20,
	fill: 0xFFFFFF
});
westLabel.anchor.set(0.5, 0.5);
westLabel.x = -40;
westLabel.y = 0;
compassBg.addChild(westLabel);
// Direction indicator
var directionText = new Text2('Facing: North', {
	size: 35,
	fill: 0x00FF00
});
directionText.anchor.set(0.5, 0);
directionText.y = 250;
LK.gui.top.addChild(directionText);
// Door indicator
var doorIndicator = new Text2('', {
	size: 40,
	fill: 0xFF0000
});
doorIndicator.anchor.set(0.5, 0.5);
LK.gui.center.addChild(doorIndicator);
doorIndicator.y = -200;
// Control arrows
var forwardArrow = new Text2('↑', {
	size: 120,
	fill: 0xFFFFFF
});
forwardArrow.anchor.set(0.5, 0.5);
forwardArrow.alpha = 0.7;
LK.gui.bottomLeft.addChild(forwardArrow);
forwardArrow.x = 150;
forwardArrow.y = -150;
var leftArrow = new Text2('←', {
	size: 120,
	fill: 0xFFFFFF
});
leftArrow.anchor.set(0.5, 0.5);
leftArrow.alpha = 0.7;
LK.gui.bottomRight.addChild(leftArrow);
leftArrow.x = -300;
leftArrow.y = -150;
var rightArrow = new Text2('→', {
	size: 120,
	fill: 0xFFFFFF
});
rightArrow.anchor.set(0.5, 0.5);
rightArrow.alpha = 0.7;
LK.gui.bottomRight.addChild(rightArrow);
rightArrow.x = -150;
rightArrow.y = -150;
// Initialize first level
function initLevel() {
	// Reset all game state
	currentLevel = 1;
	roomsCompleted = 0;
	storage.currentLevel = 1;
	storage.roomsCompleted = 0;
	var mazeSize = 60; // Larger size to accommodate 100 rooms
	maze = mazeGenerator.generate(mazeSize, mazeSize);
	// Set player starting position
	playerX = maze.startX + 0.5;
	playerY = maze.startY + 0.5;
	playerAngle = 0;
	maze.currentRoom = 0;
	// Minimap removed as requested
	// Clear breadcrumbs
	for (var i = 0; i < breadcrumbs.length; i++) {
		breadcrumbs[i].destroy();
	}
	breadcrumbs = [];
	breadcrumbContainer.removeChildren();
	// Update UI
	levelText.setText('Level: ' + currentLevel);
	roomText.setText('Room 1');
	roomCounterText.setText('Rooms: ' + roomsCompleted + '/100');
	instructionText.setText('Find the exit!');
}
// Helper functions
function getDirectionName(angle) {
	// Normalize angle to 0-360 degrees
	var degrees = (angle * 180 / Math.PI + 360) % 360;
	if (degrees >= 337.5 || degrees < 22.5) return 'North';
	if (degrees >= 22.5 && degrees < 67.5) return 'Northeast';
	if (degrees >= 67.5 && degrees < 112.5) return 'East';
	if (degrees >= 112.5 && degrees < 157.5) return 'Southeast';
	if (degrees >= 157.5 && degrees < 202.5) return 'South';
	if (degrees >= 202.5 && degrees < 247.5) return 'Southwest';
	if (degrees >= 247.5 && degrees < 292.5) return 'West';
	if (degrees >= 292.5 && degrees < 337.5) return 'Northwest';
	return 'North';
}
function findNearestDoor() {
	var nearestDoor = null;
	var minDistance = Infinity;
	var currentMapX = Math.floor(playerX);
	var currentMapY = Math.floor(playerY);
	var searchRadius = 8;
	for (var y = Math.max(0, currentMapY - searchRadius); y < Math.min(maze.height, currentMapY + searchRadius); y++) {
		for (var x = Math.max(0, currentMapX - searchRadius); x < Math.min(maze.width, currentMapX + searchRadius); x++) {
			if (maze.grid[y][x] === 3) {
				var distance = Math.sqrt((x - playerX) * (x - playerX) + (y - playerY) * (y - playerY));
				if (distance < minDistance) {
					minDistance = distance;
					nearestDoor = {
						x: x,
						y: y,
						distance: distance
					};
				}
			}
		}
	}
	return nearestDoor;
}
function getDoorDirection(doorX, doorY) {
	var dx = doorX - playerX;
	var dy = doorY - playerY;
	var angle = Math.atan2(dy, dx);
	return getDirectionName(angle);
}
// Control functions
function handleMovement() {
	var newX = playerX;
	var newY = playerY;
	if (moveForward) {
		newX += Math.cos(playerAngle) * moveSpeed;
		newY += Math.sin(playerAngle) * moveSpeed;
	}
	if (moveBackward) {
		newX -= Math.cos(playerAngle) * moveSpeed;
		newY -= Math.sin(playerAngle) * moveSpeed;
	}
	// Collision detection
	var mapX = Math.floor(newX);
	var mapY = Math.floor(newY);
	if (mapX >= 0 && mapX < maze.width && mapY >= 0 && mapY < maze.height) {
		if (maze.grid[mapY][mapX] !== 1) {
			// Check for door interaction - doors automatically open on touch
			if (maze.grid[mapY][mapX] === 3) {
				// Door found - automatically open and increment room counter
				maze.grid[mapY][mapX] = 0; // Open the door
				roomsCompleted++;
				storage.roomsCompleted = roomsCompleted;
				roomCounterText.setText('Rooms: ' + roomsCompleted + '/100');
				instructionText.setText('Door opened! Room ' + roomsCompleted + ' completed!');
				LK.setTimeout(function () {
					instructionText.setText('Find the exit!');
				}, 1000);
				// Check win condition
				if (roomsCompleted >= 100) {
					LK.showYouWin();
					return;
				}
			}
			playerX = newX;
			playerY = newY;
			// Update current room display
			if (maze.rooms) {
				for (var r = 0; r < maze.rooms.length; r++) {
					var room = maze.rooms[r];
					if (mapX >= room.x && mapX < room.x + room.width && mapY >= room.y && mapY < room.y + room.height) {
						if (maze.currentRoom !== r) {
							maze.currentRoom = r;
							var roomTypeText = room.type ? room.type.charAt(0).toUpperCase() + room.type.slice(1) : 'Room';
							roomText.setText('Room ' + (r + 1) + ' - ' + roomTypeText);
						}
						break;
					}
				}
			}
			// Check if reached exit
			if (maze.grid[mapY][mapX] === 2) {
				completeLevel();
			}
		}
	}
	if (turnLeft) {
		playerAngle -= turnSpeed;
	}
	if (turnRight) {
		playerAngle += turnSpeed;
	}
	// Normalize angle
	while (playerAngle < 0) playerAngle += Math.PI * 2;
	while (playerAngle >= Math.PI * 2) playerAngle -= Math.PI * 2;
	// Update compass needle
	compassNeedle.rotation = playerAngle;
	// Update direction text
	var currentDirection = getDirectionName(playerAngle);
	directionText.setText('Facing: ' + currentDirection);
	// Update door indicator
	var nearestDoor = findNearestDoor();
	if (nearestDoor && nearestDoor.distance < 5) {
		var doorDirection = getDoorDirection(nearestDoor.x, nearestDoor.y);
		var doorDistance = Math.round(nearestDoor.distance * 10) / 10;
		doorIndicator.setText('Door: ' + doorDirection + ' (' + doorDistance + 'm)');
		doorIndicator.visible = true;
	} else {
		doorIndicator.visible = false;
	}
}
function completeLevel() {
	LK.getSound('complete').play();
	LK.setScore(currentLevel);
	currentLevel++;
	storage.currentLevel = currentLevel;
	if (currentLevel > 10) {
		LK.showYouWin();
	} else {
		// Move to next level without flashing
		LK.setTimeout(function () {
			initLevel();
		}, 500);
	}
}
// Arrow control event handlers
forwardArrow.down = function (x, y, obj) {
	moveForward = true;
	forwardArrow.alpha = 1.0;
};
forwardArrow.up = function (x, y, obj) {
	moveForward = false;
	forwardArrow.alpha = 0.7;
};
leftArrow.down = function (x, y, obj) {
	turnLeft = true;
	leftArrow.alpha = 1.0;
};
leftArrow.up = function (x, y, obj) {
	turnLeft = false;
	leftArrow.alpha = 0.7;
};
rightArrow.down = function (x, y, obj) {
	turnRight = true;
	rightArrow.alpha = 1.0;
};
rightArrow.up = function (x, y, obj) {
	turnRight = false;
	rightArrow.alpha = 0.7;
};
// Touch event handlers
game.down = function (x, y, obj) {
	isTouching = true;
	touchStartX = x;
	touchStartY = y;
};
game.move = function (x, y, obj) {
	// Remove conflicting touch movement to allow arrow controls to work
};
game.up = function (x, y, obj) {
	isTouching = false;
	moveForward = false;
	turnLeft = false;
	turnRight = false;
};
// Add renderer to game
game.addChild(raycastRenderer);
raycastRenderer.x = 0;
raycastRenderer.y = 0;
// Add breadcrumb container
game.addChild(breadcrumbContainer);
// Breadcrumb trail variables
var lastBreadcrumbX = -1;
var lastBreadcrumbY = -1;
var breadcrumbTimer = 0;
// Main game loop
var lastRenderTime = 0;
var renderInterval = 33; // ~30fps to reduce load
game.update = function () {
	if (maze) {
		handleMovement();
		// Only render raycast every few frames to improve performance
		if (LK.ticks - lastRenderTime >= 2) {
			raycastRenderer.render(playerX, playerY, playerAngle, maze);
			lastRenderTime = LK.ticks;
		}
		// Add breadcrumb trail
		breadcrumbTimer++;
		if (breadcrumbTimer >= 60) {
			// Every second
			var currentMapX = Math.floor(playerX);
			var currentMapY = Math.floor(playerY);
			if (currentMapX !== lastBreadcrumbX || currentMapY !== lastBreadcrumbY) {
				var breadcrumb = LK.getAsset('breadcrumb', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				breadcrumb.x = (currentMapX + 0.5) * 64;
				breadcrumb.y = (currentMapY + 0.5) * 64;
				breadcrumb.alpha = 0.7;
				breadcrumbContainer.addChild(breadcrumb);
				breadcrumbs.push(breadcrumb);
				lastBreadcrumbX = currentMapX;
				lastBreadcrumbY = currentMapY;
				breadcrumbTimer = 0;
				// Limit breadcrumbs to prevent memory issues
				if (breadcrumbs.length > 50) {
					var oldBreadcrumb = breadcrumbs.shift();
					oldBreadcrumb.destroy();
				}
			}
		}
		// Minimap update removed
	}
};
// Start the game
initLevel(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var DoorRenderer = Container.expand(function () {
	var self = Container.call(this);
	self.doors = [];
	self.createDoor = function (x, y, roomNumber) {
		var doorContainer = new Container();
		// Door frame - made bigger and more prominent
		var frame = LK.getAsset('door_frame', {
			anchorX: 0.5,
			anchorY: 1.0,
			width: 80,
			height: 100
		});
		frame.tint = 0x4a2c2a;
		doorContainer.addChild(frame);
		// Door panel - made more prominent
		var panel = LK.getAsset('door', {
			anchorX: 0.5,
			anchorY: 1.0,
			y: -8,
			width: 72,
			height: 80
		});
		panel.tint = 0x8b4513;
		doorContainer.addChild(panel);
		// Door handle
		var handle = LK.getAsset('door_handle', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 25,
			y: -40
		});
		handle.tint = 0xffd700;
		doorContainer.addChild(handle);
		// Door nameplate with dimensions
		var nameplate = LK.getAsset('door_nameplate', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 0,
			y: -65
		});
		nameplate.tint = 0xc0c0c0;
		doorContainer.addChild(nameplate);
		// Room number text
		var numberText = new Text2(roomNumber.toString(), {
			size: 20,
			fill: 0x000000
		});
		numberText.anchor.set(0.5, 0.5);
		numberText.x = 0;
		numberText.y = -72;
		doorContainer.addChild(numberText);
		// Dimension text on nameplate
		var dimensionText = new Text2('80x100', {
			size: 12,
			fill: 0x000000
		});
		dimensionText.anchor.set(0.5, 0.5);
		dimensionText.x = 0;
		dimensionText.y = -58;
		doorContainer.addChild(dimensionText);
		doorContainer.x = x;
		doorContainer.y = y;
		return doorContainer;
	};
	return self;
});
var MazeGenerator = Container.expand(function () {
	var self = Container.call(this);
	self.generate = function (width, height) {
		var maze = {
			width: width,
			height: height,
			grid: [],
			startX: 1,
			startY: 1,
			endX: width - 2,
			endY: height - 2,
			rooms: [],
			currentRoom: 0
		};
		// Initialize maze with walls
		for (var y = 0; y < height; y++) {
			maze.grid[y] = [];
			for (var x = 0; x < width; x++) {
				maze.grid[y][x] = 1; // Wall
			}
		}
		// Create linear sequence of rooms like Doors game
		self.createLinearRooms(maze);
		// Ensure start and end are open
		maze.grid[maze.startY][maze.startX] = 0;
		maze.grid[maze.endY][maze.endX] = 2; // Exit
		return maze;
	};
	self.createLinearRooms = function (maze) {
		// Create linear path with unique room shapes - only one way forward
		var roomTypes = ['hallway', 'lshaped', 'library', 'bedroom'];
		var currentX = 5;
		var currentY = 5;
		var connectionWidth = 2;
		maze.rooms = [];
		var roomNumber = 1;
		// Create 100 rooms in a linear sequence
		for (var i = 0; i < 100; i++) {
			var roomType = roomTypes[i % 4]; // Cycle through room types
			var room = self.createRoomByType(maze, roomType, currentX, currentY, roomNumber);
			if (room) {
				maze.rooms.push(room);
				// Connect to next room if not the last one
				if (i < 99) {
					var nextRoomX = currentX + room.width + connectionWidth + 3;
					var nextRoomY = currentY;
					// Ensure next room fits, otherwise move to next row
					if (nextRoomX + 8 >= maze.width) {
						nextRoomX = 5;
						nextRoomY = currentY + 10; // Move down for next row
					}
					// Create connection hallway
					self.createConnection(maze, room, nextRoomX, nextRoomY);
					currentX = nextRoomX;
					currentY = nextRoomY;
				}
				roomNumber++;
			}
		}
		// Set start in first room
		if (maze.rooms.length > 0) {
			maze.startX = maze.rooms[0].x + 1;
			maze.startY = maze.rooms[0].y + 1;
			// Set exit in last room
			var lastRoom = maze.rooms[maze.rooms.length - 1];
			maze.endX = lastRoom.x + lastRoom.width - 2;
			maze.endY = lastRoom.y + lastRoom.height - 2;
		}
	};
	self.createRoomByType = function (maze, roomType, startX, startY, roomNumber) {
		var room = null;
		switch (roomType) {
			case 'hallway':
				room = self.createHallway(maze, startX, startY, roomNumber);
				break;
			case 'lshaped':
				room = self.createLShaped(maze, startX, startY, roomNumber);
				break;
			case 'library':
				room = self.createLibrary(maze, startX, startY, roomNumber);
				break;
			case 'bedroom':
				room = self.createBedroom(maze, startX, startY, roomNumber);
				break;
		}
		return room;
	};
	self.createHallway = function (maze, startX, startY, roomNumber) {
		var width = 8;
		var height = 3;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear hallway area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				maze.grid[y][x] = 0;
			}
		}
		// Add shelves along the walls using raycasting approach
		// Place shelves on the top and bottom walls
		for (var x = startX + 1; x < startX + width - 1; x += 2) {
			// Top wall shelves
			if (startY > 0 && maze.grid[startY - 1][x] === 1) {
				maze.grid[startY][x] = 4; // Shelf marker
			}
			// Bottom wall shelves
			if (startY + height < maze.height && maze.grid[startY + height][x] === 1) {
				maze.grid[startY + height - 1][x] = 4; // Shelf marker
			}
		}
		// Add desks in the middle area
		if (startX + 3 < maze.width && startY + 1 < maze.height) {
			maze.grid[startY + 1][startX + 3] = 7; // Desk marker
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'hallway'
		};
	};
	self.createLShaped = function (maze, startX, startY, roomNumber) {
		var width = 6;
		var height = 6;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear L-shaped area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				// Create L shape - full first 4 rows, then only first 3 columns
				if (y < startY + 4 || x < startX + 3) {
					maze.grid[y][x] = 0;
				}
			}
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'lshaped'
		};
	};
	self.createLibrary = function (maze, startX, startY, roomNumber) {
		var width = 7;
		var height = 5;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear library area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				maze.grid[y][x] = 0;
			}
		}
		// Add book shelves along the walls
		for (var x = startX + 1; x < startX + width - 1; x += 2) {
			if (startY + 1 < maze.height) {
				maze.grid[startY + 1][x] = 4; // Shelf marker
			}
			if (startY + 3 < maze.height) {
				maze.grid[startY + 3][x] = 4; // Shelf marker
			}
		}
		// Add reading desk in center
		if (startY + 2 < maze.height && startX + 3 < maze.width) {
			maze.grid[startY + 2][startX + 3] = 7; // Desk marker
		}
		// Add small paintings on walls
		if (startY + 1 < maze.height && startX + 1 < maze.width) {
			maze.grid[startY + 1][startX + 1] = 6; // Painting marker
		}
		if (startY + 3 < maze.height && startX + 5 < maze.width) {
			maze.grid[startY + 3][startX + 5] = 6; // Painting marker
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'library'
		};
	};
	self.createBedroom = function (maze, startX, startY, roomNumber) {
		var width = 5;
		var height = 5;
		if (startX + width >= maze.width || startY + height >= maze.height) return null;
		// Clear bedroom area
		for (var y = startY; y < startY + height; y++) {
			for (var x = startX; x < startX + width; x++) {
				maze.grid[y][x] = 0;
			}
		}
		// Add beds along the walls
		if (startY + 1 < maze.height && startX + 1 < maze.width) {
			maze.grid[startY + 1][startX + 1] = 5; // Bed marker
		}
		if (startY + 1 < maze.height && startX + 3 < maze.width) {
			maze.grid[startY + 1][startX + 3] = 5; // Bed marker
		}
		// Add desk between beds
		if (startY + 3 < maze.height && startX + 2 < maze.width) {
			maze.grid[startY + 3][startX + 2] = 7; // Desk marker
		}
		// Add small paintings on walls
		if (startY + 2 < maze.height && startX + 1 < maze.width) {
			maze.grid[startY + 2][startX + 1] = 6; // Painting marker
		}
		if (startY + 2 < maze.height && startX + 3 < maze.width) {
			maze.grid[startY + 2][startX + 3] = 6; // Painting marker
		}
		return {
			x: startX,
			y: startY,
			width: width,
			height: height,
			number: roomNumber,
			type: 'bedroom'
		};
	};
	self.createConnection = function (maze, fromRoom, toX, toY) {
		var fromX = fromRoom.x + fromRoom.width;
		var fromY = fromRoom.y + Math.floor(fromRoom.height / 2);
		var toConnectX = toX - 1;
		var toConnectY = toY + 1;
		// Create horizontal connection
		var currentX = fromX;
		while (currentX < toConnectX && currentX < maze.width) {
			if (fromY >= 0 && fromY < maze.height && currentX >= 0) {
				maze.grid[fromY][currentX] = 0;
			}
			currentX++;
		}
		// Place door at connection end with room number
		if (toConnectX >= 0 && toConnectX < maze.width && fromY >= 0 && fromY < maze.height) {
			maze.grid[fromY][toConnectX] = 3; // Door
			// Store door number for rendering
			if (!maze.doorNumbers) maze.doorNumbers = {};
			maze.doorNumbers[fromY + '_' + toConnectX] = fromRoom.number + 1;
		}
	};
	return self;
});
var Minimap = Container.expand(function () {
	var self = Container.call(this);
	self.cellSize = 8;
	self.mapCells = [];
	self.playerDot = null;
	self.setup = function (maze) {
		// Clear existing map
		for (var i = 0; i < self.mapCells.length; i++) {
			self.mapCells[i].destroy();
		}
		self.mapCells = [];
		if (self.playerDot) {
			self.playerDot.destroy();
		}
		// Create minimap cells
		for (var y = 0; y < maze.height; y++) {
			for (var x = 0; x < maze.width; x++) {
				var cell = null;
				if (maze.grid[y][x] === 1) {
					// Wall
					cell = LK.getAsset('wall', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x444444;
				} else if (maze.grid[y][x] === 2) {
					// Exit
					cell = LK.getAsset('exit', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x00FF00;
				} else if (maze.grid[y][x] === 3) {
					// Door
					cell = LK.getAsset('door', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x654321;
				} else {
					// Open path
					cell = LK.getAsset('floor', {
						width: self.cellSize,
						height: self.cellSize,
						anchorX: 0,
						anchorY: 0
					});
					cell.tint = 0x888888;
				}
				if (cell) {
					cell.x = x * self.cellSize;
					cell.y = y * self.cellSize;
					self.addChild(cell);
					self.mapCells.push(cell);
				}
			}
		}
		// Create player dot
		self.playerDot = LK.getAsset('player', {
			width: self.cellSize,
			height: self.cellSize,
			anchorX: 0.5,
			anchorY: 0.5
		});
		self.addChild(self.playerDot);
	};
	self.updatePlayer = function (playerX, playerY) {
		if (self.playerDot) {
			self.playerDot.x = playerX * self.cellSize;
			self.playerDot.y = playerY * self.cellSize;
		}
	};
	return self;
});
var RaycastRenderer = Container.expand(function () {
	var self = Container.call(this);
	self.fov = Math.PI / 3; // 60 degrees field of view
	self.rayCount = 256; // Number of rays to cast (expanded for full screen)
	self.maxDistance = 15; // Reduced max distance
	self.wallHeight = 300;
	self.walls = [];
	self.render = function (playerX, playerY, playerAngle, maze) {
		// Initialize walls array if needed
		if (self.walls.length === 0) {
			for (var i = 0; i < self.rayCount; i++) {
				var wall = LK.getAsset('raycast_wall', {
					width: 8,
					height: self.wallHeight,
					anchorX: 0,
					anchorY: 0.5
				});
				wall.x = i * 8;
				wall.y = 2732 / 2;
				wall.visible = false;
				self.addChild(wall);
				self.walls.push(wall);
			}
		}
		var angleStep = self.fov / self.rayCount;
		var rayAngle = playerAngle - self.fov / 2;
		for (var i = 0; i < self.rayCount; i++) {
			var rayResult = self.castRay(playerX, playerY, rayAngle, maze);
			var wall = self.walls[i];
			if (rayResult.distance < self.maxDistance) {
				// Calculate wall height based on distance
				var wallHeight = self.wallHeight / rayResult.distance;
				if (wallHeight > 600) wallHeight = 600; // Cap wall height
				// Update existing wall segment
				wall.height = wallHeight;
				wall.visible = true;
				// Add depth shading and color based on object type
				var shade = Math.max(0.2, 1 - rayResult.distance / self.maxDistance);
				var baseColor = 0x8B4513; // Default wall color
				if (rayResult.type === 3) baseColor = 0x4a2c2a; // Door color - darker brown for better visibility
				else if (rayResult.type === 4) baseColor = 0x654321; // Shelf color
				else if (rayResult.type === 5) baseColor = 0x800080; // Bed color
				else if (rayResult.type === 6) baseColor = 0xFFD700; // Painting color
				else if (rayResult.type === 7) baseColor = 0x8b4513; // Desk color
				wall.tint = self.interpolateColor(0x000000, baseColor, shade);
			} else {
				wall.visible = false;
			}
			rayAngle += angleStep;
		}
	};
	self.castRay = function (x, y, angle, maze) {
		var dx = Math.cos(angle) * 0.1;
		var dy = Math.sin(angle) * 0.1;
		var distance = 0;
		var stepSize = 0.1;
		var maxSteps = 200; // Prevent infinite loops
		var steps = 0;
		var hitType = 0; // Track what we hit
		while (distance < self.maxDistance && steps < maxSteps) {
			x += dx;
			y += dy;
			distance += stepSize;
			steps++;
			var mapX = Math.floor(x);
			var mapY = Math.floor(y);
			if (mapX < 0 || mapX >= maze.width || mapY < 0 || mapY >= maze.height) {
				return {
					distance: distance,
					type: 1
				};
			}
			var cellType = maze.grid[mapY][mapX];
			if (cellType === 1) {
				return {
					distance: distance,
					type: 1
				};
			}
			// Check for doors
			if (cellType === 3) {
				// Door
				return {
					distance: distance,
					type: 3
				};
			}
			// Check for furniture objects
			if (cellType === 4) {
				// Shelf
				return {
					distance: distance,
					type: 4
				};
			}
			if (cellType === 5) {
				// Bed
				return {
					distance: distance,
					type: 5
				};
			}
			if (cellType === 6) {
				// Painting
				return {
					distance: distance,
					type: 6
				};
			}
			if (cellType === 7) {
				// Desk
				return {
					distance: distance,
					type: 7
				};
			}
		}
		return {
			distance: self.maxDistance,
			type: 0
		};
	};
	self.interpolateColor = function (color1, color2, factor) {
		var r1 = color1 >> 16 & 0xFF;
		var g1 = color1 >> 8 & 0xFF;
		var b1 = color1 & 0xFF;
		var r2 = color2 >> 16 & 0xFF;
		var g2 = color2 >> 8 & 0xFF;
		var b2 = color2 & 0xFF;
		var r = Math.floor(r1 + (r2 - r1) * factor);
		var g = Math.floor(g1 + (g2 - g1) * factor);
		var b = Math.floor(b1 + (b2 - b1) * factor);
		return r << 16 | g << 8 | b;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000,
	name: 'Maze Runner',
	description: 'Navigate through a first-person maze with unique room types including hallways, libraries, and bedrooms. Find doors to progress through 100 rooms and reach the exit!',
	tags: ['maze', 'first-person', '3d', 'adventure', 'puzzle', 'exploration', 'rooms', 'doors', 'navigation']
});
/**** 
* Game Code
****/ 
// Game variables - Reset all values on new game
var currentLevel = 1;
var playerX = 1.5;
var playerY = 1.5;
var playerAngle = 0;
var moveSpeed = 0.05; // Reduced movement speed
var turnSpeed = 0.04; // Reduced turn speed
var maze = null;
var mazeGenerator = new MazeGenerator();
var raycastRenderer = new RaycastRenderer();
var minimap = new Minimap();
var roomsCompleted = 0; // Reset room counter
var doorColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var breadcrumbs = [];
var breadcrumbContainer = new Container();
// Touch controls
var touchStartX = 0;
var touchStartY = 0;
var isTouching = false;
var moveForward = false;
var moveBackward = false;
var turnLeft = false;
var turnRight = false;
// UI elements
var levelText = new Text2('Level: ' + currentLevel, {
	size: 60,
	fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var instructionText = new Text2('Find the exit!', {
	size: 40,
	fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 80;
LK.gui.top.addChild(instructionText);
var roomText = new Text2('Room 1', {
	size: 50,
	fill: 0xFFFF00
});
roomText.anchor.set(0.5, 0);
roomText.y = 140;
LK.gui.top.addChild(roomText);
var roomCounterText = new Text2('Rooms: ' + roomsCompleted + '/100', {
	size: 40,
	fill: 0xFFFFFF
});
roomCounterText.anchor.set(0.5, 0);
roomCounterText.y = 200;
LK.gui.top.addChild(roomCounterText);
// Compass UI
var compassBg = LK.getAsset('compass_bg', {
	anchorX: 0.5,
	anchorY: 0.5
});
LK.gui.topRight.addChild(compassBg);
compassBg.x = -80;
compassBg.y = 80;
var compassNeedle = LK.getAsset('compass_needle', {
	anchorX: 0.5,
	anchorY: 1.0
});
compassBg.addChild(compassNeedle);
// Direction labels
var northLabel = new Text2('N', {
	size: 20,
	fill: 0xFFFFFF
});
northLabel.anchor.set(0.5, 0.5);
northLabel.x = 0;
northLabel.y = -40;
compassBg.addChild(northLabel);
var southLabel = new Text2('S', {
	size: 20,
	fill: 0xFFFFFF
});
southLabel.anchor.set(0.5, 0.5);
southLabel.x = 0;
southLabel.y = 40;
compassBg.addChild(southLabel);
var eastLabel = new Text2('E', {
	size: 20,
	fill: 0xFFFFFF
});
eastLabel.anchor.set(0.5, 0.5);
eastLabel.x = 40;
eastLabel.y = 0;
compassBg.addChild(eastLabel);
var westLabel = new Text2('W', {
	size: 20,
	fill: 0xFFFFFF
});
westLabel.anchor.set(0.5, 0.5);
westLabel.x = -40;
westLabel.y = 0;
compassBg.addChild(westLabel);
// Direction indicator
var directionText = new Text2('Facing: North', {
	size: 35,
	fill: 0x00FF00
});
directionText.anchor.set(0.5, 0);
directionText.y = 250;
LK.gui.top.addChild(directionText);
// Door indicator
var doorIndicator = new Text2('', {
	size: 40,
	fill: 0xFF0000
});
doorIndicator.anchor.set(0.5, 0.5);
LK.gui.center.addChild(doorIndicator);
doorIndicator.y = -200;
// Control arrows
var forwardArrow = new Text2('↑', {
	size: 120,
	fill: 0xFFFFFF
});
forwardArrow.anchor.set(0.5, 0.5);
forwardArrow.alpha = 0.7;
LK.gui.bottomLeft.addChild(forwardArrow);
forwardArrow.x = 150;
forwardArrow.y = -150;
var leftArrow = new Text2('←', {
	size: 120,
	fill: 0xFFFFFF
});
leftArrow.anchor.set(0.5, 0.5);
leftArrow.alpha = 0.7;
LK.gui.bottomRight.addChild(leftArrow);
leftArrow.x = -300;
leftArrow.y = -150;
var rightArrow = new Text2('→', {
	size: 120,
	fill: 0xFFFFFF
});
rightArrow.anchor.set(0.5, 0.5);
rightArrow.alpha = 0.7;
LK.gui.bottomRight.addChild(rightArrow);
rightArrow.x = -150;
rightArrow.y = -150;
// Initialize first level
function initLevel() {
	// Reset all game state
	currentLevel = 1;
	roomsCompleted = 0;
	storage.currentLevel = 1;
	storage.roomsCompleted = 0;
	var mazeSize = 60; // Larger size to accommodate 100 rooms
	maze = mazeGenerator.generate(mazeSize, mazeSize);
	// Set player starting position
	playerX = maze.startX + 0.5;
	playerY = maze.startY + 0.5;
	playerAngle = 0;
	maze.currentRoom = 0;
	// Minimap removed as requested
	// Clear breadcrumbs
	for (var i = 0; i < breadcrumbs.length; i++) {
		breadcrumbs[i].destroy();
	}
	breadcrumbs = [];
	breadcrumbContainer.removeChildren();
	// Update UI
	levelText.setText('Level: ' + currentLevel);
	roomText.setText('Room 1');
	roomCounterText.setText('Rooms: ' + roomsCompleted + '/100');
	instructionText.setText('Find the exit!');
}
// Helper functions
function getDirectionName(angle) {
	// Normalize angle to 0-360 degrees
	var degrees = (angle * 180 / Math.PI + 360) % 360;
	if (degrees >= 337.5 || degrees < 22.5) return 'North';
	if (degrees >= 22.5 && degrees < 67.5) return 'Northeast';
	if (degrees >= 67.5 && degrees < 112.5) return 'East';
	if (degrees >= 112.5 && degrees < 157.5) return 'Southeast';
	if (degrees >= 157.5 && degrees < 202.5) return 'South';
	if (degrees >= 202.5 && degrees < 247.5) return 'Southwest';
	if (degrees >= 247.5 && degrees < 292.5) return 'West';
	if (degrees >= 292.5 && degrees < 337.5) return 'Northwest';
	return 'North';
}
function findNearestDoor() {
	var nearestDoor = null;
	var minDistance = Infinity;
	var currentMapX = Math.floor(playerX);
	var currentMapY = Math.floor(playerY);
	var searchRadius = 8;
	for (var y = Math.max(0, currentMapY - searchRadius); y < Math.min(maze.height, currentMapY + searchRadius); y++) {
		for (var x = Math.max(0, currentMapX - searchRadius); x < Math.min(maze.width, currentMapX + searchRadius); x++) {
			if (maze.grid[y][x] === 3) {
				var distance = Math.sqrt((x - playerX) * (x - playerX) + (y - playerY) * (y - playerY));
				if (distance < minDistance) {
					minDistance = distance;
					nearestDoor = {
						x: x,
						y: y,
						distance: distance
					};
				}
			}
		}
	}
	return nearestDoor;
}
function getDoorDirection(doorX, doorY) {
	var dx = doorX - playerX;
	var dy = doorY - playerY;
	var angle = Math.atan2(dy, dx);
	return getDirectionName(angle);
}
// Control functions
function handleMovement() {
	var newX = playerX;
	var newY = playerY;
	if (moveForward) {
		newX += Math.cos(playerAngle) * moveSpeed;
		newY += Math.sin(playerAngle) * moveSpeed;
	}
	if (moveBackward) {
		newX -= Math.cos(playerAngle) * moveSpeed;
		newY -= Math.sin(playerAngle) * moveSpeed;
	}
	// Collision detection
	var mapX = Math.floor(newX);
	var mapY = Math.floor(newY);
	if (mapX >= 0 && mapX < maze.width && mapY >= 0 && mapY < maze.height) {
		if (maze.grid[mapY][mapX] !== 1) {
			// Check for door interaction - doors automatically open on touch
			if (maze.grid[mapY][mapX] === 3) {
				// Door found - automatically open and increment room counter
				maze.grid[mapY][mapX] = 0; // Open the door
				roomsCompleted++;
				storage.roomsCompleted = roomsCompleted;
				roomCounterText.setText('Rooms: ' + roomsCompleted + '/100');
				instructionText.setText('Door opened! Room ' + roomsCompleted + ' completed!');
				LK.setTimeout(function () {
					instructionText.setText('Find the exit!');
				}, 1000);
				// Check win condition
				if (roomsCompleted >= 100) {
					LK.showYouWin();
					return;
				}
			}
			playerX = newX;
			playerY = newY;
			// Update current room display
			if (maze.rooms) {
				for (var r = 0; r < maze.rooms.length; r++) {
					var room = maze.rooms[r];
					if (mapX >= room.x && mapX < room.x + room.width && mapY >= room.y && mapY < room.y + room.height) {
						if (maze.currentRoom !== r) {
							maze.currentRoom = r;
							var roomTypeText = room.type ? room.type.charAt(0).toUpperCase() + room.type.slice(1) : 'Room';
							roomText.setText('Room ' + (r + 1) + ' - ' + roomTypeText);
						}
						break;
					}
				}
			}
			// Check if reached exit
			if (maze.grid[mapY][mapX] === 2) {
				completeLevel();
			}
		}
	}
	if (turnLeft) {
		playerAngle -= turnSpeed;
	}
	if (turnRight) {
		playerAngle += turnSpeed;
	}
	// Normalize angle
	while (playerAngle < 0) playerAngle += Math.PI * 2;
	while (playerAngle >= Math.PI * 2) playerAngle -= Math.PI * 2;
	// Update compass needle
	compassNeedle.rotation = playerAngle;
	// Update direction text
	var currentDirection = getDirectionName(playerAngle);
	directionText.setText('Facing: ' + currentDirection);
	// Update door indicator
	var nearestDoor = findNearestDoor();
	if (nearestDoor && nearestDoor.distance < 5) {
		var doorDirection = getDoorDirection(nearestDoor.x, nearestDoor.y);
		var doorDistance = Math.round(nearestDoor.distance * 10) / 10;
		doorIndicator.setText('Door: ' + doorDirection + ' (' + doorDistance + 'm)');
		doorIndicator.visible = true;
	} else {
		doorIndicator.visible = false;
	}
}
function completeLevel() {
	LK.getSound('complete').play();
	LK.setScore(currentLevel);
	currentLevel++;
	storage.currentLevel = currentLevel;
	if (currentLevel > 10) {
		LK.showYouWin();
	} else {
		// Move to next level without flashing
		LK.setTimeout(function () {
			initLevel();
		}, 500);
	}
}
// Arrow control event handlers
forwardArrow.down = function (x, y, obj) {
	moveForward = true;
	forwardArrow.alpha = 1.0;
};
forwardArrow.up = function (x, y, obj) {
	moveForward = false;
	forwardArrow.alpha = 0.7;
};
leftArrow.down = function (x, y, obj) {
	turnLeft = true;
	leftArrow.alpha = 1.0;
};
leftArrow.up = function (x, y, obj) {
	turnLeft = false;
	leftArrow.alpha = 0.7;
};
rightArrow.down = function (x, y, obj) {
	turnRight = true;
	rightArrow.alpha = 1.0;
};
rightArrow.up = function (x, y, obj) {
	turnRight = false;
	rightArrow.alpha = 0.7;
};
// Touch event handlers
game.down = function (x, y, obj) {
	isTouching = true;
	touchStartX = x;
	touchStartY = y;
};
game.move = function (x, y, obj) {
	// Remove conflicting touch movement to allow arrow controls to work
};
game.up = function (x, y, obj) {
	isTouching = false;
	moveForward = false;
	turnLeft = false;
	turnRight = false;
};
// Add renderer to game
game.addChild(raycastRenderer);
raycastRenderer.x = 0;
raycastRenderer.y = 0;
// Add breadcrumb container
game.addChild(breadcrumbContainer);
// Breadcrumb trail variables
var lastBreadcrumbX = -1;
var lastBreadcrumbY = -1;
var breadcrumbTimer = 0;
// Main game loop
var lastRenderTime = 0;
var renderInterval = 33; // ~30fps to reduce load
game.update = function () {
	if (maze) {
		handleMovement();
		// Only render raycast every few frames to improve performance
		if (LK.ticks - lastRenderTime >= 2) {
			raycastRenderer.render(playerX, playerY, playerAngle, maze);
			lastRenderTime = LK.ticks;
		}
		// Add breadcrumb trail
		breadcrumbTimer++;
		if (breadcrumbTimer >= 60) {
			// Every second
			var currentMapX = Math.floor(playerX);
			var currentMapY = Math.floor(playerY);
			if (currentMapX !== lastBreadcrumbX || currentMapY !== lastBreadcrumbY) {
				var breadcrumb = LK.getAsset('breadcrumb', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				breadcrumb.x = (currentMapX + 0.5) * 64;
				breadcrumb.y = (currentMapY + 0.5) * 64;
				breadcrumb.alpha = 0.7;
				breadcrumbContainer.addChild(breadcrumb);
				breadcrumbs.push(breadcrumb);
				lastBreadcrumbX = currentMapX;
				lastBreadcrumbY = currentMapY;
				breadcrumbTimer = 0;
				// Limit breadcrumbs to prevent memory issues
				if (breadcrumbs.length > 50) {
					var oldBreadcrumb = breadcrumbs.shift();
					oldBreadcrumb.destroy();
				}
			}
		}
		// Minimap update removed
	}
};
// Start the game
initLevel();