/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0
});
/**** 
* Classes
****/ 
var Arrow = Container.expand(function () {
	var self = Container.call(this);
	// Arrow body
	var arrowBody = self.attachAsset('arrow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Arrow tip
	var arrowTip = self.attachAsset('arrowTip', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 65
	});
	// Properties
	self.velocity = {
		x: 0,
		y: 0
	};
	self.gravity = 0.3;
	self.friction = 0.99;
	self.flying = false;
	self.stuck = false;
	self.targetHit = null;
	// Update arrow physics
	self.update = function () {
		if (self.lastX === undefined) {
			self.lastX = self.x;
		}
		if (self.lastY === undefined) {
			self.lastY = self.y;
		}
		if (self.flying && !self.stuck) {
			// Apply physics
			self.velocity.y += self.gravity;
			self.x += self.velocity.x;
			self.y += self.velocity.y;
			// Update rotation to match trajectory
			self.rotation = Math.atan2(self.velocity.y, self.velocity.x);
			// Check if arrow is off-screen
			if (self.y > 2732 || self.x < -100 || self.x > 2148) {
				if (!self.hasHitGround) {
					self.hasHitGround = true;
					LK.getSound('miss').play();
				}
			}
			self.lastX = self.x;
			self.lastY = self.y;
			self.lastWasIntersecting = false; // Reset intersection state for next checks
		}
	};
	// Fire the arrow with given power and angle
	self.fire = function (power, angle) {
		self.flying = true;
		self.velocity.x = Math.cos(angle) * power;
		self.velocity.y = Math.sin(angle) * power;
		self.rotation = angle;
		LK.getSound('bowRelease').play();
	};
	// Stick arrow to target
	self.stickTo = function (target, score) {
		self.stuck = true;
		self.flying = false;
		self.targetHit = target;
		self.score = score;
		// Play sound
		LK.getSound('targetHit').play();
	};
	return self;
});
var Bow = Container.expand(function () {
	var self = Container.call(this);
	// Bow body
	var bowBody = self.attachAsset('bow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Bow string
	var bowString = self.attachAsset('bowString', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: -10
	});
	// Properties
	self.aimAngle = -Math.PI / 4; // Default angle (slightly up)
	self.power = 0;
	self.maxPower = 35;
	self.charging = false;
	// Update bow
	self.update = function () {
		// Update bow rotation to match aim angle
		self.rotation = self.aimAngle;
		// Update string position/appearance based on pull
		if (self.charging) {
			var pullFactor = self.power / self.maxPower;
			bowString.scaleX = 1 + pullFactor * 0.5; // Thicker when pulled
		} else {
			bowString.scaleX = 1;
		}
	};
	// Start charging (pulling back)
	self.startCharging = function () {
		self.charging = true;
		self.power = 0;
	};
	// Continue charging
	self.updateCharging = function () {
		if (self.charging) {
			if (!self.loadingSoundPlayed) {
				LK.getSound('bowLoading').play();
				self.loadingSoundPlayed = true;
			}
			self.power += 0.4;
			if (self.power > self.maxPower) {
				self.power = self.maxPower;
			}
		}
	};
	// Release arrow
	self.releaseArrow = function () {
		var finalPower = self.power;
		self.charging = false;
		self.loadingSoundPlayed = false;
		self.power = 0;
		return finalPower;
	};
	return self;
});
var PowerMeter = Container.expand(function () {
	var self = Container.call(this);
	// Background
	var background = self.attachAsset('powerMeter', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Fill
	var fill = self.attachAsset('powerFill', {
		anchorX: 0.5,
		anchorY: 1,
		// Anchor to bottom
		y: 195 // Half height of background
	});
	fill.height = 0; // Start empty
	// Update power meter
	self.updatePower = function (power, maxPower) {
		var percentage = power / maxPower;
		fill.height = 390 * percentage; // 390 is the max height of fill
		// Change color based on power
		if (percentage < 0.33) {
			fill.tint = 0x00FF00; // Green
		} else if (percentage < 0.66) {
			fill.tint = 0xFFFF00; // Yellow
		} else {
			fill.tint = 0xFF0000; // Red
		}
	};
	return self;
});
var Target = Container.expand(function () {
	var self = Container.call(this);
	// Create rings from outside to inside
	var outerRing = self.attachAsset('target', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var ring1 = self.attachAsset('targetRing1', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var ring2 = self.attachAsset('targetRing2', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var ring3 = self.attachAsset('targetRing3', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var bullseye = self.attachAsset('targetRing4', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Target properties
	self.radius = 100; // Outer radius
	self.direction = 1; // 1 for right, -1 for left
	self.speed = 2;
	self.minX = 300;
	self.maxX = 1748; // 2048 - 300
	// Score values for each ring
	self.scoreValues = [10, 25, 50, 75, 100]; // Outer to inner
	// Update target movement
	self.update = function () {
		if (!self["static"]) {
			self.x += self.speed * self.direction;
			// Reverse direction at edges
			if (self.x > self.maxX || self.x < self.minX) {
				self.direction *= -1;
			}
		}
	};
	// Get score based on distance from center
	self.getScore = function (hitX, hitY) {
		// Calculate distance from center
		var dx = hitX - self.x;
		var dy = hitY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Determine which ring was hit
		if (distance < 20) {
			return self.scoreValues[4]; // Bullseye
		} else if (distance < 40) {
			return self.scoreValues[3];
		} else if (distance < 60) {
			return self.scoreValues[2];
		} else if (distance < 80) {
			return self.scoreValues[1];
		} else if (distance < 100) {
			return self.scoreValues[0]; // Outer ring
		}
		return 0; // Miss
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	// No title, no description
	// Always backgroundColor is black
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Load level function to initialize targets and reset game state
function loadLevel(level) {
	currentLevel = level;
	maxArrows = levels[currentLevel].arrows;
	arrowCount = 0;
	arrows = [];
	initializeTargets();
	gameActive = true;
	arrowsTxt.setText('Arrows: ' + (maxArrows - arrowCount) + '/' + maxArrows);
	levelTxt.setText('Level: ' + (currentLevel + 1)); // Update level display
}
var arrows = [];
var targets = [];
var currentArrow = null;
var arrowCount = 0;
var levels = [{
	targets: 3,
	arrows: 5
}, {
	targets: 5,
	arrows: 7
}, {
	targets: 7,
	arrows: 9
}, {
	targets: 9,
	arrows: 11
}];
var currentLevel = 0;
var maxArrows = levels[currentLevel].arrows;
var totalScore = 0;
var gameActive = true;
var aimPoint = {
	x: 0,
	y: 0
};
var dragStart = {
	x: 0,
	y: 0
};
var isDragging = false;
// Create the background
var skyBackground = game.addChild(LK.getAsset('sky', {
	anchorX: 0,
	anchorY: 0,
	y: 0
}));
var ground = game.addChild(LK.getAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	y: 2532 // Position at bottom of screen
}));
// Create bow
var bow = new Bow();
bow.x = 1024; // Center the bow horizontally on the screen
bow.y = 2500; // Position near bottom
game.addChild(bow);
// Create power meter
var powerMeter = new PowerMeter();
powerMeter.x = 100;
powerMeter.y = 1800;
game.addChild(powerMeter);
// Create targets
function createTarget(x, y, isStatic, speed) {
	var target = new Target();
	target.x = x;
	target.y = y;
	target["static"] = isStatic;
	if (speed !== undefined) {
		target.speed = speed;
	}
	game.addChild(target);
	targets.push(target);
	return target;
}
// Create initial targets based on current level
function initializeTargets() {
	targets = [];
	for (var i = 0; i < levels[currentLevel].targets; i++) {
		var x = 300 + Math.random() * 1448; // Random x position within bounds
		var y = 500 + i * 300; // Staggered y positions
		var speed = 2 + Math.random() * 4; // Random speed between 2 and 6
		createTarget(x, y, false, speed);
	}
}
initializeTargets();
// Score display
var scoreTxt = new Text2('Score: 0', {
	size: 80,
	fill: 0x0000FF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Arrows left display
var arrowsTxt = new Text2('Arrows: ' + (maxArrows - arrowCount) + '/' + maxArrows, {
	size: 80,
	fill: 0x00FF00
});
arrowsTxt.anchor.set(0.5, 0);
arrowsTxt.y = 100;
LK.gui.top.addChild(arrowsTxt);
// High score display
var highScoreTxt = new Text2('High Score: ' + storage.highScore, {
	size: 60,
	fill: 0xFFA500
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.y = 20;
LK.gui.topRight.addChild(highScoreTxt);
// Level display
var levelTxt = new Text2('Level: ' + (currentLevel + 1), {
	size: 80,
	fill: 0x800080
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 20;
levelTxt.y = 20;
LK.gui.topLeft.addChild(levelTxt);
// Aim guide
var aimGuideTxt = new Text2('Touch and drag to aim, release to shoot', {
	size: 60,
	fill: 0xFF0000
});
aimGuideTxt.anchor.set(0.5, 0);
aimGuideTxt.y = 200;
LK.gui.top.addChild(aimGuideTxt);
// Create a new arrow
function createArrow() {
	if (arrowCount >= maxArrows) {
		if (arrows.length === 0) {
			// Check if all arrows have been used and none are flying
			LK.showGameOver(); // Trigger game over
		}
		return null;
	}
	var arrow = new Arrow();
	arrow.x = bow.x;
	arrow.y = bow.y;
	arrow.rotation = bow.aimAngle;
	game.addChild(arrow);
	arrows.push(arrow);
	arrowCount++;
	// Update arrows left display
	arrowsTxt.setText('Arrows: ' + (maxArrows - arrowCount) + '/' + maxArrows);
	return arrow;
}
// Handle collision between arrow and targets
function checkArrowCollisions() {
	for (var i = 0; i < arrows.length; i++) {
		var arrow = arrows[i];
		if (arrow.flying && !arrow.stuck) {
			// Check collision with each target
			for (var j = 0; j < targets.length; j++) {
				var target = targets[j];
				// Arrow tip position
				var tipX = arrow.x + Math.cos(arrow.rotation) * 65;
				var tipY = arrow.y + Math.sin(arrow.rotation) * 65;
				// Check if tip is inside target
				var dx = tipX - target.x;
				var dy = tipY - target.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (arrow.lastWasIntersecting === undefined) {
					arrow.lastWasIntersecting = false;
				}
				if (!arrow.lastWasIntersecting && distance <= target.radius) {
					if (!target._hit) {
						// Prevent double-count
						target._hit = true;
						arrow.lastWasIntersecting = true; // Ensure we update the intersection state
						// Hit! Calculate score
						var score = target.getScore(tipX, tipY);
						totalScore += score;
						scoreTxt.setText('Score: ' + totalScore);
						// Stick arrow to target and remove from screen
						arrow.stickTo(target, score);
						arrow.destroy();
						arrows.splice(i, 1);
						// Create explosion effect
						var explosion = new Container();
						var explosionParticle = LK.getAsset('target', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						explosion.addChild(explosionParticle);
						explosion.x = target.x;
						explosion.y = target.y;
						game.addChild(explosion);
						// Animate explosion effect
						tween(explosion, {
							scaleX: 2,
							scaleY: 2,
							alpha: 0
						}, {
							duration: 500,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								explosion.destroy();
							}
						});
						// Remove the hit target
						targets.splice(j, 1);
						target.destroy();
						arrow.lastWasIntersecting = false; // Reset intersection state for next checks
						// Create score popup
						var scorePop = new Text2("+" + score, {
							size: 60,
							fill: 0xFFFF00
						});
						scorePop.x = tipX;
						scorePop.y = tipY;
						game.addChild(scorePop);
						// Animate score popup
						tween(scorePop, {
							y: scorePop.y - 100,
							alpha: 0
						}, {
							duration: 1000,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								scorePop.destroy();
							}
						});
						break;
					}
					arrow.lastWasIntersecting = distance <= target.radius;
				}
			}
		}
		// Move arrows that are stuck to targets with the targets
		if (arrow.stuck && arrow.targetHit) {
			var targetPos = arrow.targetHit;
			var dx = arrow.x - targetPos.x;
			var dy = arrow.y - targetPos.y;
			arrow.x = targetPos.x + dx;
			arrow.y = targetPos.y + dy;
		}
	}
}
// Check if game is over
function checkGameOver() {
	if (arrowCount >= maxArrows && arrows.length === 0) {
		var allArrowsLanded = true;
		// Check if all arrows have landed
		for (var i = 0; i < arrows.length; i++) {
			if (arrows[i].flying) {
				allArrowsLanded = false;
				break;
			}
		}
		if (allArrowsLanded && gameActive) {
			gameActive = false;
			console.log("Game Over: All arrows used and not all targets hit."); // Debugging log
			// Update high score if needed
			if (totalScore > storage.highScore) {
				storage.highScore = totalScore;
				highScoreTxt.setText('High Score: ' + storage.highScore);
			}
			// Check if all targets are hit or score condition for level 1 is met
			if (targets.length === 0 || currentLevel === 0 && totalScore >= 30) {
				// Create level up text
				var levelUpTxt = new Text2('Level Up!', {
					size: 120,
					fill: 0xFFFF00
				});
				levelUpTxt.anchor.set(0.5, 0.5);
				levelUpTxt.x = 1024; // Center horizontally
				levelUpTxt.y = 1366; // Center vertically
				game.addChild(levelUpTxt);
				// Tween effect for level up text
				tween(levelUpTxt, {
					alpha: 0
				}, {
					duration: 2000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						levelUpTxt.destroy();
						currentLevel++;
						if (currentLevel < levels.length) {
							// Advance to next level using loadLevel function
							loadLevel(currentLevel);
							levelTxt.setText('Level: 27'); // Update level text to 27 
							levels[currentLevel].targets += 5; // Add 5 targets 
							initializeTargets(); // Reinitialize targets for the new level
						} else {
							// All levels completed, show game over
							LK.setTimeout(function () {
								LK.showGameOver();
							}, 2000);
						}
					}
				});
			} else {
				// Wait 2 seconds before showing game over
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 2000);
			}
		}
	}
}
// Game loop
game.update = function () {
	// Update all targets
	for (var i = 0; i < targets.length; i++) {
		targets[i].update();
	}
	// Update all arrows
	for (var i = 0; i < arrows.length; i++) {
		arrows[i].update();
	}
	// Update bow charging
	if (bow.charging) {
		bow.updateCharging();
		powerMeter.updatePower(bow.power, bow.maxPower);
	}
	// Check for collisions
	checkArrowCollisions();
	// Check if game is over
	checkGameOver();
};
// Touch/mouse events
game.down = function (x, y, obj) {
	if (!gameActive || arrowCount >= maxArrows) {
		return;
	}
	isDragging = true;
	dragStart.x = x;
	dragStart.y = y;
	// Start charging bow
	bow.startCharging();
	// Hide aim guide
	aimGuideTxt.alpha = 0;
	// Create new arrow
	currentArrow = createArrow();
};
game.move = function (x, y, obj) {
	if (!isDragging || !currentArrow) {
		return;
	}
	// Calculate aim angle
	var dx = dragStart.x - x;
	var dy = dragStart.y - y;
	var angle = Math.atan2(dy, dx);
	// Constrain angle (can't aim down into ground or directly backward)
	if (angle > 0 && angle < Math.PI / 2) {
		angle = 0;
	} else if (angle > Math.PI / 2 && angle < Math.PI) {
		angle = Math.PI;
	}
	bow.aimAngle = angle;
	// Position current arrow
	currentArrow.x = bow.x;
	currentArrow.y = bow.y;
	currentArrow.rotation = angle;
};
game.up = function (x, y, obj) {
	if (!isDragging || !currentArrow) {
		return;
	}
	isDragging = false;
	// Fire arrow with current power and angle
	var power = bow.releaseArrow();
	currentArrow.fire(power, bow.aimAngle);
	// Reset power meter
	powerMeter.updatePower(0, bow.maxPower);
	currentArrow = null;
};
// Play background music
LK.playMusic('bgMusic'); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0
});
/**** 
* Classes
****/ 
var Arrow = Container.expand(function () {
	var self = Container.call(this);
	// Arrow body
	var arrowBody = self.attachAsset('arrow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Arrow tip
	var arrowTip = self.attachAsset('arrowTip', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 65
	});
	// Properties
	self.velocity = {
		x: 0,
		y: 0
	};
	self.gravity = 0.3;
	self.friction = 0.99;
	self.flying = false;
	self.stuck = false;
	self.targetHit = null;
	// Update arrow physics
	self.update = function () {
		if (self.lastX === undefined) {
			self.lastX = self.x;
		}
		if (self.lastY === undefined) {
			self.lastY = self.y;
		}
		if (self.flying && !self.stuck) {
			// Apply physics
			self.velocity.y += self.gravity;
			self.x += self.velocity.x;
			self.y += self.velocity.y;
			// Update rotation to match trajectory
			self.rotation = Math.atan2(self.velocity.y, self.velocity.x);
			// Check if arrow is off-screen
			if (self.y > 2732 || self.x < -100 || self.x > 2148) {
				if (!self.hasHitGround) {
					self.hasHitGround = true;
					LK.getSound('miss').play();
				}
			}
			self.lastX = self.x;
			self.lastY = self.y;
			self.lastWasIntersecting = false; // Reset intersection state for next checks
		}
	};
	// Fire the arrow with given power and angle
	self.fire = function (power, angle) {
		self.flying = true;
		self.velocity.x = Math.cos(angle) * power;
		self.velocity.y = Math.sin(angle) * power;
		self.rotation = angle;
		LK.getSound('bowRelease').play();
	};
	// Stick arrow to target
	self.stickTo = function (target, score) {
		self.stuck = true;
		self.flying = false;
		self.targetHit = target;
		self.score = score;
		// Play sound
		LK.getSound('targetHit').play();
	};
	return self;
});
var Bow = Container.expand(function () {
	var self = Container.call(this);
	// Bow body
	var bowBody = self.attachAsset('bow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Bow string
	var bowString = self.attachAsset('bowString', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: -10
	});
	// Properties
	self.aimAngle = -Math.PI / 4; // Default angle (slightly up)
	self.power = 0;
	self.maxPower = 35;
	self.charging = false;
	// Update bow
	self.update = function () {
		// Update bow rotation to match aim angle
		self.rotation = self.aimAngle;
		// Update string position/appearance based on pull
		if (self.charging) {
			var pullFactor = self.power / self.maxPower;
			bowString.scaleX = 1 + pullFactor * 0.5; // Thicker when pulled
		} else {
			bowString.scaleX = 1;
		}
	};
	// Start charging (pulling back)
	self.startCharging = function () {
		self.charging = true;
		self.power = 0;
	};
	// Continue charging
	self.updateCharging = function () {
		if (self.charging) {
			if (!self.loadingSoundPlayed) {
				LK.getSound('bowLoading').play();
				self.loadingSoundPlayed = true;
			}
			self.power += 0.4;
			if (self.power > self.maxPower) {
				self.power = self.maxPower;
			}
		}
	};
	// Release arrow
	self.releaseArrow = function () {
		var finalPower = self.power;
		self.charging = false;
		self.loadingSoundPlayed = false;
		self.power = 0;
		return finalPower;
	};
	return self;
});
var PowerMeter = Container.expand(function () {
	var self = Container.call(this);
	// Background
	var background = self.attachAsset('powerMeter', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Fill
	var fill = self.attachAsset('powerFill', {
		anchorX: 0.5,
		anchorY: 1,
		// Anchor to bottom
		y: 195 // Half height of background
	});
	fill.height = 0; // Start empty
	// Update power meter
	self.updatePower = function (power, maxPower) {
		var percentage = power / maxPower;
		fill.height = 390 * percentage; // 390 is the max height of fill
		// Change color based on power
		if (percentage < 0.33) {
			fill.tint = 0x00FF00; // Green
		} else if (percentage < 0.66) {
			fill.tint = 0xFFFF00; // Yellow
		} else {
			fill.tint = 0xFF0000; // Red
		}
	};
	return self;
});
var Target = Container.expand(function () {
	var self = Container.call(this);
	// Create rings from outside to inside
	var outerRing = self.attachAsset('target', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var ring1 = self.attachAsset('targetRing1', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var ring2 = self.attachAsset('targetRing2', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var ring3 = self.attachAsset('targetRing3', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var bullseye = self.attachAsset('targetRing4', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Target properties
	self.radius = 100; // Outer radius
	self.direction = 1; // 1 for right, -1 for left
	self.speed = 2;
	self.minX = 300;
	self.maxX = 1748; // 2048 - 300
	// Score values for each ring
	self.scoreValues = [10, 25, 50, 75, 100]; // Outer to inner
	// Update target movement
	self.update = function () {
		if (!self["static"]) {
			self.x += self.speed * self.direction;
			// Reverse direction at edges
			if (self.x > self.maxX || self.x < self.minX) {
				self.direction *= -1;
			}
		}
	};
	// Get score based on distance from center
	self.getScore = function (hitX, hitY) {
		// Calculate distance from center
		var dx = hitX - self.x;
		var dy = hitY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Determine which ring was hit
		if (distance < 20) {
			return self.scoreValues[4]; // Bullseye
		} else if (distance < 40) {
			return self.scoreValues[3];
		} else if (distance < 60) {
			return self.scoreValues[2];
		} else if (distance < 80) {
			return self.scoreValues[1];
		} else if (distance < 100) {
			return self.scoreValues[0]; // Outer ring
		}
		return 0; // Miss
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	// No title, no description
	// Always backgroundColor is black
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Load level function to initialize targets and reset game state
function loadLevel(level) {
	currentLevel = level;
	maxArrows = levels[currentLevel].arrows;
	arrowCount = 0;
	arrows = [];
	initializeTargets();
	gameActive = true;
	arrowsTxt.setText('Arrows: ' + (maxArrows - arrowCount) + '/' + maxArrows);
	levelTxt.setText('Level: ' + (currentLevel + 1)); // Update level display
}
var arrows = [];
var targets = [];
var currentArrow = null;
var arrowCount = 0;
var levels = [{
	targets: 3,
	arrows: 5
}, {
	targets: 5,
	arrows: 7
}, {
	targets: 7,
	arrows: 9
}, {
	targets: 9,
	arrows: 11
}];
var currentLevel = 0;
var maxArrows = levels[currentLevel].arrows;
var totalScore = 0;
var gameActive = true;
var aimPoint = {
	x: 0,
	y: 0
};
var dragStart = {
	x: 0,
	y: 0
};
var isDragging = false;
// Create the background
var skyBackground = game.addChild(LK.getAsset('sky', {
	anchorX: 0,
	anchorY: 0,
	y: 0
}));
var ground = game.addChild(LK.getAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	y: 2532 // Position at bottom of screen
}));
// Create bow
var bow = new Bow();
bow.x = 1024; // Center the bow horizontally on the screen
bow.y = 2500; // Position near bottom
game.addChild(bow);
// Create power meter
var powerMeter = new PowerMeter();
powerMeter.x = 100;
powerMeter.y = 1800;
game.addChild(powerMeter);
// Create targets
function createTarget(x, y, isStatic, speed) {
	var target = new Target();
	target.x = x;
	target.y = y;
	target["static"] = isStatic;
	if (speed !== undefined) {
		target.speed = speed;
	}
	game.addChild(target);
	targets.push(target);
	return target;
}
// Create initial targets based on current level
function initializeTargets() {
	targets = [];
	for (var i = 0; i < levels[currentLevel].targets; i++) {
		var x = 300 + Math.random() * 1448; // Random x position within bounds
		var y = 500 + i * 300; // Staggered y positions
		var speed = 2 + Math.random() * 4; // Random speed between 2 and 6
		createTarget(x, y, false, speed);
	}
}
initializeTargets();
// Score display
var scoreTxt = new Text2('Score: 0', {
	size: 80,
	fill: 0x0000FF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Arrows left display
var arrowsTxt = new Text2('Arrows: ' + (maxArrows - arrowCount) + '/' + maxArrows, {
	size: 80,
	fill: 0x00FF00
});
arrowsTxt.anchor.set(0.5, 0);
arrowsTxt.y = 100;
LK.gui.top.addChild(arrowsTxt);
// High score display
var highScoreTxt = new Text2('High Score: ' + storage.highScore, {
	size: 60,
	fill: 0xFFA500
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.y = 20;
LK.gui.topRight.addChild(highScoreTxt);
// Level display
var levelTxt = new Text2('Level: ' + (currentLevel + 1), {
	size: 80,
	fill: 0x800080
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 20;
levelTxt.y = 20;
LK.gui.topLeft.addChild(levelTxt);
// Aim guide
var aimGuideTxt = new Text2('Touch and drag to aim, release to shoot', {
	size: 60,
	fill: 0xFF0000
});
aimGuideTxt.anchor.set(0.5, 0);
aimGuideTxt.y = 200;
LK.gui.top.addChild(aimGuideTxt);
// Create a new arrow
function createArrow() {
	if (arrowCount >= maxArrows) {
		if (arrows.length === 0) {
			// Check if all arrows have been used and none are flying
			LK.showGameOver(); // Trigger game over
		}
		return null;
	}
	var arrow = new Arrow();
	arrow.x = bow.x;
	arrow.y = bow.y;
	arrow.rotation = bow.aimAngle;
	game.addChild(arrow);
	arrows.push(arrow);
	arrowCount++;
	// Update arrows left display
	arrowsTxt.setText('Arrows: ' + (maxArrows - arrowCount) + '/' + maxArrows);
	return arrow;
}
// Handle collision between arrow and targets
function checkArrowCollisions() {
	for (var i = 0; i < arrows.length; i++) {
		var arrow = arrows[i];
		if (arrow.flying && !arrow.stuck) {
			// Check collision with each target
			for (var j = 0; j < targets.length; j++) {
				var target = targets[j];
				// Arrow tip position
				var tipX = arrow.x + Math.cos(arrow.rotation) * 65;
				var tipY = arrow.y + Math.sin(arrow.rotation) * 65;
				// Check if tip is inside target
				var dx = tipX - target.x;
				var dy = tipY - target.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (arrow.lastWasIntersecting === undefined) {
					arrow.lastWasIntersecting = false;
				}
				if (!arrow.lastWasIntersecting && distance <= target.radius) {
					if (!target._hit) {
						// Prevent double-count
						target._hit = true;
						arrow.lastWasIntersecting = true; // Ensure we update the intersection state
						// Hit! Calculate score
						var score = target.getScore(tipX, tipY);
						totalScore += score;
						scoreTxt.setText('Score: ' + totalScore);
						// Stick arrow to target and remove from screen
						arrow.stickTo(target, score);
						arrow.destroy();
						arrows.splice(i, 1);
						// Create explosion effect
						var explosion = new Container();
						var explosionParticle = LK.getAsset('target', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						explosion.addChild(explosionParticle);
						explosion.x = target.x;
						explosion.y = target.y;
						game.addChild(explosion);
						// Animate explosion effect
						tween(explosion, {
							scaleX: 2,
							scaleY: 2,
							alpha: 0
						}, {
							duration: 500,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								explosion.destroy();
							}
						});
						// Remove the hit target
						targets.splice(j, 1);
						target.destroy();
						arrow.lastWasIntersecting = false; // Reset intersection state for next checks
						// Create score popup
						var scorePop = new Text2("+" + score, {
							size: 60,
							fill: 0xFFFF00
						});
						scorePop.x = tipX;
						scorePop.y = tipY;
						game.addChild(scorePop);
						// Animate score popup
						tween(scorePop, {
							y: scorePop.y - 100,
							alpha: 0
						}, {
							duration: 1000,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								scorePop.destroy();
							}
						});
						break;
					}
					arrow.lastWasIntersecting = distance <= target.radius;
				}
			}
		}
		// Move arrows that are stuck to targets with the targets
		if (arrow.stuck && arrow.targetHit) {
			var targetPos = arrow.targetHit;
			var dx = arrow.x - targetPos.x;
			var dy = arrow.y - targetPos.y;
			arrow.x = targetPos.x + dx;
			arrow.y = targetPos.y + dy;
		}
	}
}
// Check if game is over
function checkGameOver() {
	if (arrowCount >= maxArrows && arrows.length === 0) {
		var allArrowsLanded = true;
		// Check if all arrows have landed
		for (var i = 0; i < arrows.length; i++) {
			if (arrows[i].flying) {
				allArrowsLanded = false;
				break;
			}
		}
		if (allArrowsLanded && gameActive) {
			gameActive = false;
			console.log("Game Over: All arrows used and not all targets hit."); // Debugging log
			// Update high score if needed
			if (totalScore > storage.highScore) {
				storage.highScore = totalScore;
				highScoreTxt.setText('High Score: ' + storage.highScore);
			}
			// Check if all targets are hit or score condition for level 1 is met
			if (targets.length === 0 || currentLevel === 0 && totalScore >= 30) {
				// Create level up text
				var levelUpTxt = new Text2('Level Up!', {
					size: 120,
					fill: 0xFFFF00
				});
				levelUpTxt.anchor.set(0.5, 0.5);
				levelUpTxt.x = 1024; // Center horizontally
				levelUpTxt.y = 1366; // Center vertically
				game.addChild(levelUpTxt);
				// Tween effect for level up text
				tween(levelUpTxt, {
					alpha: 0
				}, {
					duration: 2000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						levelUpTxt.destroy();
						currentLevel++;
						if (currentLevel < levels.length) {
							// Advance to next level using loadLevel function
							loadLevel(currentLevel);
							levelTxt.setText('Level: 27'); // Update level text to 27 
							levels[currentLevel].targets += 5; // Add 5 targets 
							initializeTargets(); // Reinitialize targets for the new level
						} else {
							// All levels completed, show game over
							LK.setTimeout(function () {
								LK.showGameOver();
							}, 2000);
						}
					}
				});
			} else {
				// Wait 2 seconds before showing game over
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 2000);
			}
		}
	}
}
// Game loop
game.update = function () {
	// Update all targets
	for (var i = 0; i < targets.length; i++) {
		targets[i].update();
	}
	// Update all arrows
	for (var i = 0; i < arrows.length; i++) {
		arrows[i].update();
	}
	// Update bow charging
	if (bow.charging) {
		bow.updateCharging();
		powerMeter.updatePower(bow.power, bow.maxPower);
	}
	// Check for collisions
	checkArrowCollisions();
	// Check if game is over
	checkGameOver();
};
// Touch/mouse events
game.down = function (x, y, obj) {
	if (!gameActive || arrowCount >= maxArrows) {
		return;
	}
	isDragging = true;
	dragStart.x = x;
	dragStart.y = y;
	// Start charging bow
	bow.startCharging();
	// Hide aim guide
	aimGuideTxt.alpha = 0;
	// Create new arrow
	currentArrow = createArrow();
};
game.move = function (x, y, obj) {
	if (!isDragging || !currentArrow) {
		return;
	}
	// Calculate aim angle
	var dx = dragStart.x - x;
	var dy = dragStart.y - y;
	var angle = Math.atan2(dy, dx);
	// Constrain angle (can't aim down into ground or directly backward)
	if (angle > 0 && angle < Math.PI / 2) {
		angle = 0;
	} else if (angle > Math.PI / 2 && angle < Math.PI) {
		angle = Math.PI;
	}
	bow.aimAngle = angle;
	// Position current arrow
	currentArrow.x = bow.x;
	currentArrow.y = bow.y;
	currentArrow.rotation = angle;
};
game.up = function (x, y, obj) {
	if (!isDragging || !currentArrow) {
		return;
	}
	isDragging = false;
	// Fire arrow with current power and angle
	var power = bow.releaseArrow();
	currentArrow.fire(power, bow.aimAngle);
	// Reset power meter
	powerMeter.updatePower(0, bow.maxPower);
	currentArrow = null;
};
// Play background music
LK.playMusic('bgMusic');
 a sharp cartoon-style arrow flying to the right, with colorful string, 2D game asset, minimal shading, pixel-perfect edges, isolated, flat art style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 A 2D flat digital illustration of a sharp and colorful cartoonish sleek arrow tip, designed for a mobile archery game. The arrow tip should be metallic (steel or iron), with subtle gradients for a polished look. It should have a pointed triangular shape with a slightly stylized, game-friendly appearance, matching the clean, minimal aesthetic of vector-based graphics. Use a transparent background and ensure it's facing upward. Resolution: 512x512.". Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 
 "A 2D digital illustration of a bright, cartoony sky background for a mobile archery game. The sky is a soft gradient from light blue at the top to pale near the horizon. Include fluffy white clouds scattered naturally. Style is flat, colorful, and minimal—perfect for a fun, casual game. No sun or dramatic lighting. Resolution: 1920x1080. Seamless and loopable edges. Transparent-free, clean background.". Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows