User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 843
User prompt
first time a challenge is complete reste the game twice
User prompt
make sure first time game is reseted on challenge mode that the hand appears
User prompt
when reseting the game when a challenge is complete, make sure hand is back in the original position and that the first star has an obstacle around it
User prompt
when playing on challegnes mode, after each challenge is completed, reset the game to the starting point, with only 1 star, white dot, and the hand in the screen
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 797
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j] !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 801
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 801
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 801
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 803
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 803
User prompt
loop main background music while main menu is on
User prompt
play background music when main menu is on
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 797
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 796
Code edit (1 edits merged)
Please save this source code
User prompt
add game title in main menu
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 787
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 787
User prompt
Please fix the bug: 'TypeError: mainMenuStars[i].update is not a function' in or related to this line: 'mainMenuStars[i].update();' Line Number: 560
User prompt
add obstacles and starts moveing obliquoes from top to bottom in main menu screen. they will be destroyed when a mode is selectd
User prompt
When endless game is selected, make game have all 5 colors. So make sure the amount of colors an be different for each different moved
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 787
Code edit (14 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'y')' in or related to this line: 'if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && stars[j] && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {' Line Number: 787
/**** 
* Classes
****/ 
var BounceEffect = Container.expand(function (x, y, color) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var bounceGraphics = self.attachAsset('bounceEffect', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bounceGraphics.tint = color;
	var duration = 30;
	self._update_migrated = function () {
		duration--;
		bounceGraphics.scaleX += 0.1;
		bounceGraphics.scaleY += 0.1;
		bounceGraphics.alpha -= 0.033;
		bounceGraphics.scaleX -= 0.01;
		bounceGraphics.scaleY -= 0.01;
		if (duration <= 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var Challenge = Container.expand(function (color, amount) {
	var self = Container.call(this);
	self.color = color;
	self.amount = amount;
	self.completed = false;
	var obstacleIcon = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: color,
		scaleX: 0.5,
		scaleY: 0.5
	});
	obstacleIcon.x = 80;
	obstacleIcon.y = 30;
	var challengeText = new Text2('0/' + amount, {
		size: 50,
		fill: "#ffffff",
		stroke: "#000000",
		strokeThickness: 8,
		anchorX: 0.5,
		anchorY: 0.5
	});
	challengeText.x = 150;
	self.addChild(obstacleIcon);
	self.addChild(challengeText);
	self.updateProgress = function () {
		self.amount -= 1;
		challengeText.setText(amount - self.amount + '/' + amount);
		if (self.amount <= 0) {
			self.completed = true;
			if (currentChallenge.every(function (challenge) {
				return challenge.completed;
			})) {
				LK.setScore(LK.getScore() + 50);
				hud.updateScore(LK.getScore());
				showChallengeCompletePopup(self.color);
				currentChallenge.forEach(function (challenge) {
					return challenge.destroy();
				});
				currentChallenge = [];
				startNextChallenge();
			}
		}
	};
});
var CircularObstacle = Container.expand(function (starX, starY, radius, angleSpeed, initialAngle) {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: getRandomTint()
	});
	self.angle = initialAngle || 0;
	self.radius = radius;
	self.angleSpeed = angleSpeed * 0.75;
	self.starX = starX;
	self.starY = starY;
	self.updatePosition = function () {
		self.x = self.starX + Math.cos(self.angle) * self.radius;
		self.y = self.starY + Math.sin(self.angle) * self.radius;
		self.angle += self.angleSpeed * 0.35;
		obstacleGraphics.rotation += self.angleSpeed * 0.35;
	};
	self.moveDown = function (distance, dotY) {
		self.starY += distance * getSpeedMultiplier(dotY);
	};
	self.updatePosition();
});
var Dot = Container.expand(function () {
	var self = Container.call(this);
	var dotGraphics = self.attachAsset('dot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.destroyed = false;
	self.velocityY = 0;
	self.gravity = 0.7;
	self.bounce = -15;
	self._update_migrated = function () {
		if (!dotBouncing) {
			return;
		}
		var previousY = self.y;
		self.velocityY += self.gravity;
		if (self.velocityY > 0 && dotGraphics.scaleX < 1) {
			dotGraphics.scaleX += 0.02;
			dotGraphics.scaleY -= 0.02;
		}
		self.y += self.velocityY;
		if (!self.firstTouch && !self.intersects(hand)) {
			self.y = 2732 - self.height / 2 - 500;
		} else if (self.intersects(hand)) {
			self.bounceUp();
		} else if (self.y > 2232 - self.height / 2 && self.firstTouch && !self.firstStarDestroyed) {
			self.velocityY = self.bounce;
		} else if (self.y > 2832 && !self.destroyed) {
			handleDotDestruction();
		}
		self.movedDistance = self.y - previousY;
	};
	self.bounceUp = function () {
		if (!self.destroyed) {
			self.velocityY = self.bounce;
			dotGraphics.scaleX = 0.8;
			dotGraphics.scaleY = 1.2;
			LK.setTimeout(function () {
				dotGraphics.scaleX = 1.2;
				dotGraphics.scaleY = 0.8;
				LK.setTimeout(function () {
					dotGraphics.scaleX = 1;
					dotGraphics.scaleY = 1;
				}, 100);
			}, 100);
			LK.getSound('bounce').play();
			if (!self.intersects(hand)) {
				createBounceEffect(self.x, self.y, dotGraphics.tint);
			}
			self.firstTouch = true;
			if (!self.firstStarDestroyed) {
				self.firstStarDestroyed = true;
			}
		}
	};
	self.inheritStarColor = function (star) {
		dotGraphics.tint = star.children[0].tint;
	};
});
var DotParticleEffect = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var particles = [];
	var angleIncrement = Math.PI * 2 / 20;
	var speed = 30;
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	for (var i = 0; i < 20; i++) {
		var particle = self.attachAsset('dot', {
			anchorX: 0.5,
			anchorY: 0.5,
			tint: colors[Math.floor(Math.random() * colors.length)]
		});
		particle.scaleX = particle.scaleY = 0.5;
		particle.alpha = 1;
		var angle = i * angleIncrement;
		particle.vx = Math.cos(angle) * speed;
		particle.vy = Math.sin(angle) * speed;
		particles.push(particle);
	}
	self._update_migrated = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].rotation += 0.1; // Rotate the particle
			particles[i].alpha -= 0.0167;
			if (particles[i].alpha <= 0) {
				particles[i].destroy();
				particles.splice(i, 1);
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var HUD = Container.expand(function () {
	var self = Container.call(this);
	// Create background line for HUD
	var backgroundLine = self.attachAsset('backgroundLine', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	backgroundLine.x = 2048 / 2;
	backgroundLine.y = 75;
	// Create score text
	scoreTxt = new Text2('0', {
		size: 150,
		// Reduced size to fit within the HUD
		fill: "#ffffff",
		stroke: "#000000",
		strokeThickness: 8
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.x = 2048 - 200; // Adjusted position to fit within the HUD
	scoreTxt.y = -10; // Adjusted position to fit within the HUD
	self.addChild(scoreTxt);
	// Create challenges container
	var challengesContainer = new Container();
	challengesContainer.scaleX = 1.5;
	challengesContainer.scaleY = 1.5;
	challengesContainer.x = 2048 / 2;
	challengesContainer.y = 60;
	challengesContainer.anchorX = 0.5;
	challengesContainer.anchorY = 0.5;
	challengesContainer.pivotX = challengesContainer.width / 2;
	challengesContainer.pivotY = challengesContainer.height / 2;
	self.addChild(challengesContainer);
	self.updateScore = function (score) {
		scoreTxt.setText(score.toString());
	};
	self.updateChallenges = function (challenges) {
		challengesContainer.removeChildren();
		var totalWidth = challenges.reduce(function (acc, challenge) {
			return acc + challenge.width + 20; // 20px gap
		}, -20); // Subtract the last gap
		var startX = -totalWidth / 2;
		challenges.forEach(function (challenge, i) {
			challenge.x = startX + i * (challenge.width + 20);
			challengesContainer.addChild(challenge);
		});
	};
	return self;
});
// Add Hand asset below the dot
var Hand = Container.expand(function () {
	var self = Container.call(this);
	var handGraphics = self.attachAsset('hand', {
		anchorX: 0.5,
		anchorY: 0,
		alpha: 0.9
	});
	self._update_migrated = function (distance) {
		if (distance) {
			self.y += distance;
		}
	};
});
var MainMenu = Container.expand(function () {
	var self = Container.call(this);
	// Create background
	var background = self.attachAsset('mainMenuBackground', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 1.0
	});
	background.x = 0;
	background.y = 600;
	// Create Endless button using endless asset
	var endlessButton = self.attachAsset('Endless', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	endlessButton.x = 0;
	endlessButton.y = 800;
	endlessButton.down = function () {
		self.destroy();
		startGame('endless');
	};
	// Create Challenges button using challenges asset
	var challengesButton = self.attachAsset('Challenges', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	challengesButton.x = 0;
	challengesButton.y = 1000;
	challengesButton.down = function () {
		self.destroy();
		startGame('challenges');
	};
	self.addChild(background);
	self.addChild(endlessButton);
	self.addChild(challengesButton);
});
var ObstacleParticleEffect = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var particles = [];
	var angleIncrement = Math.PI * 2 / 30;
	var speed = 20;
	var colors = [0xff6666, 0x00ff00, 0x0000ff, 0xffe066, 0xcc66ff, 0x99ccff].slice(0, CONFIG.numColors);
	for (var i = 0; i < 30; i++) {
		var particle = self.attachAsset('smallObstacle', {
			anchorX: 0.5,
			anchorY: 0.5,
			tint: colors[Math.floor(Math.random() * colors.length)]
		});
		particle.scaleX = particle.scaleY = 0.5;
		particle.alpha = 1;
		var angle = i * angleIncrement;
		particle.vx = Math.cos(angle) * speed;
		particle.vy = Math.sin(angle) * speed;
		particles.push(particle);
	}
	self._update_migrated = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].alpha -= 0.0167;
			if (particles[i].alpha <= 0) {
				particles[i].destroy();
				particles.splice(i, 1);
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var ObstacleScorePopup = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var scoreText = new Text2('+10', {
		size: 100,
		fill: "#ffffff",
		anchorX: 0.5,
		anchorY: 0.5
	});
	scoreText.x = -scoreText.width / 2;
	scoreText.y = -scoreText.height / 2;
	self.addChild(scoreText);
	self.alpha = 1;
	var duration = 120;
	self._update_migrated = function () {
		duration--;
		self.y -= 2;
		self.alpha -= 1 / 120;
		if (duration <= 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var OrbitLine = Container.expand(function (starX, starY, radius) {
	var self = Container.call(this);
	self.starX = starX;
	self.starY = starY;
	self.radius = radius;
	var segments = 50;
	var angleIncrement = Math.PI * 2 / segments;
	for (var i = 0; i < segments; i++) {
		var angle = i * angleIncrement;
		var dot = self.attachAsset('smallObstacle', {
			x: starX + Math.cos(angle) * radius,
			y: starY + Math.sin(angle) * radius,
			anchorX: 0.5,
			anchorY: 0.5,
			tint: [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500][Math.floor(Math.random() * 5)]
		});
		if (i % 2 === 0) {
			dot.alpha = 0;
		}
	}
	self.moveDown = function (distance, dotY) {
		var speedMultiplier = dotY < 1200 ? 3 : dotY < 1400 ? 2 : dotY < 2000 ? 1.3 : dotY < 2300 ? 1.2 : 1;
		self.y += distance * speedMultiplier;
	};
});
var ParticleEffect = Container.expand(function (x, y, color) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var particles = [];
	for (var i = 0; i < 20; i++) {
		var particle = self.attachAsset('star', {
			anchorX: 0.5,
			anchorY: 0.5,
			tint: color
		});
		particle.scaleX = particle.scaleY = Math.random() * 0.5 + 0.5;
		particle.alpha = 0.7;
		particle.vx = (Math.random() - 0.5) * 10;
		particle.vy = (Math.random() - 0.5) * 10;
		particles.push(particle);
	}
	self._update_migrated = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].alpha -= 0.02;
			if (particles[i].alpha <= 0) {
				particles[i].destroy();
				particles.splice(i, 1);
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var ScorePopup = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var scoreText = new Text2('+' + (10 * (starCount + 1)).toString(), {
		size: 100,
		fill: "#ffffff",
		anchorX: 0.5,
		anchorY: 0.5
	});
	scoreText.x = -scoreText.width / 2;
	scoreText.y = -scoreText.height / 2;
	self.addChild(scoreText);
	self.alpha = 1;
	var duration = 120;
	self._update_migrated = function () {
		duration--;
		self.y -= 2;
		self.alpha -= 1 / 120;
		if (duration <= 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var Star = Container.expand(function (starNumber) {
	var self = Container.call(this);
	self.starNumber = starNumber;
	var starGraphics = self.attachAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: getRandomTint()
	});
	self.scaleDirection = 1;
	self.scaleSpeed = 0.005;
	self.minScale = 1;
	self.maxScale = 1.2;
	self.moveDown = function (distance, dotY) {
		self.y += distance * getSpeedMultiplier(dotY);
		if (self.y > 2732 - self.height / 2) {
			self.y = -self.height / 2;
		}
	};
	self.updateScale = function () {
		if (self.scaleDirection === 1 && starGraphics.scale.x < self.maxScale) {
			starGraphics.scale.x += self.scaleSpeed;
			starGraphics.scale.y += self.scaleSpeed;
		} else if (self.scaleDirection === -1 && starGraphics.scale.x > self.minScale) {
			starGraphics.scale.x -= self.scaleSpeed;
			starGraphics.scale.y -= self.scaleSpeed;
		}
		if (starGraphics.scale.x >= self.maxScale || starGraphics.scale.x <= self.minScale) {
			self.scaleDirection *= -1;
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xD3D3D3 // Light gray color
});
/**** 
* Game Code
****/ 
var CONFIG = {
	numColors: 2 // Default number of colors, can be set between 2 and 5
};
var gameMode = 'challenges'; // Default game mode
var mainMenu = new MainMenu();
LK.gui.top.addChild(mainMenu);
var scoreTxt;
var hud = new HUD();
game.addChild(hud);
function getRandomTint() {
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	return colors[Math.floor(Math.random() * Math.min(CONFIG.numColors, colors.length))];
}
function showChallengeCompletePopup(color) {
	var challengeCompletePopup = LK.getAsset('success', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: color,
		alpha: 0
	});
	challengeCompletePopup.x = 2048 / 2;
	challengeCompletePopup.y = 2732 / 2;
	game.addChild(challengeCompletePopup);
	var animationDuration = 120;
	var animationFrame = 0;
	var animationInterval = LK.setInterval(function () {
		if (animationFrame < animationDuration / 2) {
			if (animationFrame === 0) {
				challengeCompletePopup.alpha = 1;
			}
			challengeCompletePopup.scaleX = challengeCompletePopup.scaleY = 1 + 0.5 * (animationFrame / (animationDuration / 2));
		} else {
			challengeCompletePopup.alpha = 1 - (animationFrame - animationDuration / 2) / (animationDuration / 2);
			challengeCompletePopup.scaleX = challengeCompletePopup.scaleY = 1.5 - 0.5 * (animationFrame - animationDuration / 2) / (animationDuration / 2);
		}
		animationFrame++;
		if (animationFrame >= animationDuration) {
			LK.clearInterval(animationInterval);
			challengeCompletePopup.destroy();
		}
	}, 1000 / 60);
}
function getStarColor(starNumber) {
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	return colors[starNumber % Math.min(CONFIG.numColors, colors.length)];
}
function getSpeedMultiplier(dotY) {
	if (dotY < 1200) {
		return 3;
	}
	if (dotY < 1400) {
		return 2;
	}
	if (dotY < 2000) {
		return 1.3;
	}
	return 1.2;
}
function handleDotDestruction() {
	createDotParticleEffect(dot.x, dot.y);
	LK.getSound('explosion').play();
	dot.destroyed = true;
	dot.destroy();
	LK.setTimeout(function () {
		LK.showGameOver();
	}, 1000);
}
function createBounceEffect(x, y, color) {
	var effect = new BounceEffect(x, y + 80, color); // Adjust y position to start from a little more lower on the ball
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
var shrinkFrame = 0;
var shrinkDuration = 60;
function startGame(mode) {
	gameMode = mode;
	dot = game.addChild(new Dot());
	dot.x = 2048 / 2;
	dot.y = 2732 - dot.height / 2 - 200;
	dotBouncing = true;
	hand = new Hand();
	game.addChild(hand);
	hand.x = dot.x;
	hand.y = dot.y + dot.height / 2;
	if (mode === 'endless') {
		CONFIG.numColors = 5;
		// Start endless mode
		// Add your endless mode initialization code here
		hud.removeChild(hud.children[0]); // Remove HUD background
		CONFIG.numColors = 2;
	} else if (mode === 'challenges') {
		// Start challenges mode
		startNextChallenge();
	}
}
// Pregame screen removed
var challenges = [{
	obstacles: [{
		color: 0xffe066,
		amount: 1
	}]
}, {
	obstacles: [{
		color: 0xcc66ff,
		amount: 1
	}, {
		color: 0xff6666,
		amount: 1
	}]
}, {
	obstacles: [{
		color: 0xff6666,
		amount: 1
	}, {
		color: 0x99ccff,
		amount: 1
	}, {
		color: 0xffa500,
		amount: 1
	}]
}, {
	obstacles: [{
		color: 0x99ccff,
		amount: 4
	}]
}, {
	obstacles: [{
		color: 0xffa500,
		amount: 5
	}]
}];
var currentChallengeIndex = 0;
var currentChallenge = null;
function startNextChallenge() {
	if (gameMode === 'endless') {
		return;
	}
	if (currentChallengeIndex < challenges.length) {
		var challengeData = challenges[currentChallengeIndex];
		var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
		currentChallenge = challengeData.obstacles.map(function (obstacleData, i) {
			var challengeColor = colors[i % colors.length];
			var challenge = game.addChild(new Challenge(challengeColor, obstacleData.amount));
			return challenge;
		});
		var totalWidth = currentChallenge.reduce(function (acc, challenge) {
			return acc + challenge.width + 20; // 20px gap
		}, -20); // Subtract the last gap
		hud.updateChallenges(currentChallenge);
		hud.updateScore(LK.getScore()); // Ensure score is updated in the HUD
	}
	currentChallengeIndex++;
}
// startNextChallenge(); // Removed initial call to startNextChallenge
function createObstacleParticleEffect(x, y) {
	var effect = new ObstacleParticleEffect(x, y);
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
function changeStarColor(star) {
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	var currentColorIndex = colors.indexOf(star.children[0].tint);
	var nextColorIndex = (currentColorIndex + 1) % Math.min(CONFIG.numColors, colors.length);
	star.children[0].tint = colors[nextColorIndex];
}
function updateStarColors() {
	for (var i = 0; i < stars.length; i++) {
		changeStarColor(stars[i]);
	}
}
LK.setInterval(updateStarColors, 2000);
var starCount = 0;
// Initialize the offscreen threshold for destroying obstacles
var offscreenThreshold = 2732 + 1000;
function createParticleEffect(x, y, color) {
	var effect = new ParticleEffect(x, y, color);
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
function createDotParticleEffect(x, y) {
	var effect = new DotParticleEffect(x, y);
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
var obstacles = [];
function updateObstacles() {
	var obstacleCount = 5 + starCount;
	while (obstacles.length < obstacleCount) {
		var obstacle = game.addChild(new Obstacle());
		obstacle.x = obstacle.direction === 1 ? -obstacle.width / 2 : 2048 + obstacle.width / 2;
		obstacle.y = Math.random() * (2732 - obstacle.height) + obstacle.height / 2;
		obstacles.push(obstacle);
	}
}
// Removed duplicate score text initialization and addition to the screen
game.on('down', function (x, y, obj) {
	if (dot) {
		dot.bounceUp();
	}
});
var stars = [];
var star = game.addChildAt(new Star(), 1);
star.x = 2048 / 2;
star.y = 2732 / 2 - 500;
stars.push(star);
LK.setInterval(function () {
	changeStarColor(star);
}, 1000); // Initialize star with a random color from the obstacles
// Add dotted orbit for the first star
var orbitLine = game.addChild(new OrbitLine(star.x, star.y, 300));
obstacles.push(orbitLine);
function spawnInitialObstacles() {
	var starX = 2048 / 2;
	var starY = 2732 / 2 - 500;
	var radius = 300;
	var angleSpeed = 0.05;
	var obstacle = new CircularObstacle(starX, starY, radius, angleSpeed);
	game.addChildAt(obstacle, 1);
	obstacles.push(obstacle);
	// No additional obstacles for the first star
}
spawnInitialObstacles();
game.addChild(hud);
LK.on('tick', function () {
	if (dot) {
		dot._update_migrated();
	}
	for (var i = 0; i < obstacles.length; i++) {
		if (obstacles[i] instanceof CircularObstacle) {
			obstacles[i].updatePosition();
		} else {
			if (typeof obstacles[i]._move_migrated === 'function') {
				obstacles[i]._move_migrated();
			}
		}
		if (dot && dot.y < 2300 && dot.movedDistance < 0) {
			obstacles[i].moveDown(-dot.movedDistance, dot.y);
		}
		if (dot && dot.intersects && dot.intersects(obstacles[i]) && !(obstacles[i] instanceof OrbitLine)) {
			if (dot.children[0].tint === obstacles[i].children[0].tint) {
				createObstacleParticleEffect(obstacles[i].x, obstacles[i].y);
				LK.setScore(LK.getScore() + 10);
				hud.updateScore(LK.getScore());
				var obstacleScorePopup = new ObstacleScorePopup(obstacles[i].x, obstacles[i].y);
				LK.on('tick', function () {
					obstacleScorePopup._update_migrated();
				});
				LK.getSound('obstacle').play();
				// Update challenge progress before destroying the obstacle
				if (currentChallenge) {
					for (var j = 0; j < currentChallenge.length; j++) {
						if (obstacles[i].children[0].tint === currentChallenge[j].color) {
							currentChallenge[j].updateProgress();
							if (currentChallenge[j].completed) {
								currentChallenge.splice(j, 1);
								if (currentChallenge.length === 0) {
									startNextChallenge();
								}
							}
							break;
						}
					}
				}
				obstacles[i].destroy();
				obstacles.splice(i, 1);
			} else {
				if (!dot.destroyed) {
					createDotParticleEffect(dot.x, dot.y);
					LK.getSound('explosion').play();
					dot.destroyed = true;
				}
				dot.destroy();
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 1500);
			}
		} else if (obstacles[i].y > offscreenThreshold) {
			obstacles[i].destroy();
			obstacles.splice(i, 1);
		}
	}
	for (var j = stars.length - 1; j >= 0; j--) {
		stars[j].updateScale();
		if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {
			dot.inheritStarColor(stars[j]);
			LK.setScore(LK.getScore() + 10 * (starCount + 1));
			hud.updateScore(LK.getScore());
			var oldStarY = stars[j].y;
			createParticleEffect(stars[j].x, stars[j].y, stars[j].children[0].tint);
			LK.getSound('star').play();
			var scorePopup = new ScorePopup(stars[j].x, stars[j].y);
			LK.on('tick', function () {
				scorePopup._update_migrated();
			});
			stars[j].destroy();
			stars.splice(j, 1);
			starCount += 1;
			var newStar = game.addChildAt(new Star(), 1);
			newStar.x = 2048 / 2;
			var additionalYOffset = starCount > 1 ? (starCount - 1) * 200 : 0;
			newStar.y = oldStarY - 2000 - additionalYOffset;
			stars.push(newStar);
			// Ensure new star also has the color change function
			changeStarColor(newStar);
			if (!handMoved && hand) {
				var handMoveDistance = 0;
				var handMoveInterval = LK.setInterval(function () {
					handMoveDistance += 1;
					hand._update_migrated(handMoveDistance);
					if (handMoveDistance >= 1000) {
						LK.clearInterval(handMoveInterval);
					}
				}, 10);
				handMoved = true;
			}
			// Increase the offscreen threshold for destroying obstacles
			offscreenThreshold += 300;
			// Add a cumulative number of CircularObstacles at random positions around the new star
			var cumulativeObstacles = 1 + starCount;
			for (var k = 0; k < cumulativeObstacles; k++) {
				var randomAngle = Math.random() * Math.PI * 2; // Random angle in radians
				var radiusOffset = k * 100;
				var circularObstacle = game.addChildAt(new CircularObstacle(newStar.x, newStar.y, 300 + radiusOffset, 0.05 * (k % 2 === 0 ? 1 : -1), randomAngle), 1);
				obstacles.push(circularObstacle);
			}
			// Add orbit line before creating all obstacles
			var orbitLine = new OrbitLine(newStar.x, newStar.y, 300 + radiusOffset);
			game.addChildAt(orbitLine, 1);
			obstacles.push(orbitLine);
		} else if (dot.y < 2300 && dot.movedDistance < 0) {
			stars[j].moveDown(-dot.movedDistance, dot.y);
		}
	}
});
var dot = null;
var dotBouncing = false;
var hand;
var handMoved = false;
function createHand() {
	hand = new Hand();
	game.addChild(hand);
	hand.x = dot.x;
	hand.y = dot.y + dot.height / 2;
}
var motivationalWords = ["Great Job!", "Well Done!", "Keep Going!", "Awesome!", "Fantastic!", "Superb!", "Excellent!", "Nice Work!", "Bravo!"]; /**** 
* Classes
****/ 
var BounceEffect = Container.expand(function (x, y, color) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var bounceGraphics = self.attachAsset('bounceEffect', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bounceGraphics.tint = color;
	var duration = 30;
	self._update_migrated = function () {
		duration--;
		bounceGraphics.scaleX += 0.1;
		bounceGraphics.scaleY += 0.1;
		bounceGraphics.alpha -= 0.033;
		bounceGraphics.scaleX -= 0.01;
		bounceGraphics.scaleY -= 0.01;
		if (duration <= 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var Challenge = Container.expand(function (color, amount) {
	var self = Container.call(this);
	self.color = color;
	self.amount = amount;
	self.completed = false;
	var obstacleIcon = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: color,
		scaleX: 0.5,
		scaleY: 0.5
	});
	obstacleIcon.x = 80;
	obstacleIcon.y = 30;
	var challengeText = new Text2('0/' + amount, {
		size: 50,
		fill: "#ffffff",
		stroke: "#000000",
		strokeThickness: 8,
		anchorX: 0.5,
		anchorY: 0.5
	});
	challengeText.x = 150;
	self.addChild(obstacleIcon);
	self.addChild(challengeText);
	self.updateProgress = function () {
		self.amount -= 1;
		challengeText.setText(amount - self.amount + '/' + amount);
		if (self.amount <= 0) {
			self.completed = true;
			if (currentChallenge.every(function (challenge) {
				return challenge.completed;
			})) {
				LK.setScore(LK.getScore() + 50);
				hud.updateScore(LK.getScore());
				showChallengeCompletePopup(self.color);
				currentChallenge.forEach(function (challenge) {
					return challenge.destroy();
				});
				currentChallenge = [];
				startNextChallenge();
			}
		}
	};
});
var CircularObstacle = Container.expand(function (starX, starY, radius, angleSpeed, initialAngle) {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: getRandomTint()
	});
	self.angle = initialAngle || 0;
	self.radius = radius;
	self.angleSpeed = angleSpeed * 0.75;
	self.starX = starX;
	self.starY = starY;
	self.updatePosition = function () {
		self.x = self.starX + Math.cos(self.angle) * self.radius;
		self.y = self.starY + Math.sin(self.angle) * self.radius;
		self.angle += self.angleSpeed * 0.35;
		obstacleGraphics.rotation += self.angleSpeed * 0.35;
	};
	self.moveDown = function (distance, dotY) {
		self.starY += distance * getSpeedMultiplier(dotY);
	};
	self.updatePosition();
});
var Dot = Container.expand(function () {
	var self = Container.call(this);
	var dotGraphics = self.attachAsset('dot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.destroyed = false;
	self.velocityY = 0;
	self.gravity = 0.7;
	self.bounce = -15;
	self._update_migrated = function () {
		if (!dotBouncing) {
			return;
		}
		var previousY = self.y;
		self.velocityY += self.gravity;
		if (self.velocityY > 0 && dotGraphics.scaleX < 1) {
			dotGraphics.scaleX += 0.02;
			dotGraphics.scaleY -= 0.02;
		}
		self.y += self.velocityY;
		if (!self.firstTouch && !self.intersects(hand)) {
			self.y = 2732 - self.height / 2 - 500;
		} else if (self.intersects(hand)) {
			self.bounceUp();
		} else if (self.y > 2232 - self.height / 2 && self.firstTouch && !self.firstStarDestroyed) {
			self.velocityY = self.bounce;
		} else if (self.y > 2832 && !self.destroyed) {
			handleDotDestruction();
		}
		self.movedDistance = self.y - previousY;
	};
	self.bounceUp = function () {
		if (!self.destroyed) {
			self.velocityY = self.bounce;
			dotGraphics.scaleX = 0.8;
			dotGraphics.scaleY = 1.2;
			LK.setTimeout(function () {
				dotGraphics.scaleX = 1.2;
				dotGraphics.scaleY = 0.8;
				LK.setTimeout(function () {
					dotGraphics.scaleX = 1;
					dotGraphics.scaleY = 1;
				}, 100);
			}, 100);
			LK.getSound('bounce').play();
			if (!self.intersects(hand)) {
				createBounceEffect(self.x, self.y, dotGraphics.tint);
			}
			self.firstTouch = true;
			if (!self.firstStarDestroyed) {
				self.firstStarDestroyed = true;
			}
		}
	};
	self.inheritStarColor = function (star) {
		dotGraphics.tint = star.children[0].tint;
	};
});
var DotParticleEffect = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var particles = [];
	var angleIncrement = Math.PI * 2 / 20;
	var speed = 30;
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	for (var i = 0; i < 20; i++) {
		var particle = self.attachAsset('dot', {
			anchorX: 0.5,
			anchorY: 0.5,
			tint: colors[Math.floor(Math.random() * colors.length)]
		});
		particle.scaleX = particle.scaleY = 0.5;
		particle.alpha = 1;
		var angle = i * angleIncrement;
		particle.vx = Math.cos(angle) * speed;
		particle.vy = Math.sin(angle) * speed;
		particles.push(particle);
	}
	self._update_migrated = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].rotation += 0.1; // Rotate the particle
			particles[i].alpha -= 0.0167;
			if (particles[i].alpha <= 0) {
				particles[i].destroy();
				particles.splice(i, 1);
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var HUD = Container.expand(function () {
	var self = Container.call(this);
	// Create background line for HUD
	var backgroundLine = self.attachAsset('backgroundLine', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	backgroundLine.x = 2048 / 2;
	backgroundLine.y = 75;
	// Create score text
	scoreTxt = new Text2('0', {
		size: 150,
		// Reduced size to fit within the HUD
		fill: "#ffffff",
		stroke: "#000000",
		strokeThickness: 8
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.x = 2048 - 200; // Adjusted position to fit within the HUD
	scoreTxt.y = -10; // Adjusted position to fit within the HUD
	self.addChild(scoreTxt);
	// Create challenges container
	var challengesContainer = new Container();
	challengesContainer.scaleX = 1.5;
	challengesContainer.scaleY = 1.5;
	challengesContainer.x = 2048 / 2;
	challengesContainer.y = 60;
	challengesContainer.anchorX = 0.5;
	challengesContainer.anchorY = 0.5;
	challengesContainer.pivotX = challengesContainer.width / 2;
	challengesContainer.pivotY = challengesContainer.height / 2;
	self.addChild(challengesContainer);
	self.updateScore = function (score) {
		scoreTxt.setText(score.toString());
	};
	self.updateChallenges = function (challenges) {
		challengesContainer.removeChildren();
		var totalWidth = challenges.reduce(function (acc, challenge) {
			return acc + challenge.width + 20; // 20px gap
		}, -20); // Subtract the last gap
		var startX = -totalWidth / 2;
		challenges.forEach(function (challenge, i) {
			challenge.x = startX + i * (challenge.width + 20);
			challengesContainer.addChild(challenge);
		});
	};
	return self;
});
// Add Hand asset below the dot
var Hand = Container.expand(function () {
	var self = Container.call(this);
	var handGraphics = self.attachAsset('hand', {
		anchorX: 0.5,
		anchorY: 0,
		alpha: 0.9
	});
	self._update_migrated = function (distance) {
		if (distance) {
			self.y += distance;
		}
	};
});
var MainMenu = Container.expand(function () {
	var self = Container.call(this);
	// Create background
	var background = self.attachAsset('mainMenuBackground', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 1.0
	});
	background.x = 0;
	background.y = 600;
	// Create Endless button using endless asset
	var endlessButton = self.attachAsset('Endless', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	endlessButton.x = 0;
	endlessButton.y = 800;
	endlessButton.down = function () {
		self.destroy();
		startGame('endless');
	};
	// Create Challenges button using challenges asset
	var challengesButton = self.attachAsset('Challenges', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	challengesButton.x = 0;
	challengesButton.y = 1000;
	challengesButton.down = function () {
		self.destroy();
		startGame('challenges');
	};
	self.addChild(background);
	self.addChild(endlessButton);
	self.addChild(challengesButton);
});
var ObstacleParticleEffect = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var particles = [];
	var angleIncrement = Math.PI * 2 / 30;
	var speed = 20;
	var colors = [0xff6666, 0x00ff00, 0x0000ff, 0xffe066, 0xcc66ff, 0x99ccff].slice(0, CONFIG.numColors);
	for (var i = 0; i < 30; i++) {
		var particle = self.attachAsset('smallObstacle', {
			anchorX: 0.5,
			anchorY: 0.5,
			tint: colors[Math.floor(Math.random() * colors.length)]
		});
		particle.scaleX = particle.scaleY = 0.5;
		particle.alpha = 1;
		var angle = i * angleIncrement;
		particle.vx = Math.cos(angle) * speed;
		particle.vy = Math.sin(angle) * speed;
		particles.push(particle);
	}
	self._update_migrated = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].alpha -= 0.0167;
			if (particles[i].alpha <= 0) {
				particles[i].destroy();
				particles.splice(i, 1);
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var ObstacleScorePopup = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var scoreText = new Text2('+10', {
		size: 100,
		fill: "#ffffff",
		anchorX: 0.5,
		anchorY: 0.5
	});
	scoreText.x = -scoreText.width / 2;
	scoreText.y = -scoreText.height / 2;
	self.addChild(scoreText);
	self.alpha = 1;
	var duration = 120;
	self._update_migrated = function () {
		duration--;
		self.y -= 2;
		self.alpha -= 1 / 120;
		if (duration <= 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var OrbitLine = Container.expand(function (starX, starY, radius) {
	var self = Container.call(this);
	self.starX = starX;
	self.starY = starY;
	self.radius = radius;
	var segments = 50;
	var angleIncrement = Math.PI * 2 / segments;
	for (var i = 0; i < segments; i++) {
		var angle = i * angleIncrement;
		var dot = self.attachAsset('smallObstacle', {
			x: starX + Math.cos(angle) * radius,
			y: starY + Math.sin(angle) * radius,
			anchorX: 0.5,
			anchorY: 0.5,
			tint: [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500][Math.floor(Math.random() * 5)]
		});
		if (i % 2 === 0) {
			dot.alpha = 0;
		}
	}
	self.moveDown = function (distance, dotY) {
		var speedMultiplier = dotY < 1200 ? 3 : dotY < 1400 ? 2 : dotY < 2000 ? 1.3 : dotY < 2300 ? 1.2 : 1;
		self.y += distance * speedMultiplier;
	};
});
var ParticleEffect = Container.expand(function (x, y, color) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var particles = [];
	for (var i = 0; i < 20; i++) {
		var particle = self.attachAsset('star', {
			anchorX: 0.5,
			anchorY: 0.5,
			tint: color
		});
		particle.scaleX = particle.scaleY = Math.random() * 0.5 + 0.5;
		particle.alpha = 0.7;
		particle.vx = (Math.random() - 0.5) * 10;
		particle.vy = (Math.random() - 0.5) * 10;
		particles.push(particle);
	}
	self._update_migrated = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].alpha -= 0.02;
			if (particles[i].alpha <= 0) {
				particles[i].destroy();
				particles.splice(i, 1);
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var ScorePopup = Container.expand(function (x, y) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var scoreText = new Text2('+' + (10 * (starCount + 1)).toString(), {
		size: 100,
		fill: "#ffffff",
		anchorX: 0.5,
		anchorY: 0.5
	});
	scoreText.x = -scoreText.width / 2;
	scoreText.y = -scoreText.height / 2;
	self.addChild(scoreText);
	self.alpha = 1;
	var duration = 120;
	self._update_migrated = function () {
		duration--;
		self.y -= 2;
		self.alpha -= 1 / 120;
		if (duration <= 0) {
			self.destroy();
		}
	};
	game.addChild(self);
});
var Star = Container.expand(function (starNumber) {
	var self = Container.call(this);
	self.starNumber = starNumber;
	var starGraphics = self.attachAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: getRandomTint()
	});
	self.scaleDirection = 1;
	self.scaleSpeed = 0.005;
	self.minScale = 1;
	self.maxScale = 1.2;
	self.moveDown = function (distance, dotY) {
		self.y += distance * getSpeedMultiplier(dotY);
		if (self.y > 2732 - self.height / 2) {
			self.y = -self.height / 2;
		}
	};
	self.updateScale = function () {
		if (self.scaleDirection === 1 && starGraphics.scale.x < self.maxScale) {
			starGraphics.scale.x += self.scaleSpeed;
			starGraphics.scale.y += self.scaleSpeed;
		} else if (self.scaleDirection === -1 && starGraphics.scale.x > self.minScale) {
			starGraphics.scale.x -= self.scaleSpeed;
			starGraphics.scale.y -= self.scaleSpeed;
		}
		if (starGraphics.scale.x >= self.maxScale || starGraphics.scale.x <= self.minScale) {
			self.scaleDirection *= -1;
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xD3D3D3 // Light gray color
});
/**** 
* Game Code
****/ 
var CONFIG = {
	numColors: 2 // Default number of colors, can be set between 2 and 5
};
var gameMode = 'challenges'; // Default game mode
var mainMenu = new MainMenu();
LK.gui.top.addChild(mainMenu);
var scoreTxt;
var hud = new HUD();
game.addChild(hud);
function getRandomTint() {
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	return colors[Math.floor(Math.random() * Math.min(CONFIG.numColors, colors.length))];
}
function showChallengeCompletePopup(color) {
	var challengeCompletePopup = LK.getAsset('success', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: color,
		alpha: 0
	});
	challengeCompletePopup.x = 2048 / 2;
	challengeCompletePopup.y = 2732 / 2;
	game.addChild(challengeCompletePopup);
	var animationDuration = 120;
	var animationFrame = 0;
	var animationInterval = LK.setInterval(function () {
		if (animationFrame < animationDuration / 2) {
			if (animationFrame === 0) {
				challengeCompletePopup.alpha = 1;
			}
			challengeCompletePopup.scaleX = challengeCompletePopup.scaleY = 1 + 0.5 * (animationFrame / (animationDuration / 2));
		} else {
			challengeCompletePopup.alpha = 1 - (animationFrame - animationDuration / 2) / (animationDuration / 2);
			challengeCompletePopup.scaleX = challengeCompletePopup.scaleY = 1.5 - 0.5 * (animationFrame - animationDuration / 2) / (animationDuration / 2);
		}
		animationFrame++;
		if (animationFrame >= animationDuration) {
			LK.clearInterval(animationInterval);
			challengeCompletePopup.destroy();
		}
	}, 1000 / 60);
}
function getStarColor(starNumber) {
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	return colors[starNumber % Math.min(CONFIG.numColors, colors.length)];
}
function getSpeedMultiplier(dotY) {
	if (dotY < 1200) {
		return 3;
	}
	if (dotY < 1400) {
		return 2;
	}
	if (dotY < 2000) {
		return 1.3;
	}
	return 1.2;
}
function handleDotDestruction() {
	createDotParticleEffect(dot.x, dot.y);
	LK.getSound('explosion').play();
	dot.destroyed = true;
	dot.destroy();
	LK.setTimeout(function () {
		LK.showGameOver();
	}, 1000);
}
function createBounceEffect(x, y, color) {
	var effect = new BounceEffect(x, y + 80, color); // Adjust y position to start from a little more lower on the ball
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
var shrinkFrame = 0;
var shrinkDuration = 60;
function startGame(mode) {
	gameMode = mode;
	dot = game.addChild(new Dot());
	dot.x = 2048 / 2;
	dot.y = 2732 - dot.height / 2 - 200;
	dotBouncing = true;
	hand = new Hand();
	game.addChild(hand);
	hand.x = dot.x;
	hand.y = dot.y + dot.height / 2;
	if (mode === 'endless') {
		CONFIG.numColors = 5;
		// Start endless mode
		// Add your endless mode initialization code here
		hud.removeChild(hud.children[0]); // Remove HUD background
		CONFIG.numColors = 2;
	} else if (mode === 'challenges') {
		// Start challenges mode
		startNextChallenge();
	}
}
// Pregame screen removed
var challenges = [{
	obstacles: [{
		color: 0xffe066,
		amount: 1
	}]
}, {
	obstacles: [{
		color: 0xcc66ff,
		amount: 1
	}, {
		color: 0xff6666,
		amount: 1
	}]
}, {
	obstacles: [{
		color: 0xff6666,
		amount: 1
	}, {
		color: 0x99ccff,
		amount: 1
	}, {
		color: 0xffa500,
		amount: 1
	}]
}, {
	obstacles: [{
		color: 0x99ccff,
		amount: 4
	}]
}, {
	obstacles: [{
		color: 0xffa500,
		amount: 5
	}]
}];
var currentChallengeIndex = 0;
var currentChallenge = null;
function startNextChallenge() {
	if (gameMode === 'endless') {
		return;
	}
	if (currentChallengeIndex < challenges.length) {
		var challengeData = challenges[currentChallengeIndex];
		var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
		currentChallenge = challengeData.obstacles.map(function (obstacleData, i) {
			var challengeColor = colors[i % colors.length];
			var challenge = game.addChild(new Challenge(challengeColor, obstacleData.amount));
			return challenge;
		});
		var totalWidth = currentChallenge.reduce(function (acc, challenge) {
			return acc + challenge.width + 20; // 20px gap
		}, -20); // Subtract the last gap
		hud.updateChallenges(currentChallenge);
		hud.updateScore(LK.getScore()); // Ensure score is updated in the HUD
	}
	currentChallengeIndex++;
}
// startNextChallenge(); // Removed initial call to startNextChallenge
function createObstacleParticleEffect(x, y) {
	var effect = new ObstacleParticleEffect(x, y);
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
function changeStarColor(star) {
	var colors = [0xffe066, 0xcc66ff, 0xff6666, 0x99ccff, 0xffa500].slice(0, CONFIG.numColors);
	var currentColorIndex = colors.indexOf(star.children[0].tint);
	var nextColorIndex = (currentColorIndex + 1) % Math.min(CONFIG.numColors, colors.length);
	star.children[0].tint = colors[nextColorIndex];
}
function updateStarColors() {
	for (var i = 0; i < stars.length; i++) {
		changeStarColor(stars[i]);
	}
}
LK.setInterval(updateStarColors, 2000);
var starCount = 0;
// Initialize the offscreen threshold for destroying obstacles
var offscreenThreshold = 2732 + 1000;
function createParticleEffect(x, y, color) {
	var effect = new ParticleEffect(x, y, color);
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
function createDotParticleEffect(x, y) {
	var effect = new DotParticleEffect(x, y);
	LK.on('tick', function () {
		effect._update_migrated();
	});
}
var obstacles = [];
function updateObstacles() {
	var obstacleCount = 5 + starCount;
	while (obstacles.length < obstacleCount) {
		var obstacle = game.addChild(new Obstacle());
		obstacle.x = obstacle.direction === 1 ? -obstacle.width / 2 : 2048 + obstacle.width / 2;
		obstacle.y = Math.random() * (2732 - obstacle.height) + obstacle.height / 2;
		obstacles.push(obstacle);
	}
}
// Removed duplicate score text initialization and addition to the screen
game.on('down', function (x, y, obj) {
	if (dot) {
		dot.bounceUp();
	}
});
var stars = [];
var star = game.addChildAt(new Star(), 1);
star.x = 2048 / 2;
star.y = 2732 / 2 - 500;
stars.push(star);
LK.setInterval(function () {
	changeStarColor(star);
}, 1000); // Initialize star with a random color from the obstacles
// Add dotted orbit for the first star
var orbitLine = game.addChild(new OrbitLine(star.x, star.y, 300));
obstacles.push(orbitLine);
function spawnInitialObstacles() {
	var starX = 2048 / 2;
	var starY = 2732 / 2 - 500;
	var radius = 300;
	var angleSpeed = 0.05;
	var obstacle = new CircularObstacle(starX, starY, radius, angleSpeed);
	game.addChildAt(obstacle, 1);
	obstacles.push(obstacle);
	// No additional obstacles for the first star
}
spawnInitialObstacles();
game.addChild(hud);
LK.on('tick', function () {
	if (dot) {
		dot._update_migrated();
	}
	for (var i = 0; i < obstacles.length; i++) {
		if (obstacles[i] instanceof CircularObstacle) {
			obstacles[i].updatePosition();
		} else {
			if (typeof obstacles[i]._move_migrated === 'function') {
				obstacles[i]._move_migrated();
			}
		}
		if (dot && dot.y < 2300 && dot.movedDistance < 0) {
			obstacles[i].moveDown(-dot.movedDistance, dot.y);
		}
		if (dot && dot.intersects && dot.intersects(obstacles[i]) && !(obstacles[i] instanceof OrbitLine)) {
			if (dot.children[0].tint === obstacles[i].children[0].tint) {
				createObstacleParticleEffect(obstacles[i].x, obstacles[i].y);
				LK.setScore(LK.getScore() + 10);
				hud.updateScore(LK.getScore());
				var obstacleScorePopup = new ObstacleScorePopup(obstacles[i].x, obstacles[i].y);
				LK.on('tick', function () {
					obstacleScorePopup._update_migrated();
				});
				LK.getSound('obstacle').play();
				// Update challenge progress before destroying the obstacle
				if (currentChallenge) {
					for (var j = 0; j < currentChallenge.length; j++) {
						if (obstacles[i].children[0].tint === currentChallenge[j].color) {
							currentChallenge[j].updateProgress();
							if (currentChallenge[j].completed) {
								currentChallenge.splice(j, 1);
								if (currentChallenge.length === 0) {
									startNextChallenge();
								}
							}
							break;
						}
					}
				}
				obstacles[i].destroy();
				obstacles.splice(i, 1);
			} else {
				if (!dot.destroyed) {
					createDotParticleEffect(dot.x, dot.y);
					LK.getSound('explosion').play();
					dot.destroyed = true;
				}
				dot.destroy();
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 1500);
			}
		} else if (obstacles[i].y > offscreenThreshold) {
			obstacles[i].destroy();
			obstacles.splice(i, 1);
		}
	}
	for (var j = stars.length - 1; j >= 0; j--) {
		stars[j].updateScale();
		if (dot && dot.intersects && stars[j] && stars[j].children && stars[j].children[0] && typeof stars[j].children[0].tint !== 'undefined' && stars[j] !== null && typeof stars[j] !== 'undefined' && stars[j].y !== null && typeof stars[j].y !== 'undefined' && dot.intersects(stars[j])) {
			dot.inheritStarColor(stars[j]);
			LK.setScore(LK.getScore() + 10 * (starCount + 1));
			hud.updateScore(LK.getScore());
			var oldStarY = stars[j].y;
			createParticleEffect(stars[j].x, stars[j].y, stars[j].children[0].tint);
			LK.getSound('star').play();
			var scorePopup = new ScorePopup(stars[j].x, stars[j].y);
			LK.on('tick', function () {
				scorePopup._update_migrated();
			});
			stars[j].destroy();
			stars.splice(j, 1);
			starCount += 1;
			var newStar = game.addChildAt(new Star(), 1);
			newStar.x = 2048 / 2;
			var additionalYOffset = starCount > 1 ? (starCount - 1) * 200 : 0;
			newStar.y = oldStarY - 2000 - additionalYOffset;
			stars.push(newStar);
			// Ensure new star also has the color change function
			changeStarColor(newStar);
			if (!handMoved && hand) {
				var handMoveDistance = 0;
				var handMoveInterval = LK.setInterval(function () {
					handMoveDistance += 1;
					hand._update_migrated(handMoveDistance);
					if (handMoveDistance >= 1000) {
						LK.clearInterval(handMoveInterval);
					}
				}, 10);
				handMoved = true;
			}
			// Increase the offscreen threshold for destroying obstacles
			offscreenThreshold += 300;
			// Add a cumulative number of CircularObstacles at random positions around the new star
			var cumulativeObstacles = 1 + starCount;
			for (var k = 0; k < cumulativeObstacles; k++) {
				var randomAngle = Math.random() * Math.PI * 2; // Random angle in radians
				var radiusOffset = k * 100;
				var circularObstacle = game.addChildAt(new CircularObstacle(newStar.x, newStar.y, 300 + radiusOffset, 0.05 * (k % 2 === 0 ? 1 : -1), randomAngle), 1);
				obstacles.push(circularObstacle);
			}
			// Add orbit line before creating all obstacles
			var orbitLine = new OrbitLine(newStar.x, newStar.y, 300 + radiusOffset);
			game.addChildAt(orbitLine, 1);
			obstacles.push(orbitLine);
		} else if (dot.y < 2300 && dot.movedDistance < 0) {
			stars[j].moveDown(-dot.movedDistance, dot.y);
		}
	}
});
var dot = null;
var dotBouncing = false;
var hand;
var handMoved = false;
function createHand() {
	hand = new Hand();
	game.addChild(hand);
	hand.x = dot.x;
	hand.y = dot.y + dot.height / 2;
}
var motivationalWords = ["Great Job!", "Well Done!", "Keep Going!", "Awesome!", "Fantastic!", "Superb!", "Excellent!", "Nice Work!", "Bravo!"];
 Cartoon, white star. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 Cartoon. white circle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 cartoon white dot with eyes (just black dots).. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 cartoon white ring. simple.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 
 
 
 
 cartoon white cloud.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.