/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var AnimatedLetter = Container.expand(function (letter, targetX, targetY, index) {
	var self = Container.call(this);
	self.letterText = new Text2(letter, {
		size: 200,
		fill: 0xFFFFFF
	});
	self.letterText.anchor.set(0.5, 0.5);
	self.addChild(self.letterText);
	self.targetX = targetX;
	self.targetY = targetY;
	self.index = index;
	self.x = 2048 / 2;
	self.y = targetY + 150;
	self.alpha = 0;
	self.letterText.scaleX = 0.3;
	self.letterText.scaleY = 0.3;
	self.letterText.rotation = Math.PI * 0.5;
	self.animateIn = function () {
		// Slide from center to target position with fade in
		tween(self, {
			alpha: 1,
			x: self.targetX,
			y: self.targetY
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
		// Scale and rotate into place
		tween(self.letterText, {
			scaleX: 1,
			scaleY: 1,
			rotation: 0
		}, {
			duration: 1200,
			easing: tween.elasticOut
		});
	};
	self.transformColor = function (delay) {
		// Staggered color transformation with delay
		LK.setTimeout(function () {
			// Add subtle pulse before color change
			tween(self.letterText, {
				scaleX: 1.1,
				scaleY: 1.1
			}, {
				duration: 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(self.letterText, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 200,
						easing: tween.easeIn
					});
				}
			});
			// Color transformation wave
			tween(self.letterText, {
				tint: 0xff8000
			}, {
				duration: 800,
				easing: tween.easeInOut
			});
		}, delay);
	};
	return self;
});
var Asteroid = Container.expand(function (size, memeType) {
	var self = Container.call(this);
	// Size can be 0 (small), 1 (medium), or 2 (large)
	self.size = size || 2;
	// Create a container for the asteroid
	var asteroidGraphics = new Container();
	self.addChild(asteroidGraphics);
	// Store the meme type or generate a random one if not provided
	self.memeType = memeType !== undefined ? memeType : Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
	// Create the asteroid image based on size
	var assetId;
	if (self.size === 0) {
		assetId = 'memeSmall';
	} else if (self.size === 1) {
		assetId = 'memeMedium';
	} else {
		assetId = 'meme' + self.memeType;
	}
	// Add the meme image as the asteroid
	var memeImage = LK.getAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	asteroidGraphics.addChild(memeImage);
	// Random velocity
	var speed = (3 - self.size) * 0.8 + 0.5; // Smaller asteroids move faster
	var angle = Math.random() * Math.PI * 2;
	self.velocity = {
		x: Math.cos(angle) * speed,
		y: Math.sin(angle) * speed
	};
	// Random rotation
	self.rotationSpeed = (Math.random() - 0.5) * 0.05;
	self.update = function () {
		// Move
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Rotate
		asteroidGraphics.rotation += self.rotationSpeed;
		// Wrap around screen edges - optimize by only checking when needed
		if (self.x < -50) {
			self.x = 2098;
			self.justWrapped = true;
		} else if (self.x > 2098) {
			self.x = -50;
			self.justWrapped = true;
		} else if (self.y < -50) {
			self.y = 2782;
			self.justWrapped = true;
		} else if (self.y > 2782) {
			self.y = -50;
			self.justWrapped = true;
		} else {
			self.justWrapped = false;
		}
	};
	self.getPoints = function () {
		return (3 - self.size) * 100; // Small: 300, Medium: 200, Large: 100
	};
	return self;
});
var AuraParticle = Container.expand(function () {
	var self = Container.call(this);
	// Create particle visual - turquoise and larger than thrust particles
	var particleGraphics = LK.getAsset('bulletShape', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 36,
		// Larger than thrust particles
		height: 36,
		tint: 0x40E0D0 // Turquoise color for aura
	});
	particleGraphics.alpha = 1.0;
	self.addChild(particleGraphics);
	// Particle properties
	self.velocity = {
		x: 0,
		y: 0
	};
	self.lifespan = 45; // Longer lifespan than thrust particles
	self.age = 0;
	self.update = function () {
		// Move according to velocity
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Age the particle
		self.age++;
		// Pulse the particle size for more dynamic effect
		var pulseScale = 1 + 0.2 * Math.sin(self.age * 0.2);
		particleGraphics.scale.set(pulseScale, pulseScale);
		// Fade out as it ages, with a faster tail-end fade
		var lifeRatio = self.age / self.lifespan;
		particleGraphics.alpha = 0.9 * (1 - lifeRatio * lifeRatio);
		// Return true if particle should be removed
		return self.age >= self.lifespan;
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	// Create a container for pixel art bullet
	var bulletGraphics = new Container();
	self.addChild(bulletGraphics);
	// Create a solid bullet (a single large pixel)
	var bulletSize = 60; // Size of the bullet - increased to 60 for better visibility
	// Create a single solid element for the bullet
	var bulletSprite = LK.getAsset('bulletShape', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: bulletSize,
		height: bulletSize,
		tint: 0xFFFF00 // Bright yellow color for better visibility
	});
	bulletGraphics.addChild(bulletSprite);
	self.speed = 10;
	self.velocity = {
		x: 0,
		y: 0
	};
	self.lifespan = 180; // 3 seconds at 60fps - triple the firing range
	self.age = 0;
	self.update = function () {
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		self.age++;
		// Wrap around screen edges - use else-if to avoid redundant checks
		if (self.x < 0) {
			self.x = 2048;
		} else if (self.x > 2048) {
			self.x = 0;
		}
		if (self.y < 0) {
			self.y = 2732;
		} else if (self.y > 2732) {
			self.y = 0;
		}
	};
	return self;
});
var Button = Container.expand(function (assetId) {
	var self = Container.call(this);
	// Create button as a solid shape
	var buttonGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2,
		scaleY: 2
	});
	buttonGraphics.alpha = 0.5;
	// Determine button shape based on assetId
	var isCircle = assetId === 'fireButton' || assetId === 'forwardButton';
	var buttonSize = 60; // Radius or half-width
	self.isPressed = false;
	// Add aura ready text if this is the fire button
	self.isFireButton = assetId === 'fireButton';
	if (self.isFireButton) {
		self.auraReadyText = new Text2('AURA READY!', {
			size: 30,
			fill: 0xFFFF00
		});
		self.auraReadyText.anchor.set(0.5, 0.5);
		self.auraReadyText.y = -90; // Position above the button
		self.auraReadyText.visible = false; // Initially hidden
		self.addChild(self.auraReadyText);
	}
	self.down = function (x, y, obj) {
		self.isPressed = true;
		buttonGraphics.alpha = 0.8;
	};
	self.up = function (x, y, obj) {
		self.isPressed = false;
		buttonGraphics.alpha = 0.5;
	};
	// Method to update aura ready text visibility
	self.updateAuraText = function (isAuraReady, cooldownRemaining) {
		if (self.isFireButton && self.auraReadyText) {
			// Initialize style property if it doesn't exist
			if (!self.auraReadyText.style) {
				self.auraReadyText.style = {};
			}
			if (isAuraReady) {
				self.auraReadyText.visible = true;
				self.auraReadyText.setText('AURA READY!');
				self.auraReadyText.style.fill = 0xFFFF00; // Yellow when ready
				// Add pulsing animation when aura is ready
				if (!self.pulseAnimation) {
					self.pulseAnimation = true;
					pulsateAuraText();
				}
			} else {
				// Show countdown when not ready
				if (cooldownRemaining !== undefined) {
					var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
					var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
					self.auraReadyText.visible = true;
					self.auraReadyText.setText('AURA: ' + secondsRemaining + 's');
					self.auraReadyText.style.fill = 0x3399FF; // Blue for cooldown
				} else {
					self.auraReadyText.visible = false;
				}
				self.pulseAnimation = false;
			}
		}
		function pulsateAuraText() {
			if (!self.pulseAnimation) {
				return;
			}
			tween(self.auraReadyText, {
				scaleX: 1.2,
				scaleY: 1.2
			}, {
				duration: 500,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					if (!self.pulseAnimation) {
						return;
					}
					tween(self.auraReadyText, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 500,
						easing: tween.easeInOut,
						onFinish: pulsateAuraText
					});
				}
			});
		}
	};
	return self;
});
var CreeperAsteroid = Container.expand(function () {
	var self = Container.call(this);
	// Create a container for the asteroid
	var asteroidGraphics = new Container();
	self.addChild(asteroidGraphics);
	// Always use meme9 (the Troll Face) as the creeper meme
	self.memeType = 9;
	// Add the meme image as the asteroid
	var memeImage = LK.getAsset('meme' + self.memeType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	asteroidGraphics.addChild(memeImage);
	// Explosive properties
	self.isExplosive = true;
	self.explosionRadius = 300;
	// Random velocity - slower than normal asteroids
	var speed = 0.9;
	var angle = Math.random() * Math.PI * 2;
	self.velocity = {
		x: Math.cos(angle) * speed,
		y: Math.sin(angle) * speed
	};
	// Random rotation - slower to appear more menacing
	self.rotationSpeed = (Math.random() - 0.5) * 0.03;
	// Pulsating effect
	self.pulseDirection = 1;
	self.pulseAmount = 0;
	self.pulseMax = 0.15;
	self.pulseSpeed = 0.008;
	self.update = function () {
		// Move
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Rotate
		asteroidGraphics.rotation += self.rotationSpeed;
		// Pulsating effect
		self.pulseAmount += self.pulseDirection * self.pulseSpeed;
		if (self.pulseAmount >= self.pulseMax) {
			self.pulseDirection = -1;
		} else if (self.pulseAmount <= 0) {
			self.pulseDirection = 1;
		}
		// Apply pulse to scale
		var pulseScale = 1 + self.pulseAmount;
		asteroidGraphics.scale.set(pulseScale, pulseScale);
		// Make it glow green occasionally
		if (LK.ticks % 60 < 15) {
			asteroidGraphics.tint = 0x88FF88;
		} else {
			asteroidGraphics.tint = 0xFFFFFF;
		}
		// Wrap around screen edges
		if (self.x < -50) {
			self.x = 2098;
		}
		if (self.x > 2098) {
			self.x = -50;
		}
		if (self.y < -50) {
			self.y = 2782;
		}
		if (self.y > 2782) {
			self.y = -50;
		}
	};
	self.getPoints = function () {
		return 200; // More points than regular asteroids
	};
	self.explode = function () {
		// Create explosion visual effect
		var explosion = new Container();
		var explosionGraphic = LK.getAsset('forwardButton', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: self.explosionRadius * 2,
			height: self.explosionRadius * 2,
			tint: 0x88FF88 // Green explosion
		});
		explosionGraphic.alpha = 0.7;
		explosion.addChild(explosionGraphic);
		explosion.x = self.x;
		explosion.y = self.y;
		game.addChild(explosion);
		// Animate the explosion - optimized for better performance
		tween(explosionGraphic, {
			alpha: 0,
			width: self.explosionRadius * 2.2,
			// Slightly reduced final size
			height: self.explosionRadius * 2.2 // Slightly reduced final size
		}, {
			duration: 400,
			// Slightly faster animation
			easing: tween.easeOut,
			onFinish: function onFinish() {
				game.removeChild(explosion);
			}
		});
		// Play specific explosion sound
		LK.getSound('meme9Explosion').play();
	};
	return self;
});
var CreeperIntroSequence = Container.expand(function () {
	var self = Container.call(this);
	// Layers for effects
	var starfieldLayer = new Container();
	var creeperLayer = new Container();
	var textLayer = new Container();
	var shipLayer = new Container();
	self.addChild(starfieldLayer);
	self.addChild(creeperLayer);
	self.addChild(textLayer);
	self.addChild(shipLayer);
	// Create starfield with green tint - significantly reduced count for better performance
	var stars = [];
	for (var i = 0; i < 20; i++) {
		var star = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 3 + Math.random() * 5,
			height: 3 + Math.random() * 5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			tint: 0x88FF88 // Green stars
		});
		star.alpha = 0.3 + Math.random() * 0.7;
		star.velocity = 10 + Math.random() * 20;
		stars.push(star);
		starfieldLayer.addChild(star);
	}
	// Create creeper silhouettes in background
	var creepers = [];
	for (var j = 0; j < 6; j++) {
		var creeper = LK.getAsset('meme9', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 200 + Math.random() * 1600,
			y: -300 - Math.random() * 600,
			tint: 0x44AA44 // Dark green silhouettes
		});
		creeper.alpha = 0.3;
		creeper.scale.set(0.3, 0.3);
		creepers.push(creeper);
		creeperLayer.addChild(creeper);
	}
	// Warning text
	var warningText = new Text2('CAUTION: CREEPER TERRITORY!', {
		size: 80,
		fill: 0x88FF88 // Green text
	});
	warningText.anchor.set(0.5, 0.5);
	warningText.x = 2048 / 2;
	warningText.y = 2732 / 2;
	warningText.alpha = 0;
	textLayer.addChild(warningText);
	// Subtitle warning
	var subtitleText = new Text2('BEWARE OF EXPLOSIVES!', {
		size: 60,
		fill: 0xFF3333 // Red text for emphasis
	});
	subtitleText.anchor.set(0.5, 0.5);
	subtitleText.x = 2048 / 2;
	subtitleText.y = 2732 / 2 + 100;
	subtitleText.alpha = 0;
	textLayer.addChild(subtitleText);
	// Hero ship
	var heroShip = new Ship();
	heroShip.x = -100;
	heroShip.y = 2732 / 2;
	shipLayer.addChild(heroShip);
	// Animation sequence
	self.phase = 0;
	self.timer = 0;
	self.finished = false;
	self.update = function () {
		self.timer++;
		// Update stars
		for (var i = 0; i < stars.length; i++) {
			var star = stars[i];
			star.y += star.velocity;
			if (star.y > 2732) {
				star.y = -10;
				star.x = Math.random() * 2048;
			}
		}
		// Animation phases
		switch (self.phase) {
			case 0:
				// Ship enters from left (0-2s)
				tween(heroShip, {
					x: 2048 / 2
				}, {
					duration: 2000,
					easing: tween.easeOut
				});
				self.phase = 1;
				break;
			case 1:
				// Creepers approach (2-4s)
				for (var j = 0; j < creepers.length; j++) {
					creepers[j].y += 3;
					creepers[j].scale.x += 0.003;
					creepers[j].scale.y += 0.003;
				}
				if (self.timer === 120) {
					// After 2s, show warning text
					tween(warningText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Make text glitch effect
					LK.setInterval(function () {
						warningText.scale.set(1 + Math.random() * 0.05, 1 + Math.random() * 0.05);
						warningText.x = 2048 / 2 + (Math.random() * 20 - 10);
					}, 80);
					self.phase = 2;
				}
				break;
			case 2:
				// Warning display (4-6s)
				for (var k = 0; k < creepers.length; k++) {
					creepers[k].y += 3;
					creepers[k].scale.x += 0.004;
					creepers[k].scale.y += 0.004;
				}
				if (self.timer === 240) {
					// After 4s, show subtitle
					tween(subtitleText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Flash the screen green briefly
					LK.effects.flashScreen(0x88FF88, 300);
					self.phase = 3;
				}
				break;
			case 3:
				// Subtitle and prepare to end (6-7s)
				if (self.timer === 360) {
					// After 6s, finish intro
					tween(warningText, {
						alpha: 0
					}, {
						duration: 500
					});
					tween(subtitleText, {
						alpha: 0
					}, {
						duration: 500
					});
					tween(heroShip, {
						x: 2048 + 100
					}, {
						duration: 1000,
						easing: tween.easeIn
					});
					self.phase = 4;
				}
				break;
			case 4:
				// Fade out and end (7-8s)
				if (self.timer === 420) {
					self.finished = true;
				}
				break;
		}
		return self.finished;
	};
	self.skip = function () {
		// Do nothing - disable skipping
	};
	return self;
});
var GlaudIntroSequence = Container.expand(function () {
	var self = Container.call(this);
	var particles = [];
	var letters = [];
	var particlePool = [];
	// Create wireframe ball
	var wireframeBall = new WireframeBall();
	wireframeBall.x = 2048 / 2;
	wireframeBall.y = 2732 / 2;
	wireframeBall.scaleX = 0.1;
	wireframeBall.scaleY = 0.1;
	wireframeBall.alpha = 0;
	self.addChild(wireframeBall);
	// Create GLAUD letters
	var letterPositions = [{
		letter: 'G',
		x: 2048 / 2 - 400,
		y: 2732 / 2
	}, {
		letter: 'L',
		x: 2048 / 2 - 200,
		y: 2732 / 2
	}, {
		letter: 'A',
		x: 2048 / 2,
		y: 2732 / 2
	}, {
		letter: 'U',
		x: 2048 / 2 + 200,
		y: 2732 / 2
	}, {
		letter: 'D',
		x: 2048 / 2 + 400,
		y: 2732 / 2
	}];
	for (var i = 0; i < letterPositions.length; i++) {
		var letterData = letterPositions[i];
		var animatedLetter = new AnimatedLetter(letterData.letter, letterData.x, letterData.y, i);
		letters.push(animatedLetter);
		self.addChild(animatedLetter);
	}
	// Initialize particle pool for better performance
	function initParticlePool() {
		for (var i = 0; i < 50; i++) {
			var particle = new GlaudParticle('energy');
			particle.active = false;
			particlePool.push(particle);
		}
	}
	function getPooledParticle() {
		for (var i = 0; i < particlePool.length; i++) {
			if (!particlePool[i].active) {
				particlePool[i].active = true;
				return particlePool[i];
			}
		}
		// If pool is empty, create new particle
		var newParticle = new GlaudParticle('energy');
		newParticle.active = true;
		particlePool.push(newParticle);
		return newParticle;
	}
	function returnParticleToPool(particle) {
		particle.active = false;
		if (particle.parent) {
			particle.parent.removeChild(particle);
		}
	}
	// Initialize intro sequence with chained animations
	function initIntroSequence() {
		// Start ball growth animation
		startBallGrowth();
	}
	function startBallGrowth() {
		LK.getSound('ballGrow').play();
		// Wireframe ball growth with rotation acceleration
		tween(wireframeBall, {
			scaleX: 3.2,
			scaleY: 3.2,
			alpha: 1
		}, {
			duration: 3000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				// Brief pause at maximum size, then start contraction
				LK.setTimeout(function () {
					startBallContraction();
				}, 500);
			}
		});
		// Gradually increase rotation speeds
		tween(wireframeBall, {
			rotationSpeedX: 0.08,
			rotationSpeedY: 0.1,
			rotationSpeedZ: 0.06
		}, {
			duration: 3000,
			easing: tween.easeInOut
		});
		// Add energy buildup with sparkle intensity
		LK.setTimeout(function () {
			// Final pulse before contraction
			tween(wireframeBall, {
				scaleX: 3.5,
				scaleY: 3.5
			}, {
				duration: 200,
				easing: tween.easeInOut
			});
			// Maximum rotation speed for instability effect
			wireframeBall.rotationSpeedX = 0.12;
			wireframeBall.rotationSpeedY = 0.15;
			wireframeBall.rotationSpeedZ = 0.1;
		}, 2000);
	}
	function startBallContraction() {
		LK.getSound('ballContract').play();
		// Dramatic wireframe ball implosion with extreme rotation
		wireframeBall.rotationSpeedX = 0.8;
		wireframeBall.rotationSpeedY = 1.0;
		wireframeBall.rotationSpeedZ = 0.6;
		tween(wireframeBall, {
			scaleX: 0,
			scaleY: 0,
			alpha: 0
		}, {
			duration: 600,
			easing: tween.easeInQuad,
			onFinish: function onFinish() {
				wireframeBall.alpha = 0;
				// Start letter formation after brief pause
				LK.setTimeout(function () {
					startLetterFormation();
				}, 200);
			}
		});
		// Delay explosion slightly for implosion effect
		LK.setTimeout(function () {
			createParticleExplosion();
		}, 300);
	}
	function startLetterFormation() {
		// Animate letters appearing one by one
		animateLetterSequence(0);
	}
	function animateLetterSequence(index) {
		if (index >= letters.length) {
			// All letters have appeared, start color transformation
			LK.setTimeout(function () {
				startColorTransformation();
			}, 500);
			return;
		}
		LK.getSound('letterAppear').play();
		letters[index].animateIn();
		// Schedule next letter with delay
		LK.setTimeout(function () {
			animateLetterSequence(index + 1);
		}, 250);
	}
	function startColorTransformation() {
		LK.getSound('colorTransform').play();
		// Staggered color transformation for wave effect
		var completedTransforms = 0;
		for (var i = 0; i < letters.length; i++) {
			(function (letterIndex) {
				LK.setTimeout(function () {
					letters[letterIndex].transformColor(0);
					completedTransforms++;
					// Check if all transformations are complete
					if (completedTransforms === letters.length) {
						LK.setTimeout(function () {
							startFinalEmphasis();
						}, 800);
					}
				}, letterIndex * 150);
			})(i);
		}
	}
	function startFinalEmphasis() {
		// Overall luminosity surge for all letters
		for (var i = 0; i < letters.length; i++) {
			tween(letters[i].letterText, {
				tint: 0xffaa00,
				// Brighter orange/yellow
				scaleX: 1.08,
				scaleY: 1.08
			}, {
				duration: 500,
				easing: tween.easeOut
			});
		}
		// Start progressive fade-out after surge
		LK.setTimeout(function () {
			startProgressiveFadeOut();
		}, 500);
	}
	function startProgressiveFadeOut() {
		// Unified Power Display (0 - 0.8 Seconds)
		startUnifiedPowerDisplay();
	}
	function startUnifiedPowerDisplay() {
		// Screen flash to white briefly for dramatic effect
		LK.effects.flashScreen(0xffffff, 200);
		// Make all letters shine with intense light simultaneously
		for (var i = 0; i < letters.length; i++) {
			// Multiple tween stages for more dramatic buildup
			tween(letters[i].letterText, {
				tint: 0xffdd00,
				// Bright gold first
				scaleX: 1.25,
				scaleY: 1.25
			}, {
				duration: 300,
				easing: tween.easeOut,
				onFinish: function (targetLetter) {
					return function () {
						tween(targetLetter.letterText, {
							tint: 0xffffff,
							// Then to brilliant white
							scaleX: 1.4,
							scaleY: 1.4
						}, {
							duration: 500,
							easing: tween.easeInOut
						});
					};
				}(letters[i])
			});
		}
		// Create god rays emanating from the text
		createGodRays();
		// Create energy particles swirling around letters
		createEnergySwirl();
		// Schedule the spectacular disappearance
		LK.setTimeout(function () {
			startSpectacularDisappearance();
		}, 800);
	}
	function createGodRays() {
		// Create multiple layers of light rays for depth
		for (var layer = 0; layer < 2; layer++) {
			var rayCount = layer === 0 ? 16 : 8;
			var rayLength = layer === 0 ? 4 : 6;
			for (var i = 0; i < rayCount; i++) {
				var ray = self.addChild(LK.getAsset('wireframeEdge', {
					anchorX: 0.5,
					anchorY: 0,
					x: 2048 / 2,
					y: 2732 / 2,
					rotation: Math.PI * 2 * i / rayCount + layer * Math.PI / 16,
					scaleX: 0.3 + layer * 0.2,
					scaleY: rayLength,
					tint: layer === 0 ? 0xffaa00 : 0xffffff,
					alpha: 0
				}));
				// Staggered ray appearance
				LK.setTimeout(function (currentRay, delayTime) {
					return function () {
						tween(currentRay, {
							alpha: 0.6 + Math.random() * 0.3,
							scaleY: rayLength + 2
						}, {
							duration: 400,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								// Pulse the rays before fade
								tween(currentRay, {
									alpha: 0.9,
									scaleY: rayLength + 3
								}, {
									duration: 200,
									easing: tween.easeInOut,
									onFinish: function onFinish() {
										tween(currentRay, {
											alpha: 0
										}, {
											duration: 300,
											easing: tween.easeIn,
											onFinish: function onFinish() {
												currentRay.destroy();
											}
										});
									}
								});
							}
						});
					};
				}(ray, i * 50 + layer * 200), i * 50 + layer * 200);
			}
		}
	}
	function createEnergySwirl() {
		// Create swirling energy particles around the text
		for (var i = 0; i < 30; i++) {
			var energyParticle = self.addChild(LK.getAsset('sparkle', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2 + Math.cos(i * 0.5) * 200,
				y: 2732 / 2 + Math.sin(i * 0.5) * 200,
				tint: 0xffdd00,
				alpha: 0
			}));
			// Animate particles in spiral motion
			var particleDelay = i * 30;
			LK.setTimeout(function (particle, index) {
				return function () {
					particle.alpha = 0.8;
					// Create spiral motion
					var _spiralTween = function spiralTween(currentAngle) {
						var radius = 150 + Math.sin(currentAngle * 0.1) * 50;
						var newX = 2048 / 2 + Math.cos(currentAngle) * radius;
						var newY = 2732 / 2 + Math.sin(currentAngle) * radius;
						tween(particle, {
							x: newX,
							y: newY,
							rotation: currentAngle
						}, {
							duration: 100,
							easing: tween.linear,
							onFinish: function onFinish() {
								if (currentAngle < Math.PI * 6) {
									_spiralTween(currentAngle + 0.3);
								} else {
									// Burst toward center
									tween(particle, {
										x: 2048 / 2,
										y: 2732 / 2,
										alpha: 0,
										scaleX: 0.1,
										scaleY: 0.1
									}, {
										duration: 200,
										easing: tween.easeInQuad,
										onFinish: function onFinish() {
											particle.destroy();
										}
									});
								}
							}
						});
					};
					_spiralTween(index * 0.5);
				};
			}(energyParticle, i), particleDelay);
		}
	}
	function startSpectacularDisappearance() {
		// Create dramatic screen distortion effect
		for (var i = 0; i < letters.length; i++) {
			var letter = letters[i];
			// Add violent shaking before implosion
			var shakeIntensity = 15;
			var shakeCount = 0;
			var shakeInterval = LK.setInterval(function (targetLetter) {
				return function () {
					targetLetter.x += (Math.random() - 0.5) * shakeIntensity;
					targetLetter.y += (Math.random() - 0.5) * shakeIntensity;
					shakeCount++;
					if (shakeCount > 10) {
						LK.clearInterval(shakeInterval);
					}
				};
			}(letter), 50);
		}
		// Enhanced implosion with multiple stages
		LK.setTimeout(function () {
			var centerX = 2048 / 2;
			var centerY = 2732 / 2;
			// Stage 1: Rapid acceleration toward center
			for (var i = 0; i < letters.length; i++) {
				var letter = letters[i];
				tween(letter, {
					x: centerX,
					y: centerY,
					scaleX: 0.3,
					scaleY: 0.3
				}, {
					duration: 180,
					easing: tween.easeInCubic
				});
				tween(letter.letterText, {
					tint: 0xffffff,
					alpha: 1.2
				}, {
					duration: 180
				});
			}
			// Stage 2: Final compression
			LK.setTimeout(function () {
				for (var i = 0; i < letters.length; i++) {
					var letter = letters[i];
					tween(letter, {
						scaleX: 0.05,
						scaleY: 0.05
					}, {
						duration: 80,
						easing: tween.easeInQuart
					});
				}
			}, 120);
			// Create the enhanced bright point and burst
			LK.setTimeout(function () {
				createEnhancedBrightPointAndBurst();
			}, 200);
		}, 500);
	}
	function createEnhancedBrightPointAndBurst() {
		// Create multiple concentric energy rings
		var rings = [];
		for (var r = 0; r < 3; r++) {
			var ring = self.addChild(LK.getAsset('wireframeJoint', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2,
				y: 2732 / 2,
				scaleX: 0.1 + r * 0.1,
				scaleY: 0.1 + r * 0.1,
				tint: r === 0 ? 0xffffff : r === 1 ? 0xffdd00 : 0xffaa00,
				alpha: 1
			}));
			rings.push(ring);
		}
		// Intense multi-stage flash
		var flashStage = 0;
		var flashInterval = LK.setInterval(function () {
			// Screen flash with varying intensities
			var flashColors = [0xffffff, 0xffdd00, 0xffffff, 0xffaa00];
			LK.effects.flashScreen(flashColors[flashStage % flashColors.length], 150);
			for (var i = 0; i < rings.length; i++) {
				tween(rings[i], {
					scaleX: (flashStage + 1) * 0.5 + i * 0.2,
					scaleY: (flashStage + 1) * 0.5 + i * 0.2,
					alpha: 1 - flashStage * 0.15
				}, {
					duration: 120,
					easing: tween.easeOut
				});
			}
			flashStage++;
			if (flashStage >= 4) {
				LK.clearInterval(flashInterval);
				// Final burst
				LK.setTimeout(function () {
					createMegaEnergyBurst();
					// Hide all letters
					for (var i = 0; i < letters.length; i++) {
						letters[i].visible = false;
					}
					// Clean up rings
					for (var i = 0; i < rings.length; i++) {
						rings[i].destroy();
					}
				}, 200);
			}
		}, 150);
	}
	function createMegaEnergyBurst() {
		// Create multiple expanding shockwaves
		for (var wave = 0; wave < 4; wave++) {
			LK.setTimeout(function (waveIndex) {
				return function () {
					var shockwave = self.addChild(LK.getAsset('forwardButton', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: 2048 / 2,
						y: 2732 / 2,
						width: 30,
						height: 30,
						tint: waveIndex === 0 ? 0xffffff : waveIndex % 2 === 0 ? 0xffdd00 : 0xffaa00,
						alpha: 0.9
					}));
					// Animate shockwave expanding with easing
					tween(shockwave, {
						width: 1200 + waveIndex * 200,
						height: 1200 + waveIndex * 200,
						alpha: 0
					}, {
						duration: 600 + waveIndex * 100,
						easing: tween.easeOutCubic,
						onFinish: function onFinish() {
							shockwave.destroy();
						}
					});
				};
			}(wave), wave * 150);
		}
		// Create spectacular particle explosion
		for (var i = 0; i < 50; i++) {
			LK.setTimeout(function (particleIndex) {
				return function () {
					var particle = self.addChild(LK.getAsset('particle', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: 2048 / 2,
						y: 2732 / 2,
						tint: particleIndex % 3 === 0 ? 0xffffff : particleIndex % 3 === 1 ? 0xffdd00 : 0xffaa00
					}));
					var angle = Math.random() * Math.PI * 2;
					var speed = 12 + Math.random() * 20;
					var distance = 40 + Math.random() * 50;
					var targetX = particle.x + Math.cos(angle) * distance;
					var targetY = particle.y + Math.sin(angle) * distance;
					// Multi-stage particle motion
					tween(particle, {
						x: targetX,
						y: targetY,
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 300,
						easing: tween.easeOutQuad,
						onFinish: function onFinish() {
							// Second stage - continue outward and fade
							var finalX = particle.x + Math.cos(angle) * 30;
							var finalY = particle.y + Math.sin(angle) * 30;
							tween(particle, {
								x: finalX,
								y: finalY,
								alpha: 0,
								scaleX: 0.1,
								scaleY: 0.1
							}, {
								duration: 400 + Math.random() * 300,
								easing: tween.easeOutCubic,
								onFinish: function onFinish() {
									particle.destroy();
								}
							});
						}
					});
				};
			}(i), Math.random() * 200);
		}
		// Create lingering energy wisps
		for (var w = 0; w < 15; w++) {
			LK.setTimeout(function () {
				var wisp = self.addChild(LK.getAsset('sparkle', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: 2048 / 2 + (Math.random() - 0.5) * 100,
					y: 2732 / 2 + (Math.random() - 0.5) * 100,
					tint: 0xffdd00,
					alpha: 0.6
				}));
				// Gentle floating motion before fade
				tween(wisp, {
					x: wisp.x + (Math.random() - 0.5) * 200,
					y: wisp.y + (Math.random() - 0.5) * 200,
					alpha: 0,
					rotation: Math.PI * 2
				}, {
					duration: 1500 + Math.random() * 1000,
					easing: tween.easeOutSine,
					onFinish: function onFinish() {
						wisp.destroy();
					}
				});
			}, w * 100 + Math.random() * 300);
		}
		// Extended silence then finish with dramatic fade to black
		LK.setTimeout(function () {
			// Final dramatic fade to black
			LK.effects.flashScreen(0x000000, 1500);
			LK.setTimeout(function () {
				self.finished = true;
			}, 1500);
		}, 1200);
	}
	function createLetterParticles(letter) {
		// Create small orange light particles when letter fades
		for (var i = 0; i < 8; i++) {
			var particle = self.addChild(LK.getAsset('particle', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: letter.x + (Math.random() - 0.5) * 100,
				y: letter.y + (Math.random() - 0.5) * 100
			}));
			particle.tint = 0xff8000; // Orange particles
			particle.scaleX = 0.3 + Math.random() * 0.4;
			particle.scaleY = particle.scaleX;
			var angle = Math.random() * Math.PI * 2;
			var speed = 3 + Math.random() * 5;
			var targetX = particle.x + Math.cos(angle) * speed * 20;
			var targetY = particle.y + Math.sin(angle) * speed * 20;
			tween(particle, {
				x: targetX,
				y: targetY,
				alpha: 0,
				scaleX: 0.1,
				scaleY: 0.1
			}, {
				duration: 600 + Math.random() * 400,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
	}
	function createParticleExplosion() {
		// Create wireframe edge fragments for better visual impact
		var fragmentsToCreate = Math.min(wireframeBall.edges.length, 15); // Fewer but more prominent fragments
		for (var i = 0; i < fragmentsToCreate; i++) {
			if (Math.random() < 0.9) {
				var edgeIndex = Math.floor(Math.random() * wireframeBall.edges.length);
				var edge = wireframeBall.edges[edgeIndex];
				var fragment = self.addChild(LK.getAsset('wireframeEdge', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: wireframeBall.x + edge.x,
					y: wireframeBall.y + edge.y,
					rotation: edge.rotation,
					scaleX: edge.scaleX,
					scaleY: edge.scaleY,
					alpha: edge.alpha
				}));
				// Calculate scatter direction from center
				var centerX = wireframeBall.x;
				var centerY = wireframeBall.y;
				var fragmentX = fragment.x;
				var fragmentY = fragment.y;
				var dirX = fragmentX - centerX;
				var dirY = fragmentY - centerY;
				var distance = Math.sqrt(dirX * dirX + dirY * dirY);
				if (distance === 0) {
					distance = 1;
				}
				dirX /= distance;
				dirY /= distance;
				var speed = 15 + Math.random() * 25;
				var targetX = fragmentX + dirX * speed * 20;
				var targetY = fragmentY + dirY * speed * 20;
				// Add random spinning
				var rotationSpeed = (Math.random() - 0.5) * 0.3;
				// Animate fragment scattering
				tween(fragment, {
					x: targetX,
					y: targetY,
					alpha: 0,
					scaleX: 0.1,
					scaleY: 0.1,
					rotation: fragment.rotation + rotationSpeed * 10
				}, {
					duration: 1000 + Math.random() * 800,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						fragment.destroy();
					}
				});
			}
		}
		// Create energy burst from joints (reduced count)
		var jointsToCreate = Math.min(wireframeBall.joints.length, 6);
		for (var i = 0; i < jointsToCreate; i++) {
			var jointIndex = Math.floor(Math.random() * wireframeBall.joints.length);
			var joint = wireframeBall.joints[jointIndex];
			var energyBurst = self.addChild(LK.getAsset('wireframeJoint', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: wireframeBall.x + joint.x,
				y: wireframeBall.y + joint.y,
				scaleX: 1.5,
				scaleY: 1.5
			}));
			var angle = Math.random() * Math.PI * 2;
			var speed = 8 + Math.random() * 12;
			var targetX = energyBurst.x + Math.cos(angle) * speed * 15;
			var targetY = energyBurst.y + Math.sin(angle) * speed * 15;
			tween(energyBurst, {
				x: targetX,
				y: targetY,
				alpha: 0,
				scaleX: 0.2,
				scaleY: 0.2
			}, {
				duration: 800 + Math.random() * 600,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					energyBurst.destroy();
				}
			});
		}
		// Create main particle burst using pooled particles
		for (var i = 0; i < 15; i++) {
			var particle = getPooledParticle();
			if (particle) {
				particle.x = wireframeBall.x;
				particle.y = wireframeBall.y;
				var angle = Math.PI * 2 * i / 15;
				var speed = 10 + Math.random() * 18;
				particle.velocityX = Math.cos(angle) * speed;
				particle.velocityY = Math.sin(angle) * speed;
				particle.life = 1.0;
				particle.markForDestroy = false;
				particles.push(particle);
				self.addChild(particle);
			}
		}
	}
	// Initialize particle pool and start sequence
	initParticlePool();
	initIntroSequence();
	self.finished = false;
	self.update = function () {
		// Update active particles efficiently
		for (var i = particles.length - 1; i >= 0; i--) {
			var particle = particles[i];
			if (particle.markForDestroy) {
				returnParticleToPool(particle);
				particles.splice(i, 1);
			}
		}
		return self.finished;
	};
	return self;
});
var GlaudParticle = Container.expand(function (particleType) {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = 0;
	self.velocityY = 0;
	self.life = 1.0;
	self.maxLife = 1.0;
	self.fadeSpeed = 0.015 + Math.random() * 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.2;
	self.initialScale = 0.5 + Math.random() * 0.5;
	particleGraphics.scaleX = self.initialScale;
	particleGraphics.scaleY = self.initialScale;
	if (particleType === 'energy') {
		particleGraphics.tint = 0x4a90e2;
	} else {
		particleGraphics.tint = 0xffffff;
	}
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
		self.velocityX *= 0.98; // Add friction
		self.velocityY *= 0.98;
		particleGraphics.rotation += self.rotationSpeed;
		self.life -= self.fadeSpeed;
		var fadeRatio = self.life / self.maxLife;
		particleGraphics.alpha = fadeRatio;
		particleGraphics.scaleX = self.initialScale * fadeRatio;
		particleGraphics.scaleY = self.initialScale * fadeRatio;
		if (self.life <= 0) {
			self.markForDestroy = true;
		}
	};
	return self;
});
var IntroSequence = Container.expand(function () {
	var self = Container.call(this);
	// Layers for effects
	var starfieldLayer = new Container();
	var memesLayer = new Container();
	var textLayer = new Container();
	var shipLayer = new Container();
	var titleLayer = new Container();
	self.addChild(starfieldLayer);
	self.addChild(memesLayer);
	self.addChild(textLayer);
	self.addChild(shipLayer);
	self.addChild(titleLayer);
	// Create starfield - significantly reduced number for better performance
	var stars = [];
	for (var i = 0; i < 20; i++) {
		var star = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 3 + Math.random() * 5,
			height: 3 + Math.random() * 5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			tint: 0xFFFFFF
		});
		star.alpha = 0.3 + Math.random() * 0.7;
		star.velocity = 10 + Math.random() * 20;
		stars.push(star);
		starfieldLayer.addChild(star);
	}
	// Create distant meme silhouettes
	var silhouettes = [];
	for (var j = 0; j < 10; j++) {
		var memeType = Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
		var meme = LK.getAsset('meme' + memeType, {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 200 + Math.random() * 1600,
			y: -300 - Math.random() * 600,
			tint: 0x333333
		});
		meme.alpha = 0.3;
		meme.scale.set(0.3, 0.3);
		silhouettes.push(meme);
		memesLayer.addChild(meme);
	}
	// Emergency broadcast text
	var emergencyText = new Text2('MEME OVERLOAD DETECTED', {
		size: 80,
		fill: 0xFF3333
	});
	emergencyText.anchor.set(0.5, 0.5);
	emergencyText.x = 2048 / 2;
	emergencyText.y = 2732 / 2;
	emergencyText.alpha = 0;
	textLayer.addChild(emergencyText);
	// Hero ship
	var heroShip = new Ship();
	heroShip.x = 2048 / 2;
	heroShip.y = 2732 + 100;
	heroShip.alpha = 0;
	shipLayer.addChild(heroShip);
	// Title
	var titleText = new Text2('MEMES ASTEROID WAR', {
		size: 120,
		fill: 0xFF8000
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 2732 / 2 - 300;
	titleText.alpha = 0;
	titleLayer.addChild(titleText);
	// Call to action
	var ctaText = new Text2('TAP TO DEFEND THE INTERNET', {
		size: 60,
		fill: 0xFFFFFF
	});
	ctaText.anchor.set(0.5, 0.5);
	ctaText.x = 2048 / 2;
	ctaText.y = 2732 / 2 + 300;
	ctaText.alpha = 0;
	titleLayer.addChild(ctaText);
	// Animation sequence
	self.phase = 0;
	self.timer = 0;
	self.finished = false;
	self.update = function () {
		self.timer++;
		// Update stars
		for (var i = 0; i < stars.length; i++) {
			var star = stars[i];
			star.y += star.velocity;
			if (star.y > 2732) {
				star.y = -10;
				star.x = Math.random() * 2048;
			}
		}
		// Animation phases
		switch (self.phase) {
			case 0:
				// Starfield intro (0-2s)
				if (self.timer === 60) {
					// After 1s, start meme approach
					self.phase = 1;
				}
				break;
			case 1:
				// Meme approach (2-4s)
				for (var j = 0; j < silhouettes.length; j++) {
					silhouettes[j].y += 3;
					silhouettes[j].scale.x += 0.003;
					silhouettes[j].scale.y += 0.003;
				}
				if (self.timer === 180) {
					// After 3s, show emergency text
					self.phase = 2;
					tween(emergencyText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Make text glitch effect
					LK.setInterval(function () {
						emergencyText.scale.set(1 + Math.random() * 0.05, 1 + Math.random() * 0.05);
						emergencyText.x = 2048 / 2 + (Math.random() * 20 - 10);
					}, 80);
				}
				break;
			case 2:
				// Emergency broadcast (4-6s)
				for (var k = 0; k < silhouettes.length; k++) {
					silhouettes[k].y += 3;
					silhouettes[k].scale.x += 0.004;
					silhouettes[k].scale.y += 0.004;
				}
				if (self.timer === 300) {
					// After 5s, fade out emergency text and show ship
					self.phase = 3;
					tween(emergencyText, {
						alpha: 0
					}, {
						duration: 500
					});
					// Animate hero ship rising
					heroShip.alpha = 1;
					tween(heroShip, {
						y: 2732 / 2 + 200
					}, {
						duration: 1500,
						easing: tween.easeOut
					});
				}
				break;
			case 3:
				// Ship reveal (6-8s)
				if (self.timer === 420) {
					// After 7s, show title
					self.phase = 4;
					// Animate title card
					tween(titleText, {
						alpha: 1
					}, {
						duration: 800,
						easing: tween.easeOut
					});
					// Create distortion effect on title
					var titleDistort = LK.setInterval(function () {
						titleText.scale.set(1 + Math.random() * 0.03, 1 + Math.random() * 0.03);
						if (self.timer > 480) {
							LK.clearInterval(titleDistort);
							titleText.scale.set(1, 1);
						}
					}, 50);
				}
				break;
			case 4:
				// Title card (8-10s)
				if (self.timer === 540) {
					// After 9s, show CTA
					self.phase = 5;
					tween(ctaText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Make CTA pulse
					LK.setInterval(function () {
						if (ctaText.alpha === 1) {
							tween(ctaText, {
								alpha: 0.5
							}, {
								duration: 800
							});
						} else {
							tween(ctaText, {
								alpha: 1
							}, {
								duration: 800
							});
						}
					}, 1600);
				}
				break;
			case 5:
				// CTA (10s+)
				if (self.timer === 660) {
					// After 11s total, finish intro
					self.finished = true;
				}
				break;
		}
		return self.finished;
	};
	self.skip = function () {
		self.finished = true;
	};
	return self;
});
var OutroSequence = Container.expand(function () {
	var self = Container.call(this);
	// Layers for effects
	var starfieldLayer = new Container();
	var memesLayer = new Container();
	var textLayer = new Container();
	var shipLayer = new Container();
	self.addChild(starfieldLayer);
	self.addChild(memesLayer);
	self.addChild(textLayer);
	self.addChild(shipLayer);
	// Create starfield - significantly reduced number for better performance
	var stars = [];
	for (var i = 0; i < 20; i++) {
		var star = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 3 + Math.random() * 5,
			height: 3 + Math.random() * 5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			tint: 0xFFFFFF
		});
		star.alpha = 0.3 + Math.random() * 0.7;
		star.velocity = 10 + Math.random() * 20;
		stars.push(star);
		starfieldLayer.addChild(star);
	}
	// Create exploding memes
	var memes = [];
	for (var j = 0; j < 20; j++) {
		var memeType = Math.floor(Math.random() * 14); // 0-13 for 14 memes
		var meme = LK.getAsset('meme' + memeType, {
			anchorX: 0.5,
			anchorY: 0.5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			scaleX: 0.2,
			scaleY: 0.2
		});
		meme.rotationSpeed = (Math.random() - 0.5) * 0.1;
		meme.velocity = {
			x: (Math.random() - 0.5) * 8,
			y: (Math.random() - 0.5) * 8
		};
		memes.push(meme);
		memesLayer.addChild(meme);
	}
	// Game result text (Victory or Game Over)
	var resultText;
	if (score > (storage.highScore || 0) && score > 0) {
		resultText = new Text2('VICTORY!', {
			size: 120,
			fill: 0xFF8000
		});
	} else {
		resultText = new Text2('GAME OVER', {
			size: 120,
			fill: 0xFF3333 // Red color for Game Over
		});
	}
	resultText.anchor.set(0.5, 0.5);
	resultText.x = 2048 / 2;
	resultText.y = 2732 / 2 - 300;
	resultText.alpha = 0;
	textLayer.addChild(resultText);
	// Score text
	var finalScoreText = new Text2('FINAL SCORE: ' + score, {
		size: 80,
		fill: 0xFFFFFF
	});
	finalScoreText.anchor.set(0.5, 0.5);
	finalScoreText.x = 2048 / 2;
	finalScoreText.y = 2732 / 2;
	finalScoreText.alpha = 0;
	textLayer.addChild(finalScoreText);
	// Add message based on high score
	var messageText;
	if (score > (storage.highScore || 0) && score > 0) {
		messageText = new Text2('AMAZING JOB! NEW HIGH SCORE!', {
			size: 60,
			fill: 0xFFD700 // Gold color
		});
	} else {
		messageText = new Text2('DON\'T GIVE UP! YOU\'LL DO BETTER NEXT TIME!', {
			size: 60,
			fill: 0x3399FF // Blue color
		});
	}
	messageText.anchor.set(0.5, 0.5);
	messageText.x = 2048 / 2;
	messageText.y = 2732 / 2 + 100;
	messageText.alpha = 0;
	textLayer.addChild(messageText);
	// Continue text
	var continueText = new Text2('TAP TO CONTINUE', {
		size: 60,
		fill: 0xFFFFFF
	});
	continueText.anchor.set(0.5, 0.5);
	continueText.x = 2048 / 2;
	continueText.y = 2732 / 2 + 300;
	continueText.alpha = 0;
	textLayer.addChild(continueText);
	// Animation sequence
	self.phase = 0;
	self.timer = 0;
	self.finished = false;
	self.update = function () {
		self.timer++;
		// Update stars - moving faster for outro
		for (var i = 0; i < stars.length; i++) {
			var star = stars[i];
			star.y -= star.velocity; // Moving upward instead of downward
			if (star.y < -10) {
				star.y = 2732 + 10;
				star.x = Math.random() * 2048;
			}
		}
		// Update memes - spinning and moving across screen
		for (var j = 0; j < memes.length; j++) {
			var meme = memes[j];
			meme.rotation += meme.rotationSpeed;
			meme.x += meme.velocity.x;
			meme.y += meme.velocity.y;
			// Bounce off edges
			if (meme.x < 0 || meme.x > 2048) {
				meme.velocity.x *= -1;
			}
			if (meme.y < 0 || meme.y > 2732) {
				meme.velocity.y *= -1;
			}
		}
		// Animation phases
		switch (self.phase) {
			case 0:
				// Initial pause (0-1s)
				if (self.timer === 60) {
					// After 1s, show result text
					self.phase = 1;
					tween(resultText, {
						alpha: 1,
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 800,
						easing: tween.elasticOut,
						onFinish: function onFinish() {
							tween(resultText, {
								scaleX: 1,
								scaleY: 1
							}, {
								duration: 500,
								easing: tween.easeOut
							});
						}
					});
				}
				break;
			case 1:
				// Victory text (1-3s)
				if (self.timer === 180) {
					// After 3s, show score
					self.phase = 2;
					tween(finalScoreText, {
						alpha: 1
					}, {
						duration: 800,
						easing: tween.easeOut
					});
				}
				break;
			case 2:
				// Score display (3-5s)
				if (self.timer === 240) {
					// After 4s, show motivational message
					tween(messageText, {
						alpha: 1
					}, {
						duration: 800,
						easing: tween.easeOut
					});
				}
				if (self.timer === 300) {
					// After 5s, show continue prompt
					self.phase = 3;
					tween(continueText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Pulse the continue text
					LK.setInterval(function () {
						if (continueText.alpha === 1) {
							tween(continueText, {
								alpha: 0.5
							}, {
								duration: 800
							});
						} else {
							tween(continueText, {
								alpha: 1
							}, {
								duration: 800
							});
						}
					}, 1600);
				}
				break;
			case 3:
				// Continue prompt (5s+)
				// Player can tap to continue
				if (self.timer > 360) {
					self.canExit = true;
				}
				break;
		}
		return self.finished;
	};
	self.skip = function () {
		self.finished = true;
	};
	return self;
});
var Ship = Container.expand(function () {
	var self = Container.call(this);
	// Create a custom triangle ship
	var shipGraphics = new Container();
	self.addChild(shipGraphics);
	// Create a pixel art triangle
	var triangleSize = 72; // Scale up to 1.5 times larger from 48 to 72
	var pixelSize = 12; // Increase pixel size for more distinct lines
	var pixelGap = 1; // Gap between pixels for hollow effect
	// Create triangle points - pointing right by default (0 degrees = right)
	var points = [{
		x: triangleSize,
		y: 0
	},
	// Front tip (pointing right)
	{
		x: -triangleSize / 2,
		y: -triangleSize / 2
	},
	// Top left
	{
		x: -triangleSize / 2,
		y: triangleSize / 2
	} // Bottom left
	];
	// Draw the outline with pixel art style
	for (var i = 0; i < 3; i++) {
		var startPoint = points[i];
		var endPoint = points[(i + 1) % 3];
		// Calculate step count based on distance
		var dx = endPoint.x - startPoint.x;
		var dy = endPoint.y - startPoint.y;
		var steps = Math.max(Math.abs(dx), Math.abs(dy)) / pixelSize;
		// Draw pixels along the line
		for (var step = 0; step <= steps; step++) {
			var px = startPoint.x + dx * (step / steps);
			var py = startPoint.y + dy * (step / steps);
			var pixel = LK.getAsset('shipShape', {
				anchorX: 0.5,
				anchorY: 0.5,
				width: pixelSize - pixelGap,
				height: pixelSize - pixelGap,
				x: px,
				y: py,
				tint: 0xFF8000 // Orange color
			});
			shipGraphics.addChild(pixel);
		}
	}
	shipGraphics.x = 0;
	shipGraphics.y = 0;
	// Ship properties
	self.rot = 0; // Start pointing right (0 radians)
	self.rotationSpeed = 0.05; // Reduced rotation speed for less sensitive steering
	self.isRotatingLeft = false;
	self.isRotatingRight = false;
	self.isFiring = false;
	self.fireDelay = 15; // frames between shots
	self.fireTimer = 0;
	self.invulnerable = false;
	self.invulnerableTime = 0;
	// Aura ability properties
	self.auraReady = false;
	self.auraCooldown = 0;
	self.auraCooldownMax = 900; // 15 seconds (60fps * 15) - reduced from 20s
	self.auraActive = false;
	self.auraActiveTime = 0;
	self.auraActiveTimeMax = 180; // 3 seconds (increased from 2s)
	// Physics-based movement properties - much simpler direct movement
	self.thrustPower = 0.20; // Increased thrust power for faster acceleration
	self.dragFactor = 0.97; // Slightly increased drag to slow down faster
	self.maxSpeed = 8; // Increased maximum speed
	self.velocity = {
		x: 0,
		y: 0
	};
	// Track previous position for movement calculations
	self.lastX = 0;
	self.lastY = 0;
	// Cache rotation values for optimization
	self.lastRot = self.rot;
	self.dirX = Math.cos(self.rot);
	self.dirY = Math.sin(self.rot);
	// Apply rotation to ship graphics
	shipGraphics.rotation = self.rot;
	self.update = function () {
		// Store last position
		self.lastX = self.x;
		self.lastY = self.y;
		// Handle rotation
		if (self.isRotatingLeft) {
			self.rot -= self.rotationSpeed;
		}
		if (self.isRotatingRight) {
			self.rot += self.rotationSpeed;
		}
		// Only update rotation visual when it changes to reduce unnecessary calculations
		if (self.lastRot !== self.rot) {
			shipGraphics.rotation = self.rot;
			self.lastRot = self.rot;
			// Pre-calculate direction vectors when rotation changes
			self.dirX = Math.cos(self.rot);
			self.dirY = Math.sin(self.rot);
		}
		// Use cached direction values
		// Apply thrust force in direction ship is facing (always moving)
		self.velocity.x += self.dirX * self.thrustPower;
		self.velocity.y += self.dirY * self.thrustPower;
		// Apply drag/friction
		self.velocity.x *= self.dragFactor;
		self.velocity.y *= self.dragFactor;
		// Calculate squared speed once for both checks
		var speedSquared = self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y;
		var maxSpeedSquared = self.maxSpeed * self.maxSpeed;
		// Only calculate actual speed when needed
		var speed = 0;
		if (speedSquared > maxSpeedSquared) {
			// Only calculate square root when we need to limit speed
			speed = Math.sqrt(speedSquared);
			// Apply speed limit
			var limitFactor = self.maxSpeed / speed;
			self.velocity.x *= limitFactor;
			self.velocity.y *= limitFactor;
			speed = self.maxSpeed;
		} else {
			// Approximate speed for particle effects without expensive sqrt
			speed = Math.abs(self.velocity.x) + Math.abs(self.velocity.y) * 0.5;
		}
		// Create thrust particles - optimize by creating fewer particles
		if (speed > 0.5 && LK.ticks % 6 == 0) {
			// Create particle every 6 ticks instead of 3 to reduce particle count
			var particle = new ThrustParticle();
			// Position at the back of the ship (opposite of direction)
			var backX = self.x - self.dirX * triangleSize * 0.5;
			var backY = self.y - self.dirY * triangleSize * 0.5;
			// Add some randomness
			backX += (Math.random() - 0.5) * 10;
			backY += (Math.random() - 0.5) * 10;
			particle.x = backX;
			particle.y = backY;
			// Set velocity opposite to ship direction with some randomness
			particle.velocity.x = -self.dirX * (1 + Math.random()) + (Math.random() - 0.5) * 0.5;
			particle.velocity.y = -self.dirY * (1 + Math.random()) + (Math.random() - 0.5) * 0.5;
			// Add to game via event
			if (typeof game.addThrustParticle === 'function') {
				game.addThrustParticle(particle);
			}
		}
		// Update position based on velocity
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Wrap around screen edges
		if (self.x < 0) {
			self.x = 2048;
		}
		if (self.x > 2048) {
			self.x = 0;
		}
		if (self.y < 0) {
			self.y = 2732;
		}
		if (self.y > 2732) {
			self.y = 0;
		}
		// Handle firing
		if (self.isFiring) {
			if (self.fireTimer <= 0) {
				self.fireTimer = self.fireDelay;
				return true; // Signal to create a bullet
			}
		}
		if (self.fireTimer > 0) {
			self.fireTimer--;
		}
		// Handle invulnerability
		if (self.invulnerable) {
			self.invulnerableTime--;
			shipGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
			if (self.invulnerableTime <= 0) {
				self.invulnerable = false;
				shipGraphics.alpha = 1;
			}
		}
		// Handle Aura cooldown and activation
		if (!self.auraReady && !self.auraActive) {
			self.auraCooldown++;
			// Calculate remaining cooldown for display
			self.remainingCooldown = self.auraCooldownMax - self.auraCooldown;
			if (self.auraCooldown >= self.auraCooldownMax) {
				self.auraReady = true;
				self.auraCooldown = 0;
				self.remainingCooldown = 0;
			}
		}
		// Handle active Aura effects
		if (self.auraActive) {
			// Pulse the ship with a white glow when aura is active
			shipGraphics.tint = 0xFFFFFF;
			self.auraActiveTime++;
			if (self.auraActiveTime >= self.auraActiveTimeMax) {
				self.auraActive = false;
				self.auraActiveTime = 0;
				shipGraphics.tint = 0xFFFFFF; // Reset tint
				// Start cooldown again
				self.auraCooldown = 0;
				self.auraReady = false;
			}
		} else {
			// Reset tint when aura is not active
			shipGraphics.tint = 0xFF8000;
		}
		return false;
	};
	self.makeInvulnerable = function (frames) {
		self.invulnerable = true;
		self.invulnerableTime = frames;
	};
	// Activate aura ability
	self.activateAura = function () {
		// Only activate if aura is ready
		if (self.auraReady) {
			self.auraActive = true;
			self.auraActiveTime = 0;
			self.auraReady = false;
			// Create visual effect - ship glows white
			tween(shipGraphics, {
				tint: 0xFFFFFF
			}, {
				duration: 200
			});
			return true;
		}
		return false;
	};
	return self;
});
var ThrustParticle = Container.expand(function () {
	var self = Container.call(this);
	// Create particle visual - larger and more visible
	var particleGraphics = LK.getAsset('bulletShape', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 32,
		// Further increased size for better visibility
		// Increased size
		height: 32,
		// Further increased size for better visibility
		// Increased size
		tint: 0xFFAA00 // Brighter orange-yellow for better visibility
	});
	particleGraphics.alpha = 1.0; // Fully opaque
	self.addChild(particleGraphics);
	// Particle properties
	self.velocity = {
		x: 0,
		y: 0
	};
	self.lifespan = 35; // Increased lifespan for better visibility
	self.age = 0;
	self.update = function () {
		// Move according to velocity
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Age the particle
		self.age++;
		// Fade out as it ages, with a faster tail-end fade
		var lifeRatio = self.age / self.lifespan;
		particleGraphics.alpha = 0.9 * (1 - lifeRatio * lifeRatio);
		// Return true if particle should be removed
		return self.age >= self.lifespan;
	};
	return self;
});
var WireframeBall = Container.expand(function () {
	var self = Container.call(this);
	self.edges = [];
	self.joints = [];
	self.ballRadius = 80;
	self.rotationX = 0;
	self.rotationY = 0;
	self.rotationZ = 0;
	self.rotationSpeedX = 0.02;
	self.rotationSpeedY = 0.025;
	self.rotationSpeedZ = 0.015;
	// Create cube vertices mapped to sphere surface
	var cubeVertices = [[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
	// back face
	[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1] // front face
	];
	// Normalize vertices to sphere surface
	for (var i = 0; i < cubeVertices.length; i++) {
		var vertex = cubeVertices[i];
		var length = Math.sqrt(vertex[0] * vertex[0] + vertex[1] * vertex[1] + vertex[2] * vertex[2]);
		vertex[0] = vertex[0] / length * self.ballRadius;
		vertex[1] = vertex[1] / length * self.ballRadius;
		vertex[2] = vertex[2] / length * self.ballRadius;
	}
	// Create cube edges (12 edges total)
	var cubeEdges = [[0, 1], [1, 2], [2, 3], [3, 0],
	// back face edges
	[4, 5], [5, 6], [6, 7], [7, 4],
	// front face edges
	[0, 4], [1, 5], [2, 6], [3, 7] // connecting edges
	];
	// Create wireframe edges
	for (var i = 0; i < cubeEdges.length; i++) {
		var edge = cubeEdges[i];
		var vertex1 = cubeVertices[edge[0]];
		var vertex2 = cubeVertices[edge[1]];
		var edgeElement = self.attachAsset('wireframeEdge', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Calculate edge center and rotation
		var centerX = (vertex1[0] + vertex2[0]) / 2;
		var centerY = (vertex1[1] + vertex2[1]) / 2;
		var centerZ = (vertex1[2] + vertex2[2]) / 2;
		var dx = vertex2[0] - vertex1[0];
		var dy = vertex2[1] - vertex1[1];
		var edgeLength = Math.sqrt(dx * dx + dy * dy);
		var rotation = Math.atan2(dy, dx);
		edgeElement.x = centerX;
		edgeElement.y = centerY;
		edgeElement.z = centerZ || 0;
		edgeElement.rotation = rotation;
		edgeElement.scaleY = edgeLength / 120; // Scale to fit edge length
		edgeElement.alpha = 0.8;
		edgeElement.originalX = centerX;
		edgeElement.originalY = centerY;
		edgeElement.originalZ = centerZ || 0;
		edgeElement.originalRotation = rotation;
		edgeElement.originalScaleY = edgeElement.scaleY;
		self.edges.push(edgeElement);
	}
	// Create joints at vertices
	for (var i = 0; i < cubeVertices.length; i++) {
		var vertex = cubeVertices[i];
		var joint = self.attachAsset('wireframeJoint', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		joint.x = vertex[0];
		joint.y = vertex[1];
		joint.z = vertex[2] || 0;
		joint.originalX = vertex[0];
		joint.originalY = vertex[1];
		joint.originalZ = vertex[2] || 0;
		joint.alpha = 0;
		joint.pulsePhase = Math.random() * Math.PI * 2;
		self.joints.push(joint);
	}
	self.project3D = function (x, y, z) {
		// Simple 3D to 2D projection with rotation
		var cosX = Math.cos(self.rotationX);
		var sinX = Math.sin(self.rotationX);
		var cosY = Math.cos(self.rotationY);
		var sinY = Math.sin(self.rotationY);
		var cosZ = Math.cos(self.rotationZ);
		var sinZ = Math.sin(self.rotationZ);
		// Rotate around X axis
		var y1 = y * cosX - z * sinX;
		var z1 = y * sinX + z * cosX;
		// Rotate around Y axis
		var x2 = x * cosY + z1 * sinY;
		var z2 = -x * sinY + z1 * cosY;
		// Rotate around Z axis
		var x3 = x2 * cosZ - y1 * sinZ;
		var y3 = x2 * sinZ + y1 * cosZ;
		return {
			x: x3,
			y: y3,
			z: z2
		};
	};
	self.update = function () {
		// Update rotation
		self.rotationX += self.rotationSpeedX;
		self.rotationY += self.rotationSpeedY;
		self.rotationZ += self.rotationSpeedZ;
		// Update edge positions with 3D rotation
		for (var i = 0; i < self.edges.length; i++) {
			var edge = self.edges[i];
			var projected = self.project3D(edge.originalX, edge.originalY, edge.originalZ);
			edge.x = projected.x;
			edge.y = projected.y;
			// Depth-based alpha and scale
			var depth = (projected.z + self.ballRadius) / (2 * self.ballRadius);
			edge.alpha = 0.4 + depth * 0.6;
			edge.scaleX = 0.6 + depth * 0.4;
			// Maintain original scale for length
			edge.scaleY = edge.originalScaleY * (0.8 + depth * 0.2);
		}
		// Update joints with pulsing effect
		for (var i = 0; i < self.joints.length; i++) {
			var joint = self.joints[i];
			var projected = self.project3D(joint.originalX, joint.originalY, joint.originalZ);
			joint.x = projected.x;
			joint.y = projected.y;
			var depth = (projected.z + self.ballRadius) / (2 * self.ballRadius);
			joint.pulsePhase += 0.08;
			joint.alpha = Math.max(0, depth * 0.9 * Math.sin(joint.pulsePhase));
			joint.scaleX = joint.scaleY = 0.7 + depth * 0.3 + Math.sin(joint.pulsePhase) * 0.15;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
// Function to add thrust particles - called from Ship update
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Placeholder ID, engine will assign
// Placeholder ID, engine will assign
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Assuming ID is correct
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Music Tracks - assuming unique IDs exist for each
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Meme explosion sounds - assuming unique IDs exist for each
// Placeholder: Replace with actual music ID
// Placeholder: Replace with actual music ID
// Placeholder: Replace with actual music ID
// Initialize music tracks
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Initialize meme explosion sounds
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Initialize music tracks
// Initialize meme explosion sounds
// Add music assets
// Add music assets
// Sounds for each meme type
// Game variables
// Add sound assets for each meme asteroid (meme0 to meme9)
// Sound for tapping to start
// Sound for starting a new level
// Sound for the rhythmic beat
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Engine will assign actual ID
// Engine will assign actual ID
// Added new meme image asset
// Added new meme explosion sound asset
// Object pools for performance optimization
var bulletPool = [];
var asteroidPool = [];
var thrustParticlePool = [];
var auraParticlePool = [];
var creeperAsteroidPool = [];
var ship;
var bullets = [];
var asteroids = [];
var thrustParticles = []; // Array to store thrust particles
var score = 0;
var lives = 3;
var level = 1;
var gameStarted = false;
var gameOver = false;
var introPlayed = false;
var introSequence = null;
var outroSequence = null;
var outroPlayed = false;
var highScore = 0; // This will be loaded from storage
var highScoreTxt; // UI element for displaying the high score
var newRecordShown = false; // Track if new record notification has been shown
var nextExtraLifeScore = 20000; // Score threshold for the next extra life
var extraLifeInterval = 20000; // Get an extra life every 20,000 points
var maxLives = 5; // Maximum number of lives a player can have
var triangleSize = 36; // Ship triangle size for bullet positioning (half of the size now)
// Creeper Zone variables
var inCreeperZone = false;
var creeperIntroSequence = null;
var creeperWaveCount = 0;
var creeperMaxWaves = 3; // Number of waves to complete the Creeper Zone
var glaudIntroSequence = null;
var glaudIntroPlayed = false;
// Function to play intro sequence
function playIntroSequence() {
	// Clear any existing game objects
	bullets = [];
	asteroids = [];
	thrustParticles = [];
	// Check if GLAUD intro has been played
	if (!glaudIntroPlayed) {
		// Start with GLAUD intro sequence
		glaudIntroSequence = new GlaudIntroSequence();
		game.addChild(glaudIntroSequence);
		// Setup handler for when GLAUD intro finishes
		LK.setInterval(function () {
			if (glaudIntroSequence && glaudIntroSequence.finished) {
				game.removeChild(glaudIntroSequence);
				glaudIntroSequence = null;
				glaudIntroPlayed = true;
				// After GLAUD intro, continue with main intro
				continueWithMainIntro();
				LK.clearInterval(this);
			}
		}, 100);
	} else {
		// Skip GLAUD intro and go directly to main intro
		continueWithMainIntro();
	}
}
function continueWithMainIntro() {
	// Play gameMusic3 for intro
	LK.playMusic('gameMusic3', {
		loop: true,
		fade: {
			start: 0,
			end: 1,
			duration: 1000
		}
	});
	introMusicPlayed = true;
	// Create and add intro sequence
	introSequence = new IntroSequence();
	game.addChild(introSequence);
	// Setup a handler for when intro is finished
	LK.setInterval(function () {
		if (introSequence && introSequence.finished) {
			game.removeChild(introSequence);
			introSequence = null;
			introPlayed = true;
			// Keep gameMusic3 playing - don't stop it
			// Start game immediately
			initGame();
			LK.clearInterval(this);
		}
	}, 100);
}
// UI elements
var leftButton;
var rightButton;
var fireButton;
var scoreTxt;
var livesTxt;
var levelTxt;
var startText;
// Initialize the game
function initGame() {
	// Reset the new record notification flag
	newRecordShown = false;
	// Reset extra life score tracking
	nextExtraLifeScore = 20000;
	// Initialize object pools
	initObjectPools();
	// Check if we need to play intro
	if (!gameStarted && !introPlayed) {
		playIntroSequence();
		return;
	}
	// Create ship
	ship = new Ship();
	ship.x = 2048 / 2;
	ship.y = 200; // Position at top middle
	ship.makeInvulnerable(120); // 2 seconds
	// Add visual effect to indicate ship is ready for movement
	tween(ship, {
		alpha: 0.5
	}, {
		duration: 500,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(ship, {
				alpha: 1
			}, {
				duration: 500,
				easing: tween.easeInOut
			});
		}
	});
	game.addChild(ship);
	// Create control buttons
	leftButton = new Button('rotateLeftButton');
	leftButton.x = 300; // Position on the left side
	leftButton.y = 2732 - 200; // Position at the bottom
	leftButton.scale.set(2, 2); // Make button bigger
	game.addChild(leftButton);
	// Fire button in the middle
	fireButton = new Button('fireButton');
	fireButton.x = 2048 / 2; // Position in middle
	fireButton.y = 2732 - 200; // Position at the bottom
	fireButton.scale.set(2, 2); // Make button bigger
	game.addChild(fireButton);
	// No forward button needed - ship will constantly move forward
	// Right rotation button
	rightButton = new Button('rotateRightButton');
	rightButton.x = 2048 - 300; // Position on the right side
	rightButton.y = 2732 - 200; // Position at the bottom
	rightButton.scale.set(2, 2); // Make button bigger
	game.addChild(rightButton);
	// Create UI text
	// Create Glaud text in orange
	var glaudText = new Text2('Glaud', {
		size: 60,
		fill: 0xFF8000 // Orange color
	});
	glaudText.anchor.set(1, 0); // Right-align text
	glaudText.x = -20; // Add padding from right edge
	glaudText.y = 0; // Position at very top
	LK.gui.topRight.addChild(glaudText);
	scoreTxt = new Text2('SCORE: 0', {
		size: 40,
		fill: 0xFFFFFF
	});
	scoreTxt.anchor.set(1, 0); // Right-align text
	scoreTxt.x = -20; // Add padding from right edge
	scoreTxt.y = 80; // Position further below the Glaud text
	LK.gui.topRight.addChild(scoreTxt);
	// Initialize high score from storage, defaulting to 0 if not found
	highScore = storage.highScore || 0;
	highScoreTxt = new Text2('BEST: ' + highScore, {
		size: 40,
		fill: 0xFFD700 // A nice gold color for the high score!
	});
	highScoreTxt.anchor.set(1, 0); // Right-align text
	highScoreTxt.x = -20; // Add padding from right edge, same as scoreTxt
	highScoreTxt.y = 140; // Position below scoreTxt
	LK.gui.topRight.addChild(highScoreTxt);
	// Create a container for lives display
	var livesContainer = new Container();
	livesContainer.x = 70;
	livesContainer.y = 50;
	LK.gui.top.addChild(livesContainer);
	// Add ship icons for lives instead of text
	var lifeIcons = [];
	for (var i = 0; i < 3; i++) {
		var lifeIcon = LK.getAsset('shipAsset', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 40,
			height: 40
		});
		lifeIcon.x = i * 50; // Space them horizontally
		livesContainer.addChild(lifeIcon);
		lifeIcons.push(lifeIcon);
	}
	// Store the icons and container for later access
	livesTxt = {
		icons: lifeIcons,
		container: livesContainer,
		update: function update(livesCount) {
			for (var i = 0; i < this.icons.length; i++) {
				this.icons[i].visible = i < livesCount;
			}
		}
	};
	levelTxt = new Text2('LEVEL: 1', {
		size: 40,
		fill: 0xFFFFFF
	});
	levelTxt.anchor.set(0, 0); // Left-align text
	levelTxt.x = 180; // Move further right from top-left menu icon but slightly to the left
	levelTxt.y = 80; // Move lower down from top edge
	LK.gui.topLeft.addChild(levelTxt);
	// Add developer feature - double-tap on level to advance
	var lastLevelTapTime = 0;
	var devModeActive = false;
	levelTxt.interactive = true;
	levelTxt.down = function (x, y, obj) {
		var currentTime = Date.now();
		// Check for double tap (within 300ms)
		if (currentTime - lastLevelTapTime < 300) {
			// Toggle dev mode on double tap
			devModeActive = !devModeActive;
			// Visual feedback that dev mode is active
			if (devModeActive) {
				// Initialize style property if it doesn't exist
				if (!levelTxt.style) {
					levelTxt.style = {};
				}
				levelTxt.style.fill = 0xFF8000; // Orange to indicate dev mode
				// Show dev mode activated message
				var devModeText = new Text2('DEV MODE ACTIVE!', {
					size: 40,
					fill: 0xFF8000
				});
				devModeText.anchor.set(0.5, 0.5);
				devModeText.x = 2048 / 2;
				devModeText.y = 2732 / 2;
				game.addChild(devModeText);
				// Fade out after 2 seconds
				tween(devModeText, {
					alpha: 0
				}, {
					duration: 1000,
					delay: 1000,
					onFinish: function onFinish() {
						game.removeChild(devModeText);
					}
				});
			} else {
				levelTxt.style.fill = 0xFFFFFF; // Reset to white when disabled
			}
		} else if (devModeActive) {
			// In dev mode, single tap advances the level
			// Clear existing asteroids
			for (var i = asteroids.length - 1; i >= 0; i--) {
				game.removeChild(asteroids[i]);
			}
			asteroids = [];
			// Advance to next level
			level++;
			levelTxt.setText('LEVEL: ' + level);
			LK.getSound('levelStart').play();
			// Create new asteroids for the next level
			createAsteroidsForLevel(level);
		}
		lastLevelTapTime = currentTime;
	};
	// Start screen text
	if (!gameStarted) {
		// Create gray background for start text
		var startBackground = new Container();
		var bgShape = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 1000,
			height: 250,
			tint: 0x333333
		});
		bgShape.alpha = 0.9;
		startBackground.addChild(bgShape);
		startText = new Text2('TAP TO START', {
			size: 140,
			// Slightly smaller size
			fill: 0xFFFFFF
		});
		startText.anchor.set(0.5, 0.5);
		startBackground.addChild(startText);
		LK.gui.center.addChild(startBackground);
	}
	// Clear any existing game objects
	bullets = [];
	asteroids = [];
	thrustParticles = [];
	// Initialize asteroids for the first level
	createAsteroidsForLevel(level);
}
function createAsteroidsForLevel(level) {
	// Number of asteroids based on level
	var numAsteroids = Math.min(4 + level, 12);
	for (var i = 0; i < numAsteroids; i++) {
		// Create a random meme type (0-13)
		var memeType = Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
		// Get asteroid from pool or create new one if pool is empty
		var asteroid = getFromPool(asteroidPool);
		if (!asteroid || asteroid.size !== 2) {
			// Try to find a size 2 asteroid specifically
			for (var j = 0; j < asteroidPool.length; j++) {
				if (!asteroidPool[j].active && asteroidPool[j].size === 2) {
					asteroid = asteroidPool[j];
					break;
				}
			}
			// If no size 2 asteroid found, create a new one
			if (!asteroid || asteroid.size !== 2) {
				asteroid = new Asteroid(2, memeType);
				game.addChild(asteroid);
				asteroidPool.push(asteroid);
			} else {
				// Reset properties of pooled asteroid
				asteroid.memeType = memeType;
			}
		} else {
			// Reset properties of pooled asteroid
			asteroid.memeType = memeType;
		}
		// Reset asteroid state
		asteroid.active = true;
		asteroid.visible = true;
		asteroid.justWrapped = false;
		// Re-initialize velocity
		var speed = (3 - asteroid.size) * 0.8 + 0.5;
		var angle = Math.random() * Math.PI * 2;
		asteroid.velocity = {
			x: Math.cos(angle) * speed,
			y: Math.sin(angle) * speed
		};
		asteroid.rotationSpeed = (Math.random() - 0.5) * 0.05;
		// Apply special behavior based on meme type
		if (memeType === 7) {
			// "This is Fine" meme - moves slower
			asteroid.velocity.x *= 0.6;
			asteroid.velocity.y *= 0.6;
		} else if (memeType === 9) {
			// "Stonks" meme - worth more points
			asteroid.getPoints = function () {
				return (3 - this.size) * 150; // 50% more points
			};
		} else if (memeType === 12) {
			// Fast meme
			asteroid.velocity.x *= 1.5;
			asteroid.velocity.y *= 1.5;
		}
		// Add difficulty scaling based on level
		if (level > 3) {
			// Scale asteroid speed with level
			var speedMultiplier = 1 + (level - 3) * 0.1; // 10% faster per level after 3
			speedMultiplier = Math.min(speedMultiplier, 1.5); // Cap at 50% faster
			asteroid.velocity.x *= speedMultiplier;
			asteroid.velocity.y *= speedMultiplier;
		}
		// Position the asteroid away from the player
		do {
			asteroid.x = Math.random() * 2048;
			asteroid.y = Math.random() * 2732;
		} while (distance(asteroid.x, asteroid.y, ship.x, ship.y) < 300);
		asteroids.push(asteroid);
	}
}
function distance(x1, y1, x2, y2) {
	return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
function createBullet() {
	// Get bullet from pool or create new one if pool is empty
	var bullet = getFromPool(bulletPool);
	if (!bullet) {
		bullet = new Bullet();
		game.addChild(bullet);
		bulletPool.push(bullet);
	}
	// Reset bullet properties
	bullet.age = 0;
	bullet.active = true;
	bullet.visible = true;
	// Use ship's rotation directly
	var angle = ship.rot;
	// Calculate the position at the tip of the ship based on the triangle geometry
	// For the redesigned ship (pointing up at 0 rotation), the tip is -triangleSize units in Y
	var offsetX = Math.cos(angle) * triangleSize;
	var offsetY = Math.sin(angle) * triangleSize;
	// Position bullet at the tip of the ship
	bullet.x = ship.x + offsetX;
	bullet.y = ship.y + offsetY;
	// Set bullet velocity to match ship's exact facing direction
	bullet.velocity.x = Math.cos(angle) * bullet.speed;
	bullet.velocity.y = Math.sin(angle) * bullet.speed;
	// Add bullet to active bullets array
	bullets.push(bullet);
	// Play shoot sound
	LK.getSound('shoot').play();
}
function updateAsteroids() {
	for (var i = asteroids.length - 1; i >= 0; i--) {
		var asteroid = asteroids[i];
		asteroid.update();
		// Check for collision with the ship
		if (!ship.invulnerable && asteroid.intersects(ship)) {
			// Player loses a life
			lives--;
			livesTxt.update(lives);
			// Play explosion sound
			LK.getSound('explosion').play();
			// Flash screen
			LK.effects.flashScreen(0xFF0000, 500);
			// Make ship invulnerable for a few seconds
			ship.makeInvulnerable(180);
			// Game over if no lives left
			if (lives <= 0) {
				// Check if the current score is a new high score
				if (score > highScore) {
					highScore = score; // Update our game's high score variable
					storage.highScore = highScore; // Persist the new high score
					// The highScoreTxt will update automatically on game restart via initGame
					// Display a motivational message about the new high score
					var newHighScoreText = new Text2('NEW HIGH SCORE! AMAZING WORK!', {
						size: 60,
						fill: 0xFFD700 // Gold color
					});
					newHighScoreText.anchor.set(0.5, 0.5);
					newHighScoreText.x = 2048 / 2;
					newHighScoreText.y = 2732 / 2 - 150;
					LK.gui.center.addChild(newHighScoreText);
					// Animate the text
					tween(newHighScoreText, {
						scaleX: 1.2,
						scaleY: 1.2
					}, {
						duration: 500,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							tween(newHighScoreText, {
								scaleX: 1,
								scaleY: 1
							}, {
								duration: 500,
								easing: tween.easeIn
							});
						}
					});
					// Remove the text after 3 seconds
					LK.setTimeout(function () {
						LK.gui.center.removeChild(newHighScoreText);
					}, 3000);
				} else {
					// Display a motivational message for not beating the high score
					var motivationalText = new Text2('YOU\'LL GET IT NEXT TIME!', {
						size: 60,
						fill: 0x3399FF // Blue color
					});
					motivationalText.anchor.set(0.5, 0.5);
					motivationalText.x = 2048 / 2;
					motivationalText.y = 2732 / 2 - 150;
					LK.gui.center.addChild(motivationalText);
					// Animate the text
					tween(motivationalText, {
						alpha: 0.7
					}, {
						duration: 800,
						easing: tween.easeInOut,
						onFinish: function onFinish() {
							tween(motivationalText, {
								alpha: 1
							}, {
								duration: 800,
								easing: tween.easeInOut
							});
						}
					});
					// Remove the text after 3 seconds
					LK.setTimeout(function () {
						LK.gui.center.removeChild(motivationalText);
					}, 3000);
				}
				LK.setScore(score); // Set the score for the platform's game over UI
				// Start the outro sequence instead of showing game over immediately
				playOutroSequence();
				gameOver = true;
				return;
			}
		}
	}
}
function updateBullets() {
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		bullet.update();
		// Remove bullets that have lived too long
		if (bullet.age > bullet.lifespan) {
			// Return bullet to pool instead of removing
			bullet.active = false;
			bullet.visible = false;
			bullets.splice(i, 1);
			continue;
		}
		// Check for collisions with asteroids
		var hitAsteroid = false;
		for (var j = asteroids.length - 1; j >= 0; j--) {
			var asteroid = asteroids[j];
			// Skip intersection check if asteroid just wrapped (reduces false positives)
			if (asteroid.justWrapped) {
				continue;
			}
			if (bullet.intersects(asteroid)) {
				hitAsteroid = true;
				// Add score based on asteroid size
				score += asteroid.getPoints();
				scoreTxt.setText('SCORE: ' + score);
				// Check if player earned an extra life
				if (score >= nextExtraLifeScore) {
					// Set next threshold regardless of whether we can get a life
					nextExtraLifeScore += extraLifeInterval;
					// Only award an extra life if below maximum
					if (lives < maxLives) {
						// Award an extra life
						lives++;
						// Update lives display
						livesTxt.update(lives);
						// Show extra life notification
						var extraLifeText = new Text2('EXTRA LIFE!', {
							size: 80,
							fill: 0x00FF00 // Bright green
						});
						extraLifeText.anchor.set(0.5, 0.5);
						extraLifeText.x = 2048 / 2;
						extraLifeText.y = 2732 / 2 - 200;
						extraLifeText.alpha = 0;
						game.addChild(extraLifeText);
						// Animate the notification
						tween(extraLifeText, {
							alpha: 1,
							scaleX: 1.3,
							scaleY: 1.3
						}, {
							duration: 500,
							easing: tween.elasticOut,
							onFinish: function onFinish() {
								// Wait 2 seconds before fading out
								LK.setTimeout(function () {
									tween(extraLifeText, {
										alpha: 0
									}, {
										duration: 1000,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											game.removeChild(extraLifeText);
										}
									});
								}, 2000);
							}
						});
						// Play a positive sound for extra life
						LK.getSound('levelStart').play();
					}
				}
				// Check if player just beat the high score and notification hasn't been shown yet
				if (score > highScore && score - asteroid.getPoints() <= highScore && !newRecordShown) {
					// Set flag to true so we don't show it again this game
					newRecordShown = true;
					// Create a temporary notification
					var newRecordText = new Text2('NEW RECORD!', {
						size: 80,
						fill: 0xFFD700 // Gold color
					});
					newRecordText.anchor.set(0.5, 0.5);
					newRecordText.x = 2048 / 2;
					newRecordText.y = 2732 / 2;
					newRecordText.alpha = 0;
					game.addChild(newRecordText);
					// Animate the notification
					tween(newRecordText, {
						alpha: 1,
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 500,
						easing: tween.elasticOut,
						onFinish: function onFinish() {
							// Wait 5 seconds before fading out
							LK.setTimeout(function () {
								tween(newRecordText, {
									alpha: 0
								}, {
									duration: 1500,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										game.removeChild(newRecordText);
									}
								});
							}, 5000);
						}
					});
					// Update high score
					highScore = score;
					highScoreTxt.setText('BEST: ' + highScore);
				}
				// Special handling for Creeper asteroids in Creeper Zone
				if (inCreeperZone && asteroid.isExplosive) {
					// Call the explode method
					asteroid.explode();
					// Check if ship is within explosion radius
					var dist = distance(asteroid.x, asteroid.y, ship.x, ship.y);
					if (dist <= asteroid.explosionRadius && !ship.invulnerable) {
						// Player loses a life if within explosion radius
						lives--;
						livesTxt.update(lives);
						// Flash screen green
						LK.effects.flashScreen(0x88FF88, 300);
						// Make ship invulnerable
						ship.makeInvulnerable(180);
						// Game over if no lives left
						if (lives <= 0) {
							if (score > highScore) {
								highScore = score;
								storage.highScore = highScore;
							}
							LK.setScore(score);
							playOutroSequence();
							gameOver = true;
							return;
						}
					}
					// Remove the asteroid
					game.removeChild(asteroid);
					asteroids.splice(j, 1);
					break;
				} else {
					// Get the asteroid's meme type, defaulting to 0 if undefined
					var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0;
					// Construct the specific meme explosion sound ID
					var memeExplosionSoundId = 'meme' + memeType + 'Explosion';
					// Try to get the specific meme explosion sound
					var explosionSound = LK.getSound(memeExplosionSoundId);
					// Play the specific meme explosion sound or fallback to generic explosion
					if (explosionSound) {
						explosionSound.play();
					} else {
						// Fallback to generic explosion sound
						console.log('Fallback explosion sound for memeType:', memeType);
						LK.getSound('explosion').play();
					}
					// Break large asteroids (size 2) into smaller pieces
					if (asteroid.size === 2) {
						for (var k = 0; k < 2; k++) {
							// Get medium asteroid from pool or create new one
							var newAsteroid = null;
							// Try to find a size 1 asteroid in the pool
							for (var p = 0; p < asteroidPool.length; p++) {
								if (!asteroidPool[p].active && asteroidPool[p].size === 1) {
									newAsteroid = asteroidPool[p];
									break;
								}
							}
							// If no pooled asteroid found, create a new one
							if (!newAsteroid) {
								newAsteroid = new Asteroid(1, asteroid.memeType);
								game.addChild(newAsteroid);
								asteroidPool.push(newAsteroid);
							} else {
								// Reset pooled asteroid properties
								newAsteroid.memeType = asteroid.memeType;
								// Reset velocity
								var speed = 0.8 * 2 + 0.5; // Speed for medium asteroid
								var angle = Math.random() * Math.PI * 2;
								newAsteroid.velocity = {
									x: Math.cos(angle) * speed,
									y: Math.sin(angle) * speed
								};
								newAsteroid.rotationSpeed = (Math.random() - 0.5) * 0.05;
							}
							newAsteroid.active = true;
							newAsteroid.visible = true;
							newAsteroid.justWrapped = false;
							newAsteroid.x = asteroid.x;
							newAsteroid.y = asteroid.y;
							asteroids.push(newAsteroid);
						}
					}
					// Return hit asteroid to pool instead of removing
					asteroid.active = false;
					asteroid.visible = false;
					asteroids.splice(j, 1);
					break;
				}
			}
		}
		if (hitAsteroid) {
			// Return bullet to pool instead of removing
			bullet.active = false;
			bullet.visible = false;
			bullets.splice(i, 1);
		}
	}
	// Check if all asteroids are destroyed
	if (asteroids.length === 0) {
		// Special handling for Creeper Zone
		if (inCreeperZone) {
			creeperWaveCount++;
			// Check if we've completed all Creeper Zone waves
			if (creeperWaveCount >= creeperMaxWaves) {
				// End Creeper Zone and continue to next level
				inCreeperZone = false;
				// Show "Area Clear" message
				var areaClearText = new Text2('AREA CLEAR!', {
					size: 80,
					fill: 0x88FF88 // Green text
				});
				areaClearText.anchor.set(0.5, 0.5);
				areaClearText.x = 2048 / 2;
				areaClearText.y = 2732 / 2;
				areaClearText.alpha = 0;
				game.addChild(areaClearText);
				// Animate the message
				tween(areaClearText, {
					alpha: 1,
					scaleX: 1.5,
					scaleY: 1.5
				}, {
					duration: 500,
					easing: tween.elasticOut,
					onFinish: function onFinish() {
						LK.setTimeout(function () {
							tween(areaClearText, {
								alpha: 0
							}, {
								duration: 1000,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									game.removeChild(areaClearText);
								}
							});
						}, 2000);
					}
				});
				// Return to normal music
				LK.playMusic('gameMusic3', {
					loop: true,
					fade: {
						start: 0,
						end: 1,
						duration: 1000
					}
				});
				// Move to level 10
				level = 10;
				levelTxt.setText('LEVEL: ' + level);
				// Play level start sound
				LK.getSound('levelStart').play();
				// Create new asteroids for the next level
				createAsteroidsForLevel(level);
			} else {
				// Create next wave of creeper asteroids
				var wavesLeft = creeperMaxWaves - creeperWaveCount;
				// Display wave counter
				var waveText = new Text2('WAVE ' + creeperWaveCount + ' COMPLETE! ' + wavesLeft + ' TO GO!', {
					size: 60,
					fill: 0xFFFFFF
				});
				waveText.anchor.set(0.5, 0.5);
				waveText.x = 2048 / 2;
				waveText.y = 2732 / 2;
				game.addChild(waveText);
				// Fade out after 2 seconds
				tween(waveText, {
					alpha: 0
				}, {
					duration: 1000,
					delay: 2000,
					onFinish: function onFinish() {
						game.removeChild(waveText);
					}
				});
				// Create next wave - increase count with each wave
				createCreeperAsteroids(5 + creeperWaveCount);
			}
		} else if (level === 9) {
			// Start Creeper Zone after level 9
			startCreeperZone();
		} else {
			// Normal level progression
			// Next level
			level++;
			levelTxt.setText('LEVEL: ' + level);
			// Play level start sound
			LK.getSound('levelStart').play();
			// Ensure gameMusic3 keeps playing - no music track changes
			if (!musicPlaying) {
				// If music isn't playing for some reason, restart gameMusic3
				LK.playMusic('gameMusic3', {
					loop: true,
					fade: {
						start: 0,
						end: 1,
						duration: 1000
					}
				});
				musicPlaying = true;
			}
			// Create new asteroids for the next level
			createAsteroidsForLevel(level);
		}
	}
}
// Main game update function
game.update = function () {
	// Update GLAUD intro sequence if active
	if (glaudIntroSequence) {
		glaudIntroSequence.update();
		return;
	}
	// Update intro sequence if active
	if (introSequence) {
		introSequence.update();
		return;
	}
	// Update Creeper Zone intro if active
	if (creeperIntroSequence) {
		creeperIntroSequence.update();
		return;
	}
	// Update outro sequence if active
	if (outroSequence) {
		outroSequence.update();
		return;
	}
	if (!gameStarted) {
		return;
	}
	// Update ship controls based on button state
	ship.isRotatingLeft = leftButton.isPressed;
	ship.isRotatingRight = rightButton.isPressed;
	ship.isFiring = fireButton.isPressed;
	// Update aura ready text on fire button with cooldown info
	fireButton.updateAuraText(ship.auraReady, ship.remainingCooldown);
	// Ship constantly moves forward, no need for isMoving toggle
	// Update ship
	if (ship.update()) {
		if (ship.auraReady) {
			// If aura is ready and firing, activate aura and create bullet
			if (ship.activateAura()) {
				// Destroy nearby asteroids when aura is activated
				destroyNearbyAsteroids();
				// Visual effect for aura activation
				createAuraEffectParticles();
				// Sound effect for aura activation
				LK.getSound('shoot').play();
			}
		}
		createBullet();
	}
	// Update bullets and check for collisions
	updateBullets();
	// Update asteroids and check for collisions
	updateAsteroids();
	// Update thrust particles
	updateThrustParticles();
};
// Game music and sound state variables
var currentMusicTrack = 0; // Initialize to 0, will be set to 1 on game start
var musicPlaying = false; // Track if music is currently playing
var introMusicPlayed = false; // Track if intro music has played
// Event handlers
game.down = function (x, y, obj) {
	// Check if GLAUD intro is playing
	if (glaudIntroSequence && !glaudIntroSequence.finished) {
		glaudIntroSequence.finished = true;
		return;
	}
	// Check if intro is playing
	if (introSequence && !introSequence.finished) {
		introSequence.skip();
		return;
	}
	// Check if Creeper Zone intro is playing - but don't allow skipping
	if (creeperIntroSequence && !creeperIntroSequence.finished) {
		// Don't allow skipping the creeper intro
		return;
	}
	// Check if outro is playing and can be exited
	if (outroSequence) {
		if (outroSequence.canExit) {
			outroSequence.skip();
		}
		return;
	}
	if (!gameStarted) {
		gameStarted = true;
		LK.getSound('gameStart').play(); // Play start sound
		if (startText && startText.parent) {
			startText.parent.parent.removeChild(startText.parent);
			startText = null;
		}
		// Only play gameMusic3
		LK.playMusic('gameMusic3', {
			loop: true,
			fade: {
				start: 0,
				end: 1,
				duration: 800
			}
		});
		// Set current track to match
		currentMusicTrack = 3;
		musicPlaying = true;
	}
	// Ensure buttons can detect touch events when pressed
	var local;
	var touchConsumed = false;
	// Check if we tapped on level text for dev mode
	if (levelTxt && levelTxt.getBounds) {
		var levelBounds = levelTxt.getBounds();
		// Check if tap is within level text bounds
		if (x >= levelBounds.x && x <= levelBounds.x + levelBounds.width && y >= levelBounds.y && y <= levelBounds.y + levelBounds.height) {
			// Let the level text handle the tap through its own down method
			levelTxt.down(x, y, obj);
			touchConsumed = true;
		}
	}
	// Check left button
	if (!touchConsumed) {
		local = leftButton.toLocal({
			x: x,
			y: y
		});
		if (local.x >= -leftButton.width / 2 && local.x <= leftButton.width / 2 && local.y >= -leftButton.height / 2 && local.y <= leftButton.height / 2) {
			leftButton.down(local.x, local.y, {});
			touchConsumed = true;
		}
	}
	// Check fire button only if touch not already consumed
	if (!touchConsumed) {
		local = fireButton.toLocal({
			x: x,
			y: y
		});
		if (local.x >= -fireButton.width / 2 && local.x <= fireButton.width / 2 && local.y >= -fireButton.height / 2 && local.y <= fireButton.height / 2) {
			fireButton.down(local.x, local.y, {});
			touchConsumed = true;
		}
	}
	// Check right button only if touch not already consumed
	if (!touchConsumed) {
		local = rightButton.toLocal({
			x: x,
			y: y
		});
		if (local.x >= -rightButton.width / 2 && local.x <= rightButton.width / 2 && local.y >= -rightButton.height / 2 && local.y <= rightButton.height / 2) {
			rightButton.down(local.x, local.y, {});
			touchConsumed = true;
		}
	}
	// Only fire a bullet if no button was pressed and game is active
	if (!touchConsumed && gameStarted && ship && !gameOver) {
		createBullet();
	}
};
// Add up handler to handle releasing buttons
game.up = function (x, y, obj) {
	// Reset all button states when touch/click is released
	// Safely call button handlers by checking if they exist first
	if (leftButton && typeof leftButton.up === 'function') {
		leftButton.up(0, 0, {});
	}
	if (fireButton && typeof fireButton.up === 'function') {
		fireButton.up(0, 0, {});
	}
	if (rightButton && typeof rightButton.up === 'function') {
		rightButton.up(0, 0, {});
	}
};
// Initialize object pools with pre-populated objects
function initObjectPools() {
	// Clear existing pools
	bulletPool = [];
	asteroidPool = [];
	thrustParticlePool = [];
	auraParticlePool = [];
	creeperAsteroidPool = [];
	// Pre-populate bullet pool (30 bullets should be enough for most gameplay)
	for (var i = 0; i < 30; i++) {
		var bullet = new Bullet();
		bullet.visible = false;
		bullet.active = false;
		bulletPool.push(bullet);
		game.addChild(bullet);
	}
	// Pre-populate asteroid pool (30 for all sizes)
	for (var i = 0; i < 10; i++) {
		// Large asteroids (size 2)
		var asteroid = new Asteroid(2);
		asteroid.visible = false;
		asteroid.active = false;
		asteroidPool.push(asteroid);
		game.addChild(asteroid);
		// Medium asteroids (size 1)
		asteroid = new Asteroid(1);
		asteroid.visible = false;
		asteroid.active = false;
		asteroidPool.push(asteroid);
		game.addChild(asteroid);
		// Small asteroids (size 0)
		asteroid = new Asteroid(0);
		asteroid.visible = false;
		asteroid.active = false;
		asteroidPool.push(asteroid);
		game.addChild(asteroid);
	}
	// Pre-populate thrust particle pool (50 particles)
	for (var i = 0; i < 50; i++) {
		var particle = new ThrustParticle();
		particle.visible = false;
		particle.active = false;
		thrustParticlePool.push(particle);
		game.addChild(particle);
	}
	// Pre-populate aura particle pool (24 particles)
	for (var i = 0; i < 24; i++) {
		var auraParticle = new AuraParticle();
		auraParticle.visible = false;
		auraParticle.active = false;
		auraParticlePool.push(auraParticle);
		game.addChild(auraParticle);
	}
	// Pre-populate creeper asteroid pool (15 creepers)
	for (var i = 0; i < 15; i++) {
		var creeper = new CreeperAsteroid();
		creeper.visible = false;
		creeper.active = false;
		creeperAsteroidPool.push(creeper);
		game.addChild(creeper);
	}
}
// Initialize the game when this script runs
initGame();
// Function to add thrust particles - called from Ship update
game.addThrustParticle = function (particle) {
	// If particle is from pool, just activate it
	if (particle.active === false) {
		particle.active = true;
		particle.visible = true;
		thrustParticles.push(particle);
		// Don't need to add to game since it's already a child
	} else {
		// If it's a new particle, try to get one from the pool first
		var pooledParticle = getFromPool(thrustParticlePool);
		if (pooledParticle) {
			// Reset particle properties
			pooledParticle.x = particle.x;
			pooledParticle.y = particle.y;
			pooledParticle.velocity.x = particle.velocity.x;
			pooledParticle.velocity.y = particle.velocity.y;
			pooledParticle.age = 0;
			pooledParticle.active = true;
			pooledParticle.visible = true;
			thrustParticles.push(pooledParticle);
		} else {
			// If pool is empty, use the provided particle
			thrustParticles.push(particle);
			game.addChild(particle);
		}
	}
};
// Helper function to get object from pool
function getFromPool(pool) {
	for (var i = 0; i < pool.length; i++) {
		if (!pool[i].active) {
			return pool[i];
		}
	}
	return null; // Pool is empty
}
// Function to update thrust particles
function updateThrustParticles() {
	for (var i = thrustParticles.length - 1; i >= 0; i--) {
		var particle = thrustParticles[i];
		// If particle update returns true, it means the particle should be removed
		if (particle.update()) {
			// Return particle to pool instead of removing
			particle.active = false;
			particle.visible = false;
			thrustParticles.splice(i, 1);
		}
	}
}
// Function to destroy asteroids near the ship when aura is activated
function destroyNearbyAsteroids() {
	var auraRadius = 350; // Slightly reduced radius for better balance
	// Create a visual ring effect for the aura
	var auraRing = new Container();
	var auraRingGraphic = LK.getAsset('forwardButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: auraRadius * 2,
		height: auraRadius * 2,
		tint: 0x40E0D0 // Turquoise color to match AuraParticle
	});
	auraRingGraphic.alpha = 0.7;
	auraRing.addChild(auraRingGraphic);
	auraRing.x = ship.x;
	auraRing.y = ship.y;
	game.addChild(auraRing);
	// Animate the aura ring expanding then fading
	tween(auraRingGraphic, {
		alpha: 0,
		width: auraRadius * 2.5,
		height: auraRadius * 2.5
	}, {
		duration: 1200,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			game.removeChild(auraRing);
		}
	});
	// Flash the ship with turquoise
	tween(ship, {
		alpha: 0.8
	}, {
		duration: 200,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(ship, {
				alpha: 1
			}, {
				duration: 200,
				easing: tween.easeInOut
			});
		}
	});
	// Check all asteroids and destroy ones within the aura radius
	for (var i = asteroids.length - 1; i >= 0; i--) {
		var asteroid = asteroids[i];
		var dist = distance(ship.x, ship.y, asteroid.x, asteroid.y);
		if (dist <= auraRadius) {
			// Different behavior based on asteroid size
			if (asteroid.size === 2) {
				// Large asteroids: Break into medium asteroids and score points
				score += asteroid.getPoints();
				scoreTxt.setText('SCORE: ' + score);
				// Play the specific meme explosion sound
				var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0;
				var memeExplosionSoundId = 'meme' + memeType + 'Explosion';
				var explosionSound = LK.getSound(memeExplosionSoundId);
				if (explosionSound) {
					explosionSound.play();
				} else {
					LK.getSound('explosion').play();
				}
				// Create medium asteroids
				for (var k = 0; k < 2; k++) {
					var newAsteroid = new Asteroid(1, asteroid.memeType);
					newAsteroid.x = asteroid.x + (Math.random() - 0.5) * 50;
					newAsteroid.y = asteroid.y + (Math.random() - 0.5) * 50;
					asteroids.push(newAsteroid);
					game.addChild(newAsteroid);
				}
				// Remove the large asteroid
				game.removeChild(asteroid);
				asteroids.splice(i, 1);
			} else {
				// Small and medium asteroids: Destroy completely and score double points
				score += asteroid.getPoints() * 2; // Double points for small/medium
				scoreTxt.setText('SCORE: ' + score);
				// Play explosion sound
				var memeTypeSmall = asteroid.memeType !== undefined ? asteroid.memeType : 0;
				var explosionSoundId = 'meme' + memeTypeSmall + 'Explosion';
				var expSound = LK.getSound(explosionSoundId);
				if (expSound) {
					expSound.play();
				} else {
					LK.getSound('explosion').play();
				}
				// Remove the asteroid
				game.removeChild(asteroid);
				asteroids.splice(i, 1);
			}
		}
	}
	// Check if all asteroids are destroyed after aura
	if (asteroids.length === 0) {
		// Next level
		level++;
		levelTxt.setText('LEVEL: ' + level);
		LK.getSound('levelStart').play();
		createAsteroidsForLevel(level);
	}
}
// Function to create particle effects when aura is activated
function createAuraEffectParticles() {
	// Create a burst of particles from the ship - reduced for better performance
	for (var i = 0; i < 24; i++) {
		// Get particle from pool or create new one
		var particle = getFromPool(auraParticlePool);
		if (!particle) {
			particle = new AuraParticle();
			game.addChild(particle);
			auraParticlePool.push(particle);
		}
		// Reset particle properties
		particle.age = 0;
		particle.active = true;
		particle.visible = true;
		// Calculate angle for circular burst
		var angle = i * (Math.PI * 2 / 24);
		// Position at the ship
		particle.x = ship.x;
		particle.y = ship.y;
		// Set velocity in all directions with varying speeds
		var speed = 4 + Math.random() * 5; // Variable speeds for more organic look
		particle.velocity.x = Math.cos(angle) * speed;
		particle.velocity.y = Math.sin(angle) * speed;
		// Add to active particles
		thrustParticles.push(particle);
	}
	// Create a flash effect
	LK.effects.flashObject(ship, 0x40E0D0, 500);
}
// Create Creeper Zone asteroids
function createCreeperAsteroids(count) {
	// Create a specific number of creeper asteroids
	count = count || 5; // Default to 5 if not specified
	for (var i = 0; i < count; i++) {
		// Get creeper from pool or create new one
		var creeper = getFromPool(creeperAsteroidPool);
		if (!creeper) {
			creeper = new CreeperAsteroid();
			game.addChild(creeper);
			creeperAsteroidPool.push(creeper);
		}
		// Reset creeper properties
		creeper.active = true;
		creeper.visible = true;
		// Reset velocity
		var speed = 0.9;
		var angle = Math.random() * Math.PI * 2;
		creeper.velocity = {
			x: Math.cos(angle) * speed,
			y: Math.sin(angle) * speed
		};
		creeper.rotationSpeed = (Math.random() - 0.5) * 0.03;
		creeper.pulseDirection = 1;
		creeper.pulseAmount = 0;
		// Position the creeper away from the player
		do {
			creeper.x = Math.random() * 2048;
			creeper.y = Math.random() * 2732;
		} while (distance(creeper.x, creeper.y, ship.x, ship.y) < 350);
		asteroids.push(creeper);
	}
}
// Start the special Creeper Zone level
function startCreeperZone() {
	// Set Creeper Zone flag
	inCreeperZone = true;
	creeperWaveCount = 0;
	// Clear any existing asteroids
	for (var i = asteroids.length - 1; i >= 0; i--) {
		game.removeChild(asteroids[i]);
	}
	asteroids = [];
	// Change music to the more tense gameMusic2
	LK.playMusic('gameMusic2', {
		loop: true,
		fade: {
			start: 0,
			end: 1,
			duration: 1000
		}
	});
	// Create and play intro sequence
	creeperIntroSequence = new CreeperIntroSequence();
	game.addChild(creeperIntroSequence);
	// Setup handler for when intro finishes
	LK.setInterval(function () {
		if (creeperIntroSequence && creeperIntroSequence.finished) {
			game.removeChild(creeperIntroSequence);
			creeperIntroSequence = null;
			// Start the first wave of creeper asteroids
			createCreeperAsteroids(5); // First wave has 5 creepers
			LK.clearInterval(this);
		}
	}, 100);
}
// Function to play outro sequence
function playOutroSequence() {
	// Stop game music and start outro music
	LK.playMusic('outroMusic', {
		loop: true,
		fade: {
			start: 0,
			end: 1,
			duration: 1000
		}
	});
	// Create and add outro sequence
	outroSequence = new OutroSequence();
	game.addChild(outroSequence);
	// Setup a handler for when outro is finished
	LK.setInterval(function () {
		if (outroSequence && outroSequence.finished) {
			game.removeChild(outroSequence);
			outroSequence = null;
			outroPlayed = true;
			// Finally show game over screen when player closes outro
			LK.showGameOver();
			LK.clearInterval(this);
		}
	}, 100);
}
; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var AnimatedLetter = Container.expand(function (letter, targetX, targetY, index) {
	var self = Container.call(this);
	self.letterText = new Text2(letter, {
		size: 200,
		fill: 0xFFFFFF
	});
	self.letterText.anchor.set(0.5, 0.5);
	self.addChild(self.letterText);
	self.targetX = targetX;
	self.targetY = targetY;
	self.index = index;
	self.x = 2048 / 2;
	self.y = targetY + 150;
	self.alpha = 0;
	self.letterText.scaleX = 0.3;
	self.letterText.scaleY = 0.3;
	self.letterText.rotation = Math.PI * 0.5;
	self.animateIn = function () {
		// Slide from center to target position with fade in
		tween(self, {
			alpha: 1,
			x: self.targetX,
			y: self.targetY
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
		// Scale and rotate into place
		tween(self.letterText, {
			scaleX: 1,
			scaleY: 1,
			rotation: 0
		}, {
			duration: 1200,
			easing: tween.elasticOut
		});
	};
	self.transformColor = function (delay) {
		// Staggered color transformation with delay
		LK.setTimeout(function () {
			// Add subtle pulse before color change
			tween(self.letterText, {
				scaleX: 1.1,
				scaleY: 1.1
			}, {
				duration: 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(self.letterText, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 200,
						easing: tween.easeIn
					});
				}
			});
			// Color transformation wave
			tween(self.letterText, {
				tint: 0xff8000
			}, {
				duration: 800,
				easing: tween.easeInOut
			});
		}, delay);
	};
	return self;
});
var Asteroid = Container.expand(function (size, memeType) {
	var self = Container.call(this);
	// Size can be 0 (small), 1 (medium), or 2 (large)
	self.size = size || 2;
	// Create a container for the asteroid
	var asteroidGraphics = new Container();
	self.addChild(asteroidGraphics);
	// Store the meme type or generate a random one if not provided
	self.memeType = memeType !== undefined ? memeType : Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
	// Create the asteroid image based on size
	var assetId;
	if (self.size === 0) {
		assetId = 'memeSmall';
	} else if (self.size === 1) {
		assetId = 'memeMedium';
	} else {
		assetId = 'meme' + self.memeType;
	}
	// Add the meme image as the asteroid
	var memeImage = LK.getAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	asteroidGraphics.addChild(memeImage);
	// Random velocity
	var speed = (3 - self.size) * 0.8 + 0.5; // Smaller asteroids move faster
	var angle = Math.random() * Math.PI * 2;
	self.velocity = {
		x: Math.cos(angle) * speed,
		y: Math.sin(angle) * speed
	};
	// Random rotation
	self.rotationSpeed = (Math.random() - 0.5) * 0.05;
	self.update = function () {
		// Move
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Rotate
		asteroidGraphics.rotation += self.rotationSpeed;
		// Wrap around screen edges - optimize by only checking when needed
		if (self.x < -50) {
			self.x = 2098;
			self.justWrapped = true;
		} else if (self.x > 2098) {
			self.x = -50;
			self.justWrapped = true;
		} else if (self.y < -50) {
			self.y = 2782;
			self.justWrapped = true;
		} else if (self.y > 2782) {
			self.y = -50;
			self.justWrapped = true;
		} else {
			self.justWrapped = false;
		}
	};
	self.getPoints = function () {
		return (3 - self.size) * 100; // Small: 300, Medium: 200, Large: 100
	};
	return self;
});
var AuraParticle = Container.expand(function () {
	var self = Container.call(this);
	// Create particle visual - turquoise and larger than thrust particles
	var particleGraphics = LK.getAsset('bulletShape', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 36,
		// Larger than thrust particles
		height: 36,
		tint: 0x40E0D0 // Turquoise color for aura
	});
	particleGraphics.alpha = 1.0;
	self.addChild(particleGraphics);
	// Particle properties
	self.velocity = {
		x: 0,
		y: 0
	};
	self.lifespan = 45; // Longer lifespan than thrust particles
	self.age = 0;
	self.update = function () {
		// Move according to velocity
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Age the particle
		self.age++;
		// Pulse the particle size for more dynamic effect
		var pulseScale = 1 + 0.2 * Math.sin(self.age * 0.2);
		particleGraphics.scale.set(pulseScale, pulseScale);
		// Fade out as it ages, with a faster tail-end fade
		var lifeRatio = self.age / self.lifespan;
		particleGraphics.alpha = 0.9 * (1 - lifeRatio * lifeRatio);
		// Return true if particle should be removed
		return self.age >= self.lifespan;
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	// Create a container for pixel art bullet
	var bulletGraphics = new Container();
	self.addChild(bulletGraphics);
	// Create a solid bullet (a single large pixel)
	var bulletSize = 60; // Size of the bullet - increased to 60 for better visibility
	// Create a single solid element for the bullet
	var bulletSprite = LK.getAsset('bulletShape', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: bulletSize,
		height: bulletSize,
		tint: 0xFFFF00 // Bright yellow color for better visibility
	});
	bulletGraphics.addChild(bulletSprite);
	self.speed = 10;
	self.velocity = {
		x: 0,
		y: 0
	};
	self.lifespan = 180; // 3 seconds at 60fps - triple the firing range
	self.age = 0;
	self.update = function () {
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		self.age++;
		// Wrap around screen edges - use else-if to avoid redundant checks
		if (self.x < 0) {
			self.x = 2048;
		} else if (self.x > 2048) {
			self.x = 0;
		}
		if (self.y < 0) {
			self.y = 2732;
		} else if (self.y > 2732) {
			self.y = 0;
		}
	};
	return self;
});
var Button = Container.expand(function (assetId) {
	var self = Container.call(this);
	// Create button as a solid shape
	var buttonGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2,
		scaleY: 2
	});
	buttonGraphics.alpha = 0.5;
	// Determine button shape based on assetId
	var isCircle = assetId === 'fireButton' || assetId === 'forwardButton';
	var buttonSize = 60; // Radius or half-width
	self.isPressed = false;
	// Add aura ready text if this is the fire button
	self.isFireButton = assetId === 'fireButton';
	if (self.isFireButton) {
		self.auraReadyText = new Text2('AURA READY!', {
			size: 30,
			fill: 0xFFFF00
		});
		self.auraReadyText.anchor.set(0.5, 0.5);
		self.auraReadyText.y = -90; // Position above the button
		self.auraReadyText.visible = false; // Initially hidden
		self.addChild(self.auraReadyText);
	}
	self.down = function (x, y, obj) {
		self.isPressed = true;
		buttonGraphics.alpha = 0.8;
	};
	self.up = function (x, y, obj) {
		self.isPressed = false;
		buttonGraphics.alpha = 0.5;
	};
	// Method to update aura ready text visibility
	self.updateAuraText = function (isAuraReady, cooldownRemaining) {
		if (self.isFireButton && self.auraReadyText) {
			// Initialize style property if it doesn't exist
			if (!self.auraReadyText.style) {
				self.auraReadyText.style = {};
			}
			if (isAuraReady) {
				self.auraReadyText.visible = true;
				self.auraReadyText.setText('AURA READY!');
				self.auraReadyText.style.fill = 0xFFFF00; // Yellow when ready
				// Add pulsing animation when aura is ready
				if (!self.pulseAnimation) {
					self.pulseAnimation = true;
					pulsateAuraText();
				}
			} else {
				// Show countdown when not ready
				if (cooldownRemaining !== undefined) {
					var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
					var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
					self.auraReadyText.visible = true;
					self.auraReadyText.setText('AURA: ' + secondsRemaining + 's');
					self.auraReadyText.style.fill = 0x3399FF; // Blue for cooldown
				} else {
					self.auraReadyText.visible = false;
				}
				self.pulseAnimation = false;
			}
		}
		function pulsateAuraText() {
			if (!self.pulseAnimation) {
				return;
			}
			tween(self.auraReadyText, {
				scaleX: 1.2,
				scaleY: 1.2
			}, {
				duration: 500,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					if (!self.pulseAnimation) {
						return;
					}
					tween(self.auraReadyText, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 500,
						easing: tween.easeInOut,
						onFinish: pulsateAuraText
					});
				}
			});
		}
	};
	return self;
});
var CreeperAsteroid = Container.expand(function () {
	var self = Container.call(this);
	// Create a container for the asteroid
	var asteroidGraphics = new Container();
	self.addChild(asteroidGraphics);
	// Always use meme9 (the Troll Face) as the creeper meme
	self.memeType = 9;
	// Add the meme image as the asteroid
	var memeImage = LK.getAsset('meme' + self.memeType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	asteroidGraphics.addChild(memeImage);
	// Explosive properties
	self.isExplosive = true;
	self.explosionRadius = 300;
	// Random velocity - slower than normal asteroids
	var speed = 0.9;
	var angle = Math.random() * Math.PI * 2;
	self.velocity = {
		x: Math.cos(angle) * speed,
		y: Math.sin(angle) * speed
	};
	// Random rotation - slower to appear more menacing
	self.rotationSpeed = (Math.random() - 0.5) * 0.03;
	// Pulsating effect
	self.pulseDirection = 1;
	self.pulseAmount = 0;
	self.pulseMax = 0.15;
	self.pulseSpeed = 0.008;
	self.update = function () {
		// Move
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Rotate
		asteroidGraphics.rotation += self.rotationSpeed;
		// Pulsating effect
		self.pulseAmount += self.pulseDirection * self.pulseSpeed;
		if (self.pulseAmount >= self.pulseMax) {
			self.pulseDirection = -1;
		} else if (self.pulseAmount <= 0) {
			self.pulseDirection = 1;
		}
		// Apply pulse to scale
		var pulseScale = 1 + self.pulseAmount;
		asteroidGraphics.scale.set(pulseScale, pulseScale);
		// Make it glow green occasionally
		if (LK.ticks % 60 < 15) {
			asteroidGraphics.tint = 0x88FF88;
		} else {
			asteroidGraphics.tint = 0xFFFFFF;
		}
		// Wrap around screen edges
		if (self.x < -50) {
			self.x = 2098;
		}
		if (self.x > 2098) {
			self.x = -50;
		}
		if (self.y < -50) {
			self.y = 2782;
		}
		if (self.y > 2782) {
			self.y = -50;
		}
	};
	self.getPoints = function () {
		return 200; // More points than regular asteroids
	};
	self.explode = function () {
		// Create explosion visual effect
		var explosion = new Container();
		var explosionGraphic = LK.getAsset('forwardButton', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: self.explosionRadius * 2,
			height: self.explosionRadius * 2,
			tint: 0x88FF88 // Green explosion
		});
		explosionGraphic.alpha = 0.7;
		explosion.addChild(explosionGraphic);
		explosion.x = self.x;
		explosion.y = self.y;
		game.addChild(explosion);
		// Animate the explosion - optimized for better performance
		tween(explosionGraphic, {
			alpha: 0,
			width: self.explosionRadius * 2.2,
			// Slightly reduced final size
			height: self.explosionRadius * 2.2 // Slightly reduced final size
		}, {
			duration: 400,
			// Slightly faster animation
			easing: tween.easeOut,
			onFinish: function onFinish() {
				game.removeChild(explosion);
			}
		});
		// Play specific explosion sound
		LK.getSound('meme9Explosion').play();
	};
	return self;
});
var CreeperIntroSequence = Container.expand(function () {
	var self = Container.call(this);
	// Layers for effects
	var starfieldLayer = new Container();
	var creeperLayer = new Container();
	var textLayer = new Container();
	var shipLayer = new Container();
	self.addChild(starfieldLayer);
	self.addChild(creeperLayer);
	self.addChild(textLayer);
	self.addChild(shipLayer);
	// Create starfield with green tint - significantly reduced count for better performance
	var stars = [];
	for (var i = 0; i < 20; i++) {
		var star = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 3 + Math.random() * 5,
			height: 3 + Math.random() * 5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			tint: 0x88FF88 // Green stars
		});
		star.alpha = 0.3 + Math.random() * 0.7;
		star.velocity = 10 + Math.random() * 20;
		stars.push(star);
		starfieldLayer.addChild(star);
	}
	// Create creeper silhouettes in background
	var creepers = [];
	for (var j = 0; j < 6; j++) {
		var creeper = LK.getAsset('meme9', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 200 + Math.random() * 1600,
			y: -300 - Math.random() * 600,
			tint: 0x44AA44 // Dark green silhouettes
		});
		creeper.alpha = 0.3;
		creeper.scale.set(0.3, 0.3);
		creepers.push(creeper);
		creeperLayer.addChild(creeper);
	}
	// Warning text
	var warningText = new Text2('CAUTION: CREEPER TERRITORY!', {
		size: 80,
		fill: 0x88FF88 // Green text
	});
	warningText.anchor.set(0.5, 0.5);
	warningText.x = 2048 / 2;
	warningText.y = 2732 / 2;
	warningText.alpha = 0;
	textLayer.addChild(warningText);
	// Subtitle warning
	var subtitleText = new Text2('BEWARE OF EXPLOSIVES!', {
		size: 60,
		fill: 0xFF3333 // Red text for emphasis
	});
	subtitleText.anchor.set(0.5, 0.5);
	subtitleText.x = 2048 / 2;
	subtitleText.y = 2732 / 2 + 100;
	subtitleText.alpha = 0;
	textLayer.addChild(subtitleText);
	// Hero ship
	var heroShip = new Ship();
	heroShip.x = -100;
	heroShip.y = 2732 / 2;
	shipLayer.addChild(heroShip);
	// Animation sequence
	self.phase = 0;
	self.timer = 0;
	self.finished = false;
	self.update = function () {
		self.timer++;
		// Update stars
		for (var i = 0; i < stars.length; i++) {
			var star = stars[i];
			star.y += star.velocity;
			if (star.y > 2732) {
				star.y = -10;
				star.x = Math.random() * 2048;
			}
		}
		// Animation phases
		switch (self.phase) {
			case 0:
				// Ship enters from left (0-2s)
				tween(heroShip, {
					x: 2048 / 2
				}, {
					duration: 2000,
					easing: tween.easeOut
				});
				self.phase = 1;
				break;
			case 1:
				// Creepers approach (2-4s)
				for (var j = 0; j < creepers.length; j++) {
					creepers[j].y += 3;
					creepers[j].scale.x += 0.003;
					creepers[j].scale.y += 0.003;
				}
				if (self.timer === 120) {
					// After 2s, show warning text
					tween(warningText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Make text glitch effect
					LK.setInterval(function () {
						warningText.scale.set(1 + Math.random() * 0.05, 1 + Math.random() * 0.05);
						warningText.x = 2048 / 2 + (Math.random() * 20 - 10);
					}, 80);
					self.phase = 2;
				}
				break;
			case 2:
				// Warning display (4-6s)
				for (var k = 0; k < creepers.length; k++) {
					creepers[k].y += 3;
					creepers[k].scale.x += 0.004;
					creepers[k].scale.y += 0.004;
				}
				if (self.timer === 240) {
					// After 4s, show subtitle
					tween(subtitleText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Flash the screen green briefly
					LK.effects.flashScreen(0x88FF88, 300);
					self.phase = 3;
				}
				break;
			case 3:
				// Subtitle and prepare to end (6-7s)
				if (self.timer === 360) {
					// After 6s, finish intro
					tween(warningText, {
						alpha: 0
					}, {
						duration: 500
					});
					tween(subtitleText, {
						alpha: 0
					}, {
						duration: 500
					});
					tween(heroShip, {
						x: 2048 + 100
					}, {
						duration: 1000,
						easing: tween.easeIn
					});
					self.phase = 4;
				}
				break;
			case 4:
				// Fade out and end (7-8s)
				if (self.timer === 420) {
					self.finished = true;
				}
				break;
		}
		return self.finished;
	};
	self.skip = function () {
		// Do nothing - disable skipping
	};
	return self;
});
var GlaudIntroSequence = Container.expand(function () {
	var self = Container.call(this);
	var particles = [];
	var letters = [];
	var particlePool = [];
	// Create wireframe ball
	var wireframeBall = new WireframeBall();
	wireframeBall.x = 2048 / 2;
	wireframeBall.y = 2732 / 2;
	wireframeBall.scaleX = 0.1;
	wireframeBall.scaleY = 0.1;
	wireframeBall.alpha = 0;
	self.addChild(wireframeBall);
	// Create GLAUD letters
	var letterPositions = [{
		letter: 'G',
		x: 2048 / 2 - 400,
		y: 2732 / 2
	}, {
		letter: 'L',
		x: 2048 / 2 - 200,
		y: 2732 / 2
	}, {
		letter: 'A',
		x: 2048 / 2,
		y: 2732 / 2
	}, {
		letter: 'U',
		x: 2048 / 2 + 200,
		y: 2732 / 2
	}, {
		letter: 'D',
		x: 2048 / 2 + 400,
		y: 2732 / 2
	}];
	for (var i = 0; i < letterPositions.length; i++) {
		var letterData = letterPositions[i];
		var animatedLetter = new AnimatedLetter(letterData.letter, letterData.x, letterData.y, i);
		letters.push(animatedLetter);
		self.addChild(animatedLetter);
	}
	// Initialize particle pool for better performance
	function initParticlePool() {
		for (var i = 0; i < 50; i++) {
			var particle = new GlaudParticle('energy');
			particle.active = false;
			particlePool.push(particle);
		}
	}
	function getPooledParticle() {
		for (var i = 0; i < particlePool.length; i++) {
			if (!particlePool[i].active) {
				particlePool[i].active = true;
				return particlePool[i];
			}
		}
		// If pool is empty, create new particle
		var newParticle = new GlaudParticle('energy');
		newParticle.active = true;
		particlePool.push(newParticle);
		return newParticle;
	}
	function returnParticleToPool(particle) {
		particle.active = false;
		if (particle.parent) {
			particle.parent.removeChild(particle);
		}
	}
	// Initialize intro sequence with chained animations
	function initIntroSequence() {
		// Start ball growth animation
		startBallGrowth();
	}
	function startBallGrowth() {
		LK.getSound('ballGrow').play();
		// Wireframe ball growth with rotation acceleration
		tween(wireframeBall, {
			scaleX: 3.2,
			scaleY: 3.2,
			alpha: 1
		}, {
			duration: 3000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				// Brief pause at maximum size, then start contraction
				LK.setTimeout(function () {
					startBallContraction();
				}, 500);
			}
		});
		// Gradually increase rotation speeds
		tween(wireframeBall, {
			rotationSpeedX: 0.08,
			rotationSpeedY: 0.1,
			rotationSpeedZ: 0.06
		}, {
			duration: 3000,
			easing: tween.easeInOut
		});
		// Add energy buildup with sparkle intensity
		LK.setTimeout(function () {
			// Final pulse before contraction
			tween(wireframeBall, {
				scaleX: 3.5,
				scaleY: 3.5
			}, {
				duration: 200,
				easing: tween.easeInOut
			});
			// Maximum rotation speed for instability effect
			wireframeBall.rotationSpeedX = 0.12;
			wireframeBall.rotationSpeedY = 0.15;
			wireframeBall.rotationSpeedZ = 0.1;
		}, 2000);
	}
	function startBallContraction() {
		LK.getSound('ballContract').play();
		// Dramatic wireframe ball implosion with extreme rotation
		wireframeBall.rotationSpeedX = 0.8;
		wireframeBall.rotationSpeedY = 1.0;
		wireframeBall.rotationSpeedZ = 0.6;
		tween(wireframeBall, {
			scaleX: 0,
			scaleY: 0,
			alpha: 0
		}, {
			duration: 600,
			easing: tween.easeInQuad,
			onFinish: function onFinish() {
				wireframeBall.alpha = 0;
				// Start letter formation after brief pause
				LK.setTimeout(function () {
					startLetterFormation();
				}, 200);
			}
		});
		// Delay explosion slightly for implosion effect
		LK.setTimeout(function () {
			createParticleExplosion();
		}, 300);
	}
	function startLetterFormation() {
		// Animate letters appearing one by one
		animateLetterSequence(0);
	}
	function animateLetterSequence(index) {
		if (index >= letters.length) {
			// All letters have appeared, start color transformation
			LK.setTimeout(function () {
				startColorTransformation();
			}, 500);
			return;
		}
		LK.getSound('letterAppear').play();
		letters[index].animateIn();
		// Schedule next letter with delay
		LK.setTimeout(function () {
			animateLetterSequence(index + 1);
		}, 250);
	}
	function startColorTransformation() {
		LK.getSound('colorTransform').play();
		// Staggered color transformation for wave effect
		var completedTransforms = 0;
		for (var i = 0; i < letters.length; i++) {
			(function (letterIndex) {
				LK.setTimeout(function () {
					letters[letterIndex].transformColor(0);
					completedTransforms++;
					// Check if all transformations are complete
					if (completedTransforms === letters.length) {
						LK.setTimeout(function () {
							startFinalEmphasis();
						}, 800);
					}
				}, letterIndex * 150);
			})(i);
		}
	}
	function startFinalEmphasis() {
		// Overall luminosity surge for all letters
		for (var i = 0; i < letters.length; i++) {
			tween(letters[i].letterText, {
				tint: 0xffaa00,
				// Brighter orange/yellow
				scaleX: 1.08,
				scaleY: 1.08
			}, {
				duration: 500,
				easing: tween.easeOut
			});
		}
		// Start progressive fade-out after surge
		LK.setTimeout(function () {
			startProgressiveFadeOut();
		}, 500);
	}
	function startProgressiveFadeOut() {
		// Unified Power Display (0 - 0.8 Seconds)
		startUnifiedPowerDisplay();
	}
	function startUnifiedPowerDisplay() {
		// Screen flash to white briefly for dramatic effect
		LK.effects.flashScreen(0xffffff, 200);
		// Make all letters shine with intense light simultaneously
		for (var i = 0; i < letters.length; i++) {
			// Multiple tween stages for more dramatic buildup
			tween(letters[i].letterText, {
				tint: 0xffdd00,
				// Bright gold first
				scaleX: 1.25,
				scaleY: 1.25
			}, {
				duration: 300,
				easing: tween.easeOut,
				onFinish: function (targetLetter) {
					return function () {
						tween(targetLetter.letterText, {
							tint: 0xffffff,
							// Then to brilliant white
							scaleX: 1.4,
							scaleY: 1.4
						}, {
							duration: 500,
							easing: tween.easeInOut
						});
					};
				}(letters[i])
			});
		}
		// Create god rays emanating from the text
		createGodRays();
		// Create energy particles swirling around letters
		createEnergySwirl();
		// Schedule the spectacular disappearance
		LK.setTimeout(function () {
			startSpectacularDisappearance();
		}, 800);
	}
	function createGodRays() {
		// Create multiple layers of light rays for depth
		for (var layer = 0; layer < 2; layer++) {
			var rayCount = layer === 0 ? 16 : 8;
			var rayLength = layer === 0 ? 4 : 6;
			for (var i = 0; i < rayCount; i++) {
				var ray = self.addChild(LK.getAsset('wireframeEdge', {
					anchorX: 0.5,
					anchorY: 0,
					x: 2048 / 2,
					y: 2732 / 2,
					rotation: Math.PI * 2 * i / rayCount + layer * Math.PI / 16,
					scaleX: 0.3 + layer * 0.2,
					scaleY: rayLength,
					tint: layer === 0 ? 0xffaa00 : 0xffffff,
					alpha: 0
				}));
				// Staggered ray appearance
				LK.setTimeout(function (currentRay, delayTime) {
					return function () {
						tween(currentRay, {
							alpha: 0.6 + Math.random() * 0.3,
							scaleY: rayLength + 2
						}, {
							duration: 400,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								// Pulse the rays before fade
								tween(currentRay, {
									alpha: 0.9,
									scaleY: rayLength + 3
								}, {
									duration: 200,
									easing: tween.easeInOut,
									onFinish: function onFinish() {
										tween(currentRay, {
											alpha: 0
										}, {
											duration: 300,
											easing: tween.easeIn,
											onFinish: function onFinish() {
												currentRay.destroy();
											}
										});
									}
								});
							}
						});
					};
				}(ray, i * 50 + layer * 200), i * 50 + layer * 200);
			}
		}
	}
	function createEnergySwirl() {
		// Create swirling energy particles around the text
		for (var i = 0; i < 30; i++) {
			var energyParticle = self.addChild(LK.getAsset('sparkle', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2 + Math.cos(i * 0.5) * 200,
				y: 2732 / 2 + Math.sin(i * 0.5) * 200,
				tint: 0xffdd00,
				alpha: 0
			}));
			// Animate particles in spiral motion
			var particleDelay = i * 30;
			LK.setTimeout(function (particle, index) {
				return function () {
					particle.alpha = 0.8;
					// Create spiral motion
					var _spiralTween = function spiralTween(currentAngle) {
						var radius = 150 + Math.sin(currentAngle * 0.1) * 50;
						var newX = 2048 / 2 + Math.cos(currentAngle) * radius;
						var newY = 2732 / 2 + Math.sin(currentAngle) * radius;
						tween(particle, {
							x: newX,
							y: newY,
							rotation: currentAngle
						}, {
							duration: 100,
							easing: tween.linear,
							onFinish: function onFinish() {
								if (currentAngle < Math.PI * 6) {
									_spiralTween(currentAngle + 0.3);
								} else {
									// Burst toward center
									tween(particle, {
										x: 2048 / 2,
										y: 2732 / 2,
										alpha: 0,
										scaleX: 0.1,
										scaleY: 0.1
									}, {
										duration: 200,
										easing: tween.easeInQuad,
										onFinish: function onFinish() {
											particle.destroy();
										}
									});
								}
							}
						});
					};
					_spiralTween(index * 0.5);
				};
			}(energyParticle, i), particleDelay);
		}
	}
	function startSpectacularDisappearance() {
		// Create dramatic screen distortion effect
		for (var i = 0; i < letters.length; i++) {
			var letter = letters[i];
			// Add violent shaking before implosion
			var shakeIntensity = 15;
			var shakeCount = 0;
			var shakeInterval = LK.setInterval(function (targetLetter) {
				return function () {
					targetLetter.x += (Math.random() - 0.5) * shakeIntensity;
					targetLetter.y += (Math.random() - 0.5) * shakeIntensity;
					shakeCount++;
					if (shakeCount > 10) {
						LK.clearInterval(shakeInterval);
					}
				};
			}(letter), 50);
		}
		// Enhanced implosion with multiple stages
		LK.setTimeout(function () {
			var centerX = 2048 / 2;
			var centerY = 2732 / 2;
			// Stage 1: Rapid acceleration toward center
			for (var i = 0; i < letters.length; i++) {
				var letter = letters[i];
				tween(letter, {
					x: centerX,
					y: centerY,
					scaleX: 0.3,
					scaleY: 0.3
				}, {
					duration: 180,
					easing: tween.easeInCubic
				});
				tween(letter.letterText, {
					tint: 0xffffff,
					alpha: 1.2
				}, {
					duration: 180
				});
			}
			// Stage 2: Final compression
			LK.setTimeout(function () {
				for (var i = 0; i < letters.length; i++) {
					var letter = letters[i];
					tween(letter, {
						scaleX: 0.05,
						scaleY: 0.05
					}, {
						duration: 80,
						easing: tween.easeInQuart
					});
				}
			}, 120);
			// Create the enhanced bright point and burst
			LK.setTimeout(function () {
				createEnhancedBrightPointAndBurst();
			}, 200);
		}, 500);
	}
	function createEnhancedBrightPointAndBurst() {
		// Create multiple concentric energy rings
		var rings = [];
		for (var r = 0; r < 3; r++) {
			var ring = self.addChild(LK.getAsset('wireframeJoint', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2,
				y: 2732 / 2,
				scaleX: 0.1 + r * 0.1,
				scaleY: 0.1 + r * 0.1,
				tint: r === 0 ? 0xffffff : r === 1 ? 0xffdd00 : 0xffaa00,
				alpha: 1
			}));
			rings.push(ring);
		}
		// Intense multi-stage flash
		var flashStage = 0;
		var flashInterval = LK.setInterval(function () {
			// Screen flash with varying intensities
			var flashColors = [0xffffff, 0xffdd00, 0xffffff, 0xffaa00];
			LK.effects.flashScreen(flashColors[flashStage % flashColors.length], 150);
			for (var i = 0; i < rings.length; i++) {
				tween(rings[i], {
					scaleX: (flashStage + 1) * 0.5 + i * 0.2,
					scaleY: (flashStage + 1) * 0.5 + i * 0.2,
					alpha: 1 - flashStage * 0.15
				}, {
					duration: 120,
					easing: tween.easeOut
				});
			}
			flashStage++;
			if (flashStage >= 4) {
				LK.clearInterval(flashInterval);
				// Final burst
				LK.setTimeout(function () {
					createMegaEnergyBurst();
					// Hide all letters
					for (var i = 0; i < letters.length; i++) {
						letters[i].visible = false;
					}
					// Clean up rings
					for (var i = 0; i < rings.length; i++) {
						rings[i].destroy();
					}
				}, 200);
			}
		}, 150);
	}
	function createMegaEnergyBurst() {
		// Create multiple expanding shockwaves
		for (var wave = 0; wave < 4; wave++) {
			LK.setTimeout(function (waveIndex) {
				return function () {
					var shockwave = self.addChild(LK.getAsset('forwardButton', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: 2048 / 2,
						y: 2732 / 2,
						width: 30,
						height: 30,
						tint: waveIndex === 0 ? 0xffffff : waveIndex % 2 === 0 ? 0xffdd00 : 0xffaa00,
						alpha: 0.9
					}));
					// Animate shockwave expanding with easing
					tween(shockwave, {
						width: 1200 + waveIndex * 200,
						height: 1200 + waveIndex * 200,
						alpha: 0
					}, {
						duration: 600 + waveIndex * 100,
						easing: tween.easeOutCubic,
						onFinish: function onFinish() {
							shockwave.destroy();
						}
					});
				};
			}(wave), wave * 150);
		}
		// Create spectacular particle explosion
		for (var i = 0; i < 50; i++) {
			LK.setTimeout(function (particleIndex) {
				return function () {
					var particle = self.addChild(LK.getAsset('particle', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: 2048 / 2,
						y: 2732 / 2,
						tint: particleIndex % 3 === 0 ? 0xffffff : particleIndex % 3 === 1 ? 0xffdd00 : 0xffaa00
					}));
					var angle = Math.random() * Math.PI * 2;
					var speed = 12 + Math.random() * 20;
					var distance = 40 + Math.random() * 50;
					var targetX = particle.x + Math.cos(angle) * distance;
					var targetY = particle.y + Math.sin(angle) * distance;
					// Multi-stage particle motion
					tween(particle, {
						x: targetX,
						y: targetY,
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 300,
						easing: tween.easeOutQuad,
						onFinish: function onFinish() {
							// Second stage - continue outward and fade
							var finalX = particle.x + Math.cos(angle) * 30;
							var finalY = particle.y + Math.sin(angle) * 30;
							tween(particle, {
								x: finalX,
								y: finalY,
								alpha: 0,
								scaleX: 0.1,
								scaleY: 0.1
							}, {
								duration: 400 + Math.random() * 300,
								easing: tween.easeOutCubic,
								onFinish: function onFinish() {
									particle.destroy();
								}
							});
						}
					});
				};
			}(i), Math.random() * 200);
		}
		// Create lingering energy wisps
		for (var w = 0; w < 15; w++) {
			LK.setTimeout(function () {
				var wisp = self.addChild(LK.getAsset('sparkle', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: 2048 / 2 + (Math.random() - 0.5) * 100,
					y: 2732 / 2 + (Math.random() - 0.5) * 100,
					tint: 0xffdd00,
					alpha: 0.6
				}));
				// Gentle floating motion before fade
				tween(wisp, {
					x: wisp.x + (Math.random() - 0.5) * 200,
					y: wisp.y + (Math.random() - 0.5) * 200,
					alpha: 0,
					rotation: Math.PI * 2
				}, {
					duration: 1500 + Math.random() * 1000,
					easing: tween.easeOutSine,
					onFinish: function onFinish() {
						wisp.destroy();
					}
				});
			}, w * 100 + Math.random() * 300);
		}
		// Extended silence then finish with dramatic fade to black
		LK.setTimeout(function () {
			// Final dramatic fade to black
			LK.effects.flashScreen(0x000000, 1500);
			LK.setTimeout(function () {
				self.finished = true;
			}, 1500);
		}, 1200);
	}
	function createLetterParticles(letter) {
		// Create small orange light particles when letter fades
		for (var i = 0; i < 8; i++) {
			var particle = self.addChild(LK.getAsset('particle', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: letter.x + (Math.random() - 0.5) * 100,
				y: letter.y + (Math.random() - 0.5) * 100
			}));
			particle.tint = 0xff8000; // Orange particles
			particle.scaleX = 0.3 + Math.random() * 0.4;
			particle.scaleY = particle.scaleX;
			var angle = Math.random() * Math.PI * 2;
			var speed = 3 + Math.random() * 5;
			var targetX = particle.x + Math.cos(angle) * speed * 20;
			var targetY = particle.y + Math.sin(angle) * speed * 20;
			tween(particle, {
				x: targetX,
				y: targetY,
				alpha: 0,
				scaleX: 0.1,
				scaleY: 0.1
			}, {
				duration: 600 + Math.random() * 400,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
	}
	function createParticleExplosion() {
		// Create wireframe edge fragments for better visual impact
		var fragmentsToCreate = Math.min(wireframeBall.edges.length, 15); // Fewer but more prominent fragments
		for (var i = 0; i < fragmentsToCreate; i++) {
			if (Math.random() < 0.9) {
				var edgeIndex = Math.floor(Math.random() * wireframeBall.edges.length);
				var edge = wireframeBall.edges[edgeIndex];
				var fragment = self.addChild(LK.getAsset('wireframeEdge', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: wireframeBall.x + edge.x,
					y: wireframeBall.y + edge.y,
					rotation: edge.rotation,
					scaleX: edge.scaleX,
					scaleY: edge.scaleY,
					alpha: edge.alpha
				}));
				// Calculate scatter direction from center
				var centerX = wireframeBall.x;
				var centerY = wireframeBall.y;
				var fragmentX = fragment.x;
				var fragmentY = fragment.y;
				var dirX = fragmentX - centerX;
				var dirY = fragmentY - centerY;
				var distance = Math.sqrt(dirX * dirX + dirY * dirY);
				if (distance === 0) {
					distance = 1;
				}
				dirX /= distance;
				dirY /= distance;
				var speed = 15 + Math.random() * 25;
				var targetX = fragmentX + dirX * speed * 20;
				var targetY = fragmentY + dirY * speed * 20;
				// Add random spinning
				var rotationSpeed = (Math.random() - 0.5) * 0.3;
				// Animate fragment scattering
				tween(fragment, {
					x: targetX,
					y: targetY,
					alpha: 0,
					scaleX: 0.1,
					scaleY: 0.1,
					rotation: fragment.rotation + rotationSpeed * 10
				}, {
					duration: 1000 + Math.random() * 800,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						fragment.destroy();
					}
				});
			}
		}
		// Create energy burst from joints (reduced count)
		var jointsToCreate = Math.min(wireframeBall.joints.length, 6);
		for (var i = 0; i < jointsToCreate; i++) {
			var jointIndex = Math.floor(Math.random() * wireframeBall.joints.length);
			var joint = wireframeBall.joints[jointIndex];
			var energyBurst = self.addChild(LK.getAsset('wireframeJoint', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: wireframeBall.x + joint.x,
				y: wireframeBall.y + joint.y,
				scaleX: 1.5,
				scaleY: 1.5
			}));
			var angle = Math.random() * Math.PI * 2;
			var speed = 8 + Math.random() * 12;
			var targetX = energyBurst.x + Math.cos(angle) * speed * 15;
			var targetY = energyBurst.y + Math.sin(angle) * speed * 15;
			tween(energyBurst, {
				x: targetX,
				y: targetY,
				alpha: 0,
				scaleX: 0.2,
				scaleY: 0.2
			}, {
				duration: 800 + Math.random() * 600,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					energyBurst.destroy();
				}
			});
		}
		// Create main particle burst using pooled particles
		for (var i = 0; i < 15; i++) {
			var particle = getPooledParticle();
			if (particle) {
				particle.x = wireframeBall.x;
				particle.y = wireframeBall.y;
				var angle = Math.PI * 2 * i / 15;
				var speed = 10 + Math.random() * 18;
				particle.velocityX = Math.cos(angle) * speed;
				particle.velocityY = Math.sin(angle) * speed;
				particle.life = 1.0;
				particle.markForDestroy = false;
				particles.push(particle);
				self.addChild(particle);
			}
		}
	}
	// Initialize particle pool and start sequence
	initParticlePool();
	initIntroSequence();
	self.finished = false;
	self.update = function () {
		// Update active particles efficiently
		for (var i = particles.length - 1; i >= 0; i--) {
			var particle = particles[i];
			if (particle.markForDestroy) {
				returnParticleToPool(particle);
				particles.splice(i, 1);
			}
		}
		return self.finished;
	};
	return self;
});
var GlaudParticle = Container.expand(function (particleType) {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = 0;
	self.velocityY = 0;
	self.life = 1.0;
	self.maxLife = 1.0;
	self.fadeSpeed = 0.015 + Math.random() * 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.2;
	self.initialScale = 0.5 + Math.random() * 0.5;
	particleGraphics.scaleX = self.initialScale;
	particleGraphics.scaleY = self.initialScale;
	if (particleType === 'energy') {
		particleGraphics.tint = 0x4a90e2;
	} else {
		particleGraphics.tint = 0xffffff;
	}
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
		self.velocityX *= 0.98; // Add friction
		self.velocityY *= 0.98;
		particleGraphics.rotation += self.rotationSpeed;
		self.life -= self.fadeSpeed;
		var fadeRatio = self.life / self.maxLife;
		particleGraphics.alpha = fadeRatio;
		particleGraphics.scaleX = self.initialScale * fadeRatio;
		particleGraphics.scaleY = self.initialScale * fadeRatio;
		if (self.life <= 0) {
			self.markForDestroy = true;
		}
	};
	return self;
});
var IntroSequence = Container.expand(function () {
	var self = Container.call(this);
	// Layers for effects
	var starfieldLayer = new Container();
	var memesLayer = new Container();
	var textLayer = new Container();
	var shipLayer = new Container();
	var titleLayer = new Container();
	self.addChild(starfieldLayer);
	self.addChild(memesLayer);
	self.addChild(textLayer);
	self.addChild(shipLayer);
	self.addChild(titleLayer);
	// Create starfield - significantly reduced number for better performance
	var stars = [];
	for (var i = 0; i < 20; i++) {
		var star = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 3 + Math.random() * 5,
			height: 3 + Math.random() * 5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			tint: 0xFFFFFF
		});
		star.alpha = 0.3 + Math.random() * 0.7;
		star.velocity = 10 + Math.random() * 20;
		stars.push(star);
		starfieldLayer.addChild(star);
	}
	// Create distant meme silhouettes
	var silhouettes = [];
	for (var j = 0; j < 10; j++) {
		var memeType = Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
		var meme = LK.getAsset('meme' + memeType, {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 200 + Math.random() * 1600,
			y: -300 - Math.random() * 600,
			tint: 0x333333
		});
		meme.alpha = 0.3;
		meme.scale.set(0.3, 0.3);
		silhouettes.push(meme);
		memesLayer.addChild(meme);
	}
	// Emergency broadcast text
	var emergencyText = new Text2('MEME OVERLOAD DETECTED', {
		size: 80,
		fill: 0xFF3333
	});
	emergencyText.anchor.set(0.5, 0.5);
	emergencyText.x = 2048 / 2;
	emergencyText.y = 2732 / 2;
	emergencyText.alpha = 0;
	textLayer.addChild(emergencyText);
	// Hero ship
	var heroShip = new Ship();
	heroShip.x = 2048 / 2;
	heroShip.y = 2732 + 100;
	heroShip.alpha = 0;
	shipLayer.addChild(heroShip);
	// Title
	var titleText = new Text2('MEMES ASTEROID WAR', {
		size: 120,
		fill: 0xFF8000
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 2732 / 2 - 300;
	titleText.alpha = 0;
	titleLayer.addChild(titleText);
	// Call to action
	var ctaText = new Text2('TAP TO DEFEND THE INTERNET', {
		size: 60,
		fill: 0xFFFFFF
	});
	ctaText.anchor.set(0.5, 0.5);
	ctaText.x = 2048 / 2;
	ctaText.y = 2732 / 2 + 300;
	ctaText.alpha = 0;
	titleLayer.addChild(ctaText);
	// Animation sequence
	self.phase = 0;
	self.timer = 0;
	self.finished = false;
	self.update = function () {
		self.timer++;
		// Update stars
		for (var i = 0; i < stars.length; i++) {
			var star = stars[i];
			star.y += star.velocity;
			if (star.y > 2732) {
				star.y = -10;
				star.x = Math.random() * 2048;
			}
		}
		// Animation phases
		switch (self.phase) {
			case 0:
				// Starfield intro (0-2s)
				if (self.timer === 60) {
					// After 1s, start meme approach
					self.phase = 1;
				}
				break;
			case 1:
				// Meme approach (2-4s)
				for (var j = 0; j < silhouettes.length; j++) {
					silhouettes[j].y += 3;
					silhouettes[j].scale.x += 0.003;
					silhouettes[j].scale.y += 0.003;
				}
				if (self.timer === 180) {
					// After 3s, show emergency text
					self.phase = 2;
					tween(emergencyText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Make text glitch effect
					LK.setInterval(function () {
						emergencyText.scale.set(1 + Math.random() * 0.05, 1 + Math.random() * 0.05);
						emergencyText.x = 2048 / 2 + (Math.random() * 20 - 10);
					}, 80);
				}
				break;
			case 2:
				// Emergency broadcast (4-6s)
				for (var k = 0; k < silhouettes.length; k++) {
					silhouettes[k].y += 3;
					silhouettes[k].scale.x += 0.004;
					silhouettes[k].scale.y += 0.004;
				}
				if (self.timer === 300) {
					// After 5s, fade out emergency text and show ship
					self.phase = 3;
					tween(emergencyText, {
						alpha: 0
					}, {
						duration: 500
					});
					// Animate hero ship rising
					heroShip.alpha = 1;
					tween(heroShip, {
						y: 2732 / 2 + 200
					}, {
						duration: 1500,
						easing: tween.easeOut
					});
				}
				break;
			case 3:
				// Ship reveal (6-8s)
				if (self.timer === 420) {
					// After 7s, show title
					self.phase = 4;
					// Animate title card
					tween(titleText, {
						alpha: 1
					}, {
						duration: 800,
						easing: tween.easeOut
					});
					// Create distortion effect on title
					var titleDistort = LK.setInterval(function () {
						titleText.scale.set(1 + Math.random() * 0.03, 1 + Math.random() * 0.03);
						if (self.timer > 480) {
							LK.clearInterval(titleDistort);
							titleText.scale.set(1, 1);
						}
					}, 50);
				}
				break;
			case 4:
				// Title card (8-10s)
				if (self.timer === 540) {
					// After 9s, show CTA
					self.phase = 5;
					tween(ctaText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Make CTA pulse
					LK.setInterval(function () {
						if (ctaText.alpha === 1) {
							tween(ctaText, {
								alpha: 0.5
							}, {
								duration: 800
							});
						} else {
							tween(ctaText, {
								alpha: 1
							}, {
								duration: 800
							});
						}
					}, 1600);
				}
				break;
			case 5:
				// CTA (10s+)
				if (self.timer === 660) {
					// After 11s total, finish intro
					self.finished = true;
				}
				break;
		}
		return self.finished;
	};
	self.skip = function () {
		self.finished = true;
	};
	return self;
});
var OutroSequence = Container.expand(function () {
	var self = Container.call(this);
	// Layers for effects
	var starfieldLayer = new Container();
	var memesLayer = new Container();
	var textLayer = new Container();
	var shipLayer = new Container();
	self.addChild(starfieldLayer);
	self.addChild(memesLayer);
	self.addChild(textLayer);
	self.addChild(shipLayer);
	// Create starfield - significantly reduced number for better performance
	var stars = [];
	for (var i = 0; i < 20; i++) {
		var star = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 3 + Math.random() * 5,
			height: 3 + Math.random() * 5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			tint: 0xFFFFFF
		});
		star.alpha = 0.3 + Math.random() * 0.7;
		star.velocity = 10 + Math.random() * 20;
		stars.push(star);
		starfieldLayer.addChild(star);
	}
	// Create exploding memes
	var memes = [];
	for (var j = 0; j < 20; j++) {
		var memeType = Math.floor(Math.random() * 14); // 0-13 for 14 memes
		var meme = LK.getAsset('meme' + memeType, {
			anchorX: 0.5,
			anchorY: 0.5,
			x: Math.random() * 2048,
			y: Math.random() * 2732,
			scaleX: 0.2,
			scaleY: 0.2
		});
		meme.rotationSpeed = (Math.random() - 0.5) * 0.1;
		meme.velocity = {
			x: (Math.random() - 0.5) * 8,
			y: (Math.random() - 0.5) * 8
		};
		memes.push(meme);
		memesLayer.addChild(meme);
	}
	// Game result text (Victory or Game Over)
	var resultText;
	if (score > (storage.highScore || 0) && score > 0) {
		resultText = new Text2('VICTORY!', {
			size: 120,
			fill: 0xFF8000
		});
	} else {
		resultText = new Text2('GAME OVER', {
			size: 120,
			fill: 0xFF3333 // Red color for Game Over
		});
	}
	resultText.anchor.set(0.5, 0.5);
	resultText.x = 2048 / 2;
	resultText.y = 2732 / 2 - 300;
	resultText.alpha = 0;
	textLayer.addChild(resultText);
	// Score text
	var finalScoreText = new Text2('FINAL SCORE: ' + score, {
		size: 80,
		fill: 0xFFFFFF
	});
	finalScoreText.anchor.set(0.5, 0.5);
	finalScoreText.x = 2048 / 2;
	finalScoreText.y = 2732 / 2;
	finalScoreText.alpha = 0;
	textLayer.addChild(finalScoreText);
	// Add message based on high score
	var messageText;
	if (score > (storage.highScore || 0) && score > 0) {
		messageText = new Text2('AMAZING JOB! NEW HIGH SCORE!', {
			size: 60,
			fill: 0xFFD700 // Gold color
		});
	} else {
		messageText = new Text2('DON\'T GIVE UP! YOU\'LL DO BETTER NEXT TIME!', {
			size: 60,
			fill: 0x3399FF // Blue color
		});
	}
	messageText.anchor.set(0.5, 0.5);
	messageText.x = 2048 / 2;
	messageText.y = 2732 / 2 + 100;
	messageText.alpha = 0;
	textLayer.addChild(messageText);
	// Continue text
	var continueText = new Text2('TAP TO CONTINUE', {
		size: 60,
		fill: 0xFFFFFF
	});
	continueText.anchor.set(0.5, 0.5);
	continueText.x = 2048 / 2;
	continueText.y = 2732 / 2 + 300;
	continueText.alpha = 0;
	textLayer.addChild(continueText);
	// Animation sequence
	self.phase = 0;
	self.timer = 0;
	self.finished = false;
	self.update = function () {
		self.timer++;
		// Update stars - moving faster for outro
		for (var i = 0; i < stars.length; i++) {
			var star = stars[i];
			star.y -= star.velocity; // Moving upward instead of downward
			if (star.y < -10) {
				star.y = 2732 + 10;
				star.x = Math.random() * 2048;
			}
		}
		// Update memes - spinning and moving across screen
		for (var j = 0; j < memes.length; j++) {
			var meme = memes[j];
			meme.rotation += meme.rotationSpeed;
			meme.x += meme.velocity.x;
			meme.y += meme.velocity.y;
			// Bounce off edges
			if (meme.x < 0 || meme.x > 2048) {
				meme.velocity.x *= -1;
			}
			if (meme.y < 0 || meme.y > 2732) {
				meme.velocity.y *= -1;
			}
		}
		// Animation phases
		switch (self.phase) {
			case 0:
				// Initial pause (0-1s)
				if (self.timer === 60) {
					// After 1s, show result text
					self.phase = 1;
					tween(resultText, {
						alpha: 1,
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 800,
						easing: tween.elasticOut,
						onFinish: function onFinish() {
							tween(resultText, {
								scaleX: 1,
								scaleY: 1
							}, {
								duration: 500,
								easing: tween.easeOut
							});
						}
					});
				}
				break;
			case 1:
				// Victory text (1-3s)
				if (self.timer === 180) {
					// After 3s, show score
					self.phase = 2;
					tween(finalScoreText, {
						alpha: 1
					}, {
						duration: 800,
						easing: tween.easeOut
					});
				}
				break;
			case 2:
				// Score display (3-5s)
				if (self.timer === 240) {
					// After 4s, show motivational message
					tween(messageText, {
						alpha: 1
					}, {
						duration: 800,
						easing: tween.easeOut
					});
				}
				if (self.timer === 300) {
					// After 5s, show continue prompt
					self.phase = 3;
					tween(continueText, {
						alpha: 1
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Pulse the continue text
					LK.setInterval(function () {
						if (continueText.alpha === 1) {
							tween(continueText, {
								alpha: 0.5
							}, {
								duration: 800
							});
						} else {
							tween(continueText, {
								alpha: 1
							}, {
								duration: 800
							});
						}
					}, 1600);
				}
				break;
			case 3:
				// Continue prompt (5s+)
				// Player can tap to continue
				if (self.timer > 360) {
					self.canExit = true;
				}
				break;
		}
		return self.finished;
	};
	self.skip = function () {
		self.finished = true;
	};
	return self;
});
var Ship = Container.expand(function () {
	var self = Container.call(this);
	// Create a custom triangle ship
	var shipGraphics = new Container();
	self.addChild(shipGraphics);
	// Create a pixel art triangle
	var triangleSize = 72; // Scale up to 1.5 times larger from 48 to 72
	var pixelSize = 12; // Increase pixel size for more distinct lines
	var pixelGap = 1; // Gap between pixels for hollow effect
	// Create triangle points - pointing right by default (0 degrees = right)
	var points = [{
		x: triangleSize,
		y: 0
	},
	// Front tip (pointing right)
	{
		x: -triangleSize / 2,
		y: -triangleSize / 2
	},
	// Top left
	{
		x: -triangleSize / 2,
		y: triangleSize / 2
	} // Bottom left
	];
	// Draw the outline with pixel art style
	for (var i = 0; i < 3; i++) {
		var startPoint = points[i];
		var endPoint = points[(i + 1) % 3];
		// Calculate step count based on distance
		var dx = endPoint.x - startPoint.x;
		var dy = endPoint.y - startPoint.y;
		var steps = Math.max(Math.abs(dx), Math.abs(dy)) / pixelSize;
		// Draw pixels along the line
		for (var step = 0; step <= steps; step++) {
			var px = startPoint.x + dx * (step / steps);
			var py = startPoint.y + dy * (step / steps);
			var pixel = LK.getAsset('shipShape', {
				anchorX: 0.5,
				anchorY: 0.5,
				width: pixelSize - pixelGap,
				height: pixelSize - pixelGap,
				x: px,
				y: py,
				tint: 0xFF8000 // Orange color
			});
			shipGraphics.addChild(pixel);
		}
	}
	shipGraphics.x = 0;
	shipGraphics.y = 0;
	// Ship properties
	self.rot = 0; // Start pointing right (0 radians)
	self.rotationSpeed = 0.05; // Reduced rotation speed for less sensitive steering
	self.isRotatingLeft = false;
	self.isRotatingRight = false;
	self.isFiring = false;
	self.fireDelay = 15; // frames between shots
	self.fireTimer = 0;
	self.invulnerable = false;
	self.invulnerableTime = 0;
	// Aura ability properties
	self.auraReady = false;
	self.auraCooldown = 0;
	self.auraCooldownMax = 900; // 15 seconds (60fps * 15) - reduced from 20s
	self.auraActive = false;
	self.auraActiveTime = 0;
	self.auraActiveTimeMax = 180; // 3 seconds (increased from 2s)
	// Physics-based movement properties - much simpler direct movement
	self.thrustPower = 0.20; // Increased thrust power for faster acceleration
	self.dragFactor = 0.97; // Slightly increased drag to slow down faster
	self.maxSpeed = 8; // Increased maximum speed
	self.velocity = {
		x: 0,
		y: 0
	};
	// Track previous position for movement calculations
	self.lastX = 0;
	self.lastY = 0;
	// Cache rotation values for optimization
	self.lastRot = self.rot;
	self.dirX = Math.cos(self.rot);
	self.dirY = Math.sin(self.rot);
	// Apply rotation to ship graphics
	shipGraphics.rotation = self.rot;
	self.update = function () {
		// Store last position
		self.lastX = self.x;
		self.lastY = self.y;
		// Handle rotation
		if (self.isRotatingLeft) {
			self.rot -= self.rotationSpeed;
		}
		if (self.isRotatingRight) {
			self.rot += self.rotationSpeed;
		}
		// Only update rotation visual when it changes to reduce unnecessary calculations
		if (self.lastRot !== self.rot) {
			shipGraphics.rotation = self.rot;
			self.lastRot = self.rot;
			// Pre-calculate direction vectors when rotation changes
			self.dirX = Math.cos(self.rot);
			self.dirY = Math.sin(self.rot);
		}
		// Use cached direction values
		// Apply thrust force in direction ship is facing (always moving)
		self.velocity.x += self.dirX * self.thrustPower;
		self.velocity.y += self.dirY * self.thrustPower;
		// Apply drag/friction
		self.velocity.x *= self.dragFactor;
		self.velocity.y *= self.dragFactor;
		// Calculate squared speed once for both checks
		var speedSquared = self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y;
		var maxSpeedSquared = self.maxSpeed * self.maxSpeed;
		// Only calculate actual speed when needed
		var speed = 0;
		if (speedSquared > maxSpeedSquared) {
			// Only calculate square root when we need to limit speed
			speed = Math.sqrt(speedSquared);
			// Apply speed limit
			var limitFactor = self.maxSpeed / speed;
			self.velocity.x *= limitFactor;
			self.velocity.y *= limitFactor;
			speed = self.maxSpeed;
		} else {
			// Approximate speed for particle effects without expensive sqrt
			speed = Math.abs(self.velocity.x) + Math.abs(self.velocity.y) * 0.5;
		}
		// Create thrust particles - optimize by creating fewer particles
		if (speed > 0.5 && LK.ticks % 6 == 0) {
			// Create particle every 6 ticks instead of 3 to reduce particle count
			var particle = new ThrustParticle();
			// Position at the back of the ship (opposite of direction)
			var backX = self.x - self.dirX * triangleSize * 0.5;
			var backY = self.y - self.dirY * triangleSize * 0.5;
			// Add some randomness
			backX += (Math.random() - 0.5) * 10;
			backY += (Math.random() - 0.5) * 10;
			particle.x = backX;
			particle.y = backY;
			// Set velocity opposite to ship direction with some randomness
			particle.velocity.x = -self.dirX * (1 + Math.random()) + (Math.random() - 0.5) * 0.5;
			particle.velocity.y = -self.dirY * (1 + Math.random()) + (Math.random() - 0.5) * 0.5;
			// Add to game via event
			if (typeof game.addThrustParticle === 'function') {
				game.addThrustParticle(particle);
			}
		}
		// Update position based on velocity
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Wrap around screen edges
		if (self.x < 0) {
			self.x = 2048;
		}
		if (self.x > 2048) {
			self.x = 0;
		}
		if (self.y < 0) {
			self.y = 2732;
		}
		if (self.y > 2732) {
			self.y = 0;
		}
		// Handle firing
		if (self.isFiring) {
			if (self.fireTimer <= 0) {
				self.fireTimer = self.fireDelay;
				return true; // Signal to create a bullet
			}
		}
		if (self.fireTimer > 0) {
			self.fireTimer--;
		}
		// Handle invulnerability
		if (self.invulnerable) {
			self.invulnerableTime--;
			shipGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
			if (self.invulnerableTime <= 0) {
				self.invulnerable = false;
				shipGraphics.alpha = 1;
			}
		}
		// Handle Aura cooldown and activation
		if (!self.auraReady && !self.auraActive) {
			self.auraCooldown++;
			// Calculate remaining cooldown for display
			self.remainingCooldown = self.auraCooldownMax - self.auraCooldown;
			if (self.auraCooldown >= self.auraCooldownMax) {
				self.auraReady = true;
				self.auraCooldown = 0;
				self.remainingCooldown = 0;
			}
		}
		// Handle active Aura effects
		if (self.auraActive) {
			// Pulse the ship with a white glow when aura is active
			shipGraphics.tint = 0xFFFFFF;
			self.auraActiveTime++;
			if (self.auraActiveTime >= self.auraActiveTimeMax) {
				self.auraActive = false;
				self.auraActiveTime = 0;
				shipGraphics.tint = 0xFFFFFF; // Reset tint
				// Start cooldown again
				self.auraCooldown = 0;
				self.auraReady = false;
			}
		} else {
			// Reset tint when aura is not active
			shipGraphics.tint = 0xFF8000;
		}
		return false;
	};
	self.makeInvulnerable = function (frames) {
		self.invulnerable = true;
		self.invulnerableTime = frames;
	};
	// Activate aura ability
	self.activateAura = function () {
		// Only activate if aura is ready
		if (self.auraReady) {
			self.auraActive = true;
			self.auraActiveTime = 0;
			self.auraReady = false;
			// Create visual effect - ship glows white
			tween(shipGraphics, {
				tint: 0xFFFFFF
			}, {
				duration: 200
			});
			return true;
		}
		return false;
	};
	return self;
});
var ThrustParticle = Container.expand(function () {
	var self = Container.call(this);
	// Create particle visual - larger and more visible
	var particleGraphics = LK.getAsset('bulletShape', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 32,
		// Further increased size for better visibility
		// Increased size
		height: 32,
		// Further increased size for better visibility
		// Increased size
		tint: 0xFFAA00 // Brighter orange-yellow for better visibility
	});
	particleGraphics.alpha = 1.0; // Fully opaque
	self.addChild(particleGraphics);
	// Particle properties
	self.velocity = {
		x: 0,
		y: 0
	};
	self.lifespan = 35; // Increased lifespan for better visibility
	self.age = 0;
	self.update = function () {
		// Move according to velocity
		self.x += self.velocity.x;
		self.y += self.velocity.y;
		// Age the particle
		self.age++;
		// Fade out as it ages, with a faster tail-end fade
		var lifeRatio = self.age / self.lifespan;
		particleGraphics.alpha = 0.9 * (1 - lifeRatio * lifeRatio);
		// Return true if particle should be removed
		return self.age >= self.lifespan;
	};
	return self;
});
var WireframeBall = Container.expand(function () {
	var self = Container.call(this);
	self.edges = [];
	self.joints = [];
	self.ballRadius = 80;
	self.rotationX = 0;
	self.rotationY = 0;
	self.rotationZ = 0;
	self.rotationSpeedX = 0.02;
	self.rotationSpeedY = 0.025;
	self.rotationSpeedZ = 0.015;
	// Create cube vertices mapped to sphere surface
	var cubeVertices = [[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
	// back face
	[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1] // front face
	];
	// Normalize vertices to sphere surface
	for (var i = 0; i < cubeVertices.length; i++) {
		var vertex = cubeVertices[i];
		var length = Math.sqrt(vertex[0] * vertex[0] + vertex[1] * vertex[1] + vertex[2] * vertex[2]);
		vertex[0] = vertex[0] / length * self.ballRadius;
		vertex[1] = vertex[1] / length * self.ballRadius;
		vertex[2] = vertex[2] / length * self.ballRadius;
	}
	// Create cube edges (12 edges total)
	var cubeEdges = [[0, 1], [1, 2], [2, 3], [3, 0],
	// back face edges
	[4, 5], [5, 6], [6, 7], [7, 4],
	// front face edges
	[0, 4], [1, 5], [2, 6], [3, 7] // connecting edges
	];
	// Create wireframe edges
	for (var i = 0; i < cubeEdges.length; i++) {
		var edge = cubeEdges[i];
		var vertex1 = cubeVertices[edge[0]];
		var vertex2 = cubeVertices[edge[1]];
		var edgeElement = self.attachAsset('wireframeEdge', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Calculate edge center and rotation
		var centerX = (vertex1[0] + vertex2[0]) / 2;
		var centerY = (vertex1[1] + vertex2[1]) / 2;
		var centerZ = (vertex1[2] + vertex2[2]) / 2;
		var dx = vertex2[0] - vertex1[0];
		var dy = vertex2[1] - vertex1[1];
		var edgeLength = Math.sqrt(dx * dx + dy * dy);
		var rotation = Math.atan2(dy, dx);
		edgeElement.x = centerX;
		edgeElement.y = centerY;
		edgeElement.z = centerZ || 0;
		edgeElement.rotation = rotation;
		edgeElement.scaleY = edgeLength / 120; // Scale to fit edge length
		edgeElement.alpha = 0.8;
		edgeElement.originalX = centerX;
		edgeElement.originalY = centerY;
		edgeElement.originalZ = centerZ || 0;
		edgeElement.originalRotation = rotation;
		edgeElement.originalScaleY = edgeElement.scaleY;
		self.edges.push(edgeElement);
	}
	// Create joints at vertices
	for (var i = 0; i < cubeVertices.length; i++) {
		var vertex = cubeVertices[i];
		var joint = self.attachAsset('wireframeJoint', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		joint.x = vertex[0];
		joint.y = vertex[1];
		joint.z = vertex[2] || 0;
		joint.originalX = vertex[0];
		joint.originalY = vertex[1];
		joint.originalZ = vertex[2] || 0;
		joint.alpha = 0;
		joint.pulsePhase = Math.random() * Math.PI * 2;
		self.joints.push(joint);
	}
	self.project3D = function (x, y, z) {
		// Simple 3D to 2D projection with rotation
		var cosX = Math.cos(self.rotationX);
		var sinX = Math.sin(self.rotationX);
		var cosY = Math.cos(self.rotationY);
		var sinY = Math.sin(self.rotationY);
		var cosZ = Math.cos(self.rotationZ);
		var sinZ = Math.sin(self.rotationZ);
		// Rotate around X axis
		var y1 = y * cosX - z * sinX;
		var z1 = y * sinX + z * cosX;
		// Rotate around Y axis
		var x2 = x * cosY + z1 * sinY;
		var z2 = -x * sinY + z1 * cosY;
		// Rotate around Z axis
		var x3 = x2 * cosZ - y1 * sinZ;
		var y3 = x2 * sinZ + y1 * cosZ;
		return {
			x: x3,
			y: y3,
			z: z2
		};
	};
	self.update = function () {
		// Update rotation
		self.rotationX += self.rotationSpeedX;
		self.rotationY += self.rotationSpeedY;
		self.rotationZ += self.rotationSpeedZ;
		// Update edge positions with 3D rotation
		for (var i = 0; i < self.edges.length; i++) {
			var edge = self.edges[i];
			var projected = self.project3D(edge.originalX, edge.originalY, edge.originalZ);
			edge.x = projected.x;
			edge.y = projected.y;
			// Depth-based alpha and scale
			var depth = (projected.z + self.ballRadius) / (2 * self.ballRadius);
			edge.alpha = 0.4 + depth * 0.6;
			edge.scaleX = 0.6 + depth * 0.4;
			// Maintain original scale for length
			edge.scaleY = edge.originalScaleY * (0.8 + depth * 0.2);
		}
		// Update joints with pulsing effect
		for (var i = 0; i < self.joints.length; i++) {
			var joint = self.joints[i];
			var projected = self.project3D(joint.originalX, joint.originalY, joint.originalZ);
			joint.x = projected.x;
			joint.y = projected.y;
			var depth = (projected.z + self.ballRadius) / (2 * self.ballRadius);
			joint.pulsePhase += 0.08;
			joint.alpha = Math.max(0, depth * 0.9 * Math.sin(joint.pulsePhase));
			joint.scaleX = joint.scaleY = 0.7 + depth * 0.3 + Math.sin(joint.pulsePhase) * 0.15;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
// Function to add thrust particles - called from Ship update
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Placeholder ID, engine will assign
// Placeholder ID, engine will assign
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Assuming ID is correct
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Music Tracks - assuming unique IDs exist for each
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Meme explosion sounds - assuming unique IDs exist for each
// Placeholder: Replace with actual music ID
// Placeholder: Replace with actual music ID
// Placeholder: Replace with actual music ID
// Initialize music tracks
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Placeholder: Replace with actual sound ID or properties
// Initialize meme explosion sounds
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Placeholder: Replace with actual sound ID
// Initialize music tracks
// Initialize meme explosion sounds
// Add music assets
// Add music assets
// Sounds for each meme type
// Game variables
// Add sound assets for each meme asteroid (meme0 to meme9)
// Sound for tapping to start
// Sound for starting a new level
// Sound for the rhythmic beat
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
// Engine will assign actual ID
// Engine will assign actual ID
// Added new meme image asset
// Added new meme explosion sound asset
// Object pools for performance optimization
var bulletPool = [];
var asteroidPool = [];
var thrustParticlePool = [];
var auraParticlePool = [];
var creeperAsteroidPool = [];
var ship;
var bullets = [];
var asteroids = [];
var thrustParticles = []; // Array to store thrust particles
var score = 0;
var lives = 3;
var level = 1;
var gameStarted = false;
var gameOver = false;
var introPlayed = false;
var introSequence = null;
var outroSequence = null;
var outroPlayed = false;
var highScore = 0; // This will be loaded from storage
var highScoreTxt; // UI element for displaying the high score
var newRecordShown = false; // Track if new record notification has been shown
var nextExtraLifeScore = 20000; // Score threshold for the next extra life
var extraLifeInterval = 20000; // Get an extra life every 20,000 points
var maxLives = 5; // Maximum number of lives a player can have
var triangleSize = 36; // Ship triangle size for bullet positioning (half of the size now)
// Creeper Zone variables
var inCreeperZone = false;
var creeperIntroSequence = null;
var creeperWaveCount = 0;
var creeperMaxWaves = 3; // Number of waves to complete the Creeper Zone
var glaudIntroSequence = null;
var glaudIntroPlayed = false;
// Function to play intro sequence
function playIntroSequence() {
	// Clear any existing game objects
	bullets = [];
	asteroids = [];
	thrustParticles = [];
	// Check if GLAUD intro has been played
	if (!glaudIntroPlayed) {
		// Start with GLAUD intro sequence
		glaudIntroSequence = new GlaudIntroSequence();
		game.addChild(glaudIntroSequence);
		// Setup handler for when GLAUD intro finishes
		LK.setInterval(function () {
			if (glaudIntroSequence && glaudIntroSequence.finished) {
				game.removeChild(glaudIntroSequence);
				glaudIntroSequence = null;
				glaudIntroPlayed = true;
				// After GLAUD intro, continue with main intro
				continueWithMainIntro();
				LK.clearInterval(this);
			}
		}, 100);
	} else {
		// Skip GLAUD intro and go directly to main intro
		continueWithMainIntro();
	}
}
function continueWithMainIntro() {
	// Play gameMusic3 for intro
	LK.playMusic('gameMusic3', {
		loop: true,
		fade: {
			start: 0,
			end: 1,
			duration: 1000
		}
	});
	introMusicPlayed = true;
	// Create and add intro sequence
	introSequence = new IntroSequence();
	game.addChild(introSequence);
	// Setup a handler for when intro is finished
	LK.setInterval(function () {
		if (introSequence && introSequence.finished) {
			game.removeChild(introSequence);
			introSequence = null;
			introPlayed = true;
			// Keep gameMusic3 playing - don't stop it
			// Start game immediately
			initGame();
			LK.clearInterval(this);
		}
	}, 100);
}
// UI elements
var leftButton;
var rightButton;
var fireButton;
var scoreTxt;
var livesTxt;
var levelTxt;
var startText;
// Initialize the game
function initGame() {
	// Reset the new record notification flag
	newRecordShown = false;
	// Reset extra life score tracking
	nextExtraLifeScore = 20000;
	// Initialize object pools
	initObjectPools();
	// Check if we need to play intro
	if (!gameStarted && !introPlayed) {
		playIntroSequence();
		return;
	}
	// Create ship
	ship = new Ship();
	ship.x = 2048 / 2;
	ship.y = 200; // Position at top middle
	ship.makeInvulnerable(120); // 2 seconds
	// Add visual effect to indicate ship is ready for movement
	tween(ship, {
		alpha: 0.5
	}, {
		duration: 500,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(ship, {
				alpha: 1
			}, {
				duration: 500,
				easing: tween.easeInOut
			});
		}
	});
	game.addChild(ship);
	// Create control buttons
	leftButton = new Button('rotateLeftButton');
	leftButton.x = 300; // Position on the left side
	leftButton.y = 2732 - 200; // Position at the bottom
	leftButton.scale.set(2, 2); // Make button bigger
	game.addChild(leftButton);
	// Fire button in the middle
	fireButton = new Button('fireButton');
	fireButton.x = 2048 / 2; // Position in middle
	fireButton.y = 2732 - 200; // Position at the bottom
	fireButton.scale.set(2, 2); // Make button bigger
	game.addChild(fireButton);
	// No forward button needed - ship will constantly move forward
	// Right rotation button
	rightButton = new Button('rotateRightButton');
	rightButton.x = 2048 - 300; // Position on the right side
	rightButton.y = 2732 - 200; // Position at the bottom
	rightButton.scale.set(2, 2); // Make button bigger
	game.addChild(rightButton);
	// Create UI text
	// Create Glaud text in orange
	var glaudText = new Text2('Glaud', {
		size: 60,
		fill: 0xFF8000 // Orange color
	});
	glaudText.anchor.set(1, 0); // Right-align text
	glaudText.x = -20; // Add padding from right edge
	glaudText.y = 0; // Position at very top
	LK.gui.topRight.addChild(glaudText);
	scoreTxt = new Text2('SCORE: 0', {
		size: 40,
		fill: 0xFFFFFF
	});
	scoreTxt.anchor.set(1, 0); // Right-align text
	scoreTxt.x = -20; // Add padding from right edge
	scoreTxt.y = 80; // Position further below the Glaud text
	LK.gui.topRight.addChild(scoreTxt);
	// Initialize high score from storage, defaulting to 0 if not found
	highScore = storage.highScore || 0;
	highScoreTxt = new Text2('BEST: ' + highScore, {
		size: 40,
		fill: 0xFFD700 // A nice gold color for the high score!
	});
	highScoreTxt.anchor.set(1, 0); // Right-align text
	highScoreTxt.x = -20; // Add padding from right edge, same as scoreTxt
	highScoreTxt.y = 140; // Position below scoreTxt
	LK.gui.topRight.addChild(highScoreTxt);
	// Create a container for lives display
	var livesContainer = new Container();
	livesContainer.x = 70;
	livesContainer.y = 50;
	LK.gui.top.addChild(livesContainer);
	// Add ship icons for lives instead of text
	var lifeIcons = [];
	for (var i = 0; i < 3; i++) {
		var lifeIcon = LK.getAsset('shipAsset', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 40,
			height: 40
		});
		lifeIcon.x = i * 50; // Space them horizontally
		livesContainer.addChild(lifeIcon);
		lifeIcons.push(lifeIcon);
	}
	// Store the icons and container for later access
	livesTxt = {
		icons: lifeIcons,
		container: livesContainer,
		update: function update(livesCount) {
			for (var i = 0; i < this.icons.length; i++) {
				this.icons[i].visible = i < livesCount;
			}
		}
	};
	levelTxt = new Text2('LEVEL: 1', {
		size: 40,
		fill: 0xFFFFFF
	});
	levelTxt.anchor.set(0, 0); // Left-align text
	levelTxt.x = 180; // Move further right from top-left menu icon but slightly to the left
	levelTxt.y = 80; // Move lower down from top edge
	LK.gui.topLeft.addChild(levelTxt);
	// Add developer feature - double-tap on level to advance
	var lastLevelTapTime = 0;
	var devModeActive = false;
	levelTxt.interactive = true;
	levelTxt.down = function (x, y, obj) {
		var currentTime = Date.now();
		// Check for double tap (within 300ms)
		if (currentTime - lastLevelTapTime < 300) {
			// Toggle dev mode on double tap
			devModeActive = !devModeActive;
			// Visual feedback that dev mode is active
			if (devModeActive) {
				// Initialize style property if it doesn't exist
				if (!levelTxt.style) {
					levelTxt.style = {};
				}
				levelTxt.style.fill = 0xFF8000; // Orange to indicate dev mode
				// Show dev mode activated message
				var devModeText = new Text2('DEV MODE ACTIVE!', {
					size: 40,
					fill: 0xFF8000
				});
				devModeText.anchor.set(0.5, 0.5);
				devModeText.x = 2048 / 2;
				devModeText.y = 2732 / 2;
				game.addChild(devModeText);
				// Fade out after 2 seconds
				tween(devModeText, {
					alpha: 0
				}, {
					duration: 1000,
					delay: 1000,
					onFinish: function onFinish() {
						game.removeChild(devModeText);
					}
				});
			} else {
				levelTxt.style.fill = 0xFFFFFF; // Reset to white when disabled
			}
		} else if (devModeActive) {
			// In dev mode, single tap advances the level
			// Clear existing asteroids
			for (var i = asteroids.length - 1; i >= 0; i--) {
				game.removeChild(asteroids[i]);
			}
			asteroids = [];
			// Advance to next level
			level++;
			levelTxt.setText('LEVEL: ' + level);
			LK.getSound('levelStart').play();
			// Create new asteroids for the next level
			createAsteroidsForLevel(level);
		}
		lastLevelTapTime = currentTime;
	};
	// Start screen text
	if (!gameStarted) {
		// Create gray background for start text
		var startBackground = new Container();
		var bgShape = LK.getAsset('bulletShape', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 1000,
			height: 250,
			tint: 0x333333
		});
		bgShape.alpha = 0.9;
		startBackground.addChild(bgShape);
		startText = new Text2('TAP TO START', {
			size: 140,
			// Slightly smaller size
			fill: 0xFFFFFF
		});
		startText.anchor.set(0.5, 0.5);
		startBackground.addChild(startText);
		LK.gui.center.addChild(startBackground);
	}
	// Clear any existing game objects
	bullets = [];
	asteroids = [];
	thrustParticles = [];
	// Initialize asteroids for the first level
	createAsteroidsForLevel(level);
}
function createAsteroidsForLevel(level) {
	// Number of asteroids based on level
	var numAsteroids = Math.min(4 + level, 12);
	for (var i = 0; i < numAsteroids; i++) {
		// Create a random meme type (0-13)
		var memeType = Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
		// Get asteroid from pool or create new one if pool is empty
		var asteroid = getFromPool(asteroidPool);
		if (!asteroid || asteroid.size !== 2) {
			// Try to find a size 2 asteroid specifically
			for (var j = 0; j < asteroidPool.length; j++) {
				if (!asteroidPool[j].active && asteroidPool[j].size === 2) {
					asteroid = asteroidPool[j];
					break;
				}
			}
			// If no size 2 asteroid found, create a new one
			if (!asteroid || asteroid.size !== 2) {
				asteroid = new Asteroid(2, memeType);
				game.addChild(asteroid);
				asteroidPool.push(asteroid);
			} else {
				// Reset properties of pooled asteroid
				asteroid.memeType = memeType;
			}
		} else {
			// Reset properties of pooled asteroid
			asteroid.memeType = memeType;
		}
		// Reset asteroid state
		asteroid.active = true;
		asteroid.visible = true;
		asteroid.justWrapped = false;
		// Re-initialize velocity
		var speed = (3 - asteroid.size) * 0.8 + 0.5;
		var angle = Math.random() * Math.PI * 2;
		asteroid.velocity = {
			x: Math.cos(angle) * speed,
			y: Math.sin(angle) * speed
		};
		asteroid.rotationSpeed = (Math.random() - 0.5) * 0.05;
		// Apply special behavior based on meme type
		if (memeType === 7) {
			// "This is Fine" meme - moves slower
			asteroid.velocity.x *= 0.6;
			asteroid.velocity.y *= 0.6;
		} else if (memeType === 9) {
			// "Stonks" meme - worth more points
			asteroid.getPoints = function () {
				return (3 - this.size) * 150; // 50% more points
			};
		} else if (memeType === 12) {
			// Fast meme
			asteroid.velocity.x *= 1.5;
			asteroid.velocity.y *= 1.5;
		}
		// Add difficulty scaling based on level
		if (level > 3) {
			// Scale asteroid speed with level
			var speedMultiplier = 1 + (level - 3) * 0.1; // 10% faster per level after 3
			speedMultiplier = Math.min(speedMultiplier, 1.5); // Cap at 50% faster
			asteroid.velocity.x *= speedMultiplier;
			asteroid.velocity.y *= speedMultiplier;
		}
		// Position the asteroid away from the player
		do {
			asteroid.x = Math.random() * 2048;
			asteroid.y = Math.random() * 2732;
		} while (distance(asteroid.x, asteroid.y, ship.x, ship.y) < 300);
		asteroids.push(asteroid);
	}
}
function distance(x1, y1, x2, y2) {
	return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
function createBullet() {
	// Get bullet from pool or create new one if pool is empty
	var bullet = getFromPool(bulletPool);
	if (!bullet) {
		bullet = new Bullet();
		game.addChild(bullet);
		bulletPool.push(bullet);
	}
	// Reset bullet properties
	bullet.age = 0;
	bullet.active = true;
	bullet.visible = true;
	// Use ship's rotation directly
	var angle = ship.rot;
	// Calculate the position at the tip of the ship based on the triangle geometry
	// For the redesigned ship (pointing up at 0 rotation), the tip is -triangleSize units in Y
	var offsetX = Math.cos(angle) * triangleSize;
	var offsetY = Math.sin(angle) * triangleSize;
	// Position bullet at the tip of the ship
	bullet.x = ship.x + offsetX;
	bullet.y = ship.y + offsetY;
	// Set bullet velocity to match ship's exact facing direction
	bullet.velocity.x = Math.cos(angle) * bullet.speed;
	bullet.velocity.y = Math.sin(angle) * bullet.speed;
	// Add bullet to active bullets array
	bullets.push(bullet);
	// Play shoot sound
	LK.getSound('shoot').play();
}
function updateAsteroids() {
	for (var i = asteroids.length - 1; i >= 0; i--) {
		var asteroid = asteroids[i];
		asteroid.update();
		// Check for collision with the ship
		if (!ship.invulnerable && asteroid.intersects(ship)) {
			// Player loses a life
			lives--;
			livesTxt.update(lives);
			// Play explosion sound
			LK.getSound('explosion').play();
			// Flash screen
			LK.effects.flashScreen(0xFF0000, 500);
			// Make ship invulnerable for a few seconds
			ship.makeInvulnerable(180);
			// Game over if no lives left
			if (lives <= 0) {
				// Check if the current score is a new high score
				if (score > highScore) {
					highScore = score; // Update our game's high score variable
					storage.highScore = highScore; // Persist the new high score
					// The highScoreTxt will update automatically on game restart via initGame
					// Display a motivational message about the new high score
					var newHighScoreText = new Text2('NEW HIGH SCORE! AMAZING WORK!', {
						size: 60,
						fill: 0xFFD700 // Gold color
					});
					newHighScoreText.anchor.set(0.5, 0.5);
					newHighScoreText.x = 2048 / 2;
					newHighScoreText.y = 2732 / 2 - 150;
					LK.gui.center.addChild(newHighScoreText);
					// Animate the text
					tween(newHighScoreText, {
						scaleX: 1.2,
						scaleY: 1.2
					}, {
						duration: 500,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							tween(newHighScoreText, {
								scaleX: 1,
								scaleY: 1
							}, {
								duration: 500,
								easing: tween.easeIn
							});
						}
					});
					// Remove the text after 3 seconds
					LK.setTimeout(function () {
						LK.gui.center.removeChild(newHighScoreText);
					}, 3000);
				} else {
					// Display a motivational message for not beating the high score
					var motivationalText = new Text2('YOU\'LL GET IT NEXT TIME!', {
						size: 60,
						fill: 0x3399FF // Blue color
					});
					motivationalText.anchor.set(0.5, 0.5);
					motivationalText.x = 2048 / 2;
					motivationalText.y = 2732 / 2 - 150;
					LK.gui.center.addChild(motivationalText);
					// Animate the text
					tween(motivationalText, {
						alpha: 0.7
					}, {
						duration: 800,
						easing: tween.easeInOut,
						onFinish: function onFinish() {
							tween(motivationalText, {
								alpha: 1
							}, {
								duration: 800,
								easing: tween.easeInOut
							});
						}
					});
					// Remove the text after 3 seconds
					LK.setTimeout(function () {
						LK.gui.center.removeChild(motivationalText);
					}, 3000);
				}
				LK.setScore(score); // Set the score for the platform's game over UI
				// Start the outro sequence instead of showing game over immediately
				playOutroSequence();
				gameOver = true;
				return;
			}
		}
	}
}
function updateBullets() {
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		bullet.update();
		// Remove bullets that have lived too long
		if (bullet.age > bullet.lifespan) {
			// Return bullet to pool instead of removing
			bullet.active = false;
			bullet.visible = false;
			bullets.splice(i, 1);
			continue;
		}
		// Check for collisions with asteroids
		var hitAsteroid = false;
		for (var j = asteroids.length - 1; j >= 0; j--) {
			var asteroid = asteroids[j];
			// Skip intersection check if asteroid just wrapped (reduces false positives)
			if (asteroid.justWrapped) {
				continue;
			}
			if (bullet.intersects(asteroid)) {
				hitAsteroid = true;
				// Add score based on asteroid size
				score += asteroid.getPoints();
				scoreTxt.setText('SCORE: ' + score);
				// Check if player earned an extra life
				if (score >= nextExtraLifeScore) {
					// Set next threshold regardless of whether we can get a life
					nextExtraLifeScore += extraLifeInterval;
					// Only award an extra life if below maximum
					if (lives < maxLives) {
						// Award an extra life
						lives++;
						// Update lives display
						livesTxt.update(lives);
						// Show extra life notification
						var extraLifeText = new Text2('EXTRA LIFE!', {
							size: 80,
							fill: 0x00FF00 // Bright green
						});
						extraLifeText.anchor.set(0.5, 0.5);
						extraLifeText.x = 2048 / 2;
						extraLifeText.y = 2732 / 2 - 200;
						extraLifeText.alpha = 0;
						game.addChild(extraLifeText);
						// Animate the notification
						tween(extraLifeText, {
							alpha: 1,
							scaleX: 1.3,
							scaleY: 1.3
						}, {
							duration: 500,
							easing: tween.elasticOut,
							onFinish: function onFinish() {
								// Wait 2 seconds before fading out
								LK.setTimeout(function () {
									tween(extraLifeText, {
										alpha: 0
									}, {
										duration: 1000,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											game.removeChild(extraLifeText);
										}
									});
								}, 2000);
							}
						});
						// Play a positive sound for extra life
						LK.getSound('levelStart').play();
					}
				}
				// Check if player just beat the high score and notification hasn't been shown yet
				if (score > highScore && score - asteroid.getPoints() <= highScore && !newRecordShown) {
					// Set flag to true so we don't show it again this game
					newRecordShown = true;
					// Create a temporary notification
					var newRecordText = new Text2('NEW RECORD!', {
						size: 80,
						fill: 0xFFD700 // Gold color
					});
					newRecordText.anchor.set(0.5, 0.5);
					newRecordText.x = 2048 / 2;
					newRecordText.y = 2732 / 2;
					newRecordText.alpha = 0;
					game.addChild(newRecordText);
					// Animate the notification
					tween(newRecordText, {
						alpha: 1,
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 500,
						easing: tween.elasticOut,
						onFinish: function onFinish() {
							// Wait 5 seconds before fading out
							LK.setTimeout(function () {
								tween(newRecordText, {
									alpha: 0
								}, {
									duration: 1500,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										game.removeChild(newRecordText);
									}
								});
							}, 5000);
						}
					});
					// Update high score
					highScore = score;
					highScoreTxt.setText('BEST: ' + highScore);
				}
				// Special handling for Creeper asteroids in Creeper Zone
				if (inCreeperZone && asteroid.isExplosive) {
					// Call the explode method
					asteroid.explode();
					// Check if ship is within explosion radius
					var dist = distance(asteroid.x, asteroid.y, ship.x, ship.y);
					if (dist <= asteroid.explosionRadius && !ship.invulnerable) {
						// Player loses a life if within explosion radius
						lives--;
						livesTxt.update(lives);
						// Flash screen green
						LK.effects.flashScreen(0x88FF88, 300);
						// Make ship invulnerable
						ship.makeInvulnerable(180);
						// Game over if no lives left
						if (lives <= 0) {
							if (score > highScore) {
								highScore = score;
								storage.highScore = highScore;
							}
							LK.setScore(score);
							playOutroSequence();
							gameOver = true;
							return;
						}
					}
					// Remove the asteroid
					game.removeChild(asteroid);
					asteroids.splice(j, 1);
					break;
				} else {
					// Get the asteroid's meme type, defaulting to 0 if undefined
					var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0;
					// Construct the specific meme explosion sound ID
					var memeExplosionSoundId = 'meme' + memeType + 'Explosion';
					// Try to get the specific meme explosion sound
					var explosionSound = LK.getSound(memeExplosionSoundId);
					// Play the specific meme explosion sound or fallback to generic explosion
					if (explosionSound) {
						explosionSound.play();
					} else {
						// Fallback to generic explosion sound
						console.log('Fallback explosion sound for memeType:', memeType);
						LK.getSound('explosion').play();
					}
					// Break large asteroids (size 2) into smaller pieces
					if (asteroid.size === 2) {
						for (var k = 0; k < 2; k++) {
							// Get medium asteroid from pool or create new one
							var newAsteroid = null;
							// Try to find a size 1 asteroid in the pool
							for (var p = 0; p < asteroidPool.length; p++) {
								if (!asteroidPool[p].active && asteroidPool[p].size === 1) {
									newAsteroid = asteroidPool[p];
									break;
								}
							}
							// If no pooled asteroid found, create a new one
							if (!newAsteroid) {
								newAsteroid = new Asteroid(1, asteroid.memeType);
								game.addChild(newAsteroid);
								asteroidPool.push(newAsteroid);
							} else {
								// Reset pooled asteroid properties
								newAsteroid.memeType = asteroid.memeType;
								// Reset velocity
								var speed = 0.8 * 2 + 0.5; // Speed for medium asteroid
								var angle = Math.random() * Math.PI * 2;
								newAsteroid.velocity = {
									x: Math.cos(angle) * speed,
									y: Math.sin(angle) * speed
								};
								newAsteroid.rotationSpeed = (Math.random() - 0.5) * 0.05;
							}
							newAsteroid.active = true;
							newAsteroid.visible = true;
							newAsteroid.justWrapped = false;
							newAsteroid.x = asteroid.x;
							newAsteroid.y = asteroid.y;
							asteroids.push(newAsteroid);
						}
					}
					// Return hit asteroid to pool instead of removing
					asteroid.active = false;
					asteroid.visible = false;
					asteroids.splice(j, 1);
					break;
				}
			}
		}
		if (hitAsteroid) {
			// Return bullet to pool instead of removing
			bullet.active = false;
			bullet.visible = false;
			bullets.splice(i, 1);
		}
	}
	// Check if all asteroids are destroyed
	if (asteroids.length === 0) {
		// Special handling for Creeper Zone
		if (inCreeperZone) {
			creeperWaveCount++;
			// Check if we've completed all Creeper Zone waves
			if (creeperWaveCount >= creeperMaxWaves) {
				// End Creeper Zone and continue to next level
				inCreeperZone = false;
				// Show "Area Clear" message
				var areaClearText = new Text2('AREA CLEAR!', {
					size: 80,
					fill: 0x88FF88 // Green text
				});
				areaClearText.anchor.set(0.5, 0.5);
				areaClearText.x = 2048 / 2;
				areaClearText.y = 2732 / 2;
				areaClearText.alpha = 0;
				game.addChild(areaClearText);
				// Animate the message
				tween(areaClearText, {
					alpha: 1,
					scaleX: 1.5,
					scaleY: 1.5
				}, {
					duration: 500,
					easing: tween.elasticOut,
					onFinish: function onFinish() {
						LK.setTimeout(function () {
							tween(areaClearText, {
								alpha: 0
							}, {
								duration: 1000,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									game.removeChild(areaClearText);
								}
							});
						}, 2000);
					}
				});
				// Return to normal music
				LK.playMusic('gameMusic3', {
					loop: true,
					fade: {
						start: 0,
						end: 1,
						duration: 1000
					}
				});
				// Move to level 10
				level = 10;
				levelTxt.setText('LEVEL: ' + level);
				// Play level start sound
				LK.getSound('levelStart').play();
				// Create new asteroids for the next level
				createAsteroidsForLevel(level);
			} else {
				// Create next wave of creeper asteroids
				var wavesLeft = creeperMaxWaves - creeperWaveCount;
				// Display wave counter
				var waveText = new Text2('WAVE ' + creeperWaveCount + ' COMPLETE! ' + wavesLeft + ' TO GO!', {
					size: 60,
					fill: 0xFFFFFF
				});
				waveText.anchor.set(0.5, 0.5);
				waveText.x = 2048 / 2;
				waveText.y = 2732 / 2;
				game.addChild(waveText);
				// Fade out after 2 seconds
				tween(waveText, {
					alpha: 0
				}, {
					duration: 1000,
					delay: 2000,
					onFinish: function onFinish() {
						game.removeChild(waveText);
					}
				});
				// Create next wave - increase count with each wave
				createCreeperAsteroids(5 + creeperWaveCount);
			}
		} else if (level === 9) {
			// Start Creeper Zone after level 9
			startCreeperZone();
		} else {
			// Normal level progression
			// Next level
			level++;
			levelTxt.setText('LEVEL: ' + level);
			// Play level start sound
			LK.getSound('levelStart').play();
			// Ensure gameMusic3 keeps playing - no music track changes
			if (!musicPlaying) {
				// If music isn't playing for some reason, restart gameMusic3
				LK.playMusic('gameMusic3', {
					loop: true,
					fade: {
						start: 0,
						end: 1,
						duration: 1000
					}
				});
				musicPlaying = true;
			}
			// Create new asteroids for the next level
			createAsteroidsForLevel(level);
		}
	}
}
// Main game update function
game.update = function () {
	// Update GLAUD intro sequence if active
	if (glaudIntroSequence) {
		glaudIntroSequence.update();
		return;
	}
	// Update intro sequence if active
	if (introSequence) {
		introSequence.update();
		return;
	}
	// Update Creeper Zone intro if active
	if (creeperIntroSequence) {
		creeperIntroSequence.update();
		return;
	}
	// Update outro sequence if active
	if (outroSequence) {
		outroSequence.update();
		return;
	}
	if (!gameStarted) {
		return;
	}
	// Update ship controls based on button state
	ship.isRotatingLeft = leftButton.isPressed;
	ship.isRotatingRight = rightButton.isPressed;
	ship.isFiring = fireButton.isPressed;
	// Update aura ready text on fire button with cooldown info
	fireButton.updateAuraText(ship.auraReady, ship.remainingCooldown);
	// Ship constantly moves forward, no need for isMoving toggle
	// Update ship
	if (ship.update()) {
		if (ship.auraReady) {
			// If aura is ready and firing, activate aura and create bullet
			if (ship.activateAura()) {
				// Destroy nearby asteroids when aura is activated
				destroyNearbyAsteroids();
				// Visual effect for aura activation
				createAuraEffectParticles();
				// Sound effect for aura activation
				LK.getSound('shoot').play();
			}
		}
		createBullet();
	}
	// Update bullets and check for collisions
	updateBullets();
	// Update asteroids and check for collisions
	updateAsteroids();
	// Update thrust particles
	updateThrustParticles();
};
// Game music and sound state variables
var currentMusicTrack = 0; // Initialize to 0, will be set to 1 on game start
var musicPlaying = false; // Track if music is currently playing
var introMusicPlayed = false; // Track if intro music has played
// Event handlers
game.down = function (x, y, obj) {
	// Check if GLAUD intro is playing
	if (glaudIntroSequence && !glaudIntroSequence.finished) {
		glaudIntroSequence.finished = true;
		return;
	}
	// Check if intro is playing
	if (introSequence && !introSequence.finished) {
		introSequence.skip();
		return;
	}
	// Check if Creeper Zone intro is playing - but don't allow skipping
	if (creeperIntroSequence && !creeperIntroSequence.finished) {
		// Don't allow skipping the creeper intro
		return;
	}
	// Check if outro is playing and can be exited
	if (outroSequence) {
		if (outroSequence.canExit) {
			outroSequence.skip();
		}
		return;
	}
	if (!gameStarted) {
		gameStarted = true;
		LK.getSound('gameStart').play(); // Play start sound
		if (startText && startText.parent) {
			startText.parent.parent.removeChild(startText.parent);
			startText = null;
		}
		// Only play gameMusic3
		LK.playMusic('gameMusic3', {
			loop: true,
			fade: {
				start: 0,
				end: 1,
				duration: 800
			}
		});
		// Set current track to match
		currentMusicTrack = 3;
		musicPlaying = true;
	}
	// Ensure buttons can detect touch events when pressed
	var local;
	var touchConsumed = false;
	// Check if we tapped on level text for dev mode
	if (levelTxt && levelTxt.getBounds) {
		var levelBounds = levelTxt.getBounds();
		// Check if tap is within level text bounds
		if (x >= levelBounds.x && x <= levelBounds.x + levelBounds.width && y >= levelBounds.y && y <= levelBounds.y + levelBounds.height) {
			// Let the level text handle the tap through its own down method
			levelTxt.down(x, y, obj);
			touchConsumed = true;
		}
	}
	// Check left button
	if (!touchConsumed) {
		local = leftButton.toLocal({
			x: x,
			y: y
		});
		if (local.x >= -leftButton.width / 2 && local.x <= leftButton.width / 2 && local.y >= -leftButton.height / 2 && local.y <= leftButton.height / 2) {
			leftButton.down(local.x, local.y, {});
			touchConsumed = true;
		}
	}
	// Check fire button only if touch not already consumed
	if (!touchConsumed) {
		local = fireButton.toLocal({
			x: x,
			y: y
		});
		if (local.x >= -fireButton.width / 2 && local.x <= fireButton.width / 2 && local.y >= -fireButton.height / 2 && local.y <= fireButton.height / 2) {
			fireButton.down(local.x, local.y, {});
			touchConsumed = true;
		}
	}
	// Check right button only if touch not already consumed
	if (!touchConsumed) {
		local = rightButton.toLocal({
			x: x,
			y: y
		});
		if (local.x >= -rightButton.width / 2 && local.x <= rightButton.width / 2 && local.y >= -rightButton.height / 2 && local.y <= rightButton.height / 2) {
			rightButton.down(local.x, local.y, {});
			touchConsumed = true;
		}
	}
	// Only fire a bullet if no button was pressed and game is active
	if (!touchConsumed && gameStarted && ship && !gameOver) {
		createBullet();
	}
};
// Add up handler to handle releasing buttons
game.up = function (x, y, obj) {
	// Reset all button states when touch/click is released
	// Safely call button handlers by checking if they exist first
	if (leftButton && typeof leftButton.up === 'function') {
		leftButton.up(0, 0, {});
	}
	if (fireButton && typeof fireButton.up === 'function') {
		fireButton.up(0, 0, {});
	}
	if (rightButton && typeof rightButton.up === 'function') {
		rightButton.up(0, 0, {});
	}
};
// Initialize object pools with pre-populated objects
function initObjectPools() {
	// Clear existing pools
	bulletPool = [];
	asteroidPool = [];
	thrustParticlePool = [];
	auraParticlePool = [];
	creeperAsteroidPool = [];
	// Pre-populate bullet pool (30 bullets should be enough for most gameplay)
	for (var i = 0; i < 30; i++) {
		var bullet = new Bullet();
		bullet.visible = false;
		bullet.active = false;
		bulletPool.push(bullet);
		game.addChild(bullet);
	}
	// Pre-populate asteroid pool (30 for all sizes)
	for (var i = 0; i < 10; i++) {
		// Large asteroids (size 2)
		var asteroid = new Asteroid(2);
		asteroid.visible = false;
		asteroid.active = false;
		asteroidPool.push(asteroid);
		game.addChild(asteroid);
		// Medium asteroids (size 1)
		asteroid = new Asteroid(1);
		asteroid.visible = false;
		asteroid.active = false;
		asteroidPool.push(asteroid);
		game.addChild(asteroid);
		// Small asteroids (size 0)
		asteroid = new Asteroid(0);
		asteroid.visible = false;
		asteroid.active = false;
		asteroidPool.push(asteroid);
		game.addChild(asteroid);
	}
	// Pre-populate thrust particle pool (50 particles)
	for (var i = 0; i < 50; i++) {
		var particle = new ThrustParticle();
		particle.visible = false;
		particle.active = false;
		thrustParticlePool.push(particle);
		game.addChild(particle);
	}
	// Pre-populate aura particle pool (24 particles)
	for (var i = 0; i < 24; i++) {
		var auraParticle = new AuraParticle();
		auraParticle.visible = false;
		auraParticle.active = false;
		auraParticlePool.push(auraParticle);
		game.addChild(auraParticle);
	}
	// Pre-populate creeper asteroid pool (15 creepers)
	for (var i = 0; i < 15; i++) {
		var creeper = new CreeperAsteroid();
		creeper.visible = false;
		creeper.active = false;
		creeperAsteroidPool.push(creeper);
		game.addChild(creeper);
	}
}
// Initialize the game when this script runs
initGame();
// Function to add thrust particles - called from Ship update
game.addThrustParticle = function (particle) {
	// If particle is from pool, just activate it
	if (particle.active === false) {
		particle.active = true;
		particle.visible = true;
		thrustParticles.push(particle);
		// Don't need to add to game since it's already a child
	} else {
		// If it's a new particle, try to get one from the pool first
		var pooledParticle = getFromPool(thrustParticlePool);
		if (pooledParticle) {
			// Reset particle properties
			pooledParticle.x = particle.x;
			pooledParticle.y = particle.y;
			pooledParticle.velocity.x = particle.velocity.x;
			pooledParticle.velocity.y = particle.velocity.y;
			pooledParticle.age = 0;
			pooledParticle.active = true;
			pooledParticle.visible = true;
			thrustParticles.push(pooledParticle);
		} else {
			// If pool is empty, use the provided particle
			thrustParticles.push(particle);
			game.addChild(particle);
		}
	}
};
// Helper function to get object from pool
function getFromPool(pool) {
	for (var i = 0; i < pool.length; i++) {
		if (!pool[i].active) {
			return pool[i];
		}
	}
	return null; // Pool is empty
}
// Function to update thrust particles
function updateThrustParticles() {
	for (var i = thrustParticles.length - 1; i >= 0; i--) {
		var particle = thrustParticles[i];
		// If particle update returns true, it means the particle should be removed
		if (particle.update()) {
			// Return particle to pool instead of removing
			particle.active = false;
			particle.visible = false;
			thrustParticles.splice(i, 1);
		}
	}
}
// Function to destroy asteroids near the ship when aura is activated
function destroyNearbyAsteroids() {
	var auraRadius = 350; // Slightly reduced radius for better balance
	// Create a visual ring effect for the aura
	var auraRing = new Container();
	var auraRingGraphic = LK.getAsset('forwardButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: auraRadius * 2,
		height: auraRadius * 2,
		tint: 0x40E0D0 // Turquoise color to match AuraParticle
	});
	auraRingGraphic.alpha = 0.7;
	auraRing.addChild(auraRingGraphic);
	auraRing.x = ship.x;
	auraRing.y = ship.y;
	game.addChild(auraRing);
	// Animate the aura ring expanding then fading
	tween(auraRingGraphic, {
		alpha: 0,
		width: auraRadius * 2.5,
		height: auraRadius * 2.5
	}, {
		duration: 1200,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			game.removeChild(auraRing);
		}
	});
	// Flash the ship with turquoise
	tween(ship, {
		alpha: 0.8
	}, {
		duration: 200,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(ship, {
				alpha: 1
			}, {
				duration: 200,
				easing: tween.easeInOut
			});
		}
	});
	// Check all asteroids and destroy ones within the aura radius
	for (var i = asteroids.length - 1; i >= 0; i--) {
		var asteroid = asteroids[i];
		var dist = distance(ship.x, ship.y, asteroid.x, asteroid.y);
		if (dist <= auraRadius) {
			// Different behavior based on asteroid size
			if (asteroid.size === 2) {
				// Large asteroids: Break into medium asteroids and score points
				score += asteroid.getPoints();
				scoreTxt.setText('SCORE: ' + score);
				// Play the specific meme explosion sound
				var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0;
				var memeExplosionSoundId = 'meme' + memeType + 'Explosion';
				var explosionSound = LK.getSound(memeExplosionSoundId);
				if (explosionSound) {
					explosionSound.play();
				} else {
					LK.getSound('explosion').play();
				}
				// Create medium asteroids
				for (var k = 0; k < 2; k++) {
					var newAsteroid = new Asteroid(1, asteroid.memeType);
					newAsteroid.x = asteroid.x + (Math.random() - 0.5) * 50;
					newAsteroid.y = asteroid.y + (Math.random() - 0.5) * 50;
					asteroids.push(newAsteroid);
					game.addChild(newAsteroid);
				}
				// Remove the large asteroid
				game.removeChild(asteroid);
				asteroids.splice(i, 1);
			} else {
				// Small and medium asteroids: Destroy completely and score double points
				score += asteroid.getPoints() * 2; // Double points for small/medium
				scoreTxt.setText('SCORE: ' + score);
				// Play explosion sound
				var memeTypeSmall = asteroid.memeType !== undefined ? asteroid.memeType : 0;
				var explosionSoundId = 'meme' + memeTypeSmall + 'Explosion';
				var expSound = LK.getSound(explosionSoundId);
				if (expSound) {
					expSound.play();
				} else {
					LK.getSound('explosion').play();
				}
				// Remove the asteroid
				game.removeChild(asteroid);
				asteroids.splice(i, 1);
			}
		}
	}
	// Check if all asteroids are destroyed after aura
	if (asteroids.length === 0) {
		// Next level
		level++;
		levelTxt.setText('LEVEL: ' + level);
		LK.getSound('levelStart').play();
		createAsteroidsForLevel(level);
	}
}
// Function to create particle effects when aura is activated
function createAuraEffectParticles() {
	// Create a burst of particles from the ship - reduced for better performance
	for (var i = 0; i < 24; i++) {
		// Get particle from pool or create new one
		var particle = getFromPool(auraParticlePool);
		if (!particle) {
			particle = new AuraParticle();
			game.addChild(particle);
			auraParticlePool.push(particle);
		}
		// Reset particle properties
		particle.age = 0;
		particle.active = true;
		particle.visible = true;
		// Calculate angle for circular burst
		var angle = i * (Math.PI * 2 / 24);
		// Position at the ship
		particle.x = ship.x;
		particle.y = ship.y;
		// Set velocity in all directions with varying speeds
		var speed = 4 + Math.random() * 5; // Variable speeds for more organic look
		particle.velocity.x = Math.cos(angle) * speed;
		particle.velocity.y = Math.sin(angle) * speed;
		// Add to active particles
		thrustParticles.push(particle);
	}
	// Create a flash effect
	LK.effects.flashObject(ship, 0x40E0D0, 500);
}
// Create Creeper Zone asteroids
function createCreeperAsteroids(count) {
	// Create a specific number of creeper asteroids
	count = count || 5; // Default to 5 if not specified
	for (var i = 0; i < count; i++) {
		// Get creeper from pool or create new one
		var creeper = getFromPool(creeperAsteroidPool);
		if (!creeper) {
			creeper = new CreeperAsteroid();
			game.addChild(creeper);
			creeperAsteroidPool.push(creeper);
		}
		// Reset creeper properties
		creeper.active = true;
		creeper.visible = true;
		// Reset velocity
		var speed = 0.9;
		var angle = Math.random() * Math.PI * 2;
		creeper.velocity = {
			x: Math.cos(angle) * speed,
			y: Math.sin(angle) * speed
		};
		creeper.rotationSpeed = (Math.random() - 0.5) * 0.03;
		creeper.pulseDirection = 1;
		creeper.pulseAmount = 0;
		// Position the creeper away from the player
		do {
			creeper.x = Math.random() * 2048;
			creeper.y = Math.random() * 2732;
		} while (distance(creeper.x, creeper.y, ship.x, ship.y) < 350);
		asteroids.push(creeper);
	}
}
// Start the special Creeper Zone level
function startCreeperZone() {
	// Set Creeper Zone flag
	inCreeperZone = true;
	creeperWaveCount = 0;
	// Clear any existing asteroids
	for (var i = asteroids.length - 1; i >= 0; i--) {
		game.removeChild(asteroids[i]);
	}
	asteroids = [];
	// Change music to the more tense gameMusic2
	LK.playMusic('gameMusic2', {
		loop: true,
		fade: {
			start: 0,
			end: 1,
			duration: 1000
		}
	});
	// Create and play intro sequence
	creeperIntroSequence = new CreeperIntroSequence();
	game.addChild(creeperIntroSequence);
	// Setup handler for when intro finishes
	LK.setInterval(function () {
		if (creeperIntroSequence && creeperIntroSequence.finished) {
			game.removeChild(creeperIntroSequence);
			creeperIntroSequence = null;
			// Start the first wave of creeper asteroids
			createCreeperAsteroids(5); // First wave has 5 creepers
			LK.clearInterval(this);
		}
	}, 100);
}
// Function to play outro sequence
function playOutroSequence() {
	// Stop game music and start outro music
	LK.playMusic('outroMusic', {
		loop: true,
		fade: {
			start: 0,
			end: 1,
			duration: 1000
		}
	});
	// Create and add outro sequence
	outroSequence = new OutroSequence();
	game.addChild(outroSequence);
	// Setup a handler for when outro is finished
	LK.setInterval(function () {
		if (outroSequence && outroSequence.finished) {
			game.removeChild(outroSequence);
			outroSequence = null;
			outroPlayed = true;
			// Finally show game over screen when player closes outro
			LK.showGameOver();
			LK.clearInterval(this);
		}
	}, 100);
}
;
 bulletShape. In-Game asset. 2d. High contrast. No shadows
 fireButton is round and orange with a bullet pattern.. In-Game asset. 2d. High contrast. No shadows
 rotateLeftButton is a square button with an arrow towards the left side.. In-Game asset. 2d. High contrast. No shadows
 amungas memes no text one cracter. In-Game asset. 2d. High contrast. No shadows
 trol face no text one cracter. In-Game asset. 2d. High contrast. No shadows
 make those famous dog memes that are so well known.one cracter. head. In-Game asset. 2d. High contrast. No shadows
 very well known pickles make Rick memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 making very well known cat memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 make very well known white ghost memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 make very well known frog memes. single character. no writing. just head grinning. In-Game asset. 2d. High contrast. No shadows
 make very well known duck memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 make very well known rainbow cat memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 very well known squid game just make cookie memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 make very well known minecraft memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
 It's a spaceship made of orange pixels, reminiscent of arcade games.. In-Game asset. 2d. High contrast. No shadows
 
 Not the hand with the cat.
 A stylish orange letter G.. In-Game asset. 2d. High contrast. No shadows
 shoot
Sound effect
meme0Explosion
Sound effect
explosion
Sound effect
meme1Explosion
Sound effect
meme2Explosion
Sound effect
meme3Explosion
Sound effect
meme4Explosion
Sound effect
meme5Explosion
Sound effect
meme6Explosion
Sound effect
meme7Explosion
Sound effect
meme8Explosion
Sound effect
meme9Explosion
Sound effect
levelStart
Sound effect
gameStart
Sound effect
beatSound
Sound effect
gameMusic1
Music
gameMusic2
Music
introMusic
Sound effect
gameMusic3
Music
meme10Explosion
Sound effect
meme11Explosion
Sound effect
meme12Explosion
Sound effect
outroMusic
Music
meme13Explosion
Sound effect
ballGrow
Sound effect
ballContract
Sound effect
letterAppear
Sound effect
colorTransform
Sound effect