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