User prompt
Añade la música y el sonido al juego
User prompt
Crea música apropiada para el menú principal, la partida, el game over y efectos de sonido
User prompt
Crea un menú principal
User prompt
Haz cartas negativas, si el jugador pasa el turno las cartas negativas de ese turno se activan, para desactivar las cartas negativas hay que comprarlas
User prompt
Elimina la carta "God mode" Ya que es demasiado buena
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'name')' in or related to this line: 'return {' Line Number: 636
User prompt
Haz que por cada turno el jugador obtenga más monedas por cada turno. Crea una nueva mecánica para poder hacer combos de cartas y haz cartas nuevas relacionadas a esta nueva mecánica
User prompt
Haz que cada 5 turnos en vez de perder los puntos el jugador los mantenga y además cada 5 turnos aparezcan mejores cartas (Haz más cartas con mejoras más complejas)
User prompt
Haz que haya más cartas con diferentes mecánicas (Ejemplos: multiplicar, reducir coste de futuras cartas, sumar puntos cuantas más cartas de un tipo específico hayan sido compradas, etc.)
User prompt
Haz las cartas el doble de grande repartidas en dos columnas verticales
User prompt
Haz las cartas más pequeñas y separadas entre ellas, y haz que la habilidad de las cartas se vea, porque el botón de comprar la carta tapa la habilidad
User prompt
En vez de que las cartas estén en una fila horizontal, repártelas por toda la pantalla y hazlas el tripe de grande
User prompt
Haz que las cartas y los textos sean más grandes para que se lean mejor
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var localPos = game.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 347
Code edit (1 edits merged)
Please save this source code
User prompt
Card Collector: Score Rush
Initial prompt
Este juego trata de conseguir los mayores puntos posibles, el juego se va a dividir en turnos, en cada turno el jugador va consiguiendo monedas, al comienzo del turno van a aparecer 5 cartas diferentes aleatorias, cada carta da al jugador puntos de formas diferentes y cada una cuesta monedas dependiendo de lo buena que sea, cada 5 turnos el juego reclama una cantidad cierta cantidad de puntos, si el jugador no tiene esa cantidad de puntos el jugador pierde.
/**** * 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.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; }); /**** * 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 = 'playing'; // 'playing', 'checkpoint', 'gameOver' // 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) { 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); 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++; // 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 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.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) { // 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(); } }; // Initialize the game generateCards(); updateUI();
===================================================================
--- original.js
+++ change.js
@@ -62,25 +62,36 @@
self.costText.y = 120;
self.addChild(self.costText);
self.updateVisual = function () {
if (self.purchased) {
- background.tint = 0x27ae60;
+ 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 (nextCardCostReduction > 0) {
- self.costText.setText("Buy: " + actualCost + " coins (was " + self.cardData.cost + ")");
+ 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 {
- self.costText.setText("Buy: " + actualCost + " coins");
+ 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;
+ }
}
- if (coins < actualCost) {
- background.tint = 0x7f8c8d;
- self.buyButton.tint = 0x7f8c8d;
- } else {
- background.tint = 0x2c3e50;
- self.buyButton.tint = 0x27ae60;
- }
}
};
self.down = function (x, y, obj) {
if (!self.purchased && coins >= self.cardData.cost) {
@@ -157,8 +168,46 @@
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
@@ -466,8 +515,30 @@
nextTurnText.anchor.set(0.5, 0.5);
nextTurnText.x = 1024;
nextTurnText.y = 2500;
game.addChild(nextTurnText);
+function applyNegativeEffect(negativeEffect) {
+ 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":
@@ -575,8 +646,21 @@
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]) {
@@ -634,8 +718,10 @@
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
@@ -658,8 +744,12 @@
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() {
@@ -685,8 +775,17 @@
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++;
// Calculate total coin income: base + checkpoint bonus + permanent bonus + per-turn growth
var baseCoinIncome = 3 + Math.floor(checkpoint / 2);
var totalCoinIncome = baseCoinIncome + permanentCoinBonus + perTurnCoinGrowth;