User prompt
Extended it a tiny bit
User prompt
Make it a tiny bit more invisible
User prompt
Make the effects longer so it’s not inside of the cube or circle
User prompt
Fix the effects to wear when it hits the bottom it disappears like the obstacle
User prompt
Make the effects bigger and more colourful
User prompt
Add the colour of the obstacle effects behind it. Has it goes like the player
User prompt
Fix error displayed survive! Text 10 seconds after the warning clears
User prompt
10 seconds after the warning say survived!
User prompt
After the warning clears add a tiny bit more objects for 10 seconds then repeat
User prompt
Not that many obstacles but five seconds before it starts put a warning saying warning, obstacle rain incoming!
User prompt
After five seconds it stops
User prompt
Every 30 points make it rain obstacles at 20 speed
User prompt
Make the obstacles range from dark red to light red
User prompt
Please fix the bug: 'ReferenceError: Can't find variable: boss' in or related to this line: 'if (boss) {' Line Number: 404
User prompt
At 60 points spawn a boss that last for 20 seconds, and they will aim a 0.4 visibility laser, but when it gets set to zero, make it shoot in the direction that it was pointed at if it touches the player the player dies instantly 3 seconds later laser follow player again then repeat ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The bomb asset when the player gets close to it, make it expand, but disappear after 1 second ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the player dies, add an explosion sound
User prompt
When the player starts the game, make dubstep music play and when it ends make it repeat
User prompt
Make it speed up by 0.1 every 5 points
User prompt
Stop making the make more obstacle spawn at 30
User prompt
Make the obstacles be random sizes
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'if (leaderboardTxt) {' Line Number: 197
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'game.removeChild(leaderboardTxt);' Line Number: 197
User prompt
Add a leaderboard on the home screen showing highest score by a random player and when you click play, it disappears until the player dies
Code edit (1 edits merged)
Please save this source code
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Boss = Container.expand(function () {
	var self = Container.call(this);
	var bossGraphics = self.attachAsset('circle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.laser = new Container();
	self.laserGraphics = self.laser.attachAsset('square', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.4
	});
	self.laserGraphics.scaleY = 10; // Make the laser long
	self.laserGraphics.scaleX = 0.1; // Make the laser thin
	self.addChild(self.laser);
	self.laserDirection = {
		x: 0,
		y: 0
	};
	self.laserCooldown = 180; // 3 seconds cooldown
	self.laserActive = false;
	self.laserTimer = 0;
	self.update = function () {
		if (self.laserActive) {
			self.laserTimer++;
			if (self.laserTimer >= self.laserCooldown) {
				self.laserActive = false;
				self.laserTimer = 0;
				self.laserGraphics.alpha = 0.4;
			}
		} else {
			// Aim laser at player
			if (player) {
				var dx = player.x - self.x;
				var dy = player.y - self.y;
				var angle = Math.atan2(dy, dx);
				self.laser.rotation = angle;
				self.laserDirection.x = Math.cos(angle);
				self.laserDirection.y = Math.sin(angle);
			}
			self.laserGraphics.alpha = 0;
			self.laserActive = true;
		}
	};
	self.shootLaser = function () {
		if (self.laserActive) {
			// Check if laser hits player
			if (player && self.intersects(player)) {
				// Player hit by laser
				LK.getSound('explosion').play();
				LK.effects.flashScreen(0xFF0000, 500);
				LK.showGameOver();
			}
		}
	};
	return self;
});
var Obstacle = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'hexagon';
	self.speed = 3 + Math.random() * 2;
	self.rotationSpeed = (Math.random() - 0.5) * 0.05;
	var shapeGraphics = self.attachAsset(self.type, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Special transformations per shape type
	if (self.type === 'triangle') {
		// Make it a triangle by scaling
		shapeGraphics.scaleY = 0.866; // sqrt(3)/2 to make equilateral triangle
	} else if (self.type === 'hexagon') {
		// Create hexagon effect using rotation and scale
		self.rotationSpeed = (Math.random() - 0.5) * 0.02; // Slower rotation for hexagons
	}
	self.update = function () {
		// Add trail effect (smaller shapes that follow the obstacle)
		if (!self.trail) {
			self.trail = [];
			self.trailMaxLength = 15;
			self.trailDelay = 2;
			self.trailCounter = 0;
		}
		self.trailCounter++;
		if (self.trailCounter >= self.trailDelay) {
			self.trailCounter = 0;
			// Add new trail point
			if (self.trail.length >= self.trailMaxLength) {
				// Recycle oldest trail point
				var oldestPoint = self.trail.shift();
				oldestPoint.x = self.x;
				oldestPoint.y = self.y;
				self.trail.push(oldestPoint);
			} else {
				// Create new trail point
				var trailPoint = LK.getAsset(self.type, {
					anchorX: 0.5,
					anchorY: 0.5,
					scaleX: 0.7,
					scaleY: 0.7,
					alpha: 0.7,
					tint: 0xFF0000 + (Math.floor(Math.random() * 256) << 8) + Math.floor(Math.random() * 256) // Add color variation
				});
				trailPoint.x = self.x;
				trailPoint.y = self.y;
				self.trail.push(trailPoint);
				game.addChild(trailPoint);
			}
			// Update all trail points opacity
			for (var i = 0; i < self.trail.length; i++) {
				var point = self.trail[i];
				point.alpha = 0.5 * (i / self.trail.length);
			}
		}
		// Move shape downward
		self.y += self.speed;
		// Rotate shape
		shapeGraphics.rotation += self.rotationSpeed;
		// Check if the player is close to the bomb
		if (self.type === 'Bomb' && player && !self.expanding) {
			if (Math.abs(self.x - player.x) < 100 && Math.abs(self.y - player.y) < 100) {
				self.expanding = true;
				tween(self, {
					scaleX: 2,
					scaleY: 2
				}, {
					duration: 1000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						self.markForRemoval = true;
					}
				});
			}
		}
		// Remove if off screen
		if (self.y > 2832) {
			self.markForRemoval = true;
			// Remove trail effect when obstacle hits the bottom
			for (var i = 0; i < self.trail.length; i++) {
				self.trail[i].destroy();
			}
			self.trail = [];
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Add trail effect (smaller circles that follow the player)
	self.trail = [];
	self.trailMaxLength = 5;
	self.trailDelay = 3;
	self.trailCounter = 0;
	self.createTrailPoint = function () {
		var trailPoint = LK.getAsset('player', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.5,
			scaleY: 0.5,
			alpha: 0.5
		});
		trailPoint.x = self.x;
		trailPoint.y = self.y;
		return trailPoint;
	};
	self.updateTrail = function () {
		self.trailCounter++;
		if (self.trailCounter >= self.trailDelay) {
			self.trailCounter = 0;
			// Add new trail point
			if (self.trail.length >= self.trailMaxLength) {
				// Recycle oldest trail point
				var oldestPoint = self.trail.shift();
				oldestPoint.x = self.x;
				oldestPoint.y = self.y;
				self.trail.push(oldestPoint);
			} else {
				// Create new trail point
				var newPoint = self.createTrailPoint();
				self.trail.push(newPoint);
				game.addChild(newPoint);
			}
			// Update all trail points opacity
			for (var i = 0; i < self.trail.length; i++) {
				var point = self.trail[i];
				point.alpha = 0.5 * (i / self.trail.length);
			}
		}
	};
	return self;
});
var TitleText = Container.expand(function () {
	var self = Container.call(this);
	self.title = new Text2('Shape Escape', {
		size: 100,
		fill: 0xFFFFFF
	});
	self.title.anchor.set(0.5, 0.5);
	self.addChild(self.title);
	self.subtitle = new Text2('Tap to Start', {
		size: 60,
		fill: 0xFFFFFF
	});
	self.subtitle.anchor.set(0.5, 0.5);
	self.subtitle.y = 100;
	self.addChild(self.subtitle);
	// Pulsing animation for the subtitle
	self.pulseAnimation = function () {
		tween(self.subtitle, {
			scaleX: 1.1,
			scaleY: 1.1
		}, {
			duration: 800,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(self.subtitle, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 800,
					easing: tween.easeInOut,
					onFinish: self.pulseAnimation
				});
			}
		});
	};
	self.pulseAnimation();
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000033
});
/**** 
* Game Code
****/ 
// Game state variables
var player;
var boss = null;
var obstacles = [];
var isGameStarted = false;
var titleScreen;
var gameTime = 0;
var spawnRate = 60; // Frames between obstacle spawns
var spawnCounter = 0;
var difficulty = 1;
// Setup GUI elements
var leaderboardTxt; // Define leaderboardTxt in the global scope
var scoreTxt = new Text2('0', {
	size: 70,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.y = 20;
LK.gui.top.addChild(scoreTxt);
var highScoreTxt = new Text2('Best: 0', {
	size: 40,
	fill: 0xFFFFFF
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.x = -20;
highScoreTxt.y = 20;
LK.gui.topRight.addChild(highScoreTxt);
// Create title screen
function setupTitleScreen() {
	titleScreen = new TitleText();
	titleScreen.x = 2048 / 2;
	titleScreen.y = 2732 / 2 - 200;
	game.addChild(titleScreen);
	// Load high score
	var highScore = storage.highScore || 0;
	highScoreTxt.setText('Best: ' + highScore);
	var leaderboardTxt = new Text2('Leaderboard: Player1 - ' + highScore, {
		size: 40,
		fill: 0xFFFFFF
	});
	leaderboardTxt.anchor.set(0.5, 0);
	leaderboardTxt.y = 100;
	game.addChild(leaderboardTxt);
}
// Start the game
function startGame() {
	// Remove title screen if it exists
	if (titleScreen) {
		titleScreen.destroy();
		titleScreen = null;
		if (leaderboardTxt) {
			leaderboardTxt.destroy();
			leaderboardTxt = null;
		}
	}
	// Reset game state
	isGameStarted = true;
	gameTime = 0;
	spawnCounter = 0;
	difficulty = 1;
	LK.setScore(0);
	scoreTxt.setText('0');
	// Clear any existing obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		obstacles[i].destroy();
	}
	obstacles = [];
	// Create player
	player = new Player();
	player.x = 2048 / 2;
	player.y = 2732 - 300;
	game.addChild(player);
	// Play dubstep music and loop it
	LK.playMusic('bgMusic', {
		loop: true
	});
}
// Spawn a new obstacle
function spawnObstacle() {
	// Choose a random shape type
	var types = ['circle', 'square', 'triangle', 'hexagon'];
	var type = types[Math.floor(Math.random() * types.length)];
	// Generate random size for the obstacle
	var randomSize = 50 + Math.random() * 100; // Random size between 50 and 150
	// Create obstacle with random size and color variation
	var obstacle = new Obstacle(type);
	var colorVariation = Math.floor(Math.random() * 256); // Random value between 0 and 255
	obstacle.tint = 0xFF0000 + (colorVariation << 8) + colorVariation; // Apply color variation
	obstacle.scaleX = randomSize / 100; // Scale based on random size
	obstacle.scaleY = randomSize / 100; // Scale based on random size
	// Position randomly along the top of the screen
	obstacle.x = Math.random() * 2048;
	obstacle.y = -100;
	game.addChild(obstacle);
	obstacles.push(obstacle);
	LK.getSound('spawn').play();
}
// Check for collisions between player and obstacles
function checkCollisions() {
	if (!player) {
		return;
	}
	for (var i = 0; i < obstacles.length; i++) {
		if (player.intersects(obstacles[i])) {
			// Collision detected - game over
			LK.getSound('collision').play();
			LK.getSound('explosion').play(); // Play explosion sound when player dies
			LK.effects.flashScreen(0xFF0000, 500);
			// Save high score
			var currentScore = LK.getScore();
			var highScore = storage.highScore || 0;
			if (currentScore > highScore) {
				storage.highScore = currentScore;
				highScoreTxt.setText('Best: ' + currentScore);
			}
			// Show game over screen
			LK.showGameOver();
			return;
		}
	}
}
// Update game difficulty
function updateDifficulty() {
	// Increase difficulty over time
	if (gameTime % 600 === 0 && gameTime > 0) {
		// Every 10 seconds
		difficulty += 0.2;
		if (spawnRate > 20) {
			spawnRate -= 5;
		}
	}
	// Increase obstacle speed every 5 points
	if (LK.getScore() % 5 === 0 && LK.getScore() > 0) {
		for (var i = 0; i < obstacles.length; i++) {
			obstacles[i].speed += 0.1;
		}
	}
}
// Handle input events
game.down = function (x, y, obj) {
	if (!isGameStarted) {
		startGame();
	}
};
game.move = function (x, y, obj) {
	if (isGameStarted && player) {
		// Move player to touch position but keep it within game bounds
		player.x = Math.max(50, Math.min(x, 2048 - 50));
		player.y = Math.max(50, Math.min(y, 2732 - 50));
	}
};
// Main game update loop
game.update = function () {
	if (!isGameStarted) {
		// Show title screen if not started
		if (!titleScreen) {
			setupTitleScreen();
		}
		return;
	}
	// Update game time
	gameTime++;
	// Update score (time-based)
	LK.setScore(Math.floor(gameTime / 60)); // Score is in seconds
	scoreTxt.setText(LK.getScore().toString());
	// Update player trail
	if (player) {
		player.updateTrail();
	}
	// Update and spawn obstacles
	spawnCounter++;
	if (spawnCounter >= spawnRate && obstacles.length < 30) {
		spawnCounter = 0;
		spawnObstacle();
	}
	// Make it rain obstacles every 30 points
	if (LK.getScore() % 30 === 0 && LK.getScore() > 0) {
		if (!obstacleRainStartTime) {
			obstacleRainStartTime = gameTime;
			// Show warning text
			var warningText = new Text2('Warning: Obstacle rain incoming!', {
				size: 80,
				fill: 0xFF0000
			});
			warningText.anchor.set(0.5, 0.5);
			warningText.x = 2048 / 2;
			warningText.y = 2732 / 2;
			game.addChild(warningText);
			// Remove warning text after 5 seconds
			LK.setTimeout(function () {
				warningText.destroy();
			}, 5000);
		}
		if (gameTime - obstacleRainStartTime > 300 && gameTime - obstacleRainStartTime <= 600) {
			// 5 seconds at 60 FPS
			for (var i = 0; i < 10; i++) {
				// Spawn 10 obstacles
				var obstacle = new Obstacle();
				obstacle.x = Math.random() * 2048;
				obstacle.y = -100;
				obstacle.speed = 20; // Set speed to 20
				game.addChild(obstacle);
				obstacles.push(obstacle);
			}
		} else if (gameTime - obstacleRainStartTime > 600 && gameTime - obstacleRainStartTime <= 1200) {
			// Additional 10 seconds at 60 FPS
			for (var i = 0; i < 5; i++) {
				// Spawn 5 obstacles
				var obstacle = new Obstacle();
				obstacle.x = Math.random() * 2048;
				obstacle.y = -100;
				obstacle.speed = 15; // Set speed to 15
				game.addChild(obstacle);
				obstacles.push(obstacle);
			}
		} else if (gameTime - obstacleRainStartTime > 600 && gameTime - obstacleRainStartTime <= 660) {
			// Display 'Survived!' text for 1 second
			var survivedText = new Text2('Survived!', {
				size: 80,
				fill: 0x00FF00
			});
			survivedText.anchor.set(0.5, 0.5);
			survivedText.x = 2048 / 2;
			survivedText.y = 2732 / 2;
			game.addChild(survivedText);
			LK.setTimeout(function () {
				survivedText.destroy();
			}, 1000);
		}
	} else {
		obstacleRainStartTime = null;
	}
	// Spawn boss at 60 points
	if (LK.getScore() === 60 && !boss) {
		boss = new Boss();
		boss.x = 2048 / 2;
		boss.y = 200;
		game.addChild(boss);
		LK.getSound('spawn').play();
	}
	// Update boss
	if (boss) {
		boss.update();
		boss.shootLaser();
		if (gameTime % 1200 === 0) {
			// Boss lasts for 20 seconds
			boss.destroy();
			boss = null;
		}
	}
	// Update all obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		obstacles[i].update();
		// Remove obstacles marked for removal
		if (obstacles[i].markForRemoval) {
			obstacles[i].destroy();
			obstacles.splice(i, 1);
		}
	}
	// Check for collisions
	checkCollisions();
	// Update difficulty
	updateDifficulty();
}; ===================================================================
--- original.js
+++ change.js
@@ -84,9 +84,9 @@
 	self.update = function () {
 		// Add trail effect (smaller shapes that follow the obstacle)
 		if (!self.trail) {
 			self.trail = [];
-			self.trailMaxLength = 10;
+			self.trailMaxLength = 15;
 			self.trailDelay = 2;
 			self.trailCounter = 0;
 		}
 		self.trailCounter++;