/****
* 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