/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Meme = Container.expand(function () {
	var self = Container.call(this);
	var memeGraphics = self.attachAsset('Meme', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0;
	self.active = true;
	self.scale = 1;
	self.rotation = 0;
	self.rotationSpeed = 0;
	self.update = function () {
		if (self.active) {
			self.x += self.speed;
			self.rotation += self.rotationSpeed;
			// If meme goes off-screen, reset or deactivate
			if (self.x < -100 || self.x > 2148) {
				self.active = false;
			}
		}
	};
	self.reset = function (x, y, speed, scale, rotSpeed) {
		self.x = x;
		self.y = y;
		self.speed = speed;
		self.scale = scale || 1;
		self.scaleX = self.scale;
		self.scaleY = self.scale;
		self.rotationSpeed = rotSpeed || 0;
		self.active = true;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0;
	self.active = true;
	self.update = function () {
		if (self.active) {
			self.x += self.speed;
			// If obstacle goes off-screen, reset
			if (self.x < -100 || self.x > 2148) {
				self.active = false;
			}
		}
	};
	self.reset = function (x, y, speed) {
		self.x = x;
		self.y = y;
		self.speed = speed;
		self.active = true;
	};
	return self;
});
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platformGraphics = self.attachAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0;
	self.active = true;
	self.update = function () {
		if (self.active) {
			self.x += self.speed;
			// If platform goes off-screen, reset
			if (self.x < -250 || self.x > 2298) {
				self.active = false;
			}
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('playerCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocity = {
		x: 0,
		y: 0
	};
	self.isJumping = false;
	self.isDraggable = false;
	self.jump = function () {
		if (!self.isJumping) {
			self.velocity.y = -20;
			self.isJumping = true;
			LK.getSound('jump').play();
		}
	};
	self.reset = function (x, y) {
		self.x = x;
		self.y = y;
		self.velocity = {
			x: 0,
			y: 0
		};
		self.isJumping = false;
	};
	self.down = function (x, y, obj) {
		if (self.isDraggable) {
			draggedObject = self;
		}
	};
	return self;
});
var ProgressBar = Container.expand(function () {
	var self = Container.call(this);
	var background = self.attachAsset('progressBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	var fill = self.attachAsset('progressFill', {
		anchorX: 0,
		anchorY: 0.5
	});
	self.setProgress = function (percent) {
		fill.width = Math.min(1800 * (percent / 100), 1800);
	};
	return self;
});
var Target = Container.expand(function () {
	var self = Container.call(this);
	var targetGraphics = self.attachAsset('target', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.pulse = function () {
		tween(self, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.easeIn
				});
			}
		});
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x34495e
});
/**** 
* Game Code
****/ 
var GRAVITY = 0.8;
var GROUND_Y = 2400;
var gameState = "title"; // "title", "playing", "gameOver"
var currentLevel = 1;
var maxLevels = 5;
var levelDuration = 20000; // 20 seconds per level
var levelStartTime = 0;
var draggedObject = null;
var player;
var obstacles = [];
var platforms = [];
var targets = [];
var progressBar;
var scoreText;
var levelText;
var timerText;
var titleText;
var instructionText;
var gameOverText;
var countdownText;
var countdownValue = 3;
var levelDescriptions = ["Dodge the memes!", "Cross the platforms!", "Hit the targets!", "Stay in bounds!", "Survive them all!"];
// Initialize game UI
function initializeUI() {
	// Progress bar
	progressBar = new ProgressBar();
	progressBar.x = 124;
	progressBar.y = 100;
	LK.gui.addChild(progressBar);
	// Score
	scoreText = new Text2("Score: 0", {
		size: 60,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(1, 0);
	LK.gui.topRight.addChild(scoreText);
	// Level
	levelText = new Text2("Level: 1", {
		size: 60,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0, 0);
	levelText.x = 124;
	LK.gui.topLeft.addChild(levelText);
	levelText.y = 150;
	// Timer
	timerText = new Text2("20", {
		size: 60,
		fill: 0xFFFFFF
	});
	timerText.anchor.set(0.5, 0);
	LK.gui.top.addChild(timerText);
	// Title
	titleText = new Text2("MEME SURVIVAL\nCHALLENGE", {
		size: 120,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.visible = true;
	LK.gui.center.addChild(titleText);
	// Instruction
	instructionText = new Text2("Tap to Start", {
		size: 60,
		fill: 0xFFFFFF
	});
	instructionText.anchor.set(0.5, 0.5);
	instructionText.y = 200;
	instructionText.visible = true;
	LK.gui.center.addChild(instructionText);
	// Countdown
	countdownText = new Text2("3", {
		size: 200,
		fill: 0xFFFFFF
	});
	countdownText.anchor.set(0.5, 0.5);
	countdownText.visible = false;
	LK.gui.center.addChild(countdownText);
	// Level description
	gameOverText = new Text2("", {
		size: 60,
		fill: 0xFFFFFF
	});
	gameOverText.anchor.set(0.5, 0.5);
	gameOverText.y = 300;
	gameOverText.visible = false;
	LK.gui.center.addChild(gameOverText);
}
// Initialize player
function initializePlayer() {
	player = new Player();
	player.reset(1024, 1366);
	game.addChild(player);
}
// Initialize obstacles based on level
function initializeLevel(level) {
	// Clear any existing objects
	clearLevel();
	// Update UI
	levelText.setText("Level: " + level);
	gameOverText.setText(levelDescriptions[level - 1]);
	gameOverText.visible = true;
	// Set timer
	levelStartTime = Date.now();
	// Configure level
	switch (level) {
		case 1:
			// Dodge memes level
			setupDodgeLevel();
			break;
		case 2:
			// Platform level
			setupPlatformLevel();
			break;
		case 3:
			// Target level
			setupTargetLevel();
			break;
		case 4:
			// Boundary level
			setupBoundaryLevel();
			break;
		case 5:
			// Final level - combination
			setupFinalLevel();
			break;
	}
}
function setupDodgeLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Create memes instead of obstacles
	for (var i = 0; i < 15; i++) {
		var meme = new Meme();
		var scale = 0.8 + Math.random() * 1.5;
		var rotSpeed = (Math.random() - 0.5) * 0.1;
		var speed = -5 - Math.random() * 7;
		// Alternate memes coming from left and right with varying patterns
		if (i % 3 === 0) {
			meme.reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
		} else if (i % 3 === 1) {
			meme.reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
		} else {
			// Extra memes that start at random positions and move diagonally
			var startX = Math.random() > 0.5 ? -100 : 2300;
			var diagSpeed = (startX < 1000 ? 1 : -1) * (3 + Math.random() * 5);
			meme.reset(startX, 400 + Math.random() * 800, diagSpeed, scale * 0.8, rotSpeed * 2);
			// Add diagonal movement
			tween(meme, {
				y: meme.y + 800 + Math.random() * 600
			}, {
				duration: 4000 + Math.random() * 2000,
				easing: tween.easeInOut,
				repeat: -1,
				yoyo: true
			});
		}
		obstacles.push(meme);
		game.addChild(meme);
		// Add different effects to memes based on their position
		if (i % 5 === 0) {
			// Pulsing effect
			tween(meme, {
				scaleX: scale * 1.3,
				scaleY: scale * 1.3
			}, {
				duration: 800 + Math.random() * 500,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		} else if (i % 5 === 1) {
			// Rotation boost effect
			meme.rotationSpeed *= 3;
			// Flash effect
			tween(meme, {
				alpha: 0.6
			}, {
				duration: 400 + Math.random() * 300,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		} else if (i % 5 === 2) {
			// Wobble effect
			var wobbleScale = scale * 0.9;
			tween(meme, {
				scaleX: wobbleScale * 1.4,
				scaleY: wobbleScale * 0.8
			}, {
				duration: 300 + Math.random() * 200,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		}
	}
}
function setupPlatformLevel() {
	player.isDraggable = false;
	player.reset(200, 1000);
	// Create platforms
	for (var i = 0; i < 8; i++) {
		var platform = new Platform();
		platform.x = 300 + i * 250;
		platform.y = 1300 + Math.random() * 800;
		platform.speed = 0;
		platform.active = true;
		platforms.push(platform);
		game.addChild(platform);
	}
	// Add winning platform
	var winPlatform = new Platform();
	winPlatform.x = 2000;
	winPlatform.y = 1500;
	winPlatform.speed = 0;
	winPlatform.active = true;
	platforms.push(winPlatform);
	game.addChild(winPlatform);
	// Add floating memes that rise from below
	for (var i = 0; i < 4; i++) {
		var meme = new Meme();
		var scale = 0.6 + Math.random() * 0.8;
		var rotSpeed = (Math.random() - 0.5) * 0.05;
		meme.reset(300 + Math.random() * 1500, 3000, 0, scale, rotSpeed);
		obstacles.push(meme);
		game.addChild(meme);
		// Make memes rise from below at intervals
		LK.setTimeout(function (m) {
			return function () {
				tween(m, {
					y: -200
				}, {
					duration: 5000 + Math.random() * 3000,
					easing: tween.easeIn
				});
			};
		}(meme), 2000 + i * 3000);
	}
}
function setupTargetLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Create targets and memes
	for (var i = 0; i < 5; i++) {
		var target = new Target();
		target.x = 300 + Math.random() * 1500;
		target.y = 400 + Math.random() * 1700;
		target.pulse();
		targets.push(target);
		game.addChild(target);
		// Add a meme that circles around each target
		var meme = new Meme();
		var scale = 0.5 + Math.random() * 0.3;
		meme.reset(target.x, target.y - 100, 0, scale, 0.02);
		game.addChild(meme);
		// Make meme orbit around the target
		LK.setInterval(function (t, m) {
			return function () {
				var radius = 100 + Math.random() * 50;
				var angle = Math.random() * Math.PI * 2;
				tween(m, {
					x: t.x + Math.cos(angle) * radius,
					y: t.y + Math.sin(angle) * radius
				}, {
					duration: 1500,
					easing: tween.easeInOut
				});
			};
		}(target, meme), 1600);
	}
}
function setupBoundaryLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Create moving boundaries
	var leftBoundary = LK.getAsset('boundary', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	leftBoundary.x = 500;
	leftBoundary.y = 1366;
	game.addChild(leftBoundary);
	var rightBoundary = LK.getAsset('boundary', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	rightBoundary.x = 1548;
	rightBoundary.y = 1366;
	game.addChild(rightBoundary);
	// Add floating memes as additional obstacles
	for (var i = 0; i < 3; i++) {
		var meme = new Meme();
		var scale = 0.6 + Math.random() * 0.8;
		var rotSpeed = (Math.random() - 0.5) * 0.1;
		var posX = 600 + Math.random() * 848;
		var posY = 400 + Math.random() * 1700;
		meme.reset(posX, posY, 0, scale, rotSpeed);
		obstacles.push(meme);
		game.addChild(meme);
		// Make memes float around
		tween(meme, {
			x: posX + (Math.random() - 0.5) * 300,
			y: posY + (Math.random() - 0.5) * 300
		}, {
			duration: 2000 + Math.random() * 2000,
			easing: tween.easeInOut,
			yoyo: true,
			repeat: -1
		});
	}
	// Add movement to boundaries
	LK.setInterval(function () {
		tween(leftBoundary, {
			x: 300 + Math.random() * 400
		}, {
			duration: 1500,
			easing: tween.easeInOut
		});
		tween(rightBoundary, {
			x: 1348 + Math.random() * 400
		}, {
			duration: 1500,
			easing: tween.easeInOut
		});
	}, 2000);
}
function setupFinalLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Mix of obstacles, platforms and targets
	// Create memes instead of obstacles
	for (var i = 0; i < 8; i++) {
		var meme = new Meme();
		var scale = 0.8 + Math.random() * 1.5;
		var rotSpeed = (Math.random() - 0.5) * 0.1;
		var speed = -5 - Math.random() * 7;
		// Create memes coming from both directions
		if (i % 3 === 0) {
			meme.reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
		} else {
			meme.reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
		}
		obstacles.push(meme);
		game.addChild(meme);
		// Add effects to memes
		if (i % 2 === 0) {
			tween(meme, {
				scaleX: scale * 1.3,
				scaleY: scale * 1.3
			}, {
				duration: 800 + Math.random() * 500,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		}
	}
	// Create platforms
	for (var i = 0; i < 3; i++) {
		var platform = new Platform();
		platform.x = 300 + i * 600;
		platform.y = 1300 + Math.random() * 800;
		platform.speed = -2;
		platform.active = true;
		platforms.push(platform);
		game.addChild(platform);
		// Add a meme hovering above each platform
		var platformMeme = new Meme();
		var pScale = 0.6 + Math.random() * 0.4;
		platformMeme.reset(platform.x, platform.y - 150, -2, pScale, 0.02);
		obstacles.push(platformMeme);
		game.addChild(platformMeme);
	}
	// Create targets
	for (var i = 0; i < 3; i++) {
		var target = new Target();
		target.x = 300 + Math.random() * 1500;
		target.y = 400 + Math.random() * 1700;
		target.pulse();
		targets.push(target);
		game.addChild(target);
		// Add a meme that circles around each target
		var targetMeme = new Meme();
		var tScale = 0.5 + Math.random() * 0.3;
		targetMeme.reset(target.x, target.y - 100, 0, tScale, 0.03);
		obstacles.push(targetMeme);
		game.addChild(targetMeme);
		// Make meme orbit around the target
		LK.setInterval(function (t, m) {
			return function () {
				var radius = 120 + Math.random() * 40;
				var angle = Math.random() * Math.PI * 2;
				tween(m, {
					x: t.x + Math.cos(angle) * radius,
					y: t.y + Math.sin(angle) * radius
				}, {
					duration: 1200,
					easing: tween.easeInOut
				});
			};
		}(target, targetMeme), 1300);
	}
}
function clearLevel() {
	// Remove all obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].destroy();
	}
	obstacles = [];
	// Remove all platforms
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].destroy();
	}
	platforms = [];
	// Remove all targets
	for (var i = 0; i < targets.length; i++) {
		targets[i].destroy();
	}
	targets = [];
}
function startGame() {
	gameState = "countdown";
	titleText.visible = false;
	instructionText.visible = false;
	countdownText.visible = true;
	countdownValue = 3;
	countdownText.setText(countdownValue.toString());
	LK.getSound('countdown').play();
	// Start countdown
	var countdownTimer = LK.setInterval(function () {
		countdownValue--;
		if (countdownValue > 0) {
			countdownText.setText(countdownValue.toString());
			LK.getSound('countdown').play();
		} else {
			LK.clearInterval(countdownTimer);
			countdownText.visible = false;
			gameOverText.visible = false;
			// Start actual game
			gameState = "playing";
			currentLevel = 1;
			LK.setScore(0);
			scoreText.setText("Score: 0");
			initializeLevel(currentLevel);
			// Play game music
			LK.playMusic('gameMusic');
		}
	}, 1000);
}
function updateLevel() {
	// Update timer
	var timeLeft = Math.max(0, Math.floor((levelDuration - (Date.now() - levelStartTime)) / 1000));
	timerText.setText(timeLeft.toString());
	// Update progress bar
	var progress = (Date.now() - levelStartTime) / levelDuration * 100;
	progressBar.setProgress(progress);
	// Check if level time is up
	if (Date.now() - levelStartTime >= levelDuration) {
		completeLevel();
	}
	// Level-specific logic
	switch (currentLevel) {
		case 1:
			// Dodge level
			updateDodgeLevel();
			break;
		case 2:
			// Platform level
			updatePlatformLevel();
			break;
		case 3:
			// Target level
			updateTargetLevel();
			break;
		case 4:
			// Boundary level
			updateBoundaryLevel();
			break;
		case 5:
			// Final level
			updateFinalLevel();
			break;
	}
}
function updateDodgeLevel() {
	// Check collisions with obstacles
	for (var i = 0; i < obstacles.length; i++) {
		if (obstacles[i].active && player.intersects(obstacles[i])) {
			// Player hit an obstacle
			LK.getSound('fail').play();
			LK.effects.flashScreen(0xff0000, 500);
			LK.showGameOver();
			return;
		}
		// Replace obstacles that went off-screen
		if (!obstacles[i].active) {
			var scale = 0.8 + Math.random() * 1.5;
			var rotSpeed = (Math.random() - 0.5) * 0.1;
			var speed = -5 - Math.random() * 7;
			// Create more diverse meme patterns based on current game time
			var pattern = Math.floor((Date.now() - levelStartTime) / 5000) % 4; // Changes pattern every 5 seconds
			var patternRandom = (i + LK.ticks) % 5; // Adds more variety within patterns
			// Different spawn patterns based on time and position
			if (pattern === 0) {
				// Classic side-to-side pattern
				if (patternRandom < 2) {
					obstacles[i].reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
				} else {
					obstacles[i].reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
				}
			} else if (pattern === 1) {
				// Diagonal pattern
				var startX = patternRandom < 2 ? -100 : 2300;
				var diagSpeed = (startX < 1000 ? 1 : -1) * (3 + Math.random() * 4);
				obstacles[i].reset(startX, 400 + Math.random() * 800, diagSpeed, scale * 0.9, rotSpeed * 1.5);
				// Add diagonal movement
				tween(obstacles[i], {
					y: obstacles[i].y + 600 + Math.random() * 500
				}, {
					duration: 3000 + Math.random() * 2000,
					easing: tween.easeInOut,
					repeat: -1,
					yoyo: true
				});
			} else if (pattern === 2) {
				// Fast spinning memes
				if (patternRandom < 3) {
					obstacles[i].reset(-100, 600 + Math.random() * 1200, Math.abs(speed) * 1.2, scale * 0.7, rotSpeed * 3);
				} else {
					obstacles[i].reset(2300, 600 + Math.random() * 1200, speed * 1.2, scale * 0.7, rotSpeed * 3);
				}
			} else {
				// Wave pattern
				obstacles[i].reset(patternRandom < 2 ? -100 : 2300, 800 + Math.random() * 900, (patternRandom < 2 ? 1 : -1) * (4 + Math.random() * 3), scale, rotSpeed * 0.5);
				// Add wavy motion
				tween(obstacles[i], {
					y: obstacles[i].y + (Math.random() > 0.5 ? 400 : -400)
				}, {
					duration: 1500 + Math.random() * 1000,
					easing: tween.easeInOut,
					repeat: -1,
					yoyo: true
				});
			}
			// Add varied visual effects
			var effectType = Math.floor(Math.random() * 4);
			if (effectType === 0) {
				// Pulsing effect
				tween(obstacles[i], {
					scaleX: scale * 1.3,
					scaleY: scale * 1.3
				}, {
					duration: 800 + Math.random() * 500,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			} else if (effectType === 1) {
				// Wobble effect
				tween(obstacles[i], {
					scaleX: scale * 1.4,
					scaleY: scale * 0.8
				}, {
					duration: 300 + Math.random() * 200,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			} else if (effectType === 2) {
				// Flash effect
				tween(obstacles[i], {
					alpha: 0.6
				}, {
					duration: 400 + Math.random() * 300,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			}
		}
	}
	// Add score over time
	if (LK.ticks % 30 === 0) {
		LK.setScore(LK.getScore() + 1);
		scoreText.setText("Score: " + LK.getScore());
	}
}
function updatePlatformLevel() {
	// Apply gravity
	player.velocity.y += GRAVITY;
	player.y += player.velocity.y;
	// Check if player is standing on a platform
	var onPlatform = false;
	for (var i = 0; i < platforms.length; i++) {
		if (player.y + 60 >= platforms[i].y - 20 && player.y + 60 <= platforms[i].y + 20 && player.x >= platforms[i].x - 200 && player.x <= platforms[i].x + 200) {
			player.y = platforms[i].y - 60;
			player.velocity.y = 0;
			player.isJumping = false;
			onPlatform = true;
			// Check if player reached the end platform
			if (i === platforms.length - 1) {
				completeLevel();
				return;
			}
		}
	}
	// Check if player fell off
	if (player.y > GROUND_Y) {
		LK.getSound('fail').play();
		LK.effects.flashScreen(0xff0000, 500);
		LK.showGameOver();
		return;
	}
}
function updateTargetLevel() {
	// Check collisions with targets
	for (var i = targets.length - 1; i >= 0; i--) {
		if (targets[i].active && player.intersects(targets[i])) {
			// Player hit a target
			LK.getSound('success').play();
			targets[i].destroy();
			targets.splice(i, 1);
			// Add score
			LK.setScore(LK.getScore() + 10);
			scoreText.setText("Score: " + LK.getScore());
			// Check if all targets are hit
			if (targets.length === 0) {
				completeLevel();
				return;
			}
		}
	}
}
function updateBoundaryLevel() {
	// For this level, we check if player is out of bounds (using the existing child objects)
	var children = game.children;
	for (var i = 0; i < children.length; i++) {
		// Find the boundary objects created in setupBoundaryLevel
		if (children[i].width === 150 && children[i].height === 2732) {
			if (player.intersects(children[i])) {
				LK.getSound('fail').play();
				LK.effects.flashScreen(0xff0000, 500);
				LK.showGameOver();
				return;
			}
		}
	}
	// Add score over time
	if (LK.ticks % 30 === 0) {
		LK.setScore(LK.getScore() + 1);
		scoreText.setText("Score: " + LK.getScore());
	}
}
function updateFinalLevel() {
	// Mix of all previous levels' logic
	// Check collisions with obstacles
	for (var i = 0; i < obstacles.length; i++) {
		if (obstacles[i].active && player.intersects(obstacles[i])) {
			// Player hit an obstacle
			LK.getSound('fail').play();
			LK.effects.flashScreen(0xff0000, 500);
			LK.showGameOver();
			return;
		}
		// Replace obstacles that went off-screen
		if (!obstacles[i].active) {
			var scale = 0.8 + Math.random() * 1.5;
			var rotSpeed = (Math.random() - 0.5) * 0.1;
			var speed = -5 - Math.random() * 7;
			// Varied meme patterns
			if (i % 3 === 0) {
				obstacles[i].reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
			} else {
				obstacles[i].reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
			}
			// Add effects to newly reset memes
			if (Math.random() > 0.6) {
				tween(obstacles[i], {
					scaleX: scale * 1.3,
					scaleY: scale * 1.3
				}, {
					duration: 800 + Math.random() * 500,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			}
		}
	}
	// Check collisions with targets
	for (var i = targets.length - 1; i >= 0; i--) {
		if (targets[i].active && player.intersects(targets[i])) {
			// Player hit a target
			LK.getSound('success').play();
			targets[i].destroy();
			targets.splice(i, 1);
			// Add score
			LK.setScore(LK.getScore() + 10);
			scoreText.setText("Score: " + LK.getScore());
			// Spawn a celebratory meme
			var celebMeme = new Meme();
			var cScale = 0.7 + Math.random() * 0.5;
			celebMeme.reset(player.x, player.y - 100, 0, cScale, 0.05);
			obstacles.push(celebMeme);
			game.addChild(celebMeme);
			// Make it float up and fade out
			tween(celebMeme, {
				y: player.y - 300,
				alpha: 0
			}, {
				duration: 1500,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					celebMeme.active = false;
				}
			});
		}
	}
	// Add score over time
	if (LK.ticks % 30 === 0) {
		LK.setScore(LK.getScore() + 1);
		scoreText.setText("Score: " + LK.getScore());
	}
	// Check if all targets are hit
	if (targets.length === 0) {
		completeLevel();
		return;
	}
}
function completeLevel() {
	LK.getSound('levelComplete').play();
	currentLevel++;
	// Check if all levels are complete
	if (currentLevel > maxLevels) {
		LK.showYouWin();
	} else {
		// Start next level
		initializeLevel(currentLevel);
	}
}
// Input handlers
game.down = function (x, y, obj) {
	if (gameState === "title") {
		startGame();
	} else if (gameState === "playing") {
		if (currentLevel === 2) {
			// Jump for platform level
			player.jump();
		} else if (draggedObject === null && player.isDraggable) {
			// Start dragging player
			var localPoint = player.toLocal({
				x: x,
				y: y
			});
			if (Math.sqrt(localPoint.x * localPoint.x + localPoint.y * localPoint.y) < 60) {
				draggedObject = player;
			}
		}
	}
};
game.up = function (x, y, obj) {
	draggedObject = null;
};
game.move = function (x, y, obj) {
	if (draggedObject) {
		draggedObject.x = x;
		draggedObject.y = y;
	}
};
// Initialize game
initializeUI();
initializePlayer();
// Game loop
game.update = function () {
	if (gameState === "playing") {
		updateLevel();
	}
};
// Start with title screen
gameState = "title"; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Meme = Container.expand(function () {
	var self = Container.call(this);
	var memeGraphics = self.attachAsset('Meme', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0;
	self.active = true;
	self.scale = 1;
	self.rotation = 0;
	self.rotationSpeed = 0;
	self.update = function () {
		if (self.active) {
			self.x += self.speed;
			self.rotation += self.rotationSpeed;
			// If meme goes off-screen, reset or deactivate
			if (self.x < -100 || self.x > 2148) {
				self.active = false;
			}
		}
	};
	self.reset = function (x, y, speed, scale, rotSpeed) {
		self.x = x;
		self.y = y;
		self.speed = speed;
		self.scale = scale || 1;
		self.scaleX = self.scale;
		self.scaleY = self.scale;
		self.rotationSpeed = rotSpeed || 0;
		self.active = true;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0;
	self.active = true;
	self.update = function () {
		if (self.active) {
			self.x += self.speed;
			// If obstacle goes off-screen, reset
			if (self.x < -100 || self.x > 2148) {
				self.active = false;
			}
		}
	};
	self.reset = function (x, y, speed) {
		self.x = x;
		self.y = y;
		self.speed = speed;
		self.active = true;
	};
	return self;
});
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platformGraphics = self.attachAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0;
	self.active = true;
	self.update = function () {
		if (self.active) {
			self.x += self.speed;
			// If platform goes off-screen, reset
			if (self.x < -250 || self.x > 2298) {
				self.active = false;
			}
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('playerCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocity = {
		x: 0,
		y: 0
	};
	self.isJumping = false;
	self.isDraggable = false;
	self.jump = function () {
		if (!self.isJumping) {
			self.velocity.y = -20;
			self.isJumping = true;
			LK.getSound('jump').play();
		}
	};
	self.reset = function (x, y) {
		self.x = x;
		self.y = y;
		self.velocity = {
			x: 0,
			y: 0
		};
		self.isJumping = false;
	};
	self.down = function (x, y, obj) {
		if (self.isDraggable) {
			draggedObject = self;
		}
	};
	return self;
});
var ProgressBar = Container.expand(function () {
	var self = Container.call(this);
	var background = self.attachAsset('progressBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	var fill = self.attachAsset('progressFill', {
		anchorX: 0,
		anchorY: 0.5
	});
	self.setProgress = function (percent) {
		fill.width = Math.min(1800 * (percent / 100), 1800);
	};
	return self;
});
var Target = Container.expand(function () {
	var self = Container.call(this);
	var targetGraphics = self.attachAsset('target', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.pulse = function () {
		tween(self, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.easeIn
				});
			}
		});
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x34495e
});
/**** 
* Game Code
****/ 
var GRAVITY = 0.8;
var GROUND_Y = 2400;
var gameState = "title"; // "title", "playing", "gameOver"
var currentLevel = 1;
var maxLevels = 5;
var levelDuration = 20000; // 20 seconds per level
var levelStartTime = 0;
var draggedObject = null;
var player;
var obstacles = [];
var platforms = [];
var targets = [];
var progressBar;
var scoreText;
var levelText;
var timerText;
var titleText;
var instructionText;
var gameOverText;
var countdownText;
var countdownValue = 3;
var levelDescriptions = ["Dodge the memes!", "Cross the platforms!", "Hit the targets!", "Stay in bounds!", "Survive them all!"];
// Initialize game UI
function initializeUI() {
	// Progress bar
	progressBar = new ProgressBar();
	progressBar.x = 124;
	progressBar.y = 100;
	LK.gui.addChild(progressBar);
	// Score
	scoreText = new Text2("Score: 0", {
		size: 60,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(1, 0);
	LK.gui.topRight.addChild(scoreText);
	// Level
	levelText = new Text2("Level: 1", {
		size: 60,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0, 0);
	levelText.x = 124;
	LK.gui.topLeft.addChild(levelText);
	levelText.y = 150;
	// Timer
	timerText = new Text2("20", {
		size: 60,
		fill: 0xFFFFFF
	});
	timerText.anchor.set(0.5, 0);
	LK.gui.top.addChild(timerText);
	// Title
	titleText = new Text2("MEME SURVIVAL\nCHALLENGE", {
		size: 120,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.visible = true;
	LK.gui.center.addChild(titleText);
	// Instruction
	instructionText = new Text2("Tap to Start", {
		size: 60,
		fill: 0xFFFFFF
	});
	instructionText.anchor.set(0.5, 0.5);
	instructionText.y = 200;
	instructionText.visible = true;
	LK.gui.center.addChild(instructionText);
	// Countdown
	countdownText = new Text2("3", {
		size: 200,
		fill: 0xFFFFFF
	});
	countdownText.anchor.set(0.5, 0.5);
	countdownText.visible = false;
	LK.gui.center.addChild(countdownText);
	// Level description
	gameOverText = new Text2("", {
		size: 60,
		fill: 0xFFFFFF
	});
	gameOverText.anchor.set(0.5, 0.5);
	gameOverText.y = 300;
	gameOverText.visible = false;
	LK.gui.center.addChild(gameOverText);
}
// Initialize player
function initializePlayer() {
	player = new Player();
	player.reset(1024, 1366);
	game.addChild(player);
}
// Initialize obstacles based on level
function initializeLevel(level) {
	// Clear any existing objects
	clearLevel();
	// Update UI
	levelText.setText("Level: " + level);
	gameOverText.setText(levelDescriptions[level - 1]);
	gameOverText.visible = true;
	// Set timer
	levelStartTime = Date.now();
	// Configure level
	switch (level) {
		case 1:
			// Dodge memes level
			setupDodgeLevel();
			break;
		case 2:
			// Platform level
			setupPlatformLevel();
			break;
		case 3:
			// Target level
			setupTargetLevel();
			break;
		case 4:
			// Boundary level
			setupBoundaryLevel();
			break;
		case 5:
			// Final level - combination
			setupFinalLevel();
			break;
	}
}
function setupDodgeLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Create memes instead of obstacles
	for (var i = 0; i < 15; i++) {
		var meme = new Meme();
		var scale = 0.8 + Math.random() * 1.5;
		var rotSpeed = (Math.random() - 0.5) * 0.1;
		var speed = -5 - Math.random() * 7;
		// Alternate memes coming from left and right with varying patterns
		if (i % 3 === 0) {
			meme.reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
		} else if (i % 3 === 1) {
			meme.reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
		} else {
			// Extra memes that start at random positions and move diagonally
			var startX = Math.random() > 0.5 ? -100 : 2300;
			var diagSpeed = (startX < 1000 ? 1 : -1) * (3 + Math.random() * 5);
			meme.reset(startX, 400 + Math.random() * 800, diagSpeed, scale * 0.8, rotSpeed * 2);
			// Add diagonal movement
			tween(meme, {
				y: meme.y + 800 + Math.random() * 600
			}, {
				duration: 4000 + Math.random() * 2000,
				easing: tween.easeInOut,
				repeat: -1,
				yoyo: true
			});
		}
		obstacles.push(meme);
		game.addChild(meme);
		// Add different effects to memes based on their position
		if (i % 5 === 0) {
			// Pulsing effect
			tween(meme, {
				scaleX: scale * 1.3,
				scaleY: scale * 1.3
			}, {
				duration: 800 + Math.random() * 500,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		} else if (i % 5 === 1) {
			// Rotation boost effect
			meme.rotationSpeed *= 3;
			// Flash effect
			tween(meme, {
				alpha: 0.6
			}, {
				duration: 400 + Math.random() * 300,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		} else if (i % 5 === 2) {
			// Wobble effect
			var wobbleScale = scale * 0.9;
			tween(meme, {
				scaleX: wobbleScale * 1.4,
				scaleY: wobbleScale * 0.8
			}, {
				duration: 300 + Math.random() * 200,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		}
	}
}
function setupPlatformLevel() {
	player.isDraggable = false;
	player.reset(200, 1000);
	// Create platforms
	for (var i = 0; i < 8; i++) {
		var platform = new Platform();
		platform.x = 300 + i * 250;
		platform.y = 1300 + Math.random() * 800;
		platform.speed = 0;
		platform.active = true;
		platforms.push(platform);
		game.addChild(platform);
	}
	// Add winning platform
	var winPlatform = new Platform();
	winPlatform.x = 2000;
	winPlatform.y = 1500;
	winPlatform.speed = 0;
	winPlatform.active = true;
	platforms.push(winPlatform);
	game.addChild(winPlatform);
	// Add floating memes that rise from below
	for (var i = 0; i < 4; i++) {
		var meme = new Meme();
		var scale = 0.6 + Math.random() * 0.8;
		var rotSpeed = (Math.random() - 0.5) * 0.05;
		meme.reset(300 + Math.random() * 1500, 3000, 0, scale, rotSpeed);
		obstacles.push(meme);
		game.addChild(meme);
		// Make memes rise from below at intervals
		LK.setTimeout(function (m) {
			return function () {
				tween(m, {
					y: -200
				}, {
					duration: 5000 + Math.random() * 3000,
					easing: tween.easeIn
				});
			};
		}(meme), 2000 + i * 3000);
	}
}
function setupTargetLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Create targets and memes
	for (var i = 0; i < 5; i++) {
		var target = new Target();
		target.x = 300 + Math.random() * 1500;
		target.y = 400 + Math.random() * 1700;
		target.pulse();
		targets.push(target);
		game.addChild(target);
		// Add a meme that circles around each target
		var meme = new Meme();
		var scale = 0.5 + Math.random() * 0.3;
		meme.reset(target.x, target.y - 100, 0, scale, 0.02);
		game.addChild(meme);
		// Make meme orbit around the target
		LK.setInterval(function (t, m) {
			return function () {
				var radius = 100 + Math.random() * 50;
				var angle = Math.random() * Math.PI * 2;
				tween(m, {
					x: t.x + Math.cos(angle) * radius,
					y: t.y + Math.sin(angle) * radius
				}, {
					duration: 1500,
					easing: tween.easeInOut
				});
			};
		}(target, meme), 1600);
	}
}
function setupBoundaryLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Create moving boundaries
	var leftBoundary = LK.getAsset('boundary', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	leftBoundary.x = 500;
	leftBoundary.y = 1366;
	game.addChild(leftBoundary);
	var rightBoundary = LK.getAsset('boundary', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	rightBoundary.x = 1548;
	rightBoundary.y = 1366;
	game.addChild(rightBoundary);
	// Add floating memes as additional obstacles
	for (var i = 0; i < 3; i++) {
		var meme = new Meme();
		var scale = 0.6 + Math.random() * 0.8;
		var rotSpeed = (Math.random() - 0.5) * 0.1;
		var posX = 600 + Math.random() * 848;
		var posY = 400 + Math.random() * 1700;
		meme.reset(posX, posY, 0, scale, rotSpeed);
		obstacles.push(meme);
		game.addChild(meme);
		// Make memes float around
		tween(meme, {
			x: posX + (Math.random() - 0.5) * 300,
			y: posY + (Math.random() - 0.5) * 300
		}, {
			duration: 2000 + Math.random() * 2000,
			easing: tween.easeInOut,
			yoyo: true,
			repeat: -1
		});
	}
	// Add movement to boundaries
	LK.setInterval(function () {
		tween(leftBoundary, {
			x: 300 + Math.random() * 400
		}, {
			duration: 1500,
			easing: tween.easeInOut
		});
		tween(rightBoundary, {
			x: 1348 + Math.random() * 400
		}, {
			duration: 1500,
			easing: tween.easeInOut
		});
	}, 2000);
}
function setupFinalLevel() {
	player.isDraggable = true;
	player.reset(1024, 1366);
	// Mix of obstacles, platforms and targets
	// Create memes instead of obstacles
	for (var i = 0; i < 8; i++) {
		var meme = new Meme();
		var scale = 0.8 + Math.random() * 1.5;
		var rotSpeed = (Math.random() - 0.5) * 0.1;
		var speed = -5 - Math.random() * 7;
		// Create memes coming from both directions
		if (i % 3 === 0) {
			meme.reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
		} else {
			meme.reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
		}
		obstacles.push(meme);
		game.addChild(meme);
		// Add effects to memes
		if (i % 2 === 0) {
			tween(meme, {
				scaleX: scale * 1.3,
				scaleY: scale * 1.3
			}, {
				duration: 800 + Math.random() * 500,
				easing: tween.easeInOut,
				yoyo: true,
				repeat: -1
			});
		}
	}
	// Create platforms
	for (var i = 0; i < 3; i++) {
		var platform = new Platform();
		platform.x = 300 + i * 600;
		platform.y = 1300 + Math.random() * 800;
		platform.speed = -2;
		platform.active = true;
		platforms.push(platform);
		game.addChild(platform);
		// Add a meme hovering above each platform
		var platformMeme = new Meme();
		var pScale = 0.6 + Math.random() * 0.4;
		platformMeme.reset(platform.x, platform.y - 150, -2, pScale, 0.02);
		obstacles.push(platformMeme);
		game.addChild(platformMeme);
	}
	// Create targets
	for (var i = 0; i < 3; i++) {
		var target = new Target();
		target.x = 300 + Math.random() * 1500;
		target.y = 400 + Math.random() * 1700;
		target.pulse();
		targets.push(target);
		game.addChild(target);
		// Add a meme that circles around each target
		var targetMeme = new Meme();
		var tScale = 0.5 + Math.random() * 0.3;
		targetMeme.reset(target.x, target.y - 100, 0, tScale, 0.03);
		obstacles.push(targetMeme);
		game.addChild(targetMeme);
		// Make meme orbit around the target
		LK.setInterval(function (t, m) {
			return function () {
				var radius = 120 + Math.random() * 40;
				var angle = Math.random() * Math.PI * 2;
				tween(m, {
					x: t.x + Math.cos(angle) * radius,
					y: t.y + Math.sin(angle) * radius
				}, {
					duration: 1200,
					easing: tween.easeInOut
				});
			};
		}(target, targetMeme), 1300);
	}
}
function clearLevel() {
	// Remove all obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].destroy();
	}
	obstacles = [];
	// Remove all platforms
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].destroy();
	}
	platforms = [];
	// Remove all targets
	for (var i = 0; i < targets.length; i++) {
		targets[i].destroy();
	}
	targets = [];
}
function startGame() {
	gameState = "countdown";
	titleText.visible = false;
	instructionText.visible = false;
	countdownText.visible = true;
	countdownValue = 3;
	countdownText.setText(countdownValue.toString());
	LK.getSound('countdown').play();
	// Start countdown
	var countdownTimer = LK.setInterval(function () {
		countdownValue--;
		if (countdownValue > 0) {
			countdownText.setText(countdownValue.toString());
			LK.getSound('countdown').play();
		} else {
			LK.clearInterval(countdownTimer);
			countdownText.visible = false;
			gameOverText.visible = false;
			// Start actual game
			gameState = "playing";
			currentLevel = 1;
			LK.setScore(0);
			scoreText.setText("Score: 0");
			initializeLevel(currentLevel);
			// Play game music
			LK.playMusic('gameMusic');
		}
	}, 1000);
}
function updateLevel() {
	// Update timer
	var timeLeft = Math.max(0, Math.floor((levelDuration - (Date.now() - levelStartTime)) / 1000));
	timerText.setText(timeLeft.toString());
	// Update progress bar
	var progress = (Date.now() - levelStartTime) / levelDuration * 100;
	progressBar.setProgress(progress);
	// Check if level time is up
	if (Date.now() - levelStartTime >= levelDuration) {
		completeLevel();
	}
	// Level-specific logic
	switch (currentLevel) {
		case 1:
			// Dodge level
			updateDodgeLevel();
			break;
		case 2:
			// Platform level
			updatePlatformLevel();
			break;
		case 3:
			// Target level
			updateTargetLevel();
			break;
		case 4:
			// Boundary level
			updateBoundaryLevel();
			break;
		case 5:
			// Final level
			updateFinalLevel();
			break;
	}
}
function updateDodgeLevel() {
	// Check collisions with obstacles
	for (var i = 0; i < obstacles.length; i++) {
		if (obstacles[i].active && player.intersects(obstacles[i])) {
			// Player hit an obstacle
			LK.getSound('fail').play();
			LK.effects.flashScreen(0xff0000, 500);
			LK.showGameOver();
			return;
		}
		// Replace obstacles that went off-screen
		if (!obstacles[i].active) {
			var scale = 0.8 + Math.random() * 1.5;
			var rotSpeed = (Math.random() - 0.5) * 0.1;
			var speed = -5 - Math.random() * 7;
			// Create more diverse meme patterns based on current game time
			var pattern = Math.floor((Date.now() - levelStartTime) / 5000) % 4; // Changes pattern every 5 seconds
			var patternRandom = (i + LK.ticks) % 5; // Adds more variety within patterns
			// Different spawn patterns based on time and position
			if (pattern === 0) {
				// Classic side-to-side pattern
				if (patternRandom < 2) {
					obstacles[i].reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
				} else {
					obstacles[i].reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
				}
			} else if (pattern === 1) {
				// Diagonal pattern
				var startX = patternRandom < 2 ? -100 : 2300;
				var diagSpeed = (startX < 1000 ? 1 : -1) * (3 + Math.random() * 4);
				obstacles[i].reset(startX, 400 + Math.random() * 800, diagSpeed, scale * 0.9, rotSpeed * 1.5);
				// Add diagonal movement
				tween(obstacles[i], {
					y: obstacles[i].y + 600 + Math.random() * 500
				}, {
					duration: 3000 + Math.random() * 2000,
					easing: tween.easeInOut,
					repeat: -1,
					yoyo: true
				});
			} else if (pattern === 2) {
				// Fast spinning memes
				if (patternRandom < 3) {
					obstacles[i].reset(-100, 600 + Math.random() * 1200, Math.abs(speed) * 1.2, scale * 0.7, rotSpeed * 3);
				} else {
					obstacles[i].reset(2300, 600 + Math.random() * 1200, speed * 1.2, scale * 0.7, rotSpeed * 3);
				}
			} else {
				// Wave pattern
				obstacles[i].reset(patternRandom < 2 ? -100 : 2300, 800 + Math.random() * 900, (patternRandom < 2 ? 1 : -1) * (4 + Math.random() * 3), scale, rotSpeed * 0.5);
				// Add wavy motion
				tween(obstacles[i], {
					y: obstacles[i].y + (Math.random() > 0.5 ? 400 : -400)
				}, {
					duration: 1500 + Math.random() * 1000,
					easing: tween.easeInOut,
					repeat: -1,
					yoyo: true
				});
			}
			// Add varied visual effects
			var effectType = Math.floor(Math.random() * 4);
			if (effectType === 0) {
				// Pulsing effect
				tween(obstacles[i], {
					scaleX: scale * 1.3,
					scaleY: scale * 1.3
				}, {
					duration: 800 + Math.random() * 500,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			} else if (effectType === 1) {
				// Wobble effect
				tween(obstacles[i], {
					scaleX: scale * 1.4,
					scaleY: scale * 0.8
				}, {
					duration: 300 + Math.random() * 200,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			} else if (effectType === 2) {
				// Flash effect
				tween(obstacles[i], {
					alpha: 0.6
				}, {
					duration: 400 + Math.random() * 300,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			}
		}
	}
	// Add score over time
	if (LK.ticks % 30 === 0) {
		LK.setScore(LK.getScore() + 1);
		scoreText.setText("Score: " + LK.getScore());
	}
}
function updatePlatformLevel() {
	// Apply gravity
	player.velocity.y += GRAVITY;
	player.y += player.velocity.y;
	// Check if player is standing on a platform
	var onPlatform = false;
	for (var i = 0; i < platforms.length; i++) {
		if (player.y + 60 >= platforms[i].y - 20 && player.y + 60 <= platforms[i].y + 20 && player.x >= platforms[i].x - 200 && player.x <= platforms[i].x + 200) {
			player.y = platforms[i].y - 60;
			player.velocity.y = 0;
			player.isJumping = false;
			onPlatform = true;
			// Check if player reached the end platform
			if (i === platforms.length - 1) {
				completeLevel();
				return;
			}
		}
	}
	// Check if player fell off
	if (player.y > GROUND_Y) {
		LK.getSound('fail').play();
		LK.effects.flashScreen(0xff0000, 500);
		LK.showGameOver();
		return;
	}
}
function updateTargetLevel() {
	// Check collisions with targets
	for (var i = targets.length - 1; i >= 0; i--) {
		if (targets[i].active && player.intersects(targets[i])) {
			// Player hit a target
			LK.getSound('success').play();
			targets[i].destroy();
			targets.splice(i, 1);
			// Add score
			LK.setScore(LK.getScore() + 10);
			scoreText.setText("Score: " + LK.getScore());
			// Check if all targets are hit
			if (targets.length === 0) {
				completeLevel();
				return;
			}
		}
	}
}
function updateBoundaryLevel() {
	// For this level, we check if player is out of bounds (using the existing child objects)
	var children = game.children;
	for (var i = 0; i < children.length; i++) {
		// Find the boundary objects created in setupBoundaryLevel
		if (children[i].width === 150 && children[i].height === 2732) {
			if (player.intersects(children[i])) {
				LK.getSound('fail').play();
				LK.effects.flashScreen(0xff0000, 500);
				LK.showGameOver();
				return;
			}
		}
	}
	// Add score over time
	if (LK.ticks % 30 === 0) {
		LK.setScore(LK.getScore() + 1);
		scoreText.setText("Score: " + LK.getScore());
	}
}
function updateFinalLevel() {
	// Mix of all previous levels' logic
	// Check collisions with obstacles
	for (var i = 0; i < obstacles.length; i++) {
		if (obstacles[i].active && player.intersects(obstacles[i])) {
			// Player hit an obstacle
			LK.getSound('fail').play();
			LK.effects.flashScreen(0xff0000, 500);
			LK.showGameOver();
			return;
		}
		// Replace obstacles that went off-screen
		if (!obstacles[i].active) {
			var scale = 0.8 + Math.random() * 1.5;
			var rotSpeed = (Math.random() - 0.5) * 0.1;
			var speed = -5 - Math.random() * 7;
			// Varied meme patterns
			if (i % 3 === 0) {
				obstacles[i].reset(-100, 400 + Math.random() * 1700, Math.abs(speed), scale, rotSpeed);
			} else {
				obstacles[i].reset(2300, 400 + Math.random() * 1700, speed, scale, rotSpeed);
			}
			// Add effects to newly reset memes
			if (Math.random() > 0.6) {
				tween(obstacles[i], {
					scaleX: scale * 1.3,
					scaleY: scale * 1.3
				}, {
					duration: 800 + Math.random() * 500,
					easing: tween.easeInOut,
					yoyo: true,
					repeat: -1
				});
			}
		}
	}
	// Check collisions with targets
	for (var i = targets.length - 1; i >= 0; i--) {
		if (targets[i].active && player.intersects(targets[i])) {
			// Player hit a target
			LK.getSound('success').play();
			targets[i].destroy();
			targets.splice(i, 1);
			// Add score
			LK.setScore(LK.getScore() + 10);
			scoreText.setText("Score: " + LK.getScore());
			// Spawn a celebratory meme
			var celebMeme = new Meme();
			var cScale = 0.7 + Math.random() * 0.5;
			celebMeme.reset(player.x, player.y - 100, 0, cScale, 0.05);
			obstacles.push(celebMeme);
			game.addChild(celebMeme);
			// Make it float up and fade out
			tween(celebMeme, {
				y: player.y - 300,
				alpha: 0
			}, {
				duration: 1500,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					celebMeme.active = false;
				}
			});
		}
	}
	// Add score over time
	if (LK.ticks % 30 === 0) {
		LK.setScore(LK.getScore() + 1);
		scoreText.setText("Score: " + LK.getScore());
	}
	// Check if all targets are hit
	if (targets.length === 0) {
		completeLevel();
		return;
	}
}
function completeLevel() {
	LK.getSound('levelComplete').play();
	currentLevel++;
	// Check if all levels are complete
	if (currentLevel > maxLevels) {
		LK.showYouWin();
	} else {
		// Start next level
		initializeLevel(currentLevel);
	}
}
// Input handlers
game.down = function (x, y, obj) {
	if (gameState === "title") {
		startGame();
	} else if (gameState === "playing") {
		if (currentLevel === 2) {
			// Jump for platform level
			player.jump();
		} else if (draggedObject === null && player.isDraggable) {
			// Start dragging player
			var localPoint = player.toLocal({
				x: x,
				y: y
			});
			if (Math.sqrt(localPoint.x * localPoint.x + localPoint.y * localPoint.y) < 60) {
				draggedObject = player;
			}
		}
	}
};
game.up = function (x, y, obj) {
	draggedObject = null;
};
game.move = function (x, y, obj) {
	if (draggedObject) {
		draggedObject.x = x;
		draggedObject.y = y;
	}
};
// Initialize game
initializeUI();
initializePlayer();
// Game loop
game.update = function () {
	if (gameState === "playing") {
		updateLevel();
	}
};
// Start with title screen
gameState = "title";