User prompt
yıldız mekaniğini magic kart oyunundaki sisteme benzer uyarla
User prompt
hp yi 100 e çıkar
User prompt
end turn mekaniğini basılabilir animasyonlu tuş olarak düzenle basınça ses çıksın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
canavar isimlerini, biraz yukarı kaydır
User prompt
canavar isimlerini, biraz yukarı kaydır
User prompt
canavar isimlerini daha okunur yap
User prompt
52 karttaki canavarlara ayrı ayır canavar isimleri ver hiç biri bir birine benzemesin
User prompt
atk ve def rakamlarını daha okunur yap bu rakamların yanındaki mavi işaretleri kaldır
User prompt
kartları barok tarzı çerçeveye al
User prompt
kartların üzerindeki yıldızlarıbiraz sola kaydır ama kartların dışına çıkmasısın ona göre ayarla
User prompt
52 kartın renklerini ayrı ayrı yap hepsi farklrklı 52 renk olsun
User prompt
tüm 52 kartın üzerindeki canavar resimlerini kaldır
User prompt
kartların üzerine yerleştirdiğin canavar görsellerini kaldır
User prompt
daha önce oluşturduğum canavar görsellerini 22,25,26,52 numaralı karların üzerine yerleştir
User prompt
atc def yazılarını ve yanlarında yazan rakamları az büyüt okunmuyolar
User prompt
yazı sığmadı sığacak şekilde düzenle
User prompt
kırmızı rakamların soluna atc,mavi rakamların soluna def yazısı ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kartların üzerindeki def yazısındaki rakamlarda alev görselini atk yazan sayının üzerine al def sayısına mavi kalkan ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
October Oct. 1 to 5 will appear on these 52 monster cards Add stars to the draw randomly in each round the next player will accumulate 1 star how many stars the player has in his hand he can play this card add card burning mechanics the burned card will earn 2 stars let the card be burned. add stars to the card will appear on 1 to 5 monster cards randomly add 1 star to the next player in each round, how many stars the player can play this card ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
bu verdiğim kodu oyuna dönştür
User prompt
add 4 generated monster images to 4 cards separately Oct.
User prompt
the game is not being played, make it playable
User prompt
add click animation to monster cards Oct. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
let the monster come to the playing field with the jump animation when the cards are clicked ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Card class: visual and logical representation of a monster card var Card = Container.expand(function () { var self = Container.call(this); // Card properties self.cardId = null; self.cardData = null; self.isInHand = false; self.isPlayable = false; self.isSelected = false; self.owner = null; // "player" or "opponent" // Card visuals var cardWidth = 260; var cardHeight = 380; // Card background (use a generic box for all cards) var cardBg = self.attachAsset('monsters', { width: cardWidth, height: cardHeight, color: 0xffffff, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); // Baroque frame overlay (always on top of cardBg, but below all text/icons) var baroqueFrame = self.attachAsset('baroque_frame', { anchorX: 0.5, anchorY: 0.5, width: 300, height: 420, x: 0, y: 0 }); self.addChild(baroqueFrame); baroqueFrame.zIndex = 10; // ensure it's above cardBg, but below text/icons // Monster illustration: (removed for all cards, no monsterArt shown) var monsterArt = null; // Card name var nameTxt = new Text2('', { size: 48, fill: 0x222222, font: "Impact,'Arial Black',Tahoma", // bold font for readability stroke: "#fff", strokeThickness: 6 }); nameTxt.anchor.set(0.5, 0); // Move name higher (from -0.45 to -0.54 of cardHeight) nameTxt.y = -cardHeight * 0.54; self.addChild(nameTxt); // Star cost display var starTxt = new Text2('', { size: 38, fill: 0xffd700 }); starTxt.anchor.set(0, 0); // Anchor left edge, top starTxt.x = -cardWidth * 0.44; // Move left, but keep inside card (cardWidth * 0.5 = edge) starTxt.y = -cardHeight * 0.36; self.addChild(starTxt); // Burn button (shows only if burnable) var burnBtn = new Text2("🔥", { size: 48, fill: 0xff6600 }); burnBtn.anchor.set(0.5, 0.5); burnBtn.x = cardWidth * 0.36; burnBtn.y = cardHeight * 0.36; burnBtn.visible = false; self.addChild(burnBtn); // Burn button logic burnBtn.down = function (x, y, obj) { if (self.isInHand && self.owner === "player") { burnCard(self); } }; // Attack/Defense // ATK label var atkLabel = new Text2('ATK', { size: 32, fill: 0xd83318 }); atkLabel.anchor.set(1, 0.5); atkLabel.x = -30; atkLabel.y = cardHeight * 0.32 - 24 + 10; self.addChild(atkLabel); var atkTxt = new Text2('', { size: 54, // larger for readability fill: 0xd83318, font: "Impact,'Arial Black',Tahoma", // bold font stroke: "#fff", strokeThickness: 6 }); atkTxt.anchor.set(0, 0.5); atkTxt.y = cardHeight * 0.32 - 24 + 10; atkTxt.x = 18; // move right to center under ATK label self.addChild(atkTxt); // DEF label var defLabel = new Text2('DEF', { size: 32, fill: 0x1877f2 }); defLabel.anchor.set(1, 0.5); defLabel.x = -30; defLabel.y = cardHeight * 0.32 + 24 + 10; self.addChild(defLabel); var defTxt = new Text2('', { size: 54, // larger for readability fill: 0x1877f2, font: "Impact,'Arial Black',Tahoma", // bold font stroke: "#fff", strokeThickness: 6 }); defTxt.anchor.set(0, 0.5); defTxt.y = cardHeight * 0.32 + 24 + 10; defTxt.x = 18; // move right to center under DEF label self.addChild(defTxt); // (Removed flameIcon and shieldIcon for ATK/DEF) // Element var elementTxt = new Text2('', { size: 28, fill: 0x666666 }); elementTxt.anchor.set(0.5, 0); elementTxt.y = -cardHeight * 0.32; self.addChild(elementTxt); // Ability var abilityTxt = new Text2('', { size: 24, fill: 0x444444 }); abilityTxt.anchor.set(0.5, 0); abilityTxt.y = cardHeight * 0.12; self.addChild(abilityTxt); // Set card data self.setCard = function (cardId, owner) { self.cardId = cardId; self.cardData = CARD_DATA[cardId]; self.owner = owner; // Assign a random star cost (1-5) if not already set if (typeof self.cardData.starCost !== "number") { // For the first 5 cards, assign random star cost 1-5, others default to 1 if (self.cardId >= 0 && self.cardId <= 4) { self.cardData.starCost = 1 + Math.floor(Math.random() * 5); } else { self.cardData.starCost = 1; } } self.starCost = self.cardData.starCost; // Set visuals // Assign unique color for each card cardBg.color = self.cardData.color || 0xffffff; // Remove previous monsterArt if present (no-op, monsterArt is always null) nameTxt.setText(self.cardData.name); // Show ATK and DEF values separately, icons are already present atkTxt.setText(self.cardData.attack + ""); defTxt.setText(self.cardData.defense + ""); elementTxt.setText(self.cardData.element); abilityTxt.setText(self.cardData.ability); // Show star cost starTxt.setText("★ " + self.starCost); // For MVP, no evolution/fusion visuals }; // Highlight if playable/selected self.setPlayable = function (playable) { self.isPlayable = playable; // Only playable if player has enough stars var canPlay = playable; if (self.owner === "player" && typeof self.starCost === "number") { canPlay = playable && playerStars >= self.starCost; } cardBg.color = canPlay ? 0xffe066 : 0xffffff; // Show burn button if in hand and owned by player burnBtn.visible = self.isInHand && self.owner === "player"; }; self.setSelected = function (selected) { self.isSelected = selected; cardBg.color = selected ? 0x66ccff : self.isPlayable ? 0xffe066 : 0xffffff; }; // Animate card (e.g. on play) self.animatePlay = function (_onFinish) { // Save original y for jump landing var originalY = self.y; // Jump up tween(self, { y: originalY - 120, scaleX: 1.15, scaleY: 1.15 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { // Fall down and squash tween(self, { y: originalY, scaleX: 1.08, scaleY: 0.95 }, { duration: 120, easing: tween.cubicIn, onFinish: function onFinish() { // Restore scale tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.linear, onFinish: _onFinish }); } }); } }); }; // For MVP, no drag/drop, just tap to play self.down = function (x, y, obj) { if (self.isPlayable && self.owner === "player") { // Click animation: quick scale up and back tween(self, { scaleX: 1.18, scaleY: 1.18 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicIn, onFinish: function onFinish() { playCard(self); } }); } }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x22222a }); /**** * Game Code ****/ // --- Mana/Star System State (Magic-style) --- // Each player has a "maximum stars" (like max mana) and "current stars" (like available mana this turn) var playerMaxStars = 0; var playerStars = 0; var opponentMaxStars = 0; var opponentStars = 0; // Tween plugin for card animations (e.g. draw, play, evolve) // Card Data: 52 unique monsters with stats, element, and ability // For MVP, we'll define a small sample and generate the rest as placeholders // Pyro Drake // Aqua Serpent // Terra Golem // Zephyr Sprite var CARD_DATA = [{ id: 0, name: "Pyro Drake", element: "Fire", attack: 7, defense: 4, ability: "Scorch: Deal 2 extra damage on summon.", color: 0xff5733 }, { id: 1, name: "Aqua Serpent", element: "Water", attack: 5, defense: 6, ability: "Tidecall: Heal 2 defense on play.", color: 0x3399ff }, { id: 2, name: "Terra Golem", element: "Earth", attack: 4, defense: 8, ability: "Fortify: Gain +2 defense if not attacked this turn.", color: 0x7cfc00 }, { id: 3, name: "Zephyr Sprite", element: "Air", attack: 6, defense: 3, ability: "Gust: Can attack twice if opponent has no Air monsters.", color: 0xfafad2 }, { id: 4, name: "Shadow Wraith", element: "Dark", attack: 8, defense: 2, ability: "Ambush: Ignores defense on first attack.", color: 0x222244 }]; // Generate 52 visually distinct colors using HSL to RGB conversion function hslToHex(h, s, l) { // h: 0-360, s: 0-1, l: 0-1 var c = (1 - Math.abs(2 * l - 1)) * s; var x = c * (1 - Math.abs(h / 60 % 2 - 1)); var m = l - c / 2; var r1, g1, b1; if (h < 60) { r1 = c; g1 = x; b1 = 0; } else if (h < 120) { r1 = x; g1 = c; b1 = 0; } else if (h < 180) { r1 = 0; g1 = c; b1 = x; } else if (h < 240) { r1 = 0; g1 = x; b1 = c; } else if (h < 300) { r1 = x; g1 = 0; b1 = c; } else { r1 = c; g1 = 0; b1 = x; } var r = Math.round((r1 + m) * 255); var g = Math.round((g1 + m) * 255); var b = Math.round((b1 + m) * 255); return (r << 16) + (g << 8) + b; } // Precompute 52 unique colors var CARD_COLORS = []; for (var ci = 0; ci < 52; ci++) { var hue = ci * 360 / 52 % 360; var color = hslToHex(hue, 0.65, 0.60); CARD_COLORS.push(color); } // 52 unique monster names, all different and fantasy-themed var MONSTER_NAMES = ["Pyro Drake", "Aqua Serpent", "Terra Golem", "Zephyr Sprite", "Shadow Wraith", "Solar Griffin", "Frost Lynx", "Thunder Roc", "Venom Hydra", "Crystal Beetle", "Blaze Minotaur", "Mist Kitsune", "Iron Basilisk", "Storm Djinn", "Nightmare Mare", "Sunflare Lion", "Glacier Yeti", "Volt Mantis", "Toxic Moth", "Quartz Turtle", "Ember Jackal", "Rain Nymph", "Mud Troll", "Gale Harpy", "Phantom Fox", "Radiant Stag", "Snow Owl", "Sparkle Hare", "Swamp Croc", "Gemstone Ant", "Wildfire Wolf", "Bubble Slime", "Root Dryad", "Wind Imp", "Specter Bat", "Corona Tiger", "Polar Bear", "Plasma Jelly", "Bog Lizard", "Amber Spider", "Char Salamander", "Cascade Crab", "Boulder Ram", "Cyclone Hawk", "Shade Panther", "Star Unicorn", "Ice Ferret", "Magneton", "Fungal Gnome", "Opal Cobra", "Scorch Falcon", "Abyssal Eel"]; // Fill up to 52 cards with unique monster names and unique color for (var i = CARD_DATA.length; i < 52; i++) { CARD_DATA.push({ id: i, name: MONSTER_NAMES[i], element: ["Fire", "Water", "Earth", "Air", "Dark", "Light"][i % 6], attack: 3 + i % 7, defense: 3 + i * 2 % 7, ability: "No special ability.", color: CARD_COLORS[i] }); } var playerDeck = []; var opponentDeck = []; var playerHand = []; var opponentHand = []; var playerField = []; var opponentField = []; var playerGrave = []; var opponentGrave = []; var playerHP = 100; var opponentHP = 100; var turn = "player"; // "player" or "opponent" var phase = "draw"; // "draw", "main", "battle", "end" var selectedCard = null; var handY = 2732 - 420; var fieldY = 2732 - 900; var oppHandY = 420; var oppFieldY = 900; var handCardSpacing = 320; var fieldCardSpacing = 400; var maxHand = 5; var maxField = 3; var gameActive = true; // --- GUI Elements --- var playerHpTxt = new Text2("HP: 20", { size: 60, fill: 0xFF4444 }); playerHpTxt.anchor.set(0, 0.5); LK.gui.left.addChild(playerHpTxt); var playerStarTxt = new Text2("★: 1", { size: 60, fill: 0xffd700 }); playerStarTxt.anchor.set(0, 0.5); playerStarTxt.y = 70; LK.gui.left.addChild(playerStarTxt); var opponentHpTxt = new Text2("HP: 20", { size: 60, fill: 0x44AAFF }); opponentHpTxt.anchor.set(1, 0.5); LK.gui.right.addChild(opponentHpTxt); var opponentStarTxt = new Text2("★: 1", { size: 60, fill: 0xffd700 }); opponentStarTxt.anchor.set(1, 0.5); opponentStarTxt.y = 70; LK.gui.right.addChild(opponentStarTxt); var turnTxt = new Text2("Your Turn", { size: 60, fill: "#fff" }); turnTxt.anchor.set(0.5, 0); LK.gui.top.addChild(turnTxt); // --- Utility Functions --- 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; } } function drawCard(deck, hand, owner) { if (deck.length === 0 || hand.length >= maxHand) return null; var cardId = deck.pop(); var card = new Card(); card.setCard(cardId, owner); card.isInHand = true; hand.push(card); return card; } function updateHandPositions() { // Player hand for (var i = 0; i < playerHand.length; i++) { var card = playerHand[i]; card.x = 2048 / 2 + (i - (playerHand.length - 1) / 2) * handCardSpacing; card.y = handY; card.scaleX = card.scaleY = 1; // Only playable if enough stars card.setPlayable(turn === "player" && phase === "main" && playerField.length < maxField); card.setSelected(selectedCard === card); } // Opponent hand (hidden) for (var i = 0; i < opponentHand.length; i++) { var card = opponentHand[i]; card.x = 2048 / 2 + (i - (opponentHand.length - 1) / 2) * handCardSpacing; card.y = oppHandY; card.scaleX = card.scaleY = 1; card.setPlayable(false); card.setSelected(false); } } function updateFieldPositions() { // Player field for (var i = 0; i < playerField.length; i++) { var card = playerField[i]; card.x = 2048 / 2 + (i - (playerField.length - 1) / 2) * fieldCardSpacing; card.y = fieldY; card.scaleX = card.scaleY = 1.1; card.setPlayable(false); card.setSelected(false); } // Opponent field for (var i = 0; i < opponentField.length; i++) { var card = opponentField[i]; card.x = 2048 / 2 + (i - (opponentField.length - 1) / 2) * fieldCardSpacing; card.y = oppFieldY + 400; card.scaleX = card.scaleY = 1.1; card.setPlayable(false); card.setSelected(false); } } function updateHpText() { playerHpTxt.setText("HP: " + playerHP); opponentHpTxt.setText("HP: " + opponentHP); // Show current/max stars, Magic-style playerStarTxt.setText("★: " + playerStars + "/" + playerMaxStars); opponentStarTxt.setText("★: " + opponentStars + "/" + opponentMaxStars); } function updateTurnText() { turnTxt.setText(turn === "player" ? "Your Turn" : "Opponent Turn"); } // --- Game Setup --- function setupGame() { // Reset state playerDeck = []; opponentDeck = []; playerHand = []; opponentHand = []; playerField = []; opponentField = []; playerGrave = []; opponentGrave = []; playerHP = 100; opponentHP = 100; // Magic-style: start with 0 max stars, will increment at start of turn playerMaxStars = 0; playerStars = 0; opponentMaxStars = 0; opponentStars = 0; turn = "player"; phase = "draw"; selectedCard = null; gameActive = true; // Remove all children from game for (var i = game.children.length - 1; i >= 0; i--) { game.children[i].destroy(); } // Build decks (for MVP, both get all 52 cards, shuffled) for (var i = 0; i < 52; i++) { playerDeck.push(i); opponentDeck.push(i); } shuffleDeck(playerDeck); shuffleDeck(opponentDeck); // Draw starting hands (5 cards) for (var i = 0; i < maxHand; i++) { var card = drawCard(playerDeck, playerHand, "player"); if (card) game.addChild(card); var oppCard = drawCard(opponentDeck, opponentHand, "opponent"); if (oppCard) game.addChild(oppCard); } // Add all cards in hand to the game scene for interaction for (var i = 0; i < playerHand.length; i++) { if (!game.children.includes(playerHand[i])) { game.addChild(playerHand[i]); } } for (var i = 0; i < opponentHand.length; i++) { if (!game.children.includes(opponentHand[i])) { game.addChild(opponentHand[i]); } } updateHandPositions(); updateFieldPositions(); updateHpText(); updateTurnText(); } setupGame(); // --- Card Play Logic --- function burnCard(card) { if (!gameActive) return; if (!card.isInHand || card.owner !== "player") return; // Remove from hand var idx = playerHand.indexOf(card); if (idx !== -1) playerHand.splice(idx, 1); // Add to grave playerGrave.push(card); card.isInHand = false; // Animate burn (fade out and destroy) tween(card, { alpha: 0, scaleX: 1.3, scaleY: 1.3 }, { duration: 350, easing: tween.cubicIn, onFinish: function onFinish() { card.destroy(); } }); // Gain 1 max star (like Magic: play a land) // Only increase max, refill current to max at next turn playerMaxStars += 1; updateHpText(); updateHandPositions(); } function playCard(card) { if (!gameActive) return; if (turn !== "player" || phase !== "main") return; if (!card.isInHand || playerField.length >= maxField) return; if (typeof card.starCost === "number" && playerStars < card.starCost) return; // Not enough stars // Remove from hand var idx = playerHand.indexOf(card); if (idx !== -1) playerHand.splice(idx, 1); // Deduct stars from current (not max) if (typeof card.starCost === "number") { playerStars -= card.starCost; if (playerStars < 0) playerStars = 0; updateHpText(); } // Add to field card.isInHand = false; playerField.push(card); // Animate play card.animatePlay(function () { updateHandPositions(); updateFieldPositions(); // Ability triggers if (card.cardData.ability.indexOf("Scorch") !== -1) { // Pyro Drake: deal 2 to opponent HP opponentHP -= 2; LK.effects.flashObject(opponentHpTxt, 0xff0000, 500); updateHpText(); } if (card.cardData.ability.indexOf("Tidecall") !== -1) { // Aqua Serpent: heal 2 defense (for MVP, just flash) LK.effects.flashObject(card, 0x3399ff, 500); } // End main phase if field is full if (playerField.length >= maxField) { phase = "battle"; selectedCard = null; updateHandPositions(); updateFieldPositions(); } }); } // --- Battle Phase Logic --- function playerBattlePhase() { // For MVP: Each player monster attacks opponent monsters in order, or directly if none for (var i = 0; i < playerField.length; i++) { var attacker = playerField[i]; var defender = opponentField[i] || null; if (defender) { // Battle: ATK vs DEF var damage = attacker.cardData.attack - defender.cardData.defense; if (attacker.cardData.ability.indexOf("Ambush") !== -1) { // Shadow Wraith: ignore defense damage = attacker.cardData.attack; } if (damage > 0) { opponentHP -= damage; LK.effects.flashObject(opponentHpTxt, 0xff0000, 500); } // Remove defender if damage >= defense if (attacker.cardData.attack >= defender.cardData.defense) { var idx = opponentField.indexOf(defender); if (idx !== -1) { opponentField.splice(idx, 1); defender.destroy(); } } } else { // Direct attack opponentHP -= attacker.cardData.attack; LK.effects.flashObject(opponentHpTxt, 0xff0000, 500); } } updateHpText(); checkGameEnd(); } function opponentBattlePhase() { for (var i = 0; i < opponentField.length; i++) { var attacker = opponentField[i]; var defender = playerField[i] || null; if (defender) { var damage = attacker.cardData.attack - defender.cardData.defense; if (attacker.cardData.ability.indexOf("Ambush") !== -1) { damage = attacker.cardData.attack; } if (damage > 0) { playerHP -= damage; LK.effects.flashObject(playerHpTxt, 0xff0000, 500); } if (attacker.cardData.attack >= defender.cardData.defense) { var idx = playerField.indexOf(defender); if (idx !== -1) { playerField.splice(idx, 1); defender.destroy(); } } } else { playerHP -= attacker.cardData.attack; LK.effects.flashObject(playerHpTxt, 0xff0000, 500); } } updateHpText(); checkGameEnd(); } // --- Turn/Phase Management --- function nextPhase() { if (!gameActive) return; if (turn === "player") { if (phase === "draw") { // Draw phase (Magic-style: increment max, refill current) playerMaxStars += 1; playerStars = playerMaxStars; updateHpText(); var card = drawCard(playerDeck, playerHand, "player"); if (card) game.addChild(card); phase = "main"; updateHandPositions(); updateFieldPositions(); } else if (phase === "main") { // End main phase, go to battle phase = "battle"; selectedCard = null; updateHandPositions(); updateFieldPositions(); // Battle playerBattlePhase(); phase = "end"; nextPhase(); } else if (phase === "end") { // End turn turn = "opponent"; phase = "draw"; updateTurnText(); LK.setTimeout(opponentTurn, 900); } } else { // Opponent phases if (phase === "draw") { // Draw phase (Magic-style: increment max, refill current) opponentMaxStars += 1; opponentStars = opponentMaxStars; updateHpText(); var card = drawCard(opponentDeck, opponentHand, "opponent"); if (card) game.addChild(card); phase = "main"; updateHandPositions(); updateFieldPositions(); LK.setTimeout(opponentTurn, 700); } else if (phase === "main") { // Play first playable card if field not full if (opponentField.length < maxField && opponentHand.length > 0) { // Find first card opponent can afford var card = null; for (var i = 0; i < opponentHand.length; i++) { if (typeof opponentHand[i].starCost === "number" && opponentStars >= opponentHand[i].starCost) { card = opponentHand[i]; break; } } if (card) { var idx = opponentHand.indexOf(card); if (idx !== -1) opponentHand.splice(idx, 1); // Deduct stars from current (not max) opponentStars -= card.starCost; if (opponentStars < 0) opponentStars = 0; updateHpText(); card.isInHand = false; opponentField.push(card); card.animatePlay(function () { updateHandPositions(); updateFieldPositions(); LK.setTimeout(opponentTurn, 600); }); // Ability triggers if (card.cardData.ability.indexOf("Scorch") !== -1) { playerHP -= 2; LK.effects.flashObject(playerHpTxt, 0xff0000, 500); updateHpText(); } if (card.cardData.ability.indexOf("Tidecall") !== -1) { LK.effects.flashObject(card, 0x3399ff, 500); } return; } } phase = "battle"; LK.setTimeout(opponentTurn, 600); } else if (phase === "battle") { opponentBattlePhase(); phase = "end"; LK.setTimeout(opponentTurn, 600); } else if (phase === "end") { turn = "player"; phase = "draw"; updateTurnText(); updateHandPositions(); updateFieldPositions(); } } } function opponentTurn() { if (!gameActive) return; if (turn !== "opponent") return; nextPhase(); } // --- Game End --- function checkGameEnd() { if (playerHP <= 0) { LK.effects.flashScreen(0xff0000, 1200); LK.showGameOver(); gameActive = false; } else if (opponentHP <= 0) { LK.effects.flashScreen(0x00ff88, 1200); LK.showYouWin(); gameActive = false; } } // --- Input Handling --- game.down = function (x, y, obj) { if (!gameActive) return; if (turn !== "player" || phase !== "main") return; // Check if a card in hand was tapped var tappedCard = null; for (var i = 0; i < playerHand.length; i++) { var card = playerHand[i]; if (card.containsPoint && card.containsPoint(x, y)) { tappedCard = card; break; } } if (tappedCard && tappedCard.isPlayable) { selectedCard = tappedCard; updateHandPositions(); // Play the card playCard(tappedCard); return; } // Deselect if tap outside hand selectedCard = null; updateHandPositions(); }; game.move = function (x, y, obj) { // No drag for MVP }; game.up = function (x, y, obj) { // No drag for MVP }; // --- End Turn Button --- // Create a container for the button for animation var endTurnBtnContainer = new Container(); endTurnBtnContainer.x = 0; endTurnBtnContainer.y = -40; LK.gui.bottom.addChild(endTurnBtnContainer); // Button background (animated on press) var endTurnBtnBg = LK.getAsset('monsters', { width: 420, height: 120, color: 0x2e8b57, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); endTurnBtnContainer.addChild(endTurnBtnBg); // Button label var endTurnBtn = new Text2("End Turn", { size: 64, fill: "#fff", font: "Impact", stroke: "#222", strokeThickness: 6 }); endTurnBtn.anchor.set(0.5, 0.5); endTurnBtnContainer.addChild(endTurnBtn); // Button press sound (use a built-in sound, e.g. 'shoot' as a placeholder) endTurnBtnContainer.interactive = true; endTurnBtnContainer.buttonMode = true; endTurnBtnContainer.down = function (x, y, obj) { if (!gameActive) return; if (turn === "player" && (phase === "main" || phase === "draw")) { // Animate button press: scale down and up, tint flash tween(endTurnBtnContainer, { scaleX: 0.93, scaleY: 0.93 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(endTurnBtnContainer, { scaleX: 1, scaleY: 1 }, { duration: 90, easing: tween.cubicOut }); } }); tween(endTurnBtnBg, { color: 0x44d17a }, { duration: 80, easing: tween.linear, onFinish: function onFinish() { tween(endTurnBtnBg, { color: 0x2e8b57 }, { duration: 120, easing: tween.linear }); } }); // Play sound LK.getSound('endturn_press').play(); // Advance phase nextPhase(); } }; // --- Game Update Loop --- game.update = function () { // If the game is not active, do nothing if (!gameActive) return; // If it's the player's turn and the phase is "battle", auto-advance to end phase after a short delay if (turn === "player" && phase === "battle") { phase = "end"; nextPhase(); return; } // If it's the opponent's turn, the phase advancement is handled by timeouts in opponentTurn/nextPhase }; // --- Card Asset Initialization (for MVP, only shapes) --- // (No-op: assets are initialized at the top)
===================================================================
--- original.js
+++ change.js
@@ -259,13 +259,14 @@
/****
* Game Code
****/
-// Baroque frame asset (should be a transparent PNG with ornate gold frame, sized to fit card)
-// --- Game State ---
-// --- Star System State ---
-var playerStars = 1;
-var opponentStars = 1;
+// --- Mana/Star System State (Magic-style) ---
+// Each player has a "maximum stars" (like max mana) and "current stars" (like available mana this turn)
+var playerMaxStars = 0;
+var playerStars = 0;
+var opponentMaxStars = 0;
+var opponentStars = 0;
// Tween plugin for card animations (e.g. draw, play, evolve)
// Card Data: 52 unique monsters with stats, element, and ability
// For MVP, we'll define a small sample and generate the rest as placeholders
// Pyro Drake
@@ -487,10 +488,11 @@
}
function updateHpText() {
playerHpTxt.setText("HP: " + playerHP);
opponentHpTxt.setText("HP: " + opponentHP);
- playerStarTxt.setText("★: " + playerStars);
- opponentStarTxt.setText("★: " + opponentStars);
+ // Show current/max stars, Magic-style
+ playerStarTxt.setText("★: " + playerStars + "/" + playerMaxStars);
+ opponentStarTxt.setText("★: " + opponentStars + "/" + opponentMaxStars);
}
function updateTurnText() {
turnTxt.setText(turn === "player" ? "Your Turn" : "Opponent Turn");
}
@@ -506,8 +508,13 @@
playerGrave = [];
opponentGrave = [];
playerHP = 100;
opponentHP = 100;
+ // Magic-style: start with 0 max stars, will increment at start of turn
+ playerMaxStars = 0;
+ playerStars = 0;
+ opponentMaxStars = 0;
+ opponentStars = 0;
turn = "player";
phase = "draw";
selectedCard = null;
gameActive = true;
@@ -567,10 +574,11 @@
onFinish: function onFinish() {
card.destroy();
}
});
- // Gain 2 stars
- playerStars += 2;
+ // Gain 1 max star (like Magic: play a land)
+ // Only increase max, refill current to max at next turn
+ playerMaxStars += 1;
updateHpText();
updateHandPositions();
}
function playCard(card) {
@@ -580,9 +588,9 @@
if (typeof card.starCost === "number" && playerStars < card.starCost) return; // Not enough stars
// Remove from hand
var idx = playerHand.indexOf(card);
if (idx !== -1) playerHand.splice(idx, 1);
- // Deduct stars
+ // Deduct stars from current (not max)
if (typeof card.starCost === "number") {
playerStars -= card.starCost;
if (playerStars < 0) playerStars = 0;
updateHpText();
@@ -680,10 +688,11 @@
function nextPhase() {
if (!gameActive) return;
if (turn === "player") {
if (phase === "draw") {
- // Draw phase
- playerStars += 1; // Gain 1 star at start of player's round
+ // Draw phase (Magic-style: increment max, refill current)
+ playerMaxStars += 1;
+ playerStars = playerMaxStars;
updateHpText();
var card = drawCard(playerDeck, playerHand, "player");
if (card) game.addChild(card);
phase = "main";
@@ -708,9 +717,11 @@
}
} else {
// Opponent phases
if (phase === "draw") {
- opponentStars += 1; // Gain 1 star at start of opponent's round
+ // Draw phase (Magic-style: increment max, refill current)
+ opponentMaxStars += 1;
+ opponentStars = opponentMaxStars;
updateHpText();
var card = drawCard(opponentDeck, opponentHand, "opponent");
if (card) game.addChild(card);
phase = "main";
@@ -730,9 +741,9 @@
}
if (card) {
var idx = opponentHand.indexOf(card);
if (idx !== -1) opponentHand.splice(idx, 1);
- // Deduct stars
+ // Deduct stars from current (not max)
opponentStars -= card.starCost;
if (opponentStars < 0) opponentStars = 0;
updateHpText();
card.isInHand = false;
design monsters in different styles for monster card game let there be only 1 monster design in each frame. In-Game asset. 2d. High contrast. No shadows
design monsters in different styles for monster card game let there be only 1 monster design in each frame. In-Game asset. 2d. High contrast. No shadows
Modern App Store icon, high definition, square with rounded corners, for a game. No text on icon! monster card deck
basılabilir tuş görseli dikdörtgen. In-Game asset. 2d. High contrast. No shadows