User prompt
Kartlar ölünce yok olsun lane de durmasın
User prompt
Darth golem ve Lucifer kartı 4 mana olsun
User prompt
Rakibin luciferida can çalma özelliği olsun
User prompt
Ama can çalma çalışmadı Lucifer rakibe hasar verince kendine 2 can gelsin
User prompt
Lucifera pasif ekle rakibe hasar verince 2 can çalar
User prompt
Her tür kartlar savaşmasın sadece iki oyuncuda türünü bitirdiğinde combat phasede savaşsınlar
User prompt
Laneler bulanık görünüyor
User prompt
Savaş alanı bulanık görünüyor
User prompt
Kartlar yine savaşmıyor kartlar her tur savaşsın durmasinlar bir turdan sonra her tur karşısındaki rakiple savaşsın
User prompt
Kartlara basılı tutunca ekrana yakınlaştır isimlerini ve pasiflerini göster ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Walter spiritin ismini Lucifer olarak değiştir
User prompt
Her katta pasif ekle ama ben söyleyecem pasifleri tamam mı
User prompt
Bir lanedeki karakter ölürse o lanedeki karakterin yerine geçmesin
User prompt
Kartların kuleye vurma, birbirleriyle savaşma, hasar alma, kulenin hasar alması gibi şeylere animasyon yap ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ama kartlar doğru şekilde savaşmıyor
User prompt
Kartların assetini oluştur her kart için farklı görsel oluşturmak istiyorum
User prompt
Rakibin manasını göster
User prompt
Oyun gecikmeli oluyor rakibin attığı kartı direktmen göster bug gibi gözüküyor ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Her tür savaşmasınlar iki tarafında sırası bitince kartlar için savaşma türü olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'x' in null' in or related to this line: 'tween(humanCard, {' Line Number: 579 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyuncular kartları savaştırmasın kartlar otomatik tür bitince savaşsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'cardData')' in or related to this line: 'aiPlayer.takeDamage(selectedCard.cardData.attack);' Line Number: 728
User prompt
Fix error
User prompt
Laneler savaş alanınının ortasına gelsin
User prompt
Ekranın ortasında demiştim
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Card = Container.expand(function (cardData) { var self = Container.call(this); // Card properties self.cardData = cardData || { name: "Basic Card", cost: 1, attack: 2, health: 2, description: "A basic creature card", passive: null // Passive ability type }; self.maxHealth = self.cardData.health; self.currentHealth = self.cardData.health; self.isPlayable = false; self.isOnBattlefield = false; self.hasAttacked = false; // Create card graphics based on card type var cardAssetName = 'cardBack'; // default var symbolAssetName = null; // Determine assets based on card name switch (self.cardData.name) { case "Fire Imp": cardAssetName = 'fireImpBg'; symbolAssetName = 'fireImpSymbol'; break; case "Water Spirit": cardAssetName = 'waterSpiritBg'; symbolAssetName = 'waterSpiritSymbol'; break; case "Earth Golem": cardAssetName = 'earthGolemBg'; symbolAssetName = 'earthGolemSymbol'; break; case "Air Wisp": cardAssetName = 'airWispBg'; symbolAssetName = 'airWispSymbol'; break; case "Lightning Bolt": cardAssetName = 'lightningBoltBg'; symbolAssetName = 'lightningBoltSymbol'; break; case "Lucifer": cardAssetName = 'walterSpiritBg'; symbolAssetName = 'walterSpiritSymbol'; break; } var cardBg = self.attachAsset(cardAssetName, { anchorX: 0.5, anchorY: 0.5 }); // Add symbol if available if (symbolAssetName) { var cardSymbol = self.attachAsset(symbolAssetName, { anchorX: 0.5, anchorY: 0.5 }); cardSymbol.x = 0; cardSymbol.y = -20; // Position symbol in upper middle area } // Card text elements var nameText = new Text2(self.cardData.name, { size: 24, fill: 0x2C3E50 }); nameText.anchor.set(0.5, 0); nameText.x = 0; nameText.y = -100; self.addChild(nameText); var costText = new Text2(self.cardData.cost.toString(), { size: 32, fill: 0x9B59B6 }); costText.anchor.set(0.5, 0.5); costText.x = -70; costText.y = -100; self.addChild(costText); var attackText = new Text2(self.cardData.attack.toString(), { size: 28, fill: 0xE74C3C }); attackText.anchor.set(0.5, 0.5); attackText.x = -50; attackText.y = 90; self.addChild(attackText); var healthText = new Text2(self.currentHealth.toString(), { size: 28, fill: 0x27AE60 }); healthText.anchor.set(0.5, 0.5); healthText.x = 50; healthText.y = 90; self.addChild(healthText); self.updateHealthDisplay = function () { healthText.setText(self.currentHealth.toString()); if (self.currentHealth <= 0) { cardBg.alpha = 0.5; } }; self.takeDamage = function (damage) { // Check for passive abilities that might reduce damage var damageReduction = self.triggerPassive("take_damage", { damage: damage }); var finalDamage = Math.max(0, damage - damageReduction); self.currentHealth -= finalDamage; if (self.currentHealth < 0) self.currentHealth = 0; self.updateHealthDisplay(); // Enhanced damage animation // Screen shake for significant damage if (damage >= 3) { LK.effects.flashScreen(0xff4444, 200); } // Damage number popup animation var damageText = new Text2("-" + damage.toString(), { size: 40, fill: 0xff0000 }); damageText.anchor.set(0.5, 0.5); damageText.x = self.x + (Math.random() - 0.5) * 60; damageText.y = self.y - 50; damageText.alpha = 1.0; game.addChild(damageText); // Animate damage number floating up and fading tween(damageText, { y: damageText.y - 80, alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(damageText); } }); // Card damage animation - recoil and flash tween(self, { x: self.x + (Math.random() - 0.5) * 30, y: self.y + (Math.random() - 0.5) * 20, scaleX: 0.9, scaleY: 0.9, tint: 0xff4444 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { x: self.x, y: self.y, scaleX: 1.0, scaleY: 1.0, tint: 0xFFFFFF }, { duration: 300, easing: tween.easeOut }); } }); // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 500); }; self.canAttack = function () { return self.isOnBattlefield && !self.hasAttacked && self.currentHealth > 0; }; self.attack = function (target) { if (self.canAttack() && target) { // Check if both cards are in the same lane if (self.laneIndex !== undefined && target.laneIndex !== undefined && self.laneIndex !== target.laneIndex) { return; // Cannot attack cards in different lanes } // Store original position var originalX = self.x; var originalY = self.y; // Calculate target position (move towards target) var targetX = target.x; var targetY = target.y; // Animate attack: move toward target, then back tween(self, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Collision animation - both cards shake and flash on impact var collisionDuration = 150; // Shake the attacking card tween(self, { x: targetX + 20 }, { duration: collisionDuration / 3, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: targetX - 20 }, { duration: collisionDuration / 3, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: targetX }, { duration: collisionDuration / 3, easing: tween.easeInOut }); } }); } }); // Shake the target card tween(target, { x: target.x - 15 }, { duration: collisionDuration / 3, easing: tween.easeInOut, onFinish: function onFinish() { tween(target, { x: target.x + 15 }, { duration: collisionDuration / 3, easing: tween.easeInOut, onFinish: function onFinish() { tween(target, { x: target.x }, { duration: collisionDuration / 3, easing: tween.easeInOut }); } }); } }); // Flash both cards white for collision effect tween(self, { tint: 0xFFFFFF }, { duration: collisionDuration, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { tint: 0xFFFFFF }, { duration: collisionDuration, easing: tween.easeInOut }); } }); tween(target, { tint: 0xFFFFFF }, { duration: collisionDuration, easing: tween.easeInOut, onFinish: function onFinish() { tween(target, { tint: 0xFFFFFF }, { duration: collisionDuration, easing: tween.easeInOut }); } }); // Check for passive damage boost var damageBoost = self.triggerPassive("attack", { attacker: self, target: target }); var totalDamage = self.cardData.attack + (damageBoost || 0); // Deal damage when collision happens target.takeDamage(totalDamage); // After collision, animate return to original position LK.setTimeout(function () { tween(self, { x: originalX, y: originalY }, { duration: 300, easing: tween.easeIn }); }, collisionDuration); } }); self.hasAttacked = true; cardBg.alpha = 0.7; LK.getSound('attack').play(); } }; self.resetForNewTurn = function () { self.hasAttacked = false; if (self.currentHealth > 0) { cardBg.alpha = 1.0; } }; // Passive ability system self.triggerPassive = function (trigger, context) { if (!self.cardData.passive || self.currentHealth <= 0) return; switch (self.cardData.passive) { case "heal_on_turn_start": if (trigger === "turn_start") { self.currentHealth = Math.min(self.maxHealth, self.currentHealth + 1); self.updateHealthDisplay(); // Heal animation tween(self, { tint: 0x00ff00 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { tint: 0xFFFFFF }, { duration: 300, easing: tween.easeIn }); } }); } break; case "damage_boost": if (trigger === "attack" && context && context.attacker === self) { return 1; // Add 1 extra damage } break; case "shield": if (trigger === "take_damage" && context) { if (self.shieldActive !== false) { self.shieldActive = false; // Shield break animation tween(self, { tint: 0x0099ff }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeIn }); } }); return 0; // Negate damage } } break; case "summon_ally": if (trigger === "death" && context && context.player) { // Summon a 1/1 creature in available lane var player = context.player; if (player.battlefield.length < 3) { var availableLanes = [0, 1, 2]; for (var i = 0; i < player.battlefield.length; i++) { var occupiedLane = player.battlefield[i].laneIndex; if (occupiedLane !== undefined) { var laneIdx = availableLanes.indexOf(occupiedLane); if (laneIdx >= 0) availableLanes.splice(laneIdx, 1); } } if (availableLanes.length > 0) { var newCard = new Card({ name: "Spirit Token", cost: 0, attack: 1, health: 1, description: "A spirit summoned from death" }); newCard.laneIndex = availableLanes[0]; newCard.isOnBattlefield = true; player.battlefield.push(newCard); game.addChild(newCard); } } } break; case "regenerate": if (trigger === "end_turn") { if (self.currentHealth < self.maxHealth && self.currentHealth > 0) { self.currentHealth = Math.min(self.maxHealth, self.currentHealth + 1); self.updateHealthDisplay(); // Regenerate animation tween(self, { tint: 0x00ff88 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { tint: 0xFFFFFF }, { duration: 400, easing: tween.easeIn }); } }); } } break; } return 0; }; self.hasPassive = function () { return self.cardData.passive !== null && self.cardData.passive !== undefined; }; return self; }); var Player = Container.expand(function (isHuman) { var self = Container.call(this); self.isHuman = isHuman || false; self.health = 30; self.maxMana = 3; self.currentMana = 3; self.hand = []; self.battlefield = []; self.deck = []; // Initialize deck with basic cards var cardTypes = [{ name: "Fire Imp", cost: 1, attack: 2, health: 1, description: "A small fire creature" }, { name: "Water Spirit", cost: 2, attack: 2, health: 3, description: "A defensive water creature" }, { name: "Earth Golem", cost: 3, attack: 4, health: 3, description: "A powerful earth creature" }, { name: "Air Wisp", cost: 1, attack: 1, health: 2, description: "A quick air creature" }, { name: "Lightning Bolt", cost: 2, attack: 3, health: 1, description: "A shocking creature" }, { name: "Lucifer", cost: 2, attack: 2, health: 4, description: "A mystical water spirit with high endurance" }]; for (var i = 0; i < 20; i++) { var randomCard = cardTypes[Math.floor(Math.random() * cardTypes.length)]; self.deck.push(new Card(randomCard)); } self.drawCard = function () { if (self.deck.length > 0 && self.hand.length < 7) { var card = self.deck.pop(); self.hand.push(card); LK.getSound('cardDraw').play(); return card; } return null; }; self.canPlayCard = function (card) { return card && card.cardData.cost <= self.currentMana; }; self.playCard = function (card) { var handIndex = self.hand.indexOf(card); if (handIndex >= 0 && self.canPlayCard(card) && self.battlefield.length < 3) { self.hand.splice(handIndex, 1); self.battlefield.push(card); self.currentMana -= card.cardData.cost; card.isOnBattlefield = true; LK.getSound('cardPlay').play(); return true; } return false; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health < 0) self.health = 0; // Tower damage animation animateTowerDamage(!self.isHuman); // Damage number popup for tower var damageText = new Text2("-" + damage.toString(), { size: 60, fill: 0xff0000 }); damageText.anchor.set(0.5, 0.5); damageText.x = 1024 + (Math.random() - 0.5) * 100; damageText.y = self.isHuman ? 1700 : 400; damageText.alpha = 1.0; game.addChild(damageText); // Animate damage number tween(damageText, { y: damageText.y - 120, alpha: 0, scaleX: 2.0, scaleY: 2.0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(damageText); } }); }; self.startTurn = function () { self.currentMana = Math.min(self.maxMana, self.currentMana + 1); if (self.maxMana < 10) self.maxMana++; // Reset battlefield cards and trigger turn start passives for (var i = 0; i < self.battlefield.length; i++) { self.battlefield[i].resetForNewTurn(); self.battlefield[i].triggerPassive("turn_start", { player: self }); } // Draw a card self.drawCard(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Game state variables // Fire Imp card assets // Water Spirit card assets // Earth Golem card assets // Air Wisp card assets // Lightning Bolt card assets // Walter Spirit card assets // Generic card back var currentPlayer = 0; // 0 = human, 1 = AI var gamePhase = "playing"; // "playing", "gameOver" var selectedCard = null; var draggedCard = null; var turnCounter = 0; // Track total turns taken var combatPhase = false; // Track if we're in combat phase // Create players var humanPlayer = new Player(true); var aiPlayer = new Player(false); var players = [humanPlayer, aiPlayer]; // Create game areas var opponentAreaBg = game.addChild(LK.getAsset('opponentArea', { anchorX: 0, anchorY: 0, x: 0, y: 200, alpha: 0.3 })); var battlefieldBg = game.addChild(LK.getAsset('battlefield', { anchorX: 0, anchorY: 0, x: 0, y: 400, alpha: 0.3 })); var playerAreaBg = game.addChild(LK.getAsset('playerArea', { anchorX: 0, anchorY: 0, x: 0, y: 1800, alpha: 0.3 })); // Create visible lane graphics var lanePositions = [600, 1024, 1448]; // Left, Center, Right lanes - centered var lanes = []; // Create lanes with borders for visual clarity for (var i = 0; i < 3; i++) { // Lane border (darker background) var laneBorder = game.addChild(LK.getAsset('laneBorder', { anchorX: 0.5, anchorY: 0.5, x: lanePositions[i], y: 985, alpha: 0.4 })); // Lane background (lighter) var lane = game.addChild(LK.getAsset('lane', { anchorX: 0.5, anchorY: 0.5, x: lanePositions[i], y: 985, alpha: 0.3 })); lanes.push({ border: laneBorder, background: lane }); // Add lane number text var laneText = new Text2("Lane " + (i + 1), { size: 24, fill: 0xECF0F1 }); laneText.anchor.set(0.5, 0.5); laneText.x = lanePositions[i]; laneText.y = 1255; laneText.alpha = 0.6; game.addChild(laneText); } // UI Elements var playerHealthText = new Text2("Health: 30", { size: 48, fill: 0xECF0F1 }); playerHealthText.anchor.set(0, 0.5); playerHealthText.x = 50; playerHealthText.y = 1950; game.addChild(playerHealthText); var opponentHealthText = new Text2("Enemy: 30", { size: 48, fill: 0xECF0F1 }); opponentHealthText.anchor.set(0, 0.5); opponentHealthText.x = 50; opponentHealthText.y = 350; game.addChild(opponentHealthText); var manaText = new Text2("Mana: 3/3", { size: 36, fill: 0x9B59B6 }); manaText.anchor.set(0, 0.5); manaText.x = 50; manaText.y = 2000; game.addChild(manaText); var aiManaText = new Text2("Enemy Mana: 3/3", { size: 36, fill: 0x9B59B6 }); aiManaText.anchor.set(0, 0.5); aiManaText.x = 50; aiManaText.y = 300; game.addChild(aiManaText); var turnText = new Text2("Your Turn", { size: 42, fill: 0xF39C12 }); turnText.anchor.set(0.5, 0.5); turnText.x = 1024; turnText.y = 100; game.addChild(turnText); // End turn button var endTurnBtn = game.addChild(LK.getAsset('endTurnButton', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 1950 })); var endTurnText = new Text2("End Turn", { size: 28, fill: 0x2C3E50 }); endTurnText.anchor.set(0.5, 0.5); endTurnText.x = 1800; endTurnText.y = 1950; game.addChild(endTurnText); // Initialize starting hands for (var i = 0; i < 4; i++) { humanPlayer.drawCard(); aiPlayer.drawCard(); } function updateUI() { playerHealthText.setText("Health: " + humanPlayer.health); opponentHealthText.setText("Enemy: " + aiPlayer.health); manaText.setText("Mana: " + humanPlayer.currentMana + "/" + humanPlayer.maxMana); aiManaText.setText("Enemy Mana: " + aiPlayer.currentMana + "/" + aiPlayer.maxMana); if (combatPhase) { turnText.setText("Combat Phase"); turnText.fill = "#e67e22"; } else if (currentPlayer === 0) { turnText.setText("Your Turn"); turnText.fill = "#f39c12"; } else { turnText.setText("Enemy Turn"); turnText.fill = "#e74c3c"; } } function arrangeHand() { var handCards = humanPlayer.hand; var startX = 1024 - handCards.length * 100; for (var i = 0; i < handCards.length; i++) { var card = handCards[i]; if (!game.children.includes(card)) { game.addChild(card); } card.x = startX + i * 200; card.y = 2300; card.isPlayable = humanPlayer.canPlayCard(card); // Visual feedback for playable cards if (card.isPlayable && currentPlayer === 0) { card.alpha = 1.0; } else { card.alpha = 0.6; } } } function arrangeBattlefield() { // Define 3 lane positions var lanePositions = [600, 1024, 1448]; // Left, Center, Right lanes - centered // Player battlefield - maintain lane assignments var playerCards = humanPlayer.battlefield; for (var i = 0; i < playerCards.length; i++) { var card = playerCards[i]; if (!game.children.includes(card)) { game.addChild(card); } // Use the card's assigned lane position instead of array index if (card.laneIndex !== undefined) { card.x = lanePositions[card.laneIndex]; card.y = 1120; } } // AI battlefield - maintain lane assignments var aiCards = aiPlayer.battlefield; for (var i = 0; i < aiCards.length; i++) { var card = aiCards[i]; if (!game.children.includes(card)) { game.addChild(card); } // Use the card's assigned lane position instead of array index if (card.laneIndex !== undefined) { card.x = lanePositions[card.laneIndex]; card.y = 850; } } } function resolveCombat() { var combatAnimations = []; var combatResults = []; var animationDelay = 0; // First pass: calculate all combat results for (var lane = 0; lane < 3; lane++) { var humanCard = null; var aiCard = null; // Find cards in this lane for (var i = 0; i < humanPlayer.battlefield.length; i++) { if (humanPlayer.battlefield[i].laneIndex === lane && humanPlayer.battlefield[i].currentHealth > 0) { humanCard = humanPlayer.battlefield[i]; break; } } for (var i = 0; i < aiPlayer.battlefield.length; i++) { if (aiPlayer.battlefield[i].laneIndex === lane && aiPlayer.battlefield[i].currentHealth > 0) { aiCard = aiPlayer.battlefield[i]; break; } } // Store combat result for this lane combatResults.push({ lane: lane, humanCard: humanCard, aiCard: aiCard, humanDamage: humanCard ? humanCard.cardData.attack : 0, aiDamage: aiCard ? aiCard.cardData.attack : 0 }); } // Second pass: animate and apply all damage for (var i = 0; i < combatResults.length; i++) { var result = combatResults[i]; if (result.humanCard && result.aiCard) { // Cards fight each other - animate card-to-card combat animateCardVsCard(result.humanCard, result.aiCard, result.humanDamage, result.aiDamage, animationDelay); animationDelay += 200; // Stagger animations } else if (result.humanCard && !result.aiCard) { // Human card attacks AI tower animateCardToTower(result.humanCard, "ai", result.humanDamage, animationDelay); animationDelay += 200; } else if (result.aiCard && !result.humanCard) { // AI card attacks human tower animateCardToTower(result.aiCard, "human", result.aiDamage, animationDelay); animationDelay += 200; } } // Remove dead cards after all animations complete LK.setTimeout(function () { for (var i = humanPlayer.battlefield.length - 1; i >= 0; i--) { if (humanPlayer.battlefield[i].currentHealth <= 0) { var deadCard = humanPlayer.battlefield[i]; // Trigger death passive before removing deadCard.triggerPassive("death", { player: humanPlayer }); // Death animation animateCardDeath(deadCard); game.removeChild(deadCard); humanPlayer.battlefield.splice(i, 1); } } for (var i = aiPlayer.battlefield.length - 1; i >= 0; i--) { if (aiPlayer.battlefield[i].currentHealth <= 0) { var deadCard = aiPlayer.battlefield[i]; // Trigger death passive before removing deadCard.triggerPassive("death", { player: aiPlayer }); // Death animation animateCardDeath(deadCard); game.removeChild(deadCard); aiPlayer.battlefield.splice(i, 1); } } arrangeBattlefield(); updateUI(); }, animationDelay + 800); } function animateCardVsCard(card1, card2, damage1, damage2, delay) { LK.setTimeout(function () { // Store original positions var originalX1 = card1.x; var originalY1 = card1.y; var originalX2 = card2.x; var originalY2 = card2.y; // Calculate midpoint for collision var midX = (card1.x + card2.x) / 2; var midY = (card1.y + card2.y) / 2; // Phase 1: Both cards move toward each other tween(card1, { x: midX, y: midY - 20, scaleX: 1.1, scaleY: 1.1 }, { duration: 300, easing: tween.easeOut }); tween(card2, { x: midX, y: midY + 20, scaleX: 1.1, scaleY: 1.1 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Phase 2: Collision effect - shake and flash LK.getSound('attack').play(); // Shake both cards tween(card1, { x: midX + 15, rotation: 0.1 }, { duration: 60, easing: tween.easeInOut, onFinish: function onFinish() { tween(card1, { x: midX - 15, rotation: -0.1 }, { duration: 60, easing: tween.easeInOut, onFinish: function onFinish() { tween(card1, { x: midX, rotation: 0 }, { duration: 60, easing: tween.easeInOut }); } }); } }); tween(card2, { x: midX - 15, rotation: -0.1 }, { duration: 60, easing: tween.easeInOut, onFinish: function onFinish() { tween(card2, { x: midX + 15, rotation: 0.1 }, { duration: 60, easing: tween.easeInOut, onFinish: function onFinish() { tween(card2, { x: midX, rotation: 0 }, { duration: 60, easing: tween.easeInOut }); } }); } }); // Flash white for collision tween(card1, { tint: 0xFFFFFF }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(card1, { tint: 0xFFFFFF }, { duration: 150, easing: tween.easeInOut }); } }); tween(card2, { tint: 0xFFFFFF }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(card2, { tint: 0xFFFFFF }, { duration: 150, easing: tween.easeInOut }); } }); // Apply damage after collision LK.setTimeout(function () { card1.takeDamage(damage2); card2.takeDamage(damage1); }, 180); // Phase 3: Return to original positions LK.setTimeout(function () { tween(card1, { x: originalX1, y: originalY1, scaleX: 1.0, scaleY: 1.0 }, { duration: 400, easing: tween.easeIn }); tween(card2, { x: originalX2, y: originalY2, scaleX: 1.0, scaleY: 1.0 }, { duration: 400, easing: tween.easeIn }); }, 300); } }); }, delay); } function animateCardToTower(card, target, damage, delay) { LK.setTimeout(function () { // Store original position var originalX = card.x; var originalY = card.y; // Determine tower position var towerX = 1024; // Center of screen var towerY = target === "ai" ? 300 : 1800; // AI or human area var targetX = towerX + (Math.random() - 0.5) * 200; // Add some randomness var targetY = towerY + (Math.random() - 0.5) * 100; // Phase 1: Card charges toward tower tween(card, { x: targetX, y: targetY, scaleX: 1.2, scaleY: 1.2, rotation: Math.PI * 0.1 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { // Phase 2: Impact effect LK.getSound('attack').play(); // Flash the tower area if (target === "ai") { LK.effects.flashObject(opponentAreaBg, 0xff0000, 400); LK.effects.flashScreen(0xff0000, 200); aiPlayer.takeDamage(damage); } else { LK.effects.flashObject(playerAreaBg, 0xff0000, 400); LK.effects.flashScreen(0xff0000, 200); humanPlayer.takeDamage(damage); } // Shake the card on impact tween(card, { x: targetX + 20, rotation: Math.PI * 0.15 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(card, { x: targetX - 20, rotation: Math.PI * 0.05 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(card, { x: targetX, rotation: Math.PI * 0.1 }, { duration: 80, easing: tween.easeInOut }); } }); } }); // Phase 3: Return to original position LK.setTimeout(function () { tween(card, { x: originalX, y: originalY, scaleX: 1.0, scaleY: 1.0, rotation: 0 }, { duration: 500, easing: tween.easeIn }); }, 300); } }); }, delay); } function animateCardDeath(card) { // Death animation - fade out while spinning and shrinking tween(card, { alpha: 0, scaleX: 0.2, scaleY: 0.2, rotation: Math.PI * 2, y: card.y - 100 }, { duration: 600, easing: tween.easeIn }); } function animateTowerDamage(isAI) { // Tower damage animation - screen shake and flash var targetArea = isAI ? opponentAreaBg : playerAreaBg; var healthText = isAI ? opponentHealthText : playerHealthText; // Flash the area red LK.effects.flashObject(targetArea, 0xff0000, 500); // Screen shake effect LK.effects.flashScreen(0xff0000, 300); // Animate health text tween(healthText, { scaleX: 1.3, scaleY: 1.3, tint: 0xff0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(healthText, { scaleX: 1.0, scaleY: 1.0, tint: 0xFFFFFF }, { duration: 300, easing: tween.easeIn }); } }); } function checkGameOver() { if (humanPlayer.health <= 0) { gamePhase = "gameOver"; LK.showGameOver(); return true; } else if (aiPlayer.health <= 0) { gamePhase = "gameOver"; LK.showYouWin(); return true; } return false; } function endTurn() { // Trigger end turn passives for current player var currentPlayerObj = players[currentPlayer]; for (var i = 0; i < currentPlayerObj.battlefield.length; i++) { currentPlayerObj.battlefield[i].triggerPassive("end_turn", { player: currentPlayerObj }); } turnCounter++; currentPlayer = 1 - currentPlayer; players[currentPlayer].startTurn(); // Check if both players have taken their turns (every 2 turns) if (turnCounter % 2 === 0) { // Both players have played, trigger combat phase combatPhase = true; turnText.setText("Combat Phase"); turnText.fill = "#e67e22"; // Resolve combat after both players have played LK.setTimeout(function () { resolveCombat(); combatPhase = false; if (!checkGameOver()) { updateUI(); arrangeHand(); arrangeBattlefield(); } }, 1000); } else { // Only one player has played, continue to next player if (currentPlayer === 1) { // AI turn LK.setTimeout(function () { performAITurn(); }, 1000); } updateUI(); arrangeHand(); arrangeBattlefield(); } } function performAITurn() { // Simple AI: play random playable card if battlefield has space var playableCards = aiPlayer.hand.filter(function (card) { return aiPlayer.canPlayCard(card); }); if (playableCards.length > 0 && aiPlayer.battlefield.length < 3) { var randomCard = playableCards[Math.floor(Math.random() * playableCards.length)]; // Find available lane for AI var availableLanes = [0, 1, 2]; for (var i = 0; i < aiPlayer.battlefield.length; i++) { var occupiedLane = aiPlayer.battlefield[i].laneIndex; if (occupiedLane !== undefined) { var laneIdx = availableLanes.indexOf(occupiedLane); if (laneIdx >= 0) availableLanes.splice(laneIdx, 1); } } if (availableLanes.length > 0 && aiPlayer.playCard(randomCard)) { var selectedLane = availableLanes[Math.floor(Math.random() * availableLanes.length)]; randomCard.laneIndex = selectedLane; randomCard.targetLane = selectedLane; // Immediately update display after AI plays card updateUI(); arrangeHand(); arrangeBattlefield(); } } // Combat is now handled automatically at end of turn // AI just plays cards, combat resolution happens automatically // End AI turn LK.setTimeout(function () { if (!checkGameOver()) { endTurn(); } }, 1500); } // Card zoom preview variables var zoomPreviewCard = null; var zoomPreviewBg = null; var zoomPreviewTimeout = null; var isShowingZoom = false; function createZoomPreview(card) { if (isShowingZoom) return; // Create dark background overlay zoomPreviewBg = game.addChild(LK.getAsset('battlefield', { anchorX: 0, anchorY: 0, x: 0, y: 0, alpha: 0.8, tint: 0x000000 })); zoomPreviewBg.width = 2048; zoomPreviewBg.height = 2732; // Create zoomed card preview zoomPreviewCard = new Card(card.cardData); zoomPreviewCard.x = 1024; zoomPreviewCard.y = 1000; zoomPreviewCard.scaleX = 2.5; zoomPreviewCard.scaleY = 2.5; zoomPreviewCard.alpha = 0; game.addChild(zoomPreviewCard); // Add card name text var nameText = new Text2(card.cardData.name, { size: 60, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = 1024; nameText.y = 700; nameText.alpha = 0; game.addChild(nameText); zoomPreviewCard.nameDisplay = nameText; // Add passive description if card has passive if (card.hasPassive()) { var passiveText = new Text2("Passive: " + getPassiveDescription(card.cardData.passive), { size: 36, fill: 0xF39C12 }); passiveText.anchor.set(0.5, 0.5); passiveText.x = 1024; passiveText.y = 1400; passiveText.alpha = 0; game.addChild(passiveText); zoomPreviewCard.passiveDisplay = passiveText; } // Add description text var descText = new Text2(card.cardData.description, { size: 32, fill: 0xECF0F1 }); descText.anchor.set(0.5, 0.5); descText.x = 1024; descText.y = card.hasPassive() ? 1500 : 1400; descText.alpha = 0; game.addChild(descText); zoomPreviewCard.descDisplay = descText; // Animate zoom in tween(zoomPreviewBg, { alpha: 0.8 }, { duration: 300, easing: tween.easeOut }); tween(zoomPreviewCard, { alpha: 1.0, scaleX: 2.5, scaleY: 2.5 }, { duration: 400, easing: tween.easeOut }); tween(nameText, { alpha: 1.0 }, { duration: 400, easing: tween.easeOut }); tween(descText, { alpha: 1.0 }, { duration: 400, easing: tween.easeOut }); if (zoomPreviewCard.passiveDisplay) { tween(zoomPreviewCard.passiveDisplay, { alpha: 1.0 }, { duration: 400, easing: tween.easeOut }); } isShowingZoom = true; } function destroyZoomPreview() { if (!isShowingZoom) return; if (zoomPreviewCard) { if (zoomPreviewCard.nameDisplay) { game.removeChild(zoomPreviewCard.nameDisplay); } if (zoomPreviewCard.passiveDisplay) { game.removeChild(zoomPreviewCard.passiveDisplay); } if (zoomPreviewCard.descDisplay) { game.removeChild(zoomPreviewCard.descDisplay); } game.removeChild(zoomPreviewCard); zoomPreviewCard = null; } if (zoomPreviewBg) { game.removeChild(zoomPreviewBg); zoomPreviewBg = null; } isShowingZoom = false; } function getPassiveDescription(passiveType) { switch (passiveType) { case "heal_on_turn_start": return "Heals 1 HP at turn start"; case "damage_boost": return "Deals +1 damage when attacking"; case "shield": return "Blocks first damage taken"; case "summon_ally": return "Summons 1/1 Spirit Token on death"; case "regenerate": return "Heals 1 HP at turn end"; default: return "No passive ability"; } } // Event handlers game.down = function (x, y, obj) { if (gamePhase !== "playing" || currentPlayer !== 0 || combatPhase) return; // Close zoom preview if showing if (isShowingZoom) { destroyZoomPreview(); return; } // Check if end turn button was clicked if (x >= 1700 && x <= 1900 && y >= 1910 && y <= 1990) { endTurn(); return; } // Check if a hand card was clicked for (var i = 0; i < humanPlayer.hand.length; i++) { var card = humanPlayer.hand[i]; var cardBounds = { left: card.x - 90, right: card.x + 90, top: card.y - 125, bottom: card.y + 125 }; if (x >= cardBounds.left && x <= cardBounds.right && y >= cardBounds.top && y <= cardBounds.bottom) { if (card.isPlayable) { selectedCard = card; draggedCard = card; // Start long press timer for zoom preview if (zoomPreviewTimeout) { LK.clearTimeout(zoomPreviewTimeout); } zoomPreviewTimeout = LK.setTimeout(function () { if (selectedCard === card) { createZoomPreview(card); draggedCard = null; // Cancel drag when showing zoom } }, 800); // 800ms long press } return; } } // Check battlefield cards for zoom preview var allBattlefieldCards = humanPlayer.battlefield.concat(aiPlayer.battlefield); for (var i = 0; i < allBattlefieldCards.length; i++) { var card = allBattlefieldCards[i]; var cardBounds = { left: card.x - 90, right: card.x + 90, top: card.y - 125, bottom: card.y + 125 }; if (x >= cardBounds.left && x <= cardBounds.right && y >= cardBounds.top && y <= cardBounds.bottom) { // Start long press timer for battlefield card zoom if (zoomPreviewTimeout) { LK.clearTimeout(zoomPreviewTimeout); } zoomPreviewTimeout = LK.setTimeout(function () { createZoomPreview(card); }, 800); return; } } // Battlefield cards can no longer be manually selected for attacking // Combat is now automatic at end of turn }; game.move = function (x, y, obj) { // Cancel zoom preview if user starts moving if (zoomPreviewTimeout) { LK.clearTimeout(zoomPreviewTimeout); zoomPreviewTimeout = null; } if (draggedCard) { draggedCard.x = x; draggedCard.y = y; } }; game.up = function (x, y, obj) { // Clear zoom preview timeout if (zoomPreviewTimeout) { LK.clearTimeout(zoomPreviewTimeout); zoomPreviewTimeout = null; } if (draggedCard && y < 1350 && y > 700) { // Determine which lane the card was dropped in var targetLane = -1; if (x >= 380 && x < 812) targetLane = 0; // Left lane else if (x >= 812 && x < 1236) targetLane = 1; // Center lane else if (x >= 1236 && x < 1668) targetLane = 2; // Right lane // Check if lane is available and card can be played if (targetLane >= 0 && humanPlayer.battlefield.length < 3) { // Check if target lane is already occupied var laneOccupied = false; for (var i = 0; i < humanPlayer.battlefield.length; i++) { if (humanPlayer.battlefield[i].laneIndex === targetLane) { laneOccupied = true; break; } } if (!laneOccupied && humanPlayer.playCard(draggedCard)) { draggedCard.laneIndex = targetLane; draggedCard.targetLane = targetLane; draggedCard = null; selectedCard = null; updateUI(); arrangeHand(); arrangeBattlefield(); } } } selectedCard = null; if (draggedCard) { arrangeHand(); draggedCard = null; } // Remove dead cards for (var i = aiPlayer.battlefield.length - 1; i >= 0; i--) { if (aiPlayer.battlefield[i].currentHealth <= 0) { var deadCard = aiPlayer.battlefield[i]; game.removeChild(deadCard); aiPlayer.battlefield.splice(i, 1); } } updateUI(); arrangeBattlefield(); checkGameOver(); }; game.update = function () { if (gamePhase === "playing") { updateUI(); } }; // Initial setup updateUI(); arrangeHand(); arrangeBattlefield();
===================================================================
--- original.js
+++ change.js
@@ -1166,11 +1166,151 @@
endTurn();
}
}, 1500);
}
+// Card zoom preview variables
+var zoomPreviewCard = null;
+var zoomPreviewBg = null;
+var zoomPreviewTimeout = null;
+var isShowingZoom = false;
+function createZoomPreview(card) {
+ if (isShowingZoom) return;
+ // Create dark background overlay
+ zoomPreviewBg = game.addChild(LK.getAsset('battlefield', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0,
+ alpha: 0.8,
+ tint: 0x000000
+ }));
+ zoomPreviewBg.width = 2048;
+ zoomPreviewBg.height = 2732;
+ // Create zoomed card preview
+ zoomPreviewCard = new Card(card.cardData);
+ zoomPreviewCard.x = 1024;
+ zoomPreviewCard.y = 1000;
+ zoomPreviewCard.scaleX = 2.5;
+ zoomPreviewCard.scaleY = 2.5;
+ zoomPreviewCard.alpha = 0;
+ game.addChild(zoomPreviewCard);
+ // Add card name text
+ var nameText = new Text2(card.cardData.name, {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ nameText.anchor.set(0.5, 0.5);
+ nameText.x = 1024;
+ nameText.y = 700;
+ nameText.alpha = 0;
+ game.addChild(nameText);
+ zoomPreviewCard.nameDisplay = nameText;
+ // Add passive description if card has passive
+ if (card.hasPassive()) {
+ var passiveText = new Text2("Passive: " + getPassiveDescription(card.cardData.passive), {
+ size: 36,
+ fill: 0xF39C12
+ });
+ passiveText.anchor.set(0.5, 0.5);
+ passiveText.x = 1024;
+ passiveText.y = 1400;
+ passiveText.alpha = 0;
+ game.addChild(passiveText);
+ zoomPreviewCard.passiveDisplay = passiveText;
+ }
+ // Add description text
+ var descText = new Text2(card.cardData.description, {
+ size: 32,
+ fill: 0xECF0F1
+ });
+ descText.anchor.set(0.5, 0.5);
+ descText.x = 1024;
+ descText.y = card.hasPassive() ? 1500 : 1400;
+ descText.alpha = 0;
+ game.addChild(descText);
+ zoomPreviewCard.descDisplay = descText;
+ // Animate zoom in
+ tween(zoomPreviewBg, {
+ alpha: 0.8
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ tween(zoomPreviewCard, {
+ alpha: 1.0,
+ scaleX: 2.5,
+ scaleY: 2.5
+ }, {
+ duration: 400,
+ easing: tween.easeOut
+ });
+ tween(nameText, {
+ alpha: 1.0
+ }, {
+ duration: 400,
+ easing: tween.easeOut
+ });
+ tween(descText, {
+ alpha: 1.0
+ }, {
+ duration: 400,
+ easing: tween.easeOut
+ });
+ if (zoomPreviewCard.passiveDisplay) {
+ tween(zoomPreviewCard.passiveDisplay, {
+ alpha: 1.0
+ }, {
+ duration: 400,
+ easing: tween.easeOut
+ });
+ }
+ isShowingZoom = true;
+}
+function destroyZoomPreview() {
+ if (!isShowingZoom) return;
+ if (zoomPreviewCard) {
+ if (zoomPreviewCard.nameDisplay) {
+ game.removeChild(zoomPreviewCard.nameDisplay);
+ }
+ if (zoomPreviewCard.passiveDisplay) {
+ game.removeChild(zoomPreviewCard.passiveDisplay);
+ }
+ if (zoomPreviewCard.descDisplay) {
+ game.removeChild(zoomPreviewCard.descDisplay);
+ }
+ game.removeChild(zoomPreviewCard);
+ zoomPreviewCard = null;
+ }
+ if (zoomPreviewBg) {
+ game.removeChild(zoomPreviewBg);
+ zoomPreviewBg = null;
+ }
+ isShowingZoom = false;
+}
+function getPassiveDescription(passiveType) {
+ switch (passiveType) {
+ case "heal_on_turn_start":
+ return "Heals 1 HP at turn start";
+ case "damage_boost":
+ return "Deals +1 damage when attacking";
+ case "shield":
+ return "Blocks first damage taken";
+ case "summon_ally":
+ return "Summons 1/1 Spirit Token on death";
+ case "regenerate":
+ return "Heals 1 HP at turn end";
+ default:
+ return "No passive ability";
+ }
+}
// Event handlers
game.down = function (x, y, obj) {
if (gamePhase !== "playing" || currentPlayer !== 0 || combatPhase) return;
+ // Close zoom preview if showing
+ if (isShowingZoom) {
+ destroyZoomPreview();
+ return;
+ }
// Check if end turn button was clicked
if (x >= 1700 && x <= 1900 && y >= 1910 && y <= 1990) {
endTurn();
return;
@@ -1187,22 +1327,63 @@
if (x >= cardBounds.left && x <= cardBounds.right && y >= cardBounds.top && y <= cardBounds.bottom) {
if (card.isPlayable) {
selectedCard = card;
draggedCard = card;
+ // Start long press timer for zoom preview
+ if (zoomPreviewTimeout) {
+ LK.clearTimeout(zoomPreviewTimeout);
+ }
+ zoomPreviewTimeout = LK.setTimeout(function () {
+ if (selectedCard === card) {
+ createZoomPreview(card);
+ draggedCard = null; // Cancel drag when showing zoom
+ }
+ }, 800); // 800ms long press
}
return;
}
}
+ // Check battlefield cards for zoom preview
+ var allBattlefieldCards = humanPlayer.battlefield.concat(aiPlayer.battlefield);
+ for (var i = 0; i < allBattlefieldCards.length; i++) {
+ var card = allBattlefieldCards[i];
+ var cardBounds = {
+ left: card.x - 90,
+ right: card.x + 90,
+ top: card.y - 125,
+ bottom: card.y + 125
+ };
+ if (x >= cardBounds.left && x <= cardBounds.right && y >= cardBounds.top && y <= cardBounds.bottom) {
+ // Start long press timer for battlefield card zoom
+ if (zoomPreviewTimeout) {
+ LK.clearTimeout(zoomPreviewTimeout);
+ }
+ zoomPreviewTimeout = LK.setTimeout(function () {
+ createZoomPreview(card);
+ }, 800);
+ return;
+ }
+ }
// Battlefield cards can no longer be manually selected for attacking
// Combat is now automatic at end of turn
};
game.move = function (x, y, obj) {
+ // Cancel zoom preview if user starts moving
+ if (zoomPreviewTimeout) {
+ LK.clearTimeout(zoomPreviewTimeout);
+ zoomPreviewTimeout = null;
+ }
if (draggedCard) {
draggedCard.x = x;
draggedCard.y = y;
}
};
game.up = function (x, y, obj) {
+ // Clear zoom preview timeout
+ if (zoomPreviewTimeout) {
+ LK.clearTimeout(zoomPreviewTimeout);
+ zoomPreviewTimeout = null;
+ }
if (draggedCard && y < 1350 && y > 700) {
// Determine which lane the card was dropped in
var targetLane = -1;
if (x >= 380 && x < 812) targetLane = 0; // Left lane
End turn button fark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Kart alanı dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Ateş ruhu karakteri dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Lightning spirit character Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Kocaman kayadan oluşan golem kırmızı parıldayan gözlere sahip dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Air wisp character dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Arka planı doldur sadece aynısını yap
Koridor yukarıdan bakış dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Ateş 🔥 dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Ulan yatay tarsfa doğru geniş yap yüksekliğe doğru küçük yap
Shadow drake dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Michael demiurgos dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
İnfinity Minion character dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Fireball dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Magic stand dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Play button Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Deck yaz ama düzgün bir arka planla
Büyü asası logosu Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Suikastçı bıçağı logosu Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Kalkan logosu Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Warrior logo Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Sadece freeze büyüsü yap insan olmasın Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Sadece play yerine Wiki yaz
Spell icon Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
İpuçları icon Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Synergy icon Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Game Rules dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Frost Wolf Man Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Water spirit dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Phoenix woman Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Void Stalker Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows
Crystal guardian Dark souls style 2d pixel art. In-Game asset. 2d. High contrast. No shadows