Code edit (6 edits merged)
Please save this source code
Code edit (5 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: explosionGrahins is not defined' in this line: 'explosionGrahins.alpha = 0.5;' Line Number: 224
Code edit (2 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: gameOverText is not defined' in this line: 'self.addChild(gameOverText);' Line Number: 205
Code edit (2 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: gameOverText is not defined' in this line: 'gameOverText.anchor.set(0.5, 0);' Line Number: 204
Code edit (1 edits merged)
Please save this source code
User prompt
Fix Bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'length')' in this line: 'for (var j = enemyShips.length - 1; j >= 0; j--) {' Line Number: 259
User prompt
when an enemy is destroyed, create an explosion effect using 30 instances of Explosion that radiate outwards
/**** 
* Classes
****/
var Starfield = Container.expand(function () {
	var self = Container.call(this);
	self.stars = [];
	var numberOfStars = 300;
	for (var i = 0; i < numberOfStars; i++) {
		var star = LK.getAsset('star', 'Star');
		star.anchor.set(0.5, 0.5);
		star.x = Math.random() * game.width;
		star.y = Math.random() * game.height;
		star.speed = Math.random() * 1 + 0.1;
		star.alpha = Math.random() * 0.2 + 0.1;
		star.tint = Math.random() * 0xFFFFFF;
		self.addChild(star);
		self.stars.push(star);
	}
	self.moveStars = function () {
		for (var i = 0; i < self.stars.length; i++) {
			var star = self.stars[i];
			star.y += star.speed;
			if (star.y > game.height) {
				star.y = -30;
			}
		}
	};
});
// Hero ship class
var HeroShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.createAsset('heroShip', 'Cute smiley ship', 0.5, 0.5);
	self.speed = 5;
	self.isShooting = false;
	self.shootingInterval = 30;
	self._shootingCounter = 0;
	self.shoot = function () {
		var bullet = new HeroBullet();
		bullet.x = self.x;
		bullet.y = self.y - self.height / 2;
		game.addChild(bullet);
		return bullet;
	};
});
// Hero bullet class
var HeroBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('heroBullet', 'Heart bullet', 0.5, 1);
	self.speed = -10;
	self.move = function () {
		self.y += self.speed;
	};
});
// Enemy ship class
var EnemyShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.createAsset('enemyShip', 'Evil smiley', 0.5, 0.5);
	self.speed = 2;
	self.hitCount = 0;
	self.maxHits = 3;
	self.move = function () {
		self.y += self.speed;
	};
	self.isDestroyed = function () {
		return self.hitCount >= self.maxHits;
	};
});
// Enemy ship class
var EnemyBossShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.createAsset('enemyBossShip', 'Evil Boss smiley', 0.5, 0.5);
	// Create a red health bar
	var healthBar = self.createAsset('healthBar', 'Health Bar', 0, 0.5);
	healthBar.tint = 0xFF0000;
	healthBar.width = shipGraphics.width;
	healthBar.height = 30;
	healthBar.y = -180;
	healthBar.x = -shipGraphics.width / 2;
	self.updateHealthBar = function () {
		var healthPercentage = (self.maxHits - self.hitCount) / self.maxHits;
		healthBar.width = shipGraphics.width * healthPercentage;
	};
	self.tint = 0xFFFFFF;
	self.speed = 6;
	self.horizontalSpeed = 3;
	self.hitCount = 0;
	self.maxHits = 10;
	self.targetY = game.height * (1 / 2);
	self.shootingInterval = 60;
	self._shootingCounter = 0;
	self.canShoot = false;
	self.enemyBossShipBullets = [];
	self.shoot = function (playerX, playerY) {
		if (self.canShoot) {
			var bullet = new EnemyBossBullet();
			bullet.tint = self.tint;
			bullet.x = self.x + 100;
			bullet.y = self.y;
			bullet.initialX = playerX;
			bullet.initialY = playerY;
			self.enemyBossShipBullets.push(bullet);
			game.addChild(bullet);
		}
	};
	self.move = function () {
		if (self.y < self.targetY) {
			self.y += self.speed;
		} else if (self.speed !== 0) {
			self.speed = 0;
			self.canShoot = true;
		}
		if (!self.horizontalMovementInitialized) {
			self.horizontalMovementInitialized = true;
			self.movingRight = true;
		}
		if (self.movingRight) {
			self.x += self.horizontalSpeed;
			if (self.x > game.width - self.width / 2) {
				self.movingRight = false;
			}
		} else {
			self.x -= self.horizontalSpeed;
			if (self.x < self.width / 2) {
				self.movingRight = true;
			}
		}
		self.updateHealthBar();
		shipGraphics.tint = self.tint;
	};
	self.isDestroyed = function () {
		return self.hitCount >= self.maxHits;
	};
});
// Enemy boss bullet class
var EnemyBossBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('enemyBossBullet', 'Evil Boss Bullet', 0.5, 1);
	self.tint = 0xFFFFFF;
	self.speed = 5;
	self.initialX = 0;
	self.initialY = 0;
	self.move = function () {
		var angle = Math.atan2(self.initialY - self.y, self.initialX - self.x);
		self.x += Math.cos(angle) * self.speed;
		// continue moving downwards
		if (self.y <= self.initialY) {
			self.y += Math.sin(angle) * self.speed;
		} else {
			self.y += self.speed;
		}
		// Continue moving off the screen
		if (self.x < -self.width || self.x > game.width + self.width || self.y < -self.height || self.y > game.height + self.height) {
			self.destroy();
		}
		bulletGraphics.tint = self.tint;
	};
});
var ScoreDisplay = Container.expand(function () {
	var self = Container.call(this);
	var scoreText = new Text2('Score: 0', {
		size: 100,
		fill: "#FF6900"
	});
	scoreText.anchor.set(0.5, 0);
	self.addChild(scoreText);
	self.updateScore = function (newScore) {
		scoreText.setText('Score: ' + newScore.toString());
	};
});
var LevelDisplay = Container.expand(function () {
	var self = Container.call(this);
	var levelText = new Text2('Level: 1', {
		size: 100,
		fill: "#FF6900"
	});
	levelText.anchor.set(0.5, 0);
	self.addChild(levelText);
	self.updateLevel = function (newLevel) {
		levelText.setText('Level: ' + newLevel.toString());
	};
});
var StartButton = Container.expand(function () {
	var self = Container.call(this);
	var buttonGraphics = self.createAsset('startButton', 'Start Game Button', 0.5, 0.5);
	self.interactive = true;
	self.buttonMode = true;
	self.on('down', function () {
		self.emit('startGame');
		randomSpawnEnemyShip(); // Start the spawning process once game starts
	});
});
var HelpGuide = Container.expand(function () {
	var self = Container.call(this);
	var guideGraphics = self.createAsset('helpGuide', 'Help Guide', 0.5, 0);
	self.addChild(guideGraphics);
});
var GameOverDisplay = Container.expand(function () {
	var self = Container.call(this);
	var finalScoreText = new Text2('Final Score: 0', {
		size: 120,
		fill: "#FFFFFF"
	});
	finalScoreText.anchor.set(0.5, 0);
	var gameOverText = new Text2('Game Over', {
		size: 120,
		fill: "#FFFFFF"
	});
	gameOverText.anchor.set(0.5, 0);
	gameOverText.x = game.width / 2;
	gameOverText.y = game.height / 2 - 600;
	self.addChild(gameOverText);
	self.addChild(finalScoreText);
	finalScoreText.x = game.width / 2;
	finalScoreText.y = game.height / 2 - 500;
	self.updateFinalScore = function (score) {
		finalScoreText.setText('Final Score: ' + score.toString());
	};
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphics = self.createAsset('explosion', 'Explosion effect', 0.5, 0.5);
	explosionGraphics.tint = 0xD0021B;
	explosionGraphics.alpha = 0.5;
	var angle = Math.random() * Math.PI * 2;
	var speed = Math.random() * 5 + 2;
	self.move = function () {
		this.x += Math.cos(angle) * speed;
		this.y += Math.sin(angle) * speed;
	};
});
/**** 
* Initialize Game
****/
// Initialize starfield
var game = new LK.Game({
	backgroundColor: 0xe5b4b3,
	bossSpawned: false
	// Flag to track if boss has been spawned
});
/**** 
* Game Code
****/
// Initialize starfield
var starfield = game.addChild(new Starfield());
starfield.x = 0;
starfield.y = 0; // Start off screen
// Initialize important asset arrays and score tracking
var heroBullets = [];
var enemyShips = [];
var enemyBossShips = [];
var explosions = [];
var currentLevel = 1;
var smallEnemyPoints = 100;
var bossEnemyPoints = 400;
var currentScore = 0;
var highScore = 0;
var scoreDisplay = game.addChild(new ScoreDisplay());
scoreDisplay.x = 300;
scoreDisplay.y = 75;
// Initialize and position level display
var levelDisplay = game.addChild(new LevelDisplay());
levelDisplay.x = game.width - 300;
levelDisplay.y = 75;
// Create hero ship
var heroShip = game.addChild(new HeroShip());
heroShip.x = game.width / 2;
heroShip.y = game.height - 450;
// Create enemies
function spawnEnemyShip(speed) {
	var enemyShip = new EnemyShip();
	enemyShip.speed = speed || Math.random() * 3 + 1; // Default speed if not provided
	enemyShip.x = Math.random() * (game.width - enemyShip.width) + enemyShip.width / 2;
	enemyShip.y = -enemyShip.height / 2;
	enemyShip.maxHits = enemyShip.maxHits + currentLevel;
	game.addChild(enemyShip);
	enemyShips.push(enemyShip);
}
// Function to randomly spawn enemy ships or the enemy boss
function randomSpawnEnemyShip() {
	var minSpawnDelay = 1000; // 1 second
	var maxSpawnDelay = 3000; // 3 seconds
	var spawnDelay = Math.random() * (maxSpawnDelay - minSpawnDelay) + minSpawnDelay;
	LK.setTimeout(function () {
		if (currentScore >= (smallEnemyPoints * 1 + bossEnemyPoints) * currentLevel && !game.bossSpawned) {
			for (var n = 0; n < currentLevel; n++) {
				if (n > 3) {
					break;
				}
				game.bossSpawned = true;
				var enemyBossShip = new EnemyBossShip();
				enemyBossShip.tint = getRandomHexColor();
				enemyBossShip.x = game.width / 2;
				enemyBossShip.y = -enemyBossShip.height / (2 * n + 1);
				enemyBossShip.targetY = enemyBossShip.targetY - enemyBossShip.height * n - 64;
				enemyBossShip.horizontalSpeed = enemyBossShip.horizontalSpeed * ((currentLevel - n) / 5 + 1);
				enemyBossShip.maxHits = enemyBossShip.maxHits + 2 * currentLevel;
				game.addChild(enemyBossShip);
				enemyBossShips.push(enemyBossShip);
			}
		} else if (!game.bossSpawned) {
			spawnEnemyShip();
		}
		randomSpawnEnemyShip(); // Schedule next spawn
	}, spawnDelay);
}
// Game tick event
LK.on('tick', function () {
	// Move the starfield
	starfield.moveStars();
	// Move hero bullets
	for (var i = heroBullets.length - 1; i >= 0; i--) {
		var bullet = heroBullets[i];
		bullet.move();
		if (bullet.y < -bullet.height) {
			bullet.destroy();
			heroBullets.splice(i, 1);
		} else {
			// Check collision with enemies
			for (var j = enemyShips.length - 1; j >= 0; j--) {
				if (bullet.intersects(enemyShips[j])) {
					bullet.destroy();
					enemyShips[j].hitCount++;
					heroBullets.splice(i, 1);
					if (enemyShips[j].isDestroyed()) {
						currentScore += smallEnemyPoints;
						createExplosionAt(enemyShips[j].x, enemyShips[j].y);
						enemyShips[j].destroy();
						enemyShips.splice(j, 1);
						scoreDisplay.updateScore(currentScore);
					}
					break;
				}
			}
			//Enemy Boss collision
			for (var j = enemyBossShips.length - 1; j >= 0; j--) {
				if (bullet.intersects(enemyBossShips[j])) {
					bullet.destroy();
					heroBullets.splice(i, 1);
					enemyBossShips[j].hitCount++;
					if (enemyBossShips[j].isDestroyed()) {
						for (var k = enemyBossShips[j].enemyBossShipBullets.length - 1; k >= 0; k--) {
							var enemyBullet = enemyBossShips[j].enemyBossShipBullets[k];
							enemyBullet.destroy();
						}
						currentScore += bossEnemyPoints;
						scoreDisplay.updateScore(currentScore);
						enemyBossShips[j].destroy();
						enemyBossShips.splice(j, 1);
						if (enemyBossShips.length <= 0) {
							currentLevel += 1;
							levelDisplay.updateLevel(currentLevel);
							game.bossSpawned = false;
						}
					}
				}
			}
		}
	}
	// Move enemy ships
	for (var i = enemyShips.length - 1; i >= 0; i--) {
		var enemy = enemyShips[i];
		enemy.move();
		if (enemy.y > game.height + enemy.height / 2) {
			enemy.destroy();
			enemyShips.splice(i, 1);
		}
		if (heroShip.intersects(enemy)) {
			LK.effects.flashScreen(0xff0000, 1000);
			var gameOverDisplay = game.addChild(new GameOverDisplay());
			gameOverDisplay.updateFinalScore(currentScore);
			LK.showGameOver();
		}
	}
	// Move enemy Boss ships
	for (var i = enemyBossShips.length - 1; i >= 0; i--) {
		var enemy = enemyBossShips[i];
		enemy.move();
		if (enemy._shootingCounter % enemy.shootingInterval == 0) {
			enemy.shoot(heroShip.x, heroShip.y);
			enemy._shootingCounter = 0;
		}
		enemy._shootingCounter += 1;
		if (enemy.y > game.height + enemy.height / 2) {
			enemy.destroy();
			enemyBossShips.splice(i, 1);
		}
		for (var j = enemyBossShips[i].enemyBossShipBullets.length - 1; j >= 0; j--) {
			var enemyBullet = enemyBossShips[i].enemyBossShipBullets[j];
			enemyBullet.move();
			if (heroShip.intersects(enemyBullet)) {
				LK.effects.flashScreen(0xff0000, 1000);
				var gameOverDisplay = game.addChild(new GameOverDisplay());
				gameOverDisplay.updateFinalScore(currentScore);
				LK.showGameOver();
			}
		}
	}
	// Shoot bullets
	if (heroShip._shootingCounter % heroShip.shootingInterval == 0) {
		if (heroShip.isShooting) {
			heroBullets.push(heroShip.shoot());
			heroShip._shootingCounter = 0;
		}
	}
	heroShip._shootingCounter += 1;
	for (var i = explosions.length - 1; i >= 0; i--) {
		explosions[i].move();
	}
});
// randomSpawnEnemyShip(); // Start the spawning process
var helpguide = game.addChild(new HelpGuide());
helpguide.x = game.width / 2;
helpguide.y = game.height - 300;
helpguide.alpha = 0.3;
// Render the start button on top
var startButton = game.addChild(new StartButton());
startButton.x = game.width / 2;
startButton.y = game.height / 2;
startButton.on('startGame', function () {
	startButton.destroy();
	instructionText.destroy();
});
function createExplosionAt(x, y) {
	for (var i = 0; i < 30; i++) {
		var explosion = new Explosion();
		explosion.x = x;
		explosion.y = y;
		explosions.push(explosion);
		game.addChild(explosion);
	}
}
// Add instructional text to the screen
var instructionText = new Text2('Tap! Tap! Tap to shoot and destroy the evil smiley', {
	size: 70,
	fill: "#eb144c",
	align: 'center',
	fontWeight: 'bold'
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = game.width / 2;
instructionText.y = game.height / 2 - 400;
game.addChild(instructionText);
// Touch controls to make heroShip follow the pointer
game.on('move', function (obj) {
	var touchPos = obj.event.getLocalPosition(game);
	heroShip.x = touchPos.x;
});
game.on('down', function (obj) {
	heroShip._shootingCounter = 0;
	heroShip.isShooting = true;
});
game.on('up', function (obj) {
	heroShip.isShooting = false;
});
function getRandomHexColor() {
	var hexColors = [0xFF6900, 0xFCB900, 0xF78DA7, 0x8ED1FC, 0xABB8C3, 0x68BC00, 0xFCDC00, 0xAEA1FF];
	return hexColors[Math.floor(Math.random() * hexColors.length)];
} ===================================================================
--- original.js
+++ change.js
:quality(85)/https://cdn.frvr.ai/659d419089c637dfdd24adfc.png%3F3) 
 a cute cool looking emoji face. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/659d41dd89c637dfdd24ae0b.png%3F3) 
 a cute looking heart. bright red.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/659d423f89c637dfdd24ae16.png%3F3) 
 an evil looking emoji. purple and blue colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/659d4b7a5950620c32b48724.png%3F3) 
 a shiny blue cute star. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/659da851f5c79782ea2784fe.png%3F3) 
 A start button. White on Red.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/659ddc10ce0f9b13d5dc7854.png%3F3) 
 a grey touchpad. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/659deb44ce0f9b13d5dc789c.png%3F3) 
 a bright yellow shiny cute star. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.