/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Cavalry = Container.expand(function () {
var self = Container.call(this);
var cavalryGraphics = self.attachAsset('cavalry', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 8;
self.health = 70;
self.maxHealth = 70;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -65;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
self.heal = function () {
self.health = self.maxHealth;
self.healthBar.updateHealth(self.health);
};
return self;
});
var HealthBar = Container.expand(function (maxHealth) {
var self = Container.call(this);
self.maxHealth = maxHealth;
self.currentHealth = maxHealth;
self.barWidth = 80;
self.barHeight = 12;
// Background bar (red)
self.backgroundBar = LK.getAsset('soldier', {
anchorX: 0,
anchorY: 0
});
self.backgroundBar.tint = 0xff0000;
self.backgroundBar.width = self.barWidth;
self.backgroundBar.height = self.barHeight;
self.addChild(self.backgroundBar);
// Health bar (green)
self.healthBar = LK.getAsset('soldier', {
anchorX: 0,
anchorY: 0
});
self.healthBar.tint = 0x00ff00;
self.healthBar.width = self.barWidth;
self.healthBar.height = self.barHeight;
self.addChild(self.healthBar);
self.updateHealth = function (currentHealth) {
self.currentHealth = currentHealth;
var healthPercent = Math.max(0, currentHealth / self.maxHealth);
self.healthBar.width = self.barWidth * healthPercent;
// Change color based on health
if (healthPercent > 0.6) {
self.healthBar.tint = 0x00ff00; // Green
} else if (healthPercent > 0.3) {
self.healthBar.tint = 0xffff00; // Yellow
} else {
self.healthBar.tint = 0xff0000; // Red
}
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 10;
self.health = 100;
self.maxHealth = 100;
self.armor = 0;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -70;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
var actualDamage = Math.max(1, damage - self.armor);
self.health -= actualDamage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
self.heal = function () {
self.health = self.maxHealth;
self.healthBar.updateHealth(self.health);
};
self.update = function () {
// Move towards target position smoothly
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
var speed = 8;
self.x += dx / distance * speed;
self.y += dy / distance * speed;
}
};
self.attack = function (target) {
if (target && target.health > 0) {
target.takeDamage(self.strength);
// Flash the target red when attacked
LK.effects.flashObject(target, 0xff0000, 300);
}
};
return self;
});
var Monster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 8;
self.health = 60;
self.maxHealth = 60;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -65;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
return self;
});
var Soldier = Container.expand(function () {
var self = Container.call(this);
var soldierGraphics = self.attachAsset('soldier', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 5;
self.health = 50;
self.maxHealth = 50;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -60;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
self.heal = function () {
self.health = self.maxHealth;
self.healthBar.updateHealth(self.health);
};
return self;
});
var UpgradeButton = Container.expand(function (text, cost, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.buttonText = new Text2(text, {
size: 36,
fill: 0xFFFFFF
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
self.cost = cost;
self.callback = callback;
self.updateText = function (newText) {
self.buttonText.setText(newText);
};
self.down = function (x, y, obj) {
if (coins >= self.cost) {
coins -= self.cost;
self.callback();
LK.getSound('purchase').play();
updateUI();
} else {
// Flash button red to indicate insufficient funds
LK.effects.flashObject(self, 0xff0000, 500);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
// Game state variables
var coins = storage.coins || 100;
var currentWave = storage.currentWave || 1;
var gameState = 'shop'; // 'shop' or 'battle'
var battleTimer = 0;
var battleDuration = 3000; // 3 seconds per battle
var isMouseDown = false;
var targetX = 300;
var targetY = 400;
// Army units
var hero = null;
var soldiers = [];
var cavalry = [];
var monsters = [];
// Upgrade costs
var heroStrengthCost = 50;
var heroHealthCost = 75;
var heroArmorCost = 100;
var soldierCost = 30;
var cavalryCost = 60;
// UI elements
var coinsText = null;
var waveText = null;
var battleButton = null;
var upgradeButtons = [];
// Initialize hero
hero = new Hero();
hero.x = 300;
hero.y = 400;
game.addChild(hero);
// Create UI
function createUI() {
// Coins display
coinsText = new Text2('Coins: ' + coins, {
size: 54,
fill: 0xFFD700
});
coinsText.anchor.set(0, 0);
coinsText.x = 150;
coinsText.y = 50;
LK.gui.topLeft.addChild(coinsText);
// Wave display
waveText = new Text2('Wave: ' + currentWave, {
size: 54,
fill: 0xFFD700
});
waveText.anchor.set(1, 0);
waveText.x = -50;
waveText.y = 50;
LK.gui.topRight.addChild(waveText);
// Battle button
battleButton = LK.getAsset('battleButton', {
anchorX: 0.5,
anchorY: 0.5
});
battleButton.x = 1024;
battleButton.y = 2500;
game.addChild(battleButton);
var battleText = new Text2('BATTLE!', {
size: 48,
fill: 0xFFFFFF
});
battleText.anchor.set(0.5, 0.5);
battleButton.addChild(battleText);
battleButton.down = function (x, y, obj) {
if (gameState === 'shop') {
startBattle();
}
};
// Upgrade buttons
createUpgradeButtons();
}
function createUpgradeButtons() {
var buttonY = 2200;
var buttonSpacing = 350;
// Hero strength upgrade
var strengthButton = new UpgradeButton('Strength +5\n$' + heroStrengthCost, heroStrengthCost, function () {
hero.strength += 5;
heroStrengthCost = Math.floor(heroStrengthCost * 1.5);
updateUpgradeButtons();
});
strengthButton.x = 200;
strengthButton.y = buttonY;
game.addChild(strengthButton);
upgradeButtons.push(strengthButton);
// Hero health upgrade
var healthButton = new UpgradeButton('Health +25\n$' + heroHealthCost, heroHealthCost, function () {
hero.maxHealth += 25;
hero.health = hero.maxHealth;
hero.healthBar.maxHealth = hero.maxHealth;
hero.healthBar.updateHealth(hero.health);
heroHealthCost = Math.floor(heroHealthCost * 1.5);
updateUpgradeButtons();
});
healthButton.x = 550;
healthButton.y = buttonY;
game.addChild(healthButton);
upgradeButtons.push(healthButton);
// Hero armor upgrade
var armorButton = new UpgradeButton('Armor +2\n$' + heroArmorCost, heroArmorCost, function () {
hero.armor += 2;
heroArmorCost = Math.floor(heroArmorCost * 1.5);
updateUpgradeButtons();
});
armorButton.x = 900;
armorButton.y = buttonY;
game.addChild(armorButton);
upgradeButtons.push(armorButton);
// Hire soldier
var soldierButton = new UpgradeButton('Hire Soldier\n$' + soldierCost, soldierCost, function () {
hireSoldier();
soldierCost = Math.floor(soldierCost * 1.2);
updateUpgradeButtons();
});
soldierButton.x = 1250;
soldierButton.y = buttonY;
game.addChild(soldierButton);
upgradeButtons.push(soldierButton);
// Hire cavalry
var cavalryButton = new UpgradeButton('Hire Cavalry\n$' + cavalryCost, cavalryCost, function () {
hireCavalry();
cavalryCost = Math.floor(cavalryCost * 1.2);
updateUpgradeButtons();
});
cavalryButton.x = 1600;
cavalryButton.y = buttonY;
game.addChild(cavalryButton);
upgradeButtons.push(cavalryButton);
}
function updateUpgradeButtons() {
upgradeButtons[0].updateText('Strength +5\n$' + heroStrengthCost);
upgradeButtons[0].cost = heroStrengthCost;
upgradeButtons[1].updateText('Health +25\n$' + heroHealthCost);
upgradeButtons[1].cost = heroHealthCost;
upgradeButtons[2].updateText('Armor +2\n$' + heroArmorCost);
upgradeButtons[2].cost = heroArmorCost;
upgradeButtons[3].updateText('Hire Soldier\n$' + soldierCost);
upgradeButtons[3].cost = soldierCost;
upgradeButtons[4].updateText('Hire Cavalry\n$' + cavalryCost);
upgradeButtons[4].cost = cavalryCost;
}
function hireSoldier() {
var soldier = new Soldier();
var row = Math.floor(soldiers.length / 5);
var col = soldiers.length % 5;
soldier.x = 200 + col * 120;
soldier.y = 500 + row * 120;
soldiers.push(soldier);
game.addChild(soldier);
}
function hireCavalry() {
var cav = new Cavalry();
var row = Math.floor(cavalry.length / 4);
var col = cavalry.length % 4;
cav.x = 1400 + col * 135;
cav.y = 500 + row * 135;
cavalry.push(cav);
game.addChild(cav);
}
function startBattle() {
gameState = 'battle';
battleTimer = 0;
// Hide upgrade buttons and battle button
for (var i = 0; i < upgradeButtons.length; i++) {
upgradeButtons[i].visible = false;
}
battleButton.visible = false;
// Create monsters
var monsterCount = Math.floor(currentWave * 1.5) + 2;
for (var i = 0; i < monsterCount; i++) {
var monster = new Monster();
monster.strength += Math.floor(currentWave * 0.5);
monster.health += Math.floor(currentWave * 5);
monster.maxHealth = monster.health;
monster.healthBar.maxHealth = monster.maxHealth;
monster.healthBar.updateHealth(monster.health);
var row = Math.floor(i / 6);
var col = i % 6;
monster.x = 1200 + col * 120;
monster.y = 800 + row * 120;
monsters.push(monster);
game.addChild(monster);
}
}
function processBattle() {
// Calculate total army strength
var armyStrength = hero.health > 0 ? hero.strength : 0;
for (var i = 0; i < soldiers.length; i++) {
if (soldiers[i].health > 0) {
armyStrength += soldiers[i].strength;
}
}
for (var i = 0; i < cavalry.length; i++) {
if (cavalry[i].health > 0) {
armyStrength += cavalry[i].strength;
}
}
// Calculate total monster strength
var monsterStrength = 0;
for (var i = 0; i < monsters.length; i++) {
if (monsters[i].health > 0) {
monsterStrength += monsters[i].strength;
}
}
// Deal damage to army
if (monsterStrength > 0) {
var damageToArmy = Math.floor(monsterStrength / 10);
if (hero.health > 0) {
hero.takeDamage(damageToArmy);
// Check if hero just died and all other units are dead
if (hero.health <= 0) {
var allDead = true;
for (var j = 0; j < soldiers.length; j++) {
if (soldiers[j].health > 0) {
allDead = false;
break;
}
}
if (allDead) {
for (var j = 0; j < cavalry.length; j++) {
if (cavalry[j].health > 0) {
allDead = false;
break;
}
}
}
if (allDead) {
// Immediate game over
LK.showGameOver();
return;
}
}
}
for (var i = 0; i < soldiers.length; i++) {
if (soldiers[i].health > 0) {
soldiers[i].takeDamage(Math.floor(damageToArmy * 0.8));
}
}
for (var i = 0; i < cavalry.length; i++) {
if (cavalry[i].health > 0) {
cavalry[i].takeDamage(Math.floor(damageToArmy * 0.7));
}
}
}
// Deal damage to monsters
if (armyStrength > 0) {
var damageToMonsters = Math.floor(armyStrength / 8);
for (var i = 0; i < monsters.length; i++) {
if (monsters[i].health > 0) {
var previousHealth = monsters[i].health;
monsters[i].takeDamage(damageToMonsters);
// Check if monster just died and award coins
if (previousHealth > 0 && monsters[i].health <= 0) {
coins += 10; // Award 10 coins per monster killed
}
}
}
}
}
function endBattle() {
gameState = 'shop';
// Check if player won
var monstersAlive = 0;
for (var i = 0; i < monsters.length; i++) {
if (monsters[i].health > 0) {
monstersAlive++;
}
}
var playerAlive = hero.health > 0;
for (var i = 0; i < soldiers.length; i++) {
if (soldiers[i].health > 0) {
playerAlive = true;
break;
}
}
for (var i = 0; i < cavalry.length; i++) {
if (cavalry[i].health > 0) {
playerAlive = true;
break;
}
}
if (monstersAlive === 0 && playerAlive) {
// Victory
var reward = currentWave * 25 + 50;
coins += reward;
currentWave++;
LK.getSound('battleWin').play();
} else if (!playerAlive) {
// Game Over - show game over screen
LK.showGameOver();
return; // Exit early to prevent further processing
}
// Heal all units
hero.heal();
for (var i = 0; i < soldiers.length; i++) {
soldiers[i].heal();
}
for (var i = 0; i < cavalry.length; i++) {
cavalry[i].heal();
}
// Remove monsters
for (var i = 0; i < monsters.length; i++) {
monsters[i].destroy();
}
monsters = [];
// Show UI again
for (var i = 0; i < upgradeButtons.length; i++) {
upgradeButtons[i].visible = true;
}
battleButton.visible = true;
updateUI();
}
function updateUI() {
coinsText.setText('Coins: ' + coins);
waveText.setText('Wave: ' + currentWave);
// Save progress
storage.coins = coins;
storage.currentWave = currentWave;
}
// Initialize UI
createUI();
updateUI();
// Mouse event handlers
game.move = function (x, y, obj) {
if (gameState === 'shop' || gameState === 'battle') {
targetX = x;
targetY = y;
}
};
game.down = function (x, y, obj) {
isMouseDown = true;
targetX = x;
targetY = y;
// Check if clicking on a monster during battle for attack
if (gameState === 'battle') {
for (var i = 0; i < monsters.length; i++) {
var monster = monsters[i];
if (monster.health > 0) {
var dx = x - monster.x;
var dy = y - monster.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If clicking near a monster (within 100 pixels), attack it
if (distance < 100) {
var previousHealth = monster.health;
hero.attack(monster);
// Check if monster just died and award coins
if (previousHealth > 0 && monster.health <= 0) {
coins += 10; // Award 10 coins per monster killed
updateUI();
}
// Check if hero died from counter-attack and all units are dead
if (hero.health <= 0) {
var allDead = true;
for (var j = 0; j < soldiers.length; j++) {
if (soldiers[j].health > 0) {
allDead = false;
break;
}
}
if (allDead) {
for (var j = 0; j < cavalry.length; j++) {
if (cavalry[j].health > 0) {
allDead = false;
break;
}
}
}
if (allDead) {
LK.showGameOver();
return;
}
}
break;
}
}
}
}
};
game.up = function (x, y, obj) {
isMouseDown = false;
};
game.update = function () {
if (gameState === 'battle') {
battleTimer += 16; // Roughly 60 FPS
if (battleTimer % 10 === 0) {
// Process battle every 10 frames
processBattle();
}
if (battleTimer >= battleDuration) {
endBattle();
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Cavalry = Container.expand(function () {
var self = Container.call(this);
var cavalryGraphics = self.attachAsset('cavalry', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 8;
self.health = 70;
self.maxHealth = 70;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -65;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
self.heal = function () {
self.health = self.maxHealth;
self.healthBar.updateHealth(self.health);
};
return self;
});
var HealthBar = Container.expand(function (maxHealth) {
var self = Container.call(this);
self.maxHealth = maxHealth;
self.currentHealth = maxHealth;
self.barWidth = 80;
self.barHeight = 12;
// Background bar (red)
self.backgroundBar = LK.getAsset('soldier', {
anchorX: 0,
anchorY: 0
});
self.backgroundBar.tint = 0xff0000;
self.backgroundBar.width = self.barWidth;
self.backgroundBar.height = self.barHeight;
self.addChild(self.backgroundBar);
// Health bar (green)
self.healthBar = LK.getAsset('soldier', {
anchorX: 0,
anchorY: 0
});
self.healthBar.tint = 0x00ff00;
self.healthBar.width = self.barWidth;
self.healthBar.height = self.barHeight;
self.addChild(self.healthBar);
self.updateHealth = function (currentHealth) {
self.currentHealth = currentHealth;
var healthPercent = Math.max(0, currentHealth / self.maxHealth);
self.healthBar.width = self.barWidth * healthPercent;
// Change color based on health
if (healthPercent > 0.6) {
self.healthBar.tint = 0x00ff00; // Green
} else if (healthPercent > 0.3) {
self.healthBar.tint = 0xffff00; // Yellow
} else {
self.healthBar.tint = 0xff0000; // Red
}
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 10;
self.health = 100;
self.maxHealth = 100;
self.armor = 0;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -70;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
var actualDamage = Math.max(1, damage - self.armor);
self.health -= actualDamage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
self.heal = function () {
self.health = self.maxHealth;
self.healthBar.updateHealth(self.health);
};
self.update = function () {
// Move towards target position smoothly
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
var speed = 8;
self.x += dx / distance * speed;
self.y += dy / distance * speed;
}
};
self.attack = function (target) {
if (target && target.health > 0) {
target.takeDamage(self.strength);
// Flash the target red when attacked
LK.effects.flashObject(target, 0xff0000, 300);
}
};
return self;
});
var Monster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 8;
self.health = 60;
self.maxHealth = 60;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -65;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
return self;
});
var Soldier = Container.expand(function () {
var self = Container.call(this);
var soldierGraphics = self.attachAsset('soldier', {
anchorX: 0.5,
anchorY: 0.5
});
self.strength = 5;
self.health = 50;
self.maxHealth = 50;
// Add health bar
self.healthBar = new HealthBar(self.maxHealth);
self.healthBar.x = -40;
self.healthBar.y = -60;
self.addChild(self.healthBar);
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.healthBar.updateHealth(self.health);
};
self.heal = function () {
self.health = self.maxHealth;
self.healthBar.updateHealth(self.health);
};
return self;
});
var UpgradeButton = Container.expand(function (text, cost, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.buttonText = new Text2(text, {
size: 36,
fill: 0xFFFFFF
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
self.cost = cost;
self.callback = callback;
self.updateText = function (newText) {
self.buttonText.setText(newText);
};
self.down = function (x, y, obj) {
if (coins >= self.cost) {
coins -= self.cost;
self.callback();
LK.getSound('purchase').play();
updateUI();
} else {
// Flash button red to indicate insufficient funds
LK.effects.flashObject(self, 0xff0000, 500);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
// Game state variables
var coins = storage.coins || 100;
var currentWave = storage.currentWave || 1;
var gameState = 'shop'; // 'shop' or 'battle'
var battleTimer = 0;
var battleDuration = 3000; // 3 seconds per battle
var isMouseDown = false;
var targetX = 300;
var targetY = 400;
// Army units
var hero = null;
var soldiers = [];
var cavalry = [];
var monsters = [];
// Upgrade costs
var heroStrengthCost = 50;
var heroHealthCost = 75;
var heroArmorCost = 100;
var soldierCost = 30;
var cavalryCost = 60;
// UI elements
var coinsText = null;
var waveText = null;
var battleButton = null;
var upgradeButtons = [];
// Initialize hero
hero = new Hero();
hero.x = 300;
hero.y = 400;
game.addChild(hero);
// Create UI
function createUI() {
// Coins display
coinsText = new Text2('Coins: ' + coins, {
size: 54,
fill: 0xFFD700
});
coinsText.anchor.set(0, 0);
coinsText.x = 150;
coinsText.y = 50;
LK.gui.topLeft.addChild(coinsText);
// Wave display
waveText = new Text2('Wave: ' + currentWave, {
size: 54,
fill: 0xFFD700
});
waveText.anchor.set(1, 0);
waveText.x = -50;
waveText.y = 50;
LK.gui.topRight.addChild(waveText);
// Battle button
battleButton = LK.getAsset('battleButton', {
anchorX: 0.5,
anchorY: 0.5
});
battleButton.x = 1024;
battleButton.y = 2500;
game.addChild(battleButton);
var battleText = new Text2('BATTLE!', {
size: 48,
fill: 0xFFFFFF
});
battleText.anchor.set(0.5, 0.5);
battleButton.addChild(battleText);
battleButton.down = function (x, y, obj) {
if (gameState === 'shop') {
startBattle();
}
};
// Upgrade buttons
createUpgradeButtons();
}
function createUpgradeButtons() {
var buttonY = 2200;
var buttonSpacing = 350;
// Hero strength upgrade
var strengthButton = new UpgradeButton('Strength +5\n$' + heroStrengthCost, heroStrengthCost, function () {
hero.strength += 5;
heroStrengthCost = Math.floor(heroStrengthCost * 1.5);
updateUpgradeButtons();
});
strengthButton.x = 200;
strengthButton.y = buttonY;
game.addChild(strengthButton);
upgradeButtons.push(strengthButton);
// Hero health upgrade
var healthButton = new UpgradeButton('Health +25\n$' + heroHealthCost, heroHealthCost, function () {
hero.maxHealth += 25;
hero.health = hero.maxHealth;
hero.healthBar.maxHealth = hero.maxHealth;
hero.healthBar.updateHealth(hero.health);
heroHealthCost = Math.floor(heroHealthCost * 1.5);
updateUpgradeButtons();
});
healthButton.x = 550;
healthButton.y = buttonY;
game.addChild(healthButton);
upgradeButtons.push(healthButton);
// Hero armor upgrade
var armorButton = new UpgradeButton('Armor +2\n$' + heroArmorCost, heroArmorCost, function () {
hero.armor += 2;
heroArmorCost = Math.floor(heroArmorCost * 1.5);
updateUpgradeButtons();
});
armorButton.x = 900;
armorButton.y = buttonY;
game.addChild(armorButton);
upgradeButtons.push(armorButton);
// Hire soldier
var soldierButton = new UpgradeButton('Hire Soldier\n$' + soldierCost, soldierCost, function () {
hireSoldier();
soldierCost = Math.floor(soldierCost * 1.2);
updateUpgradeButtons();
});
soldierButton.x = 1250;
soldierButton.y = buttonY;
game.addChild(soldierButton);
upgradeButtons.push(soldierButton);
// Hire cavalry
var cavalryButton = new UpgradeButton('Hire Cavalry\n$' + cavalryCost, cavalryCost, function () {
hireCavalry();
cavalryCost = Math.floor(cavalryCost * 1.2);
updateUpgradeButtons();
});
cavalryButton.x = 1600;
cavalryButton.y = buttonY;
game.addChild(cavalryButton);
upgradeButtons.push(cavalryButton);
}
function updateUpgradeButtons() {
upgradeButtons[0].updateText('Strength +5\n$' + heroStrengthCost);
upgradeButtons[0].cost = heroStrengthCost;
upgradeButtons[1].updateText('Health +25\n$' + heroHealthCost);
upgradeButtons[1].cost = heroHealthCost;
upgradeButtons[2].updateText('Armor +2\n$' + heroArmorCost);
upgradeButtons[2].cost = heroArmorCost;
upgradeButtons[3].updateText('Hire Soldier\n$' + soldierCost);
upgradeButtons[3].cost = soldierCost;
upgradeButtons[4].updateText('Hire Cavalry\n$' + cavalryCost);
upgradeButtons[4].cost = cavalryCost;
}
function hireSoldier() {
var soldier = new Soldier();
var row = Math.floor(soldiers.length / 5);
var col = soldiers.length % 5;
soldier.x = 200 + col * 120;
soldier.y = 500 + row * 120;
soldiers.push(soldier);
game.addChild(soldier);
}
function hireCavalry() {
var cav = new Cavalry();
var row = Math.floor(cavalry.length / 4);
var col = cavalry.length % 4;
cav.x = 1400 + col * 135;
cav.y = 500 + row * 135;
cavalry.push(cav);
game.addChild(cav);
}
function startBattle() {
gameState = 'battle';
battleTimer = 0;
// Hide upgrade buttons and battle button
for (var i = 0; i < upgradeButtons.length; i++) {
upgradeButtons[i].visible = false;
}
battleButton.visible = false;
// Create monsters
var monsterCount = Math.floor(currentWave * 1.5) + 2;
for (var i = 0; i < monsterCount; i++) {
var monster = new Monster();
monster.strength += Math.floor(currentWave * 0.5);
monster.health += Math.floor(currentWave * 5);
monster.maxHealth = monster.health;
monster.healthBar.maxHealth = monster.maxHealth;
monster.healthBar.updateHealth(monster.health);
var row = Math.floor(i / 6);
var col = i % 6;
monster.x = 1200 + col * 120;
monster.y = 800 + row * 120;
monsters.push(monster);
game.addChild(monster);
}
}
function processBattle() {
// Calculate total army strength
var armyStrength = hero.health > 0 ? hero.strength : 0;
for (var i = 0; i < soldiers.length; i++) {
if (soldiers[i].health > 0) {
armyStrength += soldiers[i].strength;
}
}
for (var i = 0; i < cavalry.length; i++) {
if (cavalry[i].health > 0) {
armyStrength += cavalry[i].strength;
}
}
// Calculate total monster strength
var monsterStrength = 0;
for (var i = 0; i < monsters.length; i++) {
if (monsters[i].health > 0) {
monsterStrength += monsters[i].strength;
}
}
// Deal damage to army
if (monsterStrength > 0) {
var damageToArmy = Math.floor(monsterStrength / 10);
if (hero.health > 0) {
hero.takeDamage(damageToArmy);
// Check if hero just died and all other units are dead
if (hero.health <= 0) {
var allDead = true;
for (var j = 0; j < soldiers.length; j++) {
if (soldiers[j].health > 0) {
allDead = false;
break;
}
}
if (allDead) {
for (var j = 0; j < cavalry.length; j++) {
if (cavalry[j].health > 0) {
allDead = false;
break;
}
}
}
if (allDead) {
// Immediate game over
LK.showGameOver();
return;
}
}
}
for (var i = 0; i < soldiers.length; i++) {
if (soldiers[i].health > 0) {
soldiers[i].takeDamage(Math.floor(damageToArmy * 0.8));
}
}
for (var i = 0; i < cavalry.length; i++) {
if (cavalry[i].health > 0) {
cavalry[i].takeDamage(Math.floor(damageToArmy * 0.7));
}
}
}
// Deal damage to monsters
if (armyStrength > 0) {
var damageToMonsters = Math.floor(armyStrength / 8);
for (var i = 0; i < monsters.length; i++) {
if (monsters[i].health > 0) {
var previousHealth = monsters[i].health;
monsters[i].takeDamage(damageToMonsters);
// Check if monster just died and award coins
if (previousHealth > 0 && monsters[i].health <= 0) {
coins += 10; // Award 10 coins per monster killed
}
}
}
}
}
function endBattle() {
gameState = 'shop';
// Check if player won
var monstersAlive = 0;
for (var i = 0; i < monsters.length; i++) {
if (monsters[i].health > 0) {
monstersAlive++;
}
}
var playerAlive = hero.health > 0;
for (var i = 0; i < soldiers.length; i++) {
if (soldiers[i].health > 0) {
playerAlive = true;
break;
}
}
for (var i = 0; i < cavalry.length; i++) {
if (cavalry[i].health > 0) {
playerAlive = true;
break;
}
}
if (monstersAlive === 0 && playerAlive) {
// Victory
var reward = currentWave * 25 + 50;
coins += reward;
currentWave++;
LK.getSound('battleWin').play();
} else if (!playerAlive) {
// Game Over - show game over screen
LK.showGameOver();
return; // Exit early to prevent further processing
}
// Heal all units
hero.heal();
for (var i = 0; i < soldiers.length; i++) {
soldiers[i].heal();
}
for (var i = 0; i < cavalry.length; i++) {
cavalry[i].heal();
}
// Remove monsters
for (var i = 0; i < monsters.length; i++) {
monsters[i].destroy();
}
monsters = [];
// Show UI again
for (var i = 0; i < upgradeButtons.length; i++) {
upgradeButtons[i].visible = true;
}
battleButton.visible = true;
updateUI();
}
function updateUI() {
coinsText.setText('Coins: ' + coins);
waveText.setText('Wave: ' + currentWave);
// Save progress
storage.coins = coins;
storage.currentWave = currentWave;
}
// Initialize UI
createUI();
updateUI();
// Mouse event handlers
game.move = function (x, y, obj) {
if (gameState === 'shop' || gameState === 'battle') {
targetX = x;
targetY = y;
}
};
game.down = function (x, y, obj) {
isMouseDown = true;
targetX = x;
targetY = y;
// Check if clicking on a monster during battle for attack
if (gameState === 'battle') {
for (var i = 0; i < monsters.length; i++) {
var monster = monsters[i];
if (monster.health > 0) {
var dx = x - monster.x;
var dy = y - monster.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If clicking near a monster (within 100 pixels), attack it
if (distance < 100) {
var previousHealth = monster.health;
hero.attack(monster);
// Check if monster just died and award coins
if (previousHealth > 0 && monster.health <= 0) {
coins += 10; // Award 10 coins per monster killed
updateUI();
}
// Check if hero died from counter-attack and all units are dead
if (hero.health <= 0) {
var allDead = true;
for (var j = 0; j < soldiers.length; j++) {
if (soldiers[j].health > 0) {
allDead = false;
break;
}
}
if (allDead) {
for (var j = 0; j < cavalry.length; j++) {
if (cavalry[j].health > 0) {
allDead = false;
break;
}
}
}
if (allDead) {
LK.showGameOver();
return;
}
}
break;
}
}
}
}
};
game.up = function (x, y, obj) {
isMouseDown = false;
};
game.update = function () {
if (gameState === 'battle') {
battleTimer += 16; // Roughly 60 FPS
if (battleTimer % 10 === 0) {
// Process battle every 10 frames
processBattle();
}
if (battleTimer >= battleDuration) {
endBattle();
}
}
};
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Battle Forge: Army Builder" and with the description "Strategic battle game where you fight monsters to earn coins, then upgrade your hero and hire soldiers and cavalry to build a stronger army for tougher battles.". No text on banner!
A Player Character. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A Battle Button. In-Game asset. 2d. High contrast. No shadows
Monster for a game. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat