/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 30; self.maxHealth = 30; self.phase = 1; self.attackCooldown = 0; self.moveDir = 1; self.speed = 3; self.pointValue = 2000; self.takeDamage = function (damage) { self.health -= damage; // Update health bar updateBossHealthBar(); if (self.health <= 0) { // Add score LK.setScore(LK.getScore() + self.pointValue); // Create multiple explosions for (var i = 0; i < 5; i++) { var offsetX = (Math.random() - 0.5) * 200; var offsetY = (Math.random() - 0.5) * 150; createExplosion(self.x + offsetX, self.y + offsetY); // Stagger the explosion sounds LK.setTimeout(function () { LK.getSound('explosion').play(); }, i * 300); } // Level complete LK.showYouWin(); return true; } // Change phase at 50% health if (self.health < self.maxHealth / 2 && self.phase === 1) { self.phase = 2; self.speed = 5; LK.effects.flashObject(self, 0xffff00, 500); } // Flash red when hit LK.effects.flashObject(self, 0xff0000, 200); return false; }; self.update = function () { // Side to side movement self.x += self.speed * self.moveDir; if (self.x > 1800 || self.x < 248) { self.moveDir *= -1; } // Attack patterns self.attackCooldown--; if (self.attackCooldown <= 0) { if (self.phase === 1) { // Phase 1: Single line of bullets for (var i = -2; i <= 2; i++) { fireBullet(self.x + i * 50, self.y + 50, "enemy"); } self.attackCooldown = 60; } else { // Phase 2: More complex patterns if (Math.random() < 0.5) { // Spiral pattern for (var i = 0; i < 8; i++) { var angle = i / 8 * Math.PI * 2; var bulletX = self.x + Math.cos(angle) * 100; var bulletY = self.y + Math.sin(angle) * 100; fireBullet(bulletX, bulletY, "enemy"); } } else { // Cross pattern for (var i = -2; i <= 2; i++) { fireBullet(self.x + i * 60, self.y + 50, "enemy"); fireBullet(self.x, self.y + 50 + i * 60, "enemy"); } } self.attackCooldown = 45; } LK.getSound('enemyShoot').play(); } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.speed = 2; self.fireChance = 0.005; // Chance to fire each frame self.movementPattern = "descent"; // Default pattern self.pointValue = 100; self.moveDir = 1; self.initY = 0; self.amplitude = 100; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { // Add score LK.setScore(LK.getScore() + self.pointValue); // Create explosion createExplosion(self.x, self.y); LK.getSound('explosion').play(); // Chance to drop powerup if (Math.random() < 0.2) { createPowerUp(self.x, self.y); } // Remove enemy return true; } // Flash red when hit LK.effects.flashObject(self, 0xff0000, 200); return false; }; self.update = function () { // Different movement patterns if (self.movementPattern === "descent") { self.y += self.speed; } else if (self.movementPattern === "zigzag") { self.x += self.speed * self.moveDir; self.y += self.speed * 0.5; // Change direction at edges if (self.x > 1900 || self.x < 148) { self.moveDir *= -1; } } else if (self.movementPattern === "sine") { self.y += self.speed; self.x = self.initX + Math.sin((self.y - self.initY) * 0.02) * self.amplitude; } // Random chance to fire if (Math.random() < self.fireChance) { fireBullet(self.x, self.y, "enemy"); } }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.y += self.speed; }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); self.lifespan = 20; self.update = function () { self.lifespan--; // Grow and fade out explosionGraphics.alpha = self.lifespan / 20; explosionGraphics.scaleX = (20 - self.lifespan) / 10; explosionGraphics.scaleY = (20 - self.lifespan) / 10; if (self.lifespan <= 0) { self.destroy(); return true; } return false; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.fireRate = 10; self.lastFired = 0; self.health = 3; self.shield = false; self.shieldGraphics = null; self.invulnerable = false; self.activateShield = function () { if (!self.shield) { self.shield = true; self.shieldGraphics = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.shieldGraphics.blendMode = "screen"; // This line has no effect, but kept for demonstration // Shield expires after 10 seconds LK.setTimeout(function () { if (self.shieldGraphics) { self.shield = false; self.removeChild(self.shieldGraphics); self.shieldGraphics = null; } }, 10000); } }; self.takeDamage = function () { if (!self.invulnerable) { if (self.shield) { self.shield = false; if (self.shieldGraphics) { self.removeChild(self.shieldGraphics); self.shieldGraphics = null; } } else { self.health--; // Make player briefly invulnerable after taking damage self.invulnerable = true; // Flash effect var flashCount = 0; var flashInterval = LK.setInterval(function () { shipGraphics.alpha = shipGraphics.alpha === 1 ? 0.3 : 1; flashCount++; if (flashCount >= 10) { LK.clearInterval(flashInterval); shipGraphics.alpha = 1; self.invulnerable = false; } }, 150); if (self.health <= 0) { createExplosion(self.x, self.y); LK.getSound('explosion').play(); LK.showGameOver(); } } } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.damage = 1; self.update = function () { self.y += self.speed; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.type = "shield"; // Default self.speed = 3; // Visual effect - pulsate tween(powerUpGraphics, { alpha: 0.6 }, { duration: 500, easing: tween.sinOut, onFinish: function onFinish() { tween(powerUpGraphics, { alpha: 1 }, { duration: 500, easing: tween.sinIn, onFinish: function onFinish() { // Continuous pulsating if (self.parent) { tween(powerUpGraphics, { alpha: 0.6 }, { duration: 500, easing: tween.sinOut, onFinish: arguments.callee }); } } }); } }); self.update = function () { self.y += self.speed; }; self.collect = function () { LK.getSound('powerUp').play(); if (self.type === "shield") { player.activateShield(); } else if (self.type === "fireRate") { player.fireRate = 5; // Revert to normal fire rate after 10 seconds LK.setTimeout(function () { player.fireRate = 10; }, 10000); } else if (self.type === "health") { player.health = Math.min(player.health + 1, 5); updateLives(); } return true; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Add background image to the game var background = LK.getAsset('Background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 2048 / 100, // Scale to fit the screen width scaleY: 2732 / 100 // Scale to fit the screen height }); game.addChild(background); var player; var playerBullets = []; var enemyBullets = []; var enemies = []; var powerUps = []; var explosions = []; var gameStarted = false; var boss = null; var waveNumber = 1; var enemiesPerWave = 10; var waveDelay = 0; var dragNode = null; var bossHealthBar; var bossHealthBarBg; var lives = []; // Setup score display var scoreTxt = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -scoreTxt.width - 20; scoreTxt.y = 20; // High score display var highScoreTxt = new Text2('High Score: ' + storage.highScore, { size: 40, fill: 0xBBBBFF }); highScoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(highScoreTxt); highScoreTxt.x = -highScoreTxt.width - 20; highScoreTxt.y = 80; // Wave indicator var waveTxt = new Text2('Wave: 1', { size: 50, fill: 0xFFFFFF }); waveTxt.anchor.set(0, 0); LK.gui.top.addChild(waveTxt); waveTxt.y = 20; // Create player function createPlayer() { player = new Player(); player.x = 2048 / 2; player.y = 2732 - 200; game.addChild(player); // Setup life display updateLives(); } // Life display function updateLives() { // Clear existing lives for (var i = 0; i < lives.length; i++) { LK.gui.topLeft.removeChild(lives[i]); } lives = []; // Create life indicators for (var i = 0; i < player.health; i++) { var life = LK.getAsset('player', { scaleX: 0.4, scaleY: 0.4, anchorX: 0, anchorY: 0, x: 120 + i * 60, y: 20 }); lives.push(life); LK.gui.topLeft.addChild(life); } } // Create boss health bar function createBossHealthBar() { bossHealthBarBg = LK.getAsset('playerBullet', { width: 1000, height: 30, anchorX: 0.5, anchorY: 0, tint: 0x333333 }); bossHealthBarBg.x = 0; bossHealthBarBg.y = 100; bossHealthBar = LK.getAsset('playerBullet', { width: 1000, height: 30, anchorX: 0, anchorY: 0, tint: 0xff0000 }); bossHealthBar.x = -500; bossHealthBar.y = 100; LK.gui.top.addChild(bossHealthBarBg); LK.gui.top.addChild(bossHealthBar); } function updateBossHealthBar() { if (boss && bossHealthBar) { var percentage = boss.health / boss.maxHealth; bossHealthBar.width = 1000 * percentage; } } function removeBossHealthBar() { if (bossHealthBarBg) { LK.gui.top.removeChild(bossHealthBarBg); bossHealthBarBg = null; } if (bossHealthBar) { LK.gui.top.removeChild(bossHealthBar); bossHealthBar = null; } } // Fire a bullet function fireBullet(x, y, type) { var bullet; if (type === "player") { bullet = new PlayerBullet(); playerBullets.push(bullet); LK.getSound('playerShoot').play(); } else { bullet = new EnemyBullet(); enemyBullets.push(bullet); } bullet.x = x; bullet.y = y; game.addChild(bullet); } // Create an explosion effect function createExplosion(x, y) { var explosion = new Explosion(); explosion.x = x; explosion.y = y; game.addChild(explosion); explosions.push(explosion); } // Create a power-up function createPowerUp(x, y) { var powerUp = new PowerUp(); powerUp.x = x; powerUp.y = y; // Randomly select power-up type var types = ["shield", "fireRate", "health"]; var typeIndex = Math.floor(Math.random() * types.length); powerUp.type = types[typeIndex]; // Set color based on type var powerUpGraphics = powerUp.getChildAt(0); if (powerUp.type === "shield") { powerUpGraphics.tint = 0x3498db; // Blue } else if (powerUp.type === "fireRate") { powerUpGraphics.tint = 0xf39c12; // Orange } else if (powerUp.type === "health") { powerUpGraphics.tint = 0xe74c3c; // Red } game.addChild(powerUp); powerUps.push(powerUp); } // Spawn an enemy function spawnEnemy(x, y, pattern) { var enemy = new Enemy(); enemy.x = x; enemy.y = y; enemy.movementPattern = pattern; if (pattern === "sine") { enemy.initX = x; enemy.initY = y; } // Adjust difficulty based on wave enemy.health = 1 + Math.floor(waveNumber / 3); enemy.speed = 1 + waveNumber * 0.2; game.addChild(enemy); enemies.push(enemy); } // Spawn a boss function spawnBoss() { boss = new Boss(); boss.x = 2048 / 2; boss.y = 300; // Adjust boss difficulty based on wave boss.health = 20 + waveNumber * 5; boss.maxHealth = boss.health; game.addChild(boss); // Create boss health bar createBossHealthBar(); // Play boss music LK.getSound('bossFight').play(); } // Spawn a wave of enemies function spawnWave() { // Every 3 waves, spawn a boss if (waveNumber % 3 === 0) { spawnBoss(); return; } // Regular enemy wave var numEnemies = enemiesPerWave + waveNumber * 2; var patterns = ["descent", "zigzag", "sine"]; for (var i = 0; i < numEnemies; i++) { var x = 200 + Math.random() * (2048 - 400); var y = -100 - i * 80; var pattern = patterns[Math.floor(Math.random() * patterns.length)]; spawnEnemy(x, y, pattern); } } // Start a new wave function startNewWave() { waveNumber++; waveTxt.setText('Wave: ' + waveNumber); spawnWave(); } // Initialize game function initGame() { // Initialize start message startText = new Text2('Tap to Start', { size: 100, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); LK.gui.center.addChild(startText); playerBullets = []; enemyBullets = []; enemies = []; powerUps = []; explosions = []; gameStarted = true; if (startText && startText.parent) { LK.gui.center.removeChild(startText); } startText = null; waveNumber = 0; boss = null; // Reset score LK.setScore(0); scoreTxt.setText('Score: 0'); highScoreTxt.setText('High Score: ' + storage.highScore); // Create player createPlayer(); // Start first wave startNewWave(); // Play game music LK.playMusic('gameMusic'); } // Handle movement of player function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; // Limit player movement to bottom third of screen dragNode.y = Math.max(y, 2732 / 3 * 2); // Keep player on screen dragNode.x = Math.max(dragNode.x, 100); dragNode.x = Math.min(dragNode.x, 2048 - 100); dragNode.y = Math.min(dragNode.y, 2732 - 100); } } // Event handlers game.move = handleMove; game.down = function (x, y, obj) { if (!gameStarted) { initGame(); if (startText && startText.parent) { LK.gui.center.removeChild(startText); } startText = null; } else if (player) { dragNode = player; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Game update loop game.update = function () { if (!gameStarted) { return; } // Update score display scoreTxt.setText('Score: ' + LK.getScore()); // Player shooting if (player && LK.ticks % player.fireRate === 0) { fireBullet(player.x, player.y - 50, "player"); } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; // Remove bullets that go off screen if (bullet.y < -50) { bullet.destroy(); playerBullets.splice(i, 1); continue; } // Check for collision with enemies var hitEnemy = false; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { // Apply damage to enemy if (enemy.takeDamage(bullet.damage)) { enemy.destroy(); enemies.splice(j, 1); } // Remove bullet bullet.destroy(); playerBullets.splice(i, 1); hitEnemy = true; break; } } // Check for collision with boss if (!hitEnemy && boss && bullet.intersects(boss)) { boss.takeDamage(bullet.damage); // Remove bullet bullet.destroy(); playerBullets.splice(i, 1); // Check if boss is defeated if (boss.health <= 0) { boss.destroy(); boss = null; removeBossHealthBar(); waveDelay = 180; // Delay before next wave } } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; // Remove bullets that go off screen if (bullet.y > 2732 + 50) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check for collision with player if (player && bullet.intersects(player)) { player.takeDamage(); updateLives(); // Remove bullet bullet.destroy(); enemyBullets.splice(i, 1); } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; // Remove enemies that go off screen if (enemy.y > 2732 + 100) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check for collision with player if (player && enemy.intersects(player)) { player.takeDamage(); updateLives(); // Remove enemy createExplosion(enemy.x, enemy.y); LK.getSound('explosion').play(); enemy.destroy(); enemies.splice(i, 1); } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; // Remove power-ups that go off screen if (powerUp.y > 2732 + 50) { powerUp.destroy(); powerUps.splice(i, 1); continue; } // Check for collision with player if (player && powerUp.intersects(player)) { if (powerUp.collect()) { powerUp.destroy(); powerUps.splice(i, 1); } } } // Update explosions for (var i = explosions.length - 1; i >= 0; i--) { var explosion = explosions[i]; if (explosion.update()) { explosions.splice(i, 1); } } // Check if all enemies are defeated if (enemies.length === 0 && !boss) { if (waveDelay > 0) { waveDelay--; } else { startNewWave(); } } // Update high score if (LK.getScore() > storage.highScore) { storage.highScore = LK.getScore(); highScoreTxt.setText('High Score: ' + storage.highScore); } }; // Initialize game with a start message var startText = null; var startText = new Text2('Tap to Start', { size: 100, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); LK.gui.center.addChild(startText); // Remove start text when game starts LK.on('tick', function () { if (gameStarted && startText && startText.parent) { LK.gui.center.removeChild(startText); } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 30;
self.maxHealth = 30;
self.phase = 1;
self.attackCooldown = 0;
self.moveDir = 1;
self.speed = 3;
self.pointValue = 2000;
self.takeDamage = function (damage) {
self.health -= damage;
// Update health bar
updateBossHealthBar();
if (self.health <= 0) {
// Add score
LK.setScore(LK.getScore() + self.pointValue);
// Create multiple explosions
for (var i = 0; i < 5; i++) {
var offsetX = (Math.random() - 0.5) * 200;
var offsetY = (Math.random() - 0.5) * 150;
createExplosion(self.x + offsetX, self.y + offsetY);
// Stagger the explosion sounds
LK.setTimeout(function () {
LK.getSound('explosion').play();
}, i * 300);
}
// Level complete
LK.showYouWin();
return true;
}
// Change phase at 50% health
if (self.health < self.maxHealth / 2 && self.phase === 1) {
self.phase = 2;
self.speed = 5;
LK.effects.flashObject(self, 0xffff00, 500);
}
// Flash red when hit
LK.effects.flashObject(self, 0xff0000, 200);
return false;
};
self.update = function () {
// Side to side movement
self.x += self.speed * self.moveDir;
if (self.x > 1800 || self.x < 248) {
self.moveDir *= -1;
}
// Attack patterns
self.attackCooldown--;
if (self.attackCooldown <= 0) {
if (self.phase === 1) {
// Phase 1: Single line of bullets
for (var i = -2; i <= 2; i++) {
fireBullet(self.x + i * 50, self.y + 50, "enemy");
}
self.attackCooldown = 60;
} else {
// Phase 2: More complex patterns
if (Math.random() < 0.5) {
// Spiral pattern
for (var i = 0; i < 8; i++) {
var angle = i / 8 * Math.PI * 2;
var bulletX = self.x + Math.cos(angle) * 100;
var bulletY = self.y + Math.sin(angle) * 100;
fireBullet(bulletX, bulletY, "enemy");
}
} else {
// Cross pattern
for (var i = -2; i <= 2; i++) {
fireBullet(self.x + i * 60, self.y + 50, "enemy");
fireBullet(self.x, self.y + 50 + i * 60, "enemy");
}
}
self.attackCooldown = 45;
}
LK.getSound('enemyShoot').play();
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.speed = 2;
self.fireChance = 0.005; // Chance to fire each frame
self.movementPattern = "descent"; // Default pattern
self.pointValue = 100;
self.moveDir = 1;
self.initY = 0;
self.amplitude = 100;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
// Add score
LK.setScore(LK.getScore() + self.pointValue);
// Create explosion
createExplosion(self.x, self.y);
LK.getSound('explosion').play();
// Chance to drop powerup
if (Math.random() < 0.2) {
createPowerUp(self.x, self.y);
}
// Remove enemy
return true;
}
// Flash red when hit
LK.effects.flashObject(self, 0xff0000, 200);
return false;
};
self.update = function () {
// Different movement patterns
if (self.movementPattern === "descent") {
self.y += self.speed;
} else if (self.movementPattern === "zigzag") {
self.x += self.speed * self.moveDir;
self.y += self.speed * 0.5;
// Change direction at edges
if (self.x > 1900 || self.x < 148) {
self.moveDir *= -1;
}
} else if (self.movementPattern === "sine") {
self.y += self.speed;
self.x = self.initX + Math.sin((self.y - self.initY) * 0.02) * self.amplitude;
}
// Random chance to fire
if (Math.random() < self.fireChance) {
fireBullet(self.x, self.y, "enemy");
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.lifespan = 20;
self.update = function () {
self.lifespan--;
// Grow and fade out
explosionGraphics.alpha = self.lifespan / 20;
explosionGraphics.scaleX = (20 - self.lifespan) / 10;
explosionGraphics.scaleY = (20 - self.lifespan) / 10;
if (self.lifespan <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.fireRate = 10;
self.lastFired = 0;
self.health = 3;
self.shield = false;
self.shieldGraphics = null;
self.invulnerable = false;
self.activateShield = function () {
if (!self.shield) {
self.shield = true;
self.shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
self.shieldGraphics.blendMode = "screen"; // This line has no effect, but kept for demonstration
// Shield expires after 10 seconds
LK.setTimeout(function () {
if (self.shieldGraphics) {
self.shield = false;
self.removeChild(self.shieldGraphics);
self.shieldGraphics = null;
}
}, 10000);
}
};
self.takeDamage = function () {
if (!self.invulnerable) {
if (self.shield) {
self.shield = false;
if (self.shieldGraphics) {
self.removeChild(self.shieldGraphics);
self.shieldGraphics = null;
}
} else {
self.health--;
// Make player briefly invulnerable after taking damage
self.invulnerable = true;
// Flash effect
var flashCount = 0;
var flashInterval = LK.setInterval(function () {
shipGraphics.alpha = shipGraphics.alpha === 1 ? 0.3 : 1;
flashCount++;
if (flashCount >= 10) {
LK.clearInterval(flashInterval);
shipGraphics.alpha = 1;
self.invulnerable = false;
}
}, 150);
if (self.health <= 0) {
createExplosion(self.x, self.y);
LK.getSound('explosion').play();
LK.showGameOver();
}
}
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = "shield"; // Default
self.speed = 3;
// Visual effect - pulsate
tween(powerUpGraphics, {
alpha: 0.6
}, {
duration: 500,
easing: tween.sinOut,
onFinish: function onFinish() {
tween(powerUpGraphics, {
alpha: 1
}, {
duration: 500,
easing: tween.sinIn,
onFinish: function onFinish() {
// Continuous pulsating
if (self.parent) {
tween(powerUpGraphics, {
alpha: 0.6
}, {
duration: 500,
easing: tween.sinOut,
onFinish: arguments.callee
});
}
}
});
}
});
self.update = function () {
self.y += self.speed;
};
self.collect = function () {
LK.getSound('powerUp').play();
if (self.type === "shield") {
player.activateShield();
} else if (self.type === "fireRate") {
player.fireRate = 5;
// Revert to normal fire rate after 10 seconds
LK.setTimeout(function () {
player.fireRate = 10;
}, 10000);
} else if (self.type === "health") {
player.health = Math.min(player.health + 1, 5);
updateLives();
}
return true;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Add background image to the game
var background = LK.getAsset('Background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 2048 / 100,
// Scale to fit the screen width
scaleY: 2732 / 100 // Scale to fit the screen height
});
game.addChild(background);
var player;
var playerBullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
var explosions = [];
var gameStarted = false;
var boss = null;
var waveNumber = 1;
var enemiesPerWave = 10;
var waveDelay = 0;
var dragNode = null;
var bossHealthBar;
var bossHealthBarBg;
var lives = [];
// Setup score display
var scoreTxt = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -scoreTxt.width - 20;
scoreTxt.y = 20;
// High score display
var highScoreTxt = new Text2('High Score: ' + storage.highScore, {
size: 40,
fill: 0xBBBBFF
});
highScoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -highScoreTxt.width - 20;
highScoreTxt.y = 80;
// Wave indicator
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0, 0);
LK.gui.top.addChild(waveTxt);
waveTxt.y = 20;
// Create player
function createPlayer() {
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 200;
game.addChild(player);
// Setup life display
updateLives();
}
// Life display
function updateLives() {
// Clear existing lives
for (var i = 0; i < lives.length; i++) {
LK.gui.topLeft.removeChild(lives[i]);
}
lives = [];
// Create life indicators
for (var i = 0; i < player.health; i++) {
var life = LK.getAsset('player', {
scaleX: 0.4,
scaleY: 0.4,
anchorX: 0,
anchorY: 0,
x: 120 + i * 60,
y: 20
});
lives.push(life);
LK.gui.topLeft.addChild(life);
}
}
// Create boss health bar
function createBossHealthBar() {
bossHealthBarBg = LK.getAsset('playerBullet', {
width: 1000,
height: 30,
anchorX: 0.5,
anchorY: 0,
tint: 0x333333
});
bossHealthBarBg.x = 0;
bossHealthBarBg.y = 100;
bossHealthBar = LK.getAsset('playerBullet', {
width: 1000,
height: 30,
anchorX: 0,
anchorY: 0,
tint: 0xff0000
});
bossHealthBar.x = -500;
bossHealthBar.y = 100;
LK.gui.top.addChild(bossHealthBarBg);
LK.gui.top.addChild(bossHealthBar);
}
function updateBossHealthBar() {
if (boss && bossHealthBar) {
var percentage = boss.health / boss.maxHealth;
bossHealthBar.width = 1000 * percentage;
}
}
function removeBossHealthBar() {
if (bossHealthBarBg) {
LK.gui.top.removeChild(bossHealthBarBg);
bossHealthBarBg = null;
}
if (bossHealthBar) {
LK.gui.top.removeChild(bossHealthBar);
bossHealthBar = null;
}
}
// Fire a bullet
function fireBullet(x, y, type) {
var bullet;
if (type === "player") {
bullet = new PlayerBullet();
playerBullets.push(bullet);
LK.getSound('playerShoot').play();
} else {
bullet = new EnemyBullet();
enemyBullets.push(bullet);
}
bullet.x = x;
bullet.y = y;
game.addChild(bullet);
}
// Create an explosion effect
function createExplosion(x, y) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
game.addChild(explosion);
explosions.push(explosion);
}
// Create a power-up
function createPowerUp(x, y) {
var powerUp = new PowerUp();
powerUp.x = x;
powerUp.y = y;
// Randomly select power-up type
var types = ["shield", "fireRate", "health"];
var typeIndex = Math.floor(Math.random() * types.length);
powerUp.type = types[typeIndex];
// Set color based on type
var powerUpGraphics = powerUp.getChildAt(0);
if (powerUp.type === "shield") {
powerUpGraphics.tint = 0x3498db; // Blue
} else if (powerUp.type === "fireRate") {
powerUpGraphics.tint = 0xf39c12; // Orange
} else if (powerUp.type === "health") {
powerUpGraphics.tint = 0xe74c3c; // Red
}
game.addChild(powerUp);
powerUps.push(powerUp);
}
// Spawn an enemy
function spawnEnemy(x, y, pattern) {
var enemy = new Enemy();
enemy.x = x;
enemy.y = y;
enemy.movementPattern = pattern;
if (pattern === "sine") {
enemy.initX = x;
enemy.initY = y;
}
// Adjust difficulty based on wave
enemy.health = 1 + Math.floor(waveNumber / 3);
enemy.speed = 1 + waveNumber * 0.2;
game.addChild(enemy);
enemies.push(enemy);
}
// Spawn a boss
function spawnBoss() {
boss = new Boss();
boss.x = 2048 / 2;
boss.y = 300;
// Adjust boss difficulty based on wave
boss.health = 20 + waveNumber * 5;
boss.maxHealth = boss.health;
game.addChild(boss);
// Create boss health bar
createBossHealthBar();
// Play boss music
LK.getSound('bossFight').play();
}
// Spawn a wave of enemies
function spawnWave() {
// Every 3 waves, spawn a boss
if (waveNumber % 3 === 0) {
spawnBoss();
return;
}
// Regular enemy wave
var numEnemies = enemiesPerWave + waveNumber * 2;
var patterns = ["descent", "zigzag", "sine"];
for (var i = 0; i < numEnemies; i++) {
var x = 200 + Math.random() * (2048 - 400);
var y = -100 - i * 80;
var pattern = patterns[Math.floor(Math.random() * patterns.length)];
spawnEnemy(x, y, pattern);
}
}
// Start a new wave
function startNewWave() {
waveNumber++;
waveTxt.setText('Wave: ' + waveNumber);
spawnWave();
}
// Initialize game
function initGame() {
// Initialize start message
startText = new Text2('Tap to Start', {
size: 100,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startText);
playerBullets = [];
enemyBullets = [];
enemies = [];
powerUps = [];
explosions = [];
gameStarted = true;
if (startText && startText.parent) {
LK.gui.center.removeChild(startText);
}
startText = null;
waveNumber = 0;
boss = null;
// Reset score
LK.setScore(0);
scoreTxt.setText('Score: 0');
highScoreTxt.setText('High Score: ' + storage.highScore);
// Create player
createPlayer();
// Start first wave
startNewWave();
// Play game music
LK.playMusic('gameMusic');
}
// Handle movement of player
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
// Limit player movement to bottom third of screen
dragNode.y = Math.max(y, 2732 / 3 * 2);
// Keep player on screen
dragNode.x = Math.max(dragNode.x, 100);
dragNode.x = Math.min(dragNode.x, 2048 - 100);
dragNode.y = Math.min(dragNode.y, 2732 - 100);
}
}
// Event handlers
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameStarted) {
initGame();
if (startText && startText.parent) {
LK.gui.center.removeChild(startText);
}
startText = null;
} else if (player) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Game update loop
game.update = function () {
if (!gameStarted) {
return;
}
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
// Player shooting
if (player && LK.ticks % player.fireRate === 0) {
fireBullet(player.x, player.y - 50, "player");
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Remove bullets that go off screen
if (bullet.y < -50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check for collision with enemies
var hitEnemy = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Apply damage to enemy
if (enemy.takeDamage(bullet.damage)) {
enemy.destroy();
enemies.splice(j, 1);
}
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
// Check for collision with boss
if (!hitEnemy && boss && bullet.intersects(boss)) {
boss.takeDamage(bullet.damage);
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
// Check if boss is defeated
if (boss.health <= 0) {
boss.destroy();
boss = null;
removeBossHealthBar();
waveDelay = 180; // Delay before next wave
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Remove bullets that go off screen
if (bullet.y > 2732 + 50) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (player && bullet.intersects(player)) {
player.takeDamage();
updateLives();
// Remove bullet
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Remove enemies that go off screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check for collision with player
if (player && enemy.intersects(player)) {
player.takeDamage();
updateLives();
// Remove enemy
createExplosion(enemy.x, enemy.y);
LK.getSound('explosion').play();
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Remove power-ups that go off screen
if (powerUp.y > 2732 + 50) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check for collision with player
if (player && powerUp.intersects(player)) {
if (powerUp.collect()) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
}
// Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
var explosion = explosions[i];
if (explosion.update()) {
explosions.splice(i, 1);
}
}
// Check if all enemies are defeated
if (enemies.length === 0 && !boss) {
if (waveDelay > 0) {
waveDelay--;
} else {
startNewWave();
}
}
// Update high score
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
highScoreTxt.setText('High Score: ' + storage.highScore);
}
};
// Initialize game with a start message
var startText = null;
var startText = new Text2('Tap to Start', {
size: 100,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startText);
// Remove start text when game starts
LK.on('tick', function () {
if (gameStarted && startText && startText.parent) {
LK.gui.center.removeChild(startText);
}
});
A space ship. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows standing
Evil alien spaceship red. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Shield. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An evil alien spaceship big. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Realistic space. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows