/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BigBossCube = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('bigBossCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 10;
self.health = self.maxHealth;
self.speed = 1;
self.movePattern = 0;
self.initialX = self.x;
self.flashTimer = 0;
self.takeDamage = function () {
self.health--;
self.flashTimer = 10;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Boss is destroyed
}
return false; // Boss still alive
};
self.update = function () {
self.y += self.speed;
// Slow side-to-side movement
self.x = self.initialX + Math.sin(LK.ticks * 0.02) * 100;
// Flash effect when hit
if (self.flashTimer > 0) {
self.flashTimer--;
bossGraphics.tint = self.flashTimer % 4 < 2 ? 0xFF0000 : 0xFFFFFF;
} else {
bossGraphics.tint = 0xFFFFFF;
}
};
return self;
});
var Bullet = Container.expand(function (weaponType) {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.weaponType = weaponType || 'normal';
self.update = function () {
self.y += self.speed;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0xFF1493; // Pink color for enemy bullets
self.speed = 4;
self.targetX = 0;
self.targetY = 0;
self.directionSet = false;
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
if (!self.directionSet) {
// Calculate direction towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.velocityX = dx / distance * self.speed;
self.velocityY = dy / distance * self.speed;
}
self.directionSet = true;
}
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var EnemyCube = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 3;
self.movePattern = Math.floor(Math.random() * 3);
self.initialX = self.x;
self.update = function () {
self.y += self.speed;
if (self.movePattern === 1) {
self.x = self.initialX + Math.sin(self.y * 0.01) * 50;
} else if (self.movePattern === 2) {
self.x += Math.sin(LK.ticks * 0.1) * 2;
}
};
return self;
});
var PinkMegaBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('pinkMegaBoss', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 100;
self.health = self.maxHealth;
self.speed = 0.3;
self.movePattern = 0;
self.initialX = self.x;
self.flashTimer = 0;
self.shootCooldown = 0;
self.shootTimer = 120; // Shoot every 2 seconds at 60fps
self.takeDamage = function () {
self.health--;
self.flashTimer = 10;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Boss is destroyed
}
return false; // Boss still alive
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 175; // Shoot from bottom of boss
bullet.targetX = player.x;
bullet.targetY = player.y;
self.shootCooldown = self.shootTimer;
return bullet;
}
return null;
};
self.update = function () {
self.y += self.speed;
// Slow side-to-side movement
self.x = self.initialX + Math.sin(LK.ticks * 0.005) * 200;
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Flash effect when hit
if (self.flashTimer > 0) {
self.flashTimer--;
bossGraphics.tint = self.flashTimer % 4 < 2 ? 0xFF0000 : 0xFFFFFF;
} else {
bossGraphics.tint = 0xFFFFFF;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.weaponType = 'normal';
self.shootCooldown = 0;
self.weaponTimer = 0;
self.weaponDuration = 300; // 5 seconds at 60fps
self.setWeapon = function (weaponType) {
self.weaponType = weaponType;
self.weaponTimer = self.weaponDuration;
// Visual feedback for weapon upgrade
tween(playerGraphics, {
tint: 0xFFD700
}, {
duration: 200,
onFinish: function onFinish() {
tween(playerGraphics, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bulletSpeed = 8;
if (self.weaponType === 'rapidFire') {
self.shootCooldown = 5;
self.createBullet(0, 0);
} else if (self.weaponType === 'spreadShot') {
self.shootCooldown = 15;
self.createBullet(-20, -5);
self.createBullet(0, 0);
self.createBullet(20, 5);
} else if (self.weaponType === 'explosive') {
self.shootCooldown = 20;
var bullet = self.createBullet(0, 0);
bullet.tint = 0xFF4500;
} else {
self.shootCooldown = 10;
self.createBullet(0, 0);
}
LK.getSound('shoot').play();
}
};
self.createBullet = function (offsetX, speedX) {
var bullet = new Bullet(self.weaponType);
bullet.x = self.x + offsetX;
bullet.y = self.y - 50;
bullet.speedX = speedX || 0;
return bullet;
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.weaponTimer > 0) {
self.weaponTimer--;
if (self.weaponTimer <= 0) {
self.weaponType = 'normal';
tween(playerGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
}
};
return self;
});
var SuperBossCube = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('superBossCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = self.maxHealth;
self.speed = 0.5;
self.movePattern = 0;
self.initialX = self.x;
self.flashTimer = 0;
self.takeDamage = function () {
self.health--;
self.flashTimer = 10;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Boss is destroyed
}
return false; // Boss still alive
};
self.update = function () {
self.y += self.speed;
// Slow side-to-side movement
self.x = self.initialX + Math.sin(LK.ticks * 0.01) * 150;
// Flash effect when hit
if (self.flashTimer > 0) {
self.flashTimer--;
bossGraphics.tint = self.flashTimer % 4 < 2 ? 0xFF0000 : 0xFFFFFF;
} else {
bossGraphics.tint = 0xFFFFFF;
}
};
return self;
});
var WeaponPickup = Container.expand(function (weaponType) {
var self = Container.call(this);
var pickupGraphics = self.attachAsset('weaponPickup', {
anchorX: 0.5,
anchorY: 0.5
});
self.weaponType = weaponType || 'rapidFire';
self.speed = 3;
self.bobOffset = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.speed;
self.x += Math.sin(LK.ticks * 0.1 + self.bobOffset) * 0.5;
pickupGraphics.rotation += 0.05;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
game.setBackgroundColor(0x16213e);
// Game variables
var player;
var enemies = [];
var bullets = [];
var pickups = [];
var waveNumber = 1;
var enemiesInWave = 5;
var enemiesSpawned = 0;
var spawnTimer = 0;
var dragNode = null;
var boss = null;
var bossSpawned = false;
var superBoss = null;
var superBossSpawned = false;
var pinkMegaBoss = null;
var pinkMegaBossSpawned = false;
var enemyBullets = [];
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(waveTxt);
waveTxt.x -= 20;
var weaponTxt = new Text2('Weapon: Normal', {
size: 40,
fill: 0xFFD700
});
weaponTxt.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(weaponTxt);
weaponTxt.x += 20;
weaponTxt.y -= 20;
var bossHealthTxt = new Text2('', {
size: 50,
fill: 0xFF0000
});
bossHealthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bossHealthTxt);
bossHealthTxt.y += 80;
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2400;
// Weapon types for pickups
var weaponTypes = ['rapidFire', 'spreadShot', 'explosive'];
function spawnEnemy() {
var enemy = new EnemyCube();
enemy.x = Math.random() * 1800 + 124; // Keep enemies within screen bounds
enemy.y = -60;
enemy.initialX = enemy.x;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnWeaponPickup(x, y) {
var weaponType = weaponTypes[Math.floor(Math.random() * weaponTypes.length)];
var pickup = new WeaponPickup(weaponType);
pickup.x = x;
pickup.y = y;
pickups.push(pickup);
game.addChild(pickup);
}
function checkCollision(obj1, obj2) {
return obj1.intersects(obj2);
}
function nextWave() {
waveNumber++;
enemiesInWave = Math.min(5 + waveNumber * 2, 20);
enemiesSpawned = 0;
waveTxt.setText('Wave: ' + waveNumber);
// Spawn pink mega boss at wave 12
if (waveNumber === 12 && !pinkMegaBossSpawned) {
spawnPinkMegaBoss();
} else if (waveNumber === 8 && !superBossSpawned) {
// Spawn super boss at wave 8
spawnSuperBoss();
} else if (waveNumber % 5 === 0 && !bossSpawned) {
// Spawn boss at wave 5 and every 5 waves after
spawnBoss();
}
}
function spawnBoss() {
boss = new BigBossCube();
boss.x = 1024; // Center of screen
boss.y = -150;
boss.initialX = boss.x;
bossSpawned = true;
game.addChild(boss);
}
function spawnSuperBoss() {
superBoss = new SuperBossCube();
superBoss.x = 1024; // Center of screen
superBoss.y = -250;
superBoss.initialX = superBoss.x;
superBossSpawned = true;
game.addChild(superBoss);
}
function spawnPinkMegaBoss() {
pinkMegaBoss = new PinkMegaBoss();
pinkMegaBoss.x = 1024; // Center of screen
pinkMegaBoss.y = -350;
pinkMegaBoss.initialX = pinkMegaBoss.x;
pinkMegaBossSpawned = true;
game.addChild(pinkMegaBoss);
}
function updateWeaponText() {
var weaponName = 'Normal';
if (player.weaponType === 'rapidFire') weaponName = 'Rapid Fire';else if (player.weaponType === 'spreadShot') weaponName = 'Spread Shot';else if (player.weaponType === 'explosive') weaponName = 'Explosive';
weaponTxt.setText('Weapon: ' + weaponName);
}
// Event handlers
game.down = function (x, y, obj) {
dragNode = player;
player.x = Math.max(40, Math.min(2008, x));
player.y = Math.max(40, Math.min(2692, y));
};
game.move = function (x, y, obj) {
if (dragNode) {
dragNode.x = Math.max(40, Math.min(2008, x));
dragNode.y = Math.max(40, Math.min(2692, y));
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
// Update player
player.shoot();
updateWeaponText();
// Spawn enemies
if (enemiesSpawned < enemiesInWave) {
spawnTimer--;
if (spawnTimer <= 0) {
spawnEnemy();
enemiesSpawned++;
spawnTimer = Math.max(30 - waveNumber * 2, 10);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.speedX) {
bullet.x += bullet.speedX;
}
// Remove bullets that are off screen
if (bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-pink mega boss collision first
if (pinkMegaBoss && checkCollision(bullet, pinkMegaBoss)) {
var pinkMegaBossDestroyed = pinkMegaBoss.takeDamage();
if (pinkMegaBossDestroyed) {
LK.setScore(LK.getScore() + 1000);
LK.effects.flashObject(pinkMegaBoss, 0xFFD700, 1500);
// Drop multiple weapon pickups when pink mega boss dies
for (var pickupCount = 0; pickupCount < 8; pickupCount++) {
spawnWeaponPickup(pinkMegaBoss.x + (Math.random() - 0.5) * 300, pinkMegaBoss.y);
}
pinkMegaBoss.destroy();
pinkMegaBoss = null;
pinkMegaBossSpawned = false;
} else {
LK.setScore(LK.getScore() + 20);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
// Check bullet-super boss collision first
if (superBoss && checkCollision(bullet, superBoss)) {
var superBossDestroyed = superBoss.takeDamage();
if (superBossDestroyed) {
LK.setScore(LK.getScore() + 500);
LK.effects.flashObject(superBoss, 0xFFD700, 1000);
// Drop multiple weapon pickups when super boss dies
for (var pickupCount = 0; pickupCount < 5; pickupCount++) {
spawnWeaponPickup(superBoss.x + (Math.random() - 0.5) * 200, superBoss.y);
}
superBoss.destroy();
superBoss = null;
superBossSpawned = false;
} else {
LK.setScore(LK.getScore() + 10);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
// Check bullet-boss collision first
if (boss && checkCollision(bullet, boss)) {
var bossDestroyed = boss.takeDamage();
if (bossDestroyed) {
LK.setScore(LK.getScore() + 100);
LK.effects.flashObject(boss, 0xFFD700, 500);
// Drop multiple weapon pickups when boss dies
for (var pickupCount = 0; pickupCount < 3; pickupCount++) {
spawnWeaponPickup(boss.x + (Math.random() - 0.5) * 100, boss.y);
}
boss.destroy();
boss = null;
bossSpawned = false;
} else {
LK.setScore(LK.getScore() + 5);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (checkCollision(bullet, enemy)) {
// Handle explosive bullets
if (bullet.weaponType === 'explosive') {
for (var k = enemies.length - 1; k >= 0; k--) {
var nearbyEnemy = enemies[k];
var dx = nearbyEnemy.x - enemy.x;
var dy = nearbyEnemy.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
LK.setScore(LK.getScore() + 10);
LK.effects.flashObject(nearbyEnemy, 0xFF4500, 300);
nearbyEnemy.destroy();
enemies.splice(k, 1);
if (Math.random() < 0.3) {
spawnWeaponPickup(nearbyEnemy.x, nearbyEnemy.y);
}
}
}
} else {
LK.setScore(LK.getScore() + 10);
LK.effects.flashObject(enemy, 0xFF0000, 200);
// Chance to drop weapon pickup
if (Math.random() < 0.25) {
spawnWeaponPickup(enemy.x, enemy.y);
}
enemy.destroy();
enemies.splice(j, 1);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Remove enemies that are off screen
if (enemy.y > 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check player-enemy collision
if (checkCollision(player, enemy)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
}
// Update pink mega boss
if (pinkMegaBoss) {
bossHealthTxt.setText('Pink Mega Boss Health: ' + pinkMegaBoss.health + '/' + pinkMegaBoss.maxHealth);
// Pink mega boss shooting
var newEnemyBullet = pinkMegaBoss.shoot();
if (newEnemyBullet) {
enemyBullets.push(newEnemyBullet);
game.addChild(newEnemyBullet);
}
// Remove pink mega boss if off screen
if (pinkMegaBoss.y > 2800) {
pinkMegaBoss.destroy();
pinkMegaBoss = null;
pinkMegaBossSpawned = false;
}
// Check player-pink mega boss collision
if (checkCollision(player, pinkMegaBoss)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
} else if (superBoss) {
bossHealthTxt.setText('Super Boss Health: ' + superBoss.health + '/' + superBoss.maxHealth);
// Remove super boss if off screen (super boss escaped)
if (superBoss.y > 2800) {
superBoss.destroy();
superBoss = null;
superBossSpawned = false;
}
// Check player-super boss collision
if (checkCollision(player, superBoss)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
} else if (boss) {
bossHealthTxt.setText('Boss Health: ' + boss.health + '/' + boss.maxHealth);
// Remove boss if off screen (boss escaped)
if (boss.y > 2800) {
boss.destroy();
boss = null;
bossSpawned = false;
}
// Check player-boss collision
if (checkCollision(player, boss)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
} else {
bossHealthTxt.setText('');
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var enemyBullet = enemyBullets[i];
// Remove enemy bullets that are off screen
if (enemyBullet.y > 2800 || enemyBullet.y < -50 || enemyBullet.x < -50 || enemyBullet.x > 2100) {
enemyBullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check player-enemy bullet collision
if (checkCollision(player, enemyBullet)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
}
// Update weapon pickups
for (var i = pickups.length - 1; i >= 0; i--) {
var pickup = pickups[i];
// Remove pickups that are off screen
if (pickup.y > 2800) {
pickup.destroy();
pickups.splice(i, 1);
continue;
}
// Check player-pickup collision
if (checkCollision(player, pickup)) {
player.setWeapon(pickup.weaponType);
LK.getSound('pickup').play();
pickup.destroy();
pickups.splice(i, 1);
}
}
// Check for next wave
if (enemiesSpawned >= enemiesInWave && enemies.length === 0 && !boss && !superBoss && !pinkMegaBoss) {
nextWave();
}
// Create bullets when player shoots
if (LK.ticks % 1 === 0) {
var newBullets = [];
game.children.forEach(function (child) {
if (child.createBullet && child.shootCooldown === 0) {
// This is handled in player.shoot()
}
});
// Add bullets created by player
if (player.shootCooldown === 1) {
var playerBullets = [];
if (player.weaponType === 'rapidFire') {
playerBullets.push(player.createBullet(0, 0));
} else if (player.weaponType === 'spreadShot') {
playerBullets.push(player.createBullet(-20, -2));
playerBullets.push(player.createBullet(0, 0));
playerBullets.push(player.createBullet(20, 2));
} else if (player.weaponType === 'explosive') {
var bullet = player.createBullet(0, 0);
bullet.tint = 0xFF4500;
playerBullets.push(bullet);
} else {
playerBullets.push(player.createBullet(0, 0));
}
playerBullets.forEach(function (bullet) {
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
}
});
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BigBossCube = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('bigBossCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 10;
self.health = self.maxHealth;
self.speed = 1;
self.movePattern = 0;
self.initialX = self.x;
self.flashTimer = 0;
self.takeDamage = function () {
self.health--;
self.flashTimer = 10;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Boss is destroyed
}
return false; // Boss still alive
};
self.update = function () {
self.y += self.speed;
// Slow side-to-side movement
self.x = self.initialX + Math.sin(LK.ticks * 0.02) * 100;
// Flash effect when hit
if (self.flashTimer > 0) {
self.flashTimer--;
bossGraphics.tint = self.flashTimer % 4 < 2 ? 0xFF0000 : 0xFFFFFF;
} else {
bossGraphics.tint = 0xFFFFFF;
}
};
return self;
});
var Bullet = Container.expand(function (weaponType) {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.weaponType = weaponType || 'normal';
self.update = function () {
self.y += self.speed;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0xFF1493; // Pink color for enemy bullets
self.speed = 4;
self.targetX = 0;
self.targetY = 0;
self.directionSet = false;
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
if (!self.directionSet) {
// Calculate direction towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.velocityX = dx / distance * self.speed;
self.velocityY = dy / distance * self.speed;
}
self.directionSet = true;
}
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var EnemyCube = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 3;
self.movePattern = Math.floor(Math.random() * 3);
self.initialX = self.x;
self.update = function () {
self.y += self.speed;
if (self.movePattern === 1) {
self.x = self.initialX + Math.sin(self.y * 0.01) * 50;
} else if (self.movePattern === 2) {
self.x += Math.sin(LK.ticks * 0.1) * 2;
}
};
return self;
});
var PinkMegaBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('pinkMegaBoss', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 100;
self.health = self.maxHealth;
self.speed = 0.3;
self.movePattern = 0;
self.initialX = self.x;
self.flashTimer = 0;
self.shootCooldown = 0;
self.shootTimer = 120; // Shoot every 2 seconds at 60fps
self.takeDamage = function () {
self.health--;
self.flashTimer = 10;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Boss is destroyed
}
return false; // Boss still alive
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 175; // Shoot from bottom of boss
bullet.targetX = player.x;
bullet.targetY = player.y;
self.shootCooldown = self.shootTimer;
return bullet;
}
return null;
};
self.update = function () {
self.y += self.speed;
// Slow side-to-side movement
self.x = self.initialX + Math.sin(LK.ticks * 0.005) * 200;
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Flash effect when hit
if (self.flashTimer > 0) {
self.flashTimer--;
bossGraphics.tint = self.flashTimer % 4 < 2 ? 0xFF0000 : 0xFFFFFF;
} else {
bossGraphics.tint = 0xFFFFFF;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.weaponType = 'normal';
self.shootCooldown = 0;
self.weaponTimer = 0;
self.weaponDuration = 300; // 5 seconds at 60fps
self.setWeapon = function (weaponType) {
self.weaponType = weaponType;
self.weaponTimer = self.weaponDuration;
// Visual feedback for weapon upgrade
tween(playerGraphics, {
tint: 0xFFD700
}, {
duration: 200,
onFinish: function onFinish() {
tween(playerGraphics, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bulletSpeed = 8;
if (self.weaponType === 'rapidFire') {
self.shootCooldown = 5;
self.createBullet(0, 0);
} else if (self.weaponType === 'spreadShot') {
self.shootCooldown = 15;
self.createBullet(-20, -5);
self.createBullet(0, 0);
self.createBullet(20, 5);
} else if (self.weaponType === 'explosive') {
self.shootCooldown = 20;
var bullet = self.createBullet(0, 0);
bullet.tint = 0xFF4500;
} else {
self.shootCooldown = 10;
self.createBullet(0, 0);
}
LK.getSound('shoot').play();
}
};
self.createBullet = function (offsetX, speedX) {
var bullet = new Bullet(self.weaponType);
bullet.x = self.x + offsetX;
bullet.y = self.y - 50;
bullet.speedX = speedX || 0;
return bullet;
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.weaponTimer > 0) {
self.weaponTimer--;
if (self.weaponTimer <= 0) {
self.weaponType = 'normal';
tween(playerGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
}
};
return self;
});
var SuperBossCube = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('superBossCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = self.maxHealth;
self.speed = 0.5;
self.movePattern = 0;
self.initialX = self.x;
self.flashTimer = 0;
self.takeDamage = function () {
self.health--;
self.flashTimer = 10;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Boss is destroyed
}
return false; // Boss still alive
};
self.update = function () {
self.y += self.speed;
// Slow side-to-side movement
self.x = self.initialX + Math.sin(LK.ticks * 0.01) * 150;
// Flash effect when hit
if (self.flashTimer > 0) {
self.flashTimer--;
bossGraphics.tint = self.flashTimer % 4 < 2 ? 0xFF0000 : 0xFFFFFF;
} else {
bossGraphics.tint = 0xFFFFFF;
}
};
return self;
});
var WeaponPickup = Container.expand(function (weaponType) {
var self = Container.call(this);
var pickupGraphics = self.attachAsset('weaponPickup', {
anchorX: 0.5,
anchorY: 0.5
});
self.weaponType = weaponType || 'rapidFire';
self.speed = 3;
self.bobOffset = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.speed;
self.x += Math.sin(LK.ticks * 0.1 + self.bobOffset) * 0.5;
pickupGraphics.rotation += 0.05;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
game.setBackgroundColor(0x16213e);
// Game variables
var player;
var enemies = [];
var bullets = [];
var pickups = [];
var waveNumber = 1;
var enemiesInWave = 5;
var enemiesSpawned = 0;
var spawnTimer = 0;
var dragNode = null;
var boss = null;
var bossSpawned = false;
var superBoss = null;
var superBossSpawned = false;
var pinkMegaBoss = null;
var pinkMegaBossSpawned = false;
var enemyBullets = [];
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(waveTxt);
waveTxt.x -= 20;
var weaponTxt = new Text2('Weapon: Normal', {
size: 40,
fill: 0xFFD700
});
weaponTxt.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(weaponTxt);
weaponTxt.x += 20;
weaponTxt.y -= 20;
var bossHealthTxt = new Text2('', {
size: 50,
fill: 0xFF0000
});
bossHealthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bossHealthTxt);
bossHealthTxt.y += 80;
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2400;
// Weapon types for pickups
var weaponTypes = ['rapidFire', 'spreadShot', 'explosive'];
function spawnEnemy() {
var enemy = new EnemyCube();
enemy.x = Math.random() * 1800 + 124; // Keep enemies within screen bounds
enemy.y = -60;
enemy.initialX = enemy.x;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnWeaponPickup(x, y) {
var weaponType = weaponTypes[Math.floor(Math.random() * weaponTypes.length)];
var pickup = new WeaponPickup(weaponType);
pickup.x = x;
pickup.y = y;
pickups.push(pickup);
game.addChild(pickup);
}
function checkCollision(obj1, obj2) {
return obj1.intersects(obj2);
}
function nextWave() {
waveNumber++;
enemiesInWave = Math.min(5 + waveNumber * 2, 20);
enemiesSpawned = 0;
waveTxt.setText('Wave: ' + waveNumber);
// Spawn pink mega boss at wave 12
if (waveNumber === 12 && !pinkMegaBossSpawned) {
spawnPinkMegaBoss();
} else if (waveNumber === 8 && !superBossSpawned) {
// Spawn super boss at wave 8
spawnSuperBoss();
} else if (waveNumber % 5 === 0 && !bossSpawned) {
// Spawn boss at wave 5 and every 5 waves after
spawnBoss();
}
}
function spawnBoss() {
boss = new BigBossCube();
boss.x = 1024; // Center of screen
boss.y = -150;
boss.initialX = boss.x;
bossSpawned = true;
game.addChild(boss);
}
function spawnSuperBoss() {
superBoss = new SuperBossCube();
superBoss.x = 1024; // Center of screen
superBoss.y = -250;
superBoss.initialX = superBoss.x;
superBossSpawned = true;
game.addChild(superBoss);
}
function spawnPinkMegaBoss() {
pinkMegaBoss = new PinkMegaBoss();
pinkMegaBoss.x = 1024; // Center of screen
pinkMegaBoss.y = -350;
pinkMegaBoss.initialX = pinkMegaBoss.x;
pinkMegaBossSpawned = true;
game.addChild(pinkMegaBoss);
}
function updateWeaponText() {
var weaponName = 'Normal';
if (player.weaponType === 'rapidFire') weaponName = 'Rapid Fire';else if (player.weaponType === 'spreadShot') weaponName = 'Spread Shot';else if (player.weaponType === 'explosive') weaponName = 'Explosive';
weaponTxt.setText('Weapon: ' + weaponName);
}
// Event handlers
game.down = function (x, y, obj) {
dragNode = player;
player.x = Math.max(40, Math.min(2008, x));
player.y = Math.max(40, Math.min(2692, y));
};
game.move = function (x, y, obj) {
if (dragNode) {
dragNode.x = Math.max(40, Math.min(2008, x));
dragNode.y = Math.max(40, Math.min(2692, y));
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
// Update player
player.shoot();
updateWeaponText();
// Spawn enemies
if (enemiesSpawned < enemiesInWave) {
spawnTimer--;
if (spawnTimer <= 0) {
spawnEnemy();
enemiesSpawned++;
spawnTimer = Math.max(30 - waveNumber * 2, 10);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.speedX) {
bullet.x += bullet.speedX;
}
// Remove bullets that are off screen
if (bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-pink mega boss collision first
if (pinkMegaBoss && checkCollision(bullet, pinkMegaBoss)) {
var pinkMegaBossDestroyed = pinkMegaBoss.takeDamage();
if (pinkMegaBossDestroyed) {
LK.setScore(LK.getScore() + 1000);
LK.effects.flashObject(pinkMegaBoss, 0xFFD700, 1500);
// Drop multiple weapon pickups when pink mega boss dies
for (var pickupCount = 0; pickupCount < 8; pickupCount++) {
spawnWeaponPickup(pinkMegaBoss.x + (Math.random() - 0.5) * 300, pinkMegaBoss.y);
}
pinkMegaBoss.destroy();
pinkMegaBoss = null;
pinkMegaBossSpawned = false;
} else {
LK.setScore(LK.getScore() + 20);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
// Check bullet-super boss collision first
if (superBoss && checkCollision(bullet, superBoss)) {
var superBossDestroyed = superBoss.takeDamage();
if (superBossDestroyed) {
LK.setScore(LK.getScore() + 500);
LK.effects.flashObject(superBoss, 0xFFD700, 1000);
// Drop multiple weapon pickups when super boss dies
for (var pickupCount = 0; pickupCount < 5; pickupCount++) {
spawnWeaponPickup(superBoss.x + (Math.random() - 0.5) * 200, superBoss.y);
}
superBoss.destroy();
superBoss = null;
superBossSpawned = false;
} else {
LK.setScore(LK.getScore() + 10);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
// Check bullet-boss collision first
if (boss && checkCollision(bullet, boss)) {
var bossDestroyed = boss.takeDamage();
if (bossDestroyed) {
LK.setScore(LK.getScore() + 100);
LK.effects.flashObject(boss, 0xFFD700, 500);
// Drop multiple weapon pickups when boss dies
for (var pickupCount = 0; pickupCount < 3; pickupCount++) {
spawnWeaponPickup(boss.x + (Math.random() - 0.5) * 100, boss.y);
}
boss.destroy();
boss = null;
bossSpawned = false;
} else {
LK.setScore(LK.getScore() + 5);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (checkCollision(bullet, enemy)) {
// Handle explosive bullets
if (bullet.weaponType === 'explosive') {
for (var k = enemies.length - 1; k >= 0; k--) {
var nearbyEnemy = enemies[k];
var dx = nearbyEnemy.x - enemy.x;
var dy = nearbyEnemy.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
LK.setScore(LK.getScore() + 10);
LK.effects.flashObject(nearbyEnemy, 0xFF4500, 300);
nearbyEnemy.destroy();
enemies.splice(k, 1);
if (Math.random() < 0.3) {
spawnWeaponPickup(nearbyEnemy.x, nearbyEnemy.y);
}
}
}
} else {
LK.setScore(LK.getScore() + 10);
LK.effects.flashObject(enemy, 0xFF0000, 200);
// Chance to drop weapon pickup
if (Math.random() < 0.25) {
spawnWeaponPickup(enemy.x, enemy.y);
}
enemy.destroy();
enemies.splice(j, 1);
}
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
scoreTxt.setText('Score: ' + LK.getScore());
break;
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Remove enemies that are off screen
if (enemy.y > 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check player-enemy collision
if (checkCollision(player, enemy)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
}
// Update pink mega boss
if (pinkMegaBoss) {
bossHealthTxt.setText('Pink Mega Boss Health: ' + pinkMegaBoss.health + '/' + pinkMegaBoss.maxHealth);
// Pink mega boss shooting
var newEnemyBullet = pinkMegaBoss.shoot();
if (newEnemyBullet) {
enemyBullets.push(newEnemyBullet);
game.addChild(newEnemyBullet);
}
// Remove pink mega boss if off screen
if (pinkMegaBoss.y > 2800) {
pinkMegaBoss.destroy();
pinkMegaBoss = null;
pinkMegaBossSpawned = false;
}
// Check player-pink mega boss collision
if (checkCollision(player, pinkMegaBoss)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
} else if (superBoss) {
bossHealthTxt.setText('Super Boss Health: ' + superBoss.health + '/' + superBoss.maxHealth);
// Remove super boss if off screen (super boss escaped)
if (superBoss.y > 2800) {
superBoss.destroy();
superBoss = null;
superBossSpawned = false;
}
// Check player-super boss collision
if (checkCollision(player, superBoss)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
} else if (boss) {
bossHealthTxt.setText('Boss Health: ' + boss.health + '/' + boss.maxHealth);
// Remove boss if off screen (boss escaped)
if (boss.y > 2800) {
boss.destroy();
boss = null;
bossSpawned = false;
}
// Check player-boss collision
if (checkCollision(player, boss)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
} else {
bossHealthTxt.setText('');
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var enemyBullet = enemyBullets[i];
// Remove enemy bullets that are off screen
if (enemyBullet.y > 2800 || enemyBullet.y < -50 || enemyBullet.x < -50 || enemyBullet.x > 2100) {
enemyBullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check player-enemy bullet collision
if (checkCollision(player, enemyBullet)) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.getSound('playerHit').play();
LK.showGameOver();
return;
}
}
// Update weapon pickups
for (var i = pickups.length - 1; i >= 0; i--) {
var pickup = pickups[i];
// Remove pickups that are off screen
if (pickup.y > 2800) {
pickup.destroy();
pickups.splice(i, 1);
continue;
}
// Check player-pickup collision
if (checkCollision(player, pickup)) {
player.setWeapon(pickup.weaponType);
LK.getSound('pickup').play();
pickup.destroy();
pickups.splice(i, 1);
}
}
// Check for next wave
if (enemiesSpawned >= enemiesInWave && enemies.length === 0 && !boss && !superBoss && !pinkMegaBoss) {
nextWave();
}
// Create bullets when player shoots
if (LK.ticks % 1 === 0) {
var newBullets = [];
game.children.forEach(function (child) {
if (child.createBullet && child.shootCooldown === 0) {
// This is handled in player.shoot()
}
});
// Add bullets created by player
if (player.shootCooldown === 1) {
var playerBullets = [];
if (player.weaponType === 'rapidFire') {
playerBullets.push(player.createBullet(0, 0));
} else if (player.weaponType === 'spreadShot') {
playerBullets.push(player.createBullet(-20, -2));
playerBullets.push(player.createBullet(0, 0));
playerBullets.push(player.createBullet(20, 2));
} else if (player.weaponType === 'explosive') {
var bullet = player.createBullet(0, 0);
bullet.tint = 0xFF4500;
playerBullets.push(bullet);
} else {
playerBullets.push(player.createBullet(0, 0));
}
playerBullets.forEach(function (bullet) {
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
}
});
}
}
};