/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BigEnemyDrop = Container.expand(function () { var self = Container.call(this); var dropGraphics = self.attachAsset('bigEnemyDropAsset', { anchorX: 0.5, anchorY: 0.5 }); self.pointValue = 50; self.collectRadius = 50; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.collectRadius) { var moveSpeed = 8; self.x += dx / distance * moveSpeed; self.y += dy / distance * moveSpeed; if (distance < 30) { LK.setScore(LK.getScore() + self.pointValue); self.destroy(); for (var i = bigEnemyDrops.length - 1; i >= 0; i--) { if (bigEnemyDrops[i] === self) { bigEnemyDrops.splice(i, 1); break; } } } } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.damage = 5; self.lifespan = 0; self.maxLifespan = 120; self.update = function () { if (powerUpActive) return; self.x += self.velocityX; self.y += self.velocityY; self.lifespan++; if (self.lifespan >= self.maxLifespan || self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) { self.destroy(); for (var i = bullets.length - 1; i >= 0; i--) { if (bullets[i] === self) { bullets.splice(i, 1); break; } } } }; return self; }); var CircleBoss = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('uniqueCircleBoss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 80; self.maxHealth = 80; self.speed = 1.5; self.damage = 20; self.experienceValue = 2; self.shootTimer = 0; self.shootCooldown = 90; self.update = function () { if (powerUpActive) return; // Check if touching shield circle if (shieldActive && player.shieldCircle) { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { // Shield circle radius self.die(); return; } } var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Shooting logic self.shootTimer++; if (self.shootTimer >= self.shootCooldown && distance < 800 && distance > 100) { self.shootAtPlayer(); self.shootTimer = 0; } if (distance < 50) { player.takeDamage(15); self.destroy(); for (var i = shieldEnemies.length - 1; i >= 0; i--) { if (shieldEnemies[i] === self) { shieldEnemies.splice(i, 1); break; } } } }; self.shootAtPlayer = function () { var bullet = new CircleBossBullet(); bullet.x = self.x; bullet.y = self.y; var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); bullet.velocityX = dx / distance * 8; bullet.velocityY = dy / distance * 8; enemyBullets.push(bullet); game.addChild(bullet); }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 100); if (self.health <= 0) { self.die(); } }; self.die = function () { var drop = new ShieldPowerup(); drop.x = self.x; drop.y = self.y; shieldPowerups.push(drop); game.addChild(drop); LK.getSound('enemyHit').play(); self.destroy(); for (var i = shieldEnemies.length - 1; i >= 0; i--) { if (shieldEnemies[i] === self) { shieldEnemies.splice(i, 1); break; } } }; return self; }); var CircleBossBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('circleBossBullet', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.damage = 10; self.lifespan = 0; self.maxLifespan = 120; self.update = function () { if (powerUpActive) return; self.x += self.velocityX; self.y += self.velocityY; self.lifespan++; if (self.lifespan >= self.maxLifespan || self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) { self.destroy(); for (var i = enemyBullets.length - 1; i >= 0; i--) { if (enemyBullets[i] === self) { enemyBullets.splice(i, 1); break; } } } // Check collision with player var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { player.takeDamage(self.damage); self.destroy(); for (var i = enemyBullets.length - 1; i >= 0; i--) { if (enemyBullets[i] === self) { enemyBullets.splice(i, 1); break; } } } }; return self; }); var ClearBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 80; self.maxHealth = 80; self.speed = 1; self.damage = 50; self.experienceValue = 10; self.update = function () { if (powerUpActive) return; var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Deal damage when touching player (only once per collision) if (distance < 80) { if (!self.lastTouchingPlayer) { player.takeDamage(50); } self.lastTouchingPlayer = true; } else { self.lastTouchingPlayer = false; } }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 150); if (self.health <= 0) { self.die(); } }; self.die = function () { // Create screen clear powerup - all big enemies drop this var powerup = new ScreenClearPowerup(); powerup.x = self.x; powerup.y = self.y; screenClearPowerups.push(powerup); game.addChild(powerup); // Visual feedback for powerup drop LK.effects.flashObject(powerup, 0xFF9800, 1000); LK.getSound('bossDefeat').play(); // Remove from bosses array first, then destroy for (var i = bosses.length - 1; i >= 0; i--) { if (bosses[i] === self) { bosses.splice(i, 1); break; } } self.destroy(); }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF4444 }); self.velocityX = 0; self.velocityY = 0; self.damage = 10; self.lifespan = 0; self.maxLifespan = 120; self.update = function () { if (powerUpActive) return; self.x += self.velocityX; self.y += self.velocityY; self.lifespan++; if (self.lifespan >= self.maxLifespan || self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) { self.destroy(); for (var i = enemyBullets.length - 1; i >= 0; i--) { if (enemyBullets[i] === self) { enemyBullets.splice(i, 1); break; } } } // Check collision with player var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { player.takeDamage(self.damage); self.destroy(); for (var i = enemyBullets.length - 1; i >= 0; i--) { if (enemyBullets[i] === self) { enemyBullets.splice(i, 1); break; } } } }; return self; }); var ExperienceOrb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('experienceOrb', { anchorX: 0.5, anchorY: 0.5 }); self.experienceValue = 1; self.collectRadius = 100; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.collectRadius) { var moveSpeed = 8; self.x += dx / distance * moveSpeed; self.y += dy / distance * moveSpeed; if (distance < 30) { player.gainExperience(self.experienceValue); self.destroy(); for (var i = experienceOrbs.length - 1; i >= 0; i--) { if (experienceOrbs[i] === self) { experienceOrbs.splice(i, 1); break; } } } } }; return self; }); var Goblin = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 10; self.maxHealth = 10; self.speed = 2; self.damage = 15; self.experienceValue = 1; self.update = function () { if (powerUpActive) return; // Check if touching shield circle if (shieldActive && player.shieldCircle) { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 250) { // Shield circle radius self.die(); return; } } var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } if (distance < 50) { player.takeDamage(self.damage); self.destroy(); for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } } }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 100); if (self.health <= 0) { self.die(); } }; self.die = function () { var drop = new SmallEnemyDrop(); drop.x = self.x; drop.y = self.y; smallEnemyDrops.push(drop); game.addChild(drop); LK.getSound('enemyHit').play(); self.destroy(); for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.experience = 0; self.level = 1; self.experienceToNext = 10; self.shootTimer = 0; self.shootCooldown = 30; self.damage = 5; self.speed = 8; self.update = function () { self.shootTimer++; if (self.shootTimer >= self.shootCooldown) { self.shootAtNearestEnemy(); self.shootTimer = 0; } }; self.shootAtNearestEnemy = function () { // Can't shoot when shield is active if (shieldActive) return; var nearestEnemy = null; var nearestDistance = Infinity; // Check regular enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance && distance < 600) { nearestDistance = distance; nearestEnemy = enemy; } } // Check bosses for (var i = 0; i < bosses.length; i++) { var boss = bosses[i]; var dx = boss.x - self.x; var dy = boss.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance && distance < 600) { nearestDistance = distance; nearestEnemy = boss; } } // Check shield enemies (CircleBoss) for (var i = 0; i < shieldEnemies.length; i++) { var shieldEnemy = shieldEnemies[i]; var dx = shieldEnemy.x - self.x; var dy = shieldEnemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance && distance < 600) { nearestDistance = distance; nearestEnemy = shieldEnemy; } } // Check spiders for (var i = 0; i < spiders.length; i++) { var spider = spiders[i]; var dx = spider.x - self.x; var dy = spider.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance && distance < 600) { nearestDistance = distance; nearestEnemy = spider; } } if (nearestEnemy) { for (var b = 0; b < bulletCount; b++) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = nearestEnemy.x - self.x; var dy = nearestEnemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var spread = (b - (bulletCount - 1) / 2) * 0.2; var angle = Math.atan2(dy, dx) + spread; bullet.velocityX = Math.cos(angle) * 15; bullet.velocityY = Math.sin(angle) * 15; bullet.damage = self.damage + damageBonus; bullets.push(bullet); game.addChild(bullet); } LK.getSound('shoot').play(); } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.effects.flashObject(self, 0xFF0000, 200); }; self.gainExperience = function (amount) { self.experience += amount; if (self.experience >= self.experienceToNext) { self.levelUp(); } }; self.levelUp = function () { self.level++; self.experience = 0; self.experienceToNext = Math.floor(self.experienceToNext * 1.5); LK.getSound('levelUp').play(); }; return self; }); var ScreenClearPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('screenClearPowerup', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { // Clear all enemies when powerup is collected for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var drop = new SmallEnemyDrop(); drop.x = enemy.x; drop.y = enemy.y; smallEnemyDrops.push(drop); game.addChild(drop); enemy.destroy(); enemies.splice(i, 1); } // Clear all bosses for (var i = bosses.length - 1; i >= 0; i--) { var boss = bosses[i]; var drop = new BigEnemyDrop(); drop.x = boss.x; drop.y = boss.y; bigEnemyDrops.push(drop); game.addChild(drop); boss.destroy(); bosses.splice(i, 1); } // Clear all spiders for (var i = spiders.length - 1; i >= 0; i--) { var spider = spiders[i]; var drop = new SpiderDrop(); drop.x = spider.x; drop.y = spider.y; spiderDrops.push(drop); game.addChild(drop); spider.destroy(); spiders.splice(i, 1); } // CircleBoss enemies are not affected by screen clear powerup LK.getSound('screenClear').play(); LK.effects.flashScreen(0xFFFFFF, 500); self.destroy(); for (var i = screenClearPowerups.length - 1; i >= 0; i--) { if (screenClearPowerups[i] === self) { screenClearPowerups.splice(i, 1); break; } } } }; return self; }); var ShieldPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('uniqueCircleBossDrop', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { // Activate shield activateShield(); self.destroy(); for (var i = shieldPowerups.length - 1; i >= 0; i--) { if (shieldPowerups[i] === self) { shieldPowerups.splice(i, 1); break; } } } }; return self; }); var SmallEnemyDrop = Container.expand(function () { var self = Container.call(this); var dropGraphics = self.attachAsset('experienceOrb', { anchorX: 0.5, anchorY: 0.5, tint: 0x00FF00 }); self.pointValue = 10; self.collectRadius = 50; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.collectRadius) { var moveSpeed = 8; self.x += dx / distance * moveSpeed; self.y += dy / distance * moveSpeed; if (distance < 30) { LK.setScore(LK.getScore() + self.pointValue); self.destroy(); for (var i = smallEnemyDrops.length - 1; i >= 0; i--) { if (smallEnemyDrops[i] === self) { smallEnemyDrops.splice(i, 1); break; } } } } }; return self; }); var Spider = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('spider', { anchorX: 0.5, anchorY: 0.5 }); self.health = 8; self.maxHealth = 8; self.speed = 3; // 1.5x faster than goblins (goblin speed is 2) self.damage = 10; self.experienceValue = 1; self.update = function () { if (powerUpActive) return; // Check if touching shield circle if (shieldActive && player.shieldCircle) { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 250) { // Shield circle radius self.die(); return; } } var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } if (distance < 50) { player.takeDamage(10); // Deal 10 damage when touching player self.destroy(); for (var i = spiders.length - 1; i >= 0; i--) { if (spiders[i] === self) { spiders.splice(i, 1); break; } } } }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 100); if (self.health <= 0) { self.die(); } }; self.die = function () { var drop = new SpiderDrop(); drop.x = self.x; drop.y = self.y; spiderDrops.push(drop); game.addChild(drop); LK.getSound('enemyHit').play(); self.destroy(); for (var i = spiders.length - 1; i >= 0; i--) { if (spiders[i] === self) { spiders.splice(i, 1); break; } } }; return self; }); var SpiderDrop = Container.expand(function () { var self = Container.call(this); var dropGraphics = self.attachAsset('spiderDrop', { anchorX: 0.5, anchorY: 0.5 }); self.pointValue = 15; self.collectRadius = 50; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.collectRadius) { var moveSpeed = 8; self.x += dx / distance * moveSpeed; self.y += dy / distance * moveSpeed; if (distance < 30) { LK.setScore(LK.getScore() + self.pointValue); self.destroy(); for (var i = spiderDrops.length - 1; i >= 0; i--) { if (spiderDrops[i] === self) { spiderDrops.splice(i, 1); break; } } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2E2E2E }); /**** * Game Code ****/ var player; var enemies = []; var bosses = []; var bullets = []; var enemyBullets = []; var experienceOrbs = []; var screenClearPowerups = []; var smallEnemyDrops = []; var bigEnemyDrops = []; var shieldEnemies = []; var shieldPowerups = []; var spiders = []; var spiderDrops = []; var shieldActive = false; var shieldTimer = 0; var shieldDuration = 300; // 5 seconds at 60fps var enemySpawnTimer = 0; var enemySpawnRate = 60; var bossSpawnTimer = 0; var bossSpawnInterval = 600; var screenClearCharges = 0; var dragNode = null; var powerUpActive = false; var powerUpUI = null; var bulletCount = 1; var fireRateBonus = 0; var damageBonus = 0; var powerUpsUsed = 0; // UI Elements var healthText = new Text2('Health: 100', { size: 40, fill: 0xFF4444 }); healthText.anchor.set(0, 0); LK.gui.topLeft.addChild(healthText); healthText.x = 120; healthText.y = 20; var levelText = new Text2('Level: 1', { size: 40, fill: 0x44FF44 }); levelText.anchor.set(0, 0); LK.gui.topRight.addChild(levelText); levelText.x = -200; levelText.y = 20; var scoreText = new Text2('0', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); scoreText.y = 80; function updateUI() { healthText.setText('Health: ' + player.health); levelText.setText('Level: ' + player.level); scoreText.setText(LK.getScore().toString()); } function showPowerUpUI() { powerUpActive = true; powerUpUI = new Container(); game.addChild(powerUpUI); var background = LK.getAsset('powerUpUIBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, alpha: 0.8 }); powerUpUI.addChild(background); var titleText = new Text2('POWER UP!', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1000; powerUpUI.addChild(titleText); var healthBtn = LK.getAsset('healthPowerUp', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 6, x: 700, y: 1366 }); powerUpUI.addChild(healthBtn); var healthText = new Text2('Health +10', { size: 50, fill: 0xFFFFFF }); healthText.anchor.set(0.5, 0.5); healthText.x = 700; healthText.y = 1500; powerUpUI.addChild(healthText); var bulletBtn = LK.getAsset('addBulletPowerUp', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 6, x: 1024, y: 1366 }); if (bulletCount >= 10) { bulletBtn.alpha = 0.3; } powerUpUI.addChild(bulletBtn); var bulletText = new Text2(bulletCount >= 10 ? 'Max Bullets' : 'Add Bullet', { size: 50, fill: bulletCount >= 10 ? 0x888888 : 0xFFFFFF }); bulletText.anchor.set(0.5, 0.5); bulletText.x = 1024; bulletText.y = 1500; powerUpUI.addChild(bulletText); var damageBtn = LK.getAsset('damagePowerUp', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 6, x: 1348, y: 1366 }); powerUpUI.addChild(damageBtn); var damageText = new Text2('Damage +5', { size: 50, fill: 0xFFFFFF }); damageText.anchor.set(0.5, 0.5); damageText.x = 1348; damageText.y = 1500; powerUpUI.addChild(damageText); healthBtn.down = function () { applyPowerUp('health'); }; bulletBtn.down = function () { if (bulletCount < 10) { applyPowerUp('bullet'); } }; damageBtn.down = function () { applyPowerUp('damage'); }; } function applyPowerUp(type) { if (type === 'health') { player.health = Math.min(player.maxHealth, player.health + 10); } else if (type === 'bullet') { bulletCount += 1; } else if (type === 'damage') { damageBonus += 5; } powerUpsUsed++; tween(powerUpUI, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { if (powerUpUI) { powerUpUI.destroy(); powerUpUI = null; } powerUpActive = false; } }); } function spawnEnemy() { var enemy = new Goblin(); var side = Math.floor(Math.random() * 4); if (side === 0) { // Top enemy.x = Math.random() * 2048; enemy.y = -50; } else if (side === 1) { // Right enemy.x = 2098; enemy.y = Math.random() * 2732; } else if (side === 2) { // Bottom enemy.x = Math.random() * 2048; enemy.y = 2782; } else { // Left enemy.x = -50; enemy.y = Math.random() * 2732; } enemies.push(enemy); game.addChild(enemy); } function spawnSpider() { var spider = new Spider(); var side = Math.floor(Math.random() * 4); if (side === 0) { // Top spider.x = Math.random() * 2048; spider.y = -50; } else if (side === 1) { // Right spider.x = 2098; spider.y = Math.random() * 2732; } else if (side === 2) { // Bottom spider.x = Math.random() * 2048; spider.y = 2782; } else { // Left spider.x = -50; spider.y = Math.random() * 2732; } spiders.push(spider); game.addChild(spider); } function spawnBoss() { var boss = new ClearBoss(); var side = Math.floor(Math.random() * 4); if (side === 0) { // Top boss.x = Math.random() * 2048; boss.y = -75; } else if (side === 1) { // Right boss.x = 2048 + 75; boss.y = Math.random() * 2732; } else if (side === 2) { // Bottom boss.x = Math.random() * 2048; boss.y = 2732 + 75; } else { // Left boss.x = -75; boss.y = Math.random() * 2732; } bosses.push(boss); game.addChild(boss); } function activateShield() { shieldActive = true; shieldTimer = 0; // Create visual shield circle around player player.shieldCircle = LK.getAsset('shieldCircle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); player.addChild(player.shieldCircle); // Animate shield appearance tween(player.shieldCircle, { alpha: 0.5, scaleX: 1.1, scaleY: 1.1 }, { duration: 300, onFinish: function onFinish() { tween(player.shieldCircle, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } function spawnShieldEnemy() { var enemy = new CircleBoss(); var side = Math.floor(Math.random() * 4); if (side === 0) { enemy.x = Math.random() * 2048; enemy.y = -50; } else if (side === 1) { enemy.x = 2098; enemy.y = Math.random() * 2732; } else if (side === 2) { enemy.x = Math.random() * 2048; enemy.y = 2782; } else { enemy.x = -50; enemy.y = Math.random() * 2732; } shieldEnemies.push(enemy); game.addChild(enemy); } function useScreenClear() { if (screenClearCharges > 0) { screenClearCharges--; LK.getSound('screenClear').play(); LK.effects.flashScreen(0xFFFFFF, 500); // Clear all enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var drop = new SmallEnemyDrop(); drop.x = enemy.x; drop.y = enemy.y; smallEnemyDrops.push(drop); game.addChild(drop); enemy.destroy(); enemies.splice(i, 1); } // Clear all bosses for (var i = bosses.length - 1; i >= 0; i--) { var boss = bosses[i]; var drop = new BigEnemyDrop(); drop.x = boss.x; drop.y = boss.y; bigEnemyDrops.push(drop); game.addChild(drop); boss.destroy(); bosses.splice(i, 1); } // Clear all spiders for (var i = spiders.length - 1; i >= 0; i--) { var spider = spiders[i]; var drop = new SpiderDrop(); drop.x = spider.x; drop.y = spider.y; spiderDrops.push(drop); game.addChild(drop); spider.destroy(); spiders.splice(i, 1); } // CircleBoss enemies are not affected by screen clear } } // Add background var background = LK.getAsset('backgroundAsset', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(background); // Initialize player player = new Player(); player.x = 1024; player.y = 1366; game.addChild(player); function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; // Keep player within bounds dragNode.x = Math.max(40, Math.min(2008, dragNode.x)); dragNode.y = Math.max(40, Math.min(2692, dragNode.y)); } } game.move = handleMove; game.down = function (x, y, obj) { // Check if clicking screen clear button area if (y < 150 && Math.abs(x - 1024) < 200) { useScreenClear(); } else { dragNode = player; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { // Update all game objects player.update(); if (!powerUpActive) { for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].update(); } } if (!powerUpActive) { for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].update(); } } if (!powerUpActive) { for (var i = bosses.length - 1; i >= 0; i--) { bosses[i].update(); } } for (var i = experienceOrbs.length - 1; i >= 0; i--) { experienceOrbs[i].update(); } for (var i = screenClearPowerups.length - 1; i >= 0; i--) { screenClearPowerups[i].update(); } for (var i = smallEnemyDrops.length - 1; i >= 0; i--) { smallEnemyDrops[i].update(); } for (var i = bigEnemyDrops.length - 1; i >= 0; i--) { bigEnemyDrops[i].update(); } for (var i = shieldEnemies.length - 1; i >= 0; i--) { shieldEnemies[i].update(); } for (var i = shieldPowerups.length - 1; i >= 0; i--) { shieldPowerups[i].update(); } for (var i = enemyBullets.length - 1; i >= 0; i--) { enemyBullets[i].update(); } if (!powerUpActive) { for (var i = spiders.length - 1; i >= 0; i--) { spiders[i].update(); } } for (var i = spiderDrops.length - 1; i >= 0; i--) { spiderDrops[i].update(); } // Handle shield timer if (shieldActive) { shieldTimer++; if (shieldTimer >= shieldDuration) { // Deactivate shield shieldActive = false; shieldTimer = 0; if (player.shieldCircle) { tween(player.shieldCircle, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { player.shieldCircle.destroy(); player.shieldCircle = null; } }); } } } // Bullet collision with enemies for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { enemy.takeDamage(bullet.damage); bullet.destroy(); bullets.splice(i, 1); break; } } if (bullets[i]) { for (var j = bosses.length - 1; j >= 0; j--) { var boss = bosses[j]; if (bullet.intersects(boss)) { boss.takeDamage(bullet.damage); bullet.destroy(); bullets.splice(i, 1); break; } } } // Bullet collision with shield enemies if (bullets[i]) { for (var j = shieldEnemies.length - 1; j >= 0; j--) { var shieldEnemy = shieldEnemies[j]; if (bullet.intersects(shieldEnemy)) { shieldEnemy.takeDamage(bullet.damage); bullet.destroy(); bullets.splice(i, 1); break; } } } // Bullet collision with spiders if (bullets[i]) { for (var j = spiders.length - 1; j >= 0; j--) { var spider = spiders[j]; if (bullet.intersects(spider)) { spider.takeDamage(bullet.damage); bullet.destroy(); bullets.splice(i, 1); break; } } } } // Spawn enemies enemySpawnTimer++; if (enemySpawnTimer >= enemySpawnRate) { // 30% chance to spawn spider, 70% chance to spawn goblin if (Math.random() < 0.3) { spawnSpider(); } else { spawnEnemy(); } enemySpawnTimer = 0; // Increase spawn rate over time if (enemySpawnRate > 20) { enemySpawnRate = Math.max(20, enemySpawnRate - 0.1); } } // Spawn bosses bossSpawnTimer++; if (bossSpawnTimer >= bossSpawnInterval && bosses.length === 0) { spawnBoss(); bossSpawnTimer = 0; } // Spawn shield enemies occasionally if (LK.ticks % 900 === 0 && shieldEnemies.length < 2) { // Every 15 seconds, but only if less than 2 CircleBoss on screen spawnShieldEnemy(); } // Check for power up every 500 points var nextPowerUpThreshold = (powerUpsUsed + 1) * 500; if (LK.getScore() >= nextPowerUpThreshold && !powerUpActive) { showPowerUpUI(); } updateUI(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BigEnemyDrop = Container.expand(function () {
var self = Container.call(this);
var dropGraphics = self.attachAsset('bigEnemyDropAsset', {
anchorX: 0.5,
anchorY: 0.5
});
self.pointValue = 50;
self.collectRadius = 50;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectRadius) {
var moveSpeed = 8;
self.x += dx / distance * moveSpeed;
self.y += dy / distance * moveSpeed;
if (distance < 30) {
LK.setScore(LK.getScore() + self.pointValue);
self.destroy();
for (var i = bigEnemyDrops.length - 1; i >= 0; i--) {
if (bigEnemyDrops[i] === self) {
bigEnemyDrops.splice(i, 1);
break;
}
}
}
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = 5;
self.lifespan = 0;
self.maxLifespan = 120;
self.update = function () {
if (powerUpActive) return;
self.x += self.velocityX;
self.y += self.velocityY;
self.lifespan++;
if (self.lifespan >= self.maxLifespan || self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var CircleBoss = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('uniqueCircleBoss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 80;
self.maxHealth = 80;
self.speed = 1.5;
self.damage = 20;
self.experienceValue = 2;
self.shootTimer = 0;
self.shootCooldown = 90;
self.update = function () {
if (powerUpActive) return;
// Check if touching shield circle
if (shieldActive && player.shieldCircle) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
// Shield circle radius
self.die();
return;
}
}
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Shooting logic
self.shootTimer++;
if (self.shootTimer >= self.shootCooldown && distance < 800 && distance > 100) {
self.shootAtPlayer();
self.shootTimer = 0;
}
if (distance < 50) {
player.takeDamage(15);
self.destroy();
for (var i = shieldEnemies.length - 1; i >= 0; i--) {
if (shieldEnemies[i] === self) {
shieldEnemies.splice(i, 1);
break;
}
}
}
};
self.shootAtPlayer = function () {
var bullet = new CircleBossBullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * 8;
bullet.velocityY = dy / distance * 8;
enemyBullets.push(bullet);
game.addChild(bullet);
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 100);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
var drop = new ShieldPowerup();
drop.x = self.x;
drop.y = self.y;
shieldPowerups.push(drop);
game.addChild(drop);
LK.getSound('enemyHit').play();
self.destroy();
for (var i = shieldEnemies.length - 1; i >= 0; i--) {
if (shieldEnemies[i] === self) {
shieldEnemies.splice(i, 1);
break;
}
}
};
return self;
});
var CircleBossBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('circleBossBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = 10;
self.lifespan = 0;
self.maxLifespan = 120;
self.update = function () {
if (powerUpActive) return;
self.x += self.velocityX;
self.y += self.velocityY;
self.lifespan++;
if (self.lifespan >= self.maxLifespan || self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.destroy();
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
}
// Check collision with player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
player.takeDamage(self.damage);
self.destroy();
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var ClearBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 80;
self.maxHealth = 80;
self.speed = 1;
self.damage = 50;
self.experienceValue = 10;
self.update = function () {
if (powerUpActive) return;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Deal damage when touching player (only once per collision)
if (distance < 80) {
if (!self.lastTouchingPlayer) {
player.takeDamage(50);
}
self.lastTouchingPlayer = true;
} else {
self.lastTouchingPlayer = false;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 150);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
// Create screen clear powerup - all big enemies drop this
var powerup = new ScreenClearPowerup();
powerup.x = self.x;
powerup.y = self.y;
screenClearPowerups.push(powerup);
game.addChild(powerup);
// Visual feedback for powerup drop
LK.effects.flashObject(powerup, 0xFF9800, 1000);
LK.getSound('bossDefeat').play();
// Remove from bosses array first, then destroy
for (var i = bosses.length - 1; i >= 0; i--) {
if (bosses[i] === self) {
bosses.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFF4444
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = 10;
self.lifespan = 0;
self.maxLifespan = 120;
self.update = function () {
if (powerUpActive) return;
self.x += self.velocityX;
self.y += self.velocityY;
self.lifespan++;
if (self.lifespan >= self.maxLifespan || self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.destroy();
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
}
// Check collision with player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
player.takeDamage(self.damage);
self.destroy();
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var ExperienceOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('experienceOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.experienceValue = 1;
self.collectRadius = 100;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectRadius) {
var moveSpeed = 8;
self.x += dx / distance * moveSpeed;
self.y += dy / distance * moveSpeed;
if (distance < 30) {
player.gainExperience(self.experienceValue);
self.destroy();
for (var i = experienceOrbs.length - 1; i >= 0; i--) {
if (experienceOrbs[i] === self) {
experienceOrbs.splice(i, 1);
break;
}
}
}
}
};
return self;
});
var Goblin = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 10;
self.maxHealth = 10;
self.speed = 2;
self.damage = 15;
self.experienceValue = 1;
self.update = function () {
if (powerUpActive) return;
// Check if touching shield circle
if (shieldActive && player.shieldCircle) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 250) {
// Shield circle radius
self.die();
return;
}
}
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
if (distance < 50) {
player.takeDamage(self.damage);
self.destroy();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 100);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
var drop = new SmallEnemyDrop();
drop.x = self.x;
drop.y = self.y;
smallEnemyDrops.push(drop);
game.addChild(drop);
LK.getSound('enemyHit').play();
self.destroy();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.experience = 0;
self.level = 1;
self.experienceToNext = 10;
self.shootTimer = 0;
self.shootCooldown = 30;
self.damage = 5;
self.speed = 8;
self.update = function () {
self.shootTimer++;
if (self.shootTimer >= self.shootCooldown) {
self.shootAtNearestEnemy();
self.shootTimer = 0;
}
};
self.shootAtNearestEnemy = function () {
// Can't shoot when shield is active
if (shieldActive) return;
var nearestEnemy = null;
var nearestDistance = Infinity;
// Check regular enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance && distance < 600) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
// Check bosses
for (var i = 0; i < bosses.length; i++) {
var boss = bosses[i];
var dx = boss.x - self.x;
var dy = boss.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance && distance < 600) {
nearestDistance = distance;
nearestEnemy = boss;
}
}
// Check shield enemies (CircleBoss)
for (var i = 0; i < shieldEnemies.length; i++) {
var shieldEnemy = shieldEnemies[i];
var dx = shieldEnemy.x - self.x;
var dy = shieldEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance && distance < 600) {
nearestDistance = distance;
nearestEnemy = shieldEnemy;
}
}
// Check spiders
for (var i = 0; i < spiders.length; i++) {
var spider = spiders[i];
var dx = spider.x - self.x;
var dy = spider.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance && distance < 600) {
nearestDistance = distance;
nearestEnemy = spider;
}
}
if (nearestEnemy) {
for (var b = 0; b < bulletCount; b++) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var spread = (b - (bulletCount - 1) / 2) * 0.2;
var angle = Math.atan2(dy, dx) + spread;
bullet.velocityX = Math.cos(angle) * 15;
bullet.velocityY = Math.sin(angle) * 15;
bullet.damage = self.damage + damageBonus;
bullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('shoot').play();
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
LK.effects.flashObject(self, 0xFF0000, 200);
};
self.gainExperience = function (amount) {
self.experience += amount;
if (self.experience >= self.experienceToNext) {
self.levelUp();
}
};
self.levelUp = function () {
self.level++;
self.experience = 0;
self.experienceToNext = Math.floor(self.experienceToNext * 1.5);
LK.getSound('levelUp').play();
};
return self;
});
var ScreenClearPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('screenClearPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
// Clear all enemies when powerup is collected
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var drop = new SmallEnemyDrop();
drop.x = enemy.x;
drop.y = enemy.y;
smallEnemyDrops.push(drop);
game.addChild(drop);
enemy.destroy();
enemies.splice(i, 1);
}
// Clear all bosses
for (var i = bosses.length - 1; i >= 0; i--) {
var boss = bosses[i];
var drop = new BigEnemyDrop();
drop.x = boss.x;
drop.y = boss.y;
bigEnemyDrops.push(drop);
game.addChild(drop);
boss.destroy();
bosses.splice(i, 1);
}
// Clear all spiders
for (var i = spiders.length - 1; i >= 0; i--) {
var spider = spiders[i];
var drop = new SpiderDrop();
drop.x = spider.x;
drop.y = spider.y;
spiderDrops.push(drop);
game.addChild(drop);
spider.destroy();
spiders.splice(i, 1);
}
// CircleBoss enemies are not affected by screen clear powerup
LK.getSound('screenClear').play();
LK.effects.flashScreen(0xFFFFFF, 500);
self.destroy();
for (var i = screenClearPowerups.length - 1; i >= 0; i--) {
if (screenClearPowerups[i] === self) {
screenClearPowerups.splice(i, 1);
break;
}
}
}
};
return self;
});
var ShieldPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('uniqueCircleBossDrop', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
// Activate shield
activateShield();
self.destroy();
for (var i = shieldPowerups.length - 1; i >= 0; i--) {
if (shieldPowerups[i] === self) {
shieldPowerups.splice(i, 1);
break;
}
}
}
};
return self;
});
var SmallEnemyDrop = Container.expand(function () {
var self = Container.call(this);
var dropGraphics = self.attachAsset('experienceOrb', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x00FF00
});
self.pointValue = 10;
self.collectRadius = 50;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectRadius) {
var moveSpeed = 8;
self.x += dx / distance * moveSpeed;
self.y += dy / distance * moveSpeed;
if (distance < 30) {
LK.setScore(LK.getScore() + self.pointValue);
self.destroy();
for (var i = smallEnemyDrops.length - 1; i >= 0; i--) {
if (smallEnemyDrops[i] === self) {
smallEnemyDrops.splice(i, 1);
break;
}
}
}
}
};
return self;
});
var Spider = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('spider', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 8;
self.maxHealth = 8;
self.speed = 3; // 1.5x faster than goblins (goblin speed is 2)
self.damage = 10;
self.experienceValue = 1;
self.update = function () {
if (powerUpActive) return;
// Check if touching shield circle
if (shieldActive && player.shieldCircle) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 250) {
// Shield circle radius
self.die();
return;
}
}
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
if (distance < 50) {
player.takeDamage(10); // Deal 10 damage when touching player
self.destroy();
for (var i = spiders.length - 1; i >= 0; i--) {
if (spiders[i] === self) {
spiders.splice(i, 1);
break;
}
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 100);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
var drop = new SpiderDrop();
drop.x = self.x;
drop.y = self.y;
spiderDrops.push(drop);
game.addChild(drop);
LK.getSound('enemyHit').play();
self.destroy();
for (var i = spiders.length - 1; i >= 0; i--) {
if (spiders[i] === self) {
spiders.splice(i, 1);
break;
}
}
};
return self;
});
var SpiderDrop = Container.expand(function () {
var self = Container.call(this);
var dropGraphics = self.attachAsset('spiderDrop', {
anchorX: 0.5,
anchorY: 0.5
});
self.pointValue = 15;
self.collectRadius = 50;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectRadius) {
var moveSpeed = 8;
self.x += dx / distance * moveSpeed;
self.y += dy / distance * moveSpeed;
if (distance < 30) {
LK.setScore(LK.getScore() + self.pointValue);
self.destroy();
for (var i = spiderDrops.length - 1; i >= 0; i--) {
if (spiderDrops[i] === self) {
spiderDrops.splice(i, 1);
break;
}
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E2E2E
});
/****
* Game Code
****/
var player;
var enemies = [];
var bosses = [];
var bullets = [];
var enemyBullets = [];
var experienceOrbs = [];
var screenClearPowerups = [];
var smallEnemyDrops = [];
var bigEnemyDrops = [];
var shieldEnemies = [];
var shieldPowerups = [];
var spiders = [];
var spiderDrops = [];
var shieldActive = false;
var shieldTimer = 0;
var shieldDuration = 300; // 5 seconds at 60fps
var enemySpawnTimer = 0;
var enemySpawnRate = 60;
var bossSpawnTimer = 0;
var bossSpawnInterval = 600;
var screenClearCharges = 0;
var dragNode = null;
var powerUpActive = false;
var powerUpUI = null;
var bulletCount = 1;
var fireRateBonus = 0;
var damageBonus = 0;
var powerUpsUsed = 0;
// UI Elements
var healthText = new Text2('Health: 100', {
size: 40,
fill: 0xFF4444
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 20;
var levelText = new Text2('Level: 1', {
size: 40,
fill: 0x44FF44
});
levelText.anchor.set(0, 0);
LK.gui.topRight.addChild(levelText);
levelText.x = -200;
levelText.y = 20;
var scoreText = new Text2('0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
scoreText.y = 80;
function updateUI() {
healthText.setText('Health: ' + player.health);
levelText.setText('Level: ' + player.level);
scoreText.setText(LK.getScore().toString());
}
function showPowerUpUI() {
powerUpActive = true;
powerUpUI = new Container();
game.addChild(powerUpUI);
var background = LK.getAsset('powerUpUIBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
alpha: 0.8
});
powerUpUI.addChild(background);
var titleText = new Text2('POWER UP!', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1000;
powerUpUI.addChild(titleText);
var healthBtn = LK.getAsset('healthPowerUp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 6,
x: 700,
y: 1366
});
powerUpUI.addChild(healthBtn);
var healthText = new Text2('Health +10', {
size: 50,
fill: 0xFFFFFF
});
healthText.anchor.set(0.5, 0.5);
healthText.x = 700;
healthText.y = 1500;
powerUpUI.addChild(healthText);
var bulletBtn = LK.getAsset('addBulletPowerUp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 6,
x: 1024,
y: 1366
});
if (bulletCount >= 10) {
bulletBtn.alpha = 0.3;
}
powerUpUI.addChild(bulletBtn);
var bulletText = new Text2(bulletCount >= 10 ? 'Max Bullets' : 'Add Bullet', {
size: 50,
fill: bulletCount >= 10 ? 0x888888 : 0xFFFFFF
});
bulletText.anchor.set(0.5, 0.5);
bulletText.x = 1024;
bulletText.y = 1500;
powerUpUI.addChild(bulletText);
var damageBtn = LK.getAsset('damagePowerUp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 6,
x: 1348,
y: 1366
});
powerUpUI.addChild(damageBtn);
var damageText = new Text2('Damage +5', {
size: 50,
fill: 0xFFFFFF
});
damageText.anchor.set(0.5, 0.5);
damageText.x = 1348;
damageText.y = 1500;
powerUpUI.addChild(damageText);
healthBtn.down = function () {
applyPowerUp('health');
};
bulletBtn.down = function () {
if (bulletCount < 10) {
applyPowerUp('bullet');
}
};
damageBtn.down = function () {
applyPowerUp('damage');
};
}
function applyPowerUp(type) {
if (type === 'health') {
player.health = Math.min(player.maxHealth, player.health + 10);
} else if (type === 'bullet') {
bulletCount += 1;
} else if (type === 'damage') {
damageBonus += 5;
}
powerUpsUsed++;
tween(powerUpUI, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
if (powerUpUI) {
powerUpUI.destroy();
powerUpUI = null;
}
powerUpActive = false;
}
});
}
function spawnEnemy() {
var enemy = new Goblin();
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
} else if (side === 1) {
// Right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
} else if (side === 2) {
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
} else {
// Left
enemy.x = -50;
enemy.y = Math.random() * 2732;
}
enemies.push(enemy);
game.addChild(enemy);
}
function spawnSpider() {
var spider = new Spider();
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// Top
spider.x = Math.random() * 2048;
spider.y = -50;
} else if (side === 1) {
// Right
spider.x = 2098;
spider.y = Math.random() * 2732;
} else if (side === 2) {
// Bottom
spider.x = Math.random() * 2048;
spider.y = 2782;
} else {
// Left
spider.x = -50;
spider.y = Math.random() * 2732;
}
spiders.push(spider);
game.addChild(spider);
}
function spawnBoss() {
var boss = new ClearBoss();
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// Top
boss.x = Math.random() * 2048;
boss.y = -75;
} else if (side === 1) {
// Right
boss.x = 2048 + 75;
boss.y = Math.random() * 2732;
} else if (side === 2) {
// Bottom
boss.x = Math.random() * 2048;
boss.y = 2732 + 75;
} else {
// Left
boss.x = -75;
boss.y = Math.random() * 2732;
}
bosses.push(boss);
game.addChild(boss);
}
function activateShield() {
shieldActive = true;
shieldTimer = 0;
// Create visual shield circle around player
player.shieldCircle = LK.getAsset('shieldCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
player.addChild(player.shieldCircle);
// Animate shield appearance
tween(player.shieldCircle, {
alpha: 0.5,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
onFinish: function onFinish() {
tween(player.shieldCircle, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
function spawnShieldEnemy() {
var enemy = new CircleBoss();
var side = Math.floor(Math.random() * 4);
if (side === 0) {
enemy.x = Math.random() * 2048;
enemy.y = -50;
} else if (side === 1) {
enemy.x = 2098;
enemy.y = Math.random() * 2732;
} else if (side === 2) {
enemy.x = Math.random() * 2048;
enemy.y = 2782;
} else {
enemy.x = -50;
enemy.y = Math.random() * 2732;
}
shieldEnemies.push(enemy);
game.addChild(enemy);
}
function useScreenClear() {
if (screenClearCharges > 0) {
screenClearCharges--;
LK.getSound('screenClear').play();
LK.effects.flashScreen(0xFFFFFF, 500);
// Clear all enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var drop = new SmallEnemyDrop();
drop.x = enemy.x;
drop.y = enemy.y;
smallEnemyDrops.push(drop);
game.addChild(drop);
enemy.destroy();
enemies.splice(i, 1);
}
// Clear all bosses
for (var i = bosses.length - 1; i >= 0; i--) {
var boss = bosses[i];
var drop = new BigEnemyDrop();
drop.x = boss.x;
drop.y = boss.y;
bigEnemyDrops.push(drop);
game.addChild(drop);
boss.destroy();
bosses.splice(i, 1);
}
// Clear all spiders
for (var i = spiders.length - 1; i >= 0; i--) {
var spider = spiders[i];
var drop = new SpiderDrop();
drop.x = spider.x;
drop.y = spider.y;
spiderDrops.push(drop);
game.addChild(drop);
spider.destroy();
spiders.splice(i, 1);
}
// CircleBoss enemies are not affected by screen clear
}
}
// Add background
var background = LK.getAsset('backgroundAsset', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Initialize player
player = new Player();
player.x = 1024;
player.y = 1366;
game.addChild(player);
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
// Keep player within bounds
dragNode.x = Math.max(40, Math.min(2008, dragNode.x));
dragNode.y = Math.max(40, Math.min(2692, dragNode.y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Check if clicking screen clear button area
if (y < 150 && Math.abs(x - 1024) < 200) {
useScreenClear();
} else {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
// Update all game objects
player.update();
if (!powerUpActive) {
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].update();
}
}
if (!powerUpActive) {
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].update();
}
}
if (!powerUpActive) {
for (var i = bosses.length - 1; i >= 0; i--) {
bosses[i].update();
}
}
for (var i = experienceOrbs.length - 1; i >= 0; i--) {
experienceOrbs[i].update();
}
for (var i = screenClearPowerups.length - 1; i >= 0; i--) {
screenClearPowerups[i].update();
}
for (var i = smallEnemyDrops.length - 1; i >= 0; i--) {
smallEnemyDrops[i].update();
}
for (var i = bigEnemyDrops.length - 1; i >= 0; i--) {
bigEnemyDrops[i].update();
}
for (var i = shieldEnemies.length - 1; i >= 0; i--) {
shieldEnemies[i].update();
}
for (var i = shieldPowerups.length - 1; i >= 0; i--) {
shieldPowerups[i].update();
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
enemyBullets[i].update();
}
if (!powerUpActive) {
for (var i = spiders.length - 1; i >= 0; i--) {
spiders[i].update();
}
}
for (var i = spiderDrops.length - 1; i >= 0; i--) {
spiderDrops[i].update();
}
// Handle shield timer
if (shieldActive) {
shieldTimer++;
if (shieldTimer >= shieldDuration) {
// Deactivate shield
shieldActive = false;
shieldTimer = 0;
if (player.shieldCircle) {
tween(player.shieldCircle, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
player.shieldCircle.destroy();
player.shieldCircle = null;
}
});
}
}
}
// Bullet collision with enemies
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
enemy.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
if (bullets[i]) {
for (var j = bosses.length - 1; j >= 0; j--) {
var boss = bosses[j];
if (bullet.intersects(boss)) {
boss.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Bullet collision with shield enemies
if (bullets[i]) {
for (var j = shieldEnemies.length - 1; j >= 0; j--) {
var shieldEnemy = shieldEnemies[j];
if (bullet.intersects(shieldEnemy)) {
shieldEnemy.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Bullet collision with spiders
if (bullets[i]) {
for (var j = spiders.length - 1; j >= 0; j--) {
var spider = spiders[j];
if (bullet.intersects(spider)) {
spider.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
}
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
// 30% chance to spawn spider, 70% chance to spawn goblin
if (Math.random() < 0.3) {
spawnSpider();
} else {
spawnEnemy();
}
enemySpawnTimer = 0;
// Increase spawn rate over time
if (enemySpawnRate > 20) {
enemySpawnRate = Math.max(20, enemySpawnRate - 0.1);
}
}
// Spawn bosses
bossSpawnTimer++;
if (bossSpawnTimer >= bossSpawnInterval && bosses.length === 0) {
spawnBoss();
bossSpawnTimer = 0;
}
// Spawn shield enemies occasionally
if (LK.ticks % 900 === 0 && shieldEnemies.length < 2) {
// Every 15 seconds, but only if less than 2 CircleBoss on screen
spawnShieldEnemy();
}
// Check for power up every 500 points
var nextPowerUpThreshold = (powerUpsUsed + 1) * 500;
if (LK.getScore() >= nextPowerUpThreshold && !powerUpActive) {
showPowerUpUI();
}
updateUI();
};
a witch with red head and purple hat.. pixel art. full body
pixel art goblin. In-Game asset. 2d. High contrast. No shadows
pixel art seraphim. In-Game asset. 2d. High contrast. No shadows
a background top down game pixel art desert. In-Game asset. 2d. High contrast. No shadows
purple fireball pixel art. In-Game asset. 2d. High contrast. No shadows
pixel art circle health button. In-Game asset. 2d. High contrast. No shadows
pixel art circle damage button with symbols and no letters. In-Game asset. 2d. High contrast. No shadows
pixel art circle bullet button. In-Game asset. 2d. High contrast. No shadows
pixel art green circle. In-Game asset. 2d. High contrast. No shadows
pixel art circle red. In-Game asset. 2d. High contrast. No shadows
a background top down game pixel art desert. night In-Game asset. 2d. High contrast. No shadows
pixel art old wizard boss. In-Game asset. 2d. High contrast. No shadows
pixel art circle brown. In-Game asset. 2d. High contrast. No shadows
fire shoot pixel art. In-Game asset. 2d. High contrast. No shadows
pixel art colorful spider sideview. In-Game asset. 2d. High contrast. No shadows
pixel art pink circle. In-Game asset. 2d. High contrast. No shadows