User prompt
kanka arka planda hep çalan müziği silebilirmisin
User prompt
kanka yeni bir ses ekleyelim ve bu ses arka planda hep çalsın
User prompt
kanka arka planda hep çalan müziği silebilirmisin
User prompt
kanka arka planda hep çalan bir müzikte olsun
Code edit (1 edits merged)
Please save this source code
User prompt
renk seçincede ses çıksın
User prompt
kanka uno butonuna basamıyorum mouse ile düzeltirmisin hataları
User prompt
kanka bazen yapay zeka hiç kart atmıyor kart çekiyor sonra sıra tekrar bana geliyor düzelt hatayı ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka bazen yapay zekanın attığı kart gözükmüyo
User prompt
kanka kart atınca kart eksilmiyo yani şu hatayı düzeltte oyunun bir sonuda olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka kart atıyorum ortaya yerine yeni kart geliyo ve +4 atınca renk seçme geliyo fakat renk seçemiyom yada yapay zekanın +4te hangi rengi seçtiği gözükmüyo düzelt şu hataları ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka bi karta bir kere basınca bir daha basamıyorum düzelt şu hataları ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka ortaya kart koyunca o kart ortada dursun sonra yapay zekada kart koyarsa onunkide gözüksün hatayı düzelt ve bi karta basınca animasyonla kalksın ama mouseyi bırakınca yerine geri gelsin animasyonla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka ben kart attıktan sonra ortadaki kart yok oluyo ve oynayamıyorum ayrıca elimde o renk kart yoksa rastgele kart çekme seçeneği ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot set properties of null (setting 'isAnimating')' in or related to this line: 'draggedCard.isAnimating = false;' Line Number: 689
User prompt
kanka kart oynayamıyorum gerçek zamanlı oynayabilmem gerek unoda fakat şuan oynayamıyorum kart seçip oynuyabileyim mousemle
User prompt
kanka yapay zekanın kartlarını ben görmüyeceğim ve ortaya rastgele atılan kart ile birlikte atma sırası bende olacak biliyosun zaten unoyu aynı renkte kart atmam gerek aynı renk yoksa kart çekerim biliyosun animasyon da ekle çok fazla şekilde ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka tıklayınca seçelim kartı neden seçemiyorum animasyonuda olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
AI Uno Challenge
Initial prompt
yapay zeka ile oynadığımız uno
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Card = Container.expand(function (color, value, type) { var self = Container.call(this); self.color = color; // 'red', 'blue', 'green', 'yellow', 'wild' self.value = value; // 0-9, 'skip', 'reverse', 'draw2', 'wild', 'wild4' self.type = type || 'number'; // 'number', 'action', 'wild' self.playable = false; self.isAnimating = false; // Create card background var colorMap = { 'red': 'cardRed', 'blue': 'cardBlue', 'green': 'cardGreen', 'yellow': 'cardYellow', 'wild': 'cardWild' }; var cardBg = self.attachAsset(colorMap[self.color] || 'cardBack', { anchorX: 0.5, anchorY: 0.5 }); // Add card text var displayText = self.value; if (self.value === 'skip') displayText = 'S';else if (self.value === 'reverse') displayText = 'R';else if (self.value === 'draw2') displayText = '+2';else if (self.value === 'wild') displayText = 'W';else if (self.value === 'wild4') displayText = '+4'; var cardText = new Text2(displayText.toString(), { size: 40, fill: self.color === 'yellow' ? "#000000" : "#ffffff" }); cardText.anchor.set(0.5, 0.5); self.addChild(cardText); self.setPlayable = function (playable) { self.playable = playable; cardBg.alpha = playable ? 1.0 : 0.7; }; self.canPlayOn = function (otherCard) { if (self.type === 'wild') return true; if (self.color === otherCard.color) return true; if (self.value === otherCard.value && self.type === 'number' && otherCard.type === 'number') return true; return false; }; return self; }); var Player = Container.expand(function (isAI) { var self = Container.call(this); self.cards = []; self.isAI = isAI || false; self.hasCalledUno = false; self.addCard = function (card) { self.cards.push(card); self.addChild(card); self.arrangeCards(); }; self.removeCard = function (card) { var index = self.cards.indexOf(card); if (index > -1) { self.cards.splice(index, 1); self.removeChild(card); self.arrangeCards(); } }; self.arrangeCards = function () { var startX = -(self.cards.length - 1) * 60; for (var i = 0; i < self.cards.length; i++) { var card = self.cards[i]; if (!card.isAnimating) { tween(card, { x: startX + i * 120, y: 0 }, { duration: 300, easing: tween.easeOut }); } } }; self.getPlayableCards = function (topCard) { var playable = []; for (var i = 0; i < self.cards.length; i++) { if (self.cards[i].canPlayOn(topCard)) { playable.push(self.cards[i]); } } return playable; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0f4c3a }); /**** * Game Code ****/ // Game state variables var deck = []; var discardPile = []; var player; var aiPlayer; var currentPlayer = 0; // 0 = player, 1 = AI var gameDirection = 1; // 1 = forward, -1 = reverse var drawCount = 0; // For draw 2/4 cards var selectedWildColor = null; var gamePhase = 'playing'; // 'playing', 'colorSelect', 'gameOver' var draggedCard = null; var dragOffset = { x: 0, y: 0 }; var waitingForUno = false; // UI elements var deckPileSprite; var discardPileSprite; var topCard; var unoButton; var colorSelectors = []; var gameStateText; var playerCardCountText; var aiCardCountText; // Initialize deck function createDeck() { deck = []; var colors = ['red', 'blue', 'green', 'yellow']; // Number cards (0-9) for (var c = 0; c < colors.length; c++) { var color = colors[c]; // One 0 card per color deck.push(new Card(color, 0, 'number')); // Two of each number 1-9 per color for (var num = 1; num <= 9; num++) { deck.push(new Card(color, num, 'number')); deck.push(new Card(color, num, 'number')); } // Action cards (2 of each per color) deck.push(new Card(color, 'skip', 'action')); deck.push(new Card(color, 'skip', 'action')); deck.push(new Card(color, 'reverse', 'action')); deck.push(new Card(color, 'reverse', 'action')); deck.push(new Card(color, 'draw2', 'action')); deck.push(new Card(color, 'draw2', 'action')); } // Wild cards for (var w = 0; w < 4; w++) { deck.push(new Card('wild', 'wild', 'wild')); deck.push(new Card('wild', 'wild4', 'wild')); } // Shuffle 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 dealCards() { // Deal 7 cards to each player for (var i = 0; i < 7; i++) { player.addCard(deck.pop()); aiPlayer.addCard(deck.pop()); } // Place first card on discard pile do { topCard = deck.pop(); } while (topCard.type === 'wild'); // Ensure first card isn't wild discardPile.push(topCard); game.addChild(topCard); topCard.x = 1024 + 200; topCard.y = 1366; } function updatePlayableCards() { var currentTopCard = discardPile[discardPile.length - 1]; // Update player cards for (var i = 0; i < player.cards.length; i++) { var card = player.cards[i]; var canPlay = card.canPlayOn(currentTopCard); if (selectedWildColor && currentTopCard.type === 'wild') { canPlay = card.color === selectedWildColor || card.type === 'wild'; } card.setPlayable(canPlay && currentPlayer === 0 && gamePhase === 'playing'); } } function drawCard(targetPlayer) { if (deck.length === 0) { // Reshuffle discard pile into deck var currentTop = discardPile.pop(); deck = discardPile.slice(); discardPile = [currentTop]; // Shuffle new 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; } } if (deck.length > 0) { var card = deck.pop(); targetPlayer.addCard(card); LK.getSound('cardDraw').play(); // Position new card if (targetPlayer === player) { card.x = 1024 - 200; card.y = 1366; } else { card.x = 1024; card.y = 500; } return card; } return null; } function playCard(card, playerObj) { // Remove card from player playerObj.removeCard(card); // Add to discard pile discardPile.push(card); // Animate card to discard pile card.isAnimating = true; tween(card, { x: 1024 + 200, y: 1366 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { card.isAnimating = false; // Remove old top card if (topCard && topCard !== card) { topCard.destroy(); } topCard = card; // Handle special cards handleCardEffect(card, playerObj); // Check for Uno if (playerObj.cards.length === 1 && !playerObj.hasCalledUno) { waitingForUno = true; if (playerObj === player) { showUnoButton(); } else { // AI automatically calls Uno LK.setTimeout(function () { playerObj.hasCalledUno = true; waitingForUno = false; LK.getSound('unoCall').play(); nextTurn(); }, 500); } } else { nextTurn(); } // Check win condition if (playerObj.cards.length === 0) { endGame(playerObj === player); } } }); LK.getSound('cardPlay').play(); selectedWildColor = null; playerObj.hasCalledUno = false; } function handleCardEffect(card, playerObj) { if (card.value === 'skip') { // Skip next player currentPlayer = (currentPlayer + gameDirection + 2) % 2; } else if (card.value === 'reverse') { gameDirection *= -1; } else if (card.value === 'draw2') { drawCount += 2; } else if (card.value === 'wild4') { drawCount += 4; } if (card.type === 'wild') { gamePhase = 'colorSelect'; if (playerObj === player) { showColorSelector(); } else { // AI chooses color var aiColors = ['red', 'blue', 'green', 'yellow']; selectedWildColor = aiColors[Math.floor(Math.random() * aiColors.length)]; gamePhase = 'playing'; } } } function nextTurn() { if (gamePhase !== 'playing') return; // Handle draw effects if (drawCount > 0) { var targetPlayer = currentPlayer === 0 ? aiPlayer : player; for (var i = 0; i < drawCount; i++) { drawCard(targetPlayer); } drawCount = 0; } // Switch turns currentPlayer = (currentPlayer + gameDirection + 2) % 2; updatePlayableCards(); updateUI(); // AI turn if (currentPlayer === 1) { LK.setTimeout(function () { aiTurn(); }, 1000); } } function aiTurn() { if (currentPlayer !== 1 || gamePhase !== 'playing') return; var currentTopCard = discardPile[discardPile.length - 1]; var playableCards = aiPlayer.getPlayableCards(currentTopCard); if (selectedWildColor && currentTopCard.type === 'wild') { playableCards = aiPlayer.cards.filter(function (card) { return card.color === selectedWildColor || card.type === 'wild'; }); } if (playableCards.length > 0) { // AI strategy: prefer action cards, then matching color var selectedCard = playableCards[0]; for (var i = 0; i < playableCards.length; i++) { var card = playableCards[i]; if (card.type === 'action' && selectedCard.type !== 'action') { selectedCard = card; } } playCard(selectedCard, aiPlayer); } else { // Draw card var drawnCard = drawCard(aiPlayer); if (drawnCard && drawnCard.canPlayOn(currentTopCard)) { // Play immediately if possible LK.setTimeout(function () { playCard(drawnCard, aiPlayer); }, 500); } else { nextTurn(); } } } function showColorSelector() { var colors = ['red', 'blue', 'green', 'yellow']; var colorValues = [0xe74c3c, 0x3498db, 0x27ae60, 0xf1c40f]; for (var i = 0; i < colors.length; i++) { var selector = LK.getAsset('colorSelector', { anchorX: 0.5, anchorY: 0.5 }); selector.tint = colorValues[i]; selector.x = 1024 + (i - 1.5) * 120; selector.y = 1366 - 150; selector.colorName = colors[i]; game.addChild(selector); colorSelectors.push(selector); } } function hideColorSelector() { for (var i = 0; i < colorSelectors.length; i++) { colorSelectors[i].destroy(); } colorSelectors = []; } function showUnoButton() { if (!unoButton) { unoButton = LK.getAsset('unoButton', { anchorX: 0.5, anchorY: 0.5 }); var unoText = new Text2('UNO!', { size: 30, fill: 0xFFFFFF }); unoText.anchor.set(0.5, 0.5); unoButton.addChild(unoText); unoButton.x = 1024 - 300; unoButton.y = 1366 - 150; game.addChild(unoButton); } } function hideUnoButton() { if (unoButton) { unoButton.destroy(); unoButton = null; } } function updateUI() { gameStateText.setText('Turn: ' + (currentPlayer === 0 ? 'Player' : 'AI')); playerCardCountText.setText('Your cards: ' + player.cards.length); aiCardCountText.setText('AI cards: ' + aiPlayer.cards.length); } function endGame(playerWon) { gamePhase = 'gameOver'; if (playerWon) { LK.setScore(LK.getScore() + 100); LK.showYouWin(); } else { LK.showGameOver(); } } // Initialize game createDeck(); // Create players player = game.addChild(new Player(false)); player.x = 1024; player.y = 2200; aiPlayer = game.addChild(new Player(true)); aiPlayer.x = 1024; aiPlayer.y = 500; // Create deck and discard pile sprites deckPileSprite = LK.getAsset('deckPile', { anchorX: 0.5, anchorY: 0.5 }); deckPileSprite.x = 1024 - 200; deckPileSprite.y = 1366; game.addChild(deckPileSprite); discardPileSprite = LK.getAsset('discardPile', { anchorX: 0.5, anchorY: 0.5 }); discardPileSprite.x = 1024 + 200; discardPileSprite.y = 1366; game.addChild(discardPileSprite); // Create UI text gameStateText = new Text2('Turn: Player', { size: 40, fill: 0xFFFFFF }); gameStateText.anchor.set(0.5, 0); LK.gui.top.addChild(gameStateText); playerCardCountText = new Text2('Your cards: 7', { size: 30, fill: 0xFFFFFF }); playerCardCountText.anchor.set(0, 1); LK.gui.bottomLeft.addChild(playerCardCountText); aiCardCountText = new Text2('AI cards: 7', { size: 30, fill: 0xFFFFFF }); aiCardCountText.anchor.set(0, 0); LK.gui.topLeft.addChild(aiCardCountText); aiCardCountText.x = 120; // Deal initial cards dealCards(); updatePlayableCards(); updateUI(); // Event handlers game.down = function (x, y, obj) { if (gamePhase === 'colorSelect') { // Check color selector clicks for (var i = 0; i < colorSelectors.length; i++) { var selector = colorSelectors[i]; var bounds = selector.getBounds(); if (x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height) { selectedWildColor = selector.colorName; hideColorSelector(); gamePhase = 'playing'; nextTurn(); return; } } } if (currentPlayer === 0 && gamePhase === 'playing') { // Check Uno button if (unoButton && waitingForUno) { var unoBounds = unoButton.getBounds(); if (x >= unoBounds.x && x <= unoBounds.x + unoBounds.width && y >= unoBounds.y && y <= unoBounds.y + unoBounds.height) { player.hasCalledUno = true; waitingForUno = false; hideUnoButton(); LK.getSound('unoCall').play(); nextTurn(); return; } } // Check deck click for drawing var deckBounds = deckPileSprite.getBounds(); if (x >= deckBounds.x && x <= deckBounds.x + deckBounds.width && y >= deckBounds.y && y <= deckBounds.y + deckBounds.height) { var currentTopCard = discardPile[discardPile.length - 1]; var playableCards = player.getPlayableCards(currentTopCard); if (selectedWildColor && currentTopCard.type === 'wild') { playableCards = player.cards.filter(function (card) { return card.color === selectedWildColor || card.type === 'wild'; }); } if (playableCards.length === 0) { drawCard(player); nextTurn(); } return; } // Check card selection for (var i = 0; i < player.cards.length; i++) { var card = player.cards[i]; if (card.playable) { var cardBounds = card.getBounds(); if (x >= cardBounds.x && x <= cardBounds.x + cardBounds.width && y >= cardBounds.y && y <= cardBounds.y + cardBounds.height) { draggedCard = card; dragOffset.x = x - card.x; dragOffset.y = y - card.y; break; } } } } }; game.move = function (x, y, obj) { if (draggedCard && currentPlayer === 0 && gamePhase === 'playing') { draggedCard.x = x - dragOffset.x; draggedCard.y = y - dragOffset.y; } }; game.up = function (x, y, obj) { if (draggedCard && currentPlayer === 0 && gamePhase === 'playing') { // Check if card was dropped on discard pile var discardBounds = discardPileSprite.getBounds(); if (x >= discardBounds.x && x <= discardBounds.x + discardBounds.width && y >= discardBounds.y && y <= discardBounds.y + discardBounds.height) { playCard(draggedCard, player); } else { // Return card to hand player.arrangeCards(); } draggedCard = null; } }; game.update = function () { // Update card positions and states updatePlayableCards(); };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,535 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Card = Container.expand(function (color, value, type) {
+ var self = Container.call(this);
+ self.color = color; // 'red', 'blue', 'green', 'yellow', 'wild'
+ self.value = value; // 0-9, 'skip', 'reverse', 'draw2', 'wild', 'wild4'
+ self.type = type || 'number'; // 'number', 'action', 'wild'
+ self.playable = false;
+ self.isAnimating = false;
+ // Create card background
+ var colorMap = {
+ 'red': 'cardRed',
+ 'blue': 'cardBlue',
+ 'green': 'cardGreen',
+ 'yellow': 'cardYellow',
+ 'wild': 'cardWild'
+ };
+ var cardBg = self.attachAsset(colorMap[self.color] || 'cardBack', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Add card text
+ var displayText = self.value;
+ if (self.value === 'skip') displayText = 'S';else if (self.value === 'reverse') displayText = 'R';else if (self.value === 'draw2') displayText = '+2';else if (self.value === 'wild') displayText = 'W';else if (self.value === 'wild4') displayText = '+4';
+ var cardText = new Text2(displayText.toString(), {
+ size: 40,
+ fill: self.color === 'yellow' ? "#000000" : "#ffffff"
+ });
+ cardText.anchor.set(0.5, 0.5);
+ self.addChild(cardText);
+ self.setPlayable = function (playable) {
+ self.playable = playable;
+ cardBg.alpha = playable ? 1.0 : 0.7;
+ };
+ self.canPlayOn = function (otherCard) {
+ if (self.type === 'wild') return true;
+ if (self.color === otherCard.color) return true;
+ if (self.value === otherCard.value && self.type === 'number' && otherCard.type === 'number') return true;
+ return false;
+ };
+ return self;
+});
+var Player = Container.expand(function (isAI) {
+ var self = Container.call(this);
+ self.cards = [];
+ self.isAI = isAI || false;
+ self.hasCalledUno = false;
+ self.addCard = function (card) {
+ self.cards.push(card);
+ self.addChild(card);
+ self.arrangeCards();
+ };
+ self.removeCard = function (card) {
+ var index = self.cards.indexOf(card);
+ if (index > -1) {
+ self.cards.splice(index, 1);
+ self.removeChild(card);
+ self.arrangeCards();
+ }
+ };
+ self.arrangeCards = function () {
+ var startX = -(self.cards.length - 1) * 60;
+ for (var i = 0; i < self.cards.length; i++) {
+ var card = self.cards[i];
+ if (!card.isAnimating) {
+ tween(card, {
+ x: startX + i * 120,
+ y: 0
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ }
+ }
+ };
+ self.getPlayableCards = function (topCard) {
+ var playable = [];
+ for (var i = 0; i < self.cards.length; i++) {
+ if (self.cards[i].canPlayOn(topCard)) {
+ playable.push(self.cards[i]);
+ }
+ }
+ return playable;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x0f4c3a
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var deck = [];
+var discardPile = [];
+var player;
+var aiPlayer;
+var currentPlayer = 0; // 0 = player, 1 = AI
+var gameDirection = 1; // 1 = forward, -1 = reverse
+var drawCount = 0; // For draw 2/4 cards
+var selectedWildColor = null;
+var gamePhase = 'playing'; // 'playing', 'colorSelect', 'gameOver'
+var draggedCard = null;
+var dragOffset = {
+ x: 0,
+ y: 0
+};
+var waitingForUno = false;
+// UI elements
+var deckPileSprite;
+var discardPileSprite;
+var topCard;
+var unoButton;
+var colorSelectors = [];
+var gameStateText;
+var playerCardCountText;
+var aiCardCountText;
+// Initialize deck
+function createDeck() {
+ deck = [];
+ var colors = ['red', 'blue', 'green', 'yellow'];
+ // Number cards (0-9)
+ for (var c = 0; c < colors.length; c++) {
+ var color = colors[c];
+ // One 0 card per color
+ deck.push(new Card(color, 0, 'number'));
+ // Two of each number 1-9 per color
+ for (var num = 1; num <= 9; num++) {
+ deck.push(new Card(color, num, 'number'));
+ deck.push(new Card(color, num, 'number'));
+ }
+ // Action cards (2 of each per color)
+ deck.push(new Card(color, 'skip', 'action'));
+ deck.push(new Card(color, 'skip', 'action'));
+ deck.push(new Card(color, 'reverse', 'action'));
+ deck.push(new Card(color, 'reverse', 'action'));
+ deck.push(new Card(color, 'draw2', 'action'));
+ deck.push(new Card(color, 'draw2', 'action'));
+ }
+ // Wild cards
+ for (var w = 0; w < 4; w++) {
+ deck.push(new Card('wild', 'wild', 'wild'));
+ deck.push(new Card('wild', 'wild4', 'wild'));
+ }
+ // Shuffle 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 dealCards() {
+ // Deal 7 cards to each player
+ for (var i = 0; i < 7; i++) {
+ player.addCard(deck.pop());
+ aiPlayer.addCard(deck.pop());
+ }
+ // Place first card on discard pile
+ do {
+ topCard = deck.pop();
+ } while (topCard.type === 'wild'); // Ensure first card isn't wild
+ discardPile.push(topCard);
+ game.addChild(topCard);
+ topCard.x = 1024 + 200;
+ topCard.y = 1366;
+}
+function updatePlayableCards() {
+ var currentTopCard = discardPile[discardPile.length - 1];
+ // Update player cards
+ for (var i = 0; i < player.cards.length; i++) {
+ var card = player.cards[i];
+ var canPlay = card.canPlayOn(currentTopCard);
+ if (selectedWildColor && currentTopCard.type === 'wild') {
+ canPlay = card.color === selectedWildColor || card.type === 'wild';
+ }
+ card.setPlayable(canPlay && currentPlayer === 0 && gamePhase === 'playing');
+ }
+}
+function drawCard(targetPlayer) {
+ if (deck.length === 0) {
+ // Reshuffle discard pile into deck
+ var currentTop = discardPile.pop();
+ deck = discardPile.slice();
+ discardPile = [currentTop];
+ // Shuffle new 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;
+ }
+ }
+ if (deck.length > 0) {
+ var card = deck.pop();
+ targetPlayer.addCard(card);
+ LK.getSound('cardDraw').play();
+ // Position new card
+ if (targetPlayer === player) {
+ card.x = 1024 - 200;
+ card.y = 1366;
+ } else {
+ card.x = 1024;
+ card.y = 500;
+ }
+ return card;
+ }
+ return null;
+}
+function playCard(card, playerObj) {
+ // Remove card from player
+ playerObj.removeCard(card);
+ // Add to discard pile
+ discardPile.push(card);
+ // Animate card to discard pile
+ card.isAnimating = true;
+ tween(card, {
+ x: 1024 + 200,
+ y: 1366
+ }, {
+ duration: 400,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ card.isAnimating = false;
+ // Remove old top card
+ if (topCard && topCard !== card) {
+ topCard.destroy();
+ }
+ topCard = card;
+ // Handle special cards
+ handleCardEffect(card, playerObj);
+ // Check for Uno
+ if (playerObj.cards.length === 1 && !playerObj.hasCalledUno) {
+ waitingForUno = true;
+ if (playerObj === player) {
+ showUnoButton();
+ } else {
+ // AI automatically calls Uno
+ LK.setTimeout(function () {
+ playerObj.hasCalledUno = true;
+ waitingForUno = false;
+ LK.getSound('unoCall').play();
+ nextTurn();
+ }, 500);
+ }
+ } else {
+ nextTurn();
+ }
+ // Check win condition
+ if (playerObj.cards.length === 0) {
+ endGame(playerObj === player);
+ }
+ }
+ });
+ LK.getSound('cardPlay').play();
+ selectedWildColor = null;
+ playerObj.hasCalledUno = false;
+}
+function handleCardEffect(card, playerObj) {
+ if (card.value === 'skip') {
+ // Skip next player
+ currentPlayer = (currentPlayer + gameDirection + 2) % 2;
+ } else if (card.value === 'reverse') {
+ gameDirection *= -1;
+ } else if (card.value === 'draw2') {
+ drawCount += 2;
+ } else if (card.value === 'wild4') {
+ drawCount += 4;
+ }
+ if (card.type === 'wild') {
+ gamePhase = 'colorSelect';
+ if (playerObj === player) {
+ showColorSelector();
+ } else {
+ // AI chooses color
+ var aiColors = ['red', 'blue', 'green', 'yellow'];
+ selectedWildColor = aiColors[Math.floor(Math.random() * aiColors.length)];
+ gamePhase = 'playing';
+ }
+ }
+}
+function nextTurn() {
+ if (gamePhase !== 'playing') return;
+ // Handle draw effects
+ if (drawCount > 0) {
+ var targetPlayer = currentPlayer === 0 ? aiPlayer : player;
+ for (var i = 0; i < drawCount; i++) {
+ drawCard(targetPlayer);
+ }
+ drawCount = 0;
+ }
+ // Switch turns
+ currentPlayer = (currentPlayer + gameDirection + 2) % 2;
+ updatePlayableCards();
+ updateUI();
+ // AI turn
+ if (currentPlayer === 1) {
+ LK.setTimeout(function () {
+ aiTurn();
+ }, 1000);
+ }
+}
+function aiTurn() {
+ if (currentPlayer !== 1 || gamePhase !== 'playing') return;
+ var currentTopCard = discardPile[discardPile.length - 1];
+ var playableCards = aiPlayer.getPlayableCards(currentTopCard);
+ if (selectedWildColor && currentTopCard.type === 'wild') {
+ playableCards = aiPlayer.cards.filter(function (card) {
+ return card.color === selectedWildColor || card.type === 'wild';
+ });
+ }
+ if (playableCards.length > 0) {
+ // AI strategy: prefer action cards, then matching color
+ var selectedCard = playableCards[0];
+ for (var i = 0; i < playableCards.length; i++) {
+ var card = playableCards[i];
+ if (card.type === 'action' && selectedCard.type !== 'action') {
+ selectedCard = card;
+ }
+ }
+ playCard(selectedCard, aiPlayer);
+ } else {
+ // Draw card
+ var drawnCard = drawCard(aiPlayer);
+ if (drawnCard && drawnCard.canPlayOn(currentTopCard)) {
+ // Play immediately if possible
+ LK.setTimeout(function () {
+ playCard(drawnCard, aiPlayer);
+ }, 500);
+ } else {
+ nextTurn();
+ }
+ }
+}
+function showColorSelector() {
+ var colors = ['red', 'blue', 'green', 'yellow'];
+ var colorValues = [0xe74c3c, 0x3498db, 0x27ae60, 0xf1c40f];
+ for (var i = 0; i < colors.length; i++) {
+ var selector = LK.getAsset('colorSelector', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ selector.tint = colorValues[i];
+ selector.x = 1024 + (i - 1.5) * 120;
+ selector.y = 1366 - 150;
+ selector.colorName = colors[i];
+ game.addChild(selector);
+ colorSelectors.push(selector);
+ }
+}
+function hideColorSelector() {
+ for (var i = 0; i < colorSelectors.length; i++) {
+ colorSelectors[i].destroy();
+ }
+ colorSelectors = [];
+}
+function showUnoButton() {
+ if (!unoButton) {
+ unoButton = LK.getAsset('unoButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var unoText = new Text2('UNO!', {
+ size: 30,
+ fill: 0xFFFFFF
+ });
+ unoText.anchor.set(0.5, 0.5);
+ unoButton.addChild(unoText);
+ unoButton.x = 1024 - 300;
+ unoButton.y = 1366 - 150;
+ game.addChild(unoButton);
+ }
+}
+function hideUnoButton() {
+ if (unoButton) {
+ unoButton.destroy();
+ unoButton = null;
+ }
+}
+function updateUI() {
+ gameStateText.setText('Turn: ' + (currentPlayer === 0 ? 'Player' : 'AI'));
+ playerCardCountText.setText('Your cards: ' + player.cards.length);
+ aiCardCountText.setText('AI cards: ' + aiPlayer.cards.length);
+}
+function endGame(playerWon) {
+ gamePhase = 'gameOver';
+ if (playerWon) {
+ LK.setScore(LK.getScore() + 100);
+ LK.showYouWin();
+ } else {
+ LK.showGameOver();
+ }
+}
+// Initialize game
+createDeck();
+// Create players
+player = game.addChild(new Player(false));
+player.x = 1024;
+player.y = 2200;
+aiPlayer = game.addChild(new Player(true));
+aiPlayer.x = 1024;
+aiPlayer.y = 500;
+// Create deck and discard pile sprites
+deckPileSprite = LK.getAsset('deckPile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+deckPileSprite.x = 1024 - 200;
+deckPileSprite.y = 1366;
+game.addChild(deckPileSprite);
+discardPileSprite = LK.getAsset('discardPile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+discardPileSprite.x = 1024 + 200;
+discardPileSprite.y = 1366;
+game.addChild(discardPileSprite);
+// Create UI text
+gameStateText = new Text2('Turn: Player', {
+ size: 40,
+ fill: 0xFFFFFF
+});
+gameStateText.anchor.set(0.5, 0);
+LK.gui.top.addChild(gameStateText);
+playerCardCountText = new Text2('Your cards: 7', {
+ size: 30,
+ fill: 0xFFFFFF
+});
+playerCardCountText.anchor.set(0, 1);
+LK.gui.bottomLeft.addChild(playerCardCountText);
+aiCardCountText = new Text2('AI cards: 7', {
+ size: 30,
+ fill: 0xFFFFFF
+});
+aiCardCountText.anchor.set(0, 0);
+LK.gui.topLeft.addChild(aiCardCountText);
+aiCardCountText.x = 120;
+// Deal initial cards
+dealCards();
+updatePlayableCards();
+updateUI();
+// Event handlers
+game.down = function (x, y, obj) {
+ if (gamePhase === 'colorSelect') {
+ // Check color selector clicks
+ for (var i = 0; i < colorSelectors.length; i++) {
+ var selector = colorSelectors[i];
+ var bounds = selector.getBounds();
+ if (x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height) {
+ selectedWildColor = selector.colorName;
+ hideColorSelector();
+ gamePhase = 'playing';
+ nextTurn();
+ return;
+ }
+ }
+ }
+ if (currentPlayer === 0 && gamePhase === 'playing') {
+ // Check Uno button
+ if (unoButton && waitingForUno) {
+ var unoBounds = unoButton.getBounds();
+ if (x >= unoBounds.x && x <= unoBounds.x + unoBounds.width && y >= unoBounds.y && y <= unoBounds.y + unoBounds.height) {
+ player.hasCalledUno = true;
+ waitingForUno = false;
+ hideUnoButton();
+ LK.getSound('unoCall').play();
+ nextTurn();
+ return;
+ }
+ }
+ // Check deck click for drawing
+ var deckBounds = deckPileSprite.getBounds();
+ if (x >= deckBounds.x && x <= deckBounds.x + deckBounds.width && y >= deckBounds.y && y <= deckBounds.y + deckBounds.height) {
+ var currentTopCard = discardPile[discardPile.length - 1];
+ var playableCards = player.getPlayableCards(currentTopCard);
+ if (selectedWildColor && currentTopCard.type === 'wild') {
+ playableCards = player.cards.filter(function (card) {
+ return card.color === selectedWildColor || card.type === 'wild';
+ });
+ }
+ if (playableCards.length === 0) {
+ drawCard(player);
+ nextTurn();
+ }
+ return;
+ }
+ // Check card selection
+ for (var i = 0; i < player.cards.length; i++) {
+ var card = player.cards[i];
+ if (card.playable) {
+ var cardBounds = card.getBounds();
+ if (x >= cardBounds.x && x <= cardBounds.x + cardBounds.width && y >= cardBounds.y && y <= cardBounds.y + cardBounds.height) {
+ draggedCard = card;
+ dragOffset.x = x - card.x;
+ dragOffset.y = y - card.y;
+ break;
+ }
+ }
+ }
+ }
+};
+game.move = function (x, y, obj) {
+ if (draggedCard && currentPlayer === 0 && gamePhase === 'playing') {
+ draggedCard.x = x - dragOffset.x;
+ draggedCard.y = y - dragOffset.y;
+ }
+};
+game.up = function (x, y, obj) {
+ if (draggedCard && currentPlayer === 0 && gamePhase === 'playing') {
+ // Check if card was dropped on discard pile
+ var discardBounds = discardPileSprite.getBounds();
+ if (x >= discardBounds.x && x <= discardBounds.x + discardBounds.width && y >= discardBounds.y && y <= discardBounds.y + discardBounds.height) {
+ playCard(draggedCard, player);
+ } else {
+ // Return card to hand
+ player.arrangeCards();
+ }
+ draggedCard = null;
+ }
+};
+game.update = function () {
+ // Update card positions and states
+ updatePlayableCards();
+};
\ No newline at end of file
black card. In-Game asset. 2d. High contrast. No shadows
gray card. In-Game asset. 2d. High contrast. No shadows
green card. In-Game asset. 2d. High contrast. No shadows
blue card. In-Game asset. 2d. High contrast. No shadows
red card. In-Game asset. 2d. High contrast. No shadows
yellow card. In-Game asset. 2d. High contrast. No shadows
? card. In-Game asset. 2d. High contrast. No shadows
pink button. In-Game asset. 2d. High contrast. No shadows
uno. In-Game asset. 2d. High contrast. No shadows