User prompt
Maça girme tuşu olsun
User prompt
Kartlar nehirden geçemez ve kartların olduğu yeri ortala ana menü ekle ana menüde kartlarım iki kişilik mağaza kupa yazsın
User prompt
Please fix the bug: 'ReferenceError: cardTypes is not defined' in or related to this line: 'var unitType = cardTypes[Math.floor(Math.random() * cardTypes.length)];' Line Number: 646
User prompt
Kart atınca daha kart atılmıyo ve deste oluşturucu gelsin 15 tane kart olsun bide atıs etekleri olsun kartların canı olsun iki tane köprü olsun
User prompt
Kart atınca karakter kart bölmesinden gidiyor ve kartları sadece kendi bölgemize atalım köprü ekle köprüden geçsinler kartların canı olsun
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'concat')' in or related to this line: 'var allTargets = enemyUnits.concat(towers);' Line Number: 230
Code edit (1 edits merged)
Please save this source code
User prompt
Tower Defense Arena Clash
Initial prompt
> "Gerçek zamanlı stratejiye dayalı, Clash Royale benzeri bir mobil oyun tasarla. Oyunda 1'e 1 gerçek zamanlı savaşlar olacak. Oyuncular kart desteleriyle kendi birliklerini, büyülerini ve savunmalarını seçerek üç kuleli bir arenada rakip kuleleri yok etmeye çalışacak. Her kartın farklı enerji maliyeti ve özellikleri olacak. Arenada ortada bir nehir bulunacak, iki tarafta oyuncuların kuleleri olacak. Oyunun içinde seviye atlama, kupa sistemi, farklı arenalar, özel etkinlikler ve klan sistemi olmalı. Grafik tarzı çizgi film gibi ama yüksek kaliteli ve renkli olsun. Oyun dengeli, rekabetçi ve çevrim içi çok oyunculu olacak şekilde tasarlansın. Ana hedef: rakip kral kulesini yok etmek."
/****
* Plugins
****/
var tween = LK.import("@upit/tween.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 health based on unit type
var healthValue = getCardHealth(type);
var healthText = self.addChild(new Text2(healthValue.toString(), {
size: 30,
fill: 0xFF0000
}));
healthText.anchor.set(0.5, 0.5);
healthText.y = 110;
self.down = function (x, y, obj) {
if (deckBuilder && deckBuilder.isOpen) {
deckBuilder.selectCard(self.type);
return;
}
if (currentEnergy >= self.cost && !selectedCard) {
selectedCard = self;
self.selected = true;
cardBg.tint = 0x00FF00;
}
};
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("Choose 4 Cards", {
size: 60,
fill: 0xFFFFFF
}));
titleText.anchor.set(0.5, 0.5);
titleText.y = -300;
self.show = function () {
self.isOpen = true;
self.visible = true;
self.selectedDeck = [];
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();
}
}
for (var i = 0; i < Math.min(8, 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 % 4 * 200;
cardOption.y = -100 + Math.floor(i / 4) * 320;
cardOption.scaleX = 0.7;
cardOption.scaleY = 0.7;
}
};
self.selectCard = function (cardType) {
if (self.selectedDeck.length < 4) {
self.selectedDeck.push(cardType);
if (self.selectedDeck.length === 4) {
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
});
// Health bar
var healthBarBg = self.addChild(LK.getAsset('energyBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.3,
y: -200
}));
healthBarBg.tint = 0x333333;
var healthBar = self.addChild(LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.3,
y: -200,
x: -60
}));
healthBar.tint = isPlayer ? 0x00FF00 : 0xFF0000;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
var healthPercent = self.health / self.maxHealth;
healthBar.scaleX = 0.4 * healthPercent;
// Flash effect
LK.effects.flashObject(towerGraphics, 0xFF0000, 300);
LK.getSound('towerHit').play();
if (self.health <= 0) {
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 'knight':
self.maxHealth = 600;
self.moveSpeed = 1.8;
self.attackDamage = 100;
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;
case 'mage':
self.maxHealth = 280;
self.moveSpeed = 2.1;
self.attackDamage = 160;
self.attackRange = 190;
break;
case 'berserker':
self.maxHealth = 500;
self.moveSpeed = 2.3;
self.attackDamage = 140;
break;
case 'paladin':
self.maxHealth = 700;
self.moveSpeed = 1.6;
self.attackDamage = 110;
break;
}
self.health = self.maxHealth;
var unitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 1.0
});
if (!isPlayer) {
unitGraphics.scaleX = -1; // Flip enemy units
}
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(unitGraphics, 0xFF0000, 200);
LK.getSound('unitDeath').play();
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 () {
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 === 'healer' || self.type === 'bomber' || self.type === 'mage') {
// 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;
// Check if unit needs to cross bridge
var bridgeX = 1024;
var bridgeY = 1366;
var riverTop = 1326;
var riverBottom = 1406;
// If unit is trying to cross river, guide it to bridge first
if (self.isPlayer && self.y > riverBottom && self.target.y < riverTop || !self.isPlayer && self.y < riverTop && self.target.y > riverBottom) {
// Guide to bridge center first
var bridgeDx = bridgeX - self.x;
var bridgeDy = bridgeY - self.y;
var bridgeDistance = Math.sqrt(bridgeDx * bridgeDx + bridgeDy * bridgeDy);
if (bridgeDistance > 50) {
// Move toward bridge
moveX = bridgeDx / bridgeDistance * self.moveSpeed;
moveY = bridgeDy / bridgeDistance * 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 playerUnits = [];
var enemyUnits = [];
var playerTowers = [];
var enemyTowers = [];
var projectiles = [];
var playerCards = [];
var selectedCard = null;
// Arena setup
var arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
var river = game.addChild(LK.getAsset('river', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Add bridges over the river
var bridge1 = game.addChild(LK.getAsset('bridge', {
anchorX: 0.5,
anchorY: 0.5,
x: 700,
y: 1366
}));
var bridge2 = game.addChild(LK.getAsset('bridge', {
anchorX: 0.5,
anchorY: 0.5,
x: 1348,
y: 1366
}));
// 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
var energyBarBg = LK.gui.bottom.addChild(LK.getAsset('energyBar', {
anchorX: 0.5,
anchorY: 1.0,
y: -200,
scaleX: 1.2,
scaleY: 0.8
}));
energyBarBg.tint = 0x333333;
var energyBar = LK.gui.bottom.addChild(LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 1.0,
y: -200,
x: -180,
scaleX: 1.2,
scaleY: 0.8
}));
var energyText = LK.gui.bottom.addChild(new Text2("10/10", {
size: 40,
fill: 0xFFFFFF
}));
energyText.anchor.set(0.5, 1.0);
energyText.y = -170;
// All available card types (15 total)
var allCardTypes = ['soldier', 'archer', 'tank', 'wizard', 'dragon', 'knight', 'goblin', 'giant', 'healer', 'assassin', 'bomber', 'mage', 'berserker', 'paladin', 'fireball'];
var allCardCosts = [2, 3, 4, 5, 8, 3, 1, 6, 4, 2, 4, 5, 4, 5, 3];
var playerDeck = ['soldier', 'archer', 'tank', 'wizard']; // Default deck
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 'knight':
return 600;
case 'goblin':
return 150;
case 'giant':
return 1500;
case 'healer':
return 250;
case 'assassin':
return 180;
case 'bomber':
return 220;
case 'mage':
return 280;
case 'berserker':
return 500;
case 'paladin':
return 700;
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
for (var i = 0; i < 4; i++) {
var cardType = playerDeck[i];
var cost = allCardCosts[allCardTypes.indexOf(cardType)];
var card = new Card(cardType, cost);
card.x = 300 + i * 220;
card.y = -80;
LK.gui.bottom.addChild(card);
playerCards.push(card);
}
}
// Create deck builder
var deckBuilder = new DeckBuilder(); //{deckbuilder_create1}
deckBuilder.x = 1024; //{deckbuilder_create2}
deckBuilder.y = 1366; //{deckbuilder_create3}
LK.gui.center.addChild(deckBuilder); //{deckbuilder_create4}
// Show deck builder at start
LK.setTimeout(function () {
deckBuilder.show();
}, 1000);
// Setup initial cards
setupPlayerCards();
// Simple AI for enemy
var aiTimer = 0;
var aiDeployInterval = 180; // Deploy every 3 seconds
function updateEnergy() {
energyRegenTimer++;
if (energyRegenTimer >= 60) {
// 1 second at 60 FPS
energyRegenTimer = 0;
if (currentEnergy < maxEnergy) {
currentEnergy++;
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 1.2 * energyPercent;
energyText.setText(currentEnergy + "/" + maxEnergy);
}
}
}
function updateAI() {
aiTimer++;
if (aiTimer >= aiDeployInterval) {
aiTimer = 0;
// Simple AI: deploy random unit
var unitType = allCardTypes[Math.floor(Math.random() * allCardTypes.length)];
var enemyUnit = new Unit(unitType, false);
enemyUnit.x = 800 + Math.random() * 400;
enemyUnit.y = 1000;
game.addChild(enemyUnit);
enemyUnits.push(enemyUnit);
}
}
game.down = function (x, y, obj) {
if (selectedCard && y > 1400 && y < 2200) {
// Restrict to player's area only (below river)
// Deploy zone - player's side only
if (currentEnergy >= selectedCard.cost) {
// Deploy unit
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.2 * 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);
// Add replacement card from deck
var newCardType = playerDeck[Math.floor(Math.random() * playerDeck.length)];
var newCardCost = allCardCosts[allCardTypes.indexOf(newCardType)];
var newCard = new Card(newCardType, newCardCost);
newCard.x = 300 + cardIndex * 220;
newCard.y = -80;
LK.gui.bottom.addChild(newCard);
playerCards.splice(cardIndex, 0, newCard);
}
}
// Deselect card
selectedCard = null;
} else if (selectedCard) {
// Deselect card if clicked outside valid area
selectedCard.attachAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5
}).tint = 0xFFFFFF;
selectedCard.selected = false;
selectedCard = null;
}
};
game.update = function () {
updateEnergy();
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
@@ -603,9 +603,9 @@
aiTimer++;
if (aiTimer >= aiDeployInterval) {
aiTimer = 0;
// Simple AI: deploy random unit
- var unitType = cardTypes[Math.floor(Math.random() * cardTypes.length)];
+ var unitType = allCardTypes[Math.floor(Math.random() * allCardTypes.length)];
var enemyUnit = new Unit(unitType, false);
enemyUnit.x = 800 + Math.random() * 400;
enemyUnit.y = 1000;
game.addChild(enemyUnit);
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