User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'split')' in or related to this line: 'speedText.setText('Ball Speed: ' + speedText.text.split(':')[1] + ' (Speed up in ' + remainingTime + ')');' Line Number: 754
User prompt
Speed up ball every 30 second
User prompt
Polish the game
User prompt
Change interface
User prompt
Save progress ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Speed up the ball speed ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Speed up ball speed
Code edit (1 edits merged)
Please save this source code
User prompt
Cosmic Pong Showdown
User prompt
Please continue polishing my design document.
Initial prompt
Create a cat racing game car colour is red and trafic
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	score: 0,
	highScore: 0
});
/**** 
* Classes
****/ 
var Alien = Container.expand(function () {
	var self = Container.call(this);
	var alienGraphics = self.attachAsset('alien', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Track if the alien was hit
	self.lastWasIntersecting = false;
	// Motion pattern variables
	self.amplitude = Math.random() * 50 + 30;
	self.frequency = Math.random() * 0.05 + 0.02;
	self.baseX = 0;
	self.time = Math.random() * 100;
	self.points = 50;
	self.rotationSpeed = (Math.random() - 0.5) * 0.03;
	// Pulsate and color effect
	tween(alienGraphics, {
		alpha: 0.7
	}, {
		duration: 1000 + Math.random() * 1000,
		easing: tween.easeInOut,
		repeat: -1,
		yoyo: true
	});
	// Update alien position with sine wave motion and rotation
	self.update = function () {
		if (game.isPaused) {
			return;
		}
		self.time += 0.05;
		self.x = self.baseX + Math.sin(self.time * self.frequency) * self.amplitude;
		// Slowly rotate for visual effect
		self.rotation += self.rotationSpeed;
	};
	return self;
});
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create trail effect
	var trailEnabled = true;
	var trailInterval = 3; // Create trail every N frames
	var trailCount = 0;
	var trails = [];
	var maxTrails = 5;
	// Initial speed properties
	self.speedX = 5;
	self.speedY = 5;
	self.baseSpeed = 5;
	self.maxSpeed = 15;
	// Track previous position for collision detection
	self.lastX = 0;
	self.lastY = 0;
	// Pulse effect for the ball
	tween(ballGraphics, {
		alpha: 0.8
	}, {
		duration: 500,
		easing: tween.easeInOut,
		repeat: -1,
		yoyo: true
	});
	// Increase ball speed with limits
	self.accelerate = function (amount) {
		// Stop any ongoing speed tweens
		tween.stop(self, {
			speedX: true,
			speedY: true
		});
		// Calculate new speed maintaining direction
		var directionX = self.speedX >= 0 ? 1 : -1;
		var directionY = self.speedY >= 0 ? 1 : -1;
		var currentSpeed = Math.abs(self.speedX);
		var newSpeed = Math.min(currentSpeed + amount, self.maxSpeed);
		// Apply the new speed with tween effect
		tween(self, {
			speedX: newSpeed * directionX,
			speedY: newSpeed * directionY
		}, {
			duration: 300,
			easing: tween.easeOut
		});
		// Visual feedback for speed increase
		ballGraphics.tint = 0xFFFF00; // Yellow tint
		LK.setTimeout(function () {
			ballGraphics.tint = 0xFFFFFF; // Reset to white
		}, 500);
	};
	// Toggle trail effect
	self.enableTrail = function () {
		trailEnabled = true;
	};
	self.disableTrail = function () {
		trailEnabled = false;
		// Remove existing trails
		for (var i = 0; i < trails.length; i++) {
			if (trails[i].parent) {
				trails[i].parent.removeChild(trails[i]);
			}
		}
		trails = [];
	};
	// Reset ball speed to base value
	self.resetSpeed = function () {
		var directionX = self.speedX >= 0 ? 1 : -1;
		var directionY = self.speedY >= 0 ? 1 : -1;
		self.speedX = self.baseSpeed * directionX;
		self.speedY = self.baseSpeed * directionY;
		// Reset visual properties
		ballGraphics.tint = 0xFFFFFF;
	};
	// Update ball position and handle boundary collisions
	self.update = function () {
		// Skip updates if game is paused
		if (game.isPaused) {
			return;
		}
		// Create trail effect
		if (trailEnabled) {
			trailCount++;
			if (trailCount >= trailInterval) {
				trailCount = 0;
				// Create trail particle
				if (self.parent) {
					// Make sure ball is attached to something
					var trail = LK.getAsset('ball', {
						anchorX: 0.5,
						anchorY: 0.5,
						alpha: 0.3,
						tint: 0xf5e642
					});
					trail.x = self.x;
					trail.y = self.y;
					trail.scale.set(0.5);
					self.parent.addChild(trail);
					trails.push(trail);
					// Fade out and remove trail
					tween(trail, {
						alpha: 0,
						scaleX: 0.1,
						scaleY: 0.1
					}, {
						duration: 300,
						easing: tween.easeOut,
						onComplete: function onComplete() {
							if (trail.parent) {
								trail.parent.removeChild(trail);
							}
							var index = trails.indexOf(trail);
							if (index !== -1) {
								trails.splice(index, 1);
							}
						}
					});
					// Limit number of trails
					if (trails.length > maxTrails) {
						var oldestTrail = trails.shift();
						if (oldestTrail.parent) {
							oldestTrail.parent.removeChild(oldestTrail);
						}
					}
				}
			}
		}
		// Store last position for collision detection
		self.lastX = self.x;
		self.lastY = self.y;
		// Update position based on speed
		self.x += self.speedX;
		self.y += self.speedY;
		// Handle wall collisions
		if (self.x <= 0 || self.x >= 2048) {
			self.speedX *= -1;
			// Visual feedback for wall bounce
			LK.effects.flashObject(self, 0x00FFFF, 200);
		}
		if (self.y <= 0) {
			self.speedY *= -1;
			// Visual feedback for wall bounce
			LK.effects.flashObject(self, 0x00FFFF, 200);
		}
	};
	return self;
});
var Button = Container.expand(function () {
	var self = Container.call(this);
	var buttonGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.label = new Text2('', {
		size: 20,
		fill: 0xFFFFFF
	});
	self.label.anchor.set(0.5, 0.5);
	self.addChild(self.label);
	self.setText = function (text) {
		self.label.setText(text);
	};
	self.down = function () {
		if (self.onPress) {
			self.onPress();
		}
		LK.effects.flashObject(self, 0xFFFFFF, 300);
	};
	return self;
});
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	var paddleGraphics = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Add glow effect to paddle
	var glowEnabled = true;
	function updateGlow() {
		if (!glowEnabled) {
			return;
		}
		// Pulse effect
		tween(paddleGraphics, {
			alpha: 0.8
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			repeat: -1,
			yoyo: true
		});
	}
	// Call it once to start the effect
	updateGlow();
	// Add methods to enable/disable glow
	self.enableGlow = function () {
		glowEnabled = true;
		updateGlow();
	};
	self.disableGlow = function () {
		glowEnabled = false;
		paddleGraphics.alpha = 1;
	};
	// Handle paddle movement with constraints to keep paddle on screen
	self.move = function (x, y) {
		// Constrain paddle to screen bounds
		var halfWidth = paddleGraphics.width * self.scale.x / 2;
		if (x < halfWidth) {
			x = halfWidth;
		} else if (x > 2048 - halfWidth) {
			x = 2048 - halfWidth;
		}
		// Smooth movement with tween
		if (Math.abs(self.x - x) > 10) {
			tween.stop(self, {
				x: true
			});
			tween(self, {
				x: x
			}, {
				duration: 100,
				easing: tween.easeOut
			});
		} else {
			self.x = x;
		}
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// PowerUp properties
	self.fallSpeed = 3;
	self.type = "speed"; // Default type
	self.lastWasIntersecting = false;
	// Set the type and color of the power-up
	self.setType = function (type) {
		self.type = type;
		// Set different colors based on power-up type
		switch (type) {
			case "speed":
				powerUpGraphics.tint = 0xFF0000; // Red
				break;
			case "multiball":
				powerUpGraphics.tint = 0x00FF00; // Green
				break;
			case "expand":
				powerUpGraphics.tint = 0x0000FF; // Blue
				break;
			default:
				powerUpGraphics.tint = 0xFFFFFF;
			// White
		}
	};
	// Update PowerUp position
	self.update = function () {
		if (game.isPaused) {
			return;
		}
		// Fall down
		self.y += self.fallSpeed;
		// Rotate slightly for visual effect
		self.rotation += 0.01;
		// Remove if off screen
		if (self.y > 2732) {
			self.parent.removeChild(self);
		}
	};
	return self;
});
var Star = Container.expand(function () {
	var self = Container.call(this);
	var starGraphics = self.attachAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Initialize with random speed
	self.speed = Math.random() * 2 + 1;
	// Update star position, looping from bottom to top
	self.update = function () {
		if (game.isPaused) {
			return;
		}
		self.y += self.speed;
		// Loop back to top when star goes off screen
		if (self.y > 2732) {
			self.y = 0;
			self.x = Math.random() * 2048;
			self.speed = Math.random() * 2 + 1;
			self.alpha = Math.random() * 0.5 + 0.5;
			self.scale.set(Math.random() * 2 + 0.5);
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Create starry background
var stars = [];
for (var i = 0; i < 100; i++) {
	var star = new Star();
	star.x = Math.random() * 2048;
	star.y = Math.random() * 2732;
	star.alpha = Math.random() * 0.5 + 0.5;
	star.scale.set(Math.random() * 2 + 0.5);
	stars.push(star);
	game.addChild(star);
}
// Create alien targets
var aliens = [];
var alienRows = 3;
var aliensPerRow = 7;
var alienSpacingX = 250;
var alienSpacingY = 120;
var alienStartY = 400;
for (var row = 0; row < alienRows; row++) {
	for (var col = 0; col < aliensPerRow; col++) {
		var alien = new Alien();
		alien.baseX = 2048 / 2 - (aliensPerRow - 1) * alienSpacingX / 2 + col * alienSpacingX;
		alien.y = alienStartY + row * alienSpacingY;
		alien.x = alien.baseX;
		alien.points = 50 - row * 10; // First row worth more points
		alien.scale.set(0.8 - row * 0.1); // First row bigger
		aliens.push(alien);
		game.addChild(alien);
	}
}
// Create the game ball
var ball = new Ball();
ball.x = 2048 / 2;
ball.y = 2732 / 2;
game.addChild(ball);
// Create the player paddle
var paddle = new Paddle();
paddle.x = 2048 / 2;
paddle.y = 2732 - 100;
game.addChild(paddle);
// Tracking variables
var score = storage.score || 0; // Load saved score or start at 0
var speedUpTimer = null;
var consecutiveHits = 0;
var powerUps = [];
var alienCount = aliens.length;
game.isPaused = false; // Initialize game paused state
var paddleOriginalWidth = paddle.width;
// Create score display
var scoreText = new Text2('Score: ' + score, {
	size: 80,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create speed indicator
var speedText = new Text2('Ball Speed: Normal', {
	size: 60,
	fill: 0xFFFF00
});
speedText.anchor.set(0.5, 0);
speedText.y = 100;
LK.gui.top.addChild(speedText);
// Create high score display
var highScoreText = new Text2('High Score: ' + storage.highScore, {
	size: 60,
	fill: 0xFFA500
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 200;
LK.gui.top.addChild(highScoreText);
// Create game status text
var statusText = new Text2('', {
	size: 70,
	fill: 0x00FFFF
});
statusText.anchor.set(0.5, 0.5);
statusText.x = 2048 / 2;
statusText.y = 2732 / 2;
game.addChild(statusText);
// Create hits counter display
var hitsText = new Text2('Consecutive Hits: 0', {
	size: 50,
	fill: 0x00FF00
});
hitsText.anchor.set(0, 0);
hitsText.x = 50;
hitsText.y = 100;
LK.gui.left.addChild(hitsText);
// Update score display
function updateScore(points) {
	score += points;
	scoreText.setText('Score: ' + score);
	LK.setScore(score);
	// Save current score to storage
	storage.score = score;
	// Update high score if needed
	if (score > storage.highScore) {
		storage.highScore = score;
	}
}
// Update speed display
function updateSpeedDisplay() {
	var currentSpeed = Math.abs(ball.speedX);
	var speedLabel = "Normal";
	if (currentSpeed >= ball.maxSpeed) {
		speedLabel = "MAX!";
	} else if (currentSpeed > ball.baseSpeed + 6) {
		speedLabel = "Super Fast";
	} else if (currentSpeed > ball.baseSpeed + 3) {
		speedLabel = "Fast";
	}
	speedText.setText('Ball Speed: ' + speedLabel);
}
// Speed up the ball with visual effect
function speedUpBall() {
	ball.accelerate(1);
	updateSpeedDisplay();
	// Visual feedback for speed increase
	LK.effects.flashObject(ball, 0xff0000, 500);
	// Reset timer countdown
	lastSpeedUpTick = LK.ticks;
}
// Create a speed up button
var speedUpButton = new Button();
speedUpButton.x = 2048 - 100;
speedUpButton.y = 200;
speedUpButton.setText("Speed");
game.addChild(speedUpButton);
// Create a reset button
var resetButton = new Button();
resetButton.x = 2048 - 100;
resetButton.y = 300;
resetButton.setText("Reset");
game.addChild(resetButton);
// Create a pause button
var pauseButton = new Button();
pauseButton.x = 2048 - 100;
pauseButton.y = 400;
pauseButton.setText("Pause");
game.addChild(pauseButton);
// Event handlers
speedUpButton.onPress = function () {
	speedUpBall();
};
resetButton.onPress = function () {
	// Reset ball position
	ball.x = 2048 / 2;
	ball.y = 2732 / 2;
	ball.resetSpeed();
	updateSpeedDisplay();
};
pauseButton.onPress = function () {
	// Toggle game paused state
	var isPaused = !game.isPaused;
	game.isPaused = isPaused;
	pauseButton.setText(isPaused ? "Resume" : "Pause");
};
// Track paddle movement
game.move = function (x, y) {
	paddle.move(x, y);
};
// Collision detection
function checkCollisions() {
	// Ball-paddle collision
	if (ball.lastY <= paddle.y - paddle.height / 2 && ball.y > paddle.y - paddle.height / 2 && ball.x >= paddle.x - paddle.width / 2 && ball.x <= paddle.x + paddle.width / 2) {
		// Bounce the ball
		ball.speedY *= -1;
		// Adjust horizontal speed based on where the ball hits the paddle
		var hitPoint = (ball.x - paddle.x) / (paddle.width / 2);
		ball.speedX = ball.speedX * 0.5 + hitPoint * 5;
		// Increase consecutive hits counter
		consecutiveHits++;
		// Update hits text
		hitsText.setText('Consecutive Hits: ' + consecutiveHits);
		// Speed up after certain number of consecutive hits
		if (consecutiveHits >= 3) {
			speedUpBall();
			consecutiveHits = 0;
			statusText.setText('SPEED BOOST!');
			// Flash status and make it disappear
			LK.effects.flashObject(statusText, 0xFFFF00, 500);
			LK.setTimeout(function () {
				statusText.setText('');
			}, 1500);
			// Update hits text again
			hitsText.setText('Consecutive Hits: ' + consecutiveHits);
		}
		// Score points
		updateScore(10);
		// Play hit animation
		LK.effects.flashObject(paddle, 0x00FFFF, 300);
	}
	// Check ball-alien collisions
	for (var i = aliens.length - 1; i >= 0; i--) {
		var alien = aliens[i];
		var currentIntersecting = ball.intersects(alien);
		if (!alien.lastWasIntersecting && currentIntersecting) {
			// Bounce ball
			ball.speedY *= -1;
			// Add points based on alien value
			updateScore(alien.points);
			// Visual feedback
			LK.effects.flashObject(alien, 0xFFFFFF, 200);
			// Remove alien
			game.removeChild(alien);
			aliens.splice(i, 1);
			alienCount--;
			// Drop power-up with 20% chance
			if (Math.random() < 0.2) {
				var powerUp = new PowerUp();
				powerUp.x = alien.x;
				powerUp.y = alien.y;
				// Randomly select power-up type
				var types = ["speed", "multiball", "expand"];
				var randomType = types[Math.floor(Math.random() * types.length)];
				powerUp.setType(randomType);
				powerUps.push(powerUp);
				game.addChild(powerUp);
			}
			// Check if all aliens are destroyed
			if (alienCount === 0) {
				statusText.setText('LEVEL COMPLETE!');
				LK.effects.flashScreen(0x00FF00, 800);
				// Add bonus points
				updateScore(500);
				// Respawn aliens after delay
				LK.setTimeout(function () {
					respawnAliens();
					statusText.setText('');
				}, 2000);
			}
		}
		// Update last intersecting state
		alien.lastWasIntersecting = currentIntersecting;
	}
	// Check paddle-powerup collisions
	for (var j = powerUps.length - 1; j >= 0; j--) {
		var powerUp = powerUps[j];
		var isIntersecting = powerUp.intersects(paddle);
		if (!powerUp.lastWasIntersecting && isIntersecting) {
			// Apply power-up effect
			applyPowerUp(powerUp.type);
			// Visual feedback
			LK.effects.flashObject(paddle, 0xFFFF00, 500);
			// Remove power-up
			game.removeChild(powerUp);
			powerUps.splice(j, 1);
		}
		// Update last intersecting state
		powerUp.lastWasIntersecting = isIntersecting;
	}
	// Ball off bottom of screen (game over condition)
	if (ball.y > 2732) {
		// Show game over notification
		statusText.setText('GAME OVER!');
		LK.effects.flashObject(statusText, 0xFF0000, 800);
		// Save high score before game ends
		if (score > storage.highScore) {
			storage.highScore = score;
			// Show new high score notification
			statusText.setText('NEW HIGH SCORE!');
		}
		// Reset current score to 0 in storage
		storage.score = 0;
		// Short delay before showing game over screen
		LK.setTimeout(function () {
			LK.showGameOver();
		}, 1000);
	}
}
// Apply power-up effects
function applyPowerUp(type) {
	switch (type) {
		case "speed":
			// Speed boost
			speedUpBall();
			statusText.setText('SPEED BOOST!');
			break;
		case "multiball":
			// Multiball feature would go here
			// For simplicity, let's just add points
			updateScore(100);
			statusText.setText('BONUS POINTS!');
			break;
		case "expand":
			// Expand paddle
			var originalWidth = paddle.width;
			tween.stop(paddle.scale);
			tween(paddle.scale, {
				x: 1.5
			}, {
				duration: 300,
				easing: tween.easeOut
			});
			// Reset after 10 seconds
			LK.setTimeout(function () {
				tween(paddle.scale, {
					x: 1
				}, {
					duration: 300,
					easing: tween.easeIn
				});
			}, 10000);
			statusText.setText('PADDLE EXPANDED!');
			break;
	}
	// Clear status text after delay
	LK.setTimeout(function () {
		statusText.setText('');
	}, 1500);
}
// Respawn aliens
function respawnAliens() {
	// Clear any remaining aliens
	for (var i = aliens.length - 1; i >= 0; i--) {
		game.removeChild(aliens[i]);
	}
	aliens = [];
	// Respawn with more difficulty
	aliensPerRow += 1; // More aliens per row
	for (var row = 0; row < alienRows; row++) {
		for (var col = 0; col < aliensPerRow; col++) {
			var alien = new Alien();
			alien.baseX = 2048 / 2 - (aliensPerRow - 1) * alienSpacingX / 2 + col * alienSpacingX;
			alien.y = alienStartY + row * alienSpacingY;
			alien.x = alien.baseX;
			alien.points = (50 - row * 10) * 1.5; // Increased points
			alien.scale.set(0.8 - row * 0.1);
			alien.frequency += 0.01; // Faster movement
			aliens.push(alien);
			game.addChild(alien);
		}
	}
	alienCount = aliens.length;
	// Speed up ball slightly
	speedUpBall();
}
// Auto speed up every 30 seconds
var speedUpInterval = LK.setInterval(function () {
	speedUpBall();
	// Visual feedback for automatic speed up
	statusText.setText('AUTO SPEED BOOST!');
	LK.setTimeout(function () {
		statusText.setText('');
	}, 1500);
}, 30000);
// Track time until next speed up
var nextSpeedUpTime = 30000;
var lastSpeedUpTick = LK.ticks;
// Main game update loop
game.update = function () {
	// Skip updates if game is paused
	if (game.isPaused) {
		return;
	}
	// Update all stars
	for (var i = 0; i < stars.length; i++) {
		stars[i].update();
	}
	// Update all aliens
	for (var j = 0; j < aliens.length; j++) {
		aliens[j].update();
	}
	// Update all power-ups
	for (var k = powerUps.length - 1; k >= 0; k--) {
		powerUps[k].update();
		// Remove power-ups that have gone off screen
		if (powerUps[k].y > 2732) {
			game.removeChild(powerUps[k]);
			powerUps.splice(k, 1);
		}
	}
	checkCollisions();
	updateSpeedDisplay();
	// Update speed up timer display
	if (!game.isPaused) {
		var elapsedTicks = LK.ticks - lastSpeedUpTick;
		var elapsedMs = elapsedTicks * (1000 / 60); // Convert ticks to ms at 60fps
		var remainingTime = Math.max(0, Math.ceil((nextSpeedUpTime - elapsedMs) / 1000));
		// Display countdown when less than 10 seconds
		if (remainingTime <= 10) {
			// Get the current speed label without trying to parse the existing text
			var currentSpeed = Math.abs(ball.speedX);
			var speedLabel = "Normal";
			if (currentSpeed >= ball.maxSpeed) {
				speedLabel = "MAX!";
			} else if (currentSpeed > ball.baseSpeed + 6) {
				speedLabel = "Super Fast";
			} else if (currentSpeed > ball.baseSpeed + 3) {
				speedLabel = "Fast";
			}
			speedText.setText('Ball Speed: ' + speedLabel + ' (Speed up in ' + remainingTime + ')');
			speedText.tint = 0xFF0000; // Red for emphasis
		} else {
			speedText.tint = 0xFFFF00; // Default yellow
		}
		// Check if it's time for speed boost (handles missed intervals)
		if (elapsedMs >= nextSpeedUpTime) {
			speedUpBall();
			statusText.setText('AUTO SPEED BOOST!');
			LK.setTimeout(function () {
				statusText.setText('');
			}, 1500);
			lastSpeedUpTick = LK.ticks;
		}
	}
	// Fancy visual effect - pulsate active power-ups
	if (paddle.scale.x > 1) {
		paddle.alpha = 0.7 + Math.sin(LK.ticks * 0.1) * 0.3;
	} else {
		paddle.alpha = 1;
	}
};
// Create speed up keyboard shortcut for testing
LK.setTimeout(function () {
	// Initial speed boost to make the game more exciting from the start
	speedUpBall();
}, 3000); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	score: 0,
	highScore: 0
});
/**** 
* Classes
****/ 
var Alien = Container.expand(function () {
	var self = Container.call(this);
	var alienGraphics = self.attachAsset('alien', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Track if the alien was hit
	self.lastWasIntersecting = false;
	// Motion pattern variables
	self.amplitude = Math.random() * 50 + 30;
	self.frequency = Math.random() * 0.05 + 0.02;
	self.baseX = 0;
	self.time = Math.random() * 100;
	self.points = 50;
	self.rotationSpeed = (Math.random() - 0.5) * 0.03;
	// Pulsate and color effect
	tween(alienGraphics, {
		alpha: 0.7
	}, {
		duration: 1000 + Math.random() * 1000,
		easing: tween.easeInOut,
		repeat: -1,
		yoyo: true
	});
	// Update alien position with sine wave motion and rotation
	self.update = function () {
		if (game.isPaused) {
			return;
		}
		self.time += 0.05;
		self.x = self.baseX + Math.sin(self.time * self.frequency) * self.amplitude;
		// Slowly rotate for visual effect
		self.rotation += self.rotationSpeed;
	};
	return self;
});
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create trail effect
	var trailEnabled = true;
	var trailInterval = 3; // Create trail every N frames
	var trailCount = 0;
	var trails = [];
	var maxTrails = 5;
	// Initial speed properties
	self.speedX = 5;
	self.speedY = 5;
	self.baseSpeed = 5;
	self.maxSpeed = 15;
	// Track previous position for collision detection
	self.lastX = 0;
	self.lastY = 0;
	// Pulse effect for the ball
	tween(ballGraphics, {
		alpha: 0.8
	}, {
		duration: 500,
		easing: tween.easeInOut,
		repeat: -1,
		yoyo: true
	});
	// Increase ball speed with limits
	self.accelerate = function (amount) {
		// Stop any ongoing speed tweens
		tween.stop(self, {
			speedX: true,
			speedY: true
		});
		// Calculate new speed maintaining direction
		var directionX = self.speedX >= 0 ? 1 : -1;
		var directionY = self.speedY >= 0 ? 1 : -1;
		var currentSpeed = Math.abs(self.speedX);
		var newSpeed = Math.min(currentSpeed + amount, self.maxSpeed);
		// Apply the new speed with tween effect
		tween(self, {
			speedX: newSpeed * directionX,
			speedY: newSpeed * directionY
		}, {
			duration: 300,
			easing: tween.easeOut
		});
		// Visual feedback for speed increase
		ballGraphics.tint = 0xFFFF00; // Yellow tint
		LK.setTimeout(function () {
			ballGraphics.tint = 0xFFFFFF; // Reset to white
		}, 500);
	};
	// Toggle trail effect
	self.enableTrail = function () {
		trailEnabled = true;
	};
	self.disableTrail = function () {
		trailEnabled = false;
		// Remove existing trails
		for (var i = 0; i < trails.length; i++) {
			if (trails[i].parent) {
				trails[i].parent.removeChild(trails[i]);
			}
		}
		trails = [];
	};
	// Reset ball speed to base value
	self.resetSpeed = function () {
		var directionX = self.speedX >= 0 ? 1 : -1;
		var directionY = self.speedY >= 0 ? 1 : -1;
		self.speedX = self.baseSpeed * directionX;
		self.speedY = self.baseSpeed * directionY;
		// Reset visual properties
		ballGraphics.tint = 0xFFFFFF;
	};
	// Update ball position and handle boundary collisions
	self.update = function () {
		// Skip updates if game is paused
		if (game.isPaused) {
			return;
		}
		// Create trail effect
		if (trailEnabled) {
			trailCount++;
			if (trailCount >= trailInterval) {
				trailCount = 0;
				// Create trail particle
				if (self.parent) {
					// Make sure ball is attached to something
					var trail = LK.getAsset('ball', {
						anchorX: 0.5,
						anchorY: 0.5,
						alpha: 0.3,
						tint: 0xf5e642
					});
					trail.x = self.x;
					trail.y = self.y;
					trail.scale.set(0.5);
					self.parent.addChild(trail);
					trails.push(trail);
					// Fade out and remove trail
					tween(trail, {
						alpha: 0,
						scaleX: 0.1,
						scaleY: 0.1
					}, {
						duration: 300,
						easing: tween.easeOut,
						onComplete: function onComplete() {
							if (trail.parent) {
								trail.parent.removeChild(trail);
							}
							var index = trails.indexOf(trail);
							if (index !== -1) {
								trails.splice(index, 1);
							}
						}
					});
					// Limit number of trails
					if (trails.length > maxTrails) {
						var oldestTrail = trails.shift();
						if (oldestTrail.parent) {
							oldestTrail.parent.removeChild(oldestTrail);
						}
					}
				}
			}
		}
		// Store last position for collision detection
		self.lastX = self.x;
		self.lastY = self.y;
		// Update position based on speed
		self.x += self.speedX;
		self.y += self.speedY;
		// Handle wall collisions
		if (self.x <= 0 || self.x >= 2048) {
			self.speedX *= -1;
			// Visual feedback for wall bounce
			LK.effects.flashObject(self, 0x00FFFF, 200);
		}
		if (self.y <= 0) {
			self.speedY *= -1;
			// Visual feedback for wall bounce
			LK.effects.flashObject(self, 0x00FFFF, 200);
		}
	};
	return self;
});
var Button = Container.expand(function () {
	var self = Container.call(this);
	var buttonGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.label = new Text2('', {
		size: 20,
		fill: 0xFFFFFF
	});
	self.label.anchor.set(0.5, 0.5);
	self.addChild(self.label);
	self.setText = function (text) {
		self.label.setText(text);
	};
	self.down = function () {
		if (self.onPress) {
			self.onPress();
		}
		LK.effects.flashObject(self, 0xFFFFFF, 300);
	};
	return self;
});
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	var paddleGraphics = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Add glow effect to paddle
	var glowEnabled = true;
	function updateGlow() {
		if (!glowEnabled) {
			return;
		}
		// Pulse effect
		tween(paddleGraphics, {
			alpha: 0.8
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			repeat: -1,
			yoyo: true
		});
	}
	// Call it once to start the effect
	updateGlow();
	// Add methods to enable/disable glow
	self.enableGlow = function () {
		glowEnabled = true;
		updateGlow();
	};
	self.disableGlow = function () {
		glowEnabled = false;
		paddleGraphics.alpha = 1;
	};
	// Handle paddle movement with constraints to keep paddle on screen
	self.move = function (x, y) {
		// Constrain paddle to screen bounds
		var halfWidth = paddleGraphics.width * self.scale.x / 2;
		if (x < halfWidth) {
			x = halfWidth;
		} else if (x > 2048 - halfWidth) {
			x = 2048 - halfWidth;
		}
		// Smooth movement with tween
		if (Math.abs(self.x - x) > 10) {
			tween.stop(self, {
				x: true
			});
			tween(self, {
				x: x
			}, {
				duration: 100,
				easing: tween.easeOut
			});
		} else {
			self.x = x;
		}
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// PowerUp properties
	self.fallSpeed = 3;
	self.type = "speed"; // Default type
	self.lastWasIntersecting = false;
	// Set the type and color of the power-up
	self.setType = function (type) {
		self.type = type;
		// Set different colors based on power-up type
		switch (type) {
			case "speed":
				powerUpGraphics.tint = 0xFF0000; // Red
				break;
			case "multiball":
				powerUpGraphics.tint = 0x00FF00; // Green
				break;
			case "expand":
				powerUpGraphics.tint = 0x0000FF; // Blue
				break;
			default:
				powerUpGraphics.tint = 0xFFFFFF;
			// White
		}
	};
	// Update PowerUp position
	self.update = function () {
		if (game.isPaused) {
			return;
		}
		// Fall down
		self.y += self.fallSpeed;
		// Rotate slightly for visual effect
		self.rotation += 0.01;
		// Remove if off screen
		if (self.y > 2732) {
			self.parent.removeChild(self);
		}
	};
	return self;
});
var Star = Container.expand(function () {
	var self = Container.call(this);
	var starGraphics = self.attachAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Initialize with random speed
	self.speed = Math.random() * 2 + 1;
	// Update star position, looping from bottom to top
	self.update = function () {
		if (game.isPaused) {
			return;
		}
		self.y += self.speed;
		// Loop back to top when star goes off screen
		if (self.y > 2732) {
			self.y = 0;
			self.x = Math.random() * 2048;
			self.speed = Math.random() * 2 + 1;
			self.alpha = Math.random() * 0.5 + 0.5;
			self.scale.set(Math.random() * 2 + 0.5);
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Create starry background
var stars = [];
for (var i = 0; i < 100; i++) {
	var star = new Star();
	star.x = Math.random() * 2048;
	star.y = Math.random() * 2732;
	star.alpha = Math.random() * 0.5 + 0.5;
	star.scale.set(Math.random() * 2 + 0.5);
	stars.push(star);
	game.addChild(star);
}
// Create alien targets
var aliens = [];
var alienRows = 3;
var aliensPerRow = 7;
var alienSpacingX = 250;
var alienSpacingY = 120;
var alienStartY = 400;
for (var row = 0; row < alienRows; row++) {
	for (var col = 0; col < aliensPerRow; col++) {
		var alien = new Alien();
		alien.baseX = 2048 / 2 - (aliensPerRow - 1) * alienSpacingX / 2 + col * alienSpacingX;
		alien.y = alienStartY + row * alienSpacingY;
		alien.x = alien.baseX;
		alien.points = 50 - row * 10; // First row worth more points
		alien.scale.set(0.8 - row * 0.1); // First row bigger
		aliens.push(alien);
		game.addChild(alien);
	}
}
// Create the game ball
var ball = new Ball();
ball.x = 2048 / 2;
ball.y = 2732 / 2;
game.addChild(ball);
// Create the player paddle
var paddle = new Paddle();
paddle.x = 2048 / 2;
paddle.y = 2732 - 100;
game.addChild(paddle);
// Tracking variables
var score = storage.score || 0; // Load saved score or start at 0
var speedUpTimer = null;
var consecutiveHits = 0;
var powerUps = [];
var alienCount = aliens.length;
game.isPaused = false; // Initialize game paused state
var paddleOriginalWidth = paddle.width;
// Create score display
var scoreText = new Text2('Score: ' + score, {
	size: 80,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create speed indicator
var speedText = new Text2('Ball Speed: Normal', {
	size: 60,
	fill: 0xFFFF00
});
speedText.anchor.set(0.5, 0);
speedText.y = 100;
LK.gui.top.addChild(speedText);
// Create high score display
var highScoreText = new Text2('High Score: ' + storage.highScore, {
	size: 60,
	fill: 0xFFA500
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 200;
LK.gui.top.addChild(highScoreText);
// Create game status text
var statusText = new Text2('', {
	size: 70,
	fill: 0x00FFFF
});
statusText.anchor.set(0.5, 0.5);
statusText.x = 2048 / 2;
statusText.y = 2732 / 2;
game.addChild(statusText);
// Create hits counter display
var hitsText = new Text2('Consecutive Hits: 0', {
	size: 50,
	fill: 0x00FF00
});
hitsText.anchor.set(0, 0);
hitsText.x = 50;
hitsText.y = 100;
LK.gui.left.addChild(hitsText);
// Update score display
function updateScore(points) {
	score += points;
	scoreText.setText('Score: ' + score);
	LK.setScore(score);
	// Save current score to storage
	storage.score = score;
	// Update high score if needed
	if (score > storage.highScore) {
		storage.highScore = score;
	}
}
// Update speed display
function updateSpeedDisplay() {
	var currentSpeed = Math.abs(ball.speedX);
	var speedLabel = "Normal";
	if (currentSpeed >= ball.maxSpeed) {
		speedLabel = "MAX!";
	} else if (currentSpeed > ball.baseSpeed + 6) {
		speedLabel = "Super Fast";
	} else if (currentSpeed > ball.baseSpeed + 3) {
		speedLabel = "Fast";
	}
	speedText.setText('Ball Speed: ' + speedLabel);
}
// Speed up the ball with visual effect
function speedUpBall() {
	ball.accelerate(1);
	updateSpeedDisplay();
	// Visual feedback for speed increase
	LK.effects.flashObject(ball, 0xff0000, 500);
	// Reset timer countdown
	lastSpeedUpTick = LK.ticks;
}
// Create a speed up button
var speedUpButton = new Button();
speedUpButton.x = 2048 - 100;
speedUpButton.y = 200;
speedUpButton.setText("Speed");
game.addChild(speedUpButton);
// Create a reset button
var resetButton = new Button();
resetButton.x = 2048 - 100;
resetButton.y = 300;
resetButton.setText("Reset");
game.addChild(resetButton);
// Create a pause button
var pauseButton = new Button();
pauseButton.x = 2048 - 100;
pauseButton.y = 400;
pauseButton.setText("Pause");
game.addChild(pauseButton);
// Event handlers
speedUpButton.onPress = function () {
	speedUpBall();
};
resetButton.onPress = function () {
	// Reset ball position
	ball.x = 2048 / 2;
	ball.y = 2732 / 2;
	ball.resetSpeed();
	updateSpeedDisplay();
};
pauseButton.onPress = function () {
	// Toggle game paused state
	var isPaused = !game.isPaused;
	game.isPaused = isPaused;
	pauseButton.setText(isPaused ? "Resume" : "Pause");
};
// Track paddle movement
game.move = function (x, y) {
	paddle.move(x, y);
};
// Collision detection
function checkCollisions() {
	// Ball-paddle collision
	if (ball.lastY <= paddle.y - paddle.height / 2 && ball.y > paddle.y - paddle.height / 2 && ball.x >= paddle.x - paddle.width / 2 && ball.x <= paddle.x + paddle.width / 2) {
		// Bounce the ball
		ball.speedY *= -1;
		// Adjust horizontal speed based on where the ball hits the paddle
		var hitPoint = (ball.x - paddle.x) / (paddle.width / 2);
		ball.speedX = ball.speedX * 0.5 + hitPoint * 5;
		// Increase consecutive hits counter
		consecutiveHits++;
		// Update hits text
		hitsText.setText('Consecutive Hits: ' + consecutiveHits);
		// Speed up after certain number of consecutive hits
		if (consecutiveHits >= 3) {
			speedUpBall();
			consecutiveHits = 0;
			statusText.setText('SPEED BOOST!');
			// Flash status and make it disappear
			LK.effects.flashObject(statusText, 0xFFFF00, 500);
			LK.setTimeout(function () {
				statusText.setText('');
			}, 1500);
			// Update hits text again
			hitsText.setText('Consecutive Hits: ' + consecutiveHits);
		}
		// Score points
		updateScore(10);
		// Play hit animation
		LK.effects.flashObject(paddle, 0x00FFFF, 300);
	}
	// Check ball-alien collisions
	for (var i = aliens.length - 1; i >= 0; i--) {
		var alien = aliens[i];
		var currentIntersecting = ball.intersects(alien);
		if (!alien.lastWasIntersecting && currentIntersecting) {
			// Bounce ball
			ball.speedY *= -1;
			// Add points based on alien value
			updateScore(alien.points);
			// Visual feedback
			LK.effects.flashObject(alien, 0xFFFFFF, 200);
			// Remove alien
			game.removeChild(alien);
			aliens.splice(i, 1);
			alienCount--;
			// Drop power-up with 20% chance
			if (Math.random() < 0.2) {
				var powerUp = new PowerUp();
				powerUp.x = alien.x;
				powerUp.y = alien.y;
				// Randomly select power-up type
				var types = ["speed", "multiball", "expand"];
				var randomType = types[Math.floor(Math.random() * types.length)];
				powerUp.setType(randomType);
				powerUps.push(powerUp);
				game.addChild(powerUp);
			}
			// Check if all aliens are destroyed
			if (alienCount === 0) {
				statusText.setText('LEVEL COMPLETE!');
				LK.effects.flashScreen(0x00FF00, 800);
				// Add bonus points
				updateScore(500);
				// Respawn aliens after delay
				LK.setTimeout(function () {
					respawnAliens();
					statusText.setText('');
				}, 2000);
			}
		}
		// Update last intersecting state
		alien.lastWasIntersecting = currentIntersecting;
	}
	// Check paddle-powerup collisions
	for (var j = powerUps.length - 1; j >= 0; j--) {
		var powerUp = powerUps[j];
		var isIntersecting = powerUp.intersects(paddle);
		if (!powerUp.lastWasIntersecting && isIntersecting) {
			// Apply power-up effect
			applyPowerUp(powerUp.type);
			// Visual feedback
			LK.effects.flashObject(paddle, 0xFFFF00, 500);
			// Remove power-up
			game.removeChild(powerUp);
			powerUps.splice(j, 1);
		}
		// Update last intersecting state
		powerUp.lastWasIntersecting = isIntersecting;
	}
	// Ball off bottom of screen (game over condition)
	if (ball.y > 2732) {
		// Show game over notification
		statusText.setText('GAME OVER!');
		LK.effects.flashObject(statusText, 0xFF0000, 800);
		// Save high score before game ends
		if (score > storage.highScore) {
			storage.highScore = score;
			// Show new high score notification
			statusText.setText('NEW HIGH SCORE!');
		}
		// Reset current score to 0 in storage
		storage.score = 0;
		// Short delay before showing game over screen
		LK.setTimeout(function () {
			LK.showGameOver();
		}, 1000);
	}
}
// Apply power-up effects
function applyPowerUp(type) {
	switch (type) {
		case "speed":
			// Speed boost
			speedUpBall();
			statusText.setText('SPEED BOOST!');
			break;
		case "multiball":
			// Multiball feature would go here
			// For simplicity, let's just add points
			updateScore(100);
			statusText.setText('BONUS POINTS!');
			break;
		case "expand":
			// Expand paddle
			var originalWidth = paddle.width;
			tween.stop(paddle.scale);
			tween(paddle.scale, {
				x: 1.5
			}, {
				duration: 300,
				easing: tween.easeOut
			});
			// Reset after 10 seconds
			LK.setTimeout(function () {
				tween(paddle.scale, {
					x: 1
				}, {
					duration: 300,
					easing: tween.easeIn
				});
			}, 10000);
			statusText.setText('PADDLE EXPANDED!');
			break;
	}
	// Clear status text after delay
	LK.setTimeout(function () {
		statusText.setText('');
	}, 1500);
}
// Respawn aliens
function respawnAliens() {
	// Clear any remaining aliens
	for (var i = aliens.length - 1; i >= 0; i--) {
		game.removeChild(aliens[i]);
	}
	aliens = [];
	// Respawn with more difficulty
	aliensPerRow += 1; // More aliens per row
	for (var row = 0; row < alienRows; row++) {
		for (var col = 0; col < aliensPerRow; col++) {
			var alien = new Alien();
			alien.baseX = 2048 / 2 - (aliensPerRow - 1) * alienSpacingX / 2 + col * alienSpacingX;
			alien.y = alienStartY + row * alienSpacingY;
			alien.x = alien.baseX;
			alien.points = (50 - row * 10) * 1.5; // Increased points
			alien.scale.set(0.8 - row * 0.1);
			alien.frequency += 0.01; // Faster movement
			aliens.push(alien);
			game.addChild(alien);
		}
	}
	alienCount = aliens.length;
	// Speed up ball slightly
	speedUpBall();
}
// Auto speed up every 30 seconds
var speedUpInterval = LK.setInterval(function () {
	speedUpBall();
	// Visual feedback for automatic speed up
	statusText.setText('AUTO SPEED BOOST!');
	LK.setTimeout(function () {
		statusText.setText('');
	}, 1500);
}, 30000);
// Track time until next speed up
var nextSpeedUpTime = 30000;
var lastSpeedUpTick = LK.ticks;
// Main game update loop
game.update = function () {
	// Skip updates if game is paused
	if (game.isPaused) {
		return;
	}
	// Update all stars
	for (var i = 0; i < stars.length; i++) {
		stars[i].update();
	}
	// Update all aliens
	for (var j = 0; j < aliens.length; j++) {
		aliens[j].update();
	}
	// Update all power-ups
	for (var k = powerUps.length - 1; k >= 0; k--) {
		powerUps[k].update();
		// Remove power-ups that have gone off screen
		if (powerUps[k].y > 2732) {
			game.removeChild(powerUps[k]);
			powerUps.splice(k, 1);
		}
	}
	checkCollisions();
	updateSpeedDisplay();
	// Update speed up timer display
	if (!game.isPaused) {
		var elapsedTicks = LK.ticks - lastSpeedUpTick;
		var elapsedMs = elapsedTicks * (1000 / 60); // Convert ticks to ms at 60fps
		var remainingTime = Math.max(0, Math.ceil((nextSpeedUpTime - elapsedMs) / 1000));
		// Display countdown when less than 10 seconds
		if (remainingTime <= 10) {
			// Get the current speed label without trying to parse the existing text
			var currentSpeed = Math.abs(ball.speedX);
			var speedLabel = "Normal";
			if (currentSpeed >= ball.maxSpeed) {
				speedLabel = "MAX!";
			} else if (currentSpeed > ball.baseSpeed + 6) {
				speedLabel = "Super Fast";
			} else if (currentSpeed > ball.baseSpeed + 3) {
				speedLabel = "Fast";
			}
			speedText.setText('Ball Speed: ' + speedLabel + ' (Speed up in ' + remainingTime + ')');
			speedText.tint = 0xFF0000; // Red for emphasis
		} else {
			speedText.tint = 0xFFFF00; // Default yellow
		}
		// Check if it's time for speed boost (handles missed intervals)
		if (elapsedMs >= nextSpeedUpTime) {
			speedUpBall();
			statusText.setText('AUTO SPEED BOOST!');
			LK.setTimeout(function () {
				statusText.setText('');
			}, 1500);
			lastSpeedUpTick = LK.ticks;
		}
	}
	// Fancy visual effect - pulsate active power-ups
	if (paddle.scale.x > 1) {
		paddle.alpha = 0.7 + Math.sin(LK.ticks * 0.1) * 0.3;
	} else {
		paddle.alpha = 1;
	}
};
// Create speed up keyboard shortcut for testing
LK.setTimeout(function () {
	// Initial speed boost to make the game more exciting from the start
	speedUpBall();
}, 3000);