User prompt
5 damage per second
User prompt
Howtoplaydeki kulenin hasarını saniyede şukadar hasar olarak değiştir
User prompt
Howtoplay deki bactomenun yu aşağı al
User prompt
Howtoplay deki ni aşağı al
User prompt
Back to menü yü aşağı al
User prompt
How to play deki yazıları çok az aşağı al
User prompt
Howtoplay de nasıl oynanılıcağı karakterlerin sağlığı ,hasarı falan herşey yazsın
User prompt
Howtoplay i güncelle
User prompt
Her işçi farklı coine yönelsin
User prompt
Her işçi farklı coine yönetsin
User prompt
Karekter düşman karakterleri öldürdükten sonra kuleye saldırsınlar
User prompt
Zombi modunda zombiler başlangıçtan 30 saniye sonra çıksınlar
User prompt
Dalga lar daha yavaş gelsin ve kule yakındaki sadece 1 karektere hasar verebilsin
User prompt
En üstte yazsın
User prompt
Her wave de ekranda kaçıncı wave olduğu yazsın
User prompt
Zombi modunda zombiler tek tek değil dalga halinde gelsinler her dalga bir öncekinden güçlü olsun
User prompt
Sadece zombie Mode yi aşağı al
User prompt
Normal modu daha üste al
User prompt
ZombieMode yerine "ZombieMode " olsun
User prompt
Normalmode yerine "normalmode" assetini kullan
User prompt
Normal Mode yerine Normalmode Zombi Mode yerine ZombieMode olsun
User prompt
Dragon ,saldırı yaparken dragonattack olsun
User prompt
Düşmanları öldürdüklerinde ise kuleye saldırsınlar
User prompt
Karakterlerin tek amacı kuleyi yıkmak değil aynı zamanda düşman savaşçıları öldürmek olsun
/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Arrow = Container.expand(function (team, startX, startY, targetX, targetY, damage) {
var self = Container.call(this);
var graphics = self.attachAsset('Arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.team = team;
self.damage = damage;
self.speed = 8;
self.target = null;
// Calculate direction
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.directionX = dx / distance;
self.directionY = dy / distance;
// Set rotation to point toward target
self.rotation = Math.atan2(dy, dx);
// Position arrow at start
self.x = startX;
self.y = startY;
self.update = function () {
// Move arrow
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Check if arrow is off screen
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
// Remove from arrows array
for (var i = arrows.length - 1; i >= 0; i--) {
if (arrows[i] === self) {
arrows.splice(i, 1);
break;
}
}
}
// Check collision with enemy units
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
if (self.intersects(enemy)) {
enemy.health -= self.damage;
if (enemy.health <= 0) {
enemyUnits.splice(i, 1);
enemy.destroy();
}
self.destroy();
// Remove from arrows array
for (var j = arrows.length - 1; j >= 0; j--) {
if (arrows[j] === self) {
arrows.splice(j, 1);
break;
}
}
return;
}
}
// Check collision with enemy towers
var enemyTowers = self.team === 'player' ? aiTowers : playerTowers;
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
if (self.intersects(tower)) {
tower.health -= self.damage;
if (tower.health <= 0) {
enemyTowers.splice(i, 1);
tower.destroy();
LK.getSound('towerDestroyed').play();
}
self.destroy();
// Remove from arrows array
for (var j = arrows.length - 1; j >= 0; j--) {
if (arrows[j] === self) {
arrows.splice(j, 1);
break;
}
}
return;
}
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 1;
self.collected = false;
return self;
});
var CombatUnit = Container.expand(function (team, unitType) {
var self = Container.call(this);
var assetName = team === 'player' ? unitType : 'ai' + unitType.charAt(0).toUpperCase() + unitType.slice(1);
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.team = team;
self.unitType = unitType;
self.speed = unitType === 'dragon' ? 3 : unitType === 'wizard' ? 1.5 : unitType === 'archer' ? 2.5 : 2;
self.damage = unitType === 'dragon' ? 40 : unitType === 'wizard' ? 30 : unitType === 'archer' ? 20 : 10;
self.health = unitType === 'dragon' ? 50 : unitType === 'wizard' ? 40 : unitType === 'archer' ? 30 : unitType === 'warrior' ? 20 : 10;
self.maxHealth = self.health;
self.attackRange = unitType === 'wizard' ? 100 : unitType === 'archer' ? 200 : 50;
self.attackCooldown = 0;
self.target = null;
self.isWaiting = !zombieMode && team === 'player'; // Only player units wait in normal mode
// Create health bar background (black)
self.healthBarBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.75
});
self.healthBarBg.x = 0;
self.healthBarBg.y = -120;
self.healthBarBg.tint = team === 'player' ? 0x0000ff : 0x000000;
self.addChild(self.healthBarBg);
// Create health bar (green for player, red for AI)
self.healthBar = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.75
});
self.healthBar.x = 0;
self.healthBar.y = -120;
self.healthBar.tint = team === 'player' ? 0x00ff00 : 0xff0000;
self.addChild(self.healthBar);
self.healthText = new Text2(self.health.toString(), {
size: 50,
fill: '#ffffff'
});
self.healthText.anchor.set(0.5, 0.5);
self.addChild(self.healthText);
self.healthText.x = 0;
self.healthText.y = -120;
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
// In zombie mode, player units prioritize attacking zombies
if (zombieMode && self.team === 'player' && self.unitType !== 'worker') {
self.attackZombies();
} else if (!zombieMode && self.team === 'player' && self.isWaiting) {
// In normal mode, player units wait unless attack is triggered
// Stay in position and don't move
} else {
if (!self.target) {
self.findNearestEnemyTower();
} else {
self.moveToTarget();
}
// Combat with nearby enemy units
self.combatNearbyEnemies();
}
self.healthText.setText(self.health.toString());
// Update health bar scale based on health percentage
var healthPercentage = self.health / self.maxHealth;
tween(self.healthBar, {
scaleX: 1.5 * healthPercentage
}, {
duration: 200
});
};
self.findNearestEnemyTower = function () {
// In zombie mode, player units should prioritize attacking zombies
if (zombieMode && self.team === 'player' && self.unitType !== 'worker') {
var nearestZombie = null;
var nearestDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
var distance = Math.sqrt(Math.pow(zombie.x - self.x, 2) + Math.pow(zombie.y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestZombie = zombie;
}
}
// If we found a zombie, target it
if (nearestZombie) {
self.target = nearestZombie;
return;
}
}
// Find nearest target - prioritize ALL enemy units first (including workers), then towers
var nearestTarget = null;
var nearestDistance = Infinity;
// First check all enemy units (including workers)
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
// Target all enemy units now, including workers
if (self.unitType !== 'worker') {
var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = enemy;
}
}
}
// Only target towers if no enemy units remain
if (!nearestTarget) {
var enemyTowers = self.team === 'player' ? aiTowers : playerTowers;
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
var distance = Math.sqrt(Math.pow(tower.x - self.x, 2) + Math.pow(tower.y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = tower;
}
}
}
self.target = nearestTarget;
};
self.moveToTarget = function () {
if (!self.target) {
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.attackRange) {
self.attackTarget();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.attackTarget = function () {
if (self.attackCooldown <= 0 && self.target) {
if (self.unitType === 'archer') {
// Archer shoots arrow
var arrow = new Arrow(self.team, self.x, self.y, self.target.x, self.target.y, self.damage);
arrows.push(arrow);
game.addChild(arrow);
} else if (self.unitType === 'wizard') {
// Wizard shoots magic
var magic = new Magic(self.team, self.x, self.y, self.target.x, self.target.y, self.damage);
magics.push(magic);
game.addChild(magic);
} else if (self.unitType === 'dragon') {
// Change to attack asset for all dragon attacks
self.removeChild(graphics);
var assetName = 'DragonAttack';
graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Dragon shoots fire with 1 damage
var fire = new Fire(self.team, self.x, self.y, self.target.x, self.target.y, 1);
fires.push(fire);
game.addChild(fire);
} else {
// Melee attack
self.target.health -= self.damage;
if (self.target.health <= 0) {
// Check if target is a unit or tower
if (self.target.unitType) {
// Target is a unit
self.destroyUnit();
} else {
// Target is a tower
self.destroyTower();
}
}
}
// Set dragon attack cooldown to 3 frames (0.05 seconds)
if (self.unitType === 'dragon') {
self.attackCooldown = 3;
} else {
self.attackCooldown = 60;
}
LK.getSound('attack').play();
}
};
self.destroyUnit = function () {
var units = self.team === 'player' ? aiUnits : playerUnits;
var index = units.indexOf(self.target);
if (index > -1) {
units.splice(index, 1);
self.target.destroy();
self.target = null;
}
};
self.destroyTower = function () {
var towers = self.team === 'player' ? aiTowers : playerTowers;
var index = towers.indexOf(self.target);
if (index > -1) {
towers.splice(index, 1);
self.target.destroy();
LK.getSound('towerDestroyed').play();
self.target = null;
}
};
self.attackZombies = function () {
// Find nearest zombie to target
var nearestZombie = null;
var nearestDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
var dx = zombie.x - self.x;
var dy = zombie.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestZombie = zombie;
}
}
// Move toward and attack nearest zombie
if (nearestZombie) {
var dx = nearestZombie.x - self.x;
var dy = nearestZombie.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Move toward zombie if not in attack range
if (distance > self.attackRange) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (self.attackCooldown <= 0) {
// Attack zombie based on unit type
if (self.unitType === 'archer') {
// Archer shoots arrow at zombie
var arrow = new Arrow(self.team, self.x, self.y, nearestZombie.x, nearestZombie.y, self.damage);
arrows.push(arrow);
game.addChild(arrow);
} else if (self.unitType === 'wizard') {
// Wizard shoots magic at zombie
var magic = new Magic(self.team, self.x, self.y, nearestZombie.x, nearestZombie.y, self.damage);
magics.push(magic);
game.addChild(magic);
} else if (self.unitType === 'dragon') {
// Change to attack asset for dragon zombie attacks
self.removeChild(graphics);
var assetName = 'DragonAttack';
graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Dragon shoots fire at zombie
var fire = new Fire(self.team, self.x, self.y, nearestZombie.x, nearestZombie.y, self.damage);
fires.push(fire);
game.addChild(fire);
} else {
// Melee attack (warrior)
nearestZombie.health -= self.damage;
if (nearestZombie.health <= 0) {
for (var j = 0; j < zombies.length; j++) {
if (zombies[j] === nearestZombie) {
zombies.splice(j, 1);
nearestZombie.destroy();
break;
}
}
}
}
self.attackCooldown = 60; // 1 second cooldown
LK.getSound('attack').play();
}
}
};
self.combatNearbyEnemies = function () {
if (self.attackCooldown <= 0) {
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
var meleeRange = 60; // Close combat range
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
// Skip workers in combat
if (enemy.unitType === 'worker') {
continue;
}
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If enemy unit is within melee range, attack it
if (distance <= meleeRange) {
enemy.health -= self.damage;
self.attackCooldown = 60; // 1 second cooldown
LK.getSound('attack').play();
// Check if enemy is destroyed
if (enemy.health <= 0) {
enemyUnits.splice(i, 1);
enemy.destroy();
}
break; // Only attack one enemy per cycle
}
}
}
};
return self;
});
var Fire = Container.expand(function (team, startX, startY, targetX, targetY, damage) {
var self = Container.call(this);
var graphics = self.attachAsset('Magic', {
anchorX: 0.5,
anchorY: 0.5
});
self.team = team;
self.damage = damage;
self.speed = 4;
self.target = null;
// Calculate direction
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.directionX = dx / distance;
self.directionY = dy / distance;
// Position fire at start
self.x = startX;
self.y = startY;
// Add fire effect - orange/red tint and scaling
graphics.tint = 0xff4500; // Orange-red fire color
tween(graphics, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut
});
self.update = function () {
// Move fire
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Add fire flicker rotation
graphics.rotation += 0.15;
// Check if fire is off screen
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
// Remove from fires array
for (var i = fires.length - 1; i >= 0; i--) {
if (fires[i] === self) {
fires.splice(i, 1);
break;
}
}
}
// Check collision with enemy units
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
if (self.intersects(enemy)) {
enemy.health -= self.damage;
if (enemy.health <= 0) {
enemyUnits.splice(i, 1);
enemy.destroy();
}
self.destroy();
// Remove from fires array
for (var j = fires.length - 1; j >= 0; j--) {
if (fires[j] === self) {
fires.splice(j, 1);
break;
}
}
return;
}
}
// Check collision with enemy towers
var enemyTowers = self.team === 'player' ? aiTowers : playerTowers;
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
if (self.intersects(tower)) {
tower.health -= self.damage;
if (tower.health <= 0) {
enemyTowers.splice(i, 1);
tower.destroy();
LK.getSound('towerDestroyed').play();
}
self.destroy();
// Remove from fires array
for (var j = fires.length - 1; j >= 0; j--) {
if (fires[j] === self) {
fires.splice(j, 1);
break;
}
}
return;
}
}
};
return self;
});
var Magic = Container.expand(function (team, startX, startY, targetX, targetY, damage) {
var self = Container.call(this);
var graphics = self.attachAsset('Magic', {
anchorX: 0.5,
anchorY: 0.5
});
self.team = team;
self.damage = damage;
self.speed = 6;
self.target = null;
// Calculate direction
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.directionX = dx / distance;
self.directionY = dy / distance;
// Position magic at start
self.x = startX;
self.y = startY;
// Add magical glow effect
tween(graphics, {
tint: 0x9966ff
}, {
duration: 500,
easing: tween.easeInOut
});
tween(graphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut
});
self.update = function () {
// Move magic
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Add sparkle rotation
graphics.rotation += 0.1;
// Check if magic is off screen
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
// Remove from magics array
for (var i = magics.length - 1; i >= 0; i--) {
if (magics[i] === self) {
magics.splice(i, 1);
break;
}
}
}
// Check collision with enemy units
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
if (self.intersects(enemy)) {
enemy.health -= self.damage;
if (enemy.health <= 0) {
enemyUnits.splice(i, 1);
enemy.destroy();
}
self.destroy();
// Remove from magics array
for (var j = magics.length - 1; j >= 0; j--) {
if (magics[j] === self) {
magics.splice(j, 1);
break;
}
}
return;
}
}
// Check collision with enemy towers
var enemyTowers = self.team === 'player' ? aiTowers : playerTowers;
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
if (self.intersects(tower)) {
tower.health -= self.damage;
if (tower.health <= 0) {
enemyTowers.splice(i, 1);
tower.destroy();
LK.getSound('towerDestroyed').play();
}
self.destroy();
// Remove from magics array
for (var j = magics.length - 1; j >= 0; j--) {
if (magics[j] === self) {
magics.splice(j, 1);
break;
}
}
return;
}
}
};
return self;
});
var Tower = Container.expand(function (team) {
var self = Container.call(this);
var assetName = team === 'player' ? 'playerTower' : 'aiTower';
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1.0
});
self.team = team;
self.health = 500;
self.maxHealth = 500;
// Create health bar background (black)
self.healthBarBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.08,
scaleY: 0.625
});
self.healthBarBg.x = 0;
self.healthBarBg.y = -262.5;
self.healthBarBg.tint = 0x0000ff;
self.addChild(self.healthBarBg);
// Create health bar (green for player, red for AI)
self.healthBar = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.08,
scaleY: 0.625
});
self.healthBar.x = 0;
self.healthBar.y = -262.5;
self.healthBar.tint = team === 'player' ? 0x00ff00 : 0xff0000;
self.addChild(self.healthBar);
self.healthText = new Text2(self.health.toString(), {
size: 42,
fill: '#ffffff'
});
self.healthText.anchor.set(0.5, 0.5);
self.addChild(self.healthText);
self.healthText.x = 0;
self.healthText.y = -262.5;
self.attackCooldown = 0;
self.attackRange = 400;
// Damage area outline removed as requested
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
self.attackNearbyEnemies();
self.healthText.setText(self.health.toString());
// Update health bar scale based on health percentage
var healthPercentage = self.health / self.maxHealth;
tween(self.healthBar, {
scaleX: 2.08 * healthPercentage
}, {
duration: 200
});
};
self.attackNearbyEnemies = function () {
if (self.attackCooldown <= 0) {
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
var nearestEnemy = null;
var nearestDistance = Infinity;
// Find nearest enemy unit within attack range
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
var dx = enemy.x - self.x;
var dy = enemy.y - (self.y - 131.25); // Adjust for tower center position
var distance = Math.sqrt(dx * dx + dy * dy);
// Only consider units within the attack range
if (distance <= self.attackRange && distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
// Attack only the nearest enemy if found
if (nearestEnemy) {
nearestEnemy.health -= 1; // Deal 1 damage as specified
self.attackCooldown = 3; // 0.05 seconds at 60 FPS
LK.getSound('attack').play();
if (nearestEnemy.health <= 0) {
var index = enemyUnits.indexOf(nearestEnemy);
if (index > -1) {
self.destroyUnit(nearestEnemy, enemyUnits, index);
}
}
}
// In zombie mode, player towers also attack zombies (find nearest zombie)
if (zombieMode && self.team === 'player') {
var nearestZombie = null;
var nearestZombieDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
var dx = zombie.x - self.x;
var dy = zombie.y - (self.y - 131.25);
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.attackRange && distance < nearestZombieDistance) {
nearestZombieDistance = distance;
nearestZombie = zombie;
}
}
// Attack only the nearest zombie if found
if (nearestZombie && !nearestEnemy) {
// Only attack zombie if no enemy unit was attacked
nearestZombie.health -= 1;
self.attackCooldown = 3;
LK.getSound('attack').play();
if (nearestZombie.health <= 0) {
var index = zombies.indexOf(nearestZombie);
if (index > -1) {
zombies.splice(index, 1);
nearestZombie.destroy();
}
}
}
}
}
};
self.showDamageArea = function () {
// No visual effects when towers attack
};
self.destroyUnit = function (unit, unitsArray, index) {
unitsArray.splice(index, 1);
unit.destroy();
};
return self;
});
var Worker = Container.expand(function (team) {
var self = Container.call(this);
var assetName = team === 'player' ? 'worker' : 'aiWorker';
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.team = team;
self.speed = 4;
self.target = null;
self.collectRange = 40;
self.health = 10;
self.maxHealth = 10;
// Create health bar background (black)
self.healthBarBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.75
});
self.healthBarBg.x = 0;
self.healthBarBg.y = -120;
self.healthBarBg.tint = 0x000000;
self.addChild(self.healthBarBg);
// Create health bar (green for player, red for AI)
self.healthBar = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.75
});
self.healthBar.x = 0;
self.healthBar.y = -120;
self.healthBar.tint = team === 'player' ? 0x00ff00 : 0xff0000;
self.addChild(self.healthBar);
self.healthText = new Text2(self.health.toString(), {
size: 50,
fill: '#ffffff'
});
self.healthText.anchor.set(0.5, 0.5);
self.addChild(self.healthText);
self.healthText.x = 0;
self.healthText.y = -120;
self.update = function () {
if (!self.target) {
self.findNearestCoin();
} else {
self.moveToTarget();
}
// Workers can defend themselves
self.defendSelf();
self.healthText.setText(self.health.toString());
// Update health bar scale based on health percentage
var healthPercentage = self.health / self.maxHealth;
tween(self.healthBar, {
scaleX: 1.5 * healthPercentage
}, {
duration: 200
});
};
self.findNearestCoin = function () {
var targetCoins = self.team === 'player' ? playerCoins_array : aiCoins_array;
var teamWorkers = self.team === 'player' ? playerUnits : aiUnits;
var availableCoins = [];
// First, collect all untargeted coins
for (var i = 0; i < targetCoins.length; i++) {
var coin = targetCoins[i];
if (!coin.collected) {
// Check if another worker is already targeting this coin
var isTargeted = false;
for (var j = 0; j < teamWorkers.length; j++) {
var worker = teamWorkers[j];
if (worker.unitType === 'worker' && worker !== self && worker.target === coin) {
isTargeted = true;
break;
}
}
if (!isTargeted) {
availableCoins.push(coin);
}
}
}
// If no available coins, clear target
if (availableCoins.length === 0) {
self.target = null;
return;
}
// Get worker index to create unique targeting preference
var workerIndex = -1;
for (var i = 0; i < teamWorkers.length; i++) {
if (teamWorkers[i] === self && teamWorkers[i].unitType === 'worker') {
workerIndex = i;
break;
}
}
// Use worker index to create different targeting preferences
var targetCoin = null;
if (workerIndex >= 0 && workerIndex < availableCoins.length) {
// Each worker gets a different coin based on their index
targetCoin = availableCoins[workerIndex];
} else {
// If more workers than coins, use modulo to cycle through available coins
var coinIndex = workerIndex % availableCoins.length;
targetCoin = availableCoins[coinIndex];
}
// If targeted approach fails, fall back to nearest coin
if (!targetCoin) {
var nearestCoin = null;
var nearestDistance = Infinity;
for (var i = 0; i < availableCoins.length; i++) {
var coin = availableCoins[i];
var distance = Math.sqrt(Math.pow(coin.x - self.x, 2) + Math.pow(coin.y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestCoin = coin;
}
}
targetCoin = nearestCoin;
}
self.target = targetCoin;
};
self.moveToTarget = function () {
if (!self.target || self.target.collected) {
self.target = null;
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectRange) {
self.collectCoin();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.collectCoin = function () {
if (self.target && !self.target.collected) {
self.target.collected = true;
if (self.team === 'player') {
playerCoins += self.target.value;
} else {
aiCoins += self.target.value;
}
LK.getSound('coinCollect').play();
self.target = null;
}
};
self.defendSelf = function () {
var enemyUnits = self.team === 'player' ? aiUnits : playerUnits;
var defenseRange = 50;
for (var i = 0; i < enemyUnits.length; i++) {
var enemy = enemyUnits[i];
// Workers only defend against other workers
if (enemy.unitType === 'worker') {
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= defenseRange) {
enemy.health -= 5; // Workers do less damage
LK.getSound('attack').play();
if (enemy.health <= 0) {
enemyUnits.splice(i, 1);
enemy.destroy();
}
break;
}
}
}
};
return self;
});
var Zombie = Container.expand(function (waveNumber) {
var self = Container.call(this);
var graphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
// Stats increase with wave number
var waveMultiplier = waveNumber || 1;
self.speed = 1.5 + (waveMultiplier - 1) * 0.2; // Speed increases slightly each wave
self.health = 30 + (waveMultiplier - 1) * 15; // Health increases by 15 each wave
self.maxHealth = self.health;
self.damage = 10 + (waveMultiplier - 1) * 5; // Damage increases by 5 each wave
self.waveNumber = waveNumber;
self.target = null;
self.attackCooldown = 0;
// Create health bar background (black)
self.healthBarBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.75
});
self.healthBarBg.x = 0;
self.healthBarBg.y = -120;
self.healthBarBg.tint = 0x000000;
self.addChild(self.healthBarBg);
// Create health bar (red for zombies)
self.healthBar = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.75
});
self.healthBar.x = 0;
self.healthBar.y = -120;
self.healthBar.tint = 0xff0000;
self.addChild(self.healthBar);
self.healthText = new Text2(self.health.toString(), {
size: 50,
fill: '#ffffff'
});
self.healthText.anchor.set(0.5, 0.5);
self.addChild(self.healthText);
self.healthText.x = 0;
self.healthText.y = -120;
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
if (!self.target) {
self.findNearestPlayerTower();
} else {
self.moveToTarget();
}
// Attack nearby player units
self.attackNearbyPlayerUnits();
self.healthText.setText(self.health.toString());
// Update health bar scale based on health percentage
var healthPercentage = self.health / self.maxHealth;
tween(self.healthBar, {
scaleX: 1.5 * healthPercentage
}, {
duration: 200
});
};
self.findNearestPlayerTower = function () {
// Target player tower
if (playerTowers.length > 0) {
self.target = playerTowers[0];
}
};
self.moveToTarget = function () {
if (!self.target) {
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 60) {
self.attackTarget();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.attackTarget = function () {
if (self.attackCooldown <= 0 && self.target) {
self.target.health -= self.damage;
self.attackCooldown = 60;
LK.getSound('attack').play();
if (self.target.health <= 0) {
// Tower destroyed
var index = playerTowers.indexOf(self.target);
if (index > -1) {
playerTowers.splice(index, 1);
self.target.destroy();
LK.getSound('towerDestroyed').play();
self.target = null;
}
}
}
};
self.attackNearbyPlayerUnits = function () {
if (self.attackCooldown <= 0) {
var meleeRange = 60;
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
var dx = unit.x - self.x;
var dy = unit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= meleeRange) {
unit.health -= self.damage;
self.attackCooldown = 60;
LK.getSound('attack').play();
if (unit.health <= 0) {
playerUnits.splice(i, 1);
unit.destroy();
}
break;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu' or 'playing'
// Add menu background
var menuBackground = LK.getAsset('menuBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(menuBackground);
// Create menu overlay
var menuOverlay = new Container();
game.addChild(menuOverlay);
// Add towers asset at the top of the menu
var towersAsset = LK.getAsset('Towers', {
anchorX: 0.5,
anchorY: 0,
scaleX: 4.0,
scaleY: 4.0
});
towersAsset.x = 1024;
towersAsset.y = 50;
menuOverlay.addChild(towersAsset);
// Add app banner at top of menu
var appBanner = LK.getAsset('Appbanner', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 20
});
menuOverlay.addChild(appBanner);
// Start button background
var startButtonBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 1.5
});
startButtonBg.x = 1024;
startButtonBg.y = 1000;
startButtonBg.tint = 0x228b22;
menuOverlay.addChild(startButtonBg);
// Start button image
var startButton = LK.getAsset('StartGameButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 2.0
});
startButton.x = 1024;
startButton.y = 1000;
menuOverlay.addChild(startButton);
// How to Play button
var howToPlayButton = LK.getAsset('Howtoplay22', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 4.0
});
howToPlayButton.x = 1024;
howToPlayButton.y = 1615; // 1.3x higher (2100 - 485 = 1615)
menuOverlay.addChild(howToPlayButton);
// Play menu music when game starts
LK.playMusic('Menusong');
// How to Play instructions overlay
var howToPlayOverlay = new Container();
howToPlayOverlay.visible = false;
game.addChild(howToPlayOverlay);
// How to Play background
var howToPlayBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 18.0,
scaleY: 24.0
});
howToPlayBg.x = 1024;
howToPlayBg.y = 1366;
howToPlayBg.tint = 0x000000;
howToPlayBg.alpha = 0.9;
howToPlayOverlay.addChild(howToPlayBg);
// How to Play title
var howToPlayTitle = new Text2('HOW TO PLAY', {
size: 100,
fill: '#ffffff'
});
howToPlayTitle.anchor.set(0.5, 0.5);
howToPlayTitle.x = 1024;
howToPlayTitle.y = 400;
howToPlayOverlay.addChild(howToPlayTitle);
// How to Play instructions
var instructionsText = new Text2('NORMAL MODE:\n• Collect gold coins with workers\n• Spend gold to recruit units\n• Press Attack to command units to advance\n• Destroy enemy tower to win\n\nUNIT TYPES & STATS:\n• Worker: 5 gold, 10 HP, 5 damage, collects coins\n• Warrior: 10 gold, 20 HP, 10 damage, melee combat\n• Archer: 15 gold, 30 HP, 20 damage, ranged arrows\n• Wizard: 20 gold, 40 HP, 30 damage, magic attacks\n• Dragon: 25 gold, 50 HP, 40 damage, fire breath\n\nTOWERS:\n• Player Tower: 500 HP, 1 damage, attacks nearest enemy\n• AI Tower: 500 HP, 1 damage, attacks nearest enemy\n• Attack range: 400 pixels\n\nZOMBIE MODE:\n• Survive endless zombie waves\n• Units automatically attack zombies first\n• Zombies spawn 30 seconds after start\n• Wave 1: 5 zombies (30 HP, 10 damage)\n• Each wave: +2 zombies, +15 HP, +5 damage\n• Defend your tower at all costs!', {
size: 42,
fill: '#ffffff'
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 1024;
instructionsText.y = 1200;
howToPlayOverlay.addChild(instructionsText);
// Back button
var backButton = new Text2('BACK TO MENU', {
size: 80,
fill: '#ffff00'
});
backButton.anchor.set(0.5, 0.5);
backButton.x = 1024;
backButton.y = 1800;
howToPlayOverlay.addChild(backButton);
// Mode selection overlay
var modeSelectionOverlay = new Container();
modeSelectionOverlay.visible = false;
game.addChild(modeSelectionOverlay);
// Mode selection background
var modeSelectionBg = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 18.0,
scaleY: 24.0
});
modeSelectionBg.x = 1024;
modeSelectionBg.y = 1366;
modeSelectionBg.tint = 0x000000;
modeSelectionBg.alpha = 0.9;
modeSelectionOverlay.addChild(modeSelectionBg);
// Mode selection title
var modeSelectionTitle = new Text2('SELECT MODE', {
size: 100,
fill: '#ffffff'
});
modeSelectionTitle.anchor.set(0.5, 0.5);
modeSelectionTitle.x = 1024;
modeSelectionTitle.y = 600;
modeSelectionOverlay.addChild(modeSelectionTitle);
// Normal mode button
var normalModeButton = LK.getAsset('Normalmode', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
normalModeButton.x = 1024;
normalModeButton.y = 1000;
modeSelectionOverlay.addChild(normalModeButton);
// Zombie mode button in mode selection
var zombieModeSelectButton = LK.getAsset('Zombiemode', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
zombieModeSelectButton.x = 1024;
zombieModeSelectButton.y = 1400;
modeSelectionOverlay.addChild(zombieModeSelectButton);
// Back to menu button from mode selection
var backToMenuButton = new Text2('BACK TO MENU', {
size: 80,
fill: '#ffff00'
});
backToMenuButton.anchor.set(0.5, 0.5);
backToMenuButton.x = 1024;
backToMenuButton.y = 2000;
modeSelectionOverlay.addChild(backToMenuButton);
// Start button event handler - now shows mode selection
startButton.down = function () {
menuOverlay.visible = false;
modeSelectionOverlay.visible = true;
};
startButtonBg.down = function () {
menuOverlay.visible = false;
modeSelectionOverlay.visible = true;
};
// Normal mode button event handler
normalModeButton.down = function () {
zombieMode = false;
gameState = 'playing';
modeSelectionOverlay.visible = false;
LK.stopMusic(); // Stop menu music when starting game
initializeGame();
};
// Zombie mode button event handler in mode selection
zombieModeSelectButton.down = function () {
zombieMode = true;
gameState = 'playing';
modeSelectionOverlay.visible = false;
LK.stopMusic();
initializeGame();
};
// Back to menu button event handler
backToMenuButton.down = function () {
modeSelectionOverlay.visible = false;
menuOverlay.visible = true;
};
// How to Play button event handler
howToPlayButton.down = function () {
menuOverlay.visible = false;
howToPlayOverlay.visible = true;
};
// Back button event handler
backButton.down = function () {
howToPlayOverlay.visible = false;
menuOverlay.visible = true;
};
// Add game background (initially hidden)
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
background.visible = false;
game.addChild(background);
var playerCoins = 0;
var aiCoins = 0;
var playerTowers = [];
var aiTowers = [];
var coins = [];
var playerCoins_array = [];
var aiCoins_array = [];
var playerUnits = [];
var aiUnits = [];
var arrows = [];
var magics = [];
var fires = [];
var coinSpawnTimer = 0;
var aiActionTimer = 0;
var zombies = [];
var zombieSpawnTimer = 0;
var zombieMode = false;
var zombieWaveNumber = 1;
var zombieWaveSpawnTimer = 0;
var zombieWaveInProgress = false;
var zombiesInCurrentWave = 0;
var zombiesToSpawnInWave = 0;
// UI Elements
var coinDisplay = new Text2('Golds: 0', {
size: 80,
fill: '#ffff00'
});
coinDisplay.anchor.set(0.5, 0.5);
coinDisplay.x = 200;
coinDisplay.y = -273.75;
coinDisplay.visible = false;
LK.gui.bottom.addChild(coinDisplay);
// Attack button
var attackButton = new Text2('Attack', {
size: 80,
fill: '#ff0000'
});
attackButton.anchor.set(0.5, 0.5);
attackButton.x = -200;
attackButton.y = -273.75;
attackButton.visible = false;
LK.gui.bottom.addChild(attackButton);
var workerButton = new Text2('5', {
size: 32,
fill: '#ffffff'
});
workerButton.anchor.set(0.5, 0.5);
workerButton.x = -400;
workerButton.y = -45;
var warriorButton = new Text2('10', {
size: 32,
fill: '#ffffff'
});
warriorButton.anchor.set(0.5, 0.5);
warriorButton.x = -200;
warriorButton.y = -45;
var wizardButton = new Text2('20', {
size: 32,
fill: '#ffffff'
});
wizardButton.anchor.set(0.5, 0.5);
wizardButton.x = 200;
wizardButton.y = -45;
var archerButton = new Text2('15', {
size: 32,
fill: '#ffffff'
});
archerButton.anchor.set(0.5, 0.5);
archerButton.x = 0;
archerButton.y = -45;
var dragonButton = new Text2('25', {
size: 32,
fill: '#ffffff'
});
dragonButton.anchor.set(0.5, 0.5);
dragonButton.x = 400;
dragonButton.y = -45;
// Add unified black background behind all recruitment buttons and unit images
var unifiedBackground = LK.getAsset('blackBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 22.0,
scaleY: 2.8
});
unifiedBackground.x = 0;
unifiedBackground.y = -78;
unifiedBackground.tint = 0x000000;
unifiedBackground.alpha = 0.5;
unifiedBackground.visible = false;
LK.gui.bottom.addChild(unifiedBackground);
// Add unit images above recruitment buttons
var workerImage = LK.getAsset('worker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
workerImage.x = -400;
workerImage.y = -110;
LK.gui.bottom.addChild(workerImage);
var warriorImage = LK.getAsset('warrior', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
warriorImage.x = -200;
warriorImage.y = -110;
LK.gui.bottom.addChild(warriorImage);
var wizardImage = LK.getAsset('wizard', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
wizardImage.x = 200;
wizardImage.y = -110;
LK.gui.bottom.addChild(wizardImage);
var archerImage = LK.getAsset('archer', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
archerImage.x = 0;
archerImage.y = -110;
LK.gui.bottom.addChild(archerImage);
var dragonImage = LK.getAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
dragonImage.x = 400;
dragonImage.y = -110;
LK.gui.bottom.addChild(dragonImage);
// Wave display for zombie mode
var waveDisplay = new Text2('Wave: 1', {
size: 80,
fill: '#ff0000'
});
waveDisplay.anchor.set(0.5, 0.5);
waveDisplay.x = 0;
waveDisplay.y = 100;
waveDisplay.visible = false;
LK.gui.top.addChild(waveDisplay);
// Hide all UI elements initially (menu state)
workerButton.visible = false;
warriorButton.visible = false;
wizardButton.visible = false;
archerButton.visible = false;
dragonButton.visible = false;
workerImage.visible = false;
warriorImage.visible = false;
wizardImage.visible = false;
archerImage.visible = false;
dragonImage.visible = false;
// Add texts after backgrounds so they appear on top
LK.gui.bottom.addChild(workerButton);
LK.gui.bottom.addChild(warriorButton);
LK.gui.bottom.addChild(wizardButton);
LK.gui.bottom.addChild(archerButton);
LK.gui.bottom.addChild(dragonButton);
// Initialize towers
function initializeTowers() {
// Player tower
var playerTower = new Tower('player');
playerTower.x = 1024;
playerTower.y = 2300;
playerTowers.push(playerTower);
game.addChild(playerTower);
// AI tower (only in normal mode)
if (!zombieMode) {
var aiTower = new Tower('ai');
aiTower.x = 1024;
aiTower.y = 400;
aiTowers.push(aiTower);
game.addChild(aiTower);
}
}
;
function spawnCoin() {
// Spawn player coin
var playerCoin = new Coin();
playerCoin.x = Math.random() * 1800 + 124;
playerCoin.y = Math.random() * 1000 + 1200; // Lower half for player
playerCoins_array.push(playerCoin);
coins.push(playerCoin);
game.addChild(playerCoin);
// Spawn AI coin
var aiCoin = new Coin();
aiCoin.x = Math.random() * 1800 + 124;
aiCoin.y = Math.random() * 1000 + 400; // Upper half for AI
aiCoins_array.push(aiCoin);
coins.push(aiCoin);
game.addChild(aiCoin);
}
function spawnUnit(team, unitType) {
var unit;
var cost = unitType === 'worker' ? 5 : unitType === 'warrior' ? 10 : unitType === 'wizard' ? 20 : unitType === 'archer' ? 15 : 25;
if (team === 'player' && playerCoins >= cost) {
playerCoins -= cost;
if (unitType === 'worker') {
unit = new Worker('player');
} else {
unit = new CombatUnit('player', unitType);
}
if (!zombieMode && unitType !== 'worker') {
// Position combat units in front of tower in normal mode with better spacing
var unitCount = playerUnits.length;
var spreadRadius = 300;
var angle = unitCount * 0.5 % (Math.PI * 2);
unit.x = playerTowers[0].x + Math.cos(angle) * spreadRadius;
unit.y = playerTowers[0].y - 507 + Math.sin(angle) * 100;
} else {
var unitCount = playerUnits.length;
var spreadRadius = 200;
var angle = unitCount * 0.8 % (Math.PI * 2);
unit.x = playerTowers[0].x + Math.cos(angle) * spreadRadius;
unit.y = playerTowers[0].y - 100 + Math.sin(angle) * 50;
}
playerUnits.push(unit);
game.addChild(unit);
LK.getSound('unitSpawn').play();
} else if (team === 'ai' && aiCoins >= cost) {
aiCoins -= cost;
if (unitType === 'worker') {
unit = new Worker('ai');
} else {
unit = new CombatUnit('ai', unitType);
}
var unitCount = aiUnits.length;
var spreadRadius = 200;
var angle = unitCount * 0.8 % (Math.PI * 2);
unit.x = aiTowers[0].x + Math.cos(angle) * spreadRadius;
unit.y = aiTowers[0].y + 100 + Math.sin(angle) * 50;
aiUnits.push(unit);
game.addChild(unit);
}
}
function spawnZombie() {
var zombie = new Zombie(zombieWaveNumber);
zombie.x = Math.random() * 1800 + 124; // Random X position across screen width
zombie.y = 50; // Spawn at top of screen
zombies.push(zombie);
game.addChild(zombie);
}
function startZombieWave() {
zombieWaveInProgress = true;
zombiesToSpawnInWave = 3 + zombieWaveNumber * 2; // Wave 1: 5 zombies, Wave 2: 7 zombies, etc.
zombiesInCurrentWave = 0;
zombieWaveSpawnTimer = 0;
// Update wave display
if (zombieMode) {
waveDisplay.setText('Wave: ' + zombieWaveNumber);
}
}
function checkWaveComplete() {
// Check if all zombies in current wave are spawned and destroyed
if (zombieWaveInProgress && zombiesInCurrentWave >= zombiesToSpawnInWave && zombies.length === 0) {
zombieWaveInProgress = false;
zombieWaveNumber++;
// Start next wave after 10 seconds (doubled from 5 seconds)
zombieWaveSpawnTimer = -600; // 10 seconds delay before next wave
}
}
function aiLogic() {
if (aiActionTimer <= 0) {
if (aiCoins >= 25 && Math.random() < 0.1) {
spawnUnit('ai', 'dragon');
} else if (aiCoins >= 15 && Math.random() < 0.15) {
spawnUnit('ai', 'archer');
} else if (aiCoins >= 20 && Math.random() < 0.2) {
spawnUnit('ai', 'wizard');
} else if (aiCoins >= 10 && Math.random() < 0.3) {
spawnUnit('ai', 'warrior');
} else if (aiCoins >= 5 && Math.random() < 0.4) {
spawnUnit('ai', 'worker');
}
aiActionTimer = 120;
}
aiActionTimer--;
}
function checkGameEnd() {
if (playerTowers.length === 0) {
LK.showGameOver();
} else if (!zombieMode && aiTowers.length === 0) {
LK.showYouWin();
}
}
function cleanupCollectedCoins() {
// Clean up from main coins array
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i].collected) {
coins[i].destroy();
coins.splice(i, 1);
}
}
// Clean up from player coins array
for (var i = playerCoins_array.length - 1; i >= 0; i--) {
if (playerCoins_array[i].collected) {
playerCoins_array.splice(i, 1);
}
}
// Clean up from AI coins array
for (var i = aiCoins_array.length - 1; i >= 0; i--) {
if (aiCoins_array[i].collected) {
aiCoins_array.splice(i, 1);
}
}
}
// Button event handlers
workerButton.down = function () {
spawnUnit('player', 'worker');
};
warriorButton.down = function () {
spawnUnit('player', 'warrior');
};
wizardButton.down = function () {
spawnUnit('player', 'wizard');
};
archerButton.down = function () {
spawnUnit('player', 'archer');
};
dragonButton.down = function () {
spawnUnit('player', 'dragon');
};
// Character image event handlers
workerImage.down = function () {
spawnUnit('player', 'worker');
};
warriorImage.down = function () {
spawnUnit('player', 'warrior');
};
wizardImage.down = function () {
spawnUnit('player', 'wizard');
};
archerImage.down = function () {
spawnUnit('player', 'archer');
};
dragonImage.down = function () {
spawnUnit('player', 'dragon');
};
// Attack button event handler
attackButton.down = function () {
if (!zombieMode) {
// Make all waiting player units start attacking
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit.unitType !== 'worker') {
unit.isWaiting = false;
}
}
}
};
// Initialize game function
function initializeGame() {
background.visible = true;
// Show UI elements when game starts
coinDisplay.visible = true;
unifiedBackground.visible = true;
workerButton.visible = true;
warriorButton.visible = true;
wizardButton.visible = true;
archerButton.visible = true;
dragonButton.visible = true;
workerImage.visible = true;
warriorImage.visible = true;
wizardImage.visible = true;
archerImage.visible = true;
dragonImage.visible = true;
// Show attack button only in normal mode
if (!zombieMode) {
attackButton.visible = true;
} else {
// Show wave display in zombie mode
waveDisplay.visible = true;
waveDisplay.setText('Wave: ' + zombieWaveNumber);
}
// Reset zombie wave system
zombieWaveNumber = 1;
zombieWaveSpawnTimer = -1800; // 30 second delay (30 * 60 FPS = 1800 frames)
zombieWaveInProgress = false;
zombiesInCurrentWave = 0;
zombiesToSpawnInWave = 0;
// Play game music when match starts
LK.playMusic('Song');
initializeTowers();
// Spawn initial workers for both teams
var playerWorker = new Worker('player');
playerWorker.x = playerTowers[0].x + 50;
playerWorker.y = playerTowers[0].y - 100;
playerUnits.push(playerWorker);
game.addChild(playerWorker);
// AI worker (only in normal mode)
if (!zombieMode) {
var aiWorker = new Worker('ai');
aiWorker.x = aiTowers[0].x + 50;
aiWorker.y = aiTowers[0].y + 100;
aiUnits.push(aiWorker);
game.addChild(aiWorker);
}
}
// Main game loop
game.update = function () {
if (gameState === 'playing') {
// Update coin display
coinDisplay.setText('Golds: ' + playerCoins);
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer >= 36) {
// 5x more frequent (180/5 = 36)
spawnCoin();
coinSpawnTimer = 0;
}
// AI logic (only in normal mode)
if (!zombieMode) {
aiLogic();
}
// Clean up collected coins
cleanupCollectedCoins();
// Zombie mode logic
if (zombieMode) {
zombieWaveSpawnTimer++;
// Start first wave or next wave after delay
if (!zombieWaveInProgress && zombieWaveSpawnTimer >= 0) {
startZombieWave();
}
// Spawn zombies in current wave
if (zombieWaveInProgress && zombiesInCurrentWave < zombiesToSpawnInWave) {
if (zombieWaveSpawnTimer % 60 === 0) {
// Spawn one zombie every second during wave
spawnZombie();
zombiesInCurrentWave++;
}
}
// Check if current wave is complete
checkWaveComplete();
// Clean up off-screen zombies
for (var i = zombies.length - 1; i >= 0; i--) {
if (zombies[i].y > 2800) {
zombies[i].destroy();
zombies.splice(i, 1);
}
}
}
// Check game end conditions
checkGameEnd();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1177,9 +1177,9 @@
fill: '#ffff00'
});
backToMenuButton.anchor.set(0.5, 0.5);
backToMenuButton.x = 1024;
-backToMenuButton.y = 1800;
+backToMenuButton.y = 2000;
modeSelectionOverlay.addChild(backToMenuButton);
// Start button event handler - now shows mode selection
startButton.down = function () {
menuOverlay.visible = false;
Worker. In-Game asset. 2d. High contrast. No shadows
Wizard. In-Game asset. 2d. High contrast. No shadows
Dragon. In-Game asset. 2d. High contrast. No shadows
Warrior. In-Game asset. 2d. High contrast. No shadows
etrafı kırmızı işçi. In-Game asset. 2d. High contrast. No shadows
Archer. In-Game asset. 2d. High contrast. No shadows
Magic. In-Game asset. 2d. High contrast. No shadows
Sadece 1 Altın parçacığı. In-Game asset. 2d. High contrast. No shadows
Köşelerdeki taş yerleri kaldır
Çözünürlüğü artır ve kırmızı şeyleri kaldır. In-Game asset. 2d. High contrast. No shadows
Ağzından ateş püskürtsün
Tam yukarıdan bakılan bir kule clash royaledeki gibi. In-Game asset. 2d. High contrast. No shadows
Mavi yerler kırmızı olsun
Sol tarafında kılıçlar olan start buton. In-Game asset. 2d. High contrast. No shadows
How to play button. In-Game asset. 2d. High contrast. No shadows
Tower defence menü background. In-Game asset. 2d. High contrast. No shadows
Towers On Attack yazısı. In-Game asset. 2d. High contrast. No shadows
Zombie. In-Game asset. 2d. High contrast. No shadows
Normal Mode button. In-Game asset. 2d. High contrast. No shadows
Zombie Mode buton. In-Game asset. 2d. High contrast. No shadows