User prompt
the damage animations must be bigger and slower āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the enemy always block two damage
User prompt
more
User prompt
Health and Resource Bars**: Make these more thematic, possibly with a design that reflects the game's fantasy elements. Ensure they are large enough to be easily visible and positioned intuitively
User prompt
Move it a little up
User prompt
Make it bigger
User prompt
Now I cant see my own health bar. Move it to the buttom
User prompt
I need the cards to have a "image area" which takes up most of the top part of the card. The buttom part should be white and reserved for text, making it easier to read. MTG or Flesh and blood
User prompt
i need to be able to add individual images for earch card front. Divide all different cards into unique assets
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'resources')' in or related to this line: 'resourceIndicator = new Text2("Resources: " + playerHero.resources, {' Line Number: 338
User prompt
make a "resource indicator" on the right side that show the available resources after a player pitch
User prompt
Change the word discard to pitch
User prompt
Make it so that once a player has comited cards to an attack, the opponent can choose to block with their cards
User prompt
make the hand size 4 cards only when starting a game
User prompt
at the start of a turn, a player should draw to have minimum and maximum 4 cards
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'effectMsg.style.fill = "#ff3333";' Line Number: 972
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'effectMsg.style.fill = "#ff3333";' Line Number: 969
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'effectMsg.style.fill = "#ff3333";' Line Number: 971
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'effectMsg.style.fill = "#ff3333";' Line Number: 969
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'effectMsg.style.fill = "#ff3333";' Line Number: 971
Initial prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'effectMsg.style.fill = "#ff3333";' Line Number: 965
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, gamesPlayed: 0 }); /**** * Classes ****/ // Button class for game controls var Button = Container.expand(function (text, width, height) { var self = Container.call(this); self.isEnabled = true; // Button background self.background = self.attachAsset('buttonBg', { anchorX: 0.5, anchorY: 0.5, width: width || 200, height: height || 80 }); // Button text self.text = new Text2(text || "Button", { size: 28, fill: 0xFFFFFF }); self.text.anchor.set(0.5, 0.5); self.addChild(self.text); // Interaction handlers self.down = function (x, y, obj) { if (self.isEnabled) { self.background.alpha = 0.7; } }; self.up = function (x, y, obj) { if (self.isEnabled) { self.background.alpha = 1; if (typeof self.onClick === 'function') { self.onClick(); } } }; // Enable/disable the button self.setEnabled = function (enabled) { self.isEnabled = enabled; self.alpha = enabled ? 1 : 0.5; }; return self; }); // Card class to represent game cards var Card = Container.expand(function (type, value, name, description) { var self = Container.call(this); // Card properties self.type = type || 'attack'; // attack, defense, utility self.value = value || 1; // primary value (attack/defense/resource) self.name = name || 'Basic Card'; self.description = description || 'A basic card'; self.isPlayable = true; self.isSelected = false; // Visual elements var cardFrontId = ''; switch (self.name) { case 'Fierce Strike': cardFrontId = 'fierceStrikeFront'; break; case 'Quick Slash': cardFrontId = 'quickSlashFront'; break; case 'Heavy Blow': cardFrontId = 'heavyBlowFront'; break; case 'Crushing Attack': cardFrontId = 'crushingAttackFront'; break; case 'Jab': cardFrontId = 'jabFront'; break; case 'Block': cardFrontId = 'blockFront'; break; case 'Shield Up': cardFrontId = 'shieldUpFront'; break; case 'Deflect': cardFrontId = 'deflectFront'; break; case 'Parry': cardFrontId = 'parryFront'; break; case 'Focus': cardFrontId = 'focusFront'; break; case 'Strategize': cardFrontId = 'strategizeFront'; break; case 'Second Wind': cardFrontId = 'secondWindFront'; break; default: cardFrontId = 'cardFront'; } self.background = self.attachAsset(cardFrontId, { anchorX: 0.5, anchorY: 0.5 }); // Image area self.imageArea = new Container(); self.imageArea.width = 250; self.imageArea.height = 200; self.imageArea.y = -75; self.addChild(self.imageArea); // Text area self.textArea = new Container(); self.textArea.width = 250; self.textArea.height = 150; self.textArea.y = 75; self.textArea.tint = 0xFFFFFF; // White background for text area self.addChild(self.textArea); // Card title self.titleText = new Text2(self.name, { size: 24, fill: 0x000000 }); self.titleText.anchor.set(0.5, 0); self.titleText.y = -150; self.textArea.addChild(self.titleText); // Card value and type var typeColors = { attack: '#ff3333', defense: '#3399ff', utility: '#33cc33' }; self.valueText = new Text2(self.value.toString(), { size: 40, fill: typeColors[self.type] || "#000000" }); self.valueText.anchor.set(0.5, 0.5); self.valueText.y = -70; self.addChild(self.valueText); // Card type icon var iconType = self.type === 'attack' ? 'attackIcon' : self.type === 'defense' ? 'defenseIcon' : 'resourceIcon'; self.typeIcon = self.attachAsset(iconType, { anchorX: 0.5, anchorY: 0.5, x: 0, y: -20 }); // Description text self.descText = new Text2(self.description, { size: 18, fill: 0x333333 }); self.descText.anchor.set(0.5, 0); self.descText.y = 20; self.descText.x = 0; // Limit text width if (self.descText.width > 230) { self.descText.scale.set(230 / self.descText.width); } self.addChild(self.descText); // Resource value (all cards can be discarded for resources) self.resourceValue = Math.max(1, Math.floor(self.value / 2)); self.resourceText = new Text2("R: " + self.resourceValue, { size: 24, fill: 0xFFCC00 }); self.resourceText.anchor.set(0.5, 1); self.resourceText.y = 140; self.addChild(self.resourceText); // Highlight for selection self.highlight = self.attachAsset('cardHighlight', { anchorX: 0.5, anchorY: 0.5 }); self.highlight.alpha = 0; // Card interaction events self.down = function (x, y, obj) { if (self.isPlayable) { self.isSelected = true; self.highlight.alpha = 0.5; } }; self.up = function (x, y, obj) { if (!self.isPlayable) { return; } // Call the game's card played handler - implemented in game.cardPlayed var gameCoords = game.toLocal(self.parent.toGlobal(self.position)); game.cardSelected(self, gameCoords.x, gameCoords.y); }; // Toggle selection state self.setSelected = function (selected) { self.isSelected = selected; self.highlight.alpha = selected ? 0.5 : 0; }; // Set card playability self.setPlayable = function (playable) { self.isPlayable = playable; self.alpha = playable ? 1 : 0.6; }; return self; }); // Hero class representing player or enemy champion var Hero = Container.expand(function (isPlayer) { var self = Container.call(this); // Hero properties self.isPlayer = isPlayer; self.health = 20; self.maxHealth = 20; self.resources = 0; self.maxResources = 10; self.attack = 0; self.defense = 0; self.name = isPlayer ? "Player Hero" : "Enemy Hero"; // Visual representation self.avatar = self.attachAsset(isPlayer ? 'heroAvatar' : 'enemyAvatar', { anchorX: 0.5, anchorY: 0.5 }); // Name display self.nameText = new Text2(self.name, { size: 28, fill: 0xFFFFFF }); self.nameText.anchor.set(0.5, 0); self.nameText.y = -130; self.addChild(self.nameText); // Health bar self.healthBarBg = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, y: 180, tint: 0x666666 }); self.healthBar = self.attachAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: -150, y: 200, scaleX: 2, // Further increase the width of the health bar tint: 0x00ff00 // Apply a fantasy-themed green tint }); self.healthText = new Text2(self.health + "/" + self.maxHealth, { size: 22, fill: 0xFFFFFF }); self.healthText.anchor.set(0.5, 0.5); self.healthText.y = 200; self.addChild(self.healthText); // Resource bar (only for player) if (isPlayer) { self.resourceBarBg = self.attachAsset('resourceBar', { anchorX: 0.5, anchorY: 0.5, y: 150, tint: 0x666666 }); self.resourceBar = self.attachAsset('resourceBar', { anchorX: 0, anchorY: 0.5, x: -150, y: 150, scaleX: 2, // Further increase the width of the resource bar tint: 0xFFD700 // Apply a fantasy-themed gold tint }); // Resource text self.resourceText = new Text2(self.resources + "/" + self.maxResources, { size: 22, fill: 0xFFFFFF }); self.resourceText.anchor.set(0.5, 0.5); self.resourceText.y = 150; self.addChild(self.resourceText); } // Update health display self.updateHealth = function (newHealth) { self.health = Math.max(0, Math.min(self.maxHealth, newHealth)); self.healthText.setText(self.health + "/" + self.maxHealth); // Update health bar var healthRatio = self.health / self.maxHealth; self.healthBar.width = 200 * healthRatio; self.healthBar.x = -100; // Flash red if damage taken if (newHealth < self.health) { LK.effects.flashObject(self.avatar, 0xff0000, 500); } return self.health; }; // Update resource display (player only) self.updateResources = function (newResources) { if (!self.isPlayer) { return; } self.resources = Math.max(0, Math.min(self.maxResources, newResources)); self.resourceText.setText(self.resources + "/" + self.maxResources); // Update resource bar var resourceRatio = self.resources / self.maxResources; self.resourceBar.width = 200 * resourceRatio; }; // Take damage accounting for defense self.takeDamage = function (amount) { var actualDamage = Math.max(0, amount - (self.defense + 2)); // Always block two damage self.defense = Math.max(0, self.defense - amount); if (actualDamage > 0) { self.updateHealth(self.health - actualDamage); LK.getSound('damage').play(); // Flash effect for damage LK.effects.flashObject(self, 0xff0000, 300); } return actualDamage; }; // Add attack power self.addAttack = function (amount) { self.attack += amount; return self.attack; }; // Add defense self.addDefense = function (amount) { self.defense += amount; return self.defense; }; // Reset turn stats self.resetTurnStats = function () { self.attack = 0; self.defense = 0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game state var playerHand = []; var playerDeck = []; var enemyDeck = []; var enemyHand = []; var discardPile = []; var isPlayerTurn = true; var gameStarted = false; var selectedCard = null; var draggedCard = null; var turnCounter = 0; var playZone = null; var maxHandSize = 5; var roundActions = []; // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var CARD_WIDTH = 250; var CARD_HEIGHT = 350; var HAND_Y = 2300; var PLAY_ZONE_Y = 1500; // Game entities var playerHero; var enemyHero; var endTurnButton; var playCardButton; var discardCardButton; var actionText; var turnIndicator; // Initialize game elements function initializeGame() { // Create heroes playerHero = new Hero(true); playerHero.x = GAME_WIDTH / 2; playerHero.y = GAME_HEIGHT - 200; game.addChild(playerHero); enemyHero = new Hero(false); enemyHero.x = GAME_WIDTH / 2; enemyHero.y = 500; game.addChild(enemyHero); // Create resource indicator resourceIndicator = new Text2("Resources: " + playerHero.resources, { size: 30, fill: 0xFFCC00 }); resourceIndicator.anchor.set(0.5, 0.5); resourceIndicator.x = GAME_WIDTH - 150; resourceIndicator.y = GAME_HEIGHT / 2; game.addChild(resourceIndicator); // Create card templates createCardTemplates(); // Create play zone playZone = new Container(); playZone.x = GAME_WIDTH / 2; playZone.y = PLAY_ZONE_Y; game.addChild(playZone); // Create UI elements createUIElements(); // Shuffle and deal initial hands initializeDecks(); shuffleDeck(playerDeck); shuffleDeck(enemyDeck); dealInitialHands(); // Setup turn indicator turnIndicator = LK.getAsset('turnIndicator', { anchorX: 0.5, anchorY: 0.5 }); turnIndicator.x = GAME_WIDTH / 2; turnIndicator.y = GAME_HEIGHT / 2 - 300; turnIndicator.alpha = 0.7; game.addChild(turnIndicator); // Add action text actionText = new Text2("Your Turn", { size: 40, fill: 0xFFFFFF }); actionText.anchor.set(0.5, 0.5); actionText.x = GAME_WIDTH / 2; actionText.y = GAME_HEIGHT / 2 - 300; game.addChild(actionText); // Start with player turn startPlayerTurn(); // Play background music LK.playMusic('battleMusic'); gameStarted = true; } // Create UI buttons function createUIElements() { // End turn button endTurnButton = new Button("End Turn", 250, 80); endTurnButton.x = GAME_WIDTH - 200; endTurnButton.y = GAME_HEIGHT - 200; endTurnButton.onClick = function () { if (isPlayerTurn) { endPlayerTurn(); } }; game.addChild(endTurnButton); // Play card button (appears when a card is selected) playCardButton = new Button("Play Card", 200, 80); playCardButton.x = GAME_WIDTH / 2 - 120; playCardButton.y = GAME_HEIGHT - 200; playCardButton.alpha = 0; playCardButton.onClick = function () { if (selectedCard) { playCard(selectedCard); } }; game.addChild(playCardButton); // Discard for resources button discardCardButton = new Button("Pitch", 200, 80); discardCardButton.x = GAME_WIDTH / 2 + 120; discardCardButton.y = GAME_HEIGHT - 200; discardCardButton.alpha = 0; discardCardButton.onClick = function () { if (selectedCard) { pitchForResources(selectedCard); } }; game.addChild(discardCardButton); } // Create card templates function createCardTemplates() { cardTemplates = [ // Attack cards { type: 'attack', value: 3, name: 'Fierce Strike', description: 'Deal 3 damage to opponent' }, { type: 'attack', value: 2, name: 'Quick Slash', description: 'Deal 2 damage to opponent' }, { type: 'attack', value: 4, name: 'Heavy Blow', description: 'Deal 4 damage to opponent' }, { type: 'attack', value: 5, name: 'Crushing Attack', description: 'Deal 5 damage to opponent' }, { type: 'attack', value: 1, name: 'Jab', description: 'Deal 1 damage to opponent' }, // Defense cards { type: 'defense', value: 2, name: 'Block', description: 'Reduce damage by 2' }, { type: 'defense', value: 3, name: 'Shield Up', description: 'Reduce damage by 3' }, { type: 'defense', value: 4, name: 'Deflect', description: 'Reduce damage by 4' }, { type: 'defense', value: 1, name: 'Parry', description: 'Reduce damage by 1' }, // Utility cards { type: 'utility', value: 2, name: 'Focus', description: 'Draw 1 card' }, { type: 'utility', value: 3, name: 'Strategize', description: 'Gain 2 resources' }, { type: 'utility', value: 4, name: 'Second Wind', description: 'Restore 2 health' }]; } // Initialize player and enemy decks function initializeDecks() { playerDeck = []; enemyDeck = []; // Add 30 cards to each deck for (var i = 0; i < 30; i++) { var templateIndex = i % cardTemplates.length; var cardTemplate = cardTemplates[templateIndex]; // Create player card var playerCard = new Card(cardTemplate.type, cardTemplate.value, cardTemplate.name, cardTemplate.description); playerDeck.push(playerCard); // Create enemy card var enemyCard = new Card(cardTemplate.type, cardTemplate.value, cardTemplate.name, cardTemplate.description); enemyDeck.push(enemyCard); } } // Shuffle a deck function shuffleDeck(deck) { for (var i = deck.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = deck[i]; deck[i] = deck[j]; deck[j] = temp; } } // Deal initial hands function dealInitialHands() { // Draw exactly 4 cards for player for (var i = 0; i < 4; i++) { drawCard(true); } // Draw exactly 4 cards for enemy for (var i = 0; i < 4; i++) { drawCard(false); } // Display player hand updateHandDisplay(); } // Draw a card for player or enemy function drawCard(isPlayer) { var deck = isPlayer ? playerDeck : enemyDeck; var hand = isPlayer ? playerHand : enemyHand; if (deck.length > 0 && hand.length < maxHandSize) { var card = deck.pop(); hand.push(card); if (isPlayer) { updateHandDisplay(); } return card; } return null; } // Update the display of cards in player's hand function updateHandDisplay() { // Remove all existing cards from display for (var i = 0; i < playerHand.length; i++) { if (playerHand[i].parent) { playerHand[i].parent.removeChild(playerHand[i]); } } // Calculate card positioning var totalWidth = playerHand.length * CARD_WIDTH * 0.7; var startX = (GAME_WIDTH - totalWidth) / 2; // Add cards to display for (var i = 0; i < playerHand.length; i++) { var card = playerHand[i]; card.x = startX + i * (CARD_WIDTH * 0.7); card.y = HAND_Y; card.setPlayable(isPlayerTurn); game.addChild(card); } } // Start player turn function startPlayerTurn() { isPlayerTurn = true; turnCounter++; // Reset state playerHero.resetTurnStats(); selectedCard = null; hideCardButtons(); // Ensure player has at least 4 cards at the start of their turn while (playerHand.length < 4) { drawCard(true); } // Update player resources playerHero.updateResources(Math.min(playerHero.maxResources, playerHero.resources + 2)); // Update UI endTurnButton.setEnabled(true); actionText.setText("Your Turn"); // Update player hand cards to be playable for (var i = 0; i < playerHand.length; i++) { playerHand[i].setPlayable(true); } // Position the turn indicator near player tween(turnIndicator, { x: playerHero.x, y: playerHero.y - 250 }, { duration: 500, easing: tween.easeOut }); // Log turn start console.log("Player turn " + turnCounter + " started"); } // End player turn and start enemy turn function endPlayerTurn() { isPlayerTurn = false; // Update UI endTurnButton.setEnabled(false); actionText.setText("Enemy Turn"); hideCardButtons(); // Update player hand cards to not be playable for (var i = 0; i < playerHand.length; i++) { playerHand[i].setPlayable(false); playerHand[i].setSelected(false); } // Position turn indicator near enemy tween(turnIndicator, { x: enemyHero.x, y: enemyHero.y + 250 }, { duration: 500, easing: tween.easeOut }); // Execute enemy turn with a delay LK.setTimeout(function () { executeEnemyTurn(); }, 1000); } // Execute enemy AI turn function executeEnemyTurn() { // Reset enemy stats enemyHero.resetTurnStats(); // Ensure enemy has at least 4 cards at the start of their turn while (enemyHand.length < 4) { drawCard(false); } // Update enemy resources (AI starts with some resources) enemyHero.resources = Math.min(enemyHero.maxResources, enemyHero.resources + 2); // AI decision making var actions = planEnemyActions(); executeEnemyActions(actions); } // Plan enemy actions function planEnemyActions() { var actions = []; var availableResources = enemyHero.resources; // Sort cards by value enemyHand.sort(function (a, b) { // Prioritize attack cards if (a.type === 'attack' && b.type !== 'attack') { return -1; } if (a.type !== 'attack' && b.type === 'attack') { return 1; } // Then by value return b.value - a.value; }); // First, check if we need to defend if (playerHero.attack > 0) { // Find defense cards var defenseCards = enemyHand.filter(function (card) { return card.type === 'defense'; }); // Use defense if available if (defenseCards.length > 0) { actions.push({ type: 'play', card: defenseCards[0] }); availableResources -= defenseCards[0].value; // Remove this card from consideration var index = enemyHand.indexOf(defenseCards[0]); if (index !== -1) { enemyHand.splice(index, 1); } } } // Then, try to play attack cards var attackCards = enemyHand.filter(function (card) { return card.type === 'attack' && card.value <= availableResources; }); for (var i = 0; i < attackCards.length; i++) { if (availableResources >= attackCards[i].value) { actions.push({ type: 'play', card: attackCards[i] }); availableResources -= attackCards[i].value; // Remove this card from consideration var index = enemyHand.indexOf(attackCards[i]); if (index !== -1) { enemyHand.splice(index, 1); } } } // If we haven't used any cards but have some, discard one for resources if (actions.length === 0 && enemyHand.length > 0) { // Sort by resource value enemyHand.sort(function (a, b) { return b.resourceValue - a.resourceValue; }); actions.push({ type: 'pitch', card: enemyHand[0] }); // Remove this card from consideration var index = enemyHand.indexOf(enemyHand[0]); if (index !== -1) { enemyHand.splice(index, 1); } } return actions; } // Execute a list of enemy actions with delays function executeEnemyActions(actions) { if (actions.length === 0) { // End enemy turn if no more actions LK.setTimeout(startPlayerTurn, 1000); return; } var action = actions.shift(); var card = action.card; LK.setTimeout(function () { if (action.type === 'play') { // Create a visual representation of the card var enemyCard = new Card(card.type, card.value, card.name, card.description); enemyCard.x = enemyHero.x; enemyCard.y = enemyHero.y + 100; game.addChild(enemyCard); // Animate it to play area tween(enemyCard, { x: GAME_WIDTH / 2, y: PLAY_ZONE_Y - 200 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Apply card effect applyCardEffect(card, false); // Fade out card tween(enemyCard, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { game.removeChild(enemyCard); // Continue with next action executeEnemyActions(actions); } }); } }); } else if (action.type === 'pitch') { // Create a visual representation of the card var enemyCard = new Card(card.type, card.value, card.name, card.description); enemyCard.x = enemyHero.x; enemyCard.y = enemyHero.y + 100; game.addChild(enemyCard); // Animate discard tween(enemyCard, { x: GAME_WIDTH / 2 + 400, y: PLAY_ZONE_Y, rotation: Math.PI / 4 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Add resources enemyHero.resources += card.resourceValue; // Show resource gain var resourceMsg = new Text2("+" + card.resourceValue + " R", { size: 40, fill: 0xFFCC00 }); resourceMsg.anchor.set(0.5, 0.5); resourceMsg.x = enemyHero.x; resourceMsg.y = enemyHero.y - 50; game.addChild(resourceMsg); // Fade out card tween(enemyCard, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { game.removeChild(enemyCard); // Fade out resource message tween(resourceMsg, { alpha: 0, y: resourceMsg.y - 50 }, { duration: 500, onFinish: function onFinish() { game.removeChild(resourceMsg); // Continue with next action executeEnemyActions(actions); } }); } }); } }); } }, 1000); } // Handle card selected by player game.cardSelected = function (card, x, y) { // Deselect previous card if (selectedCard && selectedCard !== card) { selectedCard.setSelected(false); } // Toggle selection if (selectedCard === card) { selectedCard.setSelected(false); selectedCard = null; hideCardButtons(); } else { selectedCard = card; showCardButtons(); } }; // Show action buttons when a card is selected function showCardButtons() { if (!selectedCard) { return; } // Check if the card can be played (enough resources) var canPlay = playerHero.resources >= selectedCard.value; playCardButton.setEnabled(canPlay); // Show buttons tween(playCardButton, { alpha: 1 }, { duration: 200 }); tween(discardCardButton, { alpha: 1 }, { duration: 200 }); } // Hide action buttons function hideCardButtons() { tween(playCardButton, { alpha: 0 }, { duration: 200 }); tween(discardCardButton, { alpha: 0 }, { duration: 200 }); } // Play selected card function playCard(card) { if (!isPlayerTurn || playerHero.resources < card.value) { return; } // Subtract resources playerHero.updateResources(playerHero.resources - card.value); // Remove from hand var index = playerHand.indexOf(card); if (index !== -1) { playerHand.splice(index, 1); } // Play sound LK.getSound('cardPlay').play(); // Move card to play area var originalX = card.x; var originalY = card.y; tween(card, { x: GAME_WIDTH / 2, y: PLAY_ZONE_Y }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Apply card effect applyCardEffect(card, true); // Allow opponent to block with cards if (card.type === 'attack') { // Check if opponent has defense cards var defenseCards = enemyHand.filter(function (card) { return card.type === 'defense'; }); // If defense cards are available, let opponent choose to block if (defenseCards.length > 0) { // For simplicity, automatically choose the first defense card var chosenDefenseCard = defenseCards[0]; applyCardEffect(chosenDefenseCard, false); // Remove the chosen defense card from the enemy's hand var index = enemyHand.indexOf(chosenDefenseCard); if (index !== -1) { enemyHand.splice(index, 1); } } } // Fade out card tween(card, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { // Remove card game.removeChild(card); // Reset selection selectedCard = null; hideCardButtons(); // Update hand display updateHandDisplay(); } }); } }); } // Discard card for resources function pitchForResources(card) { if (!isPlayerTurn) { return; } // Add resources playerHero.updateResources(playerHero.resources + card.resourceValue); // Remove from hand var index = playerHand.indexOf(card); if (index !== -1) { playerHand.splice(index, 1); } // Play sound LK.getSound('cardPlay').play(); // Move card to discard area tween(card, { x: GAME_WIDTH / 2 + 400, y: PLAY_ZONE_Y, rotation: Math.PI / 4 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Show resource gain var resourceMsg = new Text2("+" + card.resourceValue + " Resources", { size: 40, fill: 0xFFCC00 }); resourceMsg.anchor.set(0.5, 0.5); resourceMsg.x = playerHero.x; resourceMsg.y = playerHero.y - 50; game.addChild(resourceMsg); // Fade out card tween(card, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { game.removeChild(card); // Fade out resource message tween(resourceMsg, { alpha: 0, y: resourceMsg.y - 50 }, { duration: 500, onFinish: function onFinish() { game.removeChild(resourceMsg); } }); // Reset selection selectedCard = null; hideCardButtons(); // Update hand display updateHandDisplay(); // Update resource indicator resourceIndicator.setText("Resources: " + playerHero.resources); } }); } }); } // Apply card effect based on type function applyCardEffect(card, isPlayer) { var hero = isPlayer ? playerHero : enemyHero; var opponent = isPlayer ? enemyHero : playerHero; // Create effect text var effectMsg = new Text2("", { size: 40, fill: 0xFFFFFF }); effectMsg.style = { fill: 0xFFFFFF }; // Ensure style property is defined effectMsg.anchor.set(0.5, 0.5); effectMsg.x = isPlayer ? playerHero.x : enemyHero.x; effectMsg.y = isPlayer ? playerHero.y - 50 : enemyHero.y - 50; switch (card.type) { case 'attack': // Add attack power hero.addAttack(card.value); // Deal damage immediately var damageDone = opponent.takeDamage(card.value); // Play sound LK.getSound('attack').play(); // Show damage text effectMsg.setText("-" + damageDone); effectMsg.style.fill = "#ff3333"; // Enhance damage animation size and duration tween(effectMsg, { scaleX: 1.5, scaleY: 1.5, alpha: 0, y: effectMsg.y - 50 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(effectMsg); } }); break; case 'defense': // Add defense hero.addDefense(card.value); // Play sound LK.getSound('defend').play(); // Show defense text effectMsg.setText("+" + card.value + " DEF"); effectMsg.style.fill = "#3399ff"; break; case 'utility': // Handle utility effects if (card.name.includes("Draw")) { // Draw card drawCard(isPlayer); effectMsg.setText("Draw Card"); effectMsg.style.fill = "#33cc33"; } else if (card.name.includes("Gain")) { // Add resources var resourceGain = Math.floor(card.value / 2); hero.updateResources(hero.resources + resourceGain); effectMsg.setText("+" + resourceGain + " Resources"); effectMsg.style.fill = "#ffcc00"; } else if (card.name.includes("Restore")) { // Heal var healAmount = Math.floor(card.value / 2); hero.updateHealth(hero.health + healAmount); effectMsg.setText("+" + healAmount + " HP"); effectMsg.style.fill = "#33cc33"; } break; } // Add effect message to game game.addChild(effectMsg); // Animate and remove effect message tween(effectMsg, { alpha: 0, y: effectMsg.y - 50 }, { duration: 1000, onFinish: function onFinish() { game.removeChild(effectMsg); } }); // Check for game over if (opponent.health <= 0) { LK.setTimeout(function () { if (isPlayer) { // Player won storage.gamesPlayed = (storage.gamesPlayed || 0) + 1; storage.highScore = Math.max(storage.highScore || 0, playerHero.health); LK.setScore(playerHero.health); LK.showYouWin(); } else { // Enemy won storage.gamesPlayed = (storage.gamesPlayed || 0) + 1; LK.setScore(0); LK.showGameOver(); } }, 1000); } } // Game update loop game.update = function () { if (!gameStarted) { initializeGame(); } }; // Handle touch/mouse movement game.move = function (x, y, obj) { // We could implement card dragging here if needed }; // Start the game LK.playMusic('battleMusic');
===================================================================
--- original.js
+++ change.js
@@ -1036,8 +1036,21 @@
LK.getSound('attack').play();
// Show damage text
effectMsg.setText("-" + damageDone);
effectMsg.style.fill = "#ff3333";
+ // Enhance damage animation size and duration
+ tween(effectMsg, {
+ scaleX: 1.5,
+ scaleY: 1.5,
+ alpha: 0,
+ y: effectMsg.y - 50
+ }, {
+ duration: 1500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ game.removeChild(effectMsg);
+ }
+ });
break;
case 'defense':
// Add defense
hero.addDefense(card.value);