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