/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Card = Container.expand(function (cardData) { var self = Container.call(this); self.cardData = cardData; self.purchased = false; // Card border var border = self.attachAsset('cardBorder', { anchorX: 0.5, anchorY: 0.5 }); // Card background var background = self.attachAsset('cardBackground', { anchorX: 0.5, anchorY: 0.5 }); // Card title self.titleText = new Text2(cardData.name, { size: 56, fill: 0xFFFFFF }); self.titleText.anchor.set(0.5, 0); self.titleText.x = 0; self.titleText.y = -160; self.addChild(self.titleText); // Card description self.descText = new Text2(cardData.description, { size: 40, fill: 0xECF0F1 }); self.descText.anchor.set(0.5, 0); self.descText.x = 0; self.descText.y = -100; self.addChild(self.descText); // Points text self.pointsText = new Text2("+" + cardData.points + " pts", { size: 48, fill: 0xE74C3C }); self.pointsText.anchor.set(0.5, 0); self.pointsText.x = 0; self.pointsText.y = -40; self.addChild(self.pointsText); // Cost and buy button self.buyButton = self.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5 }); self.buyButton.y = 120; self.costText = new Text2("Buy: " + cardData.cost + " coins", { size: 36, fill: 0xFFFFFF }); self.costText.anchor.set(0.5, 0.5); self.costText.x = 0; self.costText.y = 120; self.addChild(self.costText); self.updateVisual = function () { if (self.purchased) { if (self.cardData.type === "negative") { background.tint = 0x2ecc71; // Green for deactivated negative card self.titleText.setText(self.cardData.name + " (DEACTIVATED)"); } else { background.tint = 0x27ae60; } self.buyButton.visible = false; self.costText.visible = false; } else { var actualCost = Math.max(1, self.cardData.cost - nextCardCostReduction); if (self.cardData.type === "negative") { self.costText.setText("Deactivate: " + actualCost + " coins"); background.tint = 0xe74c3c; // Red for active negative card self.buyButton.tint = 0xe67e22; // Orange buy button for negative } else { if (nextCardCostReduction > 0) { self.costText.setText("Buy: " + actualCost + " coins (was " + self.cardData.cost + ")"); } else { self.costText.setText("Buy: " + actualCost + " coins"); } if (coins < actualCost) { background.tint = 0x7f8c8d; self.buyButton.tint = 0x7f8c8d; } else { background.tint = 0x2c3e50; self.buyButton.tint = 0x27ae60; } } } }; self.over = function (x, y, obj) { if (!self.purchased) { LK.getSound('cardHover').play(); } }; self.down = function (x, y, obj) { if (!self.purchased && coins >= self.cardData.cost) { self.purchase(); } }; self.purchase = function () { if (self.purchased || coins < self.cardData.cost) return; var actualCost = Math.max(1, self.cardData.cost - nextCardCostReduction); coins -= actualCost; nextCardCostReduction = 0; self.purchased = true; // Track card types if (!purchasedCardTypes[self.cardData.type]) { purchasedCardTypes[self.cardData.type] = 0; } purchasedCardTypes[self.cardData.type]++; // Apply card abilities var pointsToAdd = self.cardData.points; if (self.cardData.ability) { pointsToAdd = applyCardAbility(self.cardData, pointsToAdd); } // Apply global multiplier pointsToAdd = Math.floor(pointsToAdd * globalPointMultiplier); points += pointsToAdd; self.updateVisual(); updateUI(); LK.getSound('cardBuy').play(); tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); } }); }; return self; }); var MainMenu = Container.expand(function () { var self = Container.call(this); // Menu background var menuBg = self.attachAsset('gameBoard', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); menuBg.tint = 0x2c3e50; // Game title var titleText = new Text2("CARD STRATEGY", { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; self.addChild(titleText); // Subtitle var subtitleText = new Text2("Collect cards to survive!", { size: 60, fill: 0xBDC3C7 }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 500; self.addChild(subtitleText); // Play button var playButton = self.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 800, scaleX: 1.5, scaleY: 1.5 }); playButton.tint = 0x27ae60; var playText = new Text2("PLAY", { size: 80, fill: 0xFFFFFF }); playText.anchor.set(0.5, 0.5); playText.x = 1024; playText.y = 800; self.addChild(playText); // Instructions var instructionsText = new Text2("• Buy cards to earn points\n• Survive checkpoint requirements every 5 turns\n• Use combos and special abilities\n• Deactivate negative cards to avoid penalties", { size: 48, fill: 0xECF0F1 }); instructionsText.anchor.set(0.5, 0.5); instructionsText.x = 1024; instructionsText.y = 1200; self.addChild(instructionsText); // Credits var creditsText = new Text2("Made with FRVR", { size: 36, fill: 0x95A5A6 }); creditsText.anchor.set(0.5, 0.5); creditsText.x = 1024; creditsText.y = 1600; self.addChild(creditsText); // Play button click handler playButton.down = function (x, y, obj) { startGame(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0f1419 }); /**** * Game Code ****/ // Game state variables var coins = 10; var points = 0; var turn = 1; var checkpoint = 1; var requiredPoints = 20; var currentCards = []; var gamePhase = 'menu'; // 'menu', 'playing', 'checkpoint', 'gameOver' var mainMenu = null; // Game mechanics tracking var purchasedCardTypes = {}; var nextCardCostReduction = 0; var permanentCoinBonus = 0; var globalPointMultiplier = 1; var skipNextCheckpoint = false; // Combo system variables var comboMultiplier = 1; var comboCards = []; var maxComboSize = 3; var perTurnCoinGrowth = 0; // Negative cards system var negativeCards = []; var negativeCardTemplates = [{ name: "Tax Collector", description: "Lose 30% of coins", points: 0, cost: 8, type: "negative", negativeEffect: "taxCoins" }, { name: "Point Drain", description: "Lose 25% of points", points: 0, cost: 12, type: "negative", negativeEffect: "drainPoints" }, { name: "Coin Thief", description: "Lose 15 coins", points: 0, cost: 6, type: "negative", negativeEffect: "stealCoins" }, { name: "Deflation", description: "Reduce coin growth by 2", points: 0, cost: 10, type: "negative", negativeEffect: "reduceGrowth" }, { name: "Combo Breaker", description: "Reset all combos", points: 0, cost: 7, type: "negative", negativeEffect: "breakCombo" }]; // Card templates organized by checkpoint level var cardTemplatesByLevel = { 1: [{ // Basic cards for checkpoint 1 name: "Basic Card", description: "Simple points", points: 5, cost: 3, type: "basic" }, { name: "Coin Card", description: "Steady income", points: 3, cost: 2, type: "economy" }, { name: "Power Card", description: "High value", points: 12, cost: 8, type: "power" }, { name: "Lucky Card", description: "Bonus points", points: 8, cost: 5, type: "luck" }, { name: "Quick Card", description: "Fast points", points: 4, cost: 2, type: "quick" }], 2: [{ // Advanced cards for checkpoint 2+ name: "Mega Card", description: "Massive points", points: 20, cost: 15, type: "mega" }, { name: "Super Card", description: "Great value", points: 15, cost: 10, type: "super" }, { name: "Bonus Card", description: "Extra boost", points: 6, cost: 4, type: "bonus" }, { name: "Multiplier Card", description: "x2 next card points", points: 2, cost: 4, type: "multiplier", ability: "nextCardMultiplier" }, { name: "Discount Card", description: "Next card costs 50% less", points: 1, cost: 3, type: "discount", ability: "costReduction" }, { name: "Combo Starter", description: "Begin a combo chain", points: 3, cost: 2, type: "combo", ability: "comboStarter" }, { name: "Combo Builder", description: "Extend current combo", points: 5, cost: 4, type: "combo", ability: "comboBuilder" }], 3: [{ // Expert cards for checkpoint 3+ name: "Economy Synergy", description: "+3 pts per Economy card", points: 1, cost: 5, type: "synergy", ability: "economySynergy" }, { name: "Power Synergy", description: "+5 pts per Power card", points: 2, cost: 7, type: "synergy", ability: "powerSynergy" }, { name: "Collection Bonus", description: "+2 pts per unique type", points: 3, cost: 6, type: "collection", ability: "typeBonus" }, { name: "Lucky Streak", description: "+1 pt per Lucky card", points: 2, cost: 3, type: "streak", ability: "luckySynergy" }, { name: "Coin Generator", description: "+2 coins next turn", points: 1, cost: 2, type: "generator", ability: "coinBonus" }, { name: "Combo Master", description: "Complete combo +50% bonus", points: 8, cost: 6, type: "combo", ability: "comboMaster" }, { name: "Chain Reactor", description: "Each combo card +2 coins/turn", points: 4, cost: 5, type: "combo", ability: "comboEconomy" }], 4: [{ // Master cards for checkpoint 4+ name: "Point Doubler", description: "Double current points", points: 0, cost: 12, type: "doubler", ability: "doublePoints" }, { name: "Chain Multiplier", description: "Each purchased card +10% pts", points: 5, cost: 8, type: "chain", ability: "chainMultiplier" }, { name: "Compound Engine", description: "Points grow exponentially", points: 3, cost: 10, type: "compound", ability: "compoundGrowth" }, { name: "Universal Synergy", description: "+1 pt per ANY card owned", points: 2, cost: 6, type: "universal", ability: "universalSynergy" }, { name: "Mega Coin Bank", description: "+5 coins per turn forever", points: 5, cost: 15, type: "bank", ability: "megaCoinBonus" }, { name: "Combo Engine", description: "Triple combo bonuses", points: 10, cost: 18, type: "combo", ability: "comboTriple" }], 5: [{ // Legendary cards for checkpoint 5+ name: "Infinity Engine", description: "Triple all future points", points: 10, cost: 20, type: "infinity", ability: "tripleMultiplier" }, { name: "Checkpoint Keeper", description: "+50% req points for easier pass", points: 15, cost: 25, type: "keeper", ability: "easierCheckpoint" }, { name: "Card Recycler", description: "Get 50% coin refund on all cards", points: 8, cost: 18, type: "recycler", ability: "coinRefund" }, { name: "Time Manipulator", description: "Skip next checkpoint req", points: 20, cost: 30, type: "time", ability: "skipCheckpoint" }, { name: "Infinite Combos", description: "No combo size limit, x5 bonus", points: 30, cost: 40, type: "combo", ability: "infiniteCombo" }] }; // Legacy compatibility - combine all templates var cardTemplates = []; for (var level in cardTemplatesByLevel) { cardTemplates = cardTemplates.concat(cardTemplatesByLevel[level]); } // UI Elements var board = game.attachAsset('gameBoard', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); // Coins display var coinsText = new Text2("Coins: " + coins, { size: 48, fill: 0xF1C40F }); coinsText.anchor.set(0, 0); coinsText.x = 100; coinsText.y = 150; LK.gui.topLeft.addChild(coinsText); // Points display var pointsText = new Text2("Points: " + points, { size: 48, fill: 0xE74C3C }); pointsText.anchor.set(0, 0); pointsText.x = 100; pointsText.y = 220; LK.gui.topLeft.addChild(pointsText); // Turn display var turnText = new Text2("Turn: " + turn, { size: 36, fill: 0x3498DB }); turnText.anchor.set(0, 0); turnText.x = 100; turnText.y = 290; LK.gui.topLeft.addChild(turnText); // Required points display var requiredText = new Text2("Need: " + requiredPoints + " pts", { size: 36, fill: 0xE67E22 }); requiredText.anchor.set(0, 0); requiredText.x = 100; requiredText.y = 340; LK.gui.topLeft.addChild(requiredText); // Combo display var comboText = new Text2("Combo: " + comboCards.length + "/" + maxComboSize, { size: 32, fill: 0x9B59B6 }); comboText.anchor.set(0, 0); comboText.x = 100; comboText.y = 390; LK.gui.topLeft.addChild(comboText); // Coin growth display var growthText = new Text2("Coin Growth: +" + perTurnCoinGrowth + "/turn", { size: 28, fill: 0x1ABC9C }); growthText.anchor.set(0, 0); growthText.x = 100; growthText.y = 440; LK.gui.topLeft.addChild(growthText); // Progress bar var progressBarBg = game.attachAsset('progressBar', { anchorX: 0.5, anchorY: 0, x: 1024, y: 200 }); var progressBarFill = game.attachAsset('progressFill', { anchorX: 0, anchorY: 0, x: 224, y: 200 }); // Next turn button var nextTurnButton = game.attachAsset('nextTurnButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2500 }); var nextTurnText = new Text2("Next Turn", { size: 44, fill: 0xFFFFFF }); nextTurnText.anchor.set(0.5, 0.5); nextTurnText.x = 1024; nextTurnText.y = 2500; game.addChild(nextTurnText); function applyNegativeEffect(negativeEffect) { LK.getSound('negativeEffect').play(); switch (negativeEffect) { case "taxCoins": var coinsLost = Math.floor(coins * 0.3); coins = Math.max(0, coins - coinsLost); break; case "drainPoints": var pointsLost = Math.floor(points * 0.25); points = Math.max(0, points - pointsLost); break; case "stealCoins": coins = Math.max(0, coins - 15); break; case "reduceGrowth": perTurnCoinGrowth = Math.max(0, perTurnCoinGrowth - 2); break; case "breakCombo": comboCards = []; comboMultiplier = 1; break; } } function applyCardAbility(cardData, basePoints) { var bonusPoints = 0; switch (cardData.ability) { case "nextCardMultiplier": // This will be handled when the next card is purchased return basePoints; case "costReduction": nextCardCostReduction = Math.floor(cardData.cost * 0.5); return basePoints; case "economySynergy": bonusPoints = (purchasedCardTypes["economy"] || 0) * 3; return basePoints + bonusPoints; case "powerSynergy": bonusPoints = (purchasedCardTypes["power"] || 0) * 5; return basePoints + bonusPoints; case "luckySynergy": bonusPoints = (purchasedCardTypes["luck"] || 0) * 1; return basePoints + bonusPoints; case "typeBonus": var uniqueTypes = Object.keys(purchasedCardTypes).length; bonusPoints = uniqueTypes * 2; return basePoints + bonusPoints; case "coinBonus": coins += 2; return basePoints; case "doublePoints": points = points * 2; return 0; case "chainMultiplier": var totalCards = 0; for (var type in purchasedCardTypes) { totalCards += purchasedCardTypes[type]; } bonusPoints = Math.floor(totalCards * 0.1 * basePoints); return basePoints + bonusPoints; case "compoundGrowth": bonusPoints = Math.floor(points * 0.1); return basePoints + bonusPoints; case "universalSynergy": var totalCards = 0; for (var type in purchasedCardTypes) { totalCards += purchasedCardTypes[type]; } bonusPoints = totalCards; return basePoints + bonusPoints; case "megaCoinBonus": // Add permanent income bonus if (!permanentCoinBonus) permanentCoinBonus = 0; permanentCoinBonus += 5; return basePoints; case "tripleMultiplier": if (!globalPointMultiplier) globalPointMultiplier = 1; globalPointMultiplier *= 3; return basePoints; case "easierCheckpoint": requiredPoints = Math.floor(requiredPoints * 0.5); return basePoints; case "coinRefund": coins += Math.floor(cardData.cost * 0.5); return basePoints; case "skipCheckpoint": // Skip next checkpoint requirement skipNextCheckpoint = true; return basePoints; case "comboStarter": comboCards = [cardData]; comboMultiplier = 1.2; return basePoints; case "comboBuilder": if (comboCards.length > 0 && comboCards.length < maxComboSize) { comboCards.push(cardData); comboMultiplier += 0.3; bonusPoints = Math.floor(basePoints * (comboMultiplier - 1)); return basePoints + bonusPoints; } else { return basePoints; } case "comboMaster": if (comboCards.length >= maxComboSize) { bonusPoints = Math.floor(basePoints * 0.5); LK.getSound('comboComplete').play(); comboCards = []; comboMultiplier = 1; return basePoints + bonusPoints; } else { return basePoints; } case "comboEconomy": var comboCardCount = 0; for (var type in purchasedCardTypes) { if (type === "combo") { comboCardCount = purchasedCardTypes[type]; break; } } perTurnCoinGrowth += comboCardCount * 2; return basePoints; case "comboTriple": comboMultiplier *= 3; return basePoints; case "infiniteCombo": maxComboSize = 999; comboMultiplier *= 5; return basePoints; // Don't add base points since we doubled existing default: return basePoints; } } function generateRandomCard() { // 20% chance to generate a negative card from checkpoint 2 onwards if (checkpoint >= 2 && Math.random() < 0.2) { var template = negativeCardTemplates[Math.floor(Math.random() * negativeCardTemplates.length)]; var scaleFactor = 1 + (checkpoint - 1) * 0.15; return { name: template.name, description: template.description, points: template.points, cost: Math.floor(template.cost * scaleFactor), type: template.type, negativeEffect: template.negativeEffect }; } // Get available card templates based on current checkpoint var availableTemplates = []; for (var level = 1; level <= Math.min(checkpoint, 5); level++) { if (cardTemplatesByLevel[level]) { availableTemplates = availableTemplates.concat(cardTemplatesByLevel[level]); } } // Fallback to level 1 cards if no templates available if (availableTemplates.length === 0) { availableTemplates = cardTemplatesByLevel[1] || []; } // Higher checkpoints have better chance of getting advanced cards var template; if (checkpoint >= 3 && Math.random() < 0.6) { // 60% chance for advanced cards in checkpoint 3+ var advancedTemplates = []; for (var level = Math.max(2, checkpoint - 1); level <= Math.min(checkpoint, 5); level++) { if (cardTemplatesByLevel[level]) { advancedTemplates = advancedTemplates.concat(cardTemplatesByLevel[level]); } } if (advancedTemplates.length > 0) { template = advancedTemplates[Math.floor(Math.random() * advancedTemplates.length)]; } else { template = availableTemplates[Math.floor(Math.random() * availableTemplates.length)]; } } else { template = availableTemplates[Math.floor(Math.random() * availableTemplates.length)]; } // Final safety check - use first available template if still undefined if (!template && availableTemplates.length > 0) { template = availableTemplates[0]; } // If still no template, create a default one if (!template) { template = { name: "Emergency Card", description: "Basic fallback", points: 3, cost: 2, type: "basic" }; } var scaleFactor = 1 + (checkpoint - 1) * 0.2; return { name: template.name, description: template.description, points: Math.floor(template.points * scaleFactor), cost: Math.floor(template.cost * scaleFactor), type: template.type, ability: template.ability }; } function generateCards() { // Clear existing cards for (var i = 0; i < currentCards.length; i++) { currentCards[i].destroy(); } currentCards = []; // Clear negative cards tracking for new turn negativeCards = []; // Generate 5 new cards in two vertical columns with doubled size var cardPositions = [{ x: 700, y: 600 }, { x: 1348, y: 600 }, { x: 700, y: 1200 }, { x: 1348, y: 1200 }, { x: 700, y: 1800 }]; for (var i = 0; i < 5; i++) { var cardData = generateRandomCard(); var card = new Card(cardData); card.x = cardPositions[i].x; card.y = cardPositions[i].y; currentCards.push(card); game.addChild(card); // Track negative cards if (cardData.type === "negative") { negativeCards.push(card); } } updateCardsVisual(); } function updateCardsVisual() { for (var i = 0; i < currentCards.length; i++) { currentCards[i].updateVisual(); } } function updateUI() { coinsText.setText("Coins: " + coins); pointsText.setText("Points: " + points); turnText.setText("Turn: " + turn); requiredText.setText("Need: " + requiredPoints + " pts"); comboText.setText("Combo: " + comboCards.length + "/" + maxComboSize + " (x" + comboMultiplier.toFixed(1) + ")"); growthText.setText("Coin Growth: +" + perTurnCoinGrowth + "/turn"); // Update progress bar var progress = Math.min(points / requiredPoints, 1); progressBarFill.width = 1600 * progress; if (points >= requiredPoints) { progressBarFill.tint = 0x2ecc71; } else { progressBarFill.tint = 0xe74c3c; } updateCardsVisual(); } function nextTurn() { if (gamePhase !== 'playing') return; // Apply negative card effects before ending turn for (var i = 0; i < negativeCards.length; i++) { var negativeCard = negativeCards[i]; if (!negativeCard.purchased && negativeCard.cardData.negativeEffect) { applyNegativeEffect(negativeCard.cardData.negativeEffect); // Flash screen red briefly to show negative effect LK.effects.flashScreen(0xe74c3c, 300); } } turn++; LK.getSound('turnAdvance').play(); // Calculate total coin income: base + checkpoint bonus + permanent bonus + per-turn growth var baseCoinIncome = 3 + Math.floor(checkpoint / 2); var totalCoinIncome = baseCoinIncome + permanentCoinBonus + perTurnCoinGrowth; coins += totalCoinIncome; // Increase per-turn coin growth by 1 each turn perTurnCoinGrowth += 1; // Check for checkpoint every 5 turns if (turn % 5 === 1 && turn > 1) { checkCheckpoint(); } else { generateCards(); updateUI(); } } function startGame() { if (mainMenu) { mainMenu.destroy(); mainMenu = null; } // Stop menu music and start gameplay music LK.stopMusic(); LK.playMusic('gameplayMusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); // Reset game state coins = 10; points = 0; turn = 1; checkpoint = 1; requiredPoints = 20; currentCards = []; gamePhase = 'playing'; purchasedCardTypes = {}; nextCardCostReduction = 0; permanentCoinBonus = 0; globalPointMultiplier = 1; skipNextCheckpoint = false; comboMultiplier = 1; comboCards = []; maxComboSize = 3; perTurnCoinGrowth = 0; negativeCards = []; // Show game UI elements coinsText.visible = true; pointsText.visible = true; turnText.visible = true; requiredText.visible = true; comboText.visible = true; growthText.visible = true; progressBarBg.visible = true; progressBarFill.visible = true; nextTurnButton.visible = true; nextTurnText.visible = true; // Start the game generateCards(); updateUI(); } function checkCheckpoint() { if (points >= requiredPoints) { // Pass checkpoint checkpoint++; requiredPoints = Math.floor(requiredPoints * 1.8); // Points are now maintained between checkpoints LK.getSound('checkpoint').play(); // Flash screen green LK.effects.flashScreen(0x2ecc71, 1000); generateCards(); updateUI(); LK.setScore(checkpoint - 1); } else { // Fail checkpoint - game over gamePhase = 'gameOver'; LK.getSound('gameOver').play(); LK.stopMusic(); LK.playMusic('gameOverMusic', { fade: { start: 0, end: 0.6, duration: 800 } }); LK.effects.flashScreen(0xe74c3c, 1500); LK.setTimeout(function () { LK.showGameOver(); }, 1500); } } // Event handlers nextTurnButton.down = function (x, y, obj) { nextTurn(); }; game.down = function (x, y, obj) { if (gamePhase !== 'playing') return; // Use direct x, y coordinates instead of trying to convert positions // Check if clicked on next turn button if (x >= nextTurnButton.x - 200 && x <= nextTurnButton.x + 200 && y >= nextTurnButton.y - 40 && y <= nextTurnButton.y + 40) { nextTurn(); } }; // Hide UI elements initially coinsText.visible = false; pointsText.visible = false; turnText.visible = false; requiredText.visible = false; comboText.visible = false; growthText.visible = false; progressBarBg.visible = false; progressBarFill.visible = false; nextTurnButton.visible = false; nextTurnText.visible = false; // Show main menu mainMenu = new MainMenu(); game.addChild(mainMenu); // Start menu music LK.playMusic('menuMusic', { fade: { start: 0, end: 0.7, duration: 1500 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Card = Container.expand(function (cardData) {
var self = Container.call(this);
self.cardData = cardData;
self.purchased = false;
// Card border
var border = self.attachAsset('cardBorder', {
anchorX: 0.5,
anchorY: 0.5
});
// Card background
var background = self.attachAsset('cardBackground', {
anchorX: 0.5,
anchorY: 0.5
});
// Card title
self.titleText = new Text2(cardData.name, {
size: 56,
fill: 0xFFFFFF
});
self.titleText.anchor.set(0.5, 0);
self.titleText.x = 0;
self.titleText.y = -160;
self.addChild(self.titleText);
// Card description
self.descText = new Text2(cardData.description, {
size: 40,
fill: 0xECF0F1
});
self.descText.anchor.set(0.5, 0);
self.descText.x = 0;
self.descText.y = -100;
self.addChild(self.descText);
// Points text
self.pointsText = new Text2("+" + cardData.points + " pts", {
size: 48,
fill: 0xE74C3C
});
self.pointsText.anchor.set(0.5, 0);
self.pointsText.x = 0;
self.pointsText.y = -40;
self.addChild(self.pointsText);
// Cost and buy button
self.buyButton = self.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.buyButton.y = 120;
self.costText = new Text2("Buy: " + cardData.cost + " coins", {
size: 36,
fill: 0xFFFFFF
});
self.costText.anchor.set(0.5, 0.5);
self.costText.x = 0;
self.costText.y = 120;
self.addChild(self.costText);
self.updateVisual = function () {
if (self.purchased) {
if (self.cardData.type === "negative") {
background.tint = 0x2ecc71; // Green for deactivated negative card
self.titleText.setText(self.cardData.name + " (DEACTIVATED)");
} else {
background.tint = 0x27ae60;
}
self.buyButton.visible = false;
self.costText.visible = false;
} else {
var actualCost = Math.max(1, self.cardData.cost - nextCardCostReduction);
if (self.cardData.type === "negative") {
self.costText.setText("Deactivate: " + actualCost + " coins");
background.tint = 0xe74c3c; // Red for active negative card
self.buyButton.tint = 0xe67e22; // Orange buy button for negative
} else {
if (nextCardCostReduction > 0) {
self.costText.setText("Buy: " + actualCost + " coins (was " + self.cardData.cost + ")");
} else {
self.costText.setText("Buy: " + actualCost + " coins");
}
if (coins < actualCost) {
background.tint = 0x7f8c8d;
self.buyButton.tint = 0x7f8c8d;
} else {
background.tint = 0x2c3e50;
self.buyButton.tint = 0x27ae60;
}
}
}
};
self.over = function (x, y, obj) {
if (!self.purchased) {
LK.getSound('cardHover').play();
}
};
self.down = function (x, y, obj) {
if (!self.purchased && coins >= self.cardData.cost) {
self.purchase();
}
};
self.purchase = function () {
if (self.purchased || coins < self.cardData.cost) return;
var actualCost = Math.max(1, self.cardData.cost - nextCardCostReduction);
coins -= actualCost;
nextCardCostReduction = 0;
self.purchased = true;
// Track card types
if (!purchasedCardTypes[self.cardData.type]) {
purchasedCardTypes[self.cardData.type] = 0;
}
purchasedCardTypes[self.cardData.type]++;
// Apply card abilities
var pointsToAdd = self.cardData.points;
if (self.cardData.ability) {
pointsToAdd = applyCardAbility(self.cardData, pointsToAdd);
}
// Apply global multiplier
pointsToAdd = Math.floor(pointsToAdd * globalPointMultiplier);
points += pointsToAdd;
self.updateVisual();
updateUI();
LK.getSound('cardBuy').play();
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Menu background
var menuBg = self.attachAsset('gameBoard', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
menuBg.tint = 0x2c3e50;
// Game title
var titleText = new Text2("CARD STRATEGY", {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
self.addChild(titleText);
// Subtitle
var subtitleText = new Text2("Collect cards to survive!", {
size: 60,
fill: 0xBDC3C7
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 500;
self.addChild(subtitleText);
// Play button
var playButton = self.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
scaleX: 1.5,
scaleY: 1.5
});
playButton.tint = 0x27ae60;
var playText = new Text2("PLAY", {
size: 80,
fill: 0xFFFFFF
});
playText.anchor.set(0.5, 0.5);
playText.x = 1024;
playText.y = 800;
self.addChild(playText);
// Instructions
var instructionsText = new Text2("• Buy cards to earn points\n• Survive checkpoint requirements every 5 turns\n• Use combos and special abilities\n• Deactivate negative cards to avoid penalties", {
size: 48,
fill: 0xECF0F1
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 1024;
instructionsText.y = 1200;
self.addChild(instructionsText);
// Credits
var creditsText = new Text2("Made with FRVR", {
size: 36,
fill: 0x95A5A6
});
creditsText.anchor.set(0.5, 0.5);
creditsText.x = 1024;
creditsText.y = 1600;
self.addChild(creditsText);
// Play button click handler
playButton.down = function (x, y, obj) {
startGame();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0f1419
});
/****
* Game Code
****/
// Game state variables
var coins = 10;
var points = 0;
var turn = 1;
var checkpoint = 1;
var requiredPoints = 20;
var currentCards = [];
var gamePhase = 'menu'; // 'menu', 'playing', 'checkpoint', 'gameOver'
var mainMenu = null;
// Game mechanics tracking
var purchasedCardTypes = {};
var nextCardCostReduction = 0;
var permanentCoinBonus = 0;
var globalPointMultiplier = 1;
var skipNextCheckpoint = false;
// Combo system variables
var comboMultiplier = 1;
var comboCards = [];
var maxComboSize = 3;
var perTurnCoinGrowth = 0;
// Negative cards system
var negativeCards = [];
var negativeCardTemplates = [{
name: "Tax Collector",
description: "Lose 30% of coins",
points: 0,
cost: 8,
type: "negative",
negativeEffect: "taxCoins"
}, {
name: "Point Drain",
description: "Lose 25% of points",
points: 0,
cost: 12,
type: "negative",
negativeEffect: "drainPoints"
}, {
name: "Coin Thief",
description: "Lose 15 coins",
points: 0,
cost: 6,
type: "negative",
negativeEffect: "stealCoins"
}, {
name: "Deflation",
description: "Reduce coin growth by 2",
points: 0,
cost: 10,
type: "negative",
negativeEffect: "reduceGrowth"
}, {
name: "Combo Breaker",
description: "Reset all combos",
points: 0,
cost: 7,
type: "negative",
negativeEffect: "breakCombo"
}];
// Card templates organized by checkpoint level
var cardTemplatesByLevel = {
1: [{
// Basic cards for checkpoint 1
name: "Basic Card",
description: "Simple points",
points: 5,
cost: 3,
type: "basic"
}, {
name: "Coin Card",
description: "Steady income",
points: 3,
cost: 2,
type: "economy"
}, {
name: "Power Card",
description: "High value",
points: 12,
cost: 8,
type: "power"
}, {
name: "Lucky Card",
description: "Bonus points",
points: 8,
cost: 5,
type: "luck"
}, {
name: "Quick Card",
description: "Fast points",
points: 4,
cost: 2,
type: "quick"
}],
2: [{
// Advanced cards for checkpoint 2+
name: "Mega Card",
description: "Massive points",
points: 20,
cost: 15,
type: "mega"
}, {
name: "Super Card",
description: "Great value",
points: 15,
cost: 10,
type: "super"
}, {
name: "Bonus Card",
description: "Extra boost",
points: 6,
cost: 4,
type: "bonus"
}, {
name: "Multiplier Card",
description: "x2 next card points",
points: 2,
cost: 4,
type: "multiplier",
ability: "nextCardMultiplier"
}, {
name: "Discount Card",
description: "Next card costs 50% less",
points: 1,
cost: 3,
type: "discount",
ability: "costReduction"
}, {
name: "Combo Starter",
description: "Begin a combo chain",
points: 3,
cost: 2,
type: "combo",
ability: "comboStarter"
}, {
name: "Combo Builder",
description: "Extend current combo",
points: 5,
cost: 4,
type: "combo",
ability: "comboBuilder"
}],
3: [{
// Expert cards for checkpoint 3+
name: "Economy Synergy",
description: "+3 pts per Economy card",
points: 1,
cost: 5,
type: "synergy",
ability: "economySynergy"
}, {
name: "Power Synergy",
description: "+5 pts per Power card",
points: 2,
cost: 7,
type: "synergy",
ability: "powerSynergy"
}, {
name: "Collection Bonus",
description: "+2 pts per unique type",
points: 3,
cost: 6,
type: "collection",
ability: "typeBonus"
}, {
name: "Lucky Streak",
description: "+1 pt per Lucky card",
points: 2,
cost: 3,
type: "streak",
ability: "luckySynergy"
}, {
name: "Coin Generator",
description: "+2 coins next turn",
points: 1,
cost: 2,
type: "generator",
ability: "coinBonus"
}, {
name: "Combo Master",
description: "Complete combo +50% bonus",
points: 8,
cost: 6,
type: "combo",
ability: "comboMaster"
}, {
name: "Chain Reactor",
description: "Each combo card +2 coins/turn",
points: 4,
cost: 5,
type: "combo",
ability: "comboEconomy"
}],
4: [{
// Master cards for checkpoint 4+
name: "Point Doubler",
description: "Double current points",
points: 0,
cost: 12,
type: "doubler",
ability: "doublePoints"
}, {
name: "Chain Multiplier",
description: "Each purchased card +10% pts",
points: 5,
cost: 8,
type: "chain",
ability: "chainMultiplier"
}, {
name: "Compound Engine",
description: "Points grow exponentially",
points: 3,
cost: 10,
type: "compound",
ability: "compoundGrowth"
}, {
name: "Universal Synergy",
description: "+1 pt per ANY card owned",
points: 2,
cost: 6,
type: "universal",
ability: "universalSynergy"
}, {
name: "Mega Coin Bank",
description: "+5 coins per turn forever",
points: 5,
cost: 15,
type: "bank",
ability: "megaCoinBonus"
}, {
name: "Combo Engine",
description: "Triple combo bonuses",
points: 10,
cost: 18,
type: "combo",
ability: "comboTriple"
}],
5: [{
// Legendary cards for checkpoint 5+
name: "Infinity Engine",
description: "Triple all future points",
points: 10,
cost: 20,
type: "infinity",
ability: "tripleMultiplier"
}, {
name: "Checkpoint Keeper",
description: "+50% req points for easier pass",
points: 15,
cost: 25,
type: "keeper",
ability: "easierCheckpoint"
}, {
name: "Card Recycler",
description: "Get 50% coin refund on all cards",
points: 8,
cost: 18,
type: "recycler",
ability: "coinRefund"
}, {
name: "Time Manipulator",
description: "Skip next checkpoint req",
points: 20,
cost: 30,
type: "time",
ability: "skipCheckpoint"
}, {
name: "Infinite Combos",
description: "No combo size limit, x5 bonus",
points: 30,
cost: 40,
type: "combo",
ability: "infiniteCombo"
}]
};
// Legacy compatibility - combine all templates
var cardTemplates = [];
for (var level in cardTemplatesByLevel) {
cardTemplates = cardTemplates.concat(cardTemplatesByLevel[level]);
}
// UI Elements
var board = game.attachAsset('gameBoard', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
// Coins display
var coinsText = new Text2("Coins: " + coins, {
size: 48,
fill: 0xF1C40F
});
coinsText.anchor.set(0, 0);
coinsText.x = 100;
coinsText.y = 150;
LK.gui.topLeft.addChild(coinsText);
// Points display
var pointsText = new Text2("Points: " + points, {
size: 48,
fill: 0xE74C3C
});
pointsText.anchor.set(0, 0);
pointsText.x = 100;
pointsText.y = 220;
LK.gui.topLeft.addChild(pointsText);
// Turn display
var turnText = new Text2("Turn: " + turn, {
size: 36,
fill: 0x3498DB
});
turnText.anchor.set(0, 0);
turnText.x = 100;
turnText.y = 290;
LK.gui.topLeft.addChild(turnText);
// Required points display
var requiredText = new Text2("Need: " + requiredPoints + " pts", {
size: 36,
fill: 0xE67E22
});
requiredText.anchor.set(0, 0);
requiredText.x = 100;
requiredText.y = 340;
LK.gui.topLeft.addChild(requiredText);
// Combo display
var comboText = new Text2("Combo: " + comboCards.length + "/" + maxComboSize, {
size: 32,
fill: 0x9B59B6
});
comboText.anchor.set(0, 0);
comboText.x = 100;
comboText.y = 390;
LK.gui.topLeft.addChild(comboText);
// Coin growth display
var growthText = new Text2("Coin Growth: +" + perTurnCoinGrowth + "/turn", {
size: 28,
fill: 0x1ABC9C
});
growthText.anchor.set(0, 0);
growthText.x = 100;
growthText.y = 440;
LK.gui.topLeft.addChild(growthText);
// Progress bar
var progressBarBg = game.attachAsset('progressBar', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 200
});
var progressBarFill = game.attachAsset('progressFill', {
anchorX: 0,
anchorY: 0,
x: 224,
y: 200
});
// Next turn button
var nextTurnButton = game.attachAsset('nextTurnButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2500
});
var nextTurnText = new Text2("Next Turn", {
size: 44,
fill: 0xFFFFFF
});
nextTurnText.anchor.set(0.5, 0.5);
nextTurnText.x = 1024;
nextTurnText.y = 2500;
game.addChild(nextTurnText);
function applyNegativeEffect(negativeEffect) {
LK.getSound('negativeEffect').play();
switch (negativeEffect) {
case "taxCoins":
var coinsLost = Math.floor(coins * 0.3);
coins = Math.max(0, coins - coinsLost);
break;
case "drainPoints":
var pointsLost = Math.floor(points * 0.25);
points = Math.max(0, points - pointsLost);
break;
case "stealCoins":
coins = Math.max(0, coins - 15);
break;
case "reduceGrowth":
perTurnCoinGrowth = Math.max(0, perTurnCoinGrowth - 2);
break;
case "breakCombo":
comboCards = [];
comboMultiplier = 1;
break;
}
}
function applyCardAbility(cardData, basePoints) {
var bonusPoints = 0;
switch (cardData.ability) {
case "nextCardMultiplier":
// This will be handled when the next card is purchased
return basePoints;
case "costReduction":
nextCardCostReduction = Math.floor(cardData.cost * 0.5);
return basePoints;
case "economySynergy":
bonusPoints = (purchasedCardTypes["economy"] || 0) * 3;
return basePoints + bonusPoints;
case "powerSynergy":
bonusPoints = (purchasedCardTypes["power"] || 0) * 5;
return basePoints + bonusPoints;
case "luckySynergy":
bonusPoints = (purchasedCardTypes["luck"] || 0) * 1;
return basePoints + bonusPoints;
case "typeBonus":
var uniqueTypes = Object.keys(purchasedCardTypes).length;
bonusPoints = uniqueTypes * 2;
return basePoints + bonusPoints;
case "coinBonus":
coins += 2;
return basePoints;
case "doublePoints":
points = points * 2;
return 0;
case "chainMultiplier":
var totalCards = 0;
for (var type in purchasedCardTypes) {
totalCards += purchasedCardTypes[type];
}
bonusPoints = Math.floor(totalCards * 0.1 * basePoints);
return basePoints + bonusPoints;
case "compoundGrowth":
bonusPoints = Math.floor(points * 0.1);
return basePoints + bonusPoints;
case "universalSynergy":
var totalCards = 0;
for (var type in purchasedCardTypes) {
totalCards += purchasedCardTypes[type];
}
bonusPoints = totalCards;
return basePoints + bonusPoints;
case "megaCoinBonus":
// Add permanent income bonus
if (!permanentCoinBonus) permanentCoinBonus = 0;
permanentCoinBonus += 5;
return basePoints;
case "tripleMultiplier":
if (!globalPointMultiplier) globalPointMultiplier = 1;
globalPointMultiplier *= 3;
return basePoints;
case "easierCheckpoint":
requiredPoints = Math.floor(requiredPoints * 0.5);
return basePoints;
case "coinRefund":
coins += Math.floor(cardData.cost * 0.5);
return basePoints;
case "skipCheckpoint":
// Skip next checkpoint requirement
skipNextCheckpoint = true;
return basePoints;
case "comboStarter":
comboCards = [cardData];
comboMultiplier = 1.2;
return basePoints;
case "comboBuilder":
if (comboCards.length > 0 && comboCards.length < maxComboSize) {
comboCards.push(cardData);
comboMultiplier += 0.3;
bonusPoints = Math.floor(basePoints * (comboMultiplier - 1));
return basePoints + bonusPoints;
} else {
return basePoints;
}
case "comboMaster":
if (comboCards.length >= maxComboSize) {
bonusPoints = Math.floor(basePoints * 0.5);
LK.getSound('comboComplete').play();
comboCards = [];
comboMultiplier = 1;
return basePoints + bonusPoints;
} else {
return basePoints;
}
case "comboEconomy":
var comboCardCount = 0;
for (var type in purchasedCardTypes) {
if (type === "combo") {
comboCardCount = purchasedCardTypes[type];
break;
}
}
perTurnCoinGrowth += comboCardCount * 2;
return basePoints;
case "comboTriple":
comboMultiplier *= 3;
return basePoints;
case "infiniteCombo":
maxComboSize = 999;
comboMultiplier *= 5;
return basePoints;
// Don't add base points since we doubled existing
default:
return basePoints;
}
}
function generateRandomCard() {
// 20% chance to generate a negative card from checkpoint 2 onwards
if (checkpoint >= 2 && Math.random() < 0.2) {
var template = negativeCardTemplates[Math.floor(Math.random() * negativeCardTemplates.length)];
var scaleFactor = 1 + (checkpoint - 1) * 0.15;
return {
name: template.name,
description: template.description,
points: template.points,
cost: Math.floor(template.cost * scaleFactor),
type: template.type,
negativeEffect: template.negativeEffect
};
}
// Get available card templates based on current checkpoint
var availableTemplates = [];
for (var level = 1; level <= Math.min(checkpoint, 5); level++) {
if (cardTemplatesByLevel[level]) {
availableTemplates = availableTemplates.concat(cardTemplatesByLevel[level]);
}
}
// Fallback to level 1 cards if no templates available
if (availableTemplates.length === 0) {
availableTemplates = cardTemplatesByLevel[1] || [];
}
// Higher checkpoints have better chance of getting advanced cards
var template;
if (checkpoint >= 3 && Math.random() < 0.6) {
// 60% chance for advanced cards in checkpoint 3+
var advancedTemplates = [];
for (var level = Math.max(2, checkpoint - 1); level <= Math.min(checkpoint, 5); level++) {
if (cardTemplatesByLevel[level]) {
advancedTemplates = advancedTemplates.concat(cardTemplatesByLevel[level]);
}
}
if (advancedTemplates.length > 0) {
template = advancedTemplates[Math.floor(Math.random() * advancedTemplates.length)];
} else {
template = availableTemplates[Math.floor(Math.random() * availableTemplates.length)];
}
} else {
template = availableTemplates[Math.floor(Math.random() * availableTemplates.length)];
}
// Final safety check - use first available template if still undefined
if (!template && availableTemplates.length > 0) {
template = availableTemplates[0];
}
// If still no template, create a default one
if (!template) {
template = {
name: "Emergency Card",
description: "Basic fallback",
points: 3,
cost: 2,
type: "basic"
};
}
var scaleFactor = 1 + (checkpoint - 1) * 0.2;
return {
name: template.name,
description: template.description,
points: Math.floor(template.points * scaleFactor),
cost: Math.floor(template.cost * scaleFactor),
type: template.type,
ability: template.ability
};
}
function generateCards() {
// Clear existing cards
for (var i = 0; i < currentCards.length; i++) {
currentCards[i].destroy();
}
currentCards = [];
// Clear negative cards tracking for new turn
negativeCards = [];
// Generate 5 new cards in two vertical columns with doubled size
var cardPositions = [{
x: 700,
y: 600
}, {
x: 1348,
y: 600
}, {
x: 700,
y: 1200
}, {
x: 1348,
y: 1200
}, {
x: 700,
y: 1800
}];
for (var i = 0; i < 5; i++) {
var cardData = generateRandomCard();
var card = new Card(cardData);
card.x = cardPositions[i].x;
card.y = cardPositions[i].y;
currentCards.push(card);
game.addChild(card);
// Track negative cards
if (cardData.type === "negative") {
negativeCards.push(card);
}
}
updateCardsVisual();
}
function updateCardsVisual() {
for (var i = 0; i < currentCards.length; i++) {
currentCards[i].updateVisual();
}
}
function updateUI() {
coinsText.setText("Coins: " + coins);
pointsText.setText("Points: " + points);
turnText.setText("Turn: " + turn);
requiredText.setText("Need: " + requiredPoints + " pts");
comboText.setText("Combo: " + comboCards.length + "/" + maxComboSize + " (x" + comboMultiplier.toFixed(1) + ")");
growthText.setText("Coin Growth: +" + perTurnCoinGrowth + "/turn");
// Update progress bar
var progress = Math.min(points / requiredPoints, 1);
progressBarFill.width = 1600 * progress;
if (points >= requiredPoints) {
progressBarFill.tint = 0x2ecc71;
} else {
progressBarFill.tint = 0xe74c3c;
}
updateCardsVisual();
}
function nextTurn() {
if (gamePhase !== 'playing') return;
// Apply negative card effects before ending turn
for (var i = 0; i < negativeCards.length; i++) {
var negativeCard = negativeCards[i];
if (!negativeCard.purchased && negativeCard.cardData.negativeEffect) {
applyNegativeEffect(negativeCard.cardData.negativeEffect);
// Flash screen red briefly to show negative effect
LK.effects.flashScreen(0xe74c3c, 300);
}
}
turn++;
LK.getSound('turnAdvance').play();
// Calculate total coin income: base + checkpoint bonus + permanent bonus + per-turn growth
var baseCoinIncome = 3 + Math.floor(checkpoint / 2);
var totalCoinIncome = baseCoinIncome + permanentCoinBonus + perTurnCoinGrowth;
coins += totalCoinIncome;
// Increase per-turn coin growth by 1 each turn
perTurnCoinGrowth += 1;
// Check for checkpoint every 5 turns
if (turn % 5 === 1 && turn > 1) {
checkCheckpoint();
} else {
generateCards();
updateUI();
}
}
function startGame() {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
// Stop menu music and start gameplay music
LK.stopMusic();
LK.playMusic('gameplayMusic', {
fade: {
start: 0,
end: 0.4,
duration: 1000
}
});
// Reset game state
coins = 10;
points = 0;
turn = 1;
checkpoint = 1;
requiredPoints = 20;
currentCards = [];
gamePhase = 'playing';
purchasedCardTypes = {};
nextCardCostReduction = 0;
permanentCoinBonus = 0;
globalPointMultiplier = 1;
skipNextCheckpoint = false;
comboMultiplier = 1;
comboCards = [];
maxComboSize = 3;
perTurnCoinGrowth = 0;
negativeCards = [];
// Show game UI elements
coinsText.visible = true;
pointsText.visible = true;
turnText.visible = true;
requiredText.visible = true;
comboText.visible = true;
growthText.visible = true;
progressBarBg.visible = true;
progressBarFill.visible = true;
nextTurnButton.visible = true;
nextTurnText.visible = true;
// Start the game
generateCards();
updateUI();
}
function checkCheckpoint() {
if (points >= requiredPoints) {
// Pass checkpoint
checkpoint++;
requiredPoints = Math.floor(requiredPoints * 1.8);
// Points are now maintained between checkpoints
LK.getSound('checkpoint').play();
// Flash screen green
LK.effects.flashScreen(0x2ecc71, 1000);
generateCards();
updateUI();
LK.setScore(checkpoint - 1);
} else {
// Fail checkpoint - game over
gamePhase = 'gameOver';
LK.getSound('gameOver').play();
LK.stopMusic();
LK.playMusic('gameOverMusic', {
fade: {
start: 0,
end: 0.6,
duration: 800
}
});
LK.effects.flashScreen(0xe74c3c, 1500);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
}
// Event handlers
nextTurnButton.down = function (x, y, obj) {
nextTurn();
};
game.down = function (x, y, obj) {
if (gamePhase !== 'playing') return;
// Use direct x, y coordinates instead of trying to convert positions
// Check if clicked on next turn button
if (x >= nextTurnButton.x - 200 && x <= nextTurnButton.x + 200 && y >= nextTurnButton.y - 40 && y <= nextTurnButton.y + 40) {
nextTurn();
}
};
// Hide UI elements initially
coinsText.visible = false;
pointsText.visible = false;
turnText.visible = false;
requiredText.visible = false;
comboText.visible = false;
growthText.visible = false;
progressBarBg.visible = false;
progressBarFill.visible = false;
nextTurnButton.visible = false;
nextTurnText.visible = false;
// Show main menu
mainMenu = new MainMenu();
game.addChild(mainMenu);
// Start menu music
LK.playMusic('menuMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1500
}
});