/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Background = Container.expand(function () {
	var self = Container.call(this);
	// Create sky gradient
	var skyGradient = new Container();
	// Create several bands of sky color
	var skyColors = [0x1a3c80, 0x3a5c9f, 0x5a7cbf, 0x7a9cdf, 0x9abcff];
	var bandHeight = 2732 / skyColors.length;
	for (var i = 0; i < skyColors.length; i++) {
		var skyBand = LK.getAsset('skyBand' + i, {
			width: 2048,
			height: bandHeight,
			color: skyColors[i],
			shape: 'box',
			y: i * bandHeight
		});
		skyGradient.addChild(skyBand);
	}
	self.addChild(skyGradient);
	// Create buildings
	var buildings = new Container();
	self.addChild(buildings);
	// Far buildings (darker)
	var buildingColors = [0x222a40, 0x323a50, 0x424a60];
	var buildingCount = 15;
	for (var i = 0; i < buildingCount; i++) {
		var buildingWidth = 100 + Math.random() * 150;
		var buildingHeight = 300 + Math.random() * 400;
		var building = LK.getAsset('building_far_' + i, {
			width: buildingWidth,
			height: buildingHeight,
			color: buildingColors[Math.floor(Math.random() * buildingColors.length)],
			shape: 'box',
			x: i * (2048 / buildingCount),
			y: 2732 - buildingHeight,
			anchorY: 0
		});
		buildings.addChild(building);
	}
	// Near buildings (slightly lighter)
	var nearBuildingColors = [0x303a50, 0x404a60, 0x505a70];
	var nearBuildingCount = 10;
	for (var i = 0; i < nearBuildingCount; i++) {
		var buildingWidth = 180 + Math.random() * 150;
		var buildingHeight = 500 + Math.random() * 600;
		var building = LK.getAsset('building_near_' + i, {
			width: buildingWidth,
			height: buildingHeight,
			color: nearBuildingColors[Math.floor(Math.random() * nearBuildingColors.length)],
			shape: 'box',
			x: i * (2048 / nearBuildingCount),
			y: 2732 - buildingHeight,
			anchorY: 0
		});
		buildings.addChild(building);
	}
	// Add some windows to buildings (as small yellow rectangles)
	for (var b = 0; b < buildings.children.length; b++) {
		var building = buildings.children[b];
		var windowCount = Math.floor(building.width / 30) * Math.floor(building.height / 40);
		// Limit window count for performance
		windowCount = Math.min(windowCount, 20);
		for (var w = 0; w < windowCount; w++) {
			var windowSize = 10 + Math.random() * 10;
			var windowX = Math.random() * (building.width - windowSize);
			var windowY = Math.random() * (building.height - windowSize);
			// Only add some windows (randomized lighting effect)
			if (Math.random() > 0.4) {
				var windowLight = LK.getAsset('window_' + b + '_' + w, {
					width: windowSize,
					height: windowSize,
					color: Math.random() > 0.7 ? 0xffcc66 : 0x888888,
					// Some windows lit, some not
					shape: 'box',
					x: building.x + windowX,
					y: building.y + windowY
				});
				self.addChild(windowLight);
			}
		}
	}
	// Add clouds
	var clouds = new Container();
	self.clouds = clouds;
	self.addChild(clouds);
	var cloudCount = 6;
	for (var i = 0; i < cloudCount; i++) {
		var cloudWidth = 200 + Math.random() * 300;
		var cloudHeight = 100 + Math.random() * 100;
		var cloud = LK.getAsset('cloud_' + i, {
			width: cloudWidth,
			height: cloudHeight,
			color: 0xddddff,
			shape: 'ellipse',
			x: Math.random() * 2048,
			y: 200 + Math.random() * 400,
			alpha: 0.7
		});
		// Add some variation to clouds with slight scaling
		cloud.scaleX = 0.8 + Math.random() * 0.4;
		cloud.scaleY = 0.8 + Math.random() * 0.4;
		// Store cloud speed for animation
		cloud.speedX = 0.2 + Math.random() * 0.3;
		clouds.addChild(cloud);
	}
	// Update function to animate clouds
	self.update = function () {
		// Move clouds horizontally
		for (var i = 0; i < clouds.children.length; i++) {
			var cloud = clouds.children[i];
			cloud.x += cloud.speedX;
			// Loop clouds when they move off screen
			if (cloud.x > 2048 + cloud.width) {
				cloud.x = -cloud.width;
				cloud.y = 200 + Math.random() * 400;
			}
		}
	};
	return self;
});
var BreathingCircle = Container.expand(function () {
	var self = Container.call(this);
	// Create the breathing circle
	var innerCircle = self.attachAsset('centerCircle', {
		width: 200,
		height: 200,
		color: 0x3a5c9f,
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.4
	});
	var outerCircle = LK.getAsset('centerCircle', {
		width: 240,
		height: 240,
		color: 0x5a7cbf,
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.2
	});
	self.addChild(outerCircle);
	// Breathing animation state
	self.breathPhase = 0; // 0: inhale growing, 1: hold, 2: exhale shrinking, 3: hold
	self.breathTimer = 0;
	self.inhaleDuration = 240; // 4 seconds
	self.holdDuration = 120; // 2 seconds
	self.exhaleDuration = 240; // 4 seconds
	self.restDuration = 60; // 1 second
	// Text guide for breathing
	self.breathText = new Text2("Breathe In", {
		size: 40,
		fill: 0xffffff
	});
	self.breathText.anchor.set(0.5, 0.5);
	self.breathText.y = -160;
	self.addChild(self.breathText);
	// Update method to animate the breathing circle
	self.update = function () {
		self.breathTimer++;
		// Determine current phase based on timer
		if (self.breathPhase === 0) {
			// Inhale
			var progress = self.breathTimer / self.inhaleDuration;
			var scale = 1 + progress * 0.5;
			innerCircle.scale.x = innerCircle.scale.y = scale;
			outerCircle.scale.x = outerCircle.scale.y = 0.9 + progress * 0.5;
			self.breathText.setText("Breathe In");
			if (self.breathTimer >= self.inhaleDuration) {
				self.breathPhase = 1;
				self.breathTimer = 0;
			}
		} else if (self.breathPhase === 1) {
			// Hold after inhale
			self.breathText.setText("Hold");
			if (self.breathTimer >= self.holdDuration) {
				self.breathPhase = 2;
				self.breathTimer = 0;
			}
		} else if (self.breathPhase === 2) {
			// Exhale
			var progress = self.breathTimer / self.exhaleDuration;
			var scale = 1.5 - progress * 0.5;
			innerCircle.scale.x = innerCircle.scale.y = scale;
			outerCircle.scale.x = outerCircle.scale.y = 1.4 - progress * 0.5;
			self.breathText.setText("Breathe Out");
			if (self.breathTimer >= self.exhaleDuration) {
				self.breathPhase = 3;
				self.breathTimer = 0;
			}
		} else {
			// Hold after exhale
			self.breathText.setText("Rest");
			if (self.breathTimer >= self.restDuration) {
				self.breathPhase = 0;
				self.breathTimer = 0;
			}
		}
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 12;
	self.direction = {
		x: 0,
		y: -1
	}; // Default upward
	self.lifespan = 120; // 2 seconds at 60fps
	self.age = 0;
	self.damage = 1;
	self.update = function () {
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		self.age++;
		if (self.age > self.lifespan) {
			self.markForDeletion = true;
		}
	};
	return self;
});
var Criminal = Container.expand(function () {
	var self = Container.call(this);
	var criminalGraphics = self.attachAsset('criminal', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 2;
	self.health = 2; // Reduced from 3
	self.shootCooldown = 0;
	self.shootDelay = 120; // Frames between shots
	self.attackRange = 300; // Reduced from 500
	self.movePattern = Math.floor(Math.random() * 3); // 0: direct, 1: zigzag, 2: circle
	self.moveTimer = 0;
	self.update = function () {
		// Target the player
		var dx = player.x - self.x;
		var dy = player.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Movement based on pattern
		if (distance > 100) {
			// Keep some distance
			var moveX = 0;
			var moveY = 0;
			switch (self.movePattern) {
				case 0:
					// Direct
					moveX = dx / distance;
					moveY = dy / distance;
					break;
				case 1:
					// Zigzag
					self.moveTimer++;
					moveX = dx / distance + Math.sin(self.moveTimer * 0.1) * 0.5;
					moveY = dy / distance;
					break;
				case 2:
					// Circle
					self.moveTimer++;
					moveX = dx / distance + Math.sin(self.moveTimer * 0.05) * 0.8;
					moveY = dy / distance + Math.cos(self.moveTimer * 0.05) * 0.8;
					break;
			}
			self.x += moveX * self.speed;
			self.y += moveY * self.speed;
		}
		// Shooting logic
		if (distance < self.attackRange) {
			if (self.shootCooldown <= 0) {
				// Create enemy bullet
				var bullet = new Bullet();
				bullet.x = self.x;
				bullet.y = self.y;
				// Calculate direction toward player
				var dirX = dx / distance;
				var dirY = dy / distance;
				bullet.direction = {
					x: dirX,
					y: dirY
				};
				// Mark as enemy bullet
				bullet.isEnemyBullet = true;
				// Add to game's bullets array
				bullets.push(bullet);
				game.addChild(bullet);
				// Reset cooldown with some randomness
				self.shootCooldown = self.shootDelay + Math.random() * 60;
			}
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	self.takeDamage = function () {
		self.health--;
		LK.effects.flashObject(self, 0xFF0000, 300);
		if (self.health <= 0) {
			LK.getSound('criminal_down').play();
			LK.setScore(LK.getScore() + 1);
			self.markForDeletion = true;
			// Track criminal elimination task
			var eliminateTask = tasks.find(function (task) {
				return task.id === 'eliminate';
			});
			if (eliminateTask && !eliminateTask.completed) {
				eliminateTask.count++;
				if (eliminateTask.count >= eliminateTask.target) {
					eliminateTask.completed = true;
					LK.effects.flashObject(taskTexts[1], 0x00FF00, 1000);
				}
				updateTaskDisplay();
			}
		}
	};
	return self;
});
var EmergencyCall = Container.expand(function () {
	var self = Container.call(this);
	var callGraphics = self.attachAsset('emergencyCall', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lifetime = 600; // 10 seconds at 60fps
	self.age = 0;
	self.flashInterval = 30;
	self.update = function () {
		self.age++;
		// Flash effect
		if (self.age % self.flashInterval === 0) {
			if (callGraphics.alpha === 1) {
				tween(callGraphics, {
					alpha: 0.3
				}, {
					duration: 500
				});
			} else {
				tween(callGraphics, {
					alpha: 1
				}, {
					duration: 500
				});
			}
		}
		// Expire after lifetime
		if (self.age > self.lifetime) {
			self.markForDeletion = true;
		}
	};
	self.down = function () {
		// Responding to call
		LK.getSound('radiochatter').play();
		// Spawn criminals from top of screen, using emergency call's X position
		spawnCriminals(self.x, 0, 2 + Math.floor(Math.random() * 3));
		self.markForDeletion = true;
		// Increase score for responding
		LK.setScore(LK.getScore() + 2);
		// Track emergency call response task
		var respondTask = tasks.find(function (task) {
			return task.id === 'respond';
		});
		if (respondTask && !respondTask.completed) {
			respondTask.count++;
			if (respondTask.count >= respondTask.target) {
				respondTask.completed = true;
				LK.effects.flashObject(taskTexts[0], 0x00FF00, 1000);
			}
			updateTaskDisplay();
		}
	};
	return self;
});
var MeditationGuide = Container.expand(function () {
	var self = Container.call(this);
	// Create a text display for meditation prompts
	self.promptText = new Text2("Breathe deeply...", {
		size: 60,
		fill: 0xffffff,
		align: 'center'
	});
	self.promptText.anchor.set(0.5, 0.5);
	self.addChild(self.promptText);
	// List of meditation prompts
	self.prompts = ["Breathe deeply...", "Focus on your breath...", "Let go of your thoughts...", "Feel the peace within...", "You are present...", "Allow yourself to be...", "Feel the energy flow...", "Find your center..."];
	self.currentPrompt = 0;
	self.promptTimer = 0;
	self.promptDuration = 300; // 5 seconds per prompt
	// Update method to cycle through prompts
	self.update = function () {
		self.promptTimer++;
		// Change prompt periodically
		if (self.promptTimer >= self.promptDuration) {
			self.currentPrompt = (self.currentPrompt + 1) % self.prompts.length;
			self.promptText.setText(self.prompts[self.currentPrompt]);
			self.promptTimer = 0;
			// Animate text appearance
			self.promptText.alpha = 0;
			tween(self.promptText, {
				alpha: 1
			}, {
				duration: 1000
			});
		}
		// Subtle pulse animation
		var scale = 1 + 0.05 * Math.sin(self.promptTimer * 0.01);
		self.promptText.scale.x = scale;
		self.promptText.scale.y = scale;
	};
	return self;
});
var MeditationSpace = Container.expand(function () {
	var self = Container.call(this);
	// Create a peaceful gradient background
	var background = new Container();
	self.addChild(background);
	// Create calming gradient colors for the background
	var skyColors = [0x081832, 0x112a4e, 0x1a3c6a, 0x234e86, 0x2c60a2];
	var bandHeight = 2732 / skyColors.length;
	for (var i = 0; i < skyColors.length; i++) {
		var skyBand = LK.getAsset('skyBand' + i, {
			width: 2048,
			height: bandHeight,
			color: skyColors[i],
			y: i * bandHeight
		});
		background.addChild(skyBand);
	}
	// Create stars
	var stars = new Container();
	self.stars = stars;
	self.addChild(stars);
	// Add stars to the night sky
	var starCount = 100;
	for (var i = 0; i < starCount; i++) {
		var starSize = 2 + Math.random() * 4;
		var star = LK.getAsset('star_' + i, {
			width: starSize,
			height: starSize,
			color: 0xffffff,
			shape: 'ellipse',
			x: Math.random() * 2048,
			y: Math.random() * 1200,
			alpha: 0.5 + Math.random() * 0.5
		});
		star.pulseSpeed = 0.01 + Math.random() * 0.02;
		star.pulsePhase = Math.random() * Math.PI * 2;
		stars.addChild(star);
	}
	// Add floating lotus flowers
	var lotusFlowers = new Container();
	self.lotusFlowers = lotusFlowers;
	self.addChild(lotusFlowers);
	var lotusCount = 5;
	for (var i = 0; i < lotusCount; i++) {
		var lotusSize = 80 + Math.random() * 40;
		var lotus = LK.getAsset('lotus_' + i, {
			width: lotusSize,
			height: lotusSize,
			color: 0xffb6c1,
			shape: 'ellipse',
			x: 400 + Math.random() * 1200,
			y: 1500 + Math.random() * 800
		});
		lotus.floatSpeed = 0.2 + Math.random() * 0.3;
		lotus.floatPhase = Math.random() * Math.PI * 2;
		lotusFlowers.addChild(lotus);
	}
	// Add water ripples
	var ripples = new Container();
	self.ripples = ripples;
	self.addChild(ripples);
	self.rippleTimer = 0;
	// Update function to animate elements
	self.update = function () {
		// Animate stars (pulsing effect)
		for (var i = 0; i < stars.children.length; i++) {
			var star = stars.children[i];
			star.pulsePhase += star.pulseSpeed;
			star.alpha = 0.5 + 0.5 * Math.sin(star.pulsePhase);
		}
		// Animate lotus flowers (gentle floating)
		for (var i = 0; i < lotusFlowers.children.length; i++) {
			var lotus = lotusFlowers.children[i];
			lotus.floatPhase += 0.01;
			lotus.y += Math.sin(lotus.floatPhase) * lotus.floatSpeed;
		}
		// Create new ripples periodically
		self.rippleTimer++;
		if (self.rippleTimer > 120) {
			// Every 2 seconds
			self.createRipple(400 + Math.random() * 1200, 1500 + Math.random() * 800);
			self.rippleTimer = 0;
		}
		// Update existing ripples
		for (var i = ripples.children.length - 1; i >= 0; i--) {
			var ripple = ripples.children[i];
			ripple.age++;
			// Expand ripple
			ripple.scale.x += 0.01;
			ripple.scale.y += 0.01;
			// Fade out ripple
			ripple.alpha = 1 - ripple.age / ripple.lifespan;
			// Remove old ripples
			if (ripple.age >= ripple.lifespan) {
				ripple.destroy();
				ripples.removeChild(ripple);
			}
		}
	};
	// Method to create a new water ripple
	self.createRipple = function (x, y) {
		var ripple = LK.getAsset('ripple', {
			width: 50,
			height: 50,
			color: 0xffffff,
			shape: 'ellipse',
			x: x,
			y: y,
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0.7
		});
		ripple.age = 0;
		ripple.lifespan = 120; // 2 seconds
		ripples.addChild(ripple);
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 5;
	self.health = 100;
	self.maxHealth = 100;
	self.shootCooldown = 0;
	self.shootDelay = 15; // Frames between shots
	self.canMove = true;
	// Health bar setup
	var healthBarBg = self.attachAsset('healthBarBackground', {
		anchorX: 0.5,
		anchorY: 0,
		y: 120
	});
	var healthBarFill = self.attachAsset('healthBar', {
		anchorX: 0.5,
		anchorY: 0,
		y: 122
	});
	self.updateHealthBar = function () {
		var healthPercentage = self.health / self.maxHealth;
		healthBarFill.scale.x = healthPercentage;
		// Center the health bar
		healthBarFill.x = -100 * (1 - healthPercentage);
	};
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			self.health = 0;
			LK.effects.flashScreen(0xFF0000, 1000);
			LK.showGameOver();
		}
		self.updateHealthBar();
	};
	self.shoot = function () {
		if (self.shootCooldown <= 0) {
			var bullet = new Bullet();
			bullet.x = self.x;
			bullet.y = self.y - 40;
			// Add to game's bullets array
			bullets.push(bullet);
			game.addChild(bullet);
			// Play gun sound
			LK.getSound('gunshot').play();
			// Reset cooldown
			self.shootCooldown = self.shootDelay;
		}
	};
	self.update = function () {
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	self.down = function (x, y, obj) {
		self.shoot();
	};
	// Initialize health bar
	self.updateHealthBar();
	return self;
});
var SoulOrb = Container.expand(function () {
	var self = Container.call(this);
	// Create the soul orb with a glowing effect
	var orbCore = self.attachAsset('centerCircle', {
		width: 60,
		height: 60,
		color: 0x83de44,
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create outer glow
	var orbGlow = LK.getAsset('centerCircle', {
		width: 100,
		height: 100,
		color: 0xb8ffb0,
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5
	});
	self.addChild(orbGlow);
	// Add pulsating animation to the glow
	self.glowPhase = 0;
	self.energy = 0; // Energy level (0-100)
	self.maxEnergy = 100;
	self.pulseSpeed = 0.05;
	// Update method to animate the orb
	self.update = function () {
		self.glowPhase += self.pulseSpeed;
		orbGlow.scale.x = 1 + 0.2 * Math.sin(self.glowPhase);
		orbGlow.scale.y = 1 + 0.2 * Math.sin(self.glowPhase);
		// Adjust color based on energy level
		var energyRatio = self.energy / self.maxEnergy;
		var r = Math.floor(131 + (255 - 131) * energyRatio);
		var g = Math.floor(222 + (255 - 222) * energyRatio);
		var b = Math.floor(68 + (255 - 68) * energyRatio);
		// Convert RGB to hex
		var color = r << 16 | g << 8 | b;
		orbCore.tint = color;
	};
	// Method to add energy to the orb
	self.addEnergy = function (amount) {
		self.energy = Math.min(self.maxEnergy, self.energy + amount);
		// Flash with increasing brightness as energy increases
		LK.effects.flashObject(self, 0xffffff, 300);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x081832
});
/**** 
* Game Code
****/ 
// Game variables
var meditationSpace;
var soulOrb;
var breathingCircle;
var meditationGuide;
var gameActive = true;
var dragOffset = {
	x: 0,
	y: 0
};
var meditationLevel = 1;
var meditationTime = 0;
var soulEnergy = 0;
var maxSoulEnergy = 100;
var breathingTimer = 0;
// Meditation practices
var practices = [{
	id: 'breathe',
	text: 'Complete 5 breathing cycles',
	count: 0,
	target: 5,
	completed: false
}, {
	id: 'focus',
	text: 'Maintain focus for 60 seconds',
	count: 0,
	target: 60,
	completed: false
}, {
	id: 'energy',
	text: 'Fill your soul with energy',
	count: 0,
	target: 100,
	completed: false
}];
// Setup practice UI
var practiceContainer = new Container();
practiceContainer.x = 40;
practiceContainer.y = 180;
LK.gui.left.addChild(practiceContainer);
var practiceTitle = new Text2('PRACTICES:', {
	size: 50,
	fill: 0xFFFFFF
});
practiceContainer.addChild(practiceTitle);
// Create text for each practice
var practiceTexts = [];
for (var i = 0; i < practices.length; i++) {
	var practiceText = new Text2('• ' + practices[i].text + ' (0/' + practices[i].target + ')', {
		size: 40,
		fill: 0xCCCCCC
	});
	practiceText.y = 60 + i * 50;
	practiceContainer.addChild(practiceText);
	practiceTexts.push(practiceText);
}
// Function to update practice UI
function updatePracticeDisplay() {
	for (var i = 0; i < practices.length; i++) {
		var practice = practices[i];
		var color = practice.completed ? 0x83de44 : 0xCCCCCC;
		practiceTexts[i].setText('• ' + practice.text + ' (' + practice.count + '/' + practice.target + ')');
		practiceTexts[i].fill = color;
	}
}
// Setup UI
var energyTxt = new Text2('Soul Energy: 0%', {
	size: 60,
	fill: 0xFFFFFF
});
energyTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(energyTxt);
var levelTxt = new Text2('Meditation Level: 1', {
	size: 60,
	fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 70;
LK.gui.top.addChild(levelTxt);
// Create and add meditation space
meditationSpace = new MeditationSpace();
game.addChild(meditationSpace);
// Initialize soul orb
soulOrb = new SoulOrb();
soulOrb.x = 2048 / 2;
soulOrb.y = 2732 / 3;
game.addChild(soulOrb);
// Initialize breathing circle
breathingCircle = new BreathingCircle();
breathingCircle.x = 2048 / 2;
breathingCircle.y = 2732 / 2 + 200;
game.addChild(breathingCircle);
// Initialize meditation guide
meditationGuide = new MeditationGuide();
meditationGuide.x = 2048 / 2;
meditationGuide.y = 2732 / 5;
game.addChild(meditationGuide);
// Play meditation music
LK.playMusic('background_music');
// Create a ripple at a position (utility function)
function createRipple(x, y) {
	meditationSpace.createRipple(x, y);
}
// Add soul energy
function addSoulEnergy(amount) {
	soulOrb.addEnergy(amount);
	// Update energy practice
	var energyPractice = practices.find(function (practice) {
		return practice.id === 'energy';
	});
	if (energyPractice && !energyPractice.completed) {
		energyPractice.count = Math.floor(soulOrb.energy);
		if (energyPractice.count >= energyPractice.target) {
			energyPractice.completed = true;
			LK.effects.flashObject(practiceTexts[2], 0x83de44, 1000);
		}
		updatePracticeDisplay();
	}
}
// Check if meditation level should increase
function checkMeditationProgress() {
	// Check if practices are completed to progress meditation level
	var completedPractices = practices.filter(function (practice) {
		return practice.completed;
	}).length;
	var newLevel = 1 + Math.floor(completedPractices / 2);
	if (newLevel > meditationLevel) {
		meditationLevel = newLevel;
		levelTxt.setText('Meditation Level: ' + meditationLevel);
		// Bonus for reaching new level
		addSoulEnergy(10 * meditationLevel);
		// Visual feedback
		LK.effects.flashScreen(0x83de44, 500);
	}
}
// Meditation interaction handling
game.down = function (x, y, obj) {
	// Calculate distances to interactive elements
	var distToOrb = Math.sqrt(Math.pow(x - soulOrb.x, 2) + Math.pow(y - soulOrb.y, 2));
	// If touching the soul orb
	if (distToOrb < 100) {
		// Add energy to the soul
		soulOrb.addEnergy(5);
		// Emit a ripple effect from the interaction point
		meditationSpace.createRipple(x, y);
		// Create visual feedback
		LK.effects.flashObject(soulOrb, 0xFFFFFF, 500);
	} else {
		// Create ripple at touch point
		meditationSpace.createRipple(x, y);
	}
	// Set drag offset for moving the orb
	dragOffset.x = soulOrb.x - x;
	dragOffset.y = soulOrb.y - y;
};
game.move = function (x, y, obj) {
	// Move soul orb with drag
	soulOrb.x = x + dragOffset.x;
	soulOrb.y = y + dragOffset.y;
	// Keep soul orb in bounds
	soulOrb.x = Math.max(100, Math.min(2048 - 100, soulOrb.x));
	soulOrb.y = Math.max(100, Math.min(2732 - 100, soulOrb.y));
	// Create subtle ripple effects during movement
	if (Math.random() < 0.1) {
		meditationSpace.createRipple(soulOrb.x + (Math.random() * 100 - 50), soulOrb.y + (Math.random() * 100 - 50));
	}
};
game.up = function () {
	// Create final ripple at release point
	meditationSpace.createRipple(soulOrb.x, soulOrb.y);
};
// Game update loop
game.update = function () {
	if (!gameActive) return;
	// Update meditation space
	meditationSpace.update();
	// Update soul orb, breathing circle, and guide
	soulOrb.update();
	breathingCircle.update();
	meditationGuide.update();
	// Update energy display
	energyTxt.setText('Soul Energy: ' + Math.floor(soulOrb.energy / maxSoulEnergy * 100) + '%');
	// Track breathing cycles for breathe practice
	if (breathingCircle.breathPhase === 3 && breathingCircle.breathTimer === 0) {
		// Just completed a full breathing cycle
		var breathePractice = practices.find(function (practice) {
			return practice.id === 'breathe';
		});
		if (breathePractice && !breathePractice.completed) {
			breathePractice.count++;
			if (breathePractice.count >= breathePractice.target) {
				breathePractice.completed = true;
				LK.effects.flashObject(practiceTexts[0], 0x83de44, 1000);
				// Add soul energy when completing breathing practice
				soulOrb.addEnergy(20);
			}
			updatePracticeDisplay();
		}
	}
	// Track focus time for focus practice
	meditationTime++;
	if (meditationTime % 60 === 0) {
		// Every second
		var focusPractice = practices.find(function (practice) {
			return practice.id === 'focus';
		});
		if (focusPractice && !focusPractice.completed) {
			focusPractice.count++;
			if (focusPractice.count >= focusPractice.target) {
				focusPractice.completed = true;
				LK.effects.flashObject(practiceTexts[1], 0x83de44, 1000);
				// Add soul energy when completing focus practice
				soulOrb.addEnergy(30);
			}
			updatePracticeDisplay();
		}
	}
	// Add soul energy over time with active meditation
	if (meditationTime % 180 === 0) {
		// Every 3 seconds
		soulOrb.addEnergy(1);
		// Track soul energy for energy practice
		var energyPractice = practices.find(function (practice) {
			return practice.id === 'energy';
		});
		if (energyPractice && !energyPractice.completed) {
			energyPractice.count = Math.floor(soulOrb.energy);
			if (energyPractice.count >= energyPractice.target) {
				energyPractice.completed = true;
				LK.effects.flashObject(practiceTexts[2], 0x83de44, 1000);
			}
			updatePracticeDisplay();
		}
	}
	// Check for meditation level up
	if (meditationTime % 600 === 0) {
		// Every 10 seconds
		meditationLevel++;
		levelTxt.setText('Meditation Level: ' + meditationLevel);
		// Visual feedback for level up
		LK.effects.flashScreen(0x83de44, 500);
	}
	// Check if all practices are completed
	var allPracticesCompleted = practices.every(function (practice) {
		return practice.completed;
	});
	if (allPracticesCompleted && gameActive) {
		// Show enlightenment message
		var enlightenmentMessage = new Text2('ENLIGHTENMENT ACHIEVED!', {
			size: 100,
			fill: 0xFFFFFF
		});
		enlightenmentMessage.anchor.set(0.5, 0.5);
		enlightenmentMessage.x = 2048 / 2;
		enlightenmentMessage.y = 2732 / 2;
		game.addChild(enlightenmentMessage);
		// Visual effects for enlightenment
		LK.effects.flashScreen(0xFFFFFF, 2000);
		// Create new practices with higher requirements
		practices = [{
			id: 'breathe',
			text: 'Complete 10 breathing cycles',
			count: 0,
			target: 10,
			completed: false
		}, {
			id: 'focus',
			text: 'Maintain focus for 120 seconds',
			count: 0,
			target: 120,
			completed: false
		}, {
			id: 'energy',
			text: 'Achieve deeper enlightenment',
			count: 0,
			target: 200,
			completed: false
		}];
		// Update practice display
		for (var i = 0; i < practices.length; i++) {
			practiceTexts[i].setText('• ' + practices[i].text + ' (0/' + practices[i].target + ')');
			practiceTexts[i].fill = 0xCCCCCC;
		}
		// Increase soul orb capacity
		maxSoulEnergy = 200;
		// Remove the enlightenment message after 3 seconds
		LK.setTimeout(function () {
			enlightenmentMessage.destroy();
			updatePracticeDisplay();
		}, 3000);
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Background = Container.expand(function () {
	var self = Container.call(this);
	// Create sky gradient
	var skyGradient = new Container();
	// Create several bands of sky color
	var skyColors = [0x1a3c80, 0x3a5c9f, 0x5a7cbf, 0x7a9cdf, 0x9abcff];
	var bandHeight = 2732 / skyColors.length;
	for (var i = 0; i < skyColors.length; i++) {
		var skyBand = LK.getAsset('skyBand' + i, {
			width: 2048,
			height: bandHeight,
			color: skyColors[i],
			shape: 'box',
			y: i * bandHeight
		});
		skyGradient.addChild(skyBand);
	}
	self.addChild(skyGradient);
	// Create buildings
	var buildings = new Container();
	self.addChild(buildings);
	// Far buildings (darker)
	var buildingColors = [0x222a40, 0x323a50, 0x424a60];
	var buildingCount = 15;
	for (var i = 0; i < buildingCount; i++) {
		var buildingWidth = 100 + Math.random() * 150;
		var buildingHeight = 300 + Math.random() * 400;
		var building = LK.getAsset('building_far_' + i, {
			width: buildingWidth,
			height: buildingHeight,
			color: buildingColors[Math.floor(Math.random() * buildingColors.length)],
			shape: 'box',
			x: i * (2048 / buildingCount),
			y: 2732 - buildingHeight,
			anchorY: 0
		});
		buildings.addChild(building);
	}
	// Near buildings (slightly lighter)
	var nearBuildingColors = [0x303a50, 0x404a60, 0x505a70];
	var nearBuildingCount = 10;
	for (var i = 0; i < nearBuildingCount; i++) {
		var buildingWidth = 180 + Math.random() * 150;
		var buildingHeight = 500 + Math.random() * 600;
		var building = LK.getAsset('building_near_' + i, {
			width: buildingWidth,
			height: buildingHeight,
			color: nearBuildingColors[Math.floor(Math.random() * nearBuildingColors.length)],
			shape: 'box',
			x: i * (2048 / nearBuildingCount),
			y: 2732 - buildingHeight,
			anchorY: 0
		});
		buildings.addChild(building);
	}
	// Add some windows to buildings (as small yellow rectangles)
	for (var b = 0; b < buildings.children.length; b++) {
		var building = buildings.children[b];
		var windowCount = Math.floor(building.width / 30) * Math.floor(building.height / 40);
		// Limit window count for performance
		windowCount = Math.min(windowCount, 20);
		for (var w = 0; w < windowCount; w++) {
			var windowSize = 10 + Math.random() * 10;
			var windowX = Math.random() * (building.width - windowSize);
			var windowY = Math.random() * (building.height - windowSize);
			// Only add some windows (randomized lighting effect)
			if (Math.random() > 0.4) {
				var windowLight = LK.getAsset('window_' + b + '_' + w, {
					width: windowSize,
					height: windowSize,
					color: Math.random() > 0.7 ? 0xffcc66 : 0x888888,
					// Some windows lit, some not
					shape: 'box',
					x: building.x + windowX,
					y: building.y + windowY
				});
				self.addChild(windowLight);
			}
		}
	}
	// Add clouds
	var clouds = new Container();
	self.clouds = clouds;
	self.addChild(clouds);
	var cloudCount = 6;
	for (var i = 0; i < cloudCount; i++) {
		var cloudWidth = 200 + Math.random() * 300;
		var cloudHeight = 100 + Math.random() * 100;
		var cloud = LK.getAsset('cloud_' + i, {
			width: cloudWidth,
			height: cloudHeight,
			color: 0xddddff,
			shape: 'ellipse',
			x: Math.random() * 2048,
			y: 200 + Math.random() * 400,
			alpha: 0.7
		});
		// Add some variation to clouds with slight scaling
		cloud.scaleX = 0.8 + Math.random() * 0.4;
		cloud.scaleY = 0.8 + Math.random() * 0.4;
		// Store cloud speed for animation
		cloud.speedX = 0.2 + Math.random() * 0.3;
		clouds.addChild(cloud);
	}
	// Update function to animate clouds
	self.update = function () {
		// Move clouds horizontally
		for (var i = 0; i < clouds.children.length; i++) {
			var cloud = clouds.children[i];
			cloud.x += cloud.speedX;
			// Loop clouds when they move off screen
			if (cloud.x > 2048 + cloud.width) {
				cloud.x = -cloud.width;
				cloud.y = 200 + Math.random() * 400;
			}
		}
	};
	return self;
});
var BreathingCircle = Container.expand(function () {
	var self = Container.call(this);
	// Create the breathing circle
	var innerCircle = self.attachAsset('centerCircle', {
		width: 200,
		height: 200,
		color: 0x3a5c9f,
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.4
	});
	var outerCircle = LK.getAsset('centerCircle', {
		width: 240,
		height: 240,
		color: 0x5a7cbf,
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.2
	});
	self.addChild(outerCircle);
	// Breathing animation state
	self.breathPhase = 0; // 0: inhale growing, 1: hold, 2: exhale shrinking, 3: hold
	self.breathTimer = 0;
	self.inhaleDuration = 240; // 4 seconds
	self.holdDuration = 120; // 2 seconds
	self.exhaleDuration = 240; // 4 seconds
	self.restDuration = 60; // 1 second
	// Text guide for breathing
	self.breathText = new Text2("Breathe In", {
		size: 40,
		fill: 0xffffff
	});
	self.breathText.anchor.set(0.5, 0.5);
	self.breathText.y = -160;
	self.addChild(self.breathText);
	// Update method to animate the breathing circle
	self.update = function () {
		self.breathTimer++;
		// Determine current phase based on timer
		if (self.breathPhase === 0) {
			// Inhale
			var progress = self.breathTimer / self.inhaleDuration;
			var scale = 1 + progress * 0.5;
			innerCircle.scale.x = innerCircle.scale.y = scale;
			outerCircle.scale.x = outerCircle.scale.y = 0.9 + progress * 0.5;
			self.breathText.setText("Breathe In");
			if (self.breathTimer >= self.inhaleDuration) {
				self.breathPhase = 1;
				self.breathTimer = 0;
			}
		} else if (self.breathPhase === 1) {
			// Hold after inhale
			self.breathText.setText("Hold");
			if (self.breathTimer >= self.holdDuration) {
				self.breathPhase = 2;
				self.breathTimer = 0;
			}
		} else if (self.breathPhase === 2) {
			// Exhale
			var progress = self.breathTimer / self.exhaleDuration;
			var scale = 1.5 - progress * 0.5;
			innerCircle.scale.x = innerCircle.scale.y = scale;
			outerCircle.scale.x = outerCircle.scale.y = 1.4 - progress * 0.5;
			self.breathText.setText("Breathe Out");
			if (self.breathTimer >= self.exhaleDuration) {
				self.breathPhase = 3;
				self.breathTimer = 0;
			}
		} else {
			// Hold after exhale
			self.breathText.setText("Rest");
			if (self.breathTimer >= self.restDuration) {
				self.breathPhase = 0;
				self.breathTimer = 0;
			}
		}
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 12;
	self.direction = {
		x: 0,
		y: -1
	}; // Default upward
	self.lifespan = 120; // 2 seconds at 60fps
	self.age = 0;
	self.damage = 1;
	self.update = function () {
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		self.age++;
		if (self.age > self.lifespan) {
			self.markForDeletion = true;
		}
	};
	return self;
});
var Criminal = Container.expand(function () {
	var self = Container.call(this);
	var criminalGraphics = self.attachAsset('criminal', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 2;
	self.health = 2; // Reduced from 3
	self.shootCooldown = 0;
	self.shootDelay = 120; // Frames between shots
	self.attackRange = 300; // Reduced from 500
	self.movePattern = Math.floor(Math.random() * 3); // 0: direct, 1: zigzag, 2: circle
	self.moveTimer = 0;
	self.update = function () {
		// Target the player
		var dx = player.x - self.x;
		var dy = player.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Movement based on pattern
		if (distance > 100) {
			// Keep some distance
			var moveX = 0;
			var moveY = 0;
			switch (self.movePattern) {
				case 0:
					// Direct
					moveX = dx / distance;
					moveY = dy / distance;
					break;
				case 1:
					// Zigzag
					self.moveTimer++;
					moveX = dx / distance + Math.sin(self.moveTimer * 0.1) * 0.5;
					moveY = dy / distance;
					break;
				case 2:
					// Circle
					self.moveTimer++;
					moveX = dx / distance + Math.sin(self.moveTimer * 0.05) * 0.8;
					moveY = dy / distance + Math.cos(self.moveTimer * 0.05) * 0.8;
					break;
			}
			self.x += moveX * self.speed;
			self.y += moveY * self.speed;
		}
		// Shooting logic
		if (distance < self.attackRange) {
			if (self.shootCooldown <= 0) {
				// Create enemy bullet
				var bullet = new Bullet();
				bullet.x = self.x;
				bullet.y = self.y;
				// Calculate direction toward player
				var dirX = dx / distance;
				var dirY = dy / distance;
				bullet.direction = {
					x: dirX,
					y: dirY
				};
				// Mark as enemy bullet
				bullet.isEnemyBullet = true;
				// Add to game's bullets array
				bullets.push(bullet);
				game.addChild(bullet);
				// Reset cooldown with some randomness
				self.shootCooldown = self.shootDelay + Math.random() * 60;
			}
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	self.takeDamage = function () {
		self.health--;
		LK.effects.flashObject(self, 0xFF0000, 300);
		if (self.health <= 0) {
			LK.getSound('criminal_down').play();
			LK.setScore(LK.getScore() + 1);
			self.markForDeletion = true;
			// Track criminal elimination task
			var eliminateTask = tasks.find(function (task) {
				return task.id === 'eliminate';
			});
			if (eliminateTask && !eliminateTask.completed) {
				eliminateTask.count++;
				if (eliminateTask.count >= eliminateTask.target) {
					eliminateTask.completed = true;
					LK.effects.flashObject(taskTexts[1], 0x00FF00, 1000);
				}
				updateTaskDisplay();
			}
		}
	};
	return self;
});
var EmergencyCall = Container.expand(function () {
	var self = Container.call(this);
	var callGraphics = self.attachAsset('emergencyCall', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lifetime = 600; // 10 seconds at 60fps
	self.age = 0;
	self.flashInterval = 30;
	self.update = function () {
		self.age++;
		// Flash effect
		if (self.age % self.flashInterval === 0) {
			if (callGraphics.alpha === 1) {
				tween(callGraphics, {
					alpha: 0.3
				}, {
					duration: 500
				});
			} else {
				tween(callGraphics, {
					alpha: 1
				}, {
					duration: 500
				});
			}
		}
		// Expire after lifetime
		if (self.age > self.lifetime) {
			self.markForDeletion = true;
		}
	};
	self.down = function () {
		// Responding to call
		LK.getSound('radiochatter').play();
		// Spawn criminals from top of screen, using emergency call's X position
		spawnCriminals(self.x, 0, 2 + Math.floor(Math.random() * 3));
		self.markForDeletion = true;
		// Increase score for responding
		LK.setScore(LK.getScore() + 2);
		// Track emergency call response task
		var respondTask = tasks.find(function (task) {
			return task.id === 'respond';
		});
		if (respondTask && !respondTask.completed) {
			respondTask.count++;
			if (respondTask.count >= respondTask.target) {
				respondTask.completed = true;
				LK.effects.flashObject(taskTexts[0], 0x00FF00, 1000);
			}
			updateTaskDisplay();
		}
	};
	return self;
});
var MeditationGuide = Container.expand(function () {
	var self = Container.call(this);
	// Create a text display for meditation prompts
	self.promptText = new Text2("Breathe deeply...", {
		size: 60,
		fill: 0xffffff,
		align: 'center'
	});
	self.promptText.anchor.set(0.5, 0.5);
	self.addChild(self.promptText);
	// List of meditation prompts
	self.prompts = ["Breathe deeply...", "Focus on your breath...", "Let go of your thoughts...", "Feel the peace within...", "You are present...", "Allow yourself to be...", "Feel the energy flow...", "Find your center..."];
	self.currentPrompt = 0;
	self.promptTimer = 0;
	self.promptDuration = 300; // 5 seconds per prompt
	// Update method to cycle through prompts
	self.update = function () {
		self.promptTimer++;
		// Change prompt periodically
		if (self.promptTimer >= self.promptDuration) {
			self.currentPrompt = (self.currentPrompt + 1) % self.prompts.length;
			self.promptText.setText(self.prompts[self.currentPrompt]);
			self.promptTimer = 0;
			// Animate text appearance
			self.promptText.alpha = 0;
			tween(self.promptText, {
				alpha: 1
			}, {
				duration: 1000
			});
		}
		// Subtle pulse animation
		var scale = 1 + 0.05 * Math.sin(self.promptTimer * 0.01);
		self.promptText.scale.x = scale;
		self.promptText.scale.y = scale;
	};
	return self;
});
var MeditationSpace = Container.expand(function () {
	var self = Container.call(this);
	// Create a peaceful gradient background
	var background = new Container();
	self.addChild(background);
	// Create calming gradient colors for the background
	var skyColors = [0x081832, 0x112a4e, 0x1a3c6a, 0x234e86, 0x2c60a2];
	var bandHeight = 2732 / skyColors.length;
	for (var i = 0; i < skyColors.length; i++) {
		var skyBand = LK.getAsset('skyBand' + i, {
			width: 2048,
			height: bandHeight,
			color: skyColors[i],
			y: i * bandHeight
		});
		background.addChild(skyBand);
	}
	// Create stars
	var stars = new Container();
	self.stars = stars;
	self.addChild(stars);
	// Add stars to the night sky
	var starCount = 100;
	for (var i = 0; i < starCount; i++) {
		var starSize = 2 + Math.random() * 4;
		var star = LK.getAsset('star_' + i, {
			width: starSize,
			height: starSize,
			color: 0xffffff,
			shape: 'ellipse',
			x: Math.random() * 2048,
			y: Math.random() * 1200,
			alpha: 0.5 + Math.random() * 0.5
		});
		star.pulseSpeed = 0.01 + Math.random() * 0.02;
		star.pulsePhase = Math.random() * Math.PI * 2;
		stars.addChild(star);
	}
	// Add floating lotus flowers
	var lotusFlowers = new Container();
	self.lotusFlowers = lotusFlowers;
	self.addChild(lotusFlowers);
	var lotusCount = 5;
	for (var i = 0; i < lotusCount; i++) {
		var lotusSize = 80 + Math.random() * 40;
		var lotus = LK.getAsset('lotus_' + i, {
			width: lotusSize,
			height: lotusSize,
			color: 0xffb6c1,
			shape: 'ellipse',
			x: 400 + Math.random() * 1200,
			y: 1500 + Math.random() * 800
		});
		lotus.floatSpeed = 0.2 + Math.random() * 0.3;
		lotus.floatPhase = Math.random() * Math.PI * 2;
		lotusFlowers.addChild(lotus);
	}
	// Add water ripples
	var ripples = new Container();
	self.ripples = ripples;
	self.addChild(ripples);
	self.rippleTimer = 0;
	// Update function to animate elements
	self.update = function () {
		// Animate stars (pulsing effect)
		for (var i = 0; i < stars.children.length; i++) {
			var star = stars.children[i];
			star.pulsePhase += star.pulseSpeed;
			star.alpha = 0.5 + 0.5 * Math.sin(star.pulsePhase);
		}
		// Animate lotus flowers (gentle floating)
		for (var i = 0; i < lotusFlowers.children.length; i++) {
			var lotus = lotusFlowers.children[i];
			lotus.floatPhase += 0.01;
			lotus.y += Math.sin(lotus.floatPhase) * lotus.floatSpeed;
		}
		// Create new ripples periodically
		self.rippleTimer++;
		if (self.rippleTimer > 120) {
			// Every 2 seconds
			self.createRipple(400 + Math.random() * 1200, 1500 + Math.random() * 800);
			self.rippleTimer = 0;
		}
		// Update existing ripples
		for (var i = ripples.children.length - 1; i >= 0; i--) {
			var ripple = ripples.children[i];
			ripple.age++;
			// Expand ripple
			ripple.scale.x += 0.01;
			ripple.scale.y += 0.01;
			// Fade out ripple
			ripple.alpha = 1 - ripple.age / ripple.lifespan;
			// Remove old ripples
			if (ripple.age >= ripple.lifespan) {
				ripple.destroy();
				ripples.removeChild(ripple);
			}
		}
	};
	// Method to create a new water ripple
	self.createRipple = function (x, y) {
		var ripple = LK.getAsset('ripple', {
			width: 50,
			height: 50,
			color: 0xffffff,
			shape: 'ellipse',
			x: x,
			y: y,
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0.7
		});
		ripple.age = 0;
		ripple.lifespan = 120; // 2 seconds
		ripples.addChild(ripple);
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 5;
	self.health = 100;
	self.maxHealth = 100;
	self.shootCooldown = 0;
	self.shootDelay = 15; // Frames between shots
	self.canMove = true;
	// Health bar setup
	var healthBarBg = self.attachAsset('healthBarBackground', {
		anchorX: 0.5,
		anchorY: 0,
		y: 120
	});
	var healthBarFill = self.attachAsset('healthBar', {
		anchorX: 0.5,
		anchorY: 0,
		y: 122
	});
	self.updateHealthBar = function () {
		var healthPercentage = self.health / self.maxHealth;
		healthBarFill.scale.x = healthPercentage;
		// Center the health bar
		healthBarFill.x = -100 * (1 - healthPercentage);
	};
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			self.health = 0;
			LK.effects.flashScreen(0xFF0000, 1000);
			LK.showGameOver();
		}
		self.updateHealthBar();
	};
	self.shoot = function () {
		if (self.shootCooldown <= 0) {
			var bullet = new Bullet();
			bullet.x = self.x;
			bullet.y = self.y - 40;
			// Add to game's bullets array
			bullets.push(bullet);
			game.addChild(bullet);
			// Play gun sound
			LK.getSound('gunshot').play();
			// Reset cooldown
			self.shootCooldown = self.shootDelay;
		}
	};
	self.update = function () {
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	self.down = function (x, y, obj) {
		self.shoot();
	};
	// Initialize health bar
	self.updateHealthBar();
	return self;
});
var SoulOrb = Container.expand(function () {
	var self = Container.call(this);
	// Create the soul orb with a glowing effect
	var orbCore = self.attachAsset('centerCircle', {
		width: 60,
		height: 60,
		color: 0x83de44,
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create outer glow
	var orbGlow = LK.getAsset('centerCircle', {
		width: 100,
		height: 100,
		color: 0xb8ffb0,
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5
	});
	self.addChild(orbGlow);
	// Add pulsating animation to the glow
	self.glowPhase = 0;
	self.energy = 0; // Energy level (0-100)
	self.maxEnergy = 100;
	self.pulseSpeed = 0.05;
	// Update method to animate the orb
	self.update = function () {
		self.glowPhase += self.pulseSpeed;
		orbGlow.scale.x = 1 + 0.2 * Math.sin(self.glowPhase);
		orbGlow.scale.y = 1 + 0.2 * Math.sin(self.glowPhase);
		// Adjust color based on energy level
		var energyRatio = self.energy / self.maxEnergy;
		var r = Math.floor(131 + (255 - 131) * energyRatio);
		var g = Math.floor(222 + (255 - 222) * energyRatio);
		var b = Math.floor(68 + (255 - 68) * energyRatio);
		// Convert RGB to hex
		var color = r << 16 | g << 8 | b;
		orbCore.tint = color;
	};
	// Method to add energy to the orb
	self.addEnergy = function (amount) {
		self.energy = Math.min(self.maxEnergy, self.energy + amount);
		// Flash with increasing brightness as energy increases
		LK.effects.flashObject(self, 0xffffff, 300);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x081832
});
/**** 
* Game Code
****/ 
// Game variables
var meditationSpace;
var soulOrb;
var breathingCircle;
var meditationGuide;
var gameActive = true;
var dragOffset = {
	x: 0,
	y: 0
};
var meditationLevel = 1;
var meditationTime = 0;
var soulEnergy = 0;
var maxSoulEnergy = 100;
var breathingTimer = 0;
// Meditation practices
var practices = [{
	id: 'breathe',
	text: 'Complete 5 breathing cycles',
	count: 0,
	target: 5,
	completed: false
}, {
	id: 'focus',
	text: 'Maintain focus for 60 seconds',
	count: 0,
	target: 60,
	completed: false
}, {
	id: 'energy',
	text: 'Fill your soul with energy',
	count: 0,
	target: 100,
	completed: false
}];
// Setup practice UI
var practiceContainer = new Container();
practiceContainer.x = 40;
practiceContainer.y = 180;
LK.gui.left.addChild(practiceContainer);
var practiceTitle = new Text2('PRACTICES:', {
	size: 50,
	fill: 0xFFFFFF
});
practiceContainer.addChild(practiceTitle);
// Create text for each practice
var practiceTexts = [];
for (var i = 0; i < practices.length; i++) {
	var practiceText = new Text2('• ' + practices[i].text + ' (0/' + practices[i].target + ')', {
		size: 40,
		fill: 0xCCCCCC
	});
	practiceText.y = 60 + i * 50;
	practiceContainer.addChild(practiceText);
	practiceTexts.push(practiceText);
}
// Function to update practice UI
function updatePracticeDisplay() {
	for (var i = 0; i < practices.length; i++) {
		var practice = practices[i];
		var color = practice.completed ? 0x83de44 : 0xCCCCCC;
		practiceTexts[i].setText('• ' + practice.text + ' (' + practice.count + '/' + practice.target + ')');
		practiceTexts[i].fill = color;
	}
}
// Setup UI
var energyTxt = new Text2('Soul Energy: 0%', {
	size: 60,
	fill: 0xFFFFFF
});
energyTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(energyTxt);
var levelTxt = new Text2('Meditation Level: 1', {
	size: 60,
	fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 70;
LK.gui.top.addChild(levelTxt);
// Create and add meditation space
meditationSpace = new MeditationSpace();
game.addChild(meditationSpace);
// Initialize soul orb
soulOrb = new SoulOrb();
soulOrb.x = 2048 / 2;
soulOrb.y = 2732 / 3;
game.addChild(soulOrb);
// Initialize breathing circle
breathingCircle = new BreathingCircle();
breathingCircle.x = 2048 / 2;
breathingCircle.y = 2732 / 2 + 200;
game.addChild(breathingCircle);
// Initialize meditation guide
meditationGuide = new MeditationGuide();
meditationGuide.x = 2048 / 2;
meditationGuide.y = 2732 / 5;
game.addChild(meditationGuide);
// Play meditation music
LK.playMusic('background_music');
// Create a ripple at a position (utility function)
function createRipple(x, y) {
	meditationSpace.createRipple(x, y);
}
// Add soul energy
function addSoulEnergy(amount) {
	soulOrb.addEnergy(amount);
	// Update energy practice
	var energyPractice = practices.find(function (practice) {
		return practice.id === 'energy';
	});
	if (energyPractice && !energyPractice.completed) {
		energyPractice.count = Math.floor(soulOrb.energy);
		if (energyPractice.count >= energyPractice.target) {
			energyPractice.completed = true;
			LK.effects.flashObject(practiceTexts[2], 0x83de44, 1000);
		}
		updatePracticeDisplay();
	}
}
// Check if meditation level should increase
function checkMeditationProgress() {
	// Check if practices are completed to progress meditation level
	var completedPractices = practices.filter(function (practice) {
		return practice.completed;
	}).length;
	var newLevel = 1 + Math.floor(completedPractices / 2);
	if (newLevel > meditationLevel) {
		meditationLevel = newLevel;
		levelTxt.setText('Meditation Level: ' + meditationLevel);
		// Bonus for reaching new level
		addSoulEnergy(10 * meditationLevel);
		// Visual feedback
		LK.effects.flashScreen(0x83de44, 500);
	}
}
// Meditation interaction handling
game.down = function (x, y, obj) {
	// Calculate distances to interactive elements
	var distToOrb = Math.sqrt(Math.pow(x - soulOrb.x, 2) + Math.pow(y - soulOrb.y, 2));
	// If touching the soul orb
	if (distToOrb < 100) {
		// Add energy to the soul
		soulOrb.addEnergy(5);
		// Emit a ripple effect from the interaction point
		meditationSpace.createRipple(x, y);
		// Create visual feedback
		LK.effects.flashObject(soulOrb, 0xFFFFFF, 500);
	} else {
		// Create ripple at touch point
		meditationSpace.createRipple(x, y);
	}
	// Set drag offset for moving the orb
	dragOffset.x = soulOrb.x - x;
	dragOffset.y = soulOrb.y - y;
};
game.move = function (x, y, obj) {
	// Move soul orb with drag
	soulOrb.x = x + dragOffset.x;
	soulOrb.y = y + dragOffset.y;
	// Keep soul orb in bounds
	soulOrb.x = Math.max(100, Math.min(2048 - 100, soulOrb.x));
	soulOrb.y = Math.max(100, Math.min(2732 - 100, soulOrb.y));
	// Create subtle ripple effects during movement
	if (Math.random() < 0.1) {
		meditationSpace.createRipple(soulOrb.x + (Math.random() * 100 - 50), soulOrb.y + (Math.random() * 100 - 50));
	}
};
game.up = function () {
	// Create final ripple at release point
	meditationSpace.createRipple(soulOrb.x, soulOrb.y);
};
// Game update loop
game.update = function () {
	if (!gameActive) return;
	// Update meditation space
	meditationSpace.update();
	// Update soul orb, breathing circle, and guide
	soulOrb.update();
	breathingCircle.update();
	meditationGuide.update();
	// Update energy display
	energyTxt.setText('Soul Energy: ' + Math.floor(soulOrb.energy / maxSoulEnergy * 100) + '%');
	// Track breathing cycles for breathe practice
	if (breathingCircle.breathPhase === 3 && breathingCircle.breathTimer === 0) {
		// Just completed a full breathing cycle
		var breathePractice = practices.find(function (practice) {
			return practice.id === 'breathe';
		});
		if (breathePractice && !breathePractice.completed) {
			breathePractice.count++;
			if (breathePractice.count >= breathePractice.target) {
				breathePractice.completed = true;
				LK.effects.flashObject(practiceTexts[0], 0x83de44, 1000);
				// Add soul energy when completing breathing practice
				soulOrb.addEnergy(20);
			}
			updatePracticeDisplay();
		}
	}
	// Track focus time for focus practice
	meditationTime++;
	if (meditationTime % 60 === 0) {
		// Every second
		var focusPractice = practices.find(function (practice) {
			return practice.id === 'focus';
		});
		if (focusPractice && !focusPractice.completed) {
			focusPractice.count++;
			if (focusPractice.count >= focusPractice.target) {
				focusPractice.completed = true;
				LK.effects.flashObject(practiceTexts[1], 0x83de44, 1000);
				// Add soul energy when completing focus practice
				soulOrb.addEnergy(30);
			}
			updatePracticeDisplay();
		}
	}
	// Add soul energy over time with active meditation
	if (meditationTime % 180 === 0) {
		// Every 3 seconds
		soulOrb.addEnergy(1);
		// Track soul energy for energy practice
		var energyPractice = practices.find(function (practice) {
			return practice.id === 'energy';
		});
		if (energyPractice && !energyPractice.completed) {
			energyPractice.count = Math.floor(soulOrb.energy);
			if (energyPractice.count >= energyPractice.target) {
				energyPractice.completed = true;
				LK.effects.flashObject(practiceTexts[2], 0x83de44, 1000);
			}
			updatePracticeDisplay();
		}
	}
	// Check for meditation level up
	if (meditationTime % 600 === 0) {
		// Every 10 seconds
		meditationLevel++;
		levelTxt.setText('Meditation Level: ' + meditationLevel);
		// Visual feedback for level up
		LK.effects.flashScreen(0x83de44, 500);
	}
	// Check if all practices are completed
	var allPracticesCompleted = practices.every(function (practice) {
		return practice.completed;
	});
	if (allPracticesCompleted && gameActive) {
		// Show enlightenment message
		var enlightenmentMessage = new Text2('ENLIGHTENMENT ACHIEVED!', {
			size: 100,
			fill: 0xFFFFFF
		});
		enlightenmentMessage.anchor.set(0.5, 0.5);
		enlightenmentMessage.x = 2048 / 2;
		enlightenmentMessage.y = 2732 / 2;
		game.addChild(enlightenmentMessage);
		// Visual effects for enlightenment
		LK.effects.flashScreen(0xFFFFFF, 2000);
		// Create new practices with higher requirements
		practices = [{
			id: 'breathe',
			text: 'Complete 10 breathing cycles',
			count: 0,
			target: 10,
			completed: false
		}, {
			id: 'focus',
			text: 'Maintain focus for 120 seconds',
			count: 0,
			target: 120,
			completed: false
		}, {
			id: 'energy',
			text: 'Achieve deeper enlightenment',
			count: 0,
			target: 200,
			completed: false
		}];
		// Update practice display
		for (var i = 0; i < practices.length; i++) {
			practiceTexts[i].setText('• ' + practices[i].text + ' (0/' + practices[i].target + ')');
			practiceTexts[i].fill = 0xCCCCCC;
		}
		// Increase soul orb capacity
		maxSoulEnergy = 200;
		// Remove the enlightenment message after 3 seconds
		LK.setTimeout(function () {
			enlightenmentMessage.destroy();
			updatePracticeDisplay();
		}, 3000);
	}
};