/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0
});
/**** 
* Classes
****/ 
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphic = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = 0;
	self.speedY = 0;
	self.active = true;
	self.trailCounter = 0;
	self.gravity = 0.18; // Further reduced gravity for slower falling
	self.airResistance = 0.995; // Slightly increased air resistance for slower movement
	self.bounciness = 0.92; // Lower bounciness for less energetic bounces
	self.spin = 0; // Ball spin (affects horizontal movement)
	self.lastHitPos = 0; // Last hit position on paddle (for spin calculation)
	self.reset = function (speedMultiplier) {
		// Set position to center of screen
		self.x = 2048 / 2;
		self.y = 2732 / 2;
		// Generate a random angle between 0 and 2π (full 360 degrees)
		var randomAngle = Math.random() * Math.PI * 2;
		// Set initial speed magnitude
		var speedMagnitude = 15 * speedMultiplier;
		// Calculate velocity components based on random angle
		self.speedX = Math.cos(randomAngle) * speedMagnitude;
		self.speedY = Math.sin(randomAngle) * speedMagnitude;
		self.active = true;
		self.spin = 0; // Reset spin
		self.lastHitPos = 0; // Reset last hit position
	};
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Store last positions for collision detection
		var lastX = self.x;
		var lastY = self.y;
		// Apply gravity - increases vertical speed over time
		self.speedY += self.gravity;
		// Apply air resistance
		self.speedX *= self.airResistance;
		self.speedY *= self.airResistance;
		// Apply spin effect to horizontal movement
		self.speedX += self.spin * 0.1;
		// Gradually reduce spin over time
		self.spin *= 0.98;
		// Apply velocity
		self.x += self.speedX;
		self.y += self.speedY;
		// Add trail effect based on speed
		self.trailCounter++;
		// Adjust trail frequency based on speed - faster speed = more frequent trails
		var trailFrequency = Math.max(1, 5 - Math.floor((Math.abs(self.speedX) + Math.abs(self.speedY)) / 10));
		// Create more trails at higher speeds
		if (self.trailCounter > trailFrequency) {
			self.trailCounter = 0;
			var trail = LK.getAsset('ball', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: lastX,
				y: lastY
			});
			// Adjust trail size based on ball speed
			var speedFactor = Math.min(1, (Math.abs(self.speedX) + Math.abs(self.speedY)) / 40);
			trail.scale.set(self.scale.x * (0.7 - speedFactor * 0.2), self.scale.y * (0.7 - speedFactor * 0.2));
			trail.tint = gameColors.ball;
			// Higher alpha for faster speeds
			trail.alpha = 0.5 + speedFactor * 0.3;
			game.addChildAt(trail, game.getChildIndex(self));
			// Fade out and remove trail - faster trails disappear quicker
			var trailDuration = 300 - speedFactor * 150;
			tween(trail, {
				alpha: 0,
				scaleX: trail.scale.x * 0.5,
				scaleY: trail.scale.y * 0.5
			}, {
				duration: trailDuration,
				onFinish: function onFinish() {
					trail.destroy();
				}
			});
		}
		// Rotate the ball based on horizontal speed to show rolling effect
		ballGraphic.rotation += self.speedX * 0.05;
		// Bounce off sides with more random physics
		if (self.x < 20 || self.x > 2028) {
			// Create particles at wall collision point
			createCollisionParticles(self.x, self.y);
			// Flip the horizontal direction
			self.speedX = -self.speedX * self.bounciness * 1.2;
			// Add significant random variation to both speed components
			self.speedX += Math.random() * 6 - 3; // Major randomness on x-axis
			self.speedY += Math.random() * 4 - 2; // Add randomness to y-axis on wall bounce too
			// Chance for a very wild bounce (20% chance)
			if (Math.random() < 0.2) {
				self.speedX *= 0.5 + Math.random();
				self.speedY *= 0.5 + Math.random();
			}
			// Keep the ball within the game boundaries
			self.x = Math.max(20, Math.min(2028, self.x));
			// Play bounce sound if soundEnabled is true
			if (soundEnabled) {
				LK.getSound('bounce').play();
			}
		}
		// Check if ball hits the top of the screen with more random bounces
		if (self.y < 20) {
			// Create particles at ceiling collision point
			createCollisionParticles(self.x, self.y);
			// Flip the vertical direction
			self.speedY = -self.speedY * self.bounciness * 1.25;
			// Add significant random variation to both speed components
			self.speedX += Math.random() * 5 - 2.5; // Add randomness to x-axis on ceiling bounce
			self.speedY += Math.random() * 5 - 2.5; // Major randomness on y-axis
			// Chance for a very wild bounce (20% chance)
			if (Math.random() < 0.2) {
				// Completely random direction after ceiling hit
				var randomAngle = Math.random() * Math.PI + Math.PI; // Angle in bottom half
				var currentSpeed = Math.sqrt(self.speedX * self.speedX + self.speedY * self.speedY);
				self.speedX = Math.cos(randomAngle) * currentSpeed;
				self.speedY = Math.sin(randomAngle) * currentSpeed;
			}
			self.y = 20;
			// Play bounce sound if soundEnabled is true
			if (soundEnabled) {
				LK.getSound('bounce').play();
			}
		}
	};
	return self;
});
var DiagonalStripe = Container.expand(function () {
	var self = Container.call(this);
	// Create a shape for the diagonal stripe
	var stripeGraphic = self.attachAsset('background', {
		anchorX: 0,
		anchorY: 0
	});
	// Configure the stripe appearance
	stripeGraphic.width = 3000; // Increased width to extend past screen edges
	stripeGraphic.height = 100;
	stripeGraphic.tint = 0xffffff; // White
	// Initial position and rotation
	stripeGraphic.rotation = Math.PI / 4; // 45 degrees in radians
	// Position it to extend past screen edges
	stripeGraphic.x = -500; // Start before the left edge
	// Empty update method (stripe will be still)
	self.update = function () {
		// No animation - stripe remains still
	};
	return self;
});
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	// Create the main paddle base - middle rectangle section
	var paddleGraphic = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	paddleGraphic.tint = 0xFFB612; // Set paddle color to #FFB612
	// Create the left rounded end (circle shape)
	var leftEnd = LK.getAsset('ball', {
		// Using the ball asset as it's a circle
		anchorX: 0.5,
		anchorY: 0.5,
		width: paddleGraphic.height,
		height: paddleGraphic.height,
		tint: 0xFFB612
	});
	leftEnd.x = -paddleGraphic.width / 2 + leftEnd.width / 2;
	self.addChild(leftEnd);
	// Create the right rounded end (circle shape)
	var rightEnd = LK.getAsset('ball', {
		// Using the ball asset as it's a circle
		anchorX: 0.5,
		anchorY: 0.5,
		width: paddleGraphic.height,
		height: paddleGraphic.height,
		tint: 0xFFB612
	});
	rightEnd.x = paddleGraphic.width / 2 - rightEnd.width / 2;
	// Make sure the right end is the correct color
	rightEnd.tint = 0xFFB612;
	self.addChild(rightEnd);
	// Trim the main paddle to accommodate rounded ends
	paddleGraphic.width = paddleGraphic.width - paddleGraphic.height;
	self.width = paddleGraphic.width + paddleGraphic.height; // Total width includes the circles
	self.height = paddleGraphic.height;
	self.update = function () {
		// Keep paddle within screen bounds
		self.x = Math.max(self.width / 2, Math.min(2048 - self.width / 2, self.x));
	};
	return self;
});
var Particle = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphic = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Initial size scale
	self.scale.set(0.5, 0.5); // Start with smaller particles
	// Particle colors
	var colors = [0xFFB612, 0xC60C30, 0x003087, 0xFFFFFF];
	particleGraphic.tint = colors[Math.floor(Math.random() * colors.length)];
	// Random speed and direction
	var angle = Math.random() * Math.PI * 2;
	var speed = 2 + Math.random() * 8;
	self.vx = Math.cos(angle) * speed;
	self.vy = Math.sin(angle) * speed;
	// Random rotation
	self.rotationSpeed = (Math.random() - 0.5) * 0.2;
	// Particle lifespan tracking
	self.lifetime = 0;
	self.maxLifetime = 30 + Math.random() * 30;
	// Update function
	self.update = function () {
		// Update position with reduced movement (smaller radius)
		self.x += self.vx * 0.5; // Reduce horizontal movement by 50%
		self.vy += 0.1; // Gravity effect
		self.y += self.vy * 0.5; // Reduce vertical movement by 50%
		// Rotate particle
		particleGraphic.rotation += self.rotationSpeed;
		// Update lifetime
		self.lifetime++;
		// Fade out based on lifetime
		if (self.lifetime > self.maxLifetime * 0.7) {
			self.alpha = 1 - (self.lifetime - self.maxLifetime * 0.7) / (self.maxLifetime * 0.3);
		}
		// Remove when lifetime is over
		if (self.lifetime >= self.maxLifetime) {
			self.active = false;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xffffff // Light sky blue for a calmer atmosphere
});
/**** 
* Game Code
****/ 
// Game state management
var GAME_STATE = {
	MENU: 0,
	PLAYING: 1,
	SETTINGS: 2
};
var currentState = GAME_STATE.MENU;
// Default colors for game elements - softer, more calming colors
var gameColors = {
	paddle: 0xffb612,
	// Changed to requested color #ffb612
	ball: 0xFFB612,
	// Changed to requested color #FFB612
	lava: 0xC60C30 // Changed to requested color #C60C30
};
// Color saving/loading disabled
// Make game accessible to other functions
var gameInstance = game;
// Game variables
var background;
var paddle;
var lava;
var balls = [];
var particles = []; // Array to track active particles
var score = 0;
var highScore = storage.highScore || 0;
var level = 1;
var combo = 0;
var lastBallHit = 0;
var gameActive = false;
var speedMultiplier = 1.0;
var maxBalls = 1;
var ballsInPlay = 0;
var spawnInterval;
var hitsToNextLevel = 25;
var currentHits = 0;
var hitCounterText;
// UI elements
var scoreTxt;
var levelTxt;
var comboTxt;
var highScoreTxt;
var speedTxt;
// Default sound settings
var soundEnabled = true;
var musicEnabled = true;
// Load stored sound settings
var soundSetting = storage.soundEnabled;
if (soundSetting !== undefined) {
	soundEnabled = soundSetting;
}
// Initialize game elements (called when starting game)
function initializeGameElements() {
	if (!background) {
		// Create background
		background = LK.getAsset('background', {
			anchorX: 0,
			anchorY: 0,
			x: 0,
			y: 0
		});
		game.addChild(background);
		// Initialize lava
		lava = LK.getAsset('lava', {
			anchorX: 0.5,
			anchorY: 0,
			x: 2048 / 2,
			y: 2732 - 200
		});
		lava.tint = gameColors.lava;
		game.addChild(lava);
		// Initialize paddle
		paddle = new Paddle();
		paddle.x = 2048 / 2;
		paddle.y = 2732 - 250;
		paddle.getChildAt(0).tint = 0xffb612;
		game.addChild(paddle);
		// Diagonal stripe removed from here and placed in menu
		// Create hit counter text
		scoreTxt = new Text2('0', {
			size: 180,
			fill: 0x101820
		});
		scoreTxt.anchor.set(0.5, 0.5);
		// Position score text precisely in the center of the screen
		scoreTxt.x = 2048 / 2; // True center horizontally
		scoreTxt.y = 2732 / 2; // True center vertically
		game.addChild(scoreTxt);
		// Create level text
		levelTxt = new Text2('Level: 1', {
			size: 70,
			fill: 0xFFFFFF
		});
		levelTxt.anchor.set(1, 0);
		levelTxt.x = 2000;
		levelTxt.y = 50;
		LK.gui.addChild(levelTxt);
		// Create combo text
		comboTxt = new Text2('', {
			size: 60,
			fill: 0xFFFFFF
		});
		comboTxt.anchor.set(0.5, 0);
		comboTxt.x = 1024;
		comboTxt.y = 50;
		comboTxt.alpha = 0;
		LK.gui.addChild(comboTxt);
		// Create high score text
		highScoreTxt = new Text2('High Score: ' + highScore, {
			size: 60,
			fill: 0xffb612
		});
		highScoreTxt.anchor.set(1, 0);
		highScoreTxt.x = 2000;
		highScoreTxt.y = 130; // Position below hit counter
		game.addChild(highScoreTxt); // Add directly to game to ensure visibility
		// Create speed indicator text
		speedTxt = new Text2('Speed: x' + speedMultiplier.toFixed(1), {
			size: 60,
			fill: 0xffb612
		});
		speedTxt.anchor.set(0, 0);
		speedTxt.x = 48;
		speedTxt.y = 50;
		game.addChild(speedTxt);
		// Create hit counter text
		hitCounterText = new Text2(currentHits + '/25', {
			size: 70,
			fill: 0x003087
		});
		hitCounterText.anchor.set(0.5, 0);
		hitCounterText.x = 1024;
		hitCounterText.y = 150; // More visible position at top of screen
		game.addChild(hitCounterText); // Add directly to game to ensure visibility
	}
	// Show game elements
	background.visible = true;
	lava.visible = true;
	paddle.visible = true;
	scoreTxt.visible = true;
	levelTxt.visible = true;
	comboTxt.visible = true;
	highScoreTxt.visible = true;
	hitCounterText.visible = true;
}
// Create menu elements
var titleText;
var startButton;
var settingsButton;
var settingsPanel;
var menuBackground;
// Initialize menu
initializeMenu();
function initializeMenu() {
	// Play menu music if enabled
	if (musicEnabled) {
		LK.playMusic('menuMusic', {
			fade: {
				start: 0,
				end: 0.6,
				duration: 1500
			}
		});
	}
	// Create menu background
	menuBackground = new Container();
	var menuBg = LK.getAsset('background', {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0,
		tint: 0xFFFFFF // White color for menu background
	});
	// Create a border by adding a slightly larger background behind it
	var menuBorder = LK.getAsset('background', {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0,
		tint: 0xA5ACAF // Border color set to #A5ACAF
	});
	menuBorder.width = 2048 + 10 * 2; // Adding 10px on each side
	menuBorder.height = 2732 + 10 * 2; // Adding 10px on each side
	menuBorder.x = -10; // Position it 10px to the left
	menuBorder.y = -10; // Position it 10px to the top
	menuBackground.addChild(menuBorder);
	menuBackground.addChild(menuBg);
	game.addChild(menuBackground);
	// Diagonal stripe removed from menu
	// Create game title
	titleText = new Text2('Lava Bounce', {
		size: 150,
		fill: 0x101820
	});
	titleText.anchor.set(0.5, 0);
	titleText.x = 1024;
	titleText.y = 200;
	game.addChild(titleText);
	// Animate the title to rotate back and forth
	function animateTitleRotation() {
		// Rotate to one side
		tween(titleText, {
			rotation: 0.1 // Slight rotation to the right (in radians)
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				// Rotate to the other side
				tween(titleText, {
					rotation: -0.1 // Slight rotation to the left (in radians)
				}, {
					duration: 1000,
					easing: tween.easeInOut,
					onFinish: animateTitleRotation // Loop the animation
				});
			}
		});
	}
	// Start the title rotation animation
	animateTitleRotation();
	// Create the "2" as a separate, larger text element
	var titleNumber = new Text2('2', {
		size: 200,
		// Bigger than the main title text
		fill: 0xFFB612 // Gold color
	});
	titleNumber.anchor.set(0.5, 0);
	titleNumber.x = 1024; // Centered horizontally
	titleNumber.y = 350; // Positioned below the main title
	game.addChild(titleNumber);
	// Animate the "2" with a continuous bounce effect
	function animateTitle2() {
		// Bounce up animation
		tween(titleNumber, {
			y: 320,
			// Move up slightly
			scaleX: 1.1,
			scaleY: 1.1
		}, {
			duration: 700,
			onFinish: function onFinish() {
				// Bounce down animation
				tween(titleNumber, {
					y: 350,
					// Back to original position
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 700,
					onFinish: animateTitle2 // Loop the animation
				});
			}
		});
	}
	// Start the animation
	animateTitle2();
	// Create start button
	startButton = new Text2('Start Game', {
		size: 90,
		fill: 0xFFB612
	});
	startButton.anchor.set(0.5, 0.5);
	startButton.x = 1024;
	startButton.y = 1200;
	startButton.interactive = true;
	startButton.isHovered = false; // Track hover state
	startButton.move = function (x, y, obj) {
		// Check if cursor is over the button
		if (x >= startButton.x - startButton.width / 2 && x <= startButton.x + startButton.width / 2 && y >= startButton.y - startButton.height / 2 && y <= startButton.y + startButton.height / 2) {
			// Start animation only if not already hovering
			if (!startButton.isHovered) {
				startButton.isHovered = true;
				// Apply a slight scale increase when hovered
				tween(startButton, {
					scaleX: 1.05,
					scaleY: 1.05
				}, {
					duration: 200,
					easing: tween.easeOut
				});
				animateStartButton();
			}
		} else {
			// Stop animation when cursor moves away
			if (startButton.isHovered) {
				startButton.isHovered = false;
				tween.stop(startButton, {
					rotation: true
				});
				tween(startButton, {
					rotation: 0,
					scaleX: 1.0,
					scaleY: 1.0
				}, {
					duration: 200
				});
			}
		}
	};
	// Function to animate the start button
	function animateStartButton() {
		if (!startButton.isHovered) {
			return;
		}
		// Rotate to one side
		tween(startButton, {
			rotation: 0.08 // Slight rotation (in radians)
		}, {
			duration: 50,
			// Very quick rotation for more responsive feel
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				if (!startButton.isHovered) {
					startButton.rotation = 0;
					return;
				}
				// Rotate to the other side
				tween(startButton, {
					rotation: -0.08 // Slight rotation in opposite direction
				}, {
					duration: 50,
					// Very quick rotation for more responsive feel
					easing: tween.easeInOut,
					onFinish: animateStartButton // Continue the animation
				});
			}
		});
	}
	game.addChild(startButton);
	// Create settings button
	settingsButton = new Text2('Settings', {
		size: 90,
		fill: 0x101820
	});
	settingsButton.anchor.set(0.5, 0.5);
	settingsButton.x = 1024;
	settingsButton.y = 1400;
	settingsButton.interactive = true;
	game.addChild(settingsButton);
	// Set up event handlers for menu
	startButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		// Stop menu music with fade out
		if (musicEnabled) {
			LK.playMusic('menuMusic', {
				fade: {
					start: 0.6,
					end: 0,
					duration: 500
				}
			});
		}
		hideMenu();
		initializeGameElements();
		startGame();
	};
	settingsButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		hideMenu();
		showSettings();
	};
}
function hideMenu() {
	if (menuBackground) {
		menuBackground.visible = false;
	}
	if (titleText) {
		titleText.visible = false;
	}
	if (startButton) {
		startButton.visible = false;
	}
	if (settingsButton) {
		settingsButton.visible = false;
	}
	// Make sure high score is visible in game
	if (highScoreTxt) {
		highScoreTxt.visible = true;
	}
}
function showMenu() {
	currentState = GAME_STATE.MENU;
	if (menuBackground) {
		menuBackground.visible = true;
	}
	if (titleText) {
		titleText.visible = true;
	}
	if (startButton) {
		startButton.visible = true;
	}
	if (settingsButton) {
		settingsButton.visible = true;
	}
	if (settingsPanel) {
		settingsPanel.visible = false;
	}
	// Play menu music when returning to menu from game over
	if (musicEnabled && currentState === GAME_STATE.MENU) {
		LK.playMusic('menuMusic', {
			fade: {
				start: 0,
				end: 0.6,
				duration: 1000
			}
		});
	}
}
function showSettings() {
	currentState = GAME_STATE.SETTINGS;
	// Create settings panel if it doesn't exist
	if (!settingsPanel) {
		settingsPanel = new Container();
		game.addChild(settingsPanel);
		// Settings panel background without border
		var panelContainer = new Container();
		panelContainer.x = 1024;
		panelContainer.y = 1366;
		// Set initial scale to zero for animation
		panelContainer.scale.x = 0;
		panelContainer.scale.y = 0;
		// Inner panel background (without blue border)
		var panelBg = LK.getAsset('background', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 0,
			y: 0
		});
		panelBg.width = 1600;
		panelBg.height = 1000;
		panelBg.tint = 0x101820; // Dark blue/black color for settings panel
		panelContainer.addChild(panelBg);
		settingsPanel.addChild(panelContainer);
		// Settings title
		var settingsTitle = new Text2('Settings', {
			size: 80,
			fill: 0xFFFFFF
		});
		settingsTitle.anchor.set(0.5, 0);
		settingsTitle.x = 1024;
		settingsTitle.y = 500;
		settingsPanel.addChild(settingsTitle);
		// Color selectors have been removed
		// Game description text
		var gameDescription = new Text2('Lava Bounce 2: A frantic paddle game where you\ncontrol a golden paddle to bounce balls away from\ndeadly red lava. Score points with each bounce,\nlevel up for increased speed and challenge.\nCan you set a new high score record?', {
			size: 50,
			fill: 0xFFB612
		});
		gameDescription.anchor.set(0.5, 0.5);
		gameDescription.x = 1024; // True center horizontally
		gameDescription.y = 700;
		settingsPanel.addChild(gameDescription);
		// High score display in settings
		var highScoreDisplay = new Text2('High Score: ' + highScore, {
			size: 60,
			fill: 0xFFFFFF
		});
		highScoreDisplay.anchor.set(0, 0.5);
		highScoreDisplay.x = 400;
		highScoreDisplay.y = 970; // Moved down a bit
		settingsPanel.addChild(highScoreDisplay);
		// Reset high score button
		var resetButton = new Text2('Reset High Score', {
			size: 60,
			fill: 0xFF6B6B
		});
		resetButton.anchor.set(0.5, 0.5);
		resetButton.x = 1024; // True center horizontally
		resetButton.y = 1366; // True center vertically 
		resetButton.interactive = true;
		resetButton.down = function () {
			if (soundEnabled) {
				LK.getSound('click').play();
			}
			showResetConfirmation();
		};
		settingsPanel.addChild(resetButton);
		// Back to menu button
		var backButton = new Text2('Back to Menu', {
			size: 60,
			fill: 0xFFFFFF
		});
		backButton.anchor.set(0.5, 0.5);
		backButton.x = 1024;
		backButton.y = 1100;
		backButton.interactive = true;
		backButton.down = function () {
			if (soundEnabled) {
				LK.getSound('click').play();
			}
			// Animate settings panel closing
			tween(settingsPanel.getChildAt(0), {
				scaleX: 0,
				scaleY: 0
			}, {
				duration: 300,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					settingsPanel.visible = false;
					showMenu();
					// Play menu music when returning to menu
					if (musicEnabled) {
						LK.playMusic('menuMusic', {
							fade: {
								start: 0,
								end: 0.6,
								duration: 1000
							}
						});
					}
				}
			});
		};
		settingsPanel.addChild(backButton);
	} else {
		settingsPanel.visible = true;
		// Reset scale for animation if panel already exists
		settingsPanel.getChildAt(0).scale.x = 0;
		settingsPanel.getChildAt(0).scale.y = 0;
	}
	// Animate the settings panel opening with bounce effect
	tween(settingsPanel.getChildAt(0), {
		scaleX: 1,
		scaleY: 1
	}, {
		duration: 600,
		easing: tween.elasticOut
	});
	// Color buttons function has been removed
}
// Function to create particles at click location
function createClickParticles(x, y) {
	// Create 15-20 particles for a visually impressive effect
	var particleCount = 15 + Math.floor(Math.random() * 6);
	for (var i = 0; i < particleCount; i++) {
		var particle = new Particle();
		particle.x = x;
		particle.y = y;
		particle.active = true;
		// Add to particles array and game display
		particles.push(particle);
		game.addChild(particle);
	}
}
// Function to create particles at collision location
function createCollisionParticles(x, y) {
	// Create 8-12 particles for collision effect - fewer than click particles
	var particleCount = 8 + Math.floor(Math.random() * 5);
	for (var i = 0; i < particleCount; i++) {
		var particle = new Particle();
		particle.x = x;
		particle.y = y;
		particle.active = true;
		particle.scale.set(0.3, 0.3); // Smaller particles for collisions
		// Add to particles array and game display
		particles.push(particle);
		game.addChild(particle);
	}
}
// Initialize balls array
function createBall() {
	if (ballsInPlay >= maxBalls || !gameActive) {
		return;
	}
	var ball = new Ball();
	ball.reset(speedMultiplier);
	ball.getChildAt(0).tint = gameColors.ball;
	// Visual indicator of speed - make ball slightly smaller as it gets faster
	var scale = Math.max(0.6, 1 - (speedMultiplier - 1) * 0.15);
	ball.scale.set(scale, scale);
	balls.push(ball);
	game.addChild(ball);
	ballsInPlay++;
}
// Handle input events based on current state
game.down = function (x, y, obj) {
	// Play click sound whenever cursor is clicked
	if (soundEnabled) {
		LK.getSound('click').play();
	}
	// Create particles at click location
	createClickParticles(x, y);
	if (currentState === GAME_STATE.PLAYING) {
		paddle.x = x;
	}
	// Check if we hit any interactive elements
	if (obj && obj.event && obj.event.target && obj.event.target.down) {
		obj.event.target.down(x, y, obj);
	}
};
game.move = function (x, y, obj) {
	if (currentState === GAME_STATE.PLAYING) {
		paddle.x = x;
	}
};
// Update function
game.update = function () {
	// Update any diagonal stripes in the game (always update even when not playing)
	for (var i = 0; i < game.children.length; i++) {
		if (game.children[i] instanceof DiagonalStripe) {
			game.children[i].update();
		}
	}
	// Update all particles
	for (var i = particles.length - 1; i >= 0; i--) {
		var particle = particles[i];
		if (particle.active === false) {
			particle.destroy();
			particles.splice(i, 1);
			continue;
		}
		particle.update();
	}
	// Check if in playing state
	if (currentState !== GAME_STATE.PLAYING) {
		return;
	}
	// Game play state
	if (!gameActive) {
		return;
	}
	// Update speed indicator if it exists
	if (speedTxt) {
		speedTxt.setText('Speed: x' + speedMultiplier.toFixed(1));
	}
	// Only create a ball if none exists
	if (ballsInPlay === 0) {
		createBall();
	}
	// Update paddle and track position for physics calculations
	game.lastPaddleX = paddle.x; // Store current position for next frame
	paddle.update();
	// Update all balls
	for (var i = balls.length - 1; i >= 0; i--) {
		var ball = balls[i];
		if (!ball.active) {
			continue;
		}
		ball.update();
		// Check if ball hits paddle with improved collision detection
		if (ball.speedY > 0 && ball.y + 20 >= paddle.y - paddle.height / 2 && ball.y - 20 <= paddle.y + paddle.height / 2 && ball.x + 20 >= paddle.x - paddle.width / 2 && ball.x - 20 <= paddle.x + paddle.width / 2) {
			// Create particles at collision point
			createCollisionParticles(ball.x, ball.y);
			// Calculate hit position from -1 (left edge) to 1 (right edge)
			var hitPos = (ball.x - paddle.x) / (paddle.width / 2);
			// Calculate spin based on the difference between current and last hit position
			// This simulates the effect of a moving paddle hitting the ball
			var paddleMovementEffect = 0;
			if (game.lastPaddleX !== undefined) {
				paddleMovementEffect = (paddle.x - game.lastPaddleX) * 0.1;
			}
			// Apply reduced spin based on hit position and paddle movement
			ball.spin = hitPos * 0.3 + paddleMovementEffect * 0.6; // Reduced spin effect
			ball.lastHitPos = hitPos;
			// Calculate angle based on where the ball hits the paddle with more randomness
			// Wider angle range - full 180 degrees (0 to 180) instead of 120 degrees
			var angle = Math.PI * Math.random() + Math.PI / 2; // Random angle in upper half (90 to 270 degrees)
			// Add influence from hit position
			angle = angle * 0.7 + (Math.PI / 3 * hitPos + Math.PI / 2) * 0.3;
			// Calculate current speed with an adjustment
			var currentSpeed = Math.sqrt(ball.speedX * ball.speedX + ball.speedY * ball.speedY);
			var speed = Math.max(currentSpeed * 1.25, 12 * speedMultiplier);
			// Adjust ball direction with more random bounce physics
			ball.speedX = Math.cos(angle) * speed + paddleMovementEffect * 1.5;
			ball.speedY = -Math.sin(angle) * speed * 1.4; // Increased vertical multiplier for higher bounce
			// Add larger random variations for more unpredictable bouncing
			ball.speedX += (Math.random() * 4 - 2) * speedMultiplier; // Increased randomness
			ball.speedY += (Math.random() * 4 - 2) * speedMultiplier; // Increased randomness
			// Create a bounce effect with the paddle - make it visually respond to the hit
			tween(paddle, {
				scaleY: 0.85,
				y: paddle.y + 5
			}, {
				duration: 100,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(paddle, {
						scaleY: 1.0,
						y: paddle.y - 5
					}, {
						duration: 100,
						easing: tween.elasticOut
					});
				}
			});
			// Move ball above paddle to prevent multiple collisions
			ball.y = paddle.y - paddle.height / 2 - 20;
			// Add a visual impact effect
			var impactEffect = LK.getAsset('ball', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: ball.x,
				y: ball.y + 10,
				tint: 0xFFFFFF
			});
			impactEffect.scale.set(1.5, 0.5);
			impactEffect.alpha = 0.7;
			game.addChild(impactEffect);
			// Animate and remove the impact effect
			tween(impactEffect, {
				alpha: 0,
				scaleX: 2.5,
				scaleY: 0.2
			}, {
				duration: 200,
				onFinish: function onFinish() {
					impactEffect.destroy();
				}
			});
			// Simple scoring - always add 1 point
			score += 1;
			// Hide combo text
			comboTxt.alpha = 0;
			// Update hit counter
			scoreTxt.setText('' + score);
			// Center the score text
			scoreTxt.x = 2048 / 2; // True center horizontally
			scoreTxt.y = 2732 / 2; // True center vertically
			// Make it fade and gently grow when updated
			tween(scoreTxt, {
				scaleX: 1.1,
				// Smaller scale change
				scaleY: 1.1,
				// Smaller scale change
				alpha: 0.8 // Slight fade out
			}, {
				duration: 300,
				// Longer duration for smoother animation
				easing: tween.easeInOut,
				// Smoother easing
				onFinish: function onFinish() {
					tween(scoreTxt, {
						scaleX: 1,
						scaleY: 1,
						alpha: 1 // Back to full opacity
					}, {
						duration: 300,
						// Longer duration
						easing: tween.easeInOut // Smoother easing
					});
				}
			});
			LK.setScore(score);
			// Play bounce sound if enabled
			if (soundEnabled) {
				LK.getSound('bounce').play();
			}
			// Update hit counter for level system
			currentHits++;
			hitCounterText.setText(currentHits + '/' + hitsToNextLevel);
			// Level up based on hits
			if (currentHits >= hitsToNextLevel) {
				currentHits = 0;
				levelUp();
				hitCounterText.setText('Hits to Next Level: ' + hitsToNextLevel);
				// Animate hit counter text
				tween(hitCounterText, {
					scaleX: 1.2,
					scaleY: 1.2,
					alpha: 0.8
				}, {
					duration: 300,
					easing: tween.easeInOut,
					onFinish: function onFinish() {
						tween(hitCounterText, {
							scaleX: 1,
							scaleY: 1,
							alpha: 1
						}, {
							duration: 300,
							easing: tween.easeInOut
						});
					}
				});
			}
		}
		// Check if ball falls into lava
		if (ball.y > lava.y) {
			// Play lava sound if enabled
			if (soundEnabled) {
				LK.getSound('lava').play();
			}
			// Flash the lava
			tween(lava, {
				tint: 0xffffff
			}, {
				duration: 200,
				onFinish: function onFinish() {
					tween(lava, {
						tint: 0xe74c3c
					}, {
						duration: 200
					});
				}
			});
			// Remove ball
			ball.active = false;
			ball.destroy();
			balls.splice(i, 1);
			ballsInPlay--;
			// Check game over
			if (balls.length === 0 && ballsInPlay === 0) {
				gameOver();
			}
		}
	}
};
// Reset confirmation popup
function showResetConfirmation() {
	// Create popup container
	var popup = new Container();
	game.addChild(popup);
	// Popup background
	var popupBg = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	});
	popupBg.width = 1200;
	popupBg.height = 700;
	popupBg.tint = 0x101820;
	popup.addChild(popupBg);
	// Border for popup
	var popupBorder = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	});
	popupBorder.width = 1210;
	popupBorder.height = 710;
	popupBorder.tint = 0xFFB612;
	popup.addChildAt(popupBorder, 0);
	// Confirmation text
	var confirmText = new Text2('Reset High Score?', {
		size: 70,
		fill: 0xFFFFFF
	});
	confirmText.anchor.set(0.5, 0);
	confirmText.x = 1024;
	confirmText.y = 1200;
	popup.addChild(confirmText);
	// Yes button
	var yesButton = new Text2('Yes', {
		size: 60,
		fill: 0xFF6B6B
	});
	yesButton.anchor.set(0.5, 0.5);
	yesButton.x = 824;
	yesButton.y = 1450;
	yesButton.interactive = true;
	yesButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		// Reset high score
		highScore = 0;
		storage.highScore = 0;
		// Update high score display
		if (highScoreTxt) {
			highScoreTxt.setText('High Score: 0');
		}
		// Update settings display
		settingsPanel.children.forEach(function (child) {
			if (child instanceof Text2 && child.text && child.text.startsWith('High Score:')) {
				child.setText('High Score: 0');
			}
		});
		// Remove popup with animation
		tween(popup, {
			alpha: 0,
			scaleX: 0.8,
			scaleY: 0.8
		}, {
			duration: 300,
			onFinish: function onFinish() {
				popup.destroy();
			}
		});
	};
	popup.addChild(yesButton);
	// No button
	var noButton = new Text2('No', {
		size: 60,
		fill: 0xFFFFFF
	});
	noButton.anchor.set(0.5, 0.5);
	noButton.x = 1224;
	noButton.y = 1450;
	noButton.interactive = true;
	noButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		// Remove popup with animation
		tween(popup, {
			alpha: 0,
			scaleX: 0.8,
			scaleY: 0.8
		}, {
			duration: 300,
			onFinish: function onFinish() {
				popup.destroy();
			}
		});
	};
	popup.addChild(noButton);
	// Animate popup appearing
	popup.scale.set(0.8, 0.8);
	popup.alpha = 0;
	tween(popup, {
		alpha: 1,
		scaleX: 1,
		scaleY: 1
	}, {
		duration: 300,
		easing: tween.easeOut
	});
}
function levelUp() {
	level++;
	levelTxt.setText('Level: ' + level);
	// Show level up message with speed information
	var levelUpTxt = new Text2('LEVEL UP!\nSpeed x' + speedMultiplier.toFixed(1), {
		size: 80,
		fill: 0xFFFFFF
	});
	levelUpTxt.anchor.set(0.5, 0.5);
	levelUpTxt.x = 1024;
	levelUpTxt.y = 1366;
	LK.gui.addChild(levelUpTxt);
	// Animate level up message
	tween(levelUpTxt, {
		alpha: 0,
		scaleX: 2,
		scaleY: 2
	}, {
		duration: 1000,
		onFinish: function onFinish() {
			levelUpTxt.destroy();
		}
	});
	// Change music to heavy metal if level is 4 or above
	if (level === 4 && musicEnabled) {
		// Transition to heavy metal music with fade effects
		LK.playMusic('heavyMetalMusic', {
			fade: {
				start: 0,
				end: 0.7,
				duration: 1500
			}
		});
	}
	// Increase difficulty with a moderate speed boost for slightly slower progression
	speedMultiplier += 0.4 + level * 0.08; // Reduced speed boost for slightly slower gameplay
	maxBalls = 1; // Keep maxBalls at 1
	// Reset hit counter for next level
	currentHits = 0;
	// Increase hits required for next level for increasing challenge
	hitsToNextLevel = 25 + (level - 1) * 5;
	hitCounterText.setText('0/' + hitsToNextLevel);
}
function gameOver() {
	gameActive = false;
	// Check if we have a new high score
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
		// Show new high score message
		var newHighScoreTxt = new Text2('NEW HIGH SCORE!', {
			size: 80,
			fill: 0xFFB612
		});
		newHighScoreTxt.anchor.set(0.5, 0.5);
		newHighScoreTxt.x = 1024;
		newHighScoreTxt.y = 1000;
		LK.gui.addChild(newHighScoreTxt);
		// Animate high score message
		tween(newHighScoreTxt, {
			alpha: 0,
			scaleX: 2,
			scaleY: 2
		}, {
			duration: 1500,
			onFinish: function onFinish() {
				newHighScoreTxt.destroy();
			}
		});
		// Update high score display
		if (highScoreTxt) {
			highScoreTxt.setText('High Score: ' + highScore);
		}
	}
	// Flash the screen red to indicate death
	LK.effects.flashScreen(0xff0000, 500);
	// If music enabled and player was at level 4 or above, prepare to reset music
	var shouldResetMusic = level >= 4 && musicEnabled;
	// Restart the game after a short delay instead of showing menu
	LK.setTimeout(function () {
		// Keep the game elements visible, just restart game logic
		// Clear any remaining balls
		for (var i = 0; i < balls.length; i++) {
			balls[i].destroy();
		}
		balls = [];
		ballsInPlay = 0;
		// Restart the game immediately
		startGame();
		// Ensure we're in playing state
		currentState = GAME_STATE.PLAYING;
	}, 500);
}
// Start the game
function startGame() {
	// Reset variables
	score = 0;
	level = 1;
	combo = 0;
	lastBallHit = 0;
	gameActive = true;
	speedMultiplier = 1.5; // Further reduced initial speed multiplier for slower initial gameplay
	maxBalls = 3; // Maintained same number of maximum balls
	ballsInPlay = 0;
	currentHits = 0;
	hitsToNextLevel = 25;
	// Update UI
	scoreTxt.setText('0');
	scoreTxt.scale.set(1, 1); // Reset any scaling from animations
	scoreTxt.x = 2048 / 2; // True center horizontally
	scoreTxt.y = 2732 / 2; // True center vertically
	levelTxt.setText('Level: 1');
	comboTxt.setText('');
	comboTxt.alpha = 0;
	hitCounterText.setText('0/' + hitsToNextLevel);
	// Update high score display
	if (highScoreTxt) {
		highScoreTxt.setText('High Score: ' + highScore);
	}
	// Clear any existing balls
	for (var i = 0; i < balls.length; i++) {
		balls[i].destroy();
	}
	balls = [];
	// Start with one ball
	createBall();
	// Play relaxing game music at start (level 1-3)
	if (musicEnabled) {
		LK.playMusic('gameMusic', {
			fade: {
				start: 0,
				end: 0.4,
				// Lower volume
				duration: 2000 // Longer fade in
			}
		});
	}
	// Ensure the current state is set to playing
	currentState = GAME_STATE.PLAYING;
}
// Game will start when player presses the Play button in the menu /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0
});
/**** 
* Classes
****/ 
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphic = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = 0;
	self.speedY = 0;
	self.active = true;
	self.trailCounter = 0;
	self.gravity = 0.18; // Further reduced gravity for slower falling
	self.airResistance = 0.995; // Slightly increased air resistance for slower movement
	self.bounciness = 0.92; // Lower bounciness for less energetic bounces
	self.spin = 0; // Ball spin (affects horizontal movement)
	self.lastHitPos = 0; // Last hit position on paddle (for spin calculation)
	self.reset = function (speedMultiplier) {
		// Set position to center of screen
		self.x = 2048 / 2;
		self.y = 2732 / 2;
		// Generate a random angle between 0 and 2π (full 360 degrees)
		var randomAngle = Math.random() * Math.PI * 2;
		// Set initial speed magnitude
		var speedMagnitude = 15 * speedMultiplier;
		// Calculate velocity components based on random angle
		self.speedX = Math.cos(randomAngle) * speedMagnitude;
		self.speedY = Math.sin(randomAngle) * speedMagnitude;
		self.active = true;
		self.spin = 0; // Reset spin
		self.lastHitPos = 0; // Reset last hit position
	};
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Store last positions for collision detection
		var lastX = self.x;
		var lastY = self.y;
		// Apply gravity - increases vertical speed over time
		self.speedY += self.gravity;
		// Apply air resistance
		self.speedX *= self.airResistance;
		self.speedY *= self.airResistance;
		// Apply spin effect to horizontal movement
		self.speedX += self.spin * 0.1;
		// Gradually reduce spin over time
		self.spin *= 0.98;
		// Apply velocity
		self.x += self.speedX;
		self.y += self.speedY;
		// Add trail effect based on speed
		self.trailCounter++;
		// Adjust trail frequency based on speed - faster speed = more frequent trails
		var trailFrequency = Math.max(1, 5 - Math.floor((Math.abs(self.speedX) + Math.abs(self.speedY)) / 10));
		// Create more trails at higher speeds
		if (self.trailCounter > trailFrequency) {
			self.trailCounter = 0;
			var trail = LK.getAsset('ball', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: lastX,
				y: lastY
			});
			// Adjust trail size based on ball speed
			var speedFactor = Math.min(1, (Math.abs(self.speedX) + Math.abs(self.speedY)) / 40);
			trail.scale.set(self.scale.x * (0.7 - speedFactor * 0.2), self.scale.y * (0.7 - speedFactor * 0.2));
			trail.tint = gameColors.ball;
			// Higher alpha for faster speeds
			trail.alpha = 0.5 + speedFactor * 0.3;
			game.addChildAt(trail, game.getChildIndex(self));
			// Fade out and remove trail - faster trails disappear quicker
			var trailDuration = 300 - speedFactor * 150;
			tween(trail, {
				alpha: 0,
				scaleX: trail.scale.x * 0.5,
				scaleY: trail.scale.y * 0.5
			}, {
				duration: trailDuration,
				onFinish: function onFinish() {
					trail.destroy();
				}
			});
		}
		// Rotate the ball based on horizontal speed to show rolling effect
		ballGraphic.rotation += self.speedX * 0.05;
		// Bounce off sides with more random physics
		if (self.x < 20 || self.x > 2028) {
			// Create particles at wall collision point
			createCollisionParticles(self.x, self.y);
			// Flip the horizontal direction
			self.speedX = -self.speedX * self.bounciness * 1.2;
			// Add significant random variation to both speed components
			self.speedX += Math.random() * 6 - 3; // Major randomness on x-axis
			self.speedY += Math.random() * 4 - 2; // Add randomness to y-axis on wall bounce too
			// Chance for a very wild bounce (20% chance)
			if (Math.random() < 0.2) {
				self.speedX *= 0.5 + Math.random();
				self.speedY *= 0.5 + Math.random();
			}
			// Keep the ball within the game boundaries
			self.x = Math.max(20, Math.min(2028, self.x));
			// Play bounce sound if soundEnabled is true
			if (soundEnabled) {
				LK.getSound('bounce').play();
			}
		}
		// Check if ball hits the top of the screen with more random bounces
		if (self.y < 20) {
			// Create particles at ceiling collision point
			createCollisionParticles(self.x, self.y);
			// Flip the vertical direction
			self.speedY = -self.speedY * self.bounciness * 1.25;
			// Add significant random variation to both speed components
			self.speedX += Math.random() * 5 - 2.5; // Add randomness to x-axis on ceiling bounce
			self.speedY += Math.random() * 5 - 2.5; // Major randomness on y-axis
			// Chance for a very wild bounce (20% chance)
			if (Math.random() < 0.2) {
				// Completely random direction after ceiling hit
				var randomAngle = Math.random() * Math.PI + Math.PI; // Angle in bottom half
				var currentSpeed = Math.sqrt(self.speedX * self.speedX + self.speedY * self.speedY);
				self.speedX = Math.cos(randomAngle) * currentSpeed;
				self.speedY = Math.sin(randomAngle) * currentSpeed;
			}
			self.y = 20;
			// Play bounce sound if soundEnabled is true
			if (soundEnabled) {
				LK.getSound('bounce').play();
			}
		}
	};
	return self;
});
var DiagonalStripe = Container.expand(function () {
	var self = Container.call(this);
	// Create a shape for the diagonal stripe
	var stripeGraphic = self.attachAsset('background', {
		anchorX: 0,
		anchorY: 0
	});
	// Configure the stripe appearance
	stripeGraphic.width = 3000; // Increased width to extend past screen edges
	stripeGraphic.height = 100;
	stripeGraphic.tint = 0xffffff; // White
	// Initial position and rotation
	stripeGraphic.rotation = Math.PI / 4; // 45 degrees in radians
	// Position it to extend past screen edges
	stripeGraphic.x = -500; // Start before the left edge
	// Empty update method (stripe will be still)
	self.update = function () {
		// No animation - stripe remains still
	};
	return self;
});
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	// Create the main paddle base - middle rectangle section
	var paddleGraphic = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	paddleGraphic.tint = 0xFFB612; // Set paddle color to #FFB612
	// Create the left rounded end (circle shape)
	var leftEnd = LK.getAsset('ball', {
		// Using the ball asset as it's a circle
		anchorX: 0.5,
		anchorY: 0.5,
		width: paddleGraphic.height,
		height: paddleGraphic.height,
		tint: 0xFFB612
	});
	leftEnd.x = -paddleGraphic.width / 2 + leftEnd.width / 2;
	self.addChild(leftEnd);
	// Create the right rounded end (circle shape)
	var rightEnd = LK.getAsset('ball', {
		// Using the ball asset as it's a circle
		anchorX: 0.5,
		anchorY: 0.5,
		width: paddleGraphic.height,
		height: paddleGraphic.height,
		tint: 0xFFB612
	});
	rightEnd.x = paddleGraphic.width / 2 - rightEnd.width / 2;
	// Make sure the right end is the correct color
	rightEnd.tint = 0xFFB612;
	self.addChild(rightEnd);
	// Trim the main paddle to accommodate rounded ends
	paddleGraphic.width = paddleGraphic.width - paddleGraphic.height;
	self.width = paddleGraphic.width + paddleGraphic.height; // Total width includes the circles
	self.height = paddleGraphic.height;
	self.update = function () {
		// Keep paddle within screen bounds
		self.x = Math.max(self.width / 2, Math.min(2048 - self.width / 2, self.x));
	};
	return self;
});
var Particle = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphic = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Initial size scale
	self.scale.set(0.5, 0.5); // Start with smaller particles
	// Particle colors
	var colors = [0xFFB612, 0xC60C30, 0x003087, 0xFFFFFF];
	particleGraphic.tint = colors[Math.floor(Math.random() * colors.length)];
	// Random speed and direction
	var angle = Math.random() * Math.PI * 2;
	var speed = 2 + Math.random() * 8;
	self.vx = Math.cos(angle) * speed;
	self.vy = Math.sin(angle) * speed;
	// Random rotation
	self.rotationSpeed = (Math.random() - 0.5) * 0.2;
	// Particle lifespan tracking
	self.lifetime = 0;
	self.maxLifetime = 30 + Math.random() * 30;
	// Update function
	self.update = function () {
		// Update position with reduced movement (smaller radius)
		self.x += self.vx * 0.5; // Reduce horizontal movement by 50%
		self.vy += 0.1; // Gravity effect
		self.y += self.vy * 0.5; // Reduce vertical movement by 50%
		// Rotate particle
		particleGraphic.rotation += self.rotationSpeed;
		// Update lifetime
		self.lifetime++;
		// Fade out based on lifetime
		if (self.lifetime > self.maxLifetime * 0.7) {
			self.alpha = 1 - (self.lifetime - self.maxLifetime * 0.7) / (self.maxLifetime * 0.3);
		}
		// Remove when lifetime is over
		if (self.lifetime >= self.maxLifetime) {
			self.active = false;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xffffff // Light sky blue for a calmer atmosphere
});
/**** 
* Game Code
****/ 
// Game state management
var GAME_STATE = {
	MENU: 0,
	PLAYING: 1,
	SETTINGS: 2
};
var currentState = GAME_STATE.MENU;
// Default colors for game elements - softer, more calming colors
var gameColors = {
	paddle: 0xffb612,
	// Changed to requested color #ffb612
	ball: 0xFFB612,
	// Changed to requested color #FFB612
	lava: 0xC60C30 // Changed to requested color #C60C30
};
// Color saving/loading disabled
// Make game accessible to other functions
var gameInstance = game;
// Game variables
var background;
var paddle;
var lava;
var balls = [];
var particles = []; // Array to track active particles
var score = 0;
var highScore = storage.highScore || 0;
var level = 1;
var combo = 0;
var lastBallHit = 0;
var gameActive = false;
var speedMultiplier = 1.0;
var maxBalls = 1;
var ballsInPlay = 0;
var spawnInterval;
var hitsToNextLevel = 25;
var currentHits = 0;
var hitCounterText;
// UI elements
var scoreTxt;
var levelTxt;
var comboTxt;
var highScoreTxt;
var speedTxt;
// Default sound settings
var soundEnabled = true;
var musicEnabled = true;
// Load stored sound settings
var soundSetting = storage.soundEnabled;
if (soundSetting !== undefined) {
	soundEnabled = soundSetting;
}
// Initialize game elements (called when starting game)
function initializeGameElements() {
	if (!background) {
		// Create background
		background = LK.getAsset('background', {
			anchorX: 0,
			anchorY: 0,
			x: 0,
			y: 0
		});
		game.addChild(background);
		// Initialize lava
		lava = LK.getAsset('lava', {
			anchorX: 0.5,
			anchorY: 0,
			x: 2048 / 2,
			y: 2732 - 200
		});
		lava.tint = gameColors.lava;
		game.addChild(lava);
		// Initialize paddle
		paddle = new Paddle();
		paddle.x = 2048 / 2;
		paddle.y = 2732 - 250;
		paddle.getChildAt(0).tint = 0xffb612;
		game.addChild(paddle);
		// Diagonal stripe removed from here and placed in menu
		// Create hit counter text
		scoreTxt = new Text2('0', {
			size: 180,
			fill: 0x101820
		});
		scoreTxt.anchor.set(0.5, 0.5);
		// Position score text precisely in the center of the screen
		scoreTxt.x = 2048 / 2; // True center horizontally
		scoreTxt.y = 2732 / 2; // True center vertically
		game.addChild(scoreTxt);
		// Create level text
		levelTxt = new Text2('Level: 1', {
			size: 70,
			fill: 0xFFFFFF
		});
		levelTxt.anchor.set(1, 0);
		levelTxt.x = 2000;
		levelTxt.y = 50;
		LK.gui.addChild(levelTxt);
		// Create combo text
		comboTxt = new Text2('', {
			size: 60,
			fill: 0xFFFFFF
		});
		comboTxt.anchor.set(0.5, 0);
		comboTxt.x = 1024;
		comboTxt.y = 50;
		comboTxt.alpha = 0;
		LK.gui.addChild(comboTxt);
		// Create high score text
		highScoreTxt = new Text2('High Score: ' + highScore, {
			size: 60,
			fill: 0xffb612
		});
		highScoreTxt.anchor.set(1, 0);
		highScoreTxt.x = 2000;
		highScoreTxt.y = 130; // Position below hit counter
		game.addChild(highScoreTxt); // Add directly to game to ensure visibility
		// Create speed indicator text
		speedTxt = new Text2('Speed: x' + speedMultiplier.toFixed(1), {
			size: 60,
			fill: 0xffb612
		});
		speedTxt.anchor.set(0, 0);
		speedTxt.x = 48;
		speedTxt.y = 50;
		game.addChild(speedTxt);
		// Create hit counter text
		hitCounterText = new Text2(currentHits + '/25', {
			size: 70,
			fill: 0x003087
		});
		hitCounterText.anchor.set(0.5, 0);
		hitCounterText.x = 1024;
		hitCounterText.y = 150; // More visible position at top of screen
		game.addChild(hitCounterText); // Add directly to game to ensure visibility
	}
	// Show game elements
	background.visible = true;
	lava.visible = true;
	paddle.visible = true;
	scoreTxt.visible = true;
	levelTxt.visible = true;
	comboTxt.visible = true;
	highScoreTxt.visible = true;
	hitCounterText.visible = true;
}
// Create menu elements
var titleText;
var startButton;
var settingsButton;
var settingsPanel;
var menuBackground;
// Initialize menu
initializeMenu();
function initializeMenu() {
	// Play menu music if enabled
	if (musicEnabled) {
		LK.playMusic('menuMusic', {
			fade: {
				start: 0,
				end: 0.6,
				duration: 1500
			}
		});
	}
	// Create menu background
	menuBackground = new Container();
	var menuBg = LK.getAsset('background', {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0,
		tint: 0xFFFFFF // White color for menu background
	});
	// Create a border by adding a slightly larger background behind it
	var menuBorder = LK.getAsset('background', {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0,
		tint: 0xA5ACAF // Border color set to #A5ACAF
	});
	menuBorder.width = 2048 + 10 * 2; // Adding 10px on each side
	menuBorder.height = 2732 + 10 * 2; // Adding 10px on each side
	menuBorder.x = -10; // Position it 10px to the left
	menuBorder.y = -10; // Position it 10px to the top
	menuBackground.addChild(menuBorder);
	menuBackground.addChild(menuBg);
	game.addChild(menuBackground);
	// Diagonal stripe removed from menu
	// Create game title
	titleText = new Text2('Lava Bounce', {
		size: 150,
		fill: 0x101820
	});
	titleText.anchor.set(0.5, 0);
	titleText.x = 1024;
	titleText.y = 200;
	game.addChild(titleText);
	// Animate the title to rotate back and forth
	function animateTitleRotation() {
		// Rotate to one side
		tween(titleText, {
			rotation: 0.1 // Slight rotation to the right (in radians)
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				// Rotate to the other side
				tween(titleText, {
					rotation: -0.1 // Slight rotation to the left (in radians)
				}, {
					duration: 1000,
					easing: tween.easeInOut,
					onFinish: animateTitleRotation // Loop the animation
				});
			}
		});
	}
	// Start the title rotation animation
	animateTitleRotation();
	// Create the "2" as a separate, larger text element
	var titleNumber = new Text2('2', {
		size: 200,
		// Bigger than the main title text
		fill: 0xFFB612 // Gold color
	});
	titleNumber.anchor.set(0.5, 0);
	titleNumber.x = 1024; // Centered horizontally
	titleNumber.y = 350; // Positioned below the main title
	game.addChild(titleNumber);
	// Animate the "2" with a continuous bounce effect
	function animateTitle2() {
		// Bounce up animation
		tween(titleNumber, {
			y: 320,
			// Move up slightly
			scaleX: 1.1,
			scaleY: 1.1
		}, {
			duration: 700,
			onFinish: function onFinish() {
				// Bounce down animation
				tween(titleNumber, {
					y: 350,
					// Back to original position
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 700,
					onFinish: animateTitle2 // Loop the animation
				});
			}
		});
	}
	// Start the animation
	animateTitle2();
	// Create start button
	startButton = new Text2('Start Game', {
		size: 90,
		fill: 0xFFB612
	});
	startButton.anchor.set(0.5, 0.5);
	startButton.x = 1024;
	startButton.y = 1200;
	startButton.interactive = true;
	startButton.isHovered = false; // Track hover state
	startButton.move = function (x, y, obj) {
		// Check if cursor is over the button
		if (x >= startButton.x - startButton.width / 2 && x <= startButton.x + startButton.width / 2 && y >= startButton.y - startButton.height / 2 && y <= startButton.y + startButton.height / 2) {
			// Start animation only if not already hovering
			if (!startButton.isHovered) {
				startButton.isHovered = true;
				// Apply a slight scale increase when hovered
				tween(startButton, {
					scaleX: 1.05,
					scaleY: 1.05
				}, {
					duration: 200,
					easing: tween.easeOut
				});
				animateStartButton();
			}
		} else {
			// Stop animation when cursor moves away
			if (startButton.isHovered) {
				startButton.isHovered = false;
				tween.stop(startButton, {
					rotation: true
				});
				tween(startButton, {
					rotation: 0,
					scaleX: 1.0,
					scaleY: 1.0
				}, {
					duration: 200
				});
			}
		}
	};
	// Function to animate the start button
	function animateStartButton() {
		if (!startButton.isHovered) {
			return;
		}
		// Rotate to one side
		tween(startButton, {
			rotation: 0.08 // Slight rotation (in radians)
		}, {
			duration: 50,
			// Very quick rotation for more responsive feel
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				if (!startButton.isHovered) {
					startButton.rotation = 0;
					return;
				}
				// Rotate to the other side
				tween(startButton, {
					rotation: -0.08 // Slight rotation in opposite direction
				}, {
					duration: 50,
					// Very quick rotation for more responsive feel
					easing: tween.easeInOut,
					onFinish: animateStartButton // Continue the animation
				});
			}
		});
	}
	game.addChild(startButton);
	// Create settings button
	settingsButton = new Text2('Settings', {
		size: 90,
		fill: 0x101820
	});
	settingsButton.anchor.set(0.5, 0.5);
	settingsButton.x = 1024;
	settingsButton.y = 1400;
	settingsButton.interactive = true;
	game.addChild(settingsButton);
	// Set up event handlers for menu
	startButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		// Stop menu music with fade out
		if (musicEnabled) {
			LK.playMusic('menuMusic', {
				fade: {
					start: 0.6,
					end: 0,
					duration: 500
				}
			});
		}
		hideMenu();
		initializeGameElements();
		startGame();
	};
	settingsButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		hideMenu();
		showSettings();
	};
}
function hideMenu() {
	if (menuBackground) {
		menuBackground.visible = false;
	}
	if (titleText) {
		titleText.visible = false;
	}
	if (startButton) {
		startButton.visible = false;
	}
	if (settingsButton) {
		settingsButton.visible = false;
	}
	// Make sure high score is visible in game
	if (highScoreTxt) {
		highScoreTxt.visible = true;
	}
}
function showMenu() {
	currentState = GAME_STATE.MENU;
	if (menuBackground) {
		menuBackground.visible = true;
	}
	if (titleText) {
		titleText.visible = true;
	}
	if (startButton) {
		startButton.visible = true;
	}
	if (settingsButton) {
		settingsButton.visible = true;
	}
	if (settingsPanel) {
		settingsPanel.visible = false;
	}
	// Play menu music when returning to menu from game over
	if (musicEnabled && currentState === GAME_STATE.MENU) {
		LK.playMusic('menuMusic', {
			fade: {
				start: 0,
				end: 0.6,
				duration: 1000
			}
		});
	}
}
function showSettings() {
	currentState = GAME_STATE.SETTINGS;
	// Create settings panel if it doesn't exist
	if (!settingsPanel) {
		settingsPanel = new Container();
		game.addChild(settingsPanel);
		// Settings panel background without border
		var panelContainer = new Container();
		panelContainer.x = 1024;
		panelContainer.y = 1366;
		// Set initial scale to zero for animation
		panelContainer.scale.x = 0;
		panelContainer.scale.y = 0;
		// Inner panel background (without blue border)
		var panelBg = LK.getAsset('background', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 0,
			y: 0
		});
		panelBg.width = 1600;
		panelBg.height = 1000;
		panelBg.tint = 0x101820; // Dark blue/black color for settings panel
		panelContainer.addChild(panelBg);
		settingsPanel.addChild(panelContainer);
		// Settings title
		var settingsTitle = new Text2('Settings', {
			size: 80,
			fill: 0xFFFFFF
		});
		settingsTitle.anchor.set(0.5, 0);
		settingsTitle.x = 1024;
		settingsTitle.y = 500;
		settingsPanel.addChild(settingsTitle);
		// Color selectors have been removed
		// Game description text
		var gameDescription = new Text2('Lava Bounce 2: A frantic paddle game where you\ncontrol a golden paddle to bounce balls away from\ndeadly red lava. Score points with each bounce,\nlevel up for increased speed and challenge.\nCan you set a new high score record?', {
			size: 50,
			fill: 0xFFB612
		});
		gameDescription.anchor.set(0.5, 0.5);
		gameDescription.x = 1024; // True center horizontally
		gameDescription.y = 700;
		settingsPanel.addChild(gameDescription);
		// High score display in settings
		var highScoreDisplay = new Text2('High Score: ' + highScore, {
			size: 60,
			fill: 0xFFFFFF
		});
		highScoreDisplay.anchor.set(0, 0.5);
		highScoreDisplay.x = 400;
		highScoreDisplay.y = 970; // Moved down a bit
		settingsPanel.addChild(highScoreDisplay);
		// Reset high score button
		var resetButton = new Text2('Reset High Score', {
			size: 60,
			fill: 0xFF6B6B
		});
		resetButton.anchor.set(0.5, 0.5);
		resetButton.x = 1024; // True center horizontally
		resetButton.y = 1366; // True center vertically 
		resetButton.interactive = true;
		resetButton.down = function () {
			if (soundEnabled) {
				LK.getSound('click').play();
			}
			showResetConfirmation();
		};
		settingsPanel.addChild(resetButton);
		// Back to menu button
		var backButton = new Text2('Back to Menu', {
			size: 60,
			fill: 0xFFFFFF
		});
		backButton.anchor.set(0.5, 0.5);
		backButton.x = 1024;
		backButton.y = 1100;
		backButton.interactive = true;
		backButton.down = function () {
			if (soundEnabled) {
				LK.getSound('click').play();
			}
			// Animate settings panel closing
			tween(settingsPanel.getChildAt(0), {
				scaleX: 0,
				scaleY: 0
			}, {
				duration: 300,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					settingsPanel.visible = false;
					showMenu();
					// Play menu music when returning to menu
					if (musicEnabled) {
						LK.playMusic('menuMusic', {
							fade: {
								start: 0,
								end: 0.6,
								duration: 1000
							}
						});
					}
				}
			});
		};
		settingsPanel.addChild(backButton);
	} else {
		settingsPanel.visible = true;
		// Reset scale for animation if panel already exists
		settingsPanel.getChildAt(0).scale.x = 0;
		settingsPanel.getChildAt(0).scale.y = 0;
	}
	// Animate the settings panel opening with bounce effect
	tween(settingsPanel.getChildAt(0), {
		scaleX: 1,
		scaleY: 1
	}, {
		duration: 600,
		easing: tween.elasticOut
	});
	// Color buttons function has been removed
}
// Function to create particles at click location
function createClickParticles(x, y) {
	// Create 15-20 particles for a visually impressive effect
	var particleCount = 15 + Math.floor(Math.random() * 6);
	for (var i = 0; i < particleCount; i++) {
		var particle = new Particle();
		particle.x = x;
		particle.y = y;
		particle.active = true;
		// Add to particles array and game display
		particles.push(particle);
		game.addChild(particle);
	}
}
// Function to create particles at collision location
function createCollisionParticles(x, y) {
	// Create 8-12 particles for collision effect - fewer than click particles
	var particleCount = 8 + Math.floor(Math.random() * 5);
	for (var i = 0; i < particleCount; i++) {
		var particle = new Particle();
		particle.x = x;
		particle.y = y;
		particle.active = true;
		particle.scale.set(0.3, 0.3); // Smaller particles for collisions
		// Add to particles array and game display
		particles.push(particle);
		game.addChild(particle);
	}
}
// Initialize balls array
function createBall() {
	if (ballsInPlay >= maxBalls || !gameActive) {
		return;
	}
	var ball = new Ball();
	ball.reset(speedMultiplier);
	ball.getChildAt(0).tint = gameColors.ball;
	// Visual indicator of speed - make ball slightly smaller as it gets faster
	var scale = Math.max(0.6, 1 - (speedMultiplier - 1) * 0.15);
	ball.scale.set(scale, scale);
	balls.push(ball);
	game.addChild(ball);
	ballsInPlay++;
}
// Handle input events based on current state
game.down = function (x, y, obj) {
	// Play click sound whenever cursor is clicked
	if (soundEnabled) {
		LK.getSound('click').play();
	}
	// Create particles at click location
	createClickParticles(x, y);
	if (currentState === GAME_STATE.PLAYING) {
		paddle.x = x;
	}
	// Check if we hit any interactive elements
	if (obj && obj.event && obj.event.target && obj.event.target.down) {
		obj.event.target.down(x, y, obj);
	}
};
game.move = function (x, y, obj) {
	if (currentState === GAME_STATE.PLAYING) {
		paddle.x = x;
	}
};
// Update function
game.update = function () {
	// Update any diagonal stripes in the game (always update even when not playing)
	for (var i = 0; i < game.children.length; i++) {
		if (game.children[i] instanceof DiagonalStripe) {
			game.children[i].update();
		}
	}
	// Update all particles
	for (var i = particles.length - 1; i >= 0; i--) {
		var particle = particles[i];
		if (particle.active === false) {
			particle.destroy();
			particles.splice(i, 1);
			continue;
		}
		particle.update();
	}
	// Check if in playing state
	if (currentState !== GAME_STATE.PLAYING) {
		return;
	}
	// Game play state
	if (!gameActive) {
		return;
	}
	// Update speed indicator if it exists
	if (speedTxt) {
		speedTxt.setText('Speed: x' + speedMultiplier.toFixed(1));
	}
	// Only create a ball if none exists
	if (ballsInPlay === 0) {
		createBall();
	}
	// Update paddle and track position for physics calculations
	game.lastPaddleX = paddle.x; // Store current position for next frame
	paddle.update();
	// Update all balls
	for (var i = balls.length - 1; i >= 0; i--) {
		var ball = balls[i];
		if (!ball.active) {
			continue;
		}
		ball.update();
		// Check if ball hits paddle with improved collision detection
		if (ball.speedY > 0 && ball.y + 20 >= paddle.y - paddle.height / 2 && ball.y - 20 <= paddle.y + paddle.height / 2 && ball.x + 20 >= paddle.x - paddle.width / 2 && ball.x - 20 <= paddle.x + paddle.width / 2) {
			// Create particles at collision point
			createCollisionParticles(ball.x, ball.y);
			// Calculate hit position from -1 (left edge) to 1 (right edge)
			var hitPos = (ball.x - paddle.x) / (paddle.width / 2);
			// Calculate spin based on the difference between current and last hit position
			// This simulates the effect of a moving paddle hitting the ball
			var paddleMovementEffect = 0;
			if (game.lastPaddleX !== undefined) {
				paddleMovementEffect = (paddle.x - game.lastPaddleX) * 0.1;
			}
			// Apply reduced spin based on hit position and paddle movement
			ball.spin = hitPos * 0.3 + paddleMovementEffect * 0.6; // Reduced spin effect
			ball.lastHitPos = hitPos;
			// Calculate angle based on where the ball hits the paddle with more randomness
			// Wider angle range - full 180 degrees (0 to 180) instead of 120 degrees
			var angle = Math.PI * Math.random() + Math.PI / 2; // Random angle in upper half (90 to 270 degrees)
			// Add influence from hit position
			angle = angle * 0.7 + (Math.PI / 3 * hitPos + Math.PI / 2) * 0.3;
			// Calculate current speed with an adjustment
			var currentSpeed = Math.sqrt(ball.speedX * ball.speedX + ball.speedY * ball.speedY);
			var speed = Math.max(currentSpeed * 1.25, 12 * speedMultiplier);
			// Adjust ball direction with more random bounce physics
			ball.speedX = Math.cos(angle) * speed + paddleMovementEffect * 1.5;
			ball.speedY = -Math.sin(angle) * speed * 1.4; // Increased vertical multiplier for higher bounce
			// Add larger random variations for more unpredictable bouncing
			ball.speedX += (Math.random() * 4 - 2) * speedMultiplier; // Increased randomness
			ball.speedY += (Math.random() * 4 - 2) * speedMultiplier; // Increased randomness
			// Create a bounce effect with the paddle - make it visually respond to the hit
			tween(paddle, {
				scaleY: 0.85,
				y: paddle.y + 5
			}, {
				duration: 100,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(paddle, {
						scaleY: 1.0,
						y: paddle.y - 5
					}, {
						duration: 100,
						easing: tween.elasticOut
					});
				}
			});
			// Move ball above paddle to prevent multiple collisions
			ball.y = paddle.y - paddle.height / 2 - 20;
			// Add a visual impact effect
			var impactEffect = LK.getAsset('ball', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: ball.x,
				y: ball.y + 10,
				tint: 0xFFFFFF
			});
			impactEffect.scale.set(1.5, 0.5);
			impactEffect.alpha = 0.7;
			game.addChild(impactEffect);
			// Animate and remove the impact effect
			tween(impactEffect, {
				alpha: 0,
				scaleX: 2.5,
				scaleY: 0.2
			}, {
				duration: 200,
				onFinish: function onFinish() {
					impactEffect.destroy();
				}
			});
			// Simple scoring - always add 1 point
			score += 1;
			// Hide combo text
			comboTxt.alpha = 0;
			// Update hit counter
			scoreTxt.setText('' + score);
			// Center the score text
			scoreTxt.x = 2048 / 2; // True center horizontally
			scoreTxt.y = 2732 / 2; // True center vertically
			// Make it fade and gently grow when updated
			tween(scoreTxt, {
				scaleX: 1.1,
				// Smaller scale change
				scaleY: 1.1,
				// Smaller scale change
				alpha: 0.8 // Slight fade out
			}, {
				duration: 300,
				// Longer duration for smoother animation
				easing: tween.easeInOut,
				// Smoother easing
				onFinish: function onFinish() {
					tween(scoreTxt, {
						scaleX: 1,
						scaleY: 1,
						alpha: 1 // Back to full opacity
					}, {
						duration: 300,
						// Longer duration
						easing: tween.easeInOut // Smoother easing
					});
				}
			});
			LK.setScore(score);
			// Play bounce sound if enabled
			if (soundEnabled) {
				LK.getSound('bounce').play();
			}
			// Update hit counter for level system
			currentHits++;
			hitCounterText.setText(currentHits + '/' + hitsToNextLevel);
			// Level up based on hits
			if (currentHits >= hitsToNextLevel) {
				currentHits = 0;
				levelUp();
				hitCounterText.setText('Hits to Next Level: ' + hitsToNextLevel);
				// Animate hit counter text
				tween(hitCounterText, {
					scaleX: 1.2,
					scaleY: 1.2,
					alpha: 0.8
				}, {
					duration: 300,
					easing: tween.easeInOut,
					onFinish: function onFinish() {
						tween(hitCounterText, {
							scaleX: 1,
							scaleY: 1,
							alpha: 1
						}, {
							duration: 300,
							easing: tween.easeInOut
						});
					}
				});
			}
		}
		// Check if ball falls into lava
		if (ball.y > lava.y) {
			// Play lava sound if enabled
			if (soundEnabled) {
				LK.getSound('lava').play();
			}
			// Flash the lava
			tween(lava, {
				tint: 0xffffff
			}, {
				duration: 200,
				onFinish: function onFinish() {
					tween(lava, {
						tint: 0xe74c3c
					}, {
						duration: 200
					});
				}
			});
			// Remove ball
			ball.active = false;
			ball.destroy();
			balls.splice(i, 1);
			ballsInPlay--;
			// Check game over
			if (balls.length === 0 && ballsInPlay === 0) {
				gameOver();
			}
		}
	}
};
// Reset confirmation popup
function showResetConfirmation() {
	// Create popup container
	var popup = new Container();
	game.addChild(popup);
	// Popup background
	var popupBg = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	});
	popupBg.width = 1200;
	popupBg.height = 700;
	popupBg.tint = 0x101820;
	popup.addChild(popupBg);
	// Border for popup
	var popupBorder = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	});
	popupBorder.width = 1210;
	popupBorder.height = 710;
	popupBorder.tint = 0xFFB612;
	popup.addChildAt(popupBorder, 0);
	// Confirmation text
	var confirmText = new Text2('Reset High Score?', {
		size: 70,
		fill: 0xFFFFFF
	});
	confirmText.anchor.set(0.5, 0);
	confirmText.x = 1024;
	confirmText.y = 1200;
	popup.addChild(confirmText);
	// Yes button
	var yesButton = new Text2('Yes', {
		size: 60,
		fill: 0xFF6B6B
	});
	yesButton.anchor.set(0.5, 0.5);
	yesButton.x = 824;
	yesButton.y = 1450;
	yesButton.interactive = true;
	yesButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		// Reset high score
		highScore = 0;
		storage.highScore = 0;
		// Update high score display
		if (highScoreTxt) {
			highScoreTxt.setText('High Score: 0');
		}
		// Update settings display
		settingsPanel.children.forEach(function (child) {
			if (child instanceof Text2 && child.text && child.text.startsWith('High Score:')) {
				child.setText('High Score: 0');
			}
		});
		// Remove popup with animation
		tween(popup, {
			alpha: 0,
			scaleX: 0.8,
			scaleY: 0.8
		}, {
			duration: 300,
			onFinish: function onFinish() {
				popup.destroy();
			}
		});
	};
	popup.addChild(yesButton);
	// No button
	var noButton = new Text2('No', {
		size: 60,
		fill: 0xFFFFFF
	});
	noButton.anchor.set(0.5, 0.5);
	noButton.x = 1224;
	noButton.y = 1450;
	noButton.interactive = true;
	noButton.down = function () {
		if (soundEnabled) {
			LK.getSound('click').play();
		}
		// Remove popup with animation
		tween(popup, {
			alpha: 0,
			scaleX: 0.8,
			scaleY: 0.8
		}, {
			duration: 300,
			onFinish: function onFinish() {
				popup.destroy();
			}
		});
	};
	popup.addChild(noButton);
	// Animate popup appearing
	popup.scale.set(0.8, 0.8);
	popup.alpha = 0;
	tween(popup, {
		alpha: 1,
		scaleX: 1,
		scaleY: 1
	}, {
		duration: 300,
		easing: tween.easeOut
	});
}
function levelUp() {
	level++;
	levelTxt.setText('Level: ' + level);
	// Show level up message with speed information
	var levelUpTxt = new Text2('LEVEL UP!\nSpeed x' + speedMultiplier.toFixed(1), {
		size: 80,
		fill: 0xFFFFFF
	});
	levelUpTxt.anchor.set(0.5, 0.5);
	levelUpTxt.x = 1024;
	levelUpTxt.y = 1366;
	LK.gui.addChild(levelUpTxt);
	// Animate level up message
	tween(levelUpTxt, {
		alpha: 0,
		scaleX: 2,
		scaleY: 2
	}, {
		duration: 1000,
		onFinish: function onFinish() {
			levelUpTxt.destroy();
		}
	});
	// Change music to heavy metal if level is 4 or above
	if (level === 4 && musicEnabled) {
		// Transition to heavy metal music with fade effects
		LK.playMusic('heavyMetalMusic', {
			fade: {
				start: 0,
				end: 0.7,
				duration: 1500
			}
		});
	}
	// Increase difficulty with a moderate speed boost for slightly slower progression
	speedMultiplier += 0.4 + level * 0.08; // Reduced speed boost for slightly slower gameplay
	maxBalls = 1; // Keep maxBalls at 1
	// Reset hit counter for next level
	currentHits = 0;
	// Increase hits required for next level for increasing challenge
	hitsToNextLevel = 25 + (level - 1) * 5;
	hitCounterText.setText('0/' + hitsToNextLevel);
}
function gameOver() {
	gameActive = false;
	// Check if we have a new high score
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
		// Show new high score message
		var newHighScoreTxt = new Text2('NEW HIGH SCORE!', {
			size: 80,
			fill: 0xFFB612
		});
		newHighScoreTxt.anchor.set(0.5, 0.5);
		newHighScoreTxt.x = 1024;
		newHighScoreTxt.y = 1000;
		LK.gui.addChild(newHighScoreTxt);
		// Animate high score message
		tween(newHighScoreTxt, {
			alpha: 0,
			scaleX: 2,
			scaleY: 2
		}, {
			duration: 1500,
			onFinish: function onFinish() {
				newHighScoreTxt.destroy();
			}
		});
		// Update high score display
		if (highScoreTxt) {
			highScoreTxt.setText('High Score: ' + highScore);
		}
	}
	// Flash the screen red to indicate death
	LK.effects.flashScreen(0xff0000, 500);
	// If music enabled and player was at level 4 or above, prepare to reset music
	var shouldResetMusic = level >= 4 && musicEnabled;
	// Restart the game after a short delay instead of showing menu
	LK.setTimeout(function () {
		// Keep the game elements visible, just restart game logic
		// Clear any remaining balls
		for (var i = 0; i < balls.length; i++) {
			balls[i].destroy();
		}
		balls = [];
		ballsInPlay = 0;
		// Restart the game immediately
		startGame();
		// Ensure we're in playing state
		currentState = GAME_STATE.PLAYING;
	}, 500);
}
// Start the game
function startGame() {
	// Reset variables
	score = 0;
	level = 1;
	combo = 0;
	lastBallHit = 0;
	gameActive = true;
	speedMultiplier = 1.5; // Further reduced initial speed multiplier for slower initial gameplay
	maxBalls = 3; // Maintained same number of maximum balls
	ballsInPlay = 0;
	currentHits = 0;
	hitsToNextLevel = 25;
	// Update UI
	scoreTxt.setText('0');
	scoreTxt.scale.set(1, 1); // Reset any scaling from animations
	scoreTxt.x = 2048 / 2; // True center horizontally
	scoreTxt.y = 2732 / 2; // True center vertically
	levelTxt.setText('Level: 1');
	comboTxt.setText('');
	comboTxt.alpha = 0;
	hitCounterText.setText('0/' + hitsToNextLevel);
	// Update high score display
	if (highScoreTxt) {
		highScoreTxt.setText('High Score: ' + highScore);
	}
	// Clear any existing balls
	for (var i = 0; i < balls.length; i++) {
		balls[i].destroy();
	}
	balls = [];
	// Start with one ball
	createBall();
	// Play relaxing game music at start (level 1-3)
	if (musicEnabled) {
		LK.playMusic('gameMusic', {
			fade: {
				start: 0,
				end: 0.4,
				// Lower volume
				duration: 2000 // Longer fade in
			}
		});
	}
	// Ensure the current state is set to playing
	currentState = GAME_STATE.PLAYING;
}
// Game will start when player presses the Play button in the menu