/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	currentLevel: 1,
	unlockedLevels: 1
});
/**** 
* Classes
****/ 
var DimensionSwitch = Container.expand(function () {
	var self = Container.call(this);
	// Create switch graphic
	self.graphic = self.attachAsset('dimensionSwitch', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create pulsing animation
	self.pulseAnimation = function () {
		tween(self.graphic, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(self.graphic, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.easeInOut,
					onFinish: self.pulseAnimation
				});
			}
		});
	};
	// Start pulsing
	self.pulseAnimation();
	return self;
});
var Goal = Container.expand(function () {
	var self = Container.call(this);
	// Create goal graphic
	self.graphic = self.attachAsset('goal', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Animate the goal
	self.animateGoal = function () {
		tween(self, {
			rotation: Math.PI * 2
		}, {
			duration: 3000,
			onFinish: function onFinish() {
				self.rotation = 0;
				self.animateGoal();
			}
		});
	};
	// Start animation
	self.animateGoal();
	return self;
});
var Hazard = Container.expand(function () {
	var self = Container.call(this);
	// Create hazard graphic
	self.graphic = self.attachAsset('hazard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	return self;
});
var LevelButton = Container.expand(function (levelNum) {
	var self = Container.call(this);
	self.levelNum = levelNum;
	// Create button background
	self.background = self.attachAsset('levelSelectButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create level text
	self.text = new Text2(levelNum.toString(), {
		size: 50,
		fill: 0xFFFFFF
	});
	self.text.anchor.set(0.5, 0.5);
	self.addChild(self.text);
	// Interactive events
	self.down = function (x, y, obj) {
		if (storage.unlockedLevels >= self.levelNum) {
			tween(self, {
				scaleX: 0.9,
				scaleY: 0.9
			}, {
				duration: 100
			});
		}
	};
	self.up = function (x, y, obj) {
		tween(self, {
			scaleX: 1,
			scaleY: 1
		}, {
			duration: 100,
			onFinish: function onFinish() {
				if (storage.unlockedLevels >= self.levelNum) {
					storage.currentLevel = self.levelNum;
					startGame();
				}
			}
		});
	};
	// Update appearance based on level unlock status
	self.updateAppearance = function () {
		if (storage.unlockedLevels >= self.levelNum) {
			self.background.alpha = 1;
			self.text.alpha = 1;
		} else {
			self.background.alpha = 0.5;
			self.text.setText("🔒");
		}
	};
	self.updateAppearance();
	return self;
});
var Platform = Container.expand(function (type) {
	var self = Container.call(this);
	// Platform properties
	self.type = type || 'light'; // 'light' or 'shadow'
	// Create platform graphic
	self.graphic = self.attachAsset(self.type === 'light' ? 'lightPlatform' : 'shadowPlatform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Check if platform is solid in current dimension
	self.isSolid = function (isDimensionLight) {
		return self.type === 'light' && isDimensionLight || self.type === 'shadow' && !isDimensionLight;
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	// Player properties
	self.velocityX = 0;
	self.velocityY = 0;
	self.speed = 10;
	self.jumpForce = -24;
	self.gravity = 0.3; // Reduced gravity for slower falling
	self.isGrounded = false;
	self.isDimensionLight = true;
	self.isDead = false;
	self.isGliding = false;
	self.collectedTrophies = 0;
	self.totalTrophies = 0;
	// Create light and shadow versions of player
	self.lightForm = self.attachAsset('playerLight', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.shadowForm = self.attachAsset('playerShadow', {
		anchorX: 0.5,
		anchorY: 0.5,
		visible: false
	});
	// Swap dimensions
	self.swapDimension = function () {
		if (self.isDead) {
			return;
		}
		self.isDimensionLight = !self.isDimensionLight;
		self.lightForm.visible = self.isDimensionLight;
		self.shadowForm.visible = !self.isDimensionLight;
		LK.getSound('swap').play();
		// Visual effect for dimension swap
		LK.effects.flashObject(self, self.isDimensionLight ? 0xFFFFFF : 0x000000, 300);
	};
	// Jump action
	self.jump = function () {
		if (self.isGrounded && !self.isDead) {
			self.velocityY = self.jumpForce;
			self.isGrounded = false;
			LK.getSound('jump').play();
		}
	};
	// Move left
	self.moveLeft = function () {
		if (!self.isDead) {
			self.velocityX = -self.speed;
		}
	};
	// Move right
	self.moveRight = function () {
		if (!self.isDead) {
			self.velocityX = self.speed;
		}
	};
	// Stop horizontal movement
	self.stopMoving = function () {
		self.velocityX = 0;
	};
	// Kill player
	self.die = function () {
		if (!self.isDead) {
			self.isDead = true;
			LK.getSound('death').play();
			tween(self, {
				alpha: 0
			}, {
				duration: 500,
				onFinish: function onFinish() {
					// Let the game handle the reset
					restartLevel();
				}
			});
		}
	};
	// Physics update
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Track if player is gliding
		var isGliding = Math.abs(self.velocityX) > 3 && !self.isGrounded && self.velocityY > 0;
		// Apply gravity with gliding effect
		if (isGliding) {
			// Reduced gravity when gliding
			self.velocityY += self.gravity * 0.3;
			// Cap fall speed while gliding
			if (self.velocityY > 5) {
				self.velocityY = 5;
			}
		} else {
			// Normal gravity
			self.velocityY += self.gravity;
		}
		// Apply velocities
		self.x += self.velocityX;
		self.y += self.velocityY;
		// Simple friction
		if (Math.abs(self.velocityX) > 0.1) {
			// Less friction while gliding
			self.velocityX *= isGliding ? 0.98 : 0.9;
		} else {
			self.velocityX = 0;
		}
		// Visual effect for gliding
		if (isGliding && !self.isGliding) {
			self.isGliding = true;
			// Stretch horizontally while gliding
			tween(self, {
				scaleX: 1.3,
				scaleY: 0.8
			}, {
				duration: 300
			});
		} else if (!isGliding && self.isGliding) {
			self.isGliding = false;
			// Return to normal shape
			tween(self, {
				scaleX: 1,
				scaleY: 1
			}, {
				duration: 300
			});
		}
		// Screen bounds
		if (self.x < 30) {
			self.x = 30;
		} else if (self.x > 2048 - 30) {
			self.x = 2048 - 30;
		}
		if (self.y > 2732) {
			self.die();
		}
	};
	return self;
});
var Trophy = Container.expand(function () {
	var self = Container.call(this);
	// Create trophy graphic - using goal asset with different color
	self.graphic = self.attachAsset('goal', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.6,
		scaleY: 0.6
	});
	// Apply gold color tint
	self.graphic.tint = 0xFFD700;
	// Hover animation
	self.animate = function () {
		tween(self, {
			y: self.y - 10
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(self, {
					y: self.y + 10
				}, {
					duration: 1000,
					easing: tween.easeInOut,
					onFinish: self.animate
				});
			}
		});
	};
	// Start animation
	self.animate();
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x222222
});
/**** 
* Game Code
****/ 
// Game states
var STATE_MENU = 'menu';
var STATE_GAME = 'game';
var gameState = STATE_MENU;
// Game elements
var player;
var platforms = [];
var hazards = [];
var dimensionSwitches = [];
var trophies = [];
var goal;
var levelButtons = [];
var touchControls = {};
var background;
// Game logic variables
var totalLevels = 5;
var currentLevel = storage.currentLevel || 1;
var isSwapEnabled = true;
var swapCooldown = 0;
var levelComplete = false;
// Level designs
var levels = [
// Level 1: Simple introduction
{
	playerStart: {
		x: 300,
		y: 300
	},
	platforms: [{
		x: 300,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 600,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 900,
		y: 600,
		type: 'light',
		width: 1
	}, {
		x: 1200,
		y: 700,
		type: 'shadow',
		width: 1
	}, {
		x: 1500,
		y: 800,
		type: 'light',
		width: 1
	}],
	dimensionSwitches: [{
		x: 600,
		y: 520
	}, {
		x: 1200,
		y: 920
	}],
	hazards: [],
	goal: {
		x: 1500,
		y: 1120
	}
},
// Level 2: Platforms and hazards
{
	playerStart: {
		x: 200,
		y: 300
	},
	platforms: [{
		x: 200,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 500,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 800,
		y: 600,
		type: 'light',
		width: 1
	}, {
		x: 1100,
		y: 700,
		type: 'shadow',
		width: 1
	}, {
		x: 1400,
		y: 800,
		type: 'light',
		width: 1
	}, {
		x: 1700,
		y: 900,
		type: 'shadow',
		width: 1
	}],
	dimensionSwitches: [{
		x: 500,
		y: 420
	}, {
		x: 1100,
		y: 620
	}],
	hazards: [{
		x: 800,
		y: 500
	}, {
		x: 1400,
		y: 700
	}],
	goal: {
		x: 1700,
		y: 820
	}
},
// Level 3: More complex puzzle
{
	playerStart: {
		x: 150,
		y: 300
	},
	platforms: [{
		x: 150,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 450,
		y: 400,
		type: 'shadow',
		width: 1
	}, {
		x: 750,
		y: 500,
		type: 'light',
		width: 1
	}, {
		x: 1050,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 1350,
		y: 600,
		type: 'light',
		width: 1
	}, {
		x: 1650,
		y: 600,
		type: 'shadow',
		width: 1
	}, {
		x: 1650,
		y: 800,
		type: 'light',
		width: 1
	}, {
		x: 1350,
		y: 800,
		type: 'shadow',
		width: 1
	}, {
		x: 1050,
		y: 1000,
		type: 'light',
		width: 1
	}, {
		x: 750,
		y: 1000,
		type: 'shadow',
		width: 1
	}],
	dimensionSwitches: [{
		x: 450,
		y: 320
	}, {
		x: 1050,
		y: 420
	}, {
		x: 1650,
		y: 520
	}, {
		x: 1050,
		y: 920
	}],
	hazards: [{
		x: 750,
		y: 400
	}, {
		x: 1350,
		y: 500
	}, {
		x: 1350,
		y: 900
	}],
	goal: {
		x: 750,
		y: 920
	}
},
// Level 4: Advanced obstacles
{
	playerStart: {
		x: 200,
		y: 200
	},
	platforms: [{
		x: 200,
		y: 300,
		type: 'light',
		width: 1
	}, {
		x: 500,
		y: 300,
		type: 'shadow',
		width: 1
	}, {
		x: 800,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 1100,
		y: 400,
		type: 'shadow',
		width: 1
	}, {
		x: 1400,
		y: 500,
		type: 'light',
		width: 1
	}, {
		x: 1700,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 1400,
		y: 700,
		type: 'shadow',
		width: 1
	}, {
		x: 1100,
		y: 700,
		type: 'light',
		width: 1
	}, {
		x: 800,
		y: 900,
		type: 'shadow',
		width: 1
	}, {
		x: 500,
		y: 900,
		type: 'light',
		width: 1
	}, {
		x: 200,
		y: 1100,
		type: 'shadow',
		width: 1
	}, {
		x: 500,
		y: 1100,
		type: 'light',
		width: 1
	}],
	dimensionSwitches: [{
		x: 500,
		y: 220
	}, {
		x: 1100,
		y: 320
	}, {
		x: 1400,
		y: 620
	}, {
		x: 800,
		y: 820
	}, {
		x: 200,
		y: 1020
	}],
	hazards: [{
		x: 800,
		y: 300
	}, {
		x: 1400,
		y: 400
	}, {
		x: 1100,
		y: 600
	}, {
		x: 500,
		y: 800
	}],
	goal: {
		x: 500,
		y: 1020
	}
},
// Level 5: Final challenge
{
	playerStart: {
		x: 150,
		y: 200
	},
	platforms: [{
		x: 150,
		y: 300,
		type: 'light',
		width: 1
	}, {
		x: 450,
		y: 400,
		type: 'shadow',
		width: 1
	}, {
		x: 750,
		y: 500,
		type: 'light',
		width: 1
	}, {
		x: 1050,
		y: 600,
		type: 'shadow',
		width: 1
	}, {
		x: 1350,
		y: 700,
		type: 'light',
		width: 1
	}, {
		x: 1650,
		y: 800,
		type: 'shadow',
		width: 1
	}, {
		x: 1350,
		y: 1000,
		type: 'shadow',
		width: 1
	}, {
		x: 1050,
		y: 1200,
		type: 'light',
		width: 1
	}, {
		x: 750,
		y: 1400,
		type: 'shadow',
		width: 1
	}, {
		x: 450,
		y: 1600,
		type: 'light',
		width: 1
	}, {
		x: 750,
		y: 1800,
		type: 'shadow',
		width: 1
	}, {
		x: 1050,
		y: 2000,
		type: 'light',
		width: 1
	}, {
		x: 1350,
		y: 2200,
		type: 'shadow',
		width: 1
	}, {
		x: 1650,
		y: 2400,
		type: 'light',
		width: 1
	}],
	dimensionSwitches: [{
		x: 450,
		y: 320
	}, {
		x: 1050,
		y: 520
	}, {
		x: 1650,
		y: 720
	}, {
		x: 1050,
		y: 1120
	}, {
		x: 450,
		y: 1520
	}, {
		x: 1050,
		y: 1920
	}, {
		x: 1650,
		y: 2320
	}],
	hazards: [{
		x: 750,
		y: 400
	}, {
		x: 1350,
		y: 600
	}, {
		x: 1350,
		y: 900
	}, {
		x: 750,
		y: 1300
	}, {
		x: 750,
		y: 1700
	}, {
		x: 1350,
		y: 2100
	}],
	trophies: [{
		x: 750,
		y: 450
	}, {
		x: 1350,
		y: 650
	}, {
		x: 750,
		y: 1350
	}, {
		x: 1050,
		y: 1950
	}],
	goal: {
		x: 1650,
		y: 2320
	}
}];
// Initialize menu
function setupMenu() {
	gameState = STATE_MENU;
	clearLevel();
	// Create title text
	var titleText = new Text2("SHADOW SWAP", {
		size: 100,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 400;
	game.addChild(titleText);
	// Create level selection text
	var levelSelectText = new Text2("SELECT LEVEL", {
		size: 60,
		fill: 0xFFFFFF
	});
	levelSelectText.anchor.set(0.5, 0.5);
	levelSelectText.x = 2048 / 2;
	levelSelectText.y = 550;
	game.addChild(levelSelectText);
	// Create level selection buttons
	for (var i = 0; i < totalLevels; i++) {
		var button = new LevelButton(i + 1);
		button.x = 2048 / 2 + (i - 2) * 250;
		button.y = 700;
		levelButtons.push(button);
		game.addChild(button);
	}
	// Create instruction text
	var instructionText = new Text2("CONTROLS:\n" + "- TAP LEFT/RIGHT SIDES TO MOVE\n" + "- TAP CENTER TO JUMP\n" + "- SWIPE UP TO SWAP DIMENSIONS\n" + "- MOVE HORIZONTALLY TO GLIDE\n\n" + "GOAL:\n" + "- NAVIGATE THROUGH PLATFORMS\n" + "- LIGHT PLATFORMS ARE SOLID IN LIGHT DIMENSION\n" + "- SHADOW PLATFORMS ARE SOLID IN SHADOW DIMENSION\n" + "- COLLECT ALL GOLDEN TROPHIES\n" + "- REACH THE GREEN GOAL TO COMPLETE LEVEL", {
		size: 40,
		fill: 0xFFFFFF
	});
	instructionText.anchor.set(0.5, 0);
	instructionText.x = 2048 / 2;
	instructionText.y = 900;
	game.addChild(instructionText);
}
// Start game with the selected level
function startGame() {
	gameState = STATE_GAME;
	clearLevel();
	setupLevel(storage.currentLevel);
	LK.playMusic('gameBgm');
}
// Clear all game elements
function clearLevel() {
	// Remove all game objects
	if (player) {
		game.removeChild(player);
		player = null;
	}
	platforms.forEach(function (platform) {
		game.removeChild(platform);
	});
	platforms = [];
	hazards.forEach(function (hazard) {
		game.removeChild(hazard);
	});
	hazards = [];
	dimensionSwitches.forEach(function (dimensionSwitch) {
		game.removeChild(dimensionSwitch);
	});
	dimensionSwitches = [];
	trophies.forEach(function (trophy) {
		game.removeChild(trophy);
	});
	trophies = [];
	if (goal) {
		game.removeChild(goal);
		goal = null;
	}
	levelButtons.forEach(function (button) {
		game.removeChild(button);
	});
	levelButtons = [];
	// Remove any other UI elements
	for (var key in touchControls) {
		if (touchControls[key]) {
			game.removeChild(touchControls[key]);
		}
	}
	touchControls = {};
	// Reset game state
	levelComplete = false;
	isSwapEnabled = true;
	swapCooldown = 0;
	// Clear any existing children
	while (game.children.length > 0) {
		game.removeChild(game.children[0]);
	}
}
// Set up a level
function setupLevel(levelNum) {
	currentLevel = levelNum;
	var levelData = levels[levelNum - 1] || levels[0];
	// Create background
	background = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.3
	});
	background.x = 2048 / 2;
	background.y = 2732 / 2;
	game.addChild(background);
	// Create level text
	var levelText = new Text2("LEVEL " + currentLevel, {
		size: 60,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0.5, 0);
	levelText.x = 2048 / 2;
	levelText.y = 50;
	game.addChild(levelText);
	// Create dimension indicator
	var dimensionText = new Text2("DIMENSION: LIGHT", {
		size: 40,
		fill: 0xFFFFFF
	});
	dimensionText.anchor.set(0.5, 0);
	dimensionText.x = 2048 / 2;
	dimensionText.y = 120;
	game.addChild(dimensionText);
	touchControls.dimensionText = dimensionText;
	// Create trophy counter text
	var trophyText = new Text2("TROPHIES: 0/0", {
		size: 40,
		fill: 0xFFD700
	});
	trophyText.anchor.set(0.5, 0);
	trophyText.x = 2048 / 2;
	trophyText.y = 180;
	game.addChild(trophyText);
	touchControls.trophyText = trophyText;
	// Create player
	player = new Player();
	player.x = levelData.playerStart.x;
	player.y = levelData.playerStart.y;
	game.addChild(player);
	// Create platforms
	levelData.platforms.forEach(function (platformData) {
		var platform = new Platform(platformData.type);
		platform.x = platformData.x;
		platform.y = platformData.y;
		// Make all platforms 1.5x wider for easier landing
		platform.graphic.scaleX = platformData.width ? platformData.width * 1.5 : 1.5;
		platforms.push(platform);
		game.addChild(platform);
	});
	// Create dimension switches
	levelData.dimensionSwitches.forEach(function (switchData) {
		var dimensionSwitch = new DimensionSwitch();
		dimensionSwitch.x = switchData.x;
		dimensionSwitch.y = switchData.y;
		dimensionSwitches.push(dimensionSwitch);
		game.addChild(dimensionSwitch);
	});
	// Create hazards (limit the number of hazards per level to make it easier)
	var hazardCount = 0;
	levelData.hazards.forEach(function (hazardData) {
		// Only create 2/3 of the hazards to make game easier
		hazardCount++;
		if (hazardCount % 3 !== 0) {
			// Skip every third hazard
			var hazard = new Hazard();
			hazard.x = hazardData.x;
			hazard.y = hazardData.y;
			hazards.push(hazard);
			game.addChild(hazard);
		}
	});
	// Create trophies
	if (levelData.trophies) {
		player.totalTrophies = levelData.trophies.length;
		player.collectedTrophies = 0;
		levelData.trophies.forEach(function (trophyData) {
			var trophy = new Trophy();
			trophy.x = trophyData.x;
			trophy.y = trophyData.y;
			trophy.collected = false;
			trophies.push(trophy);
			game.addChild(trophy);
		});
		// Update trophy counter
		if (touchControls.trophyText) {
			touchControls.trophyText.setText("TROPHIES: " + player.collectedTrophies + "/" + player.totalTrophies);
		}
	}
	// Create goal
	goal = new Goal();
	goal.x = levelData.goal.x;
	goal.y = levelData.goal.y;
	game.addChild(goal);
	// Touch controls areas (invisible)
	var leftControl = LK.getAsset('lightPlatform', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0
	});
	leftControl.width = 2048 / 3;
	leftControl.height = 2732;
	leftControl.x = 0;
	leftControl.y = 0;
	game.addChild(leftControl);
	touchControls.left = leftControl;
	var rightControl = LK.getAsset('lightPlatform', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0
	});
	rightControl.width = 2048 / 3;
	rightControl.height = 2732;
	rightControl.x = 2048 * 2 / 3;
	rightControl.y = 0;
	game.addChild(rightControl);
	touchControls.right = rightControl;
	var centerControl = LK.getAsset('lightPlatform', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0
	});
	centerControl.width = 2048 / 3;
	centerControl.height = 2732;
	centerControl.x = 2048 / 3;
	centerControl.y = 0;
	game.addChild(centerControl);
	touchControls.center = centerControl;
}
// Restart current level
function restartLevel() {
	clearLevel();
	setupLevel(currentLevel);
}
// Complete level and move to next
function completeLevel() {
	if (!levelComplete) {
		// For the final level, require all trophies to be collected before completing
		if (currentLevel === totalLevels && player.collectedTrophies < player.totalTrophies) {
			// Show message that trophies are required
			var missingTrophiesText = new Text2("COLLECT ALL TROPHIES FIRST!", {
				size: 60,
				fill: 0xFFD700
			});
			missingTrophiesText.anchor.set(0.5, 0.5);
			missingTrophiesText.x = 2048 / 2;
			missingTrophiesText.y = 2732 / 2;
			game.addChild(missingTrophiesText);
			// Flash and remove after 2 seconds
			tween(missingTrophiesText, {
				alpha: 0
			}, {
				duration: 2000,
				onFinish: function onFinish() {
					game.removeChild(missingTrophiesText);
				}
			});
			return;
		}
		levelComplete = true;
		LK.getSound('win').play();
		// Update unlocked levels
		if (currentLevel >= storage.unlockedLevels) {
			storage.unlockedLevels = currentLevel + 1;
			if (storage.unlockedLevels > totalLevels) {
				storage.unlockedLevels = totalLevels;
			}
		}
		// Show win animation
		tween(player, {
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				LK.showYouWin();
				// Move to next level
				if (currentLevel < totalLevels) {
					storage.currentLevel = currentLevel + 1;
				} else {
					// If all levels completed, go back to menu
					setupMenu();
				}
			}
		});
	}
}
// Check collisions between player and platforms
function checkPlatformCollisions() {
	var wasGrounded = player.isGrounded;
	player.isGrounded = false;
	platforms.forEach(function (platform) {
		if (platform.isSolid(player.isDimensionLight) && player.intersects(platform)) {
			// Calculate collision sides
			var playerBottom = player.y + player.lightForm.height / 2;
			var playerTop = player.y - player.lightForm.height / 2;
			var playerLeft = player.x - player.lightForm.width / 2;
			var playerRight = player.x + player.lightForm.width / 2;
			var platformBottom = platform.y + platform.graphic.height / 2;
			var platformTop = platform.y - platform.graphic.height / 2;
			var platformLeft = platform.x - platform.graphic.width / 2;
			var platformRight = platform.x + platform.graphic.width / 2;
			// Calculate penetration depths
			var fromTop = playerBottom - platformTop;
			var fromBottom = platformBottom - playerTop;
			var fromLeft = playerRight - platformLeft;
			var fromRight = platformRight - playerLeft;
			// Find minimum penetration
			var minPenetration = Math.min(fromTop, fromBottom, fromLeft, fromRight);
			// Resolve collision based on minimum penetration
			if (minPenetration === fromTop && player.velocityY > 0) {
				player.y = platformTop - player.lightForm.height / 2;
				player.velocityY = 0;
				player.isGrounded = true;
			} else if (minPenetration === fromBottom && player.velocityY < 0) {
				player.y = platformBottom + player.lightForm.height / 2;
				player.velocityY = 0;
			} else if (minPenetration === fromLeft && player.velocityX > 0) {
				player.x = platformLeft - player.lightForm.width / 2;
				player.velocityX = 0;
			} else if (minPenetration === fromRight && player.velocityX < 0) {
				player.x = platformRight + player.lightForm.width / 2;
				player.velocityX = 0;
			}
		}
	});
	// Landing effect
	if (!wasGrounded && player.isGrounded) {
		tween(player, {
			scaleX: 1.2,
			scaleY: 0.8
		}, {
			duration: 100,
			onFinish: function onFinish() {
				tween(player, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 100
				});
			}
		});
	}
}
// Check other game object interactions
function checkInteractions() {
	// Check dimension switches
	dimensionSwitches.forEach(function (dimensionSwitch) {
		if (player.intersects(dimensionSwitch) && isSwapEnabled) {
			player.swapDimension();
			isSwapEnabled = false;
			swapCooldown = 45; // 0.75-second cooldown at 60 FPS
			// Update dimension text
			if (touchControls.dimensionText) {
				touchControls.dimensionText.setText("DIMENSION: " + (player.isDimensionLight ? "LIGHT" : "SHADOW"));
			}
			// Animate the switch
			tween(dimensionSwitch, {
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 200,
				onFinish: function onFinish() {
					tween(dimensionSwitch, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 200
					});
				}
			});
		}
	});
	// Check hazards
	hazards.forEach(function (hazard) {
		if (player.intersects(hazard)) {
			player.die();
		}
	});
	// Check trophies
	trophies.forEach(function (trophy, index) {
		if (!trophy.collected && player.intersects(trophy)) {
			// Collect trophy
			trophy.collected = true;
			player.collectedTrophies++;
			// Update trophy counter
			if (touchControls.trophyText) {
				touchControls.trophyText.setText("TROPHIES: " + player.collectedTrophies + "/" + player.totalTrophies);
			}
			// Trophy collection animation
			tween(trophy, {
				scaleX: 0,
				scaleY: 0,
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					game.removeChild(trophy);
				}
			});
		}
	});
	// Check goal
	if (player.intersects(goal)) {
		completeLevel();
	}
	// Swap cooldown
	if (!isSwapEnabled) {
		swapCooldown--;
		if (swapCooldown <= 0) {
			isSwapEnabled = true;
		}
	}
}
// Touch controls
var touchStart = {
	x: 0,
	y: 0
};
var isTouching = false;
var movingLeft = false;
var movingRight = false;
game.down = function (x, y, obj) {
	if (gameState === STATE_GAME) {
		touchStart.x = x;
		touchStart.y = y;
		isTouching = true;
		// Check which control area was touched
		if (x < 2048 / 3) {
			// Left side - move left
			movingLeft = true;
			player.moveLeft();
		} else if (x > 2048 * 2 / 3) {
			// Right side - move right
			movingRight = true;
			player.moveRight();
		} else {
			// Center - jump
			player.jump();
		}
	}
};
game.move = function (x, y, obj) {
	if (gameState === STATE_GAME && isTouching) {
		// Check for swipe up (dimension swap) - reduced distance required
		if (y < touchStart.y - 70) {
			if (isSwapEnabled) {
				player.swapDimension();
				isSwapEnabled = false;
				swapCooldown = 45;
				// Update dimension text
				if (touchControls.dimensionText) {
					touchControls.dimensionText.setText("DIMENSION: " + (player.isDimensionLight ? "LIGHT" : "SHADOW"));
				}
			}
			// Reset touch to prevent multiple swipes
			isTouching = false;
		}
	}
};
game.up = function (x, y, obj) {
	if (gameState === STATE_GAME) {
		isTouching = false;
		// Stop horizontal movement if this was a movement control
		if (movingLeft || movingRight) {
			player.stopMoving();
			movingLeft = false;
			movingRight = false;
		}
	}
};
// Main game update loop
game.update = function () {
	if (gameState === STATE_GAME && !levelComplete && player && !player.isDead) {
		// Update player physics
		player.update();
		// Check collisions and interactions
		checkPlatformCollisions();
		checkInteractions();
		// Update platform visuals based on current dimension
		platforms.forEach(function (platform) {
			// Make solid platforms more visible (higher alpha) in current dimension
			if (platform.isSolid(player.isDimensionLight)) {
				platform.graphic.alpha = 1.0;
			} else {
				platform.graphic.alpha = 0.5;
			}
		});
	}
};
// Initialize the game with the menu
setupMenu(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	currentLevel: 1,
	unlockedLevels: 1
});
/**** 
* Classes
****/ 
var DimensionSwitch = Container.expand(function () {
	var self = Container.call(this);
	// Create switch graphic
	self.graphic = self.attachAsset('dimensionSwitch', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create pulsing animation
	self.pulseAnimation = function () {
		tween(self.graphic, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(self.graphic, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.easeInOut,
					onFinish: self.pulseAnimation
				});
			}
		});
	};
	// Start pulsing
	self.pulseAnimation();
	return self;
});
var Goal = Container.expand(function () {
	var self = Container.call(this);
	// Create goal graphic
	self.graphic = self.attachAsset('goal', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Animate the goal
	self.animateGoal = function () {
		tween(self, {
			rotation: Math.PI * 2
		}, {
			duration: 3000,
			onFinish: function onFinish() {
				self.rotation = 0;
				self.animateGoal();
			}
		});
	};
	// Start animation
	self.animateGoal();
	return self;
});
var Hazard = Container.expand(function () {
	var self = Container.call(this);
	// Create hazard graphic
	self.graphic = self.attachAsset('hazard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	return self;
});
var LevelButton = Container.expand(function (levelNum) {
	var self = Container.call(this);
	self.levelNum = levelNum;
	// Create button background
	self.background = self.attachAsset('levelSelectButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create level text
	self.text = new Text2(levelNum.toString(), {
		size: 50,
		fill: 0xFFFFFF
	});
	self.text.anchor.set(0.5, 0.5);
	self.addChild(self.text);
	// Interactive events
	self.down = function (x, y, obj) {
		if (storage.unlockedLevels >= self.levelNum) {
			tween(self, {
				scaleX: 0.9,
				scaleY: 0.9
			}, {
				duration: 100
			});
		}
	};
	self.up = function (x, y, obj) {
		tween(self, {
			scaleX: 1,
			scaleY: 1
		}, {
			duration: 100,
			onFinish: function onFinish() {
				if (storage.unlockedLevels >= self.levelNum) {
					storage.currentLevel = self.levelNum;
					startGame();
				}
			}
		});
	};
	// Update appearance based on level unlock status
	self.updateAppearance = function () {
		if (storage.unlockedLevels >= self.levelNum) {
			self.background.alpha = 1;
			self.text.alpha = 1;
		} else {
			self.background.alpha = 0.5;
			self.text.setText("🔒");
		}
	};
	self.updateAppearance();
	return self;
});
var Platform = Container.expand(function (type) {
	var self = Container.call(this);
	// Platform properties
	self.type = type || 'light'; // 'light' or 'shadow'
	// Create platform graphic
	self.graphic = self.attachAsset(self.type === 'light' ? 'lightPlatform' : 'shadowPlatform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Check if platform is solid in current dimension
	self.isSolid = function (isDimensionLight) {
		return self.type === 'light' && isDimensionLight || self.type === 'shadow' && !isDimensionLight;
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	// Player properties
	self.velocityX = 0;
	self.velocityY = 0;
	self.speed = 10;
	self.jumpForce = -24;
	self.gravity = 0.3; // Reduced gravity for slower falling
	self.isGrounded = false;
	self.isDimensionLight = true;
	self.isDead = false;
	self.isGliding = false;
	self.collectedTrophies = 0;
	self.totalTrophies = 0;
	// Create light and shadow versions of player
	self.lightForm = self.attachAsset('playerLight', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.shadowForm = self.attachAsset('playerShadow', {
		anchorX: 0.5,
		anchorY: 0.5,
		visible: false
	});
	// Swap dimensions
	self.swapDimension = function () {
		if (self.isDead) {
			return;
		}
		self.isDimensionLight = !self.isDimensionLight;
		self.lightForm.visible = self.isDimensionLight;
		self.shadowForm.visible = !self.isDimensionLight;
		LK.getSound('swap').play();
		// Visual effect for dimension swap
		LK.effects.flashObject(self, self.isDimensionLight ? 0xFFFFFF : 0x000000, 300);
	};
	// Jump action
	self.jump = function () {
		if (self.isGrounded && !self.isDead) {
			self.velocityY = self.jumpForce;
			self.isGrounded = false;
			LK.getSound('jump').play();
		}
	};
	// Move left
	self.moveLeft = function () {
		if (!self.isDead) {
			self.velocityX = -self.speed;
		}
	};
	// Move right
	self.moveRight = function () {
		if (!self.isDead) {
			self.velocityX = self.speed;
		}
	};
	// Stop horizontal movement
	self.stopMoving = function () {
		self.velocityX = 0;
	};
	// Kill player
	self.die = function () {
		if (!self.isDead) {
			self.isDead = true;
			LK.getSound('death').play();
			tween(self, {
				alpha: 0
			}, {
				duration: 500,
				onFinish: function onFinish() {
					// Let the game handle the reset
					restartLevel();
				}
			});
		}
	};
	// Physics update
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Track if player is gliding
		var isGliding = Math.abs(self.velocityX) > 3 && !self.isGrounded && self.velocityY > 0;
		// Apply gravity with gliding effect
		if (isGliding) {
			// Reduced gravity when gliding
			self.velocityY += self.gravity * 0.3;
			// Cap fall speed while gliding
			if (self.velocityY > 5) {
				self.velocityY = 5;
			}
		} else {
			// Normal gravity
			self.velocityY += self.gravity;
		}
		// Apply velocities
		self.x += self.velocityX;
		self.y += self.velocityY;
		// Simple friction
		if (Math.abs(self.velocityX) > 0.1) {
			// Less friction while gliding
			self.velocityX *= isGliding ? 0.98 : 0.9;
		} else {
			self.velocityX = 0;
		}
		// Visual effect for gliding
		if (isGliding && !self.isGliding) {
			self.isGliding = true;
			// Stretch horizontally while gliding
			tween(self, {
				scaleX: 1.3,
				scaleY: 0.8
			}, {
				duration: 300
			});
		} else if (!isGliding && self.isGliding) {
			self.isGliding = false;
			// Return to normal shape
			tween(self, {
				scaleX: 1,
				scaleY: 1
			}, {
				duration: 300
			});
		}
		// Screen bounds
		if (self.x < 30) {
			self.x = 30;
		} else if (self.x > 2048 - 30) {
			self.x = 2048 - 30;
		}
		if (self.y > 2732) {
			self.die();
		}
	};
	return self;
});
var Trophy = Container.expand(function () {
	var self = Container.call(this);
	// Create trophy graphic - using goal asset with different color
	self.graphic = self.attachAsset('goal', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.6,
		scaleY: 0.6
	});
	// Apply gold color tint
	self.graphic.tint = 0xFFD700;
	// Hover animation
	self.animate = function () {
		tween(self, {
			y: self.y - 10
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(self, {
					y: self.y + 10
				}, {
					duration: 1000,
					easing: tween.easeInOut,
					onFinish: self.animate
				});
			}
		});
	};
	// Start animation
	self.animate();
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x222222
});
/**** 
* Game Code
****/ 
// Game states
var STATE_MENU = 'menu';
var STATE_GAME = 'game';
var gameState = STATE_MENU;
// Game elements
var player;
var platforms = [];
var hazards = [];
var dimensionSwitches = [];
var trophies = [];
var goal;
var levelButtons = [];
var touchControls = {};
var background;
// Game logic variables
var totalLevels = 5;
var currentLevel = storage.currentLevel || 1;
var isSwapEnabled = true;
var swapCooldown = 0;
var levelComplete = false;
// Level designs
var levels = [
// Level 1: Simple introduction
{
	playerStart: {
		x: 300,
		y: 300
	},
	platforms: [{
		x: 300,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 600,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 900,
		y: 600,
		type: 'light',
		width: 1
	}, {
		x: 1200,
		y: 700,
		type: 'shadow',
		width: 1
	}, {
		x: 1500,
		y: 800,
		type: 'light',
		width: 1
	}],
	dimensionSwitches: [{
		x: 600,
		y: 520
	}, {
		x: 1200,
		y: 920
	}],
	hazards: [],
	goal: {
		x: 1500,
		y: 1120
	}
},
// Level 2: Platforms and hazards
{
	playerStart: {
		x: 200,
		y: 300
	},
	platforms: [{
		x: 200,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 500,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 800,
		y: 600,
		type: 'light',
		width: 1
	}, {
		x: 1100,
		y: 700,
		type: 'shadow',
		width: 1
	}, {
		x: 1400,
		y: 800,
		type: 'light',
		width: 1
	}, {
		x: 1700,
		y: 900,
		type: 'shadow',
		width: 1
	}],
	dimensionSwitches: [{
		x: 500,
		y: 420
	}, {
		x: 1100,
		y: 620
	}],
	hazards: [{
		x: 800,
		y: 500
	}, {
		x: 1400,
		y: 700
	}],
	goal: {
		x: 1700,
		y: 820
	}
},
// Level 3: More complex puzzle
{
	playerStart: {
		x: 150,
		y: 300
	},
	platforms: [{
		x: 150,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 450,
		y: 400,
		type: 'shadow',
		width: 1
	}, {
		x: 750,
		y: 500,
		type: 'light',
		width: 1
	}, {
		x: 1050,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 1350,
		y: 600,
		type: 'light',
		width: 1
	}, {
		x: 1650,
		y: 600,
		type: 'shadow',
		width: 1
	}, {
		x: 1650,
		y: 800,
		type: 'light',
		width: 1
	}, {
		x: 1350,
		y: 800,
		type: 'shadow',
		width: 1
	}, {
		x: 1050,
		y: 1000,
		type: 'light',
		width: 1
	}, {
		x: 750,
		y: 1000,
		type: 'shadow',
		width: 1
	}],
	dimensionSwitches: [{
		x: 450,
		y: 320
	}, {
		x: 1050,
		y: 420
	}, {
		x: 1650,
		y: 520
	}, {
		x: 1050,
		y: 920
	}],
	hazards: [{
		x: 750,
		y: 400
	}, {
		x: 1350,
		y: 500
	}, {
		x: 1350,
		y: 900
	}],
	goal: {
		x: 750,
		y: 920
	}
},
// Level 4: Advanced obstacles
{
	playerStart: {
		x: 200,
		y: 200
	},
	platforms: [{
		x: 200,
		y: 300,
		type: 'light',
		width: 1
	}, {
		x: 500,
		y: 300,
		type: 'shadow',
		width: 1
	}, {
		x: 800,
		y: 400,
		type: 'light',
		width: 1
	}, {
		x: 1100,
		y: 400,
		type: 'shadow',
		width: 1
	}, {
		x: 1400,
		y: 500,
		type: 'light',
		width: 1
	}, {
		x: 1700,
		y: 500,
		type: 'shadow',
		width: 1
	}, {
		x: 1400,
		y: 700,
		type: 'shadow',
		width: 1
	}, {
		x: 1100,
		y: 700,
		type: 'light',
		width: 1
	}, {
		x: 800,
		y: 900,
		type: 'shadow',
		width: 1
	}, {
		x: 500,
		y: 900,
		type: 'light',
		width: 1
	}, {
		x: 200,
		y: 1100,
		type: 'shadow',
		width: 1
	}, {
		x: 500,
		y: 1100,
		type: 'light',
		width: 1
	}],
	dimensionSwitches: [{
		x: 500,
		y: 220
	}, {
		x: 1100,
		y: 320
	}, {
		x: 1400,
		y: 620
	}, {
		x: 800,
		y: 820
	}, {
		x: 200,
		y: 1020
	}],
	hazards: [{
		x: 800,
		y: 300
	}, {
		x: 1400,
		y: 400
	}, {
		x: 1100,
		y: 600
	}, {
		x: 500,
		y: 800
	}],
	goal: {
		x: 500,
		y: 1020
	}
},
// Level 5: Final challenge
{
	playerStart: {
		x: 150,
		y: 200
	},
	platforms: [{
		x: 150,
		y: 300,
		type: 'light',
		width: 1
	}, {
		x: 450,
		y: 400,
		type: 'shadow',
		width: 1
	}, {
		x: 750,
		y: 500,
		type: 'light',
		width: 1
	}, {
		x: 1050,
		y: 600,
		type: 'shadow',
		width: 1
	}, {
		x: 1350,
		y: 700,
		type: 'light',
		width: 1
	}, {
		x: 1650,
		y: 800,
		type: 'shadow',
		width: 1
	}, {
		x: 1350,
		y: 1000,
		type: 'shadow',
		width: 1
	}, {
		x: 1050,
		y: 1200,
		type: 'light',
		width: 1
	}, {
		x: 750,
		y: 1400,
		type: 'shadow',
		width: 1
	}, {
		x: 450,
		y: 1600,
		type: 'light',
		width: 1
	}, {
		x: 750,
		y: 1800,
		type: 'shadow',
		width: 1
	}, {
		x: 1050,
		y: 2000,
		type: 'light',
		width: 1
	}, {
		x: 1350,
		y: 2200,
		type: 'shadow',
		width: 1
	}, {
		x: 1650,
		y: 2400,
		type: 'light',
		width: 1
	}],
	dimensionSwitches: [{
		x: 450,
		y: 320
	}, {
		x: 1050,
		y: 520
	}, {
		x: 1650,
		y: 720
	}, {
		x: 1050,
		y: 1120
	}, {
		x: 450,
		y: 1520
	}, {
		x: 1050,
		y: 1920
	}, {
		x: 1650,
		y: 2320
	}],
	hazards: [{
		x: 750,
		y: 400
	}, {
		x: 1350,
		y: 600
	}, {
		x: 1350,
		y: 900
	}, {
		x: 750,
		y: 1300
	}, {
		x: 750,
		y: 1700
	}, {
		x: 1350,
		y: 2100
	}],
	trophies: [{
		x: 750,
		y: 450
	}, {
		x: 1350,
		y: 650
	}, {
		x: 750,
		y: 1350
	}, {
		x: 1050,
		y: 1950
	}],
	goal: {
		x: 1650,
		y: 2320
	}
}];
// Initialize menu
function setupMenu() {
	gameState = STATE_MENU;
	clearLevel();
	// Create title text
	var titleText = new Text2("SHADOW SWAP", {
		size: 100,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 400;
	game.addChild(titleText);
	// Create level selection text
	var levelSelectText = new Text2("SELECT LEVEL", {
		size: 60,
		fill: 0xFFFFFF
	});
	levelSelectText.anchor.set(0.5, 0.5);
	levelSelectText.x = 2048 / 2;
	levelSelectText.y = 550;
	game.addChild(levelSelectText);
	// Create level selection buttons
	for (var i = 0; i < totalLevels; i++) {
		var button = new LevelButton(i + 1);
		button.x = 2048 / 2 + (i - 2) * 250;
		button.y = 700;
		levelButtons.push(button);
		game.addChild(button);
	}
	// Create instruction text
	var instructionText = new Text2("CONTROLS:\n" + "- TAP LEFT/RIGHT SIDES TO MOVE\n" + "- TAP CENTER TO JUMP\n" + "- SWIPE UP TO SWAP DIMENSIONS\n" + "- MOVE HORIZONTALLY TO GLIDE\n\n" + "GOAL:\n" + "- NAVIGATE THROUGH PLATFORMS\n" + "- LIGHT PLATFORMS ARE SOLID IN LIGHT DIMENSION\n" + "- SHADOW PLATFORMS ARE SOLID IN SHADOW DIMENSION\n" + "- COLLECT ALL GOLDEN TROPHIES\n" + "- REACH THE GREEN GOAL TO COMPLETE LEVEL", {
		size: 40,
		fill: 0xFFFFFF
	});
	instructionText.anchor.set(0.5, 0);
	instructionText.x = 2048 / 2;
	instructionText.y = 900;
	game.addChild(instructionText);
}
// Start game with the selected level
function startGame() {
	gameState = STATE_GAME;
	clearLevel();
	setupLevel(storage.currentLevel);
	LK.playMusic('gameBgm');
}
// Clear all game elements
function clearLevel() {
	// Remove all game objects
	if (player) {
		game.removeChild(player);
		player = null;
	}
	platforms.forEach(function (platform) {
		game.removeChild(platform);
	});
	platforms = [];
	hazards.forEach(function (hazard) {
		game.removeChild(hazard);
	});
	hazards = [];
	dimensionSwitches.forEach(function (dimensionSwitch) {
		game.removeChild(dimensionSwitch);
	});
	dimensionSwitches = [];
	trophies.forEach(function (trophy) {
		game.removeChild(trophy);
	});
	trophies = [];
	if (goal) {
		game.removeChild(goal);
		goal = null;
	}
	levelButtons.forEach(function (button) {
		game.removeChild(button);
	});
	levelButtons = [];
	// Remove any other UI elements
	for (var key in touchControls) {
		if (touchControls[key]) {
			game.removeChild(touchControls[key]);
		}
	}
	touchControls = {};
	// Reset game state
	levelComplete = false;
	isSwapEnabled = true;
	swapCooldown = 0;
	// Clear any existing children
	while (game.children.length > 0) {
		game.removeChild(game.children[0]);
	}
}
// Set up a level
function setupLevel(levelNum) {
	currentLevel = levelNum;
	var levelData = levels[levelNum - 1] || levels[0];
	// Create background
	background = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.3
	});
	background.x = 2048 / 2;
	background.y = 2732 / 2;
	game.addChild(background);
	// Create level text
	var levelText = new Text2("LEVEL " + currentLevel, {
		size: 60,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0.5, 0);
	levelText.x = 2048 / 2;
	levelText.y = 50;
	game.addChild(levelText);
	// Create dimension indicator
	var dimensionText = new Text2("DIMENSION: LIGHT", {
		size: 40,
		fill: 0xFFFFFF
	});
	dimensionText.anchor.set(0.5, 0);
	dimensionText.x = 2048 / 2;
	dimensionText.y = 120;
	game.addChild(dimensionText);
	touchControls.dimensionText = dimensionText;
	// Create trophy counter text
	var trophyText = new Text2("TROPHIES: 0/0", {
		size: 40,
		fill: 0xFFD700
	});
	trophyText.anchor.set(0.5, 0);
	trophyText.x = 2048 / 2;
	trophyText.y = 180;
	game.addChild(trophyText);
	touchControls.trophyText = trophyText;
	// Create player
	player = new Player();
	player.x = levelData.playerStart.x;
	player.y = levelData.playerStart.y;
	game.addChild(player);
	// Create platforms
	levelData.platforms.forEach(function (platformData) {
		var platform = new Platform(platformData.type);
		platform.x = platformData.x;
		platform.y = platformData.y;
		// Make all platforms 1.5x wider for easier landing
		platform.graphic.scaleX = platformData.width ? platformData.width * 1.5 : 1.5;
		platforms.push(platform);
		game.addChild(platform);
	});
	// Create dimension switches
	levelData.dimensionSwitches.forEach(function (switchData) {
		var dimensionSwitch = new DimensionSwitch();
		dimensionSwitch.x = switchData.x;
		dimensionSwitch.y = switchData.y;
		dimensionSwitches.push(dimensionSwitch);
		game.addChild(dimensionSwitch);
	});
	// Create hazards (limit the number of hazards per level to make it easier)
	var hazardCount = 0;
	levelData.hazards.forEach(function (hazardData) {
		// Only create 2/3 of the hazards to make game easier
		hazardCount++;
		if (hazardCount % 3 !== 0) {
			// Skip every third hazard
			var hazard = new Hazard();
			hazard.x = hazardData.x;
			hazard.y = hazardData.y;
			hazards.push(hazard);
			game.addChild(hazard);
		}
	});
	// Create trophies
	if (levelData.trophies) {
		player.totalTrophies = levelData.trophies.length;
		player.collectedTrophies = 0;
		levelData.trophies.forEach(function (trophyData) {
			var trophy = new Trophy();
			trophy.x = trophyData.x;
			trophy.y = trophyData.y;
			trophy.collected = false;
			trophies.push(trophy);
			game.addChild(trophy);
		});
		// Update trophy counter
		if (touchControls.trophyText) {
			touchControls.trophyText.setText("TROPHIES: " + player.collectedTrophies + "/" + player.totalTrophies);
		}
	}
	// Create goal
	goal = new Goal();
	goal.x = levelData.goal.x;
	goal.y = levelData.goal.y;
	game.addChild(goal);
	// Touch controls areas (invisible)
	var leftControl = LK.getAsset('lightPlatform', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0
	});
	leftControl.width = 2048 / 3;
	leftControl.height = 2732;
	leftControl.x = 0;
	leftControl.y = 0;
	game.addChild(leftControl);
	touchControls.left = leftControl;
	var rightControl = LK.getAsset('lightPlatform', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0
	});
	rightControl.width = 2048 / 3;
	rightControl.height = 2732;
	rightControl.x = 2048 * 2 / 3;
	rightControl.y = 0;
	game.addChild(rightControl);
	touchControls.right = rightControl;
	var centerControl = LK.getAsset('lightPlatform', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0
	});
	centerControl.width = 2048 / 3;
	centerControl.height = 2732;
	centerControl.x = 2048 / 3;
	centerControl.y = 0;
	game.addChild(centerControl);
	touchControls.center = centerControl;
}
// Restart current level
function restartLevel() {
	clearLevel();
	setupLevel(currentLevel);
}
// Complete level and move to next
function completeLevel() {
	if (!levelComplete) {
		// For the final level, require all trophies to be collected before completing
		if (currentLevel === totalLevels && player.collectedTrophies < player.totalTrophies) {
			// Show message that trophies are required
			var missingTrophiesText = new Text2("COLLECT ALL TROPHIES FIRST!", {
				size: 60,
				fill: 0xFFD700
			});
			missingTrophiesText.anchor.set(0.5, 0.5);
			missingTrophiesText.x = 2048 / 2;
			missingTrophiesText.y = 2732 / 2;
			game.addChild(missingTrophiesText);
			// Flash and remove after 2 seconds
			tween(missingTrophiesText, {
				alpha: 0
			}, {
				duration: 2000,
				onFinish: function onFinish() {
					game.removeChild(missingTrophiesText);
				}
			});
			return;
		}
		levelComplete = true;
		LK.getSound('win').play();
		// Update unlocked levels
		if (currentLevel >= storage.unlockedLevels) {
			storage.unlockedLevels = currentLevel + 1;
			if (storage.unlockedLevels > totalLevels) {
				storage.unlockedLevels = totalLevels;
			}
		}
		// Show win animation
		tween(player, {
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				LK.showYouWin();
				// Move to next level
				if (currentLevel < totalLevels) {
					storage.currentLevel = currentLevel + 1;
				} else {
					// If all levels completed, go back to menu
					setupMenu();
				}
			}
		});
	}
}
// Check collisions between player and platforms
function checkPlatformCollisions() {
	var wasGrounded = player.isGrounded;
	player.isGrounded = false;
	platforms.forEach(function (platform) {
		if (platform.isSolid(player.isDimensionLight) && player.intersects(platform)) {
			// Calculate collision sides
			var playerBottom = player.y + player.lightForm.height / 2;
			var playerTop = player.y - player.lightForm.height / 2;
			var playerLeft = player.x - player.lightForm.width / 2;
			var playerRight = player.x + player.lightForm.width / 2;
			var platformBottom = platform.y + platform.graphic.height / 2;
			var platformTop = platform.y - platform.graphic.height / 2;
			var platformLeft = platform.x - platform.graphic.width / 2;
			var platformRight = platform.x + platform.graphic.width / 2;
			// Calculate penetration depths
			var fromTop = playerBottom - platformTop;
			var fromBottom = platformBottom - playerTop;
			var fromLeft = playerRight - platformLeft;
			var fromRight = platformRight - playerLeft;
			// Find minimum penetration
			var minPenetration = Math.min(fromTop, fromBottom, fromLeft, fromRight);
			// Resolve collision based on minimum penetration
			if (minPenetration === fromTop && player.velocityY > 0) {
				player.y = platformTop - player.lightForm.height / 2;
				player.velocityY = 0;
				player.isGrounded = true;
			} else if (minPenetration === fromBottom && player.velocityY < 0) {
				player.y = platformBottom + player.lightForm.height / 2;
				player.velocityY = 0;
			} else if (minPenetration === fromLeft && player.velocityX > 0) {
				player.x = platformLeft - player.lightForm.width / 2;
				player.velocityX = 0;
			} else if (minPenetration === fromRight && player.velocityX < 0) {
				player.x = platformRight + player.lightForm.width / 2;
				player.velocityX = 0;
			}
		}
	});
	// Landing effect
	if (!wasGrounded && player.isGrounded) {
		tween(player, {
			scaleX: 1.2,
			scaleY: 0.8
		}, {
			duration: 100,
			onFinish: function onFinish() {
				tween(player, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 100
				});
			}
		});
	}
}
// Check other game object interactions
function checkInteractions() {
	// Check dimension switches
	dimensionSwitches.forEach(function (dimensionSwitch) {
		if (player.intersects(dimensionSwitch) && isSwapEnabled) {
			player.swapDimension();
			isSwapEnabled = false;
			swapCooldown = 45; // 0.75-second cooldown at 60 FPS
			// Update dimension text
			if (touchControls.dimensionText) {
				touchControls.dimensionText.setText("DIMENSION: " + (player.isDimensionLight ? "LIGHT" : "SHADOW"));
			}
			// Animate the switch
			tween(dimensionSwitch, {
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 200,
				onFinish: function onFinish() {
					tween(dimensionSwitch, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 200
					});
				}
			});
		}
	});
	// Check hazards
	hazards.forEach(function (hazard) {
		if (player.intersects(hazard)) {
			player.die();
		}
	});
	// Check trophies
	trophies.forEach(function (trophy, index) {
		if (!trophy.collected && player.intersects(trophy)) {
			// Collect trophy
			trophy.collected = true;
			player.collectedTrophies++;
			// Update trophy counter
			if (touchControls.trophyText) {
				touchControls.trophyText.setText("TROPHIES: " + player.collectedTrophies + "/" + player.totalTrophies);
			}
			// Trophy collection animation
			tween(trophy, {
				scaleX: 0,
				scaleY: 0,
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					game.removeChild(trophy);
				}
			});
		}
	});
	// Check goal
	if (player.intersects(goal)) {
		completeLevel();
	}
	// Swap cooldown
	if (!isSwapEnabled) {
		swapCooldown--;
		if (swapCooldown <= 0) {
			isSwapEnabled = true;
		}
	}
}
// Touch controls
var touchStart = {
	x: 0,
	y: 0
};
var isTouching = false;
var movingLeft = false;
var movingRight = false;
game.down = function (x, y, obj) {
	if (gameState === STATE_GAME) {
		touchStart.x = x;
		touchStart.y = y;
		isTouching = true;
		// Check which control area was touched
		if (x < 2048 / 3) {
			// Left side - move left
			movingLeft = true;
			player.moveLeft();
		} else if (x > 2048 * 2 / 3) {
			// Right side - move right
			movingRight = true;
			player.moveRight();
		} else {
			// Center - jump
			player.jump();
		}
	}
};
game.move = function (x, y, obj) {
	if (gameState === STATE_GAME && isTouching) {
		// Check for swipe up (dimension swap) - reduced distance required
		if (y < touchStart.y - 70) {
			if (isSwapEnabled) {
				player.swapDimension();
				isSwapEnabled = false;
				swapCooldown = 45;
				// Update dimension text
				if (touchControls.dimensionText) {
					touchControls.dimensionText.setText("DIMENSION: " + (player.isDimensionLight ? "LIGHT" : "SHADOW"));
				}
			}
			// Reset touch to prevent multiple swipes
			isTouching = false;
		}
	}
};
game.up = function (x, y, obj) {
	if (gameState === STATE_GAME) {
		isTouching = false;
		// Stop horizontal movement if this was a movement control
		if (movingLeft || movingRight) {
			player.stopMoving();
			movingLeft = false;
			movingRight = false;
		}
	}
};
// Main game update loop
game.update = function () {
	if (gameState === STATE_GAME && !levelComplete && player && !player.isDead) {
		// Update player physics
		player.update();
		// Check collisions and interactions
		checkPlatformCollisions();
		checkInteractions();
		// Update platform visuals based on current dimension
		platforms.forEach(function (platform) {
			// Make solid platforms more visible (higher alpha) in current dimension
			if (platform.isSolid(player.isDimensionLight)) {
				platform.graphic.alpha = 1.0;
			} else {
				platform.graphic.alpha = 0.5;
			}
		});
	}
};
// Initialize the game with the menu
setupMenu();
:quality(85)/https://cdn.frvr.ai/6816cc711748bdc38e68cdfe.png%3F3) 
 Switch. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816cca01748bdc38e68ce04.png%3F3) 
 Trophy. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816ccdf1748bdc38e68ce0d.png%3F3) 
 Hazard. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816cd1f1748bdc38e68ce12.png%3F3) 
 A shadow ninja. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816cd5e1748bdc38e68ce1d.png%3F3) 
 A shadow ninja. In-Game asset. 2d. High contrast. shadow
:quality(85)/https://cdn.frvr.ai/6816cd9e1748bdc38e68ce24.png%3F3) 
 Shadow platform. In-Game asset. 2d. High contrast. No shadows