/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function (type, startX, startY, targetX, targetY, damage) {
var self = Container.call(this);
self.type = type || 'basic';
self.damage = damage || 10;
self.speed = 8;
self.targetX = targetX;
self.targetY = targetY;
var assetName = 'bullet';
if (type === 'splash') assetName = 'splashBullet';
if (type === 'slow') assetName = 'slowBullet';
var bulletGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.velocityX = dx / distance * self.speed;
self.velocityY = dy / distance * self.speed;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Enemy = Container.expand(function (type, pathIndex) {
var self = Container.call(this);
self.type = type || 'basic';
self.pathIndex = pathIndex || 0;
self.health = 30;
self.maxHealth = 30;
self.speed = 2;
self.reward = 5;
self.slowEffect = 0;
self.slowDuration = 0;
if (type === 'fast') {
self.health = 20;
self.maxHealth = 20;
self.speed = 4;
self.reward = 8;
} else if (type === 'strong') {
self.health = 80;
self.maxHealth = 80;
self.speed = 1.5;
self.reward = 15;
}
var assetName = 'basicEnemy';
if (type === 'fast') assetName = 'fastEnemy';
if (type === 'strong') assetName = 'strongEnemy';
var enemyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
return true;
}
return false;
};
self.applySlow = function (slowAmount, duration) {
self.slowEffect = slowAmount;
self.slowDuration = duration;
};
self.update = function () {
if (self.slowDuration > 0) {
self.slowDuration--;
if (self.slowDuration <= 0) {
self.slowEffect = 0;
}
}
var currentSpeed = self.speed * (1 - self.slowEffect);
if (self.pathIndex < gamePath.length - 1) {
var targetPoint = gamePath[self.pathIndex + 1];
var dx = targetPoint.x - self.x;
var dy = targetPoint.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 20) {
self.pathIndex++;
if (self.pathIndex >= gamePath.length - 1) {
return 'reachedBase';
}
} else {
self.x += dx / distance * currentSpeed;
self.y += dy / distance * currentSpeed;
}
}
return 'alive';
};
return self;
});
var Tower = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
self.type = type || 'basic';
self.level = 1;
self.damage = 10;
self.range = 150;
self.fireRate = 60;
self.lastFire = 0;
self.gridX = gridX;
self.gridY = gridY;
if (type === 'splash') {
self.damage = 15;
self.range = 120;
self.fireRate = 90;
} else if (type === 'slow') {
self.damage = 5;
self.range = 180;
self.fireRate = 45;
}
var assetName = 'basicTower';
if (type === 'splash') assetName = 'splashTower';
if (type === 'slow') assetName = 'slowTower';
var towerGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.getUpgradeCost = function () {
return self.level * 20;
};
self.upgrade = function () {
self.level++;
self.damage += Math.floor(self.damage * 0.5);
self.range += 20;
if (self.fireRate > 20) {
self.fireRate -= 5;
}
};
self.findTarget = function () {
var closestEnemy = null;
var closestDistance = self.range + 1;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < closestDistance) {
closestDistance = distance;
closestEnemy = enemy;
}
}
return closestEnemy;
};
self.fire = function (target) {
if (LK.ticks - self.lastFire >= self.fireRate) {
var bullet = new Bullet(self.type, self.x, self.y, target.x, target.y, self.damage);
bullets.push(bullet);
game.addChild(bullet);
self.lastFire = LK.ticks;
LK.getSound('shoot').play();
}
};
self.update = function () {
var target = self.findTarget();
if (target) {
self.fire(target);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
var gameWidth = 2048;
var gameHeight = 2732;
var gridSize = 100;
var towers = [];
var enemies = [];
var bullets = [];
var coins = 100;
var lives = 20;
var baseHealth = 100;
var maxBaseHealth = 100;
var currentWave = 1;
var enemiesSpawned = 0;
var enemiesPerWave = 5;
var spawnTimer = 0;
var waveComplete = false;
var selectedTowerType = 'basic';
var gamePath = [{
x: 0,
y: 400
}, {
x: 300,
y: 400
}, {
x: 300,
y: 800
}, {
x: 700,
y: 800
}, {
x: 700,
y: 1200
}, {
x: 1100,
y: 1200
}, {
x: 1100,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 1500,
y: 2000
}, {
x: 1900,
y: 2000
}];
function drawPath() {
for (var i = 0; i < gamePath.length - 1; i++) {
var pathTile = game.attachAsset('pathTile', {
anchorX: 0.5,
anchorY: 0.5,
x: gamePath[i].x,
y: gamePath[i].y
});
}
}
drawPath();
var base = game.attachAsset('base', {
anchorX: 0.5,
anchorY: 0.5,
x: gamePath[gamePath.length - 1].x,
y: gamePath[gamePath.length - 1].y
});
var coinsText = new Text2('Coins: ' + coins, {
size: 60,
fill: 0xFFFF00
});
coinsText.anchor.set(0, 0);
LK.gui.topRight.addChild(coinsText);
var moneyText = new Text2('Money: ' + coins, {
size: 60,
fill: 0x00FF00
});
moneyText.anchor.set(0.5, 0);
moneyText.y = 70;
LK.gui.top.addChild(moneyText);
var livesText = new Text2('Lives: ' + lives, {
size: 60,
fill: 0xFF0000
});
livesText.anchor.set(0, 0);
livesText.y = 70;
LK.gui.topRight.addChild(livesText);
var waveText = new Text2('Wave: ' + currentWave, {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var baseHealthText = new Text2('Base: ' + baseHealth + '/' + maxBaseHealth, {
size: 60,
fill: 0x00FF00
});
baseHealthText.anchor.set(0, 0);
baseHealthText.y = 140;
LK.gui.topRight.addChild(baseHealthText);
var towerButtons = [];
var basicTowerBtn = new Text2('Basic ($20)', {
size: 40,
fill: 0xFFFFFF
});
basicTowerBtn.anchor.set(0, 1);
basicTowerBtn.y = -20;
LK.gui.bottomLeft.addChild(basicTowerBtn);
towerButtons.push({
btn: basicTowerBtn,
type: 'basic',
cost: 20
});
var splashTowerBtn = new Text2('Splash ($35)', {
size: 40,
fill: 0xFFFFFF
});
splashTowerBtn.anchor.set(0, 1);
splashTowerBtn.y = -70;
LK.gui.bottomLeft.addChild(splashTowerBtn);
towerButtons.push({
btn: splashTowerBtn,
type: 'splash',
cost: 35
});
var slowTowerBtn = new Text2('Slow ($25)', {
size: 40,
fill: 0xFFFFFF
});
slowTowerBtn.anchor.set(0, 1);
slowTowerBtn.y = -120;
LK.gui.bottomLeft.addChild(slowTowerBtn);
towerButtons.push({
btn: slowTowerBtn,
type: 'slow',
cost: 25
});
var enemyButtons = [];
var selectedEnemyType = 'basic';
var boughtEnemies = {
basic: 0,
fast: 0,
strong: 0
};
var buyBasicEnemyBtn = new Text2('Buy Basic Enemy ($30)', {
size: 40,
fill: 0xFF6666
});
buyBasicEnemyBtn.anchor.set(1, 1);
buyBasicEnemyBtn.y = -20;
LK.gui.bottomRight.addChild(buyBasicEnemyBtn);
enemyButtons.push({
btn: buyBasicEnemyBtn,
type: 'basic',
cost: 30
});
var buyFastEnemyBtn = new Text2('Buy Fast Enemy ($50)', {
size: 40,
fill: 0xFF69B4
});
buyFastEnemyBtn.anchor.set(1, 1);
buyFastEnemyBtn.y = -70;
LK.gui.bottomRight.addChild(buyFastEnemyBtn);
enemyButtons.push({
btn: buyFastEnemyBtn,
type: 'fast',
cost: 50
});
var buyStrongEnemyBtn = new Text2('Buy Strong Enemy ($80)', {
size: 40,
fill: 0x8B0000
});
buyStrongEnemyBtn.anchor.set(1, 1);
buyStrongEnemyBtn.y = -120;
LK.gui.bottomRight.addChild(buyStrongEnemyBtn);
enemyButtons.push({
btn: buyStrongEnemyBtn,
type: 'strong',
cost: 80
});
var boughtEnemiesText = new Text2('Enemies: B:0 F:0 S:0', {
size: 50,
fill: 0xFFD700
});
boughtEnemiesText.anchor.set(0, 0);
boughtEnemiesText.y = 210;
LK.gui.topRight.addChild(boughtEnemiesText);
function getTowerCost(type) {
if (type === 'basic') return 20;
if (type === 'splash') return 35;
if (type === 'slow') return 25;
return 20;
}
function getEnemyCost(type) {
if (type === 'basic') return 30;
if (type === 'fast') return 50;
if (type === 'strong') return 80;
return 30;
}
function buyEnemy(type) {
var cost = getEnemyCost(type);
if (coins >= cost) {
coins -= cost;
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
selectedEnemyType = type;
boughtEnemies[type]++;
updateBoughtEnemiesDisplay();
}
}
function updateBoughtEnemiesDisplay() {
boughtEnemiesText.setText('Enemies: B:' + boughtEnemies.basic + ' F:' + boughtEnemies.fast + ' S:' + boughtEnemies.strong);
}
function placeEnemy(x, y) {
if (boughtEnemies[selectedEnemyType] > 0) {
var enemy = new Enemy(selectedEnemyType, 0);
enemy.x = x;
enemy.y = y;
boughtEnemies[selectedEnemyType]--;
updateBoughtEnemiesDisplay();
enemies.push(enemy);
game.addChild(enemy);
}
}
function canPlaceTower(x, y) {
var gridX = Math.floor(x / gridSize);
var gridY = Math.floor(y / gridSize);
for (var i = 0; i < towers.length; i++) {
if (towers[i].gridX === gridX && towers[i].gridY === gridY) {
return false;
}
}
for (var j = 0; j < gamePath.length; j++) {
var pathGridX = Math.floor(gamePath[j].x / gridSize);
var pathGridY = Math.floor(gamePath[j].y / gridSize);
if (pathGridX === gridX && pathGridY === gridY) {
return false;
}
}
return true;
}
function spawnEnemy() {
var enemyType = 'basic';
if (currentWave > 3 && Math.random() < 0.3) {
enemyType = 'fast';
}
if (currentWave > 5 && Math.random() < 0.2) {
enemyType = 'strong';
}
var enemy = new Enemy(enemyType, 0);
enemy.x = gamePath[0].x;
enemy.y = gamePath[0].y;
enemies.push(enemy);
game.addChild(enemy);
}
function nextWave() {
currentWave++;
enemiesPerWave = Math.floor(5 + currentWave * 1.2);
enemiesSpawned = 0;
waveComplete = false;
waveText.setText('Wave: ' + currentWave);
}
game.down = function (x, y, obj) {
for (var i = 0; i < towerButtons.length; i++) {
var btnData = towerButtons[i];
if (btnData.btn.getBounds().contains(x, y)) {
selectedTowerType = btnData.type;
return;
}
}
// Check enemy purchase buttons
for (var j = 0; j < enemyButtons.length; j++) {
var enemyBtnData = enemyButtons[j];
if (enemyBtnData.btn.getBounds().contains(x, y)) {
buyEnemy(enemyBtnData.type);
return;
}
}
// Check if placing enemy
if (boughtEnemies[selectedEnemyType] > 0) {
placeEnemy(x, y);
return;
}
if (canPlaceTower(x, y) && coins >= getTowerCost(selectedTowerType)) {
var gridX = Math.floor(x / gridSize);
var gridY = Math.floor(y / gridSize);
var tower = new Tower(selectedTowerType, gridX, gridY);
tower.x = gridX * gridSize + gridSize / 2;
tower.y = gridY * gridSize + gridSize / 2;
towers.push(tower);
game.addChild(tower);
coins -= getTowerCost(selectedTowerType);
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
}
};
game.update = function () {
if (enemiesSpawned < enemiesPerWave) {
spawnTimer++;
if (spawnTimer >= 90) {
spawnEnemy();
enemiesSpawned++;
spawnTimer = 0;
}
} else if (enemies.length === 0 && !waveComplete) {
waveComplete = true;
coins += 50;
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
if (currentWave >= 10) {
LK.showYouWin();
return;
}
LK.setTimeout(function () {
nextWave();
}, 2000);
}
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var result = enemy.update();
if (result === 'reachedBase') {
var damage = 10;
if (enemy.type === 'fast') damage = 15;
if (enemy.type === 'strong') damage = 25;
baseHealth -= damage;
if (baseHealth < 0) baseHealth = 0;
baseHealthText.setText('Base: ' + baseHealth + '/' + maxBaseHealth);
LK.getSound('enemyReachBase').play();
if (baseHealth <= 0) {
LK.showGameOver();
return;
}
enemy.destroy();
enemies.splice(i, 1);
}
}
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
bullet.update();
if (bullet.x < -50 || bullet.x > gameWidth + 50 || bullet.y < -50 || bullet.y > gameHeight + 50) {
bullet.destroy();
bullets.splice(j, 1);
continue;
}
for (var k = enemies.length - 1; k >= 0; k--) {
var enemy = enemies[k];
if (bullet.intersects(enemy)) {
var isDead = enemy.takeDamage(bullet.damage);
if (bullet.type === 'splash') {
for (var l = 0; l < enemies.length; l++) {
var nearbyEnemy = enemies[l];
if (nearbyEnemy !== enemy) {
var dx = nearbyEnemy.x - bullet.x;
var dy = nearbyEnemy.y - bullet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 80) {
nearbyEnemy.takeDamage(Math.floor(bullet.damage * 0.5));
}
}
}
} else if (bullet.type === 'slow') {
enemy.applySlow(0.5, 180);
}
if (isDead) {
coins += enemy.reward;
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
LK.getSound('enemyHit').play();
enemy.destroy();
enemies.splice(k, 1);
}
bullet.destroy();
bullets.splice(j, 1);
break;
}
}
}
for (var m = 0; m < towers.length; m++) {
towers[m].update();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function (type, startX, startY, targetX, targetY, damage) {
var self = Container.call(this);
self.type = type || 'basic';
self.damage = damage || 10;
self.speed = 8;
self.targetX = targetX;
self.targetY = targetY;
var assetName = 'bullet';
if (type === 'splash') assetName = 'splashBullet';
if (type === 'slow') assetName = 'slowBullet';
var bulletGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.velocityX = dx / distance * self.speed;
self.velocityY = dy / distance * self.speed;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Enemy = Container.expand(function (type, pathIndex) {
var self = Container.call(this);
self.type = type || 'basic';
self.pathIndex = pathIndex || 0;
self.health = 30;
self.maxHealth = 30;
self.speed = 2;
self.reward = 5;
self.slowEffect = 0;
self.slowDuration = 0;
if (type === 'fast') {
self.health = 20;
self.maxHealth = 20;
self.speed = 4;
self.reward = 8;
} else if (type === 'strong') {
self.health = 80;
self.maxHealth = 80;
self.speed = 1.5;
self.reward = 15;
}
var assetName = 'basicEnemy';
if (type === 'fast') assetName = 'fastEnemy';
if (type === 'strong') assetName = 'strongEnemy';
var enemyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
return true;
}
return false;
};
self.applySlow = function (slowAmount, duration) {
self.slowEffect = slowAmount;
self.slowDuration = duration;
};
self.update = function () {
if (self.slowDuration > 0) {
self.slowDuration--;
if (self.slowDuration <= 0) {
self.slowEffect = 0;
}
}
var currentSpeed = self.speed * (1 - self.slowEffect);
if (self.pathIndex < gamePath.length - 1) {
var targetPoint = gamePath[self.pathIndex + 1];
var dx = targetPoint.x - self.x;
var dy = targetPoint.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 20) {
self.pathIndex++;
if (self.pathIndex >= gamePath.length - 1) {
return 'reachedBase';
}
} else {
self.x += dx / distance * currentSpeed;
self.y += dy / distance * currentSpeed;
}
}
return 'alive';
};
return self;
});
var Tower = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
self.type = type || 'basic';
self.level = 1;
self.damage = 10;
self.range = 150;
self.fireRate = 60;
self.lastFire = 0;
self.gridX = gridX;
self.gridY = gridY;
if (type === 'splash') {
self.damage = 15;
self.range = 120;
self.fireRate = 90;
} else if (type === 'slow') {
self.damage = 5;
self.range = 180;
self.fireRate = 45;
}
var assetName = 'basicTower';
if (type === 'splash') assetName = 'splashTower';
if (type === 'slow') assetName = 'slowTower';
var towerGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.getUpgradeCost = function () {
return self.level * 20;
};
self.upgrade = function () {
self.level++;
self.damage += Math.floor(self.damage * 0.5);
self.range += 20;
if (self.fireRate > 20) {
self.fireRate -= 5;
}
};
self.findTarget = function () {
var closestEnemy = null;
var closestDistance = self.range + 1;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < closestDistance) {
closestDistance = distance;
closestEnemy = enemy;
}
}
return closestEnemy;
};
self.fire = function (target) {
if (LK.ticks - self.lastFire >= self.fireRate) {
var bullet = new Bullet(self.type, self.x, self.y, target.x, target.y, self.damage);
bullets.push(bullet);
game.addChild(bullet);
self.lastFire = LK.ticks;
LK.getSound('shoot').play();
}
};
self.update = function () {
var target = self.findTarget();
if (target) {
self.fire(target);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
var gameWidth = 2048;
var gameHeight = 2732;
var gridSize = 100;
var towers = [];
var enemies = [];
var bullets = [];
var coins = 100;
var lives = 20;
var baseHealth = 100;
var maxBaseHealth = 100;
var currentWave = 1;
var enemiesSpawned = 0;
var enemiesPerWave = 5;
var spawnTimer = 0;
var waveComplete = false;
var selectedTowerType = 'basic';
var gamePath = [{
x: 0,
y: 400
}, {
x: 300,
y: 400
}, {
x: 300,
y: 800
}, {
x: 700,
y: 800
}, {
x: 700,
y: 1200
}, {
x: 1100,
y: 1200
}, {
x: 1100,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 1500,
y: 2000
}, {
x: 1900,
y: 2000
}];
function drawPath() {
for (var i = 0; i < gamePath.length - 1; i++) {
var pathTile = game.attachAsset('pathTile', {
anchorX: 0.5,
anchorY: 0.5,
x: gamePath[i].x,
y: gamePath[i].y
});
}
}
drawPath();
var base = game.attachAsset('base', {
anchorX: 0.5,
anchorY: 0.5,
x: gamePath[gamePath.length - 1].x,
y: gamePath[gamePath.length - 1].y
});
var coinsText = new Text2('Coins: ' + coins, {
size: 60,
fill: 0xFFFF00
});
coinsText.anchor.set(0, 0);
LK.gui.topRight.addChild(coinsText);
var moneyText = new Text2('Money: ' + coins, {
size: 60,
fill: 0x00FF00
});
moneyText.anchor.set(0.5, 0);
moneyText.y = 70;
LK.gui.top.addChild(moneyText);
var livesText = new Text2('Lives: ' + lives, {
size: 60,
fill: 0xFF0000
});
livesText.anchor.set(0, 0);
livesText.y = 70;
LK.gui.topRight.addChild(livesText);
var waveText = new Text2('Wave: ' + currentWave, {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var baseHealthText = new Text2('Base: ' + baseHealth + '/' + maxBaseHealth, {
size: 60,
fill: 0x00FF00
});
baseHealthText.anchor.set(0, 0);
baseHealthText.y = 140;
LK.gui.topRight.addChild(baseHealthText);
var towerButtons = [];
var basicTowerBtn = new Text2('Basic ($20)', {
size: 40,
fill: 0xFFFFFF
});
basicTowerBtn.anchor.set(0, 1);
basicTowerBtn.y = -20;
LK.gui.bottomLeft.addChild(basicTowerBtn);
towerButtons.push({
btn: basicTowerBtn,
type: 'basic',
cost: 20
});
var splashTowerBtn = new Text2('Splash ($35)', {
size: 40,
fill: 0xFFFFFF
});
splashTowerBtn.anchor.set(0, 1);
splashTowerBtn.y = -70;
LK.gui.bottomLeft.addChild(splashTowerBtn);
towerButtons.push({
btn: splashTowerBtn,
type: 'splash',
cost: 35
});
var slowTowerBtn = new Text2('Slow ($25)', {
size: 40,
fill: 0xFFFFFF
});
slowTowerBtn.anchor.set(0, 1);
slowTowerBtn.y = -120;
LK.gui.bottomLeft.addChild(slowTowerBtn);
towerButtons.push({
btn: slowTowerBtn,
type: 'slow',
cost: 25
});
var enemyButtons = [];
var selectedEnemyType = 'basic';
var boughtEnemies = {
basic: 0,
fast: 0,
strong: 0
};
var buyBasicEnemyBtn = new Text2('Buy Basic Enemy ($30)', {
size: 40,
fill: 0xFF6666
});
buyBasicEnemyBtn.anchor.set(1, 1);
buyBasicEnemyBtn.y = -20;
LK.gui.bottomRight.addChild(buyBasicEnemyBtn);
enemyButtons.push({
btn: buyBasicEnemyBtn,
type: 'basic',
cost: 30
});
var buyFastEnemyBtn = new Text2('Buy Fast Enemy ($50)', {
size: 40,
fill: 0xFF69B4
});
buyFastEnemyBtn.anchor.set(1, 1);
buyFastEnemyBtn.y = -70;
LK.gui.bottomRight.addChild(buyFastEnemyBtn);
enemyButtons.push({
btn: buyFastEnemyBtn,
type: 'fast',
cost: 50
});
var buyStrongEnemyBtn = new Text2('Buy Strong Enemy ($80)', {
size: 40,
fill: 0x8B0000
});
buyStrongEnemyBtn.anchor.set(1, 1);
buyStrongEnemyBtn.y = -120;
LK.gui.bottomRight.addChild(buyStrongEnemyBtn);
enemyButtons.push({
btn: buyStrongEnemyBtn,
type: 'strong',
cost: 80
});
var boughtEnemiesText = new Text2('Enemies: B:0 F:0 S:0', {
size: 50,
fill: 0xFFD700
});
boughtEnemiesText.anchor.set(0, 0);
boughtEnemiesText.y = 210;
LK.gui.topRight.addChild(boughtEnemiesText);
function getTowerCost(type) {
if (type === 'basic') return 20;
if (type === 'splash') return 35;
if (type === 'slow') return 25;
return 20;
}
function getEnemyCost(type) {
if (type === 'basic') return 30;
if (type === 'fast') return 50;
if (type === 'strong') return 80;
return 30;
}
function buyEnemy(type) {
var cost = getEnemyCost(type);
if (coins >= cost) {
coins -= cost;
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
selectedEnemyType = type;
boughtEnemies[type]++;
updateBoughtEnemiesDisplay();
}
}
function updateBoughtEnemiesDisplay() {
boughtEnemiesText.setText('Enemies: B:' + boughtEnemies.basic + ' F:' + boughtEnemies.fast + ' S:' + boughtEnemies.strong);
}
function placeEnemy(x, y) {
if (boughtEnemies[selectedEnemyType] > 0) {
var enemy = new Enemy(selectedEnemyType, 0);
enemy.x = x;
enemy.y = y;
boughtEnemies[selectedEnemyType]--;
updateBoughtEnemiesDisplay();
enemies.push(enemy);
game.addChild(enemy);
}
}
function canPlaceTower(x, y) {
var gridX = Math.floor(x / gridSize);
var gridY = Math.floor(y / gridSize);
for (var i = 0; i < towers.length; i++) {
if (towers[i].gridX === gridX && towers[i].gridY === gridY) {
return false;
}
}
for (var j = 0; j < gamePath.length; j++) {
var pathGridX = Math.floor(gamePath[j].x / gridSize);
var pathGridY = Math.floor(gamePath[j].y / gridSize);
if (pathGridX === gridX && pathGridY === gridY) {
return false;
}
}
return true;
}
function spawnEnemy() {
var enemyType = 'basic';
if (currentWave > 3 && Math.random() < 0.3) {
enemyType = 'fast';
}
if (currentWave > 5 && Math.random() < 0.2) {
enemyType = 'strong';
}
var enemy = new Enemy(enemyType, 0);
enemy.x = gamePath[0].x;
enemy.y = gamePath[0].y;
enemies.push(enemy);
game.addChild(enemy);
}
function nextWave() {
currentWave++;
enemiesPerWave = Math.floor(5 + currentWave * 1.2);
enemiesSpawned = 0;
waveComplete = false;
waveText.setText('Wave: ' + currentWave);
}
game.down = function (x, y, obj) {
for (var i = 0; i < towerButtons.length; i++) {
var btnData = towerButtons[i];
if (btnData.btn.getBounds().contains(x, y)) {
selectedTowerType = btnData.type;
return;
}
}
// Check enemy purchase buttons
for (var j = 0; j < enemyButtons.length; j++) {
var enemyBtnData = enemyButtons[j];
if (enemyBtnData.btn.getBounds().contains(x, y)) {
buyEnemy(enemyBtnData.type);
return;
}
}
// Check if placing enemy
if (boughtEnemies[selectedEnemyType] > 0) {
placeEnemy(x, y);
return;
}
if (canPlaceTower(x, y) && coins >= getTowerCost(selectedTowerType)) {
var gridX = Math.floor(x / gridSize);
var gridY = Math.floor(y / gridSize);
var tower = new Tower(selectedTowerType, gridX, gridY);
tower.x = gridX * gridSize + gridSize / 2;
tower.y = gridY * gridSize + gridSize / 2;
towers.push(tower);
game.addChild(tower);
coins -= getTowerCost(selectedTowerType);
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
}
};
game.update = function () {
if (enemiesSpawned < enemiesPerWave) {
spawnTimer++;
if (spawnTimer >= 90) {
spawnEnemy();
enemiesSpawned++;
spawnTimer = 0;
}
} else if (enemies.length === 0 && !waveComplete) {
waveComplete = true;
coins += 50;
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
if (currentWave >= 10) {
LK.showYouWin();
return;
}
LK.setTimeout(function () {
nextWave();
}, 2000);
}
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var result = enemy.update();
if (result === 'reachedBase') {
var damage = 10;
if (enemy.type === 'fast') damage = 15;
if (enemy.type === 'strong') damage = 25;
baseHealth -= damage;
if (baseHealth < 0) baseHealth = 0;
baseHealthText.setText('Base: ' + baseHealth + '/' + maxBaseHealth);
LK.getSound('enemyReachBase').play();
if (baseHealth <= 0) {
LK.showGameOver();
return;
}
enemy.destroy();
enemies.splice(i, 1);
}
}
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
bullet.update();
if (bullet.x < -50 || bullet.x > gameWidth + 50 || bullet.y < -50 || bullet.y > gameHeight + 50) {
bullet.destroy();
bullets.splice(j, 1);
continue;
}
for (var k = enemies.length - 1; k >= 0; k--) {
var enemy = enemies[k];
if (bullet.intersects(enemy)) {
var isDead = enemy.takeDamage(bullet.damage);
if (bullet.type === 'splash') {
for (var l = 0; l < enemies.length; l++) {
var nearbyEnemy = enemies[l];
if (nearbyEnemy !== enemy) {
var dx = nearbyEnemy.x - bullet.x;
var dy = nearbyEnemy.y - bullet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 80) {
nearbyEnemy.takeDamage(Math.floor(bullet.damage * 0.5));
}
}
}
} else if (bullet.type === 'slow') {
enemy.applySlow(0.5, 180);
}
if (isDead) {
coins += enemy.reward;
coinsText.setText('Coins: ' + coins);
moneyText.setText('Money: ' + coins);
LK.getSound('enemyHit').play();
enemy.destroy();
enemies.splice(k, 1);
}
bullet.destroy();
bullets.splice(j, 1);
break;
}
}
}
for (var m = 0; m < towers.length; m++) {
towers[m].update();
}
};