User prompt
can barını biraz kartın yukarsına al c0k az bide kulelerin canı belli olmuyor düzelt
User prompt
can barı hic belli olmuyor
User prompt
canlar siyah anlasılmıyor düzelt
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'scaleX')' in or related to this line: 'healTarget.children[3].scaleX = 0.8 * healedHealthPercent;' Line Number: 529
User prompt
can barları kırmızı olsun,
User prompt
can barı ekle hem kuleye hemde kartlara
User prompt
kartların ve kulelerin canını sil bidaha yap
User prompt
Please fix the bug: 'Uncaught TypeError: cardOption.children[3].setText is not a function' in or related to this line: 'return 'Asker';' Line Number: 778
User prompt
Oyundaki tüm sorunları ve bugları düzelt
User prompt
Kartların can barıda düzelt
User prompt
Oyundaki tüm can barları hatalı düzelt
User prompt
Kulelerin canı kırmızı olsun cünkü buglu
User prompt
Kulelerin canı buglu düzelt
User prompt
Energy bar ana kulenin altındakini köşeye koy ama okunabilir olsun
User prompt
En köşeye iksir bar yerleştir
User prompt
İksir barını en köşeye koy çünkü ana kulenin canı gözükmüyor
User prompt
Yana koy iksir bar in
User prompt
İksir bar ekle
User prompt
Energybarı biraz asagı al
User prompt
Sifacı yanındaki takım arkadaşlarını iyileştirsin düsmanın sifacısıda
User prompt
Guardian düsman da 7 tane çıksın
User prompt
Kartlarım kısmındaki Tower Defence arena yazısını yukarı al
User prompt
Kartlarım kısmındaki başlığı ve altındaki yazıyı biraz üste kaydır
User prompt
Kartlarım kısmındaki kartları büyüt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ana menüdeki tuşlar birbirine giriyor
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Card = Container.expand(function (type, cost) {
var self = Container.call(this);
self.type = type;
self.cost = cost;
self.selected = false;
var cardBg = self.attachAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5
});
var unitPreview = self.addChild(LK.getAsset(type, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
y: -30
}));
var costText = self.addChild(new Text2(cost.toString(), {
size: 40,
fill: 0xFFFFFF
}));
costText.anchor.set(0.5, 0.5);
costText.y = 80;
// Add card name in Turkish
var nameText = self.addChild(new Text2(getCardName(type).toUpperCase(), {
size: 28,
fill: 0xFFFFFF
}));
nameText.anchor.set(0.5, 0.5);
nameText.y = 120;
// Add health display for cards
var cardHealth = getCardHealth(type);
var healthText = self.addChild(new Text2('HP: ' + cardHealth, {
size: 24,
fill: 0xFF0000
}));
healthText.anchor.set(0.5, 0.5);
healthText.y = -90;
// Card selection state
self.selected = false;
self.down = function (x, y, obj) {
if (deckBuilder && deckBuilder.isOpen) {
deckBuilder.selectCard(self.type);
return;
}
// Simple touch deployment - select this card for deployment
if (currentEnergy >= self.cost) {
// Deselect previously selected card
if (selectedCard) {
selectedCard.children[0].tint = 0xFFFFFF;
selectedCard.selected = false;
}
// Select this card
selectedCard = self;
self.selected = true;
cardBg.tint = 0x00FF00;
} else {
// Visual feedback for insufficient energy
cardBg.tint = 0xFF0000;
LK.setTimeout(function () {
cardBg.tint = 0xFFFFFF;
}, 500);
}
};
return self;
});
var DeckBuilder = Container.expand(function () {
var self = Container.call(this);
self.isOpen = false;
self.selectedDeck = [];
self.availableCards = allCardTypes.slice();
var bg = self.attachAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.6
});
bg.tint = 0x222222;
var titleText = self.addChild(new Text2("Tüm Kartlar - 8 Seç", {
size: 60,
fill: 0xFFFFFF
}));
titleText.anchor.set(0.5, 0.5);
titleText.y = -400;
self.show = function () {
self.isOpen = true;
self.visible = true;
self.selectedDeck = [];
titleText.setText("Tüm Kartlar - 8 Seç");
self.refreshCards();
};
self.hide = function () {
self.isOpen = false;
self.visible = false;
};
self.refreshCards = function () {
for (var i = self.children.length - 1; i >= 0; i--) {
if (self.children[i].isCardOption) {
self.children[i].destroy();
}
}
// Show all 15 cards in a 5x3 grid layout
for (var i = 0; i < self.availableCards.length; i++) {
var cardType = self.availableCards[i];
var cost = allCardCosts[allCardTypes.indexOf(cardType)];
var cardOption = self.addChild(new Card(cardType, cost));
cardOption.isCardOption = true;
cardOption.x = -400 + i % 5 * 200;
cardOption.y = -200 + Math.floor(i / 5) * 300;
cardOption.scaleX = 0.8;
cardOption.scaleY = 0.8;
// Update card name text to uppercase for deck builder cards with larger font size
if (cardOption.children.length > 4 && cardOption.children[4] && cardOption.children[4].setText) {
// Create new text with larger font size for deck builder
var oldNameText = cardOption.children[4];
oldNameText.destroy();
var newNameText = cardOption.addChild(new Text2(getCardName(cardType).toUpperCase(), {
size: 45,
fill: 0xFFFFFF
}));
newNameText.anchor.set(0.5, 0.5);
newNameText.y = 135;
}
// Add scale up animation for card preview
tween(cardOption, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 300,
easing: tween.easeOut
});
// Highlight already selected cards
for (var j = 0; j < self.selectedDeck.length; j++) {
if (self.selectedDeck[j] === cardType) {
cardOption.children[0].tint = 0x00FF00;
break;
}
}
}
};
self.selectCard = function (cardType) {
if (self.selectedDeck.length < 8) {
self.selectedDeck.push(cardType);
// Update title to show progress
titleText.setText("Seçilen: " + self.selectedDeck.length + "/8");
if (self.selectedDeck.length === 8) {
playerDeck = self.selectedDeck.slice();
self.hide();
setupPlayerCards();
}
}
};
self.visible = false;
return self;
});
var Projectile = Container.expand(function (startX, startY, target, damage) {
var self = Container.call(this);
self.x = startX;
self.y = startY;
self.target = target;
self.damage = damage;
self.speed = 8;
var projectileGraphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (!self.target || self.target.health <= 0) {
self.destroy();
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.target.height / 2 - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
// Hit target
self.target.takeDamage(self.damage);
self.destroy();
} else {
// Move toward target
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var Tower = Container.expand(function (isPlayer, isKing) {
var self = Container.call(this);
self.isPlayer = isPlayer;
self.isKing = isKing;
self.maxHealth = isKing ? 3000 : 2000;
self.health = self.maxHealth;
self.attackDamage = isKing ? 200 : 150;
self.attackRange = 250;
self.attackCooldown = 0;
self.attackSpeed = 60; // frames between attacks
var assetName = (isPlayer ? 'player' : 'enemy') + (isKing ? 'KingTower' : 'Tower');
var towerGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1.0
});
// Add health bar background
var healthBarBg = self.attachAsset('energyBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.3,
y: -150
});
healthBarBg.tint = 0xFFFFFF;
// Add health bar
var healthBar = self.attachAsset('energyBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.3,
x: -60,
y: -150
});
healthBar.tint = 0xFF0000;
// Add health text
var healthText = self.addChild(new Text2(self.health + '/' + self.maxHealth, {
size: 25,
fill: 0xFFFFFF
}));
healthText.anchor.set(0.5, 0.5);
healthText.y = -150;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
// Update health bar
var healthPercent = self.health / self.maxHealth;
healthBar.scaleX = 1.2 * healthPercent;
healthText.setText(self.health + '/' + self.maxHealth);
// Keep health bar red
healthBar.tint = 0xFF0000;
// Flash effect
LK.effects.flashObject(towerGraphics, 0xFF0000, 300);
LK.getSound('towerHit').play();
if (self.health <= 0) {
// Gain elixir when destroying enemy towers
if (self.isPlayer === false && currentElixir < maxElixir) {
currentElixir += 3; // More elixir for towers
if (currentElixir > maxElixir) currentElixir = maxElixir;
var elixirPercent = currentElixir / maxElixir;
elixirBar.scaleX = 1.0 * elixirPercent;
elixirText.setText("İksir: " + currentElixir + "/" + maxElixir);
}
self.destroy();
if (isKing) {
if (isPlayer) {
LK.showGameOver();
} else {
LK.showYouWin();
}
}
}
};
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
return;
}
// Find closest enemy unit
var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
var closestUnit = null;
var closestDistance = Infinity;
for (var i = 0; i < targetUnits.length; i++) {
var unit = targetUnits[i];
var dx = unit.x - self.x;
var dy = unit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.attackRange && distance < closestDistance) {
closestDistance = distance;
closestUnit = unit;
}
}
if (closestUnit) {
self.attackCooldown = self.attackSpeed;
// Create projectile
var projectile = new Projectile(self.x, self.y - 50, closestUnit, self.attackDamage);
game.addChild(projectile);
projectiles.push(projectile);
}
};
return self;
});
var Unit = Container.expand(function (type, isPlayer) {
var self = Container.call(this);
self.isPlayer = isPlayer;
self.type = type;
self.moveSpeed = 2;
self.attackDamage = 100;
self.attackRange = 80;
self.attackCooldown = 0;
self.attackSpeed = 60;
self.target = null;
// Set stats based on type
switch (type) {
case 'soldier':
self.maxHealth = 400;
self.moveSpeed = 2;
self.attackDamage = 80;
break;
case 'archer':
self.maxHealth = 200;
self.moveSpeed = 2.5;
self.attackDamage = 60;
self.attackRange = 150;
break;
case 'tank':
self.maxHealth = 800;
self.moveSpeed = 1;
self.attackDamage = 120;
break;
case 'wizard':
self.maxHealth = 300;
self.moveSpeed = 2;
self.attackDamage = 150;
self.attackRange = 180;
break;
case 'dragon':
self.maxHealth = 1200;
self.moveSpeed = 1.5;
self.attackDamage = 200;
self.attackRange = 200;
break;
case 'freeze':
self.maxHealth = 280;
self.moveSpeed = 1.8;
self.attackDamage = 80;
self.attackRange = 150;
break;
case 'goblin':
self.maxHealth = 150;
self.moveSpeed = 3;
self.attackDamage = 50;
break;
case 'giant':
self.maxHealth = 1500;
self.moveSpeed = 0.8;
self.attackDamage = 250;
break;
case 'healer':
self.maxHealth = 250;
self.moveSpeed = 2;
self.attackDamage = 20;
self.attackRange = 160;
break;
case 'assassin':
self.maxHealth = 180;
self.moveSpeed = 3.5;
self.attackDamage = 120;
break;
case 'bomber':
self.maxHealth = 220;
self.moveSpeed = 2.2;
self.attackDamage = 180;
self.attackRange = 140;
break;
break;
case 'guardian':
self.maxHealth = 215; // Reduced from 750 since 7 spawn
self.moveSpeed = 1.5;
self.attackDamage = 32; // Reduced from 95 since 7 spawn
break;
case 'berserker':
self.maxHealth = 500;
self.moveSpeed = 2.3;
self.attackDamage = 140;
break;
break;
}
self.health = self.maxHealth;
var unitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 1.0
});
if (!isPlayer) {
unitGraphics.scaleX = -1; // Flip enemy units
}
// Add health bar background
var healthBarBg = self.attachAsset('energyBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.2,
y: -120
});
healthBarBg.tint = 0xFFFFFF;
// Add health bar
var healthBar = self.attachAsset('energyBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.2,
x: -40,
y: -120
});
healthBar.tint = 0xFF0000;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
// Update health bar
var healthPercent = self.health / self.maxHealth;
healthBar.scaleX = 0.8 * healthPercent;
// Keep health bar red
healthBar.tint = 0xFF0000;
if (self.health <= 0) {
LK.effects.flashObject(unitGraphics, 0xFF0000, 200);
LK.getSound('unitDeath').play();
// Gain elixir when destroying enemy units
if (self.isPlayer === false && currentElixir < maxElixir) {
currentElixir += elixirGainAmount;
if (currentElixir > maxElixir) currentElixir = maxElixir;
var elixirPercent = currentElixir / maxElixir;
elixirBar.scaleX = 1.0 * elixirPercent;
elixirText.setText("İksir: " + currentElixir + "/" + maxElixir);
}
self.destroy();
} else {
LK.effects.flashObject(unitGraphics, 0xFF0000, 150);
}
};
self.findTarget = function () {
var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
var allTargets = targetUnits.concat(targetTowers);
var closest = null;
var closestDistance = Infinity;
for (var i = 0; i < allTargets.length; i++) {
var target = allTargets[i];
if (!target || target.health <= 0) continue;
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDistance) {
closestDistance = distance;
closest = target;
}
}
return closest;
};
self.update = function () {
// Special behavior for healer units
if (self.type === 'healer') {
// Find injured teammates to heal
var targetUnits = self.isPlayer ? playerUnits : enemyUnits;
var healTarget = null;
var closestDistance = Infinity;
// Find closest injured teammate within healing range
for (var i = 0; i < targetUnits.length; i++) {
var unit = targetUnits[i];
if (unit && unit !== self && unit.health > 0 && unit.health < unit.maxHealth) {
var dx = unit.x - self.x;
var dy = unit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.attackRange && distance < closestDistance) {
closestDistance = distance;
healTarget = unit;
}
}
}
if (healTarget) {
// Heal teammate
if (self.attackCooldown <= 0) {
self.attackCooldown = self.attackSpeed;
// Heal the target
var healAmount = 50; // Healing amount per cast
healTarget.health += healAmount;
if (healTarget.health > healTarget.maxHealth) {
healTarget.health = healTarget.maxHealth;
}
// Update healed unit's health bar
var healedHealthPercent = healTarget.health / healTarget.maxHealth;
if (healTarget.children[3]) {
healTarget.children[3].scaleX = 0.8 * healedHealthPercent;
healTarget.children[3].tint = 0xFF0000; // Keep red
}
// Visual healing effects
// Visual healing effects
LK.effects.flashObject(self, 0x00FF00, 200); // Green flash for healer
LK.effects.flashObject(healTarget, 0x00FF00, 300); // Green flash for healed unit
}
} else {
// No injured teammates nearby, find enemy to attack
if (!self.target || self.target.health <= 0) {
self.target = self.findTarget();
}
if (self.target) {
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) {
// Attack enemy
if (self.attackCooldown <= 0) {
self.attackCooldown = self.attackSpeed;
LK.effects.flashObject(self, 0xFFFF00, 200);
var projectile = new Projectile(self.x, self.y - 40, self.target, self.attackDamage);
game.addChild(projectile);
projectiles.push(projectile);
}
} else {
// Move toward enemy target
var moveX = dx / distance * self.moveSpeed;
var moveY = dy / distance * self.moveSpeed;
self.x += moveX;
self.y += moveY;
}
}
}
} else {
// Normal unit behavior for non-healers
if (!self.target || self.target.health <= 0) {
self.target = self.findTarget();
}
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) {
// Attack
if (self.attackCooldown <= 0) {
self.attackCooldown = self.attackSpeed;
// Create attack effects
LK.effects.flashObject(self, 0xFFFF00, 200);
if (self.type === 'archer' || self.type === 'wizard' || self.type === 'dragon' || self.type === 'bomber' || self.type === 'freeze') {
// Ranged attack with projectile
var projectile = new Projectile(self.x, self.y - 40, self.target, self.attackDamage);
game.addChild(projectile);
projectiles.push(projectile);
} else {
// Melee attack with effects
if (self.type === 'bomber') {
// Bomber creates explosion effect
LK.effects.flashObject(self.target, 0xFF4500, 400);
LK.getSound('explosion').play();
} else if (self.type === 'berserker') {
// Berserker gets damage boost when low health
var damageBonus = self.health < self.maxHealth * 0.3 ? 50 : 0;
self.target.takeDamage(self.attackDamage + damageBonus);
LK.effects.flashObject(self, 0xDC143C, 300);
} else {
self.target.takeDamage(self.attackDamage);
}
}
}
} else {
// Move toward target
var moveX = dx / distance * self.moveSpeed;
var moveY = dy / distance * self.moveSpeed;
self.x += moveX;
self.y += moveY;
}
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var currentEnergy = 10;
var maxEnergy = 10;
var energyRegenRate = 1; // energy per second
var energyRegenTimer = 0;
var currentElixir = 0;
var maxElixir = 10;
var elixirGainAmount = 1;
var playerUnits = [];
var enemyUnits = [];
var playerTowers = [];
var enemyTowers = [];
var projectiles = [];
var playerCards = [];
var selectedCard = null;
var playerCups = storage.playerCups || 100; // Starting cups
var matchInProgress = false;
var matchTimer = 120 * 60; // 2 minutes in frames (60 FPS)
var matchTimerText = null;
var inOvertime = false;
// Override LK's game over and win functions to handle cup system
LK.showGameOver = function () {
playerCups -= 5;
if (playerCups < 0) playerCups = 0;
storage.playerCups = playerCups;
matchInProgress = false;
// Reset game state
game.destroy();
// Restart the game
location.reload();
};
LK.showYouWin = function () {
playerCups += 30;
storage.playerCups = playerCups;
matchInProgress = false;
// Reset game state
game.destroy();
// Restart the game
location.reload();
};
// Arena setup
var arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Add red centerline
var centerLine = game.addChild(LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// River removed
// Bridges removed
// Create towers
// Player towers (bottom)
var playerKingTower = new Tower(true, true);
playerKingTower.x = 1024;
playerKingTower.y = 2200;
game.addChild(playerKingTower);
playerTowers.push(playerKingTower);
var playerLeftTower = new Tower(true, false);
playerLeftTower.x = 600;
playerLeftTower.y = 2000;
game.addChild(playerLeftTower);
playerTowers.push(playerLeftTower);
var playerRightTower = new Tower(true, false);
playerRightTower.x = 1448;
playerRightTower.y = 2000;
game.addChild(playerRightTower);
playerTowers.push(playerRightTower);
// Enemy towers (top)
var enemyKingTower = new Tower(false, true);
enemyKingTower.x = 1024;
enemyKingTower.y = 600;
game.addChild(enemyKingTower);
enemyTowers.push(enemyKingTower);
var enemyLeftTower = new Tower(false, false);
enemyLeftTower.x = 600;
enemyLeftTower.y = 800;
game.addChild(enemyLeftTower);
enemyTowers.push(enemyLeftTower);
var enemyRightTower = new Tower(false, false);
enemyRightTower.x = 1448;
enemyRightTower.y = 800;
game.addChild(enemyRightTower);
enemyTowers.push(enemyRightTower);
// UI Setup - moved to bottom left corner
var energyBarBg = LK.gui.bottomLeft.addChild(LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 1.0,
x: 10,
y: -300,
scaleX: 1.0,
scaleY: 0.8
}));
energyBarBg.tint = 0x333333;
var energyBar = LK.gui.bottomLeft.addChild(LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 1.0,
y: -300,
x: 10,
scaleX: 1.0,
scaleY: 0.8
}));
var energyText = LK.gui.bottomLeft.addChild(new Text2("10/10", {
size: 35,
fill: 0xFFFFFF
}));
energyText.anchor.set(0, 1.0);
energyText.x = 60;
energyText.y = -270;
// Elixir bar setup - moved to bottom right corner
var elixirBarBg = LK.gui.bottomRight.addChild(LK.getAsset('energyBar', {
anchorX: 1.0,
anchorY: 1.0,
x: -5,
y: -400,
scaleX: 0.8,
scaleY: 0.6
}));
elixirBarBg.tint = 0x8B4513;
var elixirBar = LK.gui.bottomRight.addChild(LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 1.0,
x: -85,
y: -400,
scaleX: 0.8,
scaleY: 0.6
}));
elixirBar.tint = 0xDDA0DD;
var elixirText = LK.gui.bottomRight.addChild(new Text2("İksir: 0/10", {
size: 30,
fill: 0xFFFFFF
}));
elixirText.anchor.set(0.5, 1.0);
elixirText.x = -45;
elixirText.y = -370;
// Add match timer display
matchTimerText = LK.gui.top.addChild(new Text2("2:00", {
size: 60,
fill: 0xFFFFFF
}));
matchTimerText.anchor.set(0.5, 0);
matchTimerText.y = 100;
matchTimerText.visible = false;
// All available card types (15 total)
var allCardTypes = ['soldier', 'archer', 'tank', 'wizard', 'dragon', 'poison', 'goblin', 'giant', 'healer', 'assassin', 'bomber', 'freeze', 'berserker', 'guardian', 'fireball'];
var allCardCosts = [2, 3, 4, 5, 8, 3, 1, 6, 4, 2, 4, 5, 4, 7, 3];
var playerDeck = ['soldier', 'archer', 'tank', 'wizard', 'dragon', 'poison', 'goblin', 'giant']; // Default 8-card deck
function getCardName(type) {
switch (type) {
case 'soldier':
return 'Asker';
case 'archer':
return 'Okçu';
case 'tank':
return 'Tank';
case 'wizard':
return 'Büyücü';
case 'dragon':
return 'Ejder';
case 'poison':
return 'Zehir';
case 'freeze':
return 'Dondurma';
case 'guardian':
return 'Koruyucu';
case 'goblin':
return 'Goblin';
case 'giant':
return 'Dev';
case 'healer':
return 'Şifacı';
case 'assassin':
return 'Suikastçi';
case 'bomber':
return 'Bombacı';
case 'berserker':
return 'Berserker';
case 'fireball':
return 'Alev Topu';
default:
return 'Bilinmiyen';
}
}
function getCardHealth(type) {
switch (type) {
case 'soldier':
return 400;
case 'archer':
return 200;
case 'tank':
return 800;
case 'wizard':
return 300;
case 'dragon':
return 1200;
case 'poison':
return 250;
case 'freeze':
return 280;
case 'guardian':
return 215;
// Adjusted for 7-unit spawn
case 'goblin':
return 150;
case 'giant':
return 1500;
case 'healer':
return 250;
case 'assassin':
return 180;
case 'bomber':
return 220;
case 'berserker':
return 500;
case 'fireball':
return 100;
default:
return 100;
}
}
function setupPlayerCards() {
// Clear existing cards
for (var i = 0; i < playerCards.length; i++) {
playerCards[i].destroy();
}
playerCards = [];
// Create cards from player deck - ensure different cards in hand
var cardWidth = 220;
var totalWidth = 4 * cardWidth;
var startX = -(totalWidth / 2) + cardWidth / 2;
var availableTypes = playerDeck.slice(); // Copy of deck
for (var i = 0; i < 4; i++) {
// Randomly select from available types to ensure variety
var randomIndex = Math.floor(Math.random() * availableTypes.length);
var cardType = availableTypes[randomIndex];
// Remove selected type to prevent immediate duplicates
availableTypes.splice(randomIndex, 1);
// If we run out of unique types, refill from deck
if (availableTypes.length === 0) {
availableTypes = playerDeck.slice();
}
var cost = allCardCosts[allCardTypes.indexOf(cardType)];
var card = new Card(cardType, cost);
card.x = startX + i * cardWidth;
card.y = -80;
LK.gui.bottom.addChild(card);
playerCards.push(card);
}
}
// Create main menu
var mainMenu = new Container();
mainMenu.x = 0;
mainMenu.y = 0;
LK.gui.center.addChild(mainMenu);
var menuBg = mainMenu.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
}));
menuBg.tint = 0x1a1a2e;
var titleText = mainMenu.addChild(new Text2("Tower Defense Arena", {
size: 80,
fill: 0xFFFFFF
}));
titleText.anchor.set(0.5, 0.5);
titleText.y = -500;
var myCardsBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -250,
scaleX: 0.8,
scaleY: 0.8
}));
var myCardsText = mainMenu.addChild(new Text2("Kartlarım", {
size: 40,
fill: 0xFFFFFF
}));
myCardsText.anchor.set(0.5, 0.5);
myCardsText.x = -300;
myCardsText.y = -250;
var vsBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: -100,
y: -250,
scaleX: 0.8,
scaleY: 0.8
}));
var vsText = mainMenu.addChild(new Text2("İki Kişilik", {
size: 40,
fill: 0xFFFFFF
}));
vsText.anchor.set(0.5, 0.5);
vsText.x = -100;
vsText.y = -250;
var shopBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: -250,
scaleX: 0.8,
scaleY: 0.8
}));
var shopText = mainMenu.addChild(new Text2("Mağaza", {
size: 40,
fill: 0xFFFFFF
}));
shopText.anchor.set(0.5, 0.5);
shopText.x = 100;
shopText.y = -250;
var extraBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 300,
y: -250,
scaleX: 0.8,
scaleY: 0.8
}));
var extraText = mainMenu.addChild(new Text2("Ekstra", {
size: 40,
fill: 0xFFFFFF
}));
extraText.anchor.set(0.5, 0.5);
extraText.x = 300;
extraText.y = -250;
// Add Enter Match button
var enterMatchBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -50,
scaleX: 1.2,
scaleY: 0.8
}));
enterMatchBtn.tint = 0x00AA00;
var enterMatchText = mainMenu.addChild(new Text2("Maça Girme", {
size: 50,
fill: 0xFFFFFF
}));
enterMatchText.anchor.set(0.5, 0.5);
enterMatchText.x = 0;
enterMatchText.y = -50;
var saveBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: 150,
scaleX: 0.8,
scaleY: 0.8
}));
var saveText = mainMenu.addChild(new Text2("Kaydet", {
size: 40,
fill: 0xFFFFFF
}));
saveText.anchor.set(0.5, 0.5);
saveText.x = -200;
saveText.y = 150;
var loadBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 150,
scaleX: 0.8,
scaleY: 0.8
}));
var loadText = mainMenu.addChild(new Text2("Yükle", {
size: 40,
fill: 0xFFFFFF
}));
loadText.anchor.set(0.5, 0.5);
loadText.x = 200;
loadText.y = 150;
var cupBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: 300,
scaleX: 0.8,
scaleY: 0.8
}));
var cupText = mainMenu.addChild(new Text2("Kupa", {
size: 40,
fill: 0xFFFFFF
}));
cupText.anchor.set(0.5, 0.5);
cupText.x = -200;
cupText.y = 300;
var cupResetBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 300,
scaleX: 0.8,
scaleY: 0.8
}));
cupResetBtn.tint = 0xFF4444;
var cupResetText = mainMenu.addChild(new Text2("Kupa Sıfırla", {
size: 40,
fill: 0xFFFFFF
}));
cupResetText.anchor.set(0.5, 0.5);
cupResetText.x = 200;
cupResetText.y = 300;
// Add cup counter display
var cupCountText = mainMenu.addChild(new Text2("Kupalar: " + playerCups, {
size: 50,
fill: 0xFFD700
}));
cupCountText.anchor.set(0.5, 0.5);
cupCountText.x = 0;
cupCountText.y = 400;
// Update cup display function
function updateCupDisplay() {
cupCountText.setText("Kupalar: " + playerCups);
}
// Save game function
function saveGame() {
if (!matchInProgress) return;
var gameState = {
currentEnergy: currentEnergy,
playerCups: playerCups,
playerDeck: playerDeck.slice(),
playerUnitsData: [],
enemyUnitsData: [],
playerTowersData: [],
enemyTowersData: []
};
// Save player units data
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
gameState.playerUnitsData.push({
type: unit.type,
x: unit.x,
y: unit.y,
health: unit.health,
attackCooldown: unit.attackCooldown
});
}
// Save enemy units data
for (var i = 0; i < enemyUnits.length; i++) {
var unit = enemyUnits[i];
gameState.enemyUnitsData.push({
type: unit.type,
x: unit.x,
y: unit.y,
health: unit.health,
attackCooldown: unit.attackCooldown
});
}
// Save player towers data
for (var i = 0; i < playerTowers.length; i++) {
var tower = playerTowers[i];
gameState.playerTowersData.push({
health: tower.health,
x: tower.x,
y: tower.y,
isKing: tower.isKing
});
}
// Save enemy towers data
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
gameState.enemyTowersData.push({
health: tower.health,
x: tower.x,
y: tower.y,
isKing: tower.isKing
});
}
storage.savedGame = gameState;
}
// Load game function
function loadGame() {
var gameState = storage.savedGame;
if (!gameState) return;
// Clear existing game state
for (var i = 0; i < playerUnits.length; i++) {
playerUnits[i].destroy();
}
playerUnits = [];
for (var i = 0; i < enemyUnits.length; i++) {
enemyUnits[i].destroy();
}
enemyUnits = [];
for (var i = 0; i < projectiles.length; i++) {
projectiles[i].destroy();
}
projectiles = [];
// Restore basic game state
currentEnergy = gameState.currentEnergy || 10;
playerCups = gameState.playerCups || 100;
playerDeck = gameState.playerDeck || ['soldier', 'archer', 'tank', 'wizard'];
// Update UI
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.0 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
updateCupDisplay();
// Restore player units
for (var i = 0; i < gameState.playerUnitsData.length; i++) {
var unitData = gameState.playerUnitsData[i];
var unit = new Unit(unitData.type, true);
unit.x = unitData.x;
unit.y = unitData.y;
unit.health = unitData.health;
unit.attackCooldown = unitData.attackCooldown;
game.addChild(unit);
playerUnits.push(unit);
}
// Restore enemy units
for (var i = 0; i < gameState.enemyUnitsData.length; i++) {
var unitData = gameState.enemyUnitsData[i];
var unit = new Unit(unitData.type, false);
unit.x = unitData.x;
unit.y = unitData.y;
unit.health = unitData.health;
unit.attackCooldown = unitData.attackCooldown;
game.addChild(unit);
enemyUnits.push(unit);
}
// Restore towers health
for (var i = 0; i < gameState.playerTowersData.length && i < playerTowers.length; i++) {
var towerData = gameState.playerTowersData[i];
playerTowers[i].health = towerData.health;
// Update tower health bar
var tower = playerTowers[i];
var healthPercent = tower.health / tower.maxHealth;
tower.children[2].scaleX = 1.2 * healthPercent;
tower.children[3].setText(tower.health + '/' + tower.maxHealth);
tower.children[2].tint = 0xFF0000;
}
for (var i = 0; i < gameState.enemyTowersData.length && i < enemyTowers.length; i++) {
var towerData = gameState.enemyTowersData[i];
enemyTowers[i].health = towerData.health;
// Update tower health bar
var tower = enemyTowers[i];
var healthPercent = tower.health / tower.maxHealth;
tower.children[2].scaleX = 1.2 * healthPercent;
tower.children[3].setText(tower.health + '/' + tower.maxHealth);
tower.children[2].tint = 0xFF0000;
}
setupPlayerCards();
mainMenu.visible = false;
matchInProgress = true;
matchTimer = 120 * 60; // Reset timer when loading
matchTimerText.visible = true;
inOvertime = false;
matchTimerText.tint = 0xFFFFFF; // Reset timer color
}
// Button interactions using LK event system
enterMatchBtn.down = function () {
mainMenu.visible = false;
matchInProgress = true;
matchTimer = 120 * 60; // Reset timer to 2 minutes
matchTimerText.visible = true;
inOvertime = false;
matchTimerText.tint = 0xFFFFFF; // Reset timer color
};
myCardsBtn.down = function () {
deckBuilder.show();
};
vsBtn.down = function () {
mainMenu.visible = false;
};
shopBtn.down = function () {
// Shop functionality to be added
};
saveBtn.down = function () {
saveGame();
};
loadBtn.down = function () {
loadGame();
};
cupBtn.down = function () {
// Cup/Trophy functionality to be added
};
cupResetBtn.down = function () {
playerCups = 0;
storage.playerCups = playerCups;
updateCupDisplay();
};
extraBtn.down = function () {
// Extra functionality to be added
};
// Create deck builder
var deckBuilder = new DeckBuilder();
deckBuilder.x = 0;
deckBuilder.y = 0;
LK.gui.center.addChild(deckBuilder);
// Show main menu at start
mainMenu.visible = true;
// Setup initial cards
setupPlayerCards();
// Add deployment area indicator
var deploymentArea = game.addChild(LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1783,
scaleY: 0.5
}));
deploymentArea.tint = 0x00FF00;
deploymentArea.alpha = 0.3;
// Add fireball restricted area indicator
var fireballArea = game.addChild(LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1683,
scaleX: 0.7,
scaleY: 0.3
}));
fireballArea.tint = 0xFF4500;
fireballArea.alpha = 0.2;
// Add white targeting circle for fireball (initially hidden)
var targetingCircle = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.4,
scaleY: 2.4
}));
targetingCircle.tint = 0xFFFFFF;
targetingCircle.alpha = 0.5;
targetingCircle.visible = false;
// Simple AI for enemy
var aiTimer = 0;
var aiDeployInterval = 180; // Deploy every 3 seconds
var enemyEnergy = 10;
var enemyMaxEnergy = 10;
var enemyEnergyRegenTimer = 0;
// Enemy deck system - 8 different cards
var enemyDeck = ['soldier', 'archer', 'wizard', 'tank', 'goblin', 'giant', 'healer', 'berserker'];
var enemyHand = [];
var enemyHandSize = 4;
// Initialize enemy hand with different cards from deck
function setupEnemyHand() {
enemyHand = [];
var availableCards = enemyDeck.slice(); // Copy of deck
for (var i = 0; i < enemyHandSize; i++) {
if (availableCards.length === 0) {
availableCards = enemyDeck.slice(); // Refill if needed
}
var randomIndex = Math.floor(Math.random() * availableCards.length);
var cardType = availableCards[randomIndex];
enemyHand.push(cardType);
availableCards.splice(randomIndex, 1); // Remove to prevent duplicates
}
}
// Replace a used card in enemy hand
function replaceEnemyCard(usedCardIndex) {
var currentTypesInHand = [];
for (var i = 0; i < enemyHand.length; i++) {
if (i !== usedCardIndex) {
currentTypesInHand.push(enemyHand[i]);
}
}
// Get available cards not in hand
var availableCards = enemyDeck.filter(function (type) {
return currentTypesInHand.indexOf(type) === -1;
});
// If all cards are in hand, select randomly from deck
var newCardType;
if (availableCards.length > 0) {
newCardType = availableCards[Math.floor(Math.random() * availableCards.length)];
} else {
newCardType = enemyDeck[Math.floor(Math.random() * enemyDeck.length)];
}
enemyHand[usedCardIndex] = newCardType;
}
// Initialize enemy hand
setupEnemyHand();
function updateEnergy() {
// Don't update energy when deck builder is open or match is not in progress
if (deckBuilder.isOpen || !matchInProgress) {
return;
}
energyRegenTimer++;
if (energyRegenTimer >= 60) {
// 1 second at 60 FPS
energyRegenTimer = 0;
if (currentEnergy < maxEnergy) {
currentEnergy++;
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.0 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
}
}
}
function updateMatchTimer() {
// Don't update timer when deck builder is open or match is not in progress
if (deckBuilder.isOpen || !matchInProgress) {
return;
}
matchTimer--;
if (matchTimer < 0) matchTimer = 0;
// Update timer display
var minutes = Math.floor(matchTimer / (60 * 60));
var seconds = Math.floor(matchTimer % (60 * 60) / 60);
var timeString = (inOvertime ? "UZATMA " : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
matchTimerText.setText(timeString);
// Check if time is up
if (matchTimer <= 0) {
if (!inOvertime) {
// Enter overtime when 2 minutes expire regardless of tower status
inOvertime = true;
matchTimer = 60 * 60; // 1 minute in frames
matchTimerText.tint = 0xFF0000; // Make timer red for overtime
} else {
// Overtime has ended - first check tower count, then total health
var playerTowersAlive = 0;
var enemyTowersAlive = 0;
var playerTowerHealth = 0;
var enemyTowerHealth = 0;
// Count alive towers and sum their health
for (var i = 0; i < playerTowers.length; i++) {
if (playerTowers[i].health > 0) {
playerTowersAlive++;
playerTowerHealth += playerTowers[i].health;
}
}
for (var i = 0; i < enemyTowers.length; i++) {
if (enemyTowers[i].health > 0) {
enemyTowersAlive++;
enemyTowerHealth += enemyTowers[i].health;
}
}
// First check: Compare tower count
if (playerTowersAlive < enemyTowersAlive) {
// Player loses - has fewer towers alive
playerCups -= 5;
if (playerCups < 0) playerCups = 0;
storage.playerCups = playerCups;
matchInProgress = false;
LK.showGameOver();
} else if (enemyTowersAlive < playerTowersAlive) {
// Enemy loses - has fewer towers alive
playerCups += 30;
storage.playerCups = playerCups;
matchInProgress = false;
LK.showYouWin();
} else if (playerTowersAlive === enemyTowersAlive) {
// Same number of towers - check total health
if (playerTowerHealth < enemyTowerHealth) {
// Player loses - has less tower health remaining
playerCups -= 5;
if (playerCups < 0) playerCups = 0;
storage.playerCups = playerCups;
matchInProgress = false;
LK.showGameOver();
} else if (enemyTowerHealth < playerTowerHealth) {
// Enemy loses - has less tower health remaining
playerCups += 30;
storage.playerCups = playerCups;
matchInProgress = false;
LK.showYouWin();
} else {
// Draw - same tower count and health, continue overtime indefinitely until someone wins
// Reset overtime timer for another minute
matchTimer = 60 * 60; // Another minute in frames
}
}
}
}
}
function updateAI() {
// Don't update AI when deck builder is open or match is not in progress
if (deckBuilder.isOpen || !matchInProgress) {
return;
}
// Update enemy energy
enemyEnergyRegenTimer++;
if (enemyEnergyRegenTimer >= 60) {
enemyEnergyRegenTimer = 0;
if (enemyEnergy < enemyMaxEnergy) {
enemyEnergy++;
}
}
aiTimer++;
if (aiTimer >= aiDeployInterval) {
aiTimer = 0;
// Simple AI: deploy random unit or fireball
var actionType = Math.random();
if (actionType < 0.15 && enemyEnergy >= 3) {
// Deploy fireball - only if there are player targets in range
var validTargets = [];
// Check for player units in player area
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0 && unit.y > 1366) {
validTargets.push({
x: unit.x,
y: unit.y
});
}
}
// Check for player towers
for (var i = 0; i < playerTowers.length; i++) {
var tower = playerTowers[i];
if (tower && tower.health > 0) {
validTargets.push({
x: tower.x,
y: tower.y
});
}
}
// Only cast fireball if there are valid targets
if (validTargets.length > 0) {
var target = validTargets[Math.floor(Math.random() * validTargets.length)];
var fireballX = target.x + (Math.random() - 0.5) * 200; // Add some randomness
var fireballY = target.y + (Math.random() - 0.5) * 200;
// Keep within bounds
fireballX = Math.max(300, Math.min(1748, fireballX));
fireballY = Math.max(1366, Math.min(2200, fireballY));
// Create fireball projectile
var fireballProjectile = game.addChild(LK.getAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 600
}));
// Animate projectile to target location
tween(fireballProjectile, {
x: fireballX,
y: fireballY
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Create explosion damage area
var explosionRadius = 120;
var explosionDamage = 200;
// Damage all player units in radius
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - fireballX;
var dy = unit.y - fireballY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius) {
unit.takeDamage(explosionDamage);
}
}
}
// Damage player towers in radius
for (var i = 0; i < playerTowers.length; i++) {
var tower = playerTowers[i];
if (tower && tower.health > 0) {
var dx = tower.x - fireballX;
var dy = tower.y - fireballY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius) {
tower.takeDamage(explosionDamage);
}
}
}
// Visual effects
LK.effects.flashScreen(0xFF4500, 300);
LK.getSound('explosion').play();
// Remove fireball projectile
fireballProjectile.destroy();
}
});
enemyEnergy -= 3;
}
} else if (actionType < 0.25 && enemyEnergy >= 5) {
// Deploy freeze spell - only if there are player units to freeze
var validFreezeTargets = [];
// Check for player units in any area (freeze can target anywhere)
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
validFreezeTargets.push({
x: unit.x,
y: unit.y
});
}
}
// Only cast freeze if there are valid targets
if (validFreezeTargets.length > 0) {
var target = validFreezeTargets[Math.floor(Math.random() * validFreezeTargets.length)];
var freezeX = target.x + (Math.random() - 0.5) * 200; // Add some randomness
var freezeY = target.y + (Math.random() - 0.5) * 200;
// Keep within bounds
freezeX = Math.max(300, Math.min(1748, freezeX));
freezeY = Math.max(600, Math.min(2200, freezeY));
// Create freeze projectile
var freezeProjectile = game.addChild(LK.getAsset('freeze', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 600
}));
// Animate projectile to target location
tween(freezeProjectile, {
x: freezeX,
y: freezeY
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Create freeze effect area
var freezeRadius = 150;
// Freeze all player units in radius for 3 seconds with rotation
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - freezeX;
var dy = unit.y - freezeY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < freezeRadius) {
// Store original move speed
if (!unit.originalMoveSpeed) unit.originalMoveSpeed = unit.moveSpeed;
// Freeze unit (stop movement)
unit.moveSpeed = 0;
// Add spinning rotation effect
tween(unit, {
rotation: unit.rotation + Math.PI * 6
}, {
duration: 3000,
easing: tween.linear
});
// Restore movement after 3 seconds using closure to capture unit reference
(function (frozenUnit) {
LK.setTimeout(function () {
if (frozenUnit && frozenUnit.health > 0 && frozenUnit.originalMoveSpeed) {
frozenUnit.moveSpeed = frozenUnit.originalMoveSpeed;
}
}, 3000);
})(unit);
}
}
}
// Visual effects
LK.effects.flashScreen(0x87CEEB, 300);
// Remove freeze projectile
freezeProjectile.destroy();
}
});
enemyEnergy -= 5;
}
} else if (actionType < 0.35 && enemyEnergy >= 3) {
// Deploy poison spell - only if there are player targets
var validPoisonTargets = [];
// Check for player units
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
validPoisonTargets.push({
x: unit.x,
y: unit.y
});
}
}
// Check for player towers
for (var i = 0; i < playerTowers.length; i++) {
var tower = playerTowers[i];
if (tower && tower.health > 0) {
validPoisonTargets.push({
x: tower.x,
y: tower.y
});
}
}
// Only cast poison if there are valid targets
if (validPoisonTargets.length > 0) {
var target = validPoisonTargets[Math.floor(Math.random() * validPoisonTargets.length)];
var poisonX = target.x + (Math.random() - 0.5) * 200; // Add some randomness
var poisonY = target.y + (Math.random() - 0.5) * 200;
// Keep within bounds
poisonX = Math.max(300, Math.min(1748, poisonX));
poisonY = Math.max(600, Math.min(2200, poisonY));
// Create poison projectile
var poisonProjectile = game.addChild(LK.getAsset('poison', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 600
}));
// Animate projectile to target location
tween(poisonProjectile, {
x: poisonX,
y: poisonY
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Create poison effect circle
var poisonEffect = game.addChild(LK.getAsset('poison', {
anchorX: 0.5,
anchorY: 0.5,
x: poisonX,
y: poisonY,
scaleX: 2,
scaleY: 2
}));
poisonEffect.tint = 0x9ACD32; // Yellow-green poison color
poisonEffect.alpha = 0.7;
// Create poison damage area indicator circle
var poisonAreaCircle = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: poisonX,
y: poisonY,
scaleX: 2.4,
scaleY: 2.4
}));
poisonAreaCircle.tint = 0x9ACD32; // Yellow-green for poison area
poisonAreaCircle.alpha = 0.3;
// Create poison damage area
var poisonRadius = 120;
var poisonDamage = 80;
// Apply poison damage over 5 seconds for AI poison
var enemyPoisonTimer = 0;
var enemyPoisonInterval = LK.setInterval(function () {
enemyPoisonTimer += 1000;
// Damage all player units in radius every second
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - poisonX;
var dy = unit.y - poisonY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < poisonRadius) {
unit.takeDamage(poisonDamage);
}
}
}
// Damage player towers in radius
for (var i = 0; i < playerTowers.length; i++) {
var tower = playerTowers[i];
if (tower && tower.health > 0) {
var dx = tower.x - poisonX;
var dy = tower.y - poisonY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < poisonRadius) {
tower.takeDamage(poisonDamage);
}
}
}
// Stop poison after 5 seconds
if (enemyPoisonTimer >= 5000) {
LK.clearInterval(enemyPoisonInterval);
}
}, 1000);
// Visual effects
LK.effects.flashScreen(0x9ACD32, 300);
// Remove poison effect and area circle after 5 seconds
LK.setTimeout(function () {
poisonEffect.destroy();
poisonAreaCircle.destroy();
LK.clearInterval(enemyPoisonInterval);
}, 5000);
// Remove poison projectile
poisonProjectile.destroy();
}
});
enemyEnergy -= 3;
}
} else if (enemyEnergy >= 2) {
// Deploy regular unit from enemy hand - enemy units spawn in enemy area (above centerline)
var availableCards = [];
for (var i = 0; i < enemyHand.length; i++) {
var cardType = enemyHand[i];
var unitCost = allCardCosts[allCardTypes.indexOf(cardType)];
if (enemyEnergy >= unitCost) {
availableCards.push({
type: cardType,
cost: unitCost,
index: i
});
}
}
if (availableCards.length > 0) {
// Select random available card
var selectedCard = availableCards[Math.floor(Math.random() * availableCards.length)];
// Special case for guardian - spawn 7 units
if (selectedCard.type === 'guardian') {
var baseX = 800 + Math.random() * 400;
var baseY = 900 + Math.random() * 300;
var guardianPositions = [{
x: baseX,
y: baseY
},
// Center
{
x: baseX - 80,
y: baseY - 40
},
// Top left
{
x: baseX + 80,
y: baseY - 40
},
// Top right
{
x: baseX - 80,
y: baseY + 40
},
// Bottom left
{
x: baseX + 80,
y: baseY + 40
},
// Bottom right
{
x: baseX - 120,
y: baseY
},
// Left
{
x: baseX + 120,
y: baseY
} // Right
];
for (var g = 0; g < guardianPositions.length; g++) {
var enemyUnit = new Unit(selectedCard.type, false);
enemyUnit.x = guardianPositions[g].x;
enemyUnit.y = guardianPositions[g].y;
game.addChild(enemyUnit);
enemyUnits.push(enemyUnit);
}
} else {
// Deploy single unit for all other types
var enemyUnit = new Unit(selectedCard.type, false);
enemyUnit.x = 800 + Math.random() * 400;
enemyUnit.y = 900 + Math.random() * 300; // Enemy area only
game.addChild(enemyUnit);
enemyUnits.push(enemyUnit);
}
enemyEnergy -= selectedCard.cost;
// Replace used card in hand
replaceEnemyCard(selectedCard.index);
}
}
}
}
game.move = function (x, y, obj) {
// Show targeting circle for spell cards when selected
if (selectedCard && (selectedCard.type === 'fireball' || selectedCard.type === 'freeze' || selectedCard.type === 'poison')) {
// Show targeting circle for fireball, freeze, and poison
targetingCircle.visible = true;
targetingCircle.x = x;
targetingCircle.y = y;
// Change circle color based on spell type
if (selectedCard.type === 'freeze') {
targetingCircle.tint = 0x87CEEB; // Light blue for freeze
} else if (selectedCard.type === 'poison') {
targetingCircle.tint = 0x9ACD32; // Yellow-green for poison
} else {
targetingCircle.tint = 0xFFFFFF; // White for fireball
}
} else {
targetingCircle.visible = false;
}
};
game.down = function (x, y, obj) {
if (selectedCard) {
// Special handling for fireball spell
if (selectedCard.type === 'fireball') {
// Hide targeting circle
targetingCircle.visible = false;
// Fireball can be deployed anywhere on the battlefield within bounds
var fireballAllowed = y > 600 && y < 2200 && x > 300 && x < 1748;
if (fireballAllowed && currentEnergy >= selectedCard.cost) {
// Create fireball projectile that travels like freeze
var fireballProjectile = game.addChild(LK.getAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2200
}));
// Animate projectile to target location
tween(fireballProjectile, {
x: x,
y: y
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Create explosion damage area
var explosionRadius = 120;
var explosionDamage = 200;
// Damage all enemy units in radius
for (var i = 0; i < enemyUnits.length; i++) {
var unit = enemyUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - x;
var dy = unit.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius) {
unit.takeDamage(explosionDamage);
}
}
}
// Damage enemy towers in radius
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
if (tower && tower.health > 0) {
var dx = tower.x - x;
var dy = tower.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius) {
tower.takeDamage(explosionDamage);
}
}
}
// Visual effects
LK.effects.flashScreen(0xFF4500, 500);
LK.getSound('explosion').play();
// Remove fireball projectile
fireballProjectile.destroy();
}
});
currentEnergy -= selectedCard.cost;
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.0 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
LK.getSound('cardPlay').play();
// Remove card and replace
var cardIndex = playerCards.indexOf(selectedCard);
if (cardIndex !== -1) {
selectedCard.destroy();
playerCards.splice(cardIndex, 1);
// Get current card types in hand to avoid duplicates
var currentTypesFireball = [];
for (var j = 0; j < playerCards.length; j++) {
if (playerCards[j] && playerCards[j] !== selectedCard) {
currentTypesFireball.push(playerCards[j].type);
}
}
// Select a card type not currently in hand if possible
var availableTypesFireball = playerDeck.filter(function (type) {
return currentTypesFireball.indexOf(type) === -1;
});
// If all types are in hand, select randomly from deck
var newCardType;
if (availableTypesFireball.length > 0) {
newCardType = availableTypesFireball[Math.floor(Math.random() * availableTypesFireball.length)];
} else {
newCardType = playerDeck[Math.floor(Math.random() * playerDeck.length)];
}
var newCardCost = allCardCosts[allCardTypes.indexOf(newCardType)];
var newCard = new Card(newCardType, newCardCost);
var cardWidth = 220;
var totalWidth = 4 * cardWidth;
var startX = -(totalWidth / 2) + cardWidth / 2;
newCard.x = startX + cardIndex * cardWidth;
newCard.y = -80;
LK.gui.bottom.addChild(newCard);
playerCards.splice(cardIndex, 0, newCard);
}
}
// Deselect card
selectedCard = null;
targetingCircle.visible = false;
} else if (selectedCard.type === 'poison') {
// Hide targeting circle
targetingCircle.visible = false;
// Poison can be thrown anywhere on the field
if (currentEnergy >= selectedCard.cost) {
// Create poison effect circle that damages units in area
var poisonEffect = game.addChild(LK.getAsset('poison', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 2,
scaleY: 2
}));
poisonEffect.tint = 0x9ACD32; // Yellow-green poison color
poisonEffect.alpha = 0.7;
// Create poison damage area indicator circle
var poisonAreaCircle = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 2.4,
scaleY: 2.4
}));
poisonAreaCircle.tint = 0x9ACD32; // Yellow-green for poison area
poisonAreaCircle.alpha = 0.3;
// Create poison damage area
var poisonRadius = 120;
var poisonDamage = 80;
// Apply poison damage over 5 seconds
var poisonTimer = 0;
var poisonInterval = LK.setInterval(function () {
poisonTimer += 1000;
// Damage all units in radius every second
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - x;
var dy = unit.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < poisonRadius) {
unit.takeDamage(poisonDamage);
}
}
}
for (var i = 0; i < enemyUnits.length; i++) {
var unit = enemyUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - x;
var dy = unit.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < poisonRadius) {
unit.takeDamage(poisonDamage);
}
}
}
// Damage towers in radius
for (var i = 0; i < playerTowers.length; i++) {
var tower = playerTowers[i];
if (tower && tower.health > 0) {
var dx = tower.x - x;
var dy = tower.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < poisonRadius) {
tower.takeDamage(poisonDamage);
}
}
}
for (var i = 0; i < enemyTowers.length; i++) {
var tower = enemyTowers[i];
if (tower && tower.health > 0) {
var dx = tower.x - x;
var dy = tower.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < poisonRadius) {
tower.takeDamage(poisonDamage);
}
}
}
// Stop poison after 5 seconds
if (poisonTimer >= 5000) {
LK.clearInterval(poisonInterval);
}
}, 1000);
// Visual effects
LK.effects.flashScreen(0x9ACD32, 300);
// Remove poison effect and area circle after 5 seconds
LK.setTimeout(function () {
poisonEffect.destroy();
poisonAreaCircle.destroy();
LK.clearInterval(poisonInterval);
}, 5000);
currentEnergy -= selectedCard.cost;
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.0 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
LK.getSound('cardPlay').play();
// Remove card and replace
var cardIndex = playerCards.indexOf(selectedCard);
if (cardIndex !== -1) {
selectedCard.destroy();
playerCards.splice(cardIndex, 1);
// Get current card types in hand to avoid duplicates
var currentTypesPoison = [];
for (var j = 0; j < playerCards.length; j++) {
if (playerCards[j] && playerCards[j] !== selectedCard) {
currentTypesPoison.push(playerCards[j].type);
}
}
// Select a card type not currently in hand if possible
var availableTypesPoison = playerDeck.filter(function (type) {
return currentTypesPoison.indexOf(type) === -1;
});
// If all types are in hand, select randomly from deck
var newCardType;
if (availableTypesPoison.length > 0) {
newCardType = availableTypesPoison[Math.floor(Math.random() * availableTypesPoison.length)];
} else {
newCardType = playerDeck[Math.floor(Math.random() * playerDeck.length)];
}
var newCardCost = allCardCosts[allCardTypes.indexOf(newCardType)];
var newCard = new Card(newCardType, newCardCost);
var cardWidth = 220;
var totalWidth = 4 * cardWidth;
var startX = -(totalWidth / 2) + cardWidth / 2;
newCard.x = startX + cardIndex * cardWidth;
newCard.y = -80;
LK.gui.bottom.addChild(newCard);
playerCards.splice(cardIndex, 0, newCard);
}
}
// Deselect card
selectedCard = null;
targetingCircle.visible = false;
} else if (selectedCard.type === 'freeze') {
// Hide targeting circle
targetingCircle.visible = false;
// Freeze can be thrown anywhere on the field
if (currentEnergy >= selectedCard.cost) {
// Create freeze projectile that travels like fireball
var freezeProjectile = game.addChild(LK.getAsset('freeze', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2200
}));
// Animate projectile to target location
tween(freezeProjectile, {
x: x,
y: y
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Create freeze effect area
var freezeRadius = 150;
// Freeze all units in radius for 3 seconds with rotation
for (var i = 0; i < playerUnits.length; i++) {
var unit = playerUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - x;
var dy = unit.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < freezeRadius) {
// Store original move speed
if (!unit.originalMoveSpeed) unit.originalMoveSpeed = unit.moveSpeed;
// Freeze unit (stop movement)
unit.moveSpeed = 0;
// Add spinning rotation effect
tween(unit, {
rotation: unit.rotation + Math.PI * 6
}, {
duration: 3000,
easing: tween.linear
});
// Restore movement after 3 seconds using closure to capture unit reference
(function (frozenUnit) {
LK.setTimeout(function () {
if (frozenUnit && frozenUnit.health > 0 && frozenUnit.originalMoveSpeed) {
frozenUnit.moveSpeed = frozenUnit.originalMoveSpeed;
}
}, 3000);
})(unit);
}
}
}
for (var i = 0; i < enemyUnits.length; i++) {
var unit = enemyUnits[i];
if (unit && unit.health > 0) {
var dx = unit.x - x;
var dy = unit.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < freezeRadius) {
// Store original move speed
if (!unit.originalMoveSpeed) unit.originalMoveSpeed = unit.moveSpeed;
// Freeze unit (stop movement)
unit.moveSpeed = 0;
// Add spinning rotation effect
tween(unit, {
rotation: unit.rotation + Math.PI * 6
}, {
duration: 3000,
easing: tween.linear
});
// Restore movement after 3 seconds using closure to capture unit reference
(function (frozenUnit) {
LK.setTimeout(function () {
if (frozenUnit && frozenUnit.health > 0 && frozenUnit.originalMoveSpeed) {
frozenUnit.moveSpeed = frozenUnit.originalMoveSpeed;
}
}, 3000);
})(unit);
}
}
}
// Visual effects
LK.effects.flashScreen(0x87CEEB, 300);
// Remove freeze projectile
freezeProjectile.destroy();
}
});
currentEnergy -= selectedCard.cost;
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.0 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
LK.getSound('cardPlay').play();
// Remove card and replace
var cardIndex = playerCards.indexOf(selectedCard);
if (cardIndex !== -1) {
selectedCard.destroy();
playerCards.splice(cardIndex, 1);
// Get current card types in hand to avoid duplicates
var currentTypesFreeze = [];
for (var j = 0; j < playerCards.length; j++) {
if (playerCards[j] && playerCards[j] !== selectedCard) {
currentTypesFreeze.push(playerCards[j].type);
}
}
// Select a card type not currently in hand if possible
var availableTypesFreeze = playerDeck.filter(function (type) {
return currentTypesFreeze.indexOf(type) === -1;
});
// If all types are in hand, select randomly from deck
var newCardType;
if (availableTypesFreeze.length > 0) {
newCardType = availableTypesFreeze[Math.floor(Math.random() * availableTypesFreeze.length)];
} else {
newCardType = playerDeck[Math.floor(Math.random() * playerDeck.length)];
}
var newCardCost = allCardCosts[allCardTypes.indexOf(newCardType)];
var newCard = new Card(newCardType, newCardCost);
var cardWidth = 220;
var totalWidth = 4 * cardWidth;
var startX = -(totalWidth / 2) + cardWidth / 2;
newCard.x = startX + cardIndex * cardWidth;
newCard.y = -80;
LK.gui.bottom.addChild(newCard);
playerCards.splice(cardIndex, 0, newCard);
}
}
// Deselect card
selectedCard = null;
targetingCircle.visible = false;
} else if (y > 1366 && y < 2200) {
// Regular unit deployment - restrict to player's area only (below centerline)
if (currentEnergy >= selectedCard.cost) {
// Deploy unit(s) - special case for guardian spawns 7 units
if (selectedCard.type === 'guardian') {
// Deploy 7 guardians in a formation around the target position
var guardianPositions = [{
x: x,
y: y
},
// Center
{
x: x - 80,
y: y - 40
},
// Top left
{
x: x + 80,
y: y - 40
},
// Top right
{
x: x - 80,
y: y + 40
},
// Bottom left
{
x: x + 80,
y: y + 40
},
// Bottom right
{
x: x - 120,
y: y
},
// Left
{
x: x + 120,
y: y
} // Right
];
for (var g = 0; g < guardianPositions.length; g++) {
var newUnit = new Unit(selectedCard.type, true);
newUnit.x = guardianPositions[g].x;
newUnit.y = guardianPositions[g].y;
game.addChild(newUnit);
playerUnits.push(newUnit);
}
} else {
// Deploy single unit for all other types
var newUnit = new Unit(selectedCard.type, true);
newUnit.x = x;
newUnit.y = y;
game.addChild(newUnit);
playerUnits.push(newUnit);
}
currentEnergy -= selectedCard.cost;
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.0 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
LK.getSound('cardPlay').play();
// Remove card from hand and get replacement from deck
var cardIndex = playerCards.indexOf(selectedCard);
if (cardIndex !== -1) {
selectedCard.destroy();
playerCards.splice(cardIndex, 1);
// Get current card types in hand to avoid duplicates
var currentTypes = [];
for (var j = 0; j < playerCards.length; j++) {
if (playerCards[j] && playerCards[j] !== selectedCard) {
currentTypes.push(playerCards[j].type);
}
}
// Select a card type not currently in hand if possible
var availableTypes = playerDeck.filter(function (type) {
return currentTypes.indexOf(type) === -1;
});
// If all types are in hand, select randomly from deck
var newCardType;
if (availableTypes.length > 0) {
newCardType = availableTypes[Math.floor(Math.random() * availableTypes.length)];
} else {
newCardType = playerDeck[Math.floor(Math.random() * playerDeck.length)];
}
var newCardCost = allCardCosts[allCardTypes.indexOf(newCardType)];
var newCard = new Card(newCardType, newCardCost);
var cardWidth = 220;
var totalWidth = 4 * cardWidth;
var startX = -(totalWidth / 2) + cardWidth / 2;
newCard.x = startX + cardIndex * cardWidth;
newCard.y = -80;
LK.gui.bottom.addChild(newCard);
playerCards.splice(cardIndex, 0, newCard);
}
}
// Deselect card
selectedCard = null;
targetingCircle.visible = false;
} else {
// Deselect card if clicked outside valid area
if (selectedCard) {
selectedCard.children[0].tint = 0xFFFFFF;
selectedCard.selected = false;
selectedCard = null;
}
targetingCircle.visible = false;
}
}
};
game.update = function () {
updateEnergy();
updateMatchTimer();
updateAI();
// Clean up destroyed units
for (var i = playerUnits.length - 1; i >= 0; i--) {
if (playerUnits[i].health <= 0) {
playerUnits[i].destroy();
playerUnits.splice(i, 1);
}
}
for (var i = enemyUnits.length - 1; i >= 0; i--) {
if (enemyUnits[i].health <= 0) {
enemyUnits[i].destroy();
enemyUnits.splice(i, 1);
}
}
for (var i = projectiles.length - 1; i >= 0; i--) {
if (!projectiles[i].parent) {
projectiles.splice(i, 1);
}
}
// Clean up destroyed towers
for (var i = playerTowers.length - 1; i >= 0; i--) {
if (playerTowers[i].health <= 0 && playerTowers[i].parent) {
playerTowers.splice(i, 1);
}
}
for (var i = enemyTowers.length - 1; i >= 0; i--) {
if (enemyTowers[i].health <= 0 && enemyTowers[i].parent) {
enemyTowers.splice(i, 1);
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -214,9 +214,9 @@
scaleX: 1.2,
scaleY: 0.3,
y: -150
});
- healthBarBg.tint = 0x333333;
+ healthBarBg.tint = 0xFFFFFF;
// Add health bar
var healthBar = self.attachAsset('energyBar', {
anchorX: 0,
anchorY: 0.5,
@@ -394,9 +394,9 @@
scaleX: 0.8,
scaleY: 0.2,
y: -120
});
- healthBarBg.tint = 0x333333;
+ healthBarBg.tint = 0xFFFFFF;
// Add health bar
var healthBar = self.attachAsset('energyBar', {
anchorX: 0,
anchorY: 0.5,
2d Archer bird eye. In-Game asset. 2d. High contrast. No shadows
2d knight bird. In-Game asset. 2d. High contrast. No shadows
2d bird goblin. In-Game asset. 2d. High contrast. No shadows
2d bird giant. In-Game asset. 2d. High contrast. No shadows
Yer yeşil üstünde köyü yeşil çim olsun
2d assassin bird. In-Game asset. 2d. High contrast. No shadows
2d bird wizard. In-Game asset. 2d. High contrast. No shadows
2d bird bear. In-Game asset. 2d. High contrast. No shadows
2d bird berserker. In-Game asset. 2d. High contrast. No shadows
2d bird bomber. In-Game asset. 2d. High contrast. No shadows
2d bird dragon. In-Game asset. 2d. High contrast. No shadows
Fireball. In-Game asset. 2d. High contrast. No shadows
Card slot. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
2d bird healer. In-Game asset. 2d. High contrast. No shadows
2d Freeze. In-Game asset. 2d. High contrast. No shadows
2d Poison. In-Game asset. 2d. High contrast. No shadows
King tower. In-Game asset. 2d. High contrast. No shadows
Blue Tower. In-Game asset. 2d. High contrast. No shadows
King tower red. In-Game asset. 2d. High contrast. No shadows
Red tower. In-Game asset. 2d. High contrast. No shadows
2d bird guardian. In-Game asset. 2d. High contrast. No shadows