/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function (type) {
var self = Container.call(this);
self.enemyType = type || 'normal';
if (self.enemyType === 'fast') {
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 15;
self.maxHealth = 15;
self.speed = 3;
self.damage = 15;
} else if (self.enemyType === 'tank') {
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 40;
self.maxHealth = 40;
self.speed = 1;
self.damage = 30;
} else if (self.enemyType === 'boss') {
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
tint: 0x8B0000
});
// Special health for wave 40 boss
if (wave === 40) {
self.health = 500;
self.maxHealth = 500;
} else {
self.health = 150;
self.maxHealth = 150;
}
self.speed = 1.5;
self.damage = 30;
} else {
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 25;
self.maxHealth = 25;
self.speed = 2;
self.damage = 20;
}
self.lastPlayerCollision = false;
self.takeDamage = function (damage) {
self.health -= damage;
LK.getSound('enemyHit').play();
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.destroy();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
enemiesKilled++;
if (self === currentBoss) {
currentBoss = null;
bossHealthTxt.visible = false;
}
score += 10;
updateScore();
updateEnemyCount();
} else if (self.enemyType === 'boss') {
// Update boss health display
bossHealthTxt.setText('Boss HP: ' + self.health + '/' + self.maxHealth);
}
};
self.update = function () {
// Move toward player
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;
}
// Check collision with player
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
}
self.lastPlayerCollision = currentCollision;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
var swordGraphics = self.attachAsset('sword', {
anchorX: 0.2,
anchorY: 0.5,
x: 50,
alpha: 0
});
self.health = 200;
self.maxHealth = 200;
self.attackDamage = 25;
self.attackSpeed = 1.0;
self.attackRadius = 100;
self.isAttacking = false;
self.attackCooldown = 0;
self.fireEffect = false;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
gameOver = true;
}
LK.getSound('playerHit').play();
LK.effects.flashObject(self, 0xff0000, 300);
updateHealthBar();
};
self.attack = function () {
if (self.attackCooldown > 0 || self.isAttacking) return;
self.isAttacking = true;
self.attackCooldown = 60 / self.attackSpeed;
swordGraphics.alpha = 1;
swordGraphics.rotation = -Math.PI / 4;
tween(swordGraphics, {
rotation: Math.PI / 4
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(swordGraphics, {
alpha: 0
}, {
duration: 100
});
self.isAttacking = false;
}
});
LK.getSound('swordHit').play();
// Check for enemy hits
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
if (distance <= self.attackRadius) {
enemy.takeDamage(self.attackDamage);
if (self.fireEffect) {
LK.effects.flashObject(enemy, 0xff4500, 500);
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
var player;
var enemies = [];
var score = 0;
var wave = 1;
var enemiesInWave = 5;
var enemiesSpawned = 0;
var waveComplete = false;
var gameOver = false;
var showingUpgrades = false;
var spawnTimer = 0;
var enemiesKilled = 0;
var currentBoss = null;
var gameOverShowing = false;
var bossHealthTxt = new Text2('', {
size: 50,
fill: 0xFF0000,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
bossHealthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bossHealthTxt);
bossHealthTxt.y = 120;
bossHealthTxt.visible = false;
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
waveTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(waveTxt);
waveTxt.x = -200;
waveTxt.y = 50;
var healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0
});
LK.gui.bottom.addChild(healthBarBg);
healthBarBg.y = -100;
var healthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0
});
LK.gui.bottom.addChild(healthBar);
healthBar.y = -100;
var hpTxt = new Text2('HP: 200/200', {
size: 40,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 2
});
hpTxt.anchor.set(0.5, 0);
LK.gui.bottom.addChild(hpTxt);
hpTxt.y = -80;
var enemyCountTxt = new Text2('Enemies: 0/5', {
size: 50,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
enemyCountTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(enemyCountTxt);
enemyCountTxt.x = 120;
enemyCountTxt.y = 50;
var upgradeContainer = new Container();
game.addChild(upgradeContainer);
upgradeContainer.visible = false;
// Create attack button
var attackButton = new Container();
var attackBtnBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
attackButton.addChild(attackBtnBg);
var attackBtnText = new Text2('ATTACK', {
size: 40,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 2
});
attackBtnText.anchor.set(0.5, 0.5);
attackButton.addChild(attackBtnText);
LK.gui.bottomRight.addChild(attackButton);
attackButton.x = -150;
attackButton.y = -100;
attackButton.down = function (x, y, obj) {
if (!showingUpgrades && !gameOver) {
player.attack();
}
};
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
function updateScore() {
scoreTxt.setText('Score: ' + score);
}
function updateWave() {
waveTxt.setText('Wave: ' + wave);
}
function updateHealthBar() {
var healthPercent = player.health / player.maxHealth;
healthBar.scaleX = healthPercent;
if (healthPercent > 0.6) {
healthBar.tint = 0x27ae60;
} else if (healthPercent > 0.3) {
healthBar.tint = 0xf39c12;
} else {
healthBar.tint = 0xe74c3c;
}
hpTxt.setText('HP: ' + player.health + '/' + player.maxHealth);
}
function updateEnemyCount() {
var remainingEnemies = enemiesInWave - enemiesSpawned + enemies.length;
enemyCountTxt.setText('Enemies: ' + remainingEnemies + '/' + enemiesInWave);
}
function spawnEnemy() {
var enemy;
// Check if this is a boss wave (every 10 waves)
if (wave % 10 === 0 && enemies.length === 0 && enemiesSpawned === 0) {
enemy = new Enemy('boss');
currentBoss = enemy;
bossHealthTxt.setText('Boss HP: ' + enemy.health + '/' + enemy.maxHealth);
bossHealthTxt.visible = true;
} else {
var rand = Math.random();
if (wave >= 3 && rand < 0.3) {
enemy = new Enemy('fast');
} else if (wave >= 5 && rand < 0.2) {
enemy = new Enemy('tank');
} else {
enemy = new Enemy('normal');
}
}
// Spawn from random edge
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);
enemiesSpawned++;
updateEnemyCount();
}
function showUpgrades() {
showingUpgrades = true;
upgradeContainer.visible = true;
// Clear previous upgrades
while (upgradeContainer.children.length > 0) {
upgradeContainer.removeChild(upgradeContainer.children[0]);
}
var upgrades = [{
name: 'Damage +10',
effect: function effect() {
player.attackDamage += 10;
}
}, {
name: 'Speed +25%',
effect: function effect() {
player.attackSpeed *= 1.25;
}
}, {
name: 'Radius +20',
effect: function effect() {
player.attackRadius += 20;
}
}, {
name: 'Health +30',
effect: function effect() {
player.health = Math.min(player.maxHealth, player.health + 30);
updateHealthBar();
}
}, {
name: 'Fire Effect',
effect: function effect() {
player.fireEffect = true;
}
}, {
name: 'Max Health +20',
effect: function effect() {
player.maxHealth += 20;
player.health += 20;
updateHealthBar();
}
}];
// Select 3 random upgrades
var selectedUpgrades = [];
for (var i = 0; i < 3; i++) {
var randomIndex = Math.floor(Math.random() * upgrades.length);
selectedUpgrades.push(upgrades[randomIndex]);
upgrades.splice(randomIndex, 1);
}
// Create upgrade buttons
for (var i = 0; i < selectedUpgrades.length; i++) {
var upgrade = selectedUpgrades[i];
var upgradeBtn = new Container();
var btnBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
upgradeBtn.addChild(btnBg);
var btnText = new Text2(upgrade.name, {
size: 40,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 2
});
btnText.anchor.set(0.5, 0.5);
upgradeBtn.addChild(btnText);
upgradeBtn.x = 1024;
upgradeBtn.y = 1200 + i * 150;
upgradeBtn.upgradeEffect = upgrade.effect;
upgradeBtn.down = function (x, y, obj) {
this.upgradeEffect();
showingUpgrades = false;
upgradeContainer.visible = false;
startNextWave();
};
upgradeContainer.addChild(upgradeBtn);
}
}
function startNextWave() {
wave++;
if (wave > 40) {
LK.showYouWin();
return;
}
// Restore player health - 300 for wave 40, 200 for other waves
if (wave === 40) {
player.health = 300;
player.maxHealth = 300;
} else {
player.health = 200;
}
updateHealthBar();
// Boss waves have only 1 enemy (the boss), regular waves have increasing enemies
if (wave % 10 === 0) {
enemiesInWave = 1;
} else {
enemiesInWave = Math.floor(5 + (wave - 1) * 2);
}
enemiesSpawned = 0;
waveComplete = false;
spawnTimer = 0;
updateWave();
updateEnemyCount();
}
function checkWaveComplete() {
if (enemiesSpawned >= enemiesInWave && enemies.length === 0) {
waveComplete = true;
showUpgrades();
}
}
game.move = function (x, y, obj) {
if (!showingUpgrades && !gameOver) {
player.x = x;
player.y = y;
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
}
};
game.down = function (x, y, obj) {
if (!showingUpgrades && !gameOver) {
player.x = x;
player.y = y;
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
player.attack();
}
};
game.update = function () {
if (gameOver && !gameOverShowing) {
showCustomGameOver();
return;
}
if (gameOver) {
return;
}
if (showingUpgrades) {
return;
}
// Spawn enemies
if (enemiesSpawned < enemiesInWave) {
spawnTimer++;
if (spawnTimer >= 90) {
// Spawn every 1.5 seconds
spawnEnemy();
spawnTimer = 0;
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].update();
}
// Update player
player.update();
// Check wave completion
checkWaveComplete();
};
function showCustomGameOver() {
gameOverShowing = true;
// Create game over container
var gameOverContainer = new Container();
game.addChild(gameOverContainer);
// Semi-transparent background
var bgOverlay = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 15,
scaleY: 20,
alpha: 0.8
});
gameOverContainer.addChild(bgOverlay);
bgOverlay.x = 1024;
bgOverlay.y = 1366;
// Game Over text
var gameOverText = new Text2('GAME OVER', {
size: 80,
fill: 0xFF0000,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 4
});
gameOverText.anchor.set(0.5, 0.5);
gameOverContainer.addChild(gameOverText);
gameOverText.x = 1024;
gameOverText.y = 1000;
// Stats text
var statsText = new Text2('Enemies Killed: ' + enemiesKilled + '\nScore: ' + score + '\nWave Reached: ' + wave, {
size: 50,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
statsText.anchor.set(0.5, 0.5);
gameOverContainer.addChild(statsText);
statsText.x = 1024;
statsText.y = 1200;
// Retry button
var retryButton = new Container();
var retryBg = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
retryButton.addChild(retryBg);
var retryText = new Text2('RETRY', {
size: 60,
fill: 0x000000,
font: "Arial-Bold",
stroke: 0xFFFFFF,
strokeThickness: 2
});
retryText.anchor.set(0.5, 0.5);
retryButton.addChild(retryText);
retryButton.x = 1024;
retryButton.y = 1500;
retryButton.down = function () {
// Reset game state
gameOver = false;
score = 0;
wave = 1;
enemiesKilled = 0;
enemiesInWave = 5;
enemiesSpawned = 0;
waveComplete = false;
spawnTimer = 0;
currentBoss = null;
// Clear enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
// Reset player
player.health = 200;
player.maxHealth = 200;
player.attackDamage = 25;
player.attackSpeed = 1.0;
player.attackRadius = 100;
player.fireEffect = false;
player.x = 1024;
player.y = 1366;
// Update UI
updateScore();
updateWave();
updateHealthBar();
updateEnemyCount();
bossHealthTxt.visible = false;
// Reset game over showing flag
gameOverShowing = false;
// Remove game over screen
gameOverContainer.destroy();
};
gameOverContainer.addChild(retryButton);
}
// Start background music
LK.playMusic('battleMusic');
// Initialize health bar
updateHealthBar();
// Initialize enemy counter
updateEnemyCount(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function (type) {
var self = Container.call(this);
self.enemyType = type || 'normal';
if (self.enemyType === 'fast') {
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 15;
self.maxHealth = 15;
self.speed = 3;
self.damage = 15;
} else if (self.enemyType === 'tank') {
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 40;
self.maxHealth = 40;
self.speed = 1;
self.damage = 30;
} else if (self.enemyType === 'boss') {
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
tint: 0x8B0000
});
// Special health for wave 40 boss
if (wave === 40) {
self.health = 500;
self.maxHealth = 500;
} else {
self.health = 150;
self.maxHealth = 150;
}
self.speed = 1.5;
self.damage = 30;
} else {
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 25;
self.maxHealth = 25;
self.speed = 2;
self.damage = 20;
}
self.lastPlayerCollision = false;
self.takeDamage = function (damage) {
self.health -= damage;
LK.getSound('enemyHit').play();
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.destroy();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
enemiesKilled++;
if (self === currentBoss) {
currentBoss = null;
bossHealthTxt.visible = false;
}
score += 10;
updateScore();
updateEnemyCount();
} else if (self.enemyType === 'boss') {
// Update boss health display
bossHealthTxt.setText('Boss HP: ' + self.health + '/' + self.maxHealth);
}
};
self.update = function () {
// Move toward player
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;
}
// Check collision with player
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
}
self.lastPlayerCollision = currentCollision;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
var swordGraphics = self.attachAsset('sword', {
anchorX: 0.2,
anchorY: 0.5,
x: 50,
alpha: 0
});
self.health = 200;
self.maxHealth = 200;
self.attackDamage = 25;
self.attackSpeed = 1.0;
self.attackRadius = 100;
self.isAttacking = false;
self.attackCooldown = 0;
self.fireEffect = false;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
gameOver = true;
}
LK.getSound('playerHit').play();
LK.effects.flashObject(self, 0xff0000, 300);
updateHealthBar();
};
self.attack = function () {
if (self.attackCooldown > 0 || self.isAttacking) return;
self.isAttacking = true;
self.attackCooldown = 60 / self.attackSpeed;
swordGraphics.alpha = 1;
swordGraphics.rotation = -Math.PI / 4;
tween(swordGraphics, {
rotation: Math.PI / 4
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(swordGraphics, {
alpha: 0
}, {
duration: 100
});
self.isAttacking = false;
}
});
LK.getSound('swordHit').play();
// Check for enemy hits
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
if (distance <= self.attackRadius) {
enemy.takeDamage(self.attackDamage);
if (self.fireEffect) {
LK.effects.flashObject(enemy, 0xff4500, 500);
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
var player;
var enemies = [];
var score = 0;
var wave = 1;
var enemiesInWave = 5;
var enemiesSpawned = 0;
var waveComplete = false;
var gameOver = false;
var showingUpgrades = false;
var spawnTimer = 0;
var enemiesKilled = 0;
var currentBoss = null;
var gameOverShowing = false;
var bossHealthTxt = new Text2('', {
size: 50,
fill: 0xFF0000,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
bossHealthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bossHealthTxt);
bossHealthTxt.y = 120;
bossHealthTxt.visible = false;
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
waveTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(waveTxt);
waveTxt.x = -200;
waveTxt.y = 50;
var healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0
});
LK.gui.bottom.addChild(healthBarBg);
healthBarBg.y = -100;
var healthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0
});
LK.gui.bottom.addChild(healthBar);
healthBar.y = -100;
var hpTxt = new Text2('HP: 200/200', {
size: 40,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 2
});
hpTxt.anchor.set(0.5, 0);
LK.gui.bottom.addChild(hpTxt);
hpTxt.y = -80;
var enemyCountTxt = new Text2('Enemies: 0/5', {
size: 50,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
enemyCountTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(enemyCountTxt);
enemyCountTxt.x = 120;
enemyCountTxt.y = 50;
var upgradeContainer = new Container();
game.addChild(upgradeContainer);
upgradeContainer.visible = false;
// Create attack button
var attackButton = new Container();
var attackBtnBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
attackButton.addChild(attackBtnBg);
var attackBtnText = new Text2('ATTACK', {
size: 40,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 2
});
attackBtnText.anchor.set(0.5, 0.5);
attackButton.addChild(attackBtnText);
LK.gui.bottomRight.addChild(attackButton);
attackButton.x = -150;
attackButton.y = -100;
attackButton.down = function (x, y, obj) {
if (!showingUpgrades && !gameOver) {
player.attack();
}
};
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
function updateScore() {
scoreTxt.setText('Score: ' + score);
}
function updateWave() {
waveTxt.setText('Wave: ' + wave);
}
function updateHealthBar() {
var healthPercent = player.health / player.maxHealth;
healthBar.scaleX = healthPercent;
if (healthPercent > 0.6) {
healthBar.tint = 0x27ae60;
} else if (healthPercent > 0.3) {
healthBar.tint = 0xf39c12;
} else {
healthBar.tint = 0xe74c3c;
}
hpTxt.setText('HP: ' + player.health + '/' + player.maxHealth);
}
function updateEnemyCount() {
var remainingEnemies = enemiesInWave - enemiesSpawned + enemies.length;
enemyCountTxt.setText('Enemies: ' + remainingEnemies + '/' + enemiesInWave);
}
function spawnEnemy() {
var enemy;
// Check if this is a boss wave (every 10 waves)
if (wave % 10 === 0 && enemies.length === 0 && enemiesSpawned === 0) {
enemy = new Enemy('boss');
currentBoss = enemy;
bossHealthTxt.setText('Boss HP: ' + enemy.health + '/' + enemy.maxHealth);
bossHealthTxt.visible = true;
} else {
var rand = Math.random();
if (wave >= 3 && rand < 0.3) {
enemy = new Enemy('fast');
} else if (wave >= 5 && rand < 0.2) {
enemy = new Enemy('tank');
} else {
enemy = new Enemy('normal');
}
}
// Spawn from random edge
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);
enemiesSpawned++;
updateEnemyCount();
}
function showUpgrades() {
showingUpgrades = true;
upgradeContainer.visible = true;
// Clear previous upgrades
while (upgradeContainer.children.length > 0) {
upgradeContainer.removeChild(upgradeContainer.children[0]);
}
var upgrades = [{
name: 'Damage +10',
effect: function effect() {
player.attackDamage += 10;
}
}, {
name: 'Speed +25%',
effect: function effect() {
player.attackSpeed *= 1.25;
}
}, {
name: 'Radius +20',
effect: function effect() {
player.attackRadius += 20;
}
}, {
name: 'Health +30',
effect: function effect() {
player.health = Math.min(player.maxHealth, player.health + 30);
updateHealthBar();
}
}, {
name: 'Fire Effect',
effect: function effect() {
player.fireEffect = true;
}
}, {
name: 'Max Health +20',
effect: function effect() {
player.maxHealth += 20;
player.health += 20;
updateHealthBar();
}
}];
// Select 3 random upgrades
var selectedUpgrades = [];
for (var i = 0; i < 3; i++) {
var randomIndex = Math.floor(Math.random() * upgrades.length);
selectedUpgrades.push(upgrades[randomIndex]);
upgrades.splice(randomIndex, 1);
}
// Create upgrade buttons
for (var i = 0; i < selectedUpgrades.length; i++) {
var upgrade = selectedUpgrades[i];
var upgradeBtn = new Container();
var btnBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
upgradeBtn.addChild(btnBg);
var btnText = new Text2(upgrade.name, {
size: 40,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 2
});
btnText.anchor.set(0.5, 0.5);
upgradeBtn.addChild(btnText);
upgradeBtn.x = 1024;
upgradeBtn.y = 1200 + i * 150;
upgradeBtn.upgradeEffect = upgrade.effect;
upgradeBtn.down = function (x, y, obj) {
this.upgradeEffect();
showingUpgrades = false;
upgradeContainer.visible = false;
startNextWave();
};
upgradeContainer.addChild(upgradeBtn);
}
}
function startNextWave() {
wave++;
if (wave > 40) {
LK.showYouWin();
return;
}
// Restore player health - 300 for wave 40, 200 for other waves
if (wave === 40) {
player.health = 300;
player.maxHealth = 300;
} else {
player.health = 200;
}
updateHealthBar();
// Boss waves have only 1 enemy (the boss), regular waves have increasing enemies
if (wave % 10 === 0) {
enemiesInWave = 1;
} else {
enemiesInWave = Math.floor(5 + (wave - 1) * 2);
}
enemiesSpawned = 0;
waveComplete = false;
spawnTimer = 0;
updateWave();
updateEnemyCount();
}
function checkWaveComplete() {
if (enemiesSpawned >= enemiesInWave && enemies.length === 0) {
waveComplete = true;
showUpgrades();
}
}
game.move = function (x, y, obj) {
if (!showingUpgrades && !gameOver) {
player.x = x;
player.y = y;
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
}
};
game.down = function (x, y, obj) {
if (!showingUpgrades && !gameOver) {
player.x = x;
player.y = y;
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
player.attack();
}
};
game.update = function () {
if (gameOver && !gameOverShowing) {
showCustomGameOver();
return;
}
if (gameOver) {
return;
}
if (showingUpgrades) {
return;
}
// Spawn enemies
if (enemiesSpawned < enemiesInWave) {
spawnTimer++;
if (spawnTimer >= 90) {
// Spawn every 1.5 seconds
spawnEnemy();
spawnTimer = 0;
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].update();
}
// Update player
player.update();
// Check wave completion
checkWaveComplete();
};
function showCustomGameOver() {
gameOverShowing = true;
// Create game over container
var gameOverContainer = new Container();
game.addChild(gameOverContainer);
// Semi-transparent background
var bgOverlay = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 15,
scaleY: 20,
alpha: 0.8
});
gameOverContainer.addChild(bgOverlay);
bgOverlay.x = 1024;
bgOverlay.y = 1366;
// Game Over text
var gameOverText = new Text2('GAME OVER', {
size: 80,
fill: 0xFF0000,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 4
});
gameOverText.anchor.set(0.5, 0.5);
gameOverContainer.addChild(gameOverText);
gameOverText.x = 1024;
gameOverText.y = 1000;
// Stats text
var statsText = new Text2('Enemies Killed: ' + enemiesKilled + '\nScore: ' + score + '\nWave Reached: ' + wave, {
size: 50,
fill: 0xFFFFFF,
font: "Arial-Bold",
stroke: 0x000000,
strokeThickness: 3
});
statsText.anchor.set(0.5, 0.5);
gameOverContainer.addChild(statsText);
statsText.x = 1024;
statsText.y = 1200;
// Retry button
var retryButton = new Container();
var retryBg = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
retryButton.addChild(retryBg);
var retryText = new Text2('RETRY', {
size: 60,
fill: 0x000000,
font: "Arial-Bold",
stroke: 0xFFFFFF,
strokeThickness: 2
});
retryText.anchor.set(0.5, 0.5);
retryButton.addChild(retryText);
retryButton.x = 1024;
retryButton.y = 1500;
retryButton.down = function () {
// Reset game state
gameOver = false;
score = 0;
wave = 1;
enemiesKilled = 0;
enemiesInWave = 5;
enemiesSpawned = 0;
waveComplete = false;
spawnTimer = 0;
currentBoss = null;
// Clear enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
// Reset player
player.health = 200;
player.maxHealth = 200;
player.attackDamage = 25;
player.attackSpeed = 1.0;
player.attackRadius = 100;
player.fireEffect = false;
player.x = 1024;
player.y = 1366;
// Update UI
updateScore();
updateWave();
updateHealthBar();
updateEnemyCount();
bossHealthTxt.visible = false;
// Reset game over showing flag
gameOverShowing = false;
// Remove game over screen
gameOverContainer.destroy();
};
gameOverContainer.addChild(retryButton);
}
// Start background music
LK.playMusic('battleMusic');
// Initialize health bar
updateHealthBar();
// Initialize enemy counter
updateEnemyCount();
Un hombre que parece que sobrevivió a un apocalipsis zombie. In-Game asset. 2d. High contrast. No shadows
Una Espada vieja
Un zombie. In-Game asset. 2d. High contrast. No shadows
Un zombie robot gigante controlado por otro zombie. In-Game asset. 2d. High contrast. No shadows
Un medidor de HP con contorno negro y que este lleno, y minimalista. In-Game asset. 2d. High contrast. No shadows