/****
* Classes
****/
var Boss = Container.expand(function (level) {
var self = Container.call(this);
var body = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff00ff
});
self.health = 250 + level * 150;
self.maxHealth = self.health;
self.speed = 2;
self.lastAttack = 0;
self.attackCooldown = 3000;
self.phase = 1;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Move towards player
if (player) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 200) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// Boss attacks
if (LK.ticks - self.lastAttack > self.attackCooldown) {
self.performAttack();
self.lastAttack = LK.ticks;
}
// Phase transitions
if (self.health < self.maxHealth * 0.5 && self.phase === 1) {
self.phase = 2;
self.attackCooldown = 2000;
body.tint = 0xff0000;
}
};
self.performAttack = function () {
var attack = Math.floor(Math.random() * 3);
switch (attack) {
case 0:
// Bullet spray
for (var i = 0; i < 8; i++) {
var angle = i / 8 * Math.PI * 2;
var bullet = new Bullet(20, 0xff0000, 6);
bullet.x = self.x;
bullet.y = self.y;
bullet.velocityX = Math.cos(angle) * bullet.speed;
bullet.velocityY = Math.sin(angle) * bullet.speed;
enemyBullets.push(bullet);
game.addChild(bullet);
}
break;
case 1:
// Laser beam
if (player) {
var laser = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff0000
});
var angle = Math.atan2(player.y - self.y, player.x - self.x);
laser.rotation = angle;
LK.setTimeout(function () {
laser.destroy();
}, 1000);
}
break;
case 2:
// Summon minions
for (var i = 0; i < 3; i++) {
var minion = new Enemy('normal', currentLevel);
minion.x = self.x + (Math.random() - 0.5) * 200;
minion.y = self.y + (Math.random() - 0.5) * 200;
enemies.push(minion);
game.addChild(minion);
}
break;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
createExplosion(self.x, self.y, 300);
LK.setScore(LK.getScore() + 1000);
bossMode = false;
self.destroy();
};
return self;
});
var Bullet = Container.expand(function (damage, color, speed, abilities) {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: color || 0xffff00
});
self.damage = damage || 10;
self.speed = speed || 12;
self.abilities = abilities || {};
self.bounceCount = 0;
self.maxBounces = 3;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.y += self.velocityY;
self.x += self.velocityX;
// Bouncing bullets
if (self.abilities.bouncingBullets && self.bounceCount < self.maxBounces) {
if (self.x < 0 || self.x > 2048) {
self.velocityX *= -1;
self.bounceCount++;
}
if (self.y < 0 || self.y > 2732) {
self.velocityY *= -1;
self.bounceCount++;
}
}
// Remove bullet if out of bounds
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
}
};
return self;
});
var Character = Container.expand(function (characterType) {
var self = Container.call(this);
var characterData = characters[characterType] || characters.normal;
var body = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
tint: characterData.color
});
self.characterType = characterType;
self.health = characterData.health || 100;
self.maxHealth = self.health;
self.bulletSpeed = characterData.bulletSpeed;
self.bulletDamage = characterData.bulletDamage;
self.bulletColor = characterData.bulletColor;
self.speed = 8;
self.lastShot = 0;
self.shootCooldown = 200;
self.rageMode = false;
self.rageMeter = 0;
self.invincible = false;
// Special abilities
self.abilities = {
trackingBullets: characterData.trackingBullets || false,
spreadShot: characterData.spreadShot || false,
piercing: characterData.piercing || false,
explosiveShot: characterData.explosiveShot || false,
rapidFire: characterData.rapidFire || false,
timeControl: characterData.timeControl || false,
teleport: characterData.teleport || false,
invisibility: characterData.invisibility || false
};
self.activateRage = function () {
if (self.rageMeter >= 100) {
self.rageMode = true;
self.rageMeter = 0;
body.tint = 0xffff00;
self.scale.set(1.5, 1.5);
LK.setTimeout(function () {
self.rageMode = false;
body.tint = characterData.color;
self.scale.set(1, 1);
}, 10000);
}
};
return self;
});
var Enemy = Container.expand(function (enemyType, level) {
var self = Container.call(this);
var enemyData = enemyTypes[enemyType] || enemyTypes.normal;
var body = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
tint: enemyData.color,
scaleX: enemyData.sizeMod || 1,
scaleY: enemyData.sizeMod || 1
});
self.enemyType = enemyType;
self.health = (30 + level * 10) * (enemyData.healthMod || 1);
self.maxHealth = self.health;
self.speed = (3 + level * 0.5) * (enemyData.speedMod || 1);
self.dodgeChance = enemyData.dodgeChance || 0;
self.lastDodge = 0;
self.isDodging = false;
self.dodgeDirection = {
x: 0,
y: 0
};
self.stunned = false;
self.lastStun = 0;
self.stunDuration = 0;
self.lastShot = 0;
self.lastX = self.x;
self.lastY = self.y;
// Special abilities
self.canShoot = enemyData.canShoot || false;
self.shootRange = enemyData.shootRange || 300;
self.shootCooldown = enemyData.shootCooldown || 2000;
self.explodeOnDeath = enemyData.explodeOnDeath || false;
self.splitOnDeath = enemyData.splitOnDeath || false;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
if (self.stunned && LK.ticks - self.lastStun < self.stunDuration) {
return;
}
if (self.stunned) {
self.stunned = false;
body.tint = enemyData.color;
}
// Move towards player
if (player && !self.isDodging) {
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;
}
}
// Dodge bullets
if (Math.random() < self.dodgeChance && LK.ticks - self.lastDodge > 60) {
self.isDodging = true;
self.lastDodge = LK.ticks;
self.dodgeDirection.x = (Math.random() - 0.5) * 2;
self.dodgeDirection.y = (Math.random() - 0.5) * 2;
LK.setTimeout(function () {
self.isDodging = false;
}, 500);
}
if (self.isDodging) {
self.x += self.dodgeDirection.x * self.speed;
self.y += self.dodgeDirection.y * self.speed;
}
// Enemy shooting
if (self.canShoot && player && LK.ticks - self.lastShot > self.shootCooldown) {
var distance = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distance < self.shootRange) {
self.shoot();
self.lastShot = LK.ticks;
}
}
// Keep enemy on screen
self.x = Math.max(30, Math.min(2018, self.x));
self.y = Math.max(30, Math.min(2702, self.y));
};
self.shoot = function () {
if (player) {
var bullet = new Bullet(15, 0xff0000, 8);
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 * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
enemyBullets.push(bullet);
game.addChild(bullet);
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
if (self.explodeOnDeath) {
createExplosion(self.x, self.y, 150);
}
if (self.splitOnDeath) {
for (var i = 0; i < 3; i++) {
var childEnemy = new Enemy('normal', currentLevel);
childEnemy.x = self.x + (Math.random() - 0.5) * 100;
childEnemy.y = self.y + (Math.random() - 0.5) * 100;
childEnemy.scale.set(0.6, 0.6);
enemies.push(childEnemy);
game.addChild(childEnemy);
}
}
// Drop power-ups
if (Math.random() < 0.3) {
createPowerUp(self.x, self.y);
}
LK.getSound('explosion').play();
self.destroy();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d572c
});
/****
* Game Code
****/
// UI Elements
var healthText = new Text2('Health: 100', {
size: 40,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
var scoreText = new Text2('Score: 0', {
size: 40,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var bulletText = new Text2('Bullets: 100', {
size: 30,
fill: 0xFFFF00
});
bulletText.anchor.set(0, 0);
bulletText.y = 50;
LK.gui.topLeft.addChild(bulletText);
var laserText = new Text2('Laser: 100%', {
size: 30,
fill: 0x00FFFF
});
laserText.anchor.set(0, 0);
laserText.y = 90;
LK.gui.topLeft.addChild(laserText);
var levelText = new Text2('Level: 1', {
size: 50,
fill: 0xFFD700
});
levelText.anchor.set(1, 0);
LK.gui.topRight.addChild(levelText);
var rageText = new Text2('RAGE MODE!', {
size: 60,
fill: 0xFF0000
});
rageText.anchor.set(0.5, 0.5);
rageText.visible = false;
LK.gui.center.addChild(rageText);
var characters = {
normal: {
name: "Normal",
color: 0x0055ff,
bulletSpeed: 1.0,
bulletDamage: 10,
bulletColor: 0xffff00,
health: 100
},
laserMaster: {
name: "Laser Master",
color: 0xff00ff,
bulletSpeed: 0.8,
bulletDamage: 5,
bulletColor: 0xff00ff,
health: 100,
superLaser: true
},
ranged: {
name: "Ranged",
color: 0xff5500,
bulletSpeed: 1.2,
bulletDamage: 8,
bulletColor: 0xff5500,
health: 100,
trackingBullets: true
},
close: {
name: "Close Combat",
color: 0x00ff55,
bulletSpeed: 0.8,
bulletDamage: 15,
bulletColor: 0x00ff55,
health: 100,
spreadShot: true
},
sniper: {
name: "Sniper",
color: 0x9900ff,
bulletSpeed: 2.0,
bulletDamage: 25,
bulletColor: 0x9900ff,
health: 100,
piercing: true
},
explosive: {
name: "Explosive",
color: 0xff0000,
bulletSpeed: 0.7,
bulletDamage: 12,
bulletColor: 0xff0000,
health: 100,
explosiveShot: true
},
rapid: {
name: "Rapid Fire",
color: 0x00ffff,
bulletSpeed: 1.5,
bulletDamage: 5,
bulletColor: 0x00ffff,
health: 100,
rapidFire: true,
bouncingBullets: true
},
timemaster: {
name: "Time Master",
color: 0x00ffcc,
bulletSpeed: 1.2,
bulletDamage: 15,
bulletColor: 0x00ffcc,
health: 100,
timeControl: true
},
teleporter: {
name: "Teleporter",
color: 0xff00ff,
bulletSpeed: 1.3,
bulletDamage: 12,
bulletColor: 0xff00ff,
health: 100,
teleport: true
},
shadow: {
name: "Shadow Warrior",
color: 0x4a0080,
bulletSpeed: 1.6,
bulletDamage: 15,
bulletColor: 0x800080,
health: 100,
invisibility: true
},
shocktank: {
name: "Shock Tank",
color: 0x4169e1,
bulletSpeed: 0.7,
bulletDamage: 25,
bulletColor: 0x4682b4,
health: 150,
shockwave: true
},
ultimate: {
name: "Ultimate",
color: 0xffd700,
bulletSpeed: 1.8,
bulletDamage: 20,
bulletColor: 0xffd700,
health: 150,
trackingBullets: true,
spreadShot: true,
piercing: true,
explosiveShot: true,
rapidFire: true,
bouncingBullets: true
}
};
// Start game
if (!gameStarted) {
showCharacterSelect();
}
var enemyTypes = {
normal: {
color: 0xff3333,
speedMod: 1.0,
healthMod: 1.0,
dodgeChance: 0.1,
sizeMod: 1.0
},
fast: {
color: 0x33ff33,
speedMod: 1.5,
healthMod: 0.8,
dodgeChance: 0.3,
sizeMod: 0.8
},
tank: {
color: 0x3333ff,
speedMod: 0.6,
healthMod: 2.0,
dodgeChance: 0.05,
sizeMod: 1.5
},
bomber: {
color: 0xff6600,
speedMod: 1.2,
healthMod: 0.7,
dodgeChance: 0.1,
sizeMod: 1.0,
explodeOnDeath: true
},
sniper: {
color: 0x9900ff,
speedMod: 0.7,
healthMod: 1.0,
dodgeChance: 0.4,
sizeMod: 1.0,
canShoot: true,
shootRange: 400,
shootCooldown: 2000
},
splitter: {
color: 0x00ffaa,
speedMod: 0.9,
healthMod: 1.2,
dodgeChance: 0.2,
sizeMod: 1.2,
splitOnDeath: true
},
elite: {
color: 0xffa500,
speedMod: 1.1,
healthMod: 1.8,
dodgeChance: 0.3,
sizeMod: 1.4
}
};
var currentLevel = 1;
var levelData = {
1: {
enemySpeed: 3,
enemyHealth: 30,
bossHealth: 250,
backgroundColor: 0x2d572c
},
2: {
enemySpeed: 4,
enemyHealth: 40,
bossHealth: 400,
backgroundColor: 0x654321
},
3: {
enemySpeed: 5,
enemyHealth: 50,
bossHealth: 550,
backgroundColor: 0x808080
},
4: {
enemySpeed: 6,
enemyHealth: 60,
bossHealth: 700,
backgroundColor: 0x800080
},
5: {
enemySpeed: 7,
enemyHealth: 70,
bossHealth: 850,
backgroundColor: 0xff4500
}
};
var player = null;
var bullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
var selectedCharacter = 'normal';
var bossMode = false;
var gameStarted = false;
var bulletCount = 100;
var laserCharge = 100;
var rageMeter = 0;
var rageActive = false;
var health = 100;
var shieldActive = false;
var enemySpawnTimer = 0;
var lastPowerUpSpawn = 0;
function showCharacterSelect() {
var selectContainer = new Container();
selectContainer.x = 1024;
selectContainer.y = 1366;
var titleText = new Text2('SELECT CHARACTER', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -400;
selectContainer.addChild(titleText);
var characterKeys = Object.keys(characters);
var buttonsPerRow = 3;
var buttonWidth = 300;
var buttonHeight = 150;
var spacing = 50;
for (var i = 0; i < characterKeys.length; i++) {
var key = characterKeys[i];
var _char = characters[key];
var row = Math.floor(i / buttonsPerRow);
var col = i % buttonsPerRow;
var button = new Container();
button.x = (col - 1) * (buttonWidth + spacing);
button.y = (row - 1) * (buttonHeight + spacing);
var buttonBg = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 2,
tint: _char.color
});
button.addChild(buttonBg);
var buttonText = new Text2(_char.name, {
size: 30,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.characterKey = key;
button.interactive = true;
button.down = function () {
selectedCharacter = this.characterKey;
startGame();
};
selectContainer.addChild(button);
}
game.addChild(selectContainer);
}
function startGame() {
gameStarted = true;
game.removeChildren();
// Create player
player = new Character(selectedCharacter);
player.x = 1024;
player.y = 1366;
game.addChild(player);
// Start background music
LK.playMusic('background');
// Initialize enemy spawn timer
enemySpawnTimer = 0;
lastPowerUpSpawn = 0;
// Update UI
updateUI();
}
function updateUI() {
healthText.setText('Health: ' + health);
scoreText.setText('Score: ' + LK.getScore());
bulletText.setText('Bullets: ' + bulletCount);
laserText.setText('Laser: ' + laserCharge + '%');
levelText.setText('Level: ' + currentLevel);
rageText.visible = rageActive;
}
function createPowerUp(x, y) {
var powerUp = new Container();
powerUp.x = x;
powerUp.y = y;
var types = ['health', 'bullets', 'laser', 'rage'];
var type = types[Math.floor(Math.random() * types.length)];
var colors = {
health: 0xff0000,
bullets: 0xffff00,
laser: 0x00ffff,
rage: 0xff00ff
};
var powerUpGraphics = powerUp.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
tint: colors[type]
});
powerUp.powerUpType = type;
powerUp.lastY = y;
powerUps.push(powerUp);
game.addChild(powerUp);
// Remove after 10 seconds
LK.setTimeout(function () {
if (powerUps.indexOf(powerUp) !== -1) {
powerUps.splice(powerUps.indexOf(powerUp), 1);
powerUp.destroy();
}
}, 10000);
}
function createExplosion(x, y, size) {
var explosion = new Container();
explosion.x = x;
explosion.y = y;
var explosionGraphics = explosion.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 120,
scaleY: size / 120
});
game.addChild(explosion);
LK.getSound('explosion').play();
// Animate explosion
tween.to(explosionGraphics, {
alpha: 0,
scaleX: explosionGraphics.scaleX * 2,
scaleY: explosionGraphics.scaleY * 2
}, 500).onComplete(function () {
explosion.destroy();
});
// Damage nearby enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - x, 2) + Math.pow(enemy.y - y, 2));
if (distance < size) {
enemy.takeDamage(30);
}
}
// Damage player if close
if (player) {
var playerDistance = Math.sqrt(Math.pow(player.x - x, 2) + Math.pow(player.y - y, 2));
if (playerDistance < size && !player.invincible) {
health -= 20;
if (health <= 0) {
gameOver();
}
}
}
}
function spawnEnemy() {
var availableTypes = ['normal', 'fast'];
if (currentLevel >= 2) availableTypes.push('tank', 'bomber');
if (currentLevel >= 3) availableTypes.push('sniper', 'splitter');
if (currentLevel >= 4) availableTypes.push('elite');
var type = availableTypes[Math.floor(Math.random() * availableTypes.length)];
var enemy = new Enemy(type, currentLevel);
// Spawn from edges
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// Right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
break;
case 2:
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
break;
case 3:
// Left
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
enemies.push(enemy);
game.addChild(enemy);
}
function spawnBoss() {
bossMode = true;
// Clear existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
var boss = new Boss(currentLevel);
boss.x = 1024;
boss.y = 300;
enemies.push(boss);
game.addChild(boss);
}
function gameOver() {
gameStarted = false;
LK.stopMusic();
var gameOverText = new Text2('GAME OVER', {
size: 100,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 1024;
gameOverText.y = 1366;
game.addChild(gameOverText);
var finalScoreText = new Text2('Final Score: ' + LK.getScore(), {
size: 50,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 1024;
finalScoreText.y = 1466;
game.addChild(finalScoreText);
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
}
function findClosestEnemy() {
if (!player || enemies.length === 0) return null;
var closest = null;
var minDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - player.x, 2) + Math.pow(enemy.y - player.y, 2));
if (distance < minDistance) {
minDistance = distance;
closest = enemy;
}
}
return closest;
}
function shootBullet() {
if (!player || bulletCount <= 0) return;
var _char2 = characters[selectedCharacter];
bulletCount--;
if (_char2.spreadShot) {
// Spread shot
for (var i = -1; i <= 1; i++) {
var bullet = new Bullet(_char2.bulletDamage, _char2.bulletColor, _char2.bulletSpeed * 12, _char2);
bullet.x = player.x;
bullet.y = player.y - 40;
bullet.velocityX = i * 3;
bullet.velocityY = -bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
} else if (_char2.trackingBullets) {
// Tracking bullets
var target = findClosestEnemy();
if (target) {
var bullet = new Bullet(_char2.bulletDamage, _char2.bulletColor, _char2.bulletSpeed * 12, _char2);
bullet.x = player.x;
bullet.y = player.y - 40;
var dx = target.x - bullet.x;
var dy = target.y - bullet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
} else {
// Normal shot
var bullet = new Bullet(_char2.bulletDamage, _char2.bulletColor, _char2.bulletSpeed * 12, _char2);
bullet.x = player.x;
bullet.y = player.y - 40;
bullet.velocityX = 0;
bullet.velocityY = -bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('shoot').play();
rageMeter = Math.min(100, rageMeter + 5);
if (rageMeter >= 100 && !rageActive) {
player.activateRage();
rageActive = true;
}
}
function fireLaser() {
if (!player || laserCharge <= 0) return;
var laser = new Container();
laser.x = player.x;
laser.y = player.y - 40;
var laserGraphics = laser.attachAsset('laser', {
anchorX: 0.5,
anchorY: 1,
tint: 0x00ffff
});
game.addChild(laser);
LK.getSound('laser').play();
// Damage enemies in laser path
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (Math.abs(enemy.x - laser.x) < 40 && enemy.y < laser.y) {
enemy.takeDamage(50);
}
}
laserCharge -= 20;
LK.setTimeout(function () {
laser.destroy();
}, 200);
}
// Touch controls
var moveDirection = {
x: 0,
y: 0
};
var shooting = false;
var lastShot = 0;
var laserActive = false;
game.down = function (x, y) {
if (!gameStarted) return;
// Check if touching shoot area (right side)
if (x > 1536) {
shooting = true;
} else if (x > 1024 && y > 2300) {
// Laser button area (bottom right)
laserActive = true;
} else {
// Movement area (left side)
if (player) {
moveDirection.x = (x - player.x) * 0.1;
moveDirection.y = (y - player.y) * 0.1;
}
}
};
game.move = function (x, y) {
if (!gameStarted) return;
if (x <= 1536 && player) {
moveDirection.x = (x - player.x) * 0.1;
moveDirection.y = (y - player.y) * 0.1;
}
};
game.up = function () {
shooting = false;
laserActive = false;
moveDirection = {
x: 0,
y: 0
};
};
// Add keyboard state tracking
var keyState = {
w: false,
a: false,
s: false,
d: false,
space: false,
e: false
};
// Keyboard event listeners
LK.on('keydown', function (key) {
keyState[key] = true;
});
LK.on('keyup', function (key) {
keyState[key] = false;
});
game.update = function () {
if (!gameStarted) return;
// Player movement
if (player) {
// Keyboard movement
if (keyState.w) player.y -= 8;
if (keyState.s) player.y += 8;
if (keyState.a) player.x -= 8;
if (keyState.d) player.x += 8;
// Touch movement
player.x += moveDirection.x;
player.y += moveDirection.y;
// Keep player on screen
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Auto-shoot if touching shoot area or pressing space
if ((shooting || keyState.space) && LK.ticks - lastShot > 10) {
shootBullet();
lastShot = LK.ticks;
}
// Laser controls
if ((laserActive || keyState.e) && LK.ticks % 5 === 0) {
fireLaser();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
var bulletHit = false;
// Check collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
var damageAmount = bullet.damage * (rageActive ? 2 : 1);
enemy.takeDamage(damageAmount);
// Explosive bullets
if (bullet.abilities.explosiveShot) {
createExplosion(bullet.x, bullet.y, 100);
}
// Piercing bullets don't get destroyed
if (!bullet.abilities.piercing) {
bullet.destroy();
bullets.splice(i, 1);
bulletHit = true;
}
if (enemy.health <= 0) {
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 10);
rageMeter = Math.min(100, rageMeter + 10);
}
if (bulletHit) break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check collision with player
if (player && bullet.intersects(player) && !player.invincible) {
health -= 10;
bullet.destroy();
enemyBullets.splice(i, 1);
if (health <= 0) {
gameOver();
}
}
// Remove if off screen
if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check collision with player
if (player && powerUp.intersects(player)) {
switch (powerUp.powerUpType) {
case 'health':
health = Math.min(100, health + 25);
break;
case 'bullets':
bulletCount = Math.min(999, bulletCount + 50);
break;
case 'laser':
laserCharge = Math.min(100, laserCharge + 30);
break;
case 'rage':
rageMeter = Math.min(100, rageMeter + 50);
break;
}
LK.getSound('powerup').play();
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Enemy collision with player
if (player && !player.invincible) {
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (enemy.intersects(player)) {
health -= 1;
LK.effects.flashObject(player, 0xff0000, 100);
if (health <= 0) {
gameOver();
}
}
}
}
// Spawn enemies
if (enemySpawnTimer > 0) {
enemySpawnTimer--;
} else {
if (enemies.length < 15 && !bossMode) {
spawnEnemy();
enemySpawnTimer = 60 - currentLevel * 5;
}
}
// Spawn power-ups
if (LK.ticks - lastPowerUpSpawn > 900) {
// Every 15 seconds
var x = Math.random() * 1800 + 124;
var y = Math.random() * 1800 + 466;
createPowerUp(x, y);
lastPowerUpSpawn = LK.ticks;
}
// Check for boss spawn
if (!bossMode && enemies.length === 0 && LK.getScore() >= currentLevel * 100) {
spawnBoss();
}
// Level progression
if (bossMode && enemies.length === 0) {
currentLevel++;
if (currentLevel > 5) {
// Victory!
LK.showYouWin();
} else {
bossMode = false;
game.setBackgroundColor(levelData[currentLevel].backgroundColor);
}
}
// Regenerate resources over time
if (LK.ticks % 60 === 0) {
// Every second
bulletCount = Math.min(999, bulletCount + 2);
laserCharge = Math.min(100, laserCharge + 1);
if (rageActive) {
rageMeter = Math.max(0, rageMeter - 2);
if (rageMeter <= 0) {
rageActive = false;
}
}
}
// Update UI
updateUI();
// Create mobile control UI elements
if (LK.ticks === 1) {
// Shoot button
var shootButtonBg = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xff0000,
alpha: 0.3
});
shootButtonBg.x = 1700;
shootButtonBg.y = 2400;
LK.gui.center.addChild(shootButtonBg);
// Laser button
var laserButtonBg = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x00ffff,
alpha: 0.3
});
laserButtonBg.x = 1900;
laserButtonBg.y = 2400;
LK.gui.center.addChild(laserButtonBg);
// Movement area indicator
var moveArea = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 12,
tint: 0x555555,
alpha: 0.1
});
moveArea.x = 400;
moveArea.y = 1366;
LK.gui.center.addChild(moveArea);
}
}; /****
* Classes
****/
var Boss = Container.expand(function (level) {
var self = Container.call(this);
var body = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff00ff
});
self.health = 250 + level * 150;
self.maxHealth = self.health;
self.speed = 2;
self.lastAttack = 0;
self.attackCooldown = 3000;
self.phase = 1;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Move towards player
if (player) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 200) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// Boss attacks
if (LK.ticks - self.lastAttack > self.attackCooldown) {
self.performAttack();
self.lastAttack = LK.ticks;
}
// Phase transitions
if (self.health < self.maxHealth * 0.5 && self.phase === 1) {
self.phase = 2;
self.attackCooldown = 2000;
body.tint = 0xff0000;
}
};
self.performAttack = function () {
var attack = Math.floor(Math.random() * 3);
switch (attack) {
case 0:
// Bullet spray
for (var i = 0; i < 8; i++) {
var angle = i / 8 * Math.PI * 2;
var bullet = new Bullet(20, 0xff0000, 6);
bullet.x = self.x;
bullet.y = self.y;
bullet.velocityX = Math.cos(angle) * bullet.speed;
bullet.velocityY = Math.sin(angle) * bullet.speed;
enemyBullets.push(bullet);
game.addChild(bullet);
}
break;
case 1:
// Laser beam
if (player) {
var laser = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff0000
});
var angle = Math.atan2(player.y - self.y, player.x - self.x);
laser.rotation = angle;
LK.setTimeout(function () {
laser.destroy();
}, 1000);
}
break;
case 2:
// Summon minions
for (var i = 0; i < 3; i++) {
var minion = new Enemy('normal', currentLevel);
minion.x = self.x + (Math.random() - 0.5) * 200;
minion.y = self.y + (Math.random() - 0.5) * 200;
enemies.push(minion);
game.addChild(minion);
}
break;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
createExplosion(self.x, self.y, 300);
LK.setScore(LK.getScore() + 1000);
bossMode = false;
self.destroy();
};
return self;
});
var Bullet = Container.expand(function (damage, color, speed, abilities) {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: color || 0xffff00
});
self.damage = damage || 10;
self.speed = speed || 12;
self.abilities = abilities || {};
self.bounceCount = 0;
self.maxBounces = 3;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.y += self.velocityY;
self.x += self.velocityX;
// Bouncing bullets
if (self.abilities.bouncingBullets && self.bounceCount < self.maxBounces) {
if (self.x < 0 || self.x > 2048) {
self.velocityX *= -1;
self.bounceCount++;
}
if (self.y < 0 || self.y > 2732) {
self.velocityY *= -1;
self.bounceCount++;
}
}
// Remove bullet if out of bounds
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
}
};
return self;
});
var Character = Container.expand(function (characterType) {
var self = Container.call(this);
var characterData = characters[characterType] || characters.normal;
var body = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
tint: characterData.color
});
self.characterType = characterType;
self.health = characterData.health || 100;
self.maxHealth = self.health;
self.bulletSpeed = characterData.bulletSpeed;
self.bulletDamage = characterData.bulletDamage;
self.bulletColor = characterData.bulletColor;
self.speed = 8;
self.lastShot = 0;
self.shootCooldown = 200;
self.rageMode = false;
self.rageMeter = 0;
self.invincible = false;
// Special abilities
self.abilities = {
trackingBullets: characterData.trackingBullets || false,
spreadShot: characterData.spreadShot || false,
piercing: characterData.piercing || false,
explosiveShot: characterData.explosiveShot || false,
rapidFire: characterData.rapidFire || false,
timeControl: characterData.timeControl || false,
teleport: characterData.teleport || false,
invisibility: characterData.invisibility || false
};
self.activateRage = function () {
if (self.rageMeter >= 100) {
self.rageMode = true;
self.rageMeter = 0;
body.tint = 0xffff00;
self.scale.set(1.5, 1.5);
LK.setTimeout(function () {
self.rageMode = false;
body.tint = characterData.color;
self.scale.set(1, 1);
}, 10000);
}
};
return self;
});
var Enemy = Container.expand(function (enemyType, level) {
var self = Container.call(this);
var enemyData = enemyTypes[enemyType] || enemyTypes.normal;
var body = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
tint: enemyData.color,
scaleX: enemyData.sizeMod || 1,
scaleY: enemyData.sizeMod || 1
});
self.enemyType = enemyType;
self.health = (30 + level * 10) * (enemyData.healthMod || 1);
self.maxHealth = self.health;
self.speed = (3 + level * 0.5) * (enemyData.speedMod || 1);
self.dodgeChance = enemyData.dodgeChance || 0;
self.lastDodge = 0;
self.isDodging = false;
self.dodgeDirection = {
x: 0,
y: 0
};
self.stunned = false;
self.lastStun = 0;
self.stunDuration = 0;
self.lastShot = 0;
self.lastX = self.x;
self.lastY = self.y;
// Special abilities
self.canShoot = enemyData.canShoot || false;
self.shootRange = enemyData.shootRange || 300;
self.shootCooldown = enemyData.shootCooldown || 2000;
self.explodeOnDeath = enemyData.explodeOnDeath || false;
self.splitOnDeath = enemyData.splitOnDeath || false;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
if (self.stunned && LK.ticks - self.lastStun < self.stunDuration) {
return;
}
if (self.stunned) {
self.stunned = false;
body.tint = enemyData.color;
}
// Move towards player
if (player && !self.isDodging) {
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;
}
}
// Dodge bullets
if (Math.random() < self.dodgeChance && LK.ticks - self.lastDodge > 60) {
self.isDodging = true;
self.lastDodge = LK.ticks;
self.dodgeDirection.x = (Math.random() - 0.5) * 2;
self.dodgeDirection.y = (Math.random() - 0.5) * 2;
LK.setTimeout(function () {
self.isDodging = false;
}, 500);
}
if (self.isDodging) {
self.x += self.dodgeDirection.x * self.speed;
self.y += self.dodgeDirection.y * self.speed;
}
// Enemy shooting
if (self.canShoot && player && LK.ticks - self.lastShot > self.shootCooldown) {
var distance = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distance < self.shootRange) {
self.shoot();
self.lastShot = LK.ticks;
}
}
// Keep enemy on screen
self.x = Math.max(30, Math.min(2018, self.x));
self.y = Math.max(30, Math.min(2702, self.y));
};
self.shoot = function () {
if (player) {
var bullet = new Bullet(15, 0xff0000, 8);
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 * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
enemyBullets.push(bullet);
game.addChild(bullet);
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
if (self.explodeOnDeath) {
createExplosion(self.x, self.y, 150);
}
if (self.splitOnDeath) {
for (var i = 0; i < 3; i++) {
var childEnemy = new Enemy('normal', currentLevel);
childEnemy.x = self.x + (Math.random() - 0.5) * 100;
childEnemy.y = self.y + (Math.random() - 0.5) * 100;
childEnemy.scale.set(0.6, 0.6);
enemies.push(childEnemy);
game.addChild(childEnemy);
}
}
// Drop power-ups
if (Math.random() < 0.3) {
createPowerUp(self.x, self.y);
}
LK.getSound('explosion').play();
self.destroy();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d572c
});
/****
* Game Code
****/
// UI Elements
var healthText = new Text2('Health: 100', {
size: 40,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
var scoreText = new Text2('Score: 0', {
size: 40,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var bulletText = new Text2('Bullets: 100', {
size: 30,
fill: 0xFFFF00
});
bulletText.anchor.set(0, 0);
bulletText.y = 50;
LK.gui.topLeft.addChild(bulletText);
var laserText = new Text2('Laser: 100%', {
size: 30,
fill: 0x00FFFF
});
laserText.anchor.set(0, 0);
laserText.y = 90;
LK.gui.topLeft.addChild(laserText);
var levelText = new Text2('Level: 1', {
size: 50,
fill: 0xFFD700
});
levelText.anchor.set(1, 0);
LK.gui.topRight.addChild(levelText);
var rageText = new Text2('RAGE MODE!', {
size: 60,
fill: 0xFF0000
});
rageText.anchor.set(0.5, 0.5);
rageText.visible = false;
LK.gui.center.addChild(rageText);
var characters = {
normal: {
name: "Normal",
color: 0x0055ff,
bulletSpeed: 1.0,
bulletDamage: 10,
bulletColor: 0xffff00,
health: 100
},
laserMaster: {
name: "Laser Master",
color: 0xff00ff,
bulletSpeed: 0.8,
bulletDamage: 5,
bulletColor: 0xff00ff,
health: 100,
superLaser: true
},
ranged: {
name: "Ranged",
color: 0xff5500,
bulletSpeed: 1.2,
bulletDamage: 8,
bulletColor: 0xff5500,
health: 100,
trackingBullets: true
},
close: {
name: "Close Combat",
color: 0x00ff55,
bulletSpeed: 0.8,
bulletDamage: 15,
bulletColor: 0x00ff55,
health: 100,
spreadShot: true
},
sniper: {
name: "Sniper",
color: 0x9900ff,
bulletSpeed: 2.0,
bulletDamage: 25,
bulletColor: 0x9900ff,
health: 100,
piercing: true
},
explosive: {
name: "Explosive",
color: 0xff0000,
bulletSpeed: 0.7,
bulletDamage: 12,
bulletColor: 0xff0000,
health: 100,
explosiveShot: true
},
rapid: {
name: "Rapid Fire",
color: 0x00ffff,
bulletSpeed: 1.5,
bulletDamage: 5,
bulletColor: 0x00ffff,
health: 100,
rapidFire: true,
bouncingBullets: true
},
timemaster: {
name: "Time Master",
color: 0x00ffcc,
bulletSpeed: 1.2,
bulletDamage: 15,
bulletColor: 0x00ffcc,
health: 100,
timeControl: true
},
teleporter: {
name: "Teleporter",
color: 0xff00ff,
bulletSpeed: 1.3,
bulletDamage: 12,
bulletColor: 0xff00ff,
health: 100,
teleport: true
},
shadow: {
name: "Shadow Warrior",
color: 0x4a0080,
bulletSpeed: 1.6,
bulletDamage: 15,
bulletColor: 0x800080,
health: 100,
invisibility: true
},
shocktank: {
name: "Shock Tank",
color: 0x4169e1,
bulletSpeed: 0.7,
bulletDamage: 25,
bulletColor: 0x4682b4,
health: 150,
shockwave: true
},
ultimate: {
name: "Ultimate",
color: 0xffd700,
bulletSpeed: 1.8,
bulletDamage: 20,
bulletColor: 0xffd700,
health: 150,
trackingBullets: true,
spreadShot: true,
piercing: true,
explosiveShot: true,
rapidFire: true,
bouncingBullets: true
}
};
// Start game
if (!gameStarted) {
showCharacterSelect();
}
var enemyTypes = {
normal: {
color: 0xff3333,
speedMod: 1.0,
healthMod: 1.0,
dodgeChance: 0.1,
sizeMod: 1.0
},
fast: {
color: 0x33ff33,
speedMod: 1.5,
healthMod: 0.8,
dodgeChance: 0.3,
sizeMod: 0.8
},
tank: {
color: 0x3333ff,
speedMod: 0.6,
healthMod: 2.0,
dodgeChance: 0.05,
sizeMod: 1.5
},
bomber: {
color: 0xff6600,
speedMod: 1.2,
healthMod: 0.7,
dodgeChance: 0.1,
sizeMod: 1.0,
explodeOnDeath: true
},
sniper: {
color: 0x9900ff,
speedMod: 0.7,
healthMod: 1.0,
dodgeChance: 0.4,
sizeMod: 1.0,
canShoot: true,
shootRange: 400,
shootCooldown: 2000
},
splitter: {
color: 0x00ffaa,
speedMod: 0.9,
healthMod: 1.2,
dodgeChance: 0.2,
sizeMod: 1.2,
splitOnDeath: true
},
elite: {
color: 0xffa500,
speedMod: 1.1,
healthMod: 1.8,
dodgeChance: 0.3,
sizeMod: 1.4
}
};
var currentLevel = 1;
var levelData = {
1: {
enemySpeed: 3,
enemyHealth: 30,
bossHealth: 250,
backgroundColor: 0x2d572c
},
2: {
enemySpeed: 4,
enemyHealth: 40,
bossHealth: 400,
backgroundColor: 0x654321
},
3: {
enemySpeed: 5,
enemyHealth: 50,
bossHealth: 550,
backgroundColor: 0x808080
},
4: {
enemySpeed: 6,
enemyHealth: 60,
bossHealth: 700,
backgroundColor: 0x800080
},
5: {
enemySpeed: 7,
enemyHealth: 70,
bossHealth: 850,
backgroundColor: 0xff4500
}
};
var player = null;
var bullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
var selectedCharacter = 'normal';
var bossMode = false;
var gameStarted = false;
var bulletCount = 100;
var laserCharge = 100;
var rageMeter = 0;
var rageActive = false;
var health = 100;
var shieldActive = false;
var enemySpawnTimer = 0;
var lastPowerUpSpawn = 0;
function showCharacterSelect() {
var selectContainer = new Container();
selectContainer.x = 1024;
selectContainer.y = 1366;
var titleText = new Text2('SELECT CHARACTER', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -400;
selectContainer.addChild(titleText);
var characterKeys = Object.keys(characters);
var buttonsPerRow = 3;
var buttonWidth = 300;
var buttonHeight = 150;
var spacing = 50;
for (var i = 0; i < characterKeys.length; i++) {
var key = characterKeys[i];
var _char = characters[key];
var row = Math.floor(i / buttonsPerRow);
var col = i % buttonsPerRow;
var button = new Container();
button.x = (col - 1) * (buttonWidth + spacing);
button.y = (row - 1) * (buttonHeight + spacing);
var buttonBg = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 2,
tint: _char.color
});
button.addChild(buttonBg);
var buttonText = new Text2(_char.name, {
size: 30,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.characterKey = key;
button.interactive = true;
button.down = function () {
selectedCharacter = this.characterKey;
startGame();
};
selectContainer.addChild(button);
}
game.addChild(selectContainer);
}
function startGame() {
gameStarted = true;
game.removeChildren();
// Create player
player = new Character(selectedCharacter);
player.x = 1024;
player.y = 1366;
game.addChild(player);
// Start background music
LK.playMusic('background');
// Initialize enemy spawn timer
enemySpawnTimer = 0;
lastPowerUpSpawn = 0;
// Update UI
updateUI();
}
function updateUI() {
healthText.setText('Health: ' + health);
scoreText.setText('Score: ' + LK.getScore());
bulletText.setText('Bullets: ' + bulletCount);
laserText.setText('Laser: ' + laserCharge + '%');
levelText.setText('Level: ' + currentLevel);
rageText.visible = rageActive;
}
function createPowerUp(x, y) {
var powerUp = new Container();
powerUp.x = x;
powerUp.y = y;
var types = ['health', 'bullets', 'laser', 'rage'];
var type = types[Math.floor(Math.random() * types.length)];
var colors = {
health: 0xff0000,
bullets: 0xffff00,
laser: 0x00ffff,
rage: 0xff00ff
};
var powerUpGraphics = powerUp.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
tint: colors[type]
});
powerUp.powerUpType = type;
powerUp.lastY = y;
powerUps.push(powerUp);
game.addChild(powerUp);
// Remove after 10 seconds
LK.setTimeout(function () {
if (powerUps.indexOf(powerUp) !== -1) {
powerUps.splice(powerUps.indexOf(powerUp), 1);
powerUp.destroy();
}
}, 10000);
}
function createExplosion(x, y, size) {
var explosion = new Container();
explosion.x = x;
explosion.y = y;
var explosionGraphics = explosion.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 120,
scaleY: size / 120
});
game.addChild(explosion);
LK.getSound('explosion').play();
// Animate explosion
tween.to(explosionGraphics, {
alpha: 0,
scaleX: explosionGraphics.scaleX * 2,
scaleY: explosionGraphics.scaleY * 2
}, 500).onComplete(function () {
explosion.destroy();
});
// Damage nearby enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - x, 2) + Math.pow(enemy.y - y, 2));
if (distance < size) {
enemy.takeDamage(30);
}
}
// Damage player if close
if (player) {
var playerDistance = Math.sqrt(Math.pow(player.x - x, 2) + Math.pow(player.y - y, 2));
if (playerDistance < size && !player.invincible) {
health -= 20;
if (health <= 0) {
gameOver();
}
}
}
}
function spawnEnemy() {
var availableTypes = ['normal', 'fast'];
if (currentLevel >= 2) availableTypes.push('tank', 'bomber');
if (currentLevel >= 3) availableTypes.push('sniper', 'splitter');
if (currentLevel >= 4) availableTypes.push('elite');
var type = availableTypes[Math.floor(Math.random() * availableTypes.length)];
var enemy = new Enemy(type, currentLevel);
// Spawn from edges
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// Right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
break;
case 2:
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
break;
case 3:
// Left
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
enemies.push(enemy);
game.addChild(enemy);
}
function spawnBoss() {
bossMode = true;
// Clear existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
var boss = new Boss(currentLevel);
boss.x = 1024;
boss.y = 300;
enemies.push(boss);
game.addChild(boss);
}
function gameOver() {
gameStarted = false;
LK.stopMusic();
var gameOverText = new Text2('GAME OVER', {
size: 100,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 1024;
gameOverText.y = 1366;
game.addChild(gameOverText);
var finalScoreText = new Text2('Final Score: ' + LK.getScore(), {
size: 50,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 1024;
finalScoreText.y = 1466;
game.addChild(finalScoreText);
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
}
function findClosestEnemy() {
if (!player || enemies.length === 0) return null;
var closest = null;
var minDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - player.x, 2) + Math.pow(enemy.y - player.y, 2));
if (distance < minDistance) {
minDistance = distance;
closest = enemy;
}
}
return closest;
}
function shootBullet() {
if (!player || bulletCount <= 0) return;
var _char2 = characters[selectedCharacter];
bulletCount--;
if (_char2.spreadShot) {
// Spread shot
for (var i = -1; i <= 1; i++) {
var bullet = new Bullet(_char2.bulletDamage, _char2.bulletColor, _char2.bulletSpeed * 12, _char2);
bullet.x = player.x;
bullet.y = player.y - 40;
bullet.velocityX = i * 3;
bullet.velocityY = -bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
} else if (_char2.trackingBullets) {
// Tracking bullets
var target = findClosestEnemy();
if (target) {
var bullet = new Bullet(_char2.bulletDamage, _char2.bulletColor, _char2.bulletSpeed * 12, _char2);
bullet.x = player.x;
bullet.y = player.y - 40;
var dx = target.x - bullet.x;
var dy = target.y - bullet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
} else {
// Normal shot
var bullet = new Bullet(_char2.bulletDamage, _char2.bulletColor, _char2.bulletSpeed * 12, _char2);
bullet.x = player.x;
bullet.y = player.y - 40;
bullet.velocityX = 0;
bullet.velocityY = -bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('shoot').play();
rageMeter = Math.min(100, rageMeter + 5);
if (rageMeter >= 100 && !rageActive) {
player.activateRage();
rageActive = true;
}
}
function fireLaser() {
if (!player || laserCharge <= 0) return;
var laser = new Container();
laser.x = player.x;
laser.y = player.y - 40;
var laserGraphics = laser.attachAsset('laser', {
anchorX: 0.5,
anchorY: 1,
tint: 0x00ffff
});
game.addChild(laser);
LK.getSound('laser').play();
// Damage enemies in laser path
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (Math.abs(enemy.x - laser.x) < 40 && enemy.y < laser.y) {
enemy.takeDamage(50);
}
}
laserCharge -= 20;
LK.setTimeout(function () {
laser.destroy();
}, 200);
}
// Touch controls
var moveDirection = {
x: 0,
y: 0
};
var shooting = false;
var lastShot = 0;
var laserActive = false;
game.down = function (x, y) {
if (!gameStarted) return;
// Check if touching shoot area (right side)
if (x > 1536) {
shooting = true;
} else if (x > 1024 && y > 2300) {
// Laser button area (bottom right)
laserActive = true;
} else {
// Movement area (left side)
if (player) {
moveDirection.x = (x - player.x) * 0.1;
moveDirection.y = (y - player.y) * 0.1;
}
}
};
game.move = function (x, y) {
if (!gameStarted) return;
if (x <= 1536 && player) {
moveDirection.x = (x - player.x) * 0.1;
moveDirection.y = (y - player.y) * 0.1;
}
};
game.up = function () {
shooting = false;
laserActive = false;
moveDirection = {
x: 0,
y: 0
};
};
// Add keyboard state tracking
var keyState = {
w: false,
a: false,
s: false,
d: false,
space: false,
e: false
};
// Keyboard event listeners
LK.on('keydown', function (key) {
keyState[key] = true;
});
LK.on('keyup', function (key) {
keyState[key] = false;
});
game.update = function () {
if (!gameStarted) return;
// Player movement
if (player) {
// Keyboard movement
if (keyState.w) player.y -= 8;
if (keyState.s) player.y += 8;
if (keyState.a) player.x -= 8;
if (keyState.d) player.x += 8;
// Touch movement
player.x += moveDirection.x;
player.y += moveDirection.y;
// Keep player on screen
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Auto-shoot if touching shoot area or pressing space
if ((shooting || keyState.space) && LK.ticks - lastShot > 10) {
shootBullet();
lastShot = LK.ticks;
}
// Laser controls
if ((laserActive || keyState.e) && LK.ticks % 5 === 0) {
fireLaser();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
var bulletHit = false;
// Check collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
var damageAmount = bullet.damage * (rageActive ? 2 : 1);
enemy.takeDamage(damageAmount);
// Explosive bullets
if (bullet.abilities.explosiveShot) {
createExplosion(bullet.x, bullet.y, 100);
}
// Piercing bullets don't get destroyed
if (!bullet.abilities.piercing) {
bullet.destroy();
bullets.splice(i, 1);
bulletHit = true;
}
if (enemy.health <= 0) {
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 10);
rageMeter = Math.min(100, rageMeter + 10);
}
if (bulletHit) break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check collision with player
if (player && bullet.intersects(player) && !player.invincible) {
health -= 10;
bullet.destroy();
enemyBullets.splice(i, 1);
if (health <= 0) {
gameOver();
}
}
// Remove if off screen
if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check collision with player
if (player && powerUp.intersects(player)) {
switch (powerUp.powerUpType) {
case 'health':
health = Math.min(100, health + 25);
break;
case 'bullets':
bulletCount = Math.min(999, bulletCount + 50);
break;
case 'laser':
laserCharge = Math.min(100, laserCharge + 30);
break;
case 'rage':
rageMeter = Math.min(100, rageMeter + 50);
break;
}
LK.getSound('powerup').play();
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Enemy collision with player
if (player && !player.invincible) {
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (enemy.intersects(player)) {
health -= 1;
LK.effects.flashObject(player, 0xff0000, 100);
if (health <= 0) {
gameOver();
}
}
}
}
// Spawn enemies
if (enemySpawnTimer > 0) {
enemySpawnTimer--;
} else {
if (enemies.length < 15 && !bossMode) {
spawnEnemy();
enemySpawnTimer = 60 - currentLevel * 5;
}
}
// Spawn power-ups
if (LK.ticks - lastPowerUpSpawn > 900) {
// Every 15 seconds
var x = Math.random() * 1800 + 124;
var y = Math.random() * 1800 + 466;
createPowerUp(x, y);
lastPowerUpSpawn = LK.ticks;
}
// Check for boss spawn
if (!bossMode && enemies.length === 0 && LK.getScore() >= currentLevel * 100) {
spawnBoss();
}
// Level progression
if (bossMode && enemies.length === 0) {
currentLevel++;
if (currentLevel > 5) {
// Victory!
LK.showYouWin();
} else {
bossMode = false;
game.setBackgroundColor(levelData[currentLevel].backgroundColor);
}
}
// Regenerate resources over time
if (LK.ticks % 60 === 0) {
// Every second
bulletCount = Math.min(999, bulletCount + 2);
laserCharge = Math.min(100, laserCharge + 1);
if (rageActive) {
rageMeter = Math.max(0, rageMeter - 2);
if (rageMeter <= 0) {
rageActive = false;
}
}
}
// Update UI
updateUI();
// Create mobile control UI elements
if (LK.ticks === 1) {
// Shoot button
var shootButtonBg = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xff0000,
alpha: 0.3
});
shootButtonBg.x = 1700;
shootButtonBg.y = 2400;
LK.gui.center.addChild(shootButtonBg);
// Laser button
var laserButtonBg = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x00ffff,
alpha: 0.3
});
laserButtonBg.x = 1900;
laserButtonBg.y = 2400;
LK.gui.center.addChild(laserButtonBg);
// Movement area indicator
var moveArea = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 12,
tint: 0x555555,
alpha: 0.1
});
moveArea.x = 400;
moveArea.y = 1366;
LK.gui.center.addChild(moveArea);
}
};