User prompt
Increase the health of the greatswordsman by 500%. Increase the hit damage of the greatswordsman by 350%. Increase the price of the greatswordsman to 100 coins.
User prompt
The greatsword can be used after level 5. The greatsword costs 80 coins.
User prompt
Increase the greatswordsman's speed by 100%
User prompt
Increase the greatswordsman's range by 2500%.
User prompt
Increase the range of the great swordsman by 1000%.
User prompt
Increase the greatswordsman's hit damage by 200%. Increase the greatswordsman's health by 300%.
User prompt
Add a büyükkılıççı to the game. He won't stay in place, he will move and your enemies will go and hit him. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kılıçyeniçeri 10 akçe olsun
User prompt
Oyuna kılıçlıyeniçeri ekle.Ama hareket etmesinler .Düşmalar yanlarına geldiklerinde hasar vursunlar.
User prompt
Horse archers can be used after level 5
User prompt
No moving unit should climb above the deploy panel.
User prompt
Horse archers should advance towards the enemies until they come within range. Once the enemies come within range, they should slowly move away. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
atlı okçunun hasarını %150 arttır.Düşmanlar ona yaklaştıkça onlardan az mesafelerle uzaklaşsın.Menzilini %300 arttır. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ArcherEnemy = Container.expand(function () {
var self = Container.call(this);
// Archer enemies have less health but can attack from range
var waveMultiplier = 1 + (currentWave - 1) * 0.3;
self.health = Math.floor(80 * waveMultiplier);
self.maxHealth = Math.floor(80 * waveMultiplier);
self.speed = Math.min(1.5 + (currentWave - 1) * 0.15, 3); // Slower than regular enemies
self.attackPower = Math.floor(25 * waveMultiplier);
self.attackCooldown = 0;
self.maxAttackCooldown = Math.max(80 - (currentWave - 1) * 4, 50); // Slower attacks than regular enemies
self.range = 455; // Archer range (30% increase)
var enemyGraphics = self.attachAsset('enemyArcher', {
anchorX: 0.5,
anchorY: 0.5
});
self.findNearestJanissary = function () {
var nearest = null;
var nearestDistance = Infinity;
for (var i = 0; i < janissaries.length; i++) {
var jan = janissaries[i];
var dx = jan.x - self.x;
var dy = jan.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearest = jan;
nearestDistance = distance;
}
}
return nearest;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
self.destroy();
for (var i = enemyArchers.length - 1; i >= 0; i--) {
if (enemyArchers[i] === self) {
enemyArchers.splice(i, 1);
gold += 8; // Slightly more gold for archer enemies
goldText.setText('Akçe: ' + gold);
break;
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
var target = self.findNearestJanissary();
if (target) {
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.range) {
// Move closer if target is out of range
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
} else if (distance > 120) {
// Stay at range and shoot arrows
if (self.attackCooldown <= 0) {
var enemyArrow = new EnemyArrow();
enemyArrow.x = self.x;
enemyArrow.y = self.y;
enemyArrow.target = target;
enemyArrow.damage = self.attackPower;
enemyArrows.push(enemyArrow);
game.addChild(enemyArrow);
self.attackCooldown = self.maxAttackCooldown;
}
} else {
// Move back if too close (maintain distance)
var angle = Math.atan2(dy, dx);
self.x -= Math.cos(angle) * self.speed;
self.y -= Math.sin(angle) * self.speed;
}
}
};
return self;
});
var Arrow = Container.expand(function () {
var self = Container.call(this);
self.speed = 12;
self.target = null;
self.damage = 30;
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.target.takeDamage(self.damage);
self.destroy();
for (var i = arrows.length - 1; i >= 0; i--) {
if (arrows[i] === self) {
arrows.splice(i, 1);
break;
}
}
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
arrowGraphics.rotation = angle;
}
} else {
self.destroy();
for (var i = arrows.length - 1; i >= 0; i--) {
if (arrows[i] === self) {
arrows.splice(i, 1);
break;
}
}
}
};
return self;
});
var BoostedArrow = Container.expand(function () {
var self = Container.call(this);
self.speed = 15; // Faster than regular arrows
self.target = null;
self.damage = 45; // Higher damage than regular arrows
self.pierceCount = 2; // Can hit multiple enemies
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
// Visual distinction for boosted arrows
arrowGraphics.tint = 0x00FFFF; // Cyan tint for boosted arrows
arrowGraphics.scaleX = 1.3; // Larger size
arrowGraphics.scaleY = 1.3;
self.update = function () {
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.target.takeDamage(self.damage);
self.pierceCount--;
// If arrow can still pierce, find next target
if (self.pierceCount > 0) {
var nextTarget = self.findNearestEnemyInRange();
if (nextTarget) {
self.target = nextTarget;
} else {
self.destroy();
for (var i = boostedArrows.length - 1; i >= 0; i--) {
if (boostedArrows[i] === self) {
boostedArrows.splice(i, 1);
break;
}
}
}
} else {
self.destroy();
for (var i = boostedArrows.length - 1; i >= 0; i--) {
if (boostedArrows[i] === self) {
boostedArrows.splice(i, 1);
break;
}
}
}
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
arrowGraphics.rotation = angle;
}
} else {
self.destroy();
for (var i = boostedArrows.length - 1; i >= 0; i--) {
if (boostedArrows[i] === self) {
boostedArrows.splice(i, 1);
break;
}
}
}
};
self.findNearestEnemyInRange = function () {
var nearest = null;
var nearestDistance = Infinity;
var maxRange = 200; // Range to find next target for piercing
// Check regular enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (enemy === self.target) continue; // Skip current target
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= maxRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check archer enemies
for (var i = 0; i < enemyArchers.length; i++) {
var enemy = enemyArchers[i];
if (enemy === self.target) continue; // Skip current target
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= maxRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check enemy artillery
for (var i = 0; i < enemyArtillery.length; i++) {
var enemy = enemyArtillery[i];
if (enemy === self.target) continue; // Skip current target
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= maxRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check heavy enemies
for (var i = 0; i < heavyEnemies.length; i++) {
var enemy = heavyEnemies[i];
if (enemy === self.target) continue; // Skip current target
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= maxRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check Timurunfili
for (var i = 0; i < timurunfilis.length; i++) {
var enemy = timurunfilis[i];
if (enemy === self.target) continue; // Skip current target
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= maxRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
return nearest;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 15;
self.target = null;
self.damage = 60;
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.target.takeDamage(self.damage);
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
bulletGraphics.rotation = angle;
}
} else {
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Scale enemy stats based on current wave for increased difficulty
var waveMultiplier = 1 + (currentWave - 1) * 0.3; // 30% increase per wave
self.health = Math.floor(120 * waveMultiplier);
self.maxHealth = Math.floor(120 * waveMultiplier);
self.speed = Math.min(2 + (currentWave - 1) * 0.2, 4); // Cap speed at 4
self.attackPower = Math.floor(35 * waveMultiplier);
self.attackCooldown = 0;
self.maxAttackCooldown = Math.max(60 - (currentWave - 1) * 3, 30); // Faster attacks, min 30
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.findNearestJanissary = function () {
var nearest = null;
var nearestDistance = Infinity;
for (var i = 0; i < janissaries.length; i++) {
var jan = janissaries[i];
var dx = jan.x - self.x;
var dy = jan.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearest = jan;
nearestDistance = distance;
}
}
return nearest;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
self.destroy();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
gold += 5;
goldText.setText('Akçe: ' + gold);
break;
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
var target = self.findNearestJanissary();
if (target) {
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 60) {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
} else {
if (self.attackCooldown <= 0) {
target.takeDamage(self.attackPower);
self.attackCooldown = self.maxAttackCooldown;
LK.effects.flashObject(target, 0xff0000, 200);
}
}
}
};
return self;
});
var EnemyArrow = Container.expand(function () {
var self = Container.call(this);
self.speed = 10;
self.target = null;
self.damage = 25;
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
arrowGraphics.tint = 0xff4444; // Red tint for enemy arrows
self.update = function () {
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.target.takeDamage(self.damage);
self.destroy();
for (var i = enemyArrows.length - 1; i >= 0; i--) {
if (enemyArrows[i] === self) {
enemyArrows.splice(i, 1);
break;
}
}
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
arrowGraphics.rotation = angle;
}
} else {
self.destroy();
for (var i = enemyArrows.length - 1; i >= 0; i--) {
if (enemyArrows[i] === self) {
enemyArrows.splice(i, 1);
break;
}
}
}
};
return self;
});
var EnemyArtillery = Container.expand(function () {
var self = Container.call(this);
// Enemy artillery has high health and long range
var waveMultiplier = 1 + (currentWave - 1) * 0.3;
self.health = Math.floor(200 * waveMultiplier);
self.maxHealth = Math.floor(200 * waveMultiplier);
self.speed = 0.5; // Very slow movement
self.attackPower = Math.floor(72 * waveMultiplier); // Reduced by 10% from 80 to 72
self.attackCooldown = 0;
self.maxAttackCooldown = Math.max(120 - (currentWave - 1) * 5, 80); // Slow but powerful attacks
self.range = 1288; // Double the original range (644 * 2)
var enemyGraphics = self.attachAsset('enemyArtillery', {
anchorX: 0.5,
anchorY: 0.5
});
self.findNearestJanissary = function () {
var nearest = null;
var nearestDistance = Infinity;
for (var i = 0; i < janissaries.length; i++) {
var jan = janissaries[i];
var dx = jan.x - self.x;
var dy = jan.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearest = jan;
nearestDistance = distance;
}
}
return nearest;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
self.destroy();
for (var i = enemyArtillery.length - 1; i >= 0; i--) {
if (enemyArtillery[i] === self) {
enemyArtillery.splice(i, 1);
gold += 12; // High gold reward for destroying artillery
goldText.setText('Akçe: ' + gold);
break;
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
var target = self.findNearestJanissary();
if (target) {
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range) {
// Artillery stays in position and shoots
if (self.attackCooldown <= 0) {
var enemyBullet = new EnemyBullet();
enemyBullet.x = self.x;
enemyBullet.y = self.y;
enemyBullet.target = target;
enemyBullet.damage = self.attackPower;
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
self.attackCooldown = self.maxAttackCooldown;
}
} else if (distance > self.range + 100) {
// Only move if target is very far away
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 8; // Slower than regular bullets
self.target = null;
self.damage = 80;
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0xff6666; // Red tint for enemy bullets
bulletGraphics.scaleX = 1.5; // Larger bullets
bulletGraphics.scaleY = 1.5;
self.update = function () {
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.target.takeDamage(self.damage);
self.destroy();
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
bulletGraphics.rotation = angle;
}
} else {
self.destroy();
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] === self) {
enemyBullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var HeavyEnemy = Container.expand(function () {
var self = Container.call(this);
// Heavy enemies have high health and damage but are slow
var waveMultiplier = 1 + (currentWave - 1) * 0.3;
self.health = Math.floor(250 * waveMultiplier);
self.maxHealth = Math.floor(250 * waveMultiplier);
self.speed = Math.min(1 + (currentWave - 1) * 0.1, 2); // Slower than other enemies
self.attackPower = Math.floor(50 * waveMultiplier);
self.attackCooldown = 0;
self.maxAttackCooldown = Math.max(80 - (currentWave - 1) * 3, 40); // Slower attacks
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Make heavy enemies visually distinct
enemyGraphics.tint = 0x666666; // Darker color
enemyGraphics.scaleX = 1.3; // Larger size
enemyGraphics.scaleY = 1.3;
self.findNearestJanissary = function () {
var nearest = null;
var nearestDistance = Infinity;
for (var i = 0; i < janissaries.length; i++) {
var jan = janissaries[i];
var dx = jan.x - self.x;
var dy = jan.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearest = jan;
nearestDistance = distance;
}
}
return nearest;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
self.destroy();
for (var i = heavyEnemies.length - 1; i >= 0; i--) {
if (heavyEnemies[i] === self) {
heavyEnemies.splice(i, 1);
gold += 15; // High gold reward for heavy enemies
goldText.setText('Akçe: ' + gold);
break;
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
var target = self.findNearestJanissary();
if (target) {
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 60) {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
} else {
if (self.attackCooldown <= 0) {
target.takeDamage(self.attackPower);
self.attackCooldown = self.maxAttackCooldown;
LK.effects.flashObject(target, 0xff0000, 200);
}
}
}
};
return self;
});
var Janissary = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
// Apply 20% buff to all Ottoman soldiers
var baseHealth = type === 'shielded' ? 140 : type === 'gunner' ? 150 : type === 'cavalry' ? 150 : type === 'spearman' ? 180 : type === 'swordsman' ? 150 : type === 'guard' ? 264 : type === 'horseArcher' ? 160 : type === 'swordJanissary' ? 200 : type === 'buyukkilicli' ? 280 : 100;
var baseAttackPower = type === 'archer' ? 27 : type === 'spearman' ? 60 : type === 'swordsman' ? 117 : type === 'shielded' ? 35 : type === 'gunner' ? 51 : type === 'guard' ? 0 : type === 'horseArcher' ? 35 : type === 'swordJanissary' ? 100 : type === 'buyukkilicli' ? 150 : 50;
// Apply special health multipliers
var healthMultiplier = type === 'buyukkilicli' ? 4.0 : 1.2; // 300% increase for greatswordsman = 400% total = 4.0x multiplier
self.health = Math.floor(baseHealth * healthMultiplier);
self.maxHealth = Math.floor(baseHealth * healthMultiplier);
// Apply 150% damage increase for horseback archer and 200% for greatswordsman
var attackMultiplier = type === 'horseArcher' ? 3.0 : type === 'buyukkilicli' ? 3.0 : 1.2; // 200% increase for greatswordsman = 300% total = 3.0x multiplier
self.attackPower = Math.floor(baseAttackPower * attackMultiplier);
// Apply 300% range increase for horseback archer
var baseRange = type === 'archer' ? 1560 : type === 'spearman' ? 1500 : type === 'swordsman' ? 27280 : type === 'shielded' ? 80 : type === 'gunner' ? 878 : type === 'guard' ? 80 : type === 'horseArcher' ? 1400 : type === 'swordJanissary' ? 100 : type === 'buyukkilicli' ? 120 : 80;
self.range = type === 'horseArcher' ? Math.floor(baseRange * 4.0) : baseRange; // 300% increase = 400% total = 4.0x multiplier
self.attackCooldown = 0;
self.maxAttackCooldown = type === 'archer' ? 40 : type === 'spearman' ? 70 : type === 'swordsman' ? 40 : type === 'shielded' ? 50 : type === 'gunner' ? 70 : type === 'guard' ? 50 : type === 'horseArcher' ? 45 : type === 'swordJanissary' ? 35 : type === 'buyukkilicli' ? 30 : 25;
self.isDragging = false;
self.target = null;
var unitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
var goldDisplayText = new Text2('', {
size: 30,
fill: 0xFFD700
});
goldDisplayText.anchor.set(0.5, 0);
goldDisplayText.x = -20;
goldDisplayText.y = 80;
self.addChild(goldDisplayText);
self.updateGoldDisplay = function () {
var goldCost = type === 'archer' ? 25 : type === 'spearman' ? 20 : type === 'swordsman' ? 15 : type === 'shielded' ? 10 : type === 'gunner' ? 18 : type === 'guard' ? 20 : type === 'horseArcher' ? 35 : type === 'swordJanissary' ? 10 : type === 'buyukkilicli' ? 45 : 30;
var displayText = type === 'guard' ? goldCost + ' akçe (Siper)' : goldCost + ' akçe';
goldDisplayText.setText(displayText);
};
self.updateGoldDisplay();
self.findNearestEnemy = function () {
var nearest = null;
var nearestDistance = Infinity;
// Check regular enemies
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);
// Cavalry and swordsman have extended range for target acquisition to ensure they always charge
// Shielded soldiers use normal range since they stay in position
var effectiveRange = self.type === 'cavalry' || self.type === 'swordsman' ? 800 : self.range;
if (distance <= effectiveRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check archer enemies
for (var i = 0; i < enemyArchers.length; i++) {
var enemy = enemyArchers[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Cavalry and swordsman have extended range for target acquisition to ensure they always charge
// Shielded soldiers use normal range since they stay in position
var effectiveRange = self.type === 'cavalry' || self.type === 'swordsman' ? 800 : self.range;
if (distance <= effectiveRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check enemy artillery
for (var i = 0; i < enemyArtillery.length; i++) {
var enemy = enemyArtillery[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var effectiveRange = self.type === 'cavalry' || self.type === 'swordsman' ? 800 : self.range;
if (distance <= effectiveRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check heavy enemies
for (var i = 0; i < heavyEnemies.length; i++) {
var enemy = heavyEnemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var effectiveRange = self.type === 'cavalry' || self.type === 'swordsman' ? 800 : self.range;
if (distance <= effectiveRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
// Check Timurunfili
for (var i = 0; i < timurunfilis.length; i++) {
var enemy = timurunfilis[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var effectiveRange = self.type === 'cavalry' || self.type === 'swordsman' ? 800 : self.range;
if (distance <= effectiveRange && distance < nearestDistance) {
nearest = enemy;
nearestDistance = distance;
}
}
return nearest;
};
self.attack = function (target) {
if (self.attackCooldown <= 0) {
if (self.type === 'archer') {
if (currentWave > 5) {
// Use boosted arrows after level 5
var boostedArrow = new BoostedArrow();
boostedArrow.x = self.x;
boostedArrow.y = self.y;
boostedArrow.target = target;
boostedArrow.damage = self.attackPower;
boostedArrows.push(boostedArrow);
game.addChild(boostedArrow);
} else {
// Use regular arrows for levels 1-5
var arrow = new Arrow();
arrow.x = self.x;
arrow.y = self.y;
arrow.target = target;
arrow.damage = self.attackPower;
arrows.push(arrow);
game.addChild(arrow);
}
LK.getSound('bowRelease').play();
} else if (self.type === 'spearman') {
var spear = new Spear();
spear.x = self.x;
spear.y = self.y;
spear.target = target;
spear.damage = self.attackPower;
spears.push(spear);
game.addChild(spear);
LK.getSound('spearThrow').play();
} else if (self.type === 'cavalry') {
// Cavalry melee attack
target.takeDamage(self.attackPower);
LK.getSound('swordClash').play();
LK.effects.flashObject(target, 0xff0000, 200);
} else if (self.type === 'shielded') {
// Shielded soldier melee attack
target.takeDamage(self.attackPower);
LK.getSound('swordClash').play();
LK.effects.flashObject(target, 0xff0000, 200);
} else if (self.type === 'gunner') {
// Gunner shoots bullets
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.target = target;
bullet.damage = self.attackPower;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('gunShot').play();
} else if (self.type === 'horseArcher') {
// Horse archer shoots arrows like regular archer but with mobility
if (currentWave > 5) {
// Use boosted arrows after level 5
var boostedArrow = new BoostedArrow();
boostedArrow.x = self.x;
boostedArrow.y = self.y;
boostedArrow.target = target;
boostedArrow.damage = self.attackPower;
boostedArrows.push(boostedArrow);
game.addChild(boostedArrow);
} else {
// Use regular arrows for levels 1-5
var arrow = new Arrow();
arrow.x = self.x;
arrow.y = self.y;
arrow.target = target;
arrow.damage = self.attackPower;
arrows.push(arrow);
game.addChild(arrow);
}
LK.getSound('bowRelease').play();
} else if (self.type === 'guard') {
// Guard does not deal any damage - just stands guard
// No attack action, just presence
} else if (self.type === 'swordJanissary') {
// Sword janissary melee attack - stationary but powerful
target.takeDamage(self.attackPower);
LK.getSound('swordClash').play();
LK.effects.flashObject(target, 0xff0000, 200);
} else if (self.type === 'buyukkilicli') {
// Büyükkılıççı melee attack - mobile and powerful
target.takeDamage(self.attackPower);
LK.getSound('swordClash').play();
LK.effects.flashObject(target, 0xff0000, 200);
} else {
// Swordsman melee attack
target.takeDamage(self.attackPower);
LK.getSound('swordClash').play();
LK.effects.flashObject(target, 0xff0000, 200);
}
self.attackCooldown = self.maxAttackCooldown;
}
};
self.takeDamage = function (damage) {
// Shielded soldiers take reduced damage (50% damage reduction)
var actualDamage = self.type === 'shielded' ? Math.ceil(damage * 0.5) : damage;
self.health -= actualDamage;
if (self.health <= 0) {
self.health = 0;
self.destroy();
for (var i = janissaries.length - 1; i >= 0; i--) {
if (janissaries[i] === self) {
janissaries.splice(i, 1);
break;
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
if (!self.isDragging) {
self.target = self.findNearestEnemy();
if (self.target) {
if (self.type === 'cavalry') {
// Cavalry charges towards enemies
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) {
// Move towards enemy - keep charging until very close
var angle = Math.atan2(dy, dx);
var moveSpeed = 7.2; // Cavalry charging speed (reduced by 10%)
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
} else {
// Attack when close enough but keep moving to stay engaged
self.attack(self.target);
// Continue slight movement to maintain engagement
if (distance > 30) {
var angle = Math.atan2(dy, dx);
var moveSpeed = 1.8; // Slower movement when in combat (reduced by 10%)
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
}
}
} else if (self.type === 'swordsman') {
// Swordsmen charge towards enemies like cavalry
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 80) {
// Move towards enemy - keep charging until close enough to attack
var angle = Math.atan2(dy, dx);
var moveSpeed = 6; // Swordsman speed for charging
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
} else {
// Attack when close enough and keep moving to stay engaged
self.attack(self.target);
// Continue movement to maintain engagement and follow the enemy
var angle = Math.atan2(dy, dx);
var moveSpeed = 3; // Moderate movement when in combat to stay close
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
}
} else if (self.type === 'shielded') {
// Shielded soldiers stay in position and attack enemies when they come within range
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 80) {
// Attack when enemy is close enough, but don't move
self.attack(self.target);
}
// Shielded soldiers do not move towards enemies - they stay in their defensive position
} else if (self.type === 'guard') {
// Guards stay in position and do not attack - they are purely defensive
// They just maintain their position and absorb damage
} else if (self.type === 'swordJanissary') {
// Sword janissary stays in position and attacks enemies when they come close
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 100) {
// Attack when enemy is close enough, but don't move
self.attack(self.target);
}
// Sword janissary does not move - stays in defensive position
} else if (self.type === 'buyukkilicli') {
// Büyükkılıççı charges towards enemies and attacks them - mobile melee unit
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 100) {
// Move towards enemy - charging behavior
var angle = Math.atan2(dy, dx);
var moveSpeed = 5; // Fast movement speed for büyükkılıççı
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
} else {
// Attack when close enough and keep moving to stay engaged
self.attack(self.target);
// Continue movement to maintain engagement
var angle = Math.atan2(dy, dx);
var moveSpeed = 2.5; // Moderate movement when in combat
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
}
} else if (self.type === 'horseArcher') {
// Horse archers are mobile ranged units - they advance to range, then retreat when enemies are close
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Find the closest enemy to determine retreat behavior
var closestEnemyDistance = Infinity;
var allEnemies = enemies.concat(enemyArchers).concat(enemyArtillery).concat(heavyEnemies).concat(timurunfilis);
for (var e = 0; e < allEnemies.length; e++) {
var enemy = allEnemies[e];
var edx = enemy.x - self.x;
var edy = enemy.y - self.y;
var edist = Math.sqrt(edx * edx + edy * edy);
if (edist < closestEnemyDistance) {
closestEnemyDistance = edist;
}
}
var optimalRange = self.range * 0.7; // Stay at 70% of max range for optimal positioning
var dangerZone = 500; // Distance at which to start retreating
if (distance > self.range) {
// Advance towards enemies until within range
var angle = Math.atan2(dy, dx);
var moveSpeed = 4; // Fast movement speed for advancing
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
} else if (closestEnemyDistance <= dangerZone && distance <= optimalRange) {
// Enemies are close and we're at good range - slowly retreat while maintaining position
var angle = Math.atan2(dy, dx);
var retreatSpeed = 1.5; // Slow retreat to maintain engagement
var newX = self.x - Math.cos(angle) * retreatSpeed * 10;
var newY = self.y - Math.sin(angle) * retreatSpeed * 10;
// Ensure unit stays below deploy panel during retreat
if (newY >= 300) {
// Use tween for smooth retreat movement
tween(self, {
x: newX,
y: newY
}, {
duration: 200,
easing: tween.easeOut
});
}
self.attack(self.target);
} else if (distance <= optimalRange) {
// At optimal range and enemies not too close - attack and hold position
self.attack(self.target);
} else {
// Too far from target but within max range - move closer slowly
var angle = Math.atan2(dy, dx);
var moveSpeed = 2; // Slower approach when already in range
var newX = self.x + Math.cos(angle) * moveSpeed;
var newY = self.y + Math.sin(angle) * moveSpeed;
// Ensure unit stays below deploy panel
if (newY >= 300) {
self.x = newX;
self.y = newY;
}
self.attack(self.target);
}
} else {
// Other units attack from their position
self.attack(self.target);
}
}
}
};
self.down = function (x, y, obj) {
if (deploymentPhase) {
self.isDragging = true;
draggedUnit = self;
}
};
return self;
});
var Spear = Container.expand(function () {
var self = Container.call(this);
self.speed = 10;
self.target = null;
self.damage = 40;
var spearGraphics = self.attachAsset('spear', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.target.takeDamage(self.damage);
self.destroy();
for (var i = spears.length - 1; i >= 0; i--) {
if (spears[i] === self) {
spears.splice(i, 1);
break;
}
}
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
spearGraphics.rotation = angle;
}
} else {
self.destroy();
for (var i = spears.length - 1; i >= 0; i--) {
if (spears[i] === self) {
spears.splice(i, 1);
break;
}
}
}
};
return self;
});
var Timurunfili = Container.expand(function () {
var self = Container.call(this);
// Timurunfili has the highest health and damage but moves very slowly
var waveMultiplier = 1 + (currentWave - 1) * 0.3;
self.health = Math.floor(400 * waveMultiplier); // Higher health than everyone else
self.maxHealth = Math.floor(400 * waveMultiplier);
self.speed = 1.344; // Slow movement (increased by 40% from original 0.96)
self.attackPower = Math.floor(80 * waveMultiplier); // Higher damage than everyone else
self.attackCooldown = 0;
self.maxAttackCooldown = Math.max(70 - (currentWave - 1) * 3, 50);
var timurunfiliGraphics = self.attachAsset('Timurunfili', {
anchorX: 0.5,
anchorY: 0.5
});
// Make Timurunfili visually distinct with larger size
timurunfiliGraphics.scaleX = 1.5; // Larger than other enemies
timurunfiliGraphics.scaleY = 1.5;
self.findNearestJanissary = function () {
var nearest = null;
var nearestDistance = Infinity;
for (var i = 0; i < janissaries.length; i++) {
var jan = janissaries[i];
var dx = jan.x - self.x;
var dy = jan.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearest = jan;
nearestDistance = distance;
}
}
return nearest;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
self.destroy();
for (var i = timurunfilis.length - 1; i >= 0; i--) {
if (timurunfilis[i] === self) {
timurunfilis.splice(i, 1);
gold += 25; // Highest gold reward for Timurunfili
goldText.setText('Akçe: ' + gold);
break;
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
var target = self.findNearestJanissary();
if (target) {
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 60) {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed; // Slow movement
self.y += Math.sin(angle) * self.speed;
} else {
if (self.attackCooldown <= 0) {
target.takeDamage(self.attackPower);
self.attackCooldown = self.maxAttackCooldown;
LK.effects.flashObject(target, 0xff0000, 200);
}
}
}
};
return self;
});
var UnitButton = Container.expand(function (unitType, cost) {
var self = Container.call(this);
self.unitType = unitType;
self.cost = cost;
var buttonGraphics = self.attachAsset(unitType, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
self.down = function (x, y, obj) {
if (deploymentPhase && gold >= self.cost) {
var newUnit = new Janissary(self.unitType);
newUnit.x = x;
newUnit.y = y;
newUnit.isDragging = true;
draggedUnit = newUnit;
janissaries.push(newUnit);
game.addChild(newUnit);
gold -= self.cost;
goldText.setText('Akçe: ' + gold);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
var battlefield = game.addChild(LK.getAsset('battlefield', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 300
}));
var deployPanel = game.addChild(LK.getAsset('deployPanel', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var janissaries = [];
var enemies = [];
var enemyArchers = [];
var enemyArtillery = [];
var heavyEnemies = [];
var timurunfilis = [];
var enemyArrows = [];
var enemyBullets = [];
var arrows = [];
var boostedArrows = [];
var spears = [];
var bullets = [];
var currentWave = 1;
var maxWaves = 10;
var waveTimer = 0;
var deploymentPhase = true;
var draggedUnit = null;
var gold = 100;
var waveText = new Text2('Akın sayısı: 1', {
size: 40,
fill: 0xFFFFFF
});
waveText.anchor.set(1, 1);
LK.gui.bottomRight.addChild(waveText);
waveText.x = -20;
waveText.y = -20;
var goldText = new Text2('Akçe: 100', {
size: 60,
fill: 0xFFFF00
});
goldText.anchor.set(0, 0);
LK.gui.topRight.addChild(goldText);
goldText.x = -400;
goldText.y = 20;
var phaseText = new Text2('Deployment Phase - Position Your Units!', {
size: 70,
fill: 0x00FF00
});
phaseText.anchor.set(0.5, 0);
LK.gui.center.addChild(phaseText);
phaseText.y = -200;
var archerButton = new UnitButton('archer', 25);
archerButton.x = 300;
archerButton.y = 150;
game.addChild(archerButton);
var archerGoldText = new Text2('25 akçe', {
size: 30,
fill: 0xFFD700
});
archerGoldText.anchor.set(0.5, 0);
archerGoldText.x = 300;
archerGoldText.y = 220;
game.addChild(archerGoldText);
var spearmanButton = new UnitButton('spearman', 20);
spearmanButton.x = 500;
spearmanButton.y = 150;
game.addChild(spearmanButton);
var spearmanGoldText = new Text2('20 akçe', {
size: 30,
fill: 0xFFD700
});
spearmanGoldText.anchor.set(0.5, 0);
spearmanGoldText.x = 500;
spearmanGoldText.y = 220;
game.addChild(spearmanGoldText);
var cavalryButton = new UnitButton('cavalry', 30);
cavalryButton.x = 700;
cavalryButton.y = 150;
game.addChild(cavalryButton);
var cavalryGoldText = new Text2('30 akçe', {
size: 30,
fill: 0xFFD700
});
cavalryGoldText.anchor.set(0.5, 0);
cavalryGoldText.x = 700;
cavalryGoldText.y = 220;
game.addChild(cavalryGoldText);
var swordsmanButton = new UnitButton('swordsman', 15);
swordsmanButton.x = 900;
swordsmanButton.y = 150;
game.addChild(swordsmanButton);
var swordsmanGoldText = new Text2('15 akçe', {
size: 30,
fill: 0xFFD700
});
swordsmanGoldText.anchor.set(0.5, 0);
swordsmanGoldText.x = 900;
swordsmanGoldText.y = 220;
game.addChild(swordsmanGoldText);
var shieldedButton = new UnitButton('shielded', 10);
shieldedButton.x = 1100;
shieldedButton.y = 150;
game.addChild(shieldedButton);
var shieldedGoldText = new Text2('10 akçe', {
size: 30,
fill: 0xFFD700
});
shieldedGoldText.anchor.set(0.5, 0);
shieldedGoldText.x = 1100;
shieldedGoldText.y = 220;
game.addChild(shieldedGoldText);
var gunnerButton = new UnitButton('gunner', 18);
gunnerButton.x = 1300;
gunnerButton.y = 150;
game.addChild(gunnerButton);
var gunnerGoldText = new Text2('18 akçe', {
size: 30,
fill: 0xFFD700
});
gunnerGoldText.anchor.set(0.5, 0);
gunnerGoldText.x = 1300;
gunnerGoldText.y = 220;
game.addChild(gunnerGoldText);
var guardButton = new UnitButton('guard', 20);
guardButton.x = 1500;
guardButton.y = 150;
game.addChild(guardButton);
var guardGoldText = new Text2('20 akçe (Siper)', {
size: 30,
fill: 0xFFD700
});
guardGoldText.anchor.set(0.5, 0);
guardGoldText.x = 1500;
guardGoldText.y = 220;
game.addChild(guardGoldText);
var horseArcherButton = new UnitButton('horseArcher', 35);
horseArcherButton.x = 300;
horseArcherButton.y = 280;
game.addChild(horseArcherButton);
var horseArcherGoldText = new Text2('35 akçe', {
size: 30,
fill: 0xFFD700
});
horseArcherGoldText.anchor.set(0.5, 0);
horseArcherGoldText.x = 300;
horseArcherGoldText.y = 350;
game.addChild(horseArcherGoldText);
var swordJanissaryButton = new UnitButton('swordJanissary', 10);
swordJanissaryButton.x = 500;
swordJanissaryButton.y = 280;
game.addChild(swordJanissaryButton);
var swordJanissaryGoldText = new Text2('10 akçe', {
size: 30,
fill: 0xFFD700
});
swordJanissaryGoldText.anchor.set(0.5, 0);
swordJanissaryGoldText.x = 500;
swordJanissaryGoldText.y = 350;
game.addChild(swordJanissaryGoldText);
var buyukkilicliButton = new UnitButton('buyukkilicli', 45);
buyukkilicliButton.x = 700;
buyukkilicliButton.y = 280;
game.addChild(buyukkilicliButton);
var buyukkilicliGoldText = new Text2('45 akçe', {
size: 30,
fill: 0xFFD700
});
buyukkilicliGoldText.anchor.set(0.5, 0);
buyukkilicliGoldText.x = 700;
buyukkilicliGoldText.y = 350;
game.addChild(buyukkilicliGoldText);
var startBattleText = new Text2('Start Battle', {
size: 60,
fill: 0xFF0000
});
startBattleText.anchor.set(0.5, 0.5);
startBattleText.x = 1700;
startBattleText.y = 250;
game.addChild(startBattleText);
startBattleText.down = function (x, y, obj) {
if (deploymentPhase && janissaries.length > 0) {
deploymentPhase = false;
phaseText.setText('Akın sayısı ' + currentWave + ' - Defend!');
phaseText.tint = 0xff0000;
startBattleText.visible = false;
archerButton.visible = false;
spearmanButton.visible = false;
cavalryButton.visible = false;
swordsmanButton.visible = false;
shieldedButton.visible = false;
gunnerButton.visible = false;
guardButton.visible = false;
horseArcherButton.visible = false;
swordJanissaryButton.visible = false;
buyukkilicliButton.visible = false;
archerGoldText.visible = false;
spearmanGoldText.visible = false;
cavalryGoldText.visible = false;
swordsmanGoldText.visible = false;
shieldedGoldText.visible = false;
gunnerGoldText.visible = false;
guardGoldText.visible = false;
horseArcherGoldText.visible = false;
swordJanissaryGoldText.visible = false;
buyukkilicliGoldText.visible = false;
spawnWave();
}
};
function spawnWave() {
// More aggressive scaling for higher waves
var enemyCount = currentWave <= 5 ? currentWave * 3 + 2 : currentWave * 4 + 5;
var archerCount = Math.floor(enemyCount * 0.3); // 30% of enemies are archers
var regularCount = enemyCount - archerCount;
// Spawn regular enemies
for (var i = 0; i < regularCount; i++) {
var enemy = new Enemy();
var side = Math.floor(Math.random() * 2); // Only 2 sides now (left and right)
if (side === 0) {
// Spawn from middle right
enemy.x = 2048;
enemy.y = 300 + 900 + Math.random() * 300; // Middle area (1200-1500 range)
} else {
// Spawn from middle left
enemy.x = 0;
enemy.y = 300 + 900 + Math.random() * 300; // Middle area (1200-1500 range)
}
enemies.push(enemy);
game.addChild(enemy);
}
// Spawn archer enemies
for (var i = 0; i < archerCount; i++) {
var archerEnemy = new ArcherEnemy();
var side = Math.floor(Math.random() * 2);
if (side === 0) {
// Spawn from middle right
archerEnemy.x = 2048;
archerEnemy.y = 300 + 900 + Math.random() * 300;
} else {
// Spawn from middle left
archerEnemy.x = 0;
archerEnemy.y = 300 + 900 + Math.random() * 300;
}
enemyArchers.push(archerEnemy);
game.addChild(archerEnemy);
}
// Spawn enemy artillery in middle of screen (1 per wave starting from wave 2)
if (currentWave >= 2) {
var artilleryCount = Math.floor(currentWave / 2); // 1 artillery every 2 waves
for (var i = 0; i < artilleryCount; i++) {
var enemyArt = new EnemyArtillery();
enemyArt.x = 1024 + (Math.random() - 0.5) * 200; // Center with some variation
enemyArt.y = 300 + 1050 + (Math.random() - 0.5) * 200; // Middle of battlefield
enemyArtillery.push(enemyArt);
game.addChild(enemyArt);
}
}
// Spawn Timurunfili starting from wave 5 (after level 4)
if (currentWave >= 5) {
var timurunfiliCount = Math.floor((currentWave - 4) * 1); // 1 Timurunfili per wave after wave 4
for (var i = 0; i < timurunfiliCount; i++) {
var timurunfili = new Timurunfili();
var side = Math.floor(Math.random() * 2);
if (side === 0) {
// Spawn from middle right
timurunfili.x = 2048;
timurunfili.y = 300 + 900 + Math.random() * 300;
} else {
// Spawn from middle left
timurunfili.x = 0;
timurunfili.y = 300 + 900 + Math.random() * 300;
}
timurunfilis.push(timurunfili);
game.addChild(timurunfili);
}
}
// Spawn heavy enemies starting from wave 6 (after level 5)
if (currentWave >= 6) {
var heavyCount = Math.floor((currentWave - 5) * 2); // 2 heavy enemies per wave after wave 5
for (var i = 0; i < heavyCount; i++) {
var heavyEnemy = new HeavyEnemy();
var side = Math.floor(Math.random() * 2);
if (side === 0) {
// Spawn from middle right
heavyEnemy.x = 2048;
heavyEnemy.y = 300 + 900 + Math.random() * 300;
} else {
// Spawn from middle left
heavyEnemy.x = 0;
heavyEnemy.y = 300 + 900 + Math.random() * 300;
}
heavyEnemies.push(heavyEnemy);
game.addChild(heavyEnemy);
}
}
}
function checkWaveComplete() {
if (enemies.length === 0 && enemyArchers.length === 0 && enemyArtillery.length === 0 && heavyEnemies.length === 0 && timurunfilis.length === 0 && !deploymentPhase) {
currentWave++;
if (currentWave > maxWaves) {
LK.showYouWin();
} else {
deploymentPhase = true;
phaseText.setText('Akın sayısı ' + currentWave + ' Preparation');
phaseText.tint = 0x00ff00;
waveText.setText('Akın sayısı: ' + currentWave);
startBattleText.visible = true;
archerButton.visible = true;
spearmanButton.visible = true;
cavalryButton.visible = true;
swordsmanButton.visible = true;
shieldedButton.visible = true;
gunnerButton.visible = true;
guardButton.visible = true;
horseArcherButton.visible = true;
swordJanissaryButton.visible = true;
buyukkilicliButton.visible = true;
archerGoldText.visible = true;
spearmanGoldText.visible = true;
cavalryGoldText.visible = true;
swordsmanGoldText.visible = true;
shieldedGoldText.visible = true;
gunnerGoldText.visible = true;
guardGoldText.visible = true;
horseArcherGoldText.visible = true;
swordJanissaryGoldText.visible = true;
buyukkilicliGoldText.visible = true;
// Increase gold reward for later waves - more coins after level 4
var goldReward;
if (currentWave > 4) {
goldReward = 50 + (currentWave - 1) * 20; // Double the increase after level 4
} else {
goldReward = 50 + (currentWave - 1) * 10; // Regular increase for first 4 levels
}
gold += goldReward;
goldText.setText('Akçe: ' + gold);
}
}
}
function checkGameOver() {
if (janissaries.length === 0 && !deploymentPhase) {
LK.showGameOver();
}
}
game.move = function (x, y, obj) {
if (draggedUnit && deploymentPhase) {
if (y > 300) {
draggedUnit.x = x;
draggedUnit.y = y;
}
}
};
game.up = function (x, y, obj) {
if (draggedUnit) {
draggedUnit.isDragging = false;
draggedUnit = null;
}
};
var resetButton = new Text2('Reset', {
size: 50,
fill: 0xFF0000
});
resetButton.anchor.set(0, 1);
resetButton.x = 20;
resetButton.y = -20;
LK.gui.bottomLeft.addChild(resetButton);
resetButton.down = function (x, y, obj) {
// Clear all janissaries from battlefield before resetting arrays
for (var i = janissaries.length - 1; i >= 0; i--) {
janissaries[i].destroy();
}
// Reset all game variables to initial state
janissaries = [];
enemies = [];
enemyArchers = [];
enemyArtillery = [];
heavyEnemies = [];
timurunfilis = [];
enemyArrows = [];
enemyBullets = [];
arrows = [];
boostedArrows = [];
spears = [];
bullets = [];
currentWave = 1;
maxWaves = 10;
waveTimer = 0;
deploymentPhase = true;
draggedUnit = null;
gold = 100;
// Clear all units from the game
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
if (child.type || child.unitType || child === startBattleText || child === archerButton || child === spearmanButton || child === cavalryButton || child === swordsmanButton || child === shieldedButton || child === gunnerButton || child === guardButton || child === horseArcherButton || child === swordJanissaryButton || child === buyukkilicliButton || child === archerGoldText || child === spearmanGoldText || child === cavalryGoldText || child === swordsmanGoldText || child === shieldedGoldText || child === gunnerGoldText || child === guardGoldText || child === horseArcherGoldText || child === swordJanissaryGoldText || child === buyukkilicliGoldText) {
continue; // Keep UI elements
}
// Remove projectiles and units
if (child.speed !== undefined || child.health !== undefined) {
child.destroy();
}
}
// Reset UI text
waveText.setText('Akın sayısı: 1');
goldText.setText('Akçe: 100');
phaseText.setText('Deployment Phase - Position Your Units!');
phaseText.tint = 0x00FF00;
// Show deployment UI
startBattleText.visible = true;
archerButton.visible = true;
spearmanButton.visible = true;
cavalryButton.visible = true;
swordsmanButton.visible = true;
shieldedButton.visible = true;
gunnerButton.visible = true;
guardButton.visible = true;
horseArcherButton.visible = true;
swordJanissaryButton.visible = true;
buyukkilicliButton.visible = true;
archerGoldText.visible = true;
spearmanGoldText.visible = true;
cavalryGoldText.visible = true;
swordsmanGoldText.visible = true;
shieldedGoldText.visible = true;
gunnerGoldText.visible = true;
guardGoldText.visible = true;
horseArcherGoldText.visible = true;
swordJanissaryGoldText.visible = true;
buyukkilicliGoldText.visible = true;
};
game.update = function () {
for (var i = janissaries.length - 1; i >= 0; i--) {
if (janissaries[i].health <= 0) {
janissaries[i].destroy();
janissaries.splice(i, 1);
}
}
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i].health <= 0) {
enemies[i].destroy();
enemies.splice(i, 1);
}
}
for (var i = arrows.length - 1; i >= 0; i--) {
if (!arrows[i].target || arrows[i].target.health <= 0) {
arrows[i].destroy();
arrows.splice(i, 1);
}
}
for (var i = boostedArrows.length - 1; i >= 0; i--) {
if (!boostedArrows[i].target || boostedArrows[i].target.health <= 0) {
boostedArrows[i].destroy();
boostedArrows.splice(i, 1);
}
}
for (var i = spears.length - 1; i >= 0; i--) {
if (!spears[i].target || spears[i].target.health <= 0) {
spears[i].destroy();
spears.splice(i, 1);
}
}
for (var i = bullets.length - 1; i >= 0; i--) {
if (!bullets[i].target || bullets[i].target.health <= 0) {
bullets[i].destroy();
bullets.splice(i, 1);
}
}
for (var i = enemyArchers.length - 1; i >= 0; i--) {
if (enemyArchers[i].health <= 0) {
enemyArchers[i].destroy();
enemyArchers.splice(i, 1);
}
}
for (var i = enemyArrows.length - 1; i >= 0; i--) {
if (!enemyArrows[i].target || enemyArrows[i].target.health <= 0) {
enemyArrows[i].destroy();
enemyArrows.splice(i, 1);
}
}
for (var i = enemyArtillery.length - 1; i >= 0; i--) {
if (enemyArtillery[i].health <= 0) {
enemyArtillery[i].destroy();
enemyArtillery.splice(i, 1);
}
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (!enemyBullets[i].target || enemyBullets[i].target.health <= 0) {
enemyBullets[i].destroy();
enemyBullets.splice(i, 1);
}
}
for (var i = heavyEnemies.length - 1; i >= 0; i--) {
if (heavyEnemies[i].health <= 0) {
heavyEnemies[i].destroy();
heavyEnemies.splice(i, 1);
}
}
for (var i = timurunfilis.length - 1; i >= 0; i--) {
if (timurunfilis[i].health <= 0) {
timurunfilis[i].destroy();
timurunfilis.splice(i, 1);
}
}
checkWaveComplete();
checkGameOver();
}; ===================================================================
--- original.js
+++ change.js
@@ -605,12 +605,14 @@
self.type = type;
// Apply 20% buff to all Ottoman soldiers
var baseHealth = type === 'shielded' ? 140 : type === 'gunner' ? 150 : type === 'cavalry' ? 150 : type === 'spearman' ? 180 : type === 'swordsman' ? 150 : type === 'guard' ? 264 : type === 'horseArcher' ? 160 : type === 'swordJanissary' ? 200 : type === 'buyukkilicli' ? 280 : 100;
var baseAttackPower = type === 'archer' ? 27 : type === 'spearman' ? 60 : type === 'swordsman' ? 117 : type === 'shielded' ? 35 : type === 'gunner' ? 51 : type === 'guard' ? 0 : type === 'horseArcher' ? 35 : type === 'swordJanissary' ? 100 : type === 'buyukkilicli' ? 150 : 50;
- self.health = Math.floor(baseHealth * 1.2); // 20% buff
- self.maxHealth = Math.floor(baseHealth * 1.2); // 20% buff
- // Apply 150% damage increase for horseback archer
- var attackMultiplier = type === 'horseArcher' ? 3.0 : 1.2; // 150% increase = 250% total = 2.5x multiplier, plus base 20% = 3.0x
+ // Apply special health multipliers
+ var healthMultiplier = type === 'buyukkilicli' ? 4.0 : 1.2; // 300% increase for greatswordsman = 400% total = 4.0x multiplier
+ self.health = Math.floor(baseHealth * healthMultiplier);
+ self.maxHealth = Math.floor(baseHealth * healthMultiplier);
+ // Apply 150% damage increase for horseback archer and 200% for greatswordsman
+ var attackMultiplier = type === 'horseArcher' ? 3.0 : type === 'buyukkilicli' ? 3.0 : 1.2; // 200% increase for greatswordsman = 300% total = 3.0x multiplier
self.attackPower = Math.floor(baseAttackPower * attackMultiplier);
// Apply 300% range increase for horseback archer
var baseRange = type === 'archer' ? 1560 : type === 'spearman' ? 1500 : type === 'swordsman' ? 27280 : type === 'shielded' ? 80 : type === 'gunner' ? 878 : type === 'guard' ? 80 : type === 'horseArcher' ? 1400 : type === 'swordJanissary' ? 100 : type === 'buyukkilicli' ? 120 : 80;
self.range = type === 'horseArcher' ? Math.floor(baseRange * 4.0) : baseRange; // 300% increase = 400% total = 4.0x multiplier
animasyon Çizgi dizi tarzında bir Osmanlı okçusu. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında bir At üstünde bir Osmanlı süvarisi. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında bir Osmanlı mızrakçısı. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında Beyaz bir ok. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında bir toprak ama ne ağaç var nede çimen sadece dümdüz kahverengi toprak açık kahverengi olsun toprak. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında bir bizans askeri. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında elinde kılıç olan bir osmanlı yeniçerisi. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında kalkanlı osmanlı askeri.Kalkanları büyük olsun In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında osmanlı topçusu ekle bu askerin yanında savaş topuda olsun. In-Game asset. 2d. High contrast. No shadows
animasyon çizgi dizi tarzında siyah top. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında bizans okçusu. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında bizans topçusu. In-Game asset. 2d. High contrast. No shadows
Mızrak. In-Game asset. 2d. High contrast. No shadows
animasyon çizgi dizi tarzında bir siper. In-Game asset. 2d. High contrast. No shadows
mor bir arrow. In-Game asset. 2d. High contrast. No shadows
at üstünde okçu. In-Game asset. 2d. High contrast. No shadows
Animasyon çizgi dizi tarzında yeniçeri. In-Game asset. 2d. High contrast. No shadows
animasyo çizgi dizi gibi bir osmanlı yeniçerisi ama güçlü. In-Game asset. 2d. High contrast. No shadows