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;
// Bridge coordinates
var bridge1X = 700;
var bridge1Y = 1366;
var bridge2X = 1348;
var bridge2Y = 1366;
var riverTop = 1326;
var riverBottom = 1406;
// Check if unit needs to cross river
var needsCrossing = self.isPlayer && self.y > riverBottom && self.target.y < riverTop || !self.isPlayer && self.y < riverTop && self.target.y > riverBottom;
if (needsCrossing) {
// Choose closest bridge
var dist1 = Math.sqrt((bridge1X - self.x) * (bridge1X - self.x) + (bridge1Y - self.y) * (bridge1Y - self.y));
var dist2 = Math.sqrt((bridge2X - self.x) * (bridge2X - self.x) + (bridge2Y - self.y) * (bridge2Y - self.y));
var targetBridgeX = dist1 < dist2 ? bridge1X : bridge2X;
var targetBridgeY = dist1 < dist2 ? bridge1Y : bridge2Y;
// If not at bridge yet, move to bridge first
var bridgeDx = targetBridgeX - self.x;
var bridgeDy = targetBridgeY - self.y;
var bridgeDistance = Math.sqrt(bridgeDx * bridgeDx + bridgeDy * bridgeDy);
if (bridgeDistance > 30) {
// Move toward bridge
moveX = bridgeDx / bridgeDistance * self.moveSpeed;
moveY = bridgeDy / bridgeDistance * self.moveSpeed;
}
}
// Prevent units from entering river area directly
var newX = self.x + moveX;
var newY = self.y + moveY;
// Check if new position would be in river without being on bridge
var inRiver = newY > riverTop && newY < riverBottom;
var onBridge = Math.abs(newX - bridge1X) < 100 && Math.abs(newY - bridge1Y) < 40 || Math.abs(newX - bridge2X) < 100 && Math.abs(newY - bridge2Y) < 40;
if (inRiver && !onBridge) {
// Don't move into river
moveX = 0;
moveY = 0;
}
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 - centered on screen
var cardWidth = 220;
var totalWidth = 4 * cardWidth;
var startX = -(totalWidth / 2) + cardWidth / 2;
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 = 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 = -400;
var myCardsBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: -100,
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 = -200;
myCardsText.y = -100;
var vsBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -100,
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 = 0;
vsText.y = -100;
var shopBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: -100,
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 = 200;
shopText.y = -100;
var cupBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 100,
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 = 0;
cupText.y = 100;
// Button interactions
myCardsBtn.interactive = true;
myCardsBtn.on('pointerdown', function () {
deckBuilder.show();
});
vsBtn.interactive = true;
vsBtn.on('pointerdown', function () {
mainMenu.visible = false;
});
shopBtn.interactive = true;
shopBtn.on('pointerdown', function () {
// Shop functionality to be added
});
cupBtn.interactive = true;
cupBtn.on('pointerdown', function () {
// Cup/Trophy functionality to be added
});
// Create deck builder
var deckBuilder = new DeckBuilder(); //{deckbuilder_create1}
deckBuilder.x = 0; //{deckbuilder_create2}
deckBuilder.y = 0; //{deckbuilder_create3}
LK.gui.center.addChild(deckBuilder); //{deckbuilder_create4}
// Show main menu at start
mainMenu.visible = true;
// 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 with centered positioning
var 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;
} 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
@@ -383,25 +383,44 @@
} 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;
+ // Bridge coordinates
+ var bridge1X = 700;
+ var bridge1Y = 1366;
+ var bridge2X = 1348;
+ var bridge2Y = 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;
+ // Check if unit needs to cross river
+ var needsCrossing = self.isPlayer && self.y > riverBottom && self.target.y < riverTop || !self.isPlayer && self.y < riverTop && self.target.y > riverBottom;
+ if (needsCrossing) {
+ // Choose closest bridge
+ var dist1 = Math.sqrt((bridge1X - self.x) * (bridge1X - self.x) + (bridge1Y - self.y) * (bridge1Y - self.y));
+ var dist2 = Math.sqrt((bridge2X - self.x) * (bridge2X - self.x) + (bridge2Y - self.y) * (bridge2Y - self.y));
+ var targetBridgeX = dist1 < dist2 ? bridge1X : bridge2X;
+ var targetBridgeY = dist1 < dist2 ? bridge1Y : bridge2Y;
+ // If not at bridge yet, move to bridge first
+ var bridgeDx = targetBridgeX - self.x;
+ var bridgeDy = targetBridgeY - self.y;
var bridgeDistance = Math.sqrt(bridgeDx * bridgeDx + bridgeDy * bridgeDy);
- if (bridgeDistance > 50) {
+ if (bridgeDistance > 30) {
// Move toward bridge
moveX = bridgeDx / bridgeDistance * self.moveSpeed;
moveY = bridgeDy / bridgeDistance * self.moveSpeed;
}
}
+ // Prevent units from entering river area directly
+ var newX = self.x + moveX;
+ var newY = self.y + moveY;
+ // Check if new position would be in river without being on bridge
+ var inRiver = newY > riverTop && newY < riverBottom;
+ var onBridge = Math.abs(newX - bridge1X) < 100 && Math.abs(newY - bridge1Y) < 40 || Math.abs(newX - bridge2X) < 100 && Math.abs(newY - bridge2Y) < 40;
+ if (inRiver && !onBridge) {
+ // Don't move into river
+ moveX = 0;
+ moveY = 0;
+ }
self.x += moveX;
self.y += moveY;
}
if (self.attackCooldown > 0) {
@@ -560,28 +579,124 @@
for (var i = 0; i < playerCards.length; i++) {
playerCards[i].destroy();
}
playerCards = [];
- // Create cards from player deck
+ // Create cards from player deck - centered on screen
+ var cardWidth = 220;
+ var totalWidth = 4 * cardWidth;
+ var startX = -(totalWidth / 2) + cardWidth / 2;
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.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 = -400;
+var myCardsBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -200,
+ y: -100,
+ 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 = -200;
+myCardsText.y = -100;
+var vsBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: -100,
+ 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 = 0;
+vsText.y = -100;
+var shopBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 200,
+ y: -100,
+ 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 = 200;
+shopText.y = -100;
+var cupBtn = mainMenu.addChild(LK.getAsset('cardSlot', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: 100,
+ 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 = 0;
+cupText.y = 100;
+// Button interactions
+myCardsBtn.interactive = true;
+myCardsBtn.on('pointerdown', function () {
+ deckBuilder.show();
+});
+vsBtn.interactive = true;
+vsBtn.on('pointerdown', function () {
+ mainMenu.visible = false;
+});
+shopBtn.interactive = true;
+shopBtn.on('pointerdown', function () {
+ // Shop functionality to be added
+});
+cupBtn.interactive = true;
+cupBtn.on('pointerdown', function () {
+ // Cup/Trophy functionality to be added
+});
// Create deck builder
var deckBuilder = new DeckBuilder(); //{deckbuilder_create1}
-deckBuilder.x = 1024; //{deckbuilder_create2}
-deckBuilder.y = 1366; //{deckbuilder_create3}
+deckBuilder.x = 0; //{deckbuilder_create2}
+deckBuilder.y = 0; //{deckbuilder_create3}
LK.gui.center.addChild(deckBuilder); //{deckbuilder_create4}
-// Show deck builder at start
-LK.setTimeout(function () {
- deckBuilder.show();
-}, 1000);
+// Show main menu at start
+mainMenu.visible = true;
// Setup initial cards
setupPlayerCards();
// Simple AI for enemy
var aiTimer = 0;
@@ -632,13 +747,16 @@
var cardIndex = playerCards.indexOf(selectedCard);
if (cardIndex !== -1) {
selectedCard.destroy();
playerCards.splice(cardIndex, 1);
- // Add replacement card from deck
+ // Add replacement card from deck with centered positioning
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;
+ 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);
}
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