/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ColorChooser = Container.expand(function () { var self = Container.call(this); self.visible = false; var colors = ['red', 'blue', 'green', 'yellow']; var colorValues = [0xFF4444, 0x4444FF, 0x44FF44, 0xFFFF44]; for (var i = 0; i < 4; i++) { var colorBtn = self.attachAsset('colorButton', { anchorX: 0.5, anchorY: 0.5, x: i % 2 * 140 - 70, y: Math.floor(i / 2) * 140 - 70, tint: colorValues[i] }); colorBtn.colorName = colors[i]; colorBtn.down = function (x, y, obj) { chooseWildColor(obj.colorName); }; } return self; }); var UnoCard = Container.expand(function (color, value) { var self = Container.call(this); self.color = color; // 'red', 'blue', 'green', 'yellow', 'wild' self.value = value; // 0-9, 'skip', 'reverse', 'draw2', 'wild', 'wilddraw4' self.isPlayable = false; // Create card background var cardAssetId = color + 'Card'; if (color === 'wild') cardAssetId = 'wildCard'; var cardBg = self.attachAsset(cardAssetId, { anchorX: 0.5, anchorY: 0.5 }); // Add card text var cardText = new Text2(self.value.toString(), { size: 24, fill: color === 'yellow' ? "#000000" : "#FFFFFF" }); cardText.anchor.set(0.5, 0.5); self.addChild(cardText); self.setPlayable = function (playable) { self.isPlayable = playable; cardBg.alpha = playable ? 1.0 : 0.6; }; self.canPlayOn = function (topCard) { if (self.color === 'wild') return true; if (self.color === topCard.color) return true; if (self.value === topCard.value && typeof self.value === 'number') return true; return false; }; self.down = function (x, y, obj) { if (self.isPlayable) { playCard(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x006600 }); /**** * Game Code ****/ // Game state variables // UNO Card assets // Sound effects var player1Hand = []; var player2Hand = []; var player3Hand = []; var discardPile = []; var drawPile = []; var currentPlayer = 0; // 0 = player 1, 1 = player 2, 2 = player 3 var gameDirection = 1; // 1 = forward, -1 = reverse var pendingWildCard = null; var player1Score = 0; var player2Score = 0; var player3Score = 0; var targetScore = 500; // UI elements var scoreText = new Text2('P1: 0 P2: 0 P3: 0', { size: 32, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var currentPlayerText = new Text2('Player 1 Turn', { size: 36, fill: 0xFFFF00 }); currentPlayerText.anchor.set(0.5, 0); currentPlayerText.y = 60; LK.gui.top.addChild(currentPlayerText); var unoButton = game.attachAsset('unoButton', { anchorX: 0.5, anchorY: 0.5, x: 1700, y: 2200 }); var unoButtonText = new Text2('UNO!', { size: 32, fill: 0xFFFFFF }); unoButtonText.anchor.set(0.5, 0.5); unoButton.addChild(unoButtonText); var colorChooser = game.addChild(new ColorChooser()); colorChooser.x = 1024; colorChooser.y = 1366; // Discard pile area var discardArea = game.attachAsset('discardPile', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); // Initialize deck function createDeck() { var 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({ color: color, value: 0 }); // Two of each 1-9 card per color for (var v = 1; v <= 9; v++) { deck.push({ color: color, value: v }); deck.push({ color: color, value: v }); } // Action cards (2 of each per color) deck.push({ color: color, value: 'skip' }); deck.push({ color: color, value: 'skip' }); deck.push({ color: color, value: 'reverse' }); deck.push({ color: color, value: 'reverse' }); deck.push({ color: color, value: 'draw2' }); deck.push({ color: color, value: 'draw2' }); } // Wild cards (4 of each) for (var w = 0; w < 4; w++) { deck.push({ color: 'wild', value: 'wild' }); deck.push({ color: 'wild', value: 'wilddraw4' }); } return deck; } 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 dealCards() { // Create and shuffle deck var deck = createDeck(); shuffleDeck(deck); // Deal 7 cards to each player for (var i = 0; i < 7; i++) { var card1 = new UnoCard(deck[i].color, deck[i].value); var card2 = new UnoCard(deck[i + 7].color, deck[i + 7].value); var card3 = new UnoCard(deck[i + 14].color, deck[i + 14].value); // Set initial positions for the cards before adding to game card1.x = 1024; card1.y = 1366; card2.x = 1024; card2.y = 1366; card3.x = 1024; card3.y = 1366; player1Hand.push(card1); player2Hand.push(card2); player3Hand.push(card3); game.addChild(card1); game.addChild(card2); game.addChild(card3); } // Set up draw pile for (var d = 21; d < deck.length - 1; d++) { drawPile.push(deck[d]); } // Start discard pile var startCard = deck[deck.length - 1]; var topCard = new UnoCard(startCard.color, startCard.value); discardPile.push(topCard); game.addChild(topCard); arrangeCards(); } function arrangeCards() { // Arrange player 1 hand (bottom) var cardSpacing = 120; // Increased spacing var startX = 1024 - player1Hand.length * cardSpacing / 2; for (var i = 0; i < player1Hand.length; i++) { var card = player1Hand[i]; card.x = startX + i * cardSpacing; card.y = 2500; card.rotation = 0; } // Arrange player 2 hand (top, face down) var cardSpacing2 = 120; // Increased spacing var startX2 = 1024 - player2Hand.length * cardSpacing2 / 2; for (var j = 0; j < player2Hand.length; j++) { var card2 = player2Hand[j]; card2.x = startX2 + j * cardSpacing2; card2.y = 200; card2.rotation = Math.PI; } // Arrange player 3 hand (right side, face down) var cardSpacing3 = 120; var startY3 = 1366 - player3Hand.length * cardSpacing3 / 2; for (var k = 0; k < player3Hand.length; k++) { var card3 = player3Hand[k]; card3.x = 1800; card3.y = startY3 + k * cardSpacing3; card3.rotation = Math.PI / 2; } // Position top discard card if (discardPile.length > 0) { var topCard = discardPile[discardPile.length - 1]; topCard.x = 1024; topCard.y = 1366; } updatePlayableCards(); } function updatePlayableCards() { if (discardPile.length === 0) return; var topCard = discardPile[discardPile.length - 1]; // Reset all cards to not playable first for (var i = 0; i < player1Hand.length; i++) { player1Hand[i].setPlayable(false); } for (var j = 0; j < player2Hand.length; j++) { player2Hand[j].setPlayable(false); } for (var k = 0; k < player3Hand.length; k++) { player3Hand[k].setPlayable(false); } // Update current player's cards var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand; for (var i = 0; i < currentHand.length; i++) { var canPlay = currentHand[i].canPlayOn(topCard); currentHand[i].setPlayable(canPlay); } } function playCard(card) { var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand; var cardIndex = currentHand.indexOf(card); if (cardIndex === -1) return; // Remove card from hand currentHand.splice(cardIndex, 1); // Add to discard pile discardPile.push(card); // Position card on discard pile card.x = 1024; card.y = 1366; card.rotation = 0; LK.getSound('cardPlay').play(); // Handle special cards if (card.color === 'wild') { pendingWildCard = card; colorChooser.visible = true; return; } executeCardEffect(card); // Check for UNO if (currentHand.length === 1) { // Player should call UNO LK.setTimeout(function () { if (currentHand.length === 1) { // Penalty for not calling UNO drawCards(currentPlayer, 2); LK.getSound('penalty').play(); } }, 3000); } // Check for win if (currentHand.length === 0) { endRound(currentPlayer); return; } arrangeCards(); nextTurn(); } function executeCardEffect(card) { switch (card.value) { case 'skip': // Skip next player nextTurn(); break; case 'reverse': gameDirection *= -1; break; case 'draw2': var nextPlayer = (currentPlayer + gameDirection + 3) % 3; drawCards(nextPlayer, 2); nextTurn(); break; case 'wilddraw4': var nextPlayer = (currentPlayer + gameDirection + 3) % 3; drawCards(nextPlayer, 4); nextTurn(); break; } } function chooseWildColor(color) { if (!pendingWildCard) return; pendingWildCard.color = color; colorChooser.visible = false; executeCardEffect(pendingWildCard); pendingWildCard = null; arrangeCards(); nextTurn(); } function drawCards(player, count) { for (var i = 0; i < count; i++) { if (drawPile.length === 0) { reshuffleDiscardPile(); } if (drawPile.length > 0) { var cardData = drawPile.pop(); var newCard = new UnoCard(cardData.color, cardData.value); game.addChild(newCard); if (player === 0) { player1Hand.push(newCard); } else if (player === 1) { player2Hand.push(newCard); } else { player3Hand.push(newCard); } } } LK.getSound('cardDraw').play(); arrangeCards(); } function reshuffleDiscardPile() { if (discardPile.length <= 1) return; // Keep top card, shuffle rest back into draw pile var topCard = discardPile.pop(); while (discardPile.length > 0) { var card = discardPile.shift(); drawPile.push({ color: card.color, value: card.value }); card.destroy(); } discardPile.push(topCard); shuffleDeck(drawPile); } function nextTurn() { currentPlayer = (currentPlayer + gameDirection + 3) % 3; if (currentPlayer === 0) { currentPlayerText.setText('Player 1 Turn'); } else if (currentPlayer === 1) { currentPlayerText.setText('Player 2 Turn'); } else { currentPlayerText.setText('Player 3 Turn'); } updatePlayableCards(); } function endRound(winner) { // Calculate points from all other players' hands var points = 0; var allHands = [player1Hand, player2Hand, player3Hand]; for (var h = 0; h < allHands.length; h++) { if (h === winner) continue; // Skip winner's hand var hand = allHands[h]; for (var i = 0; i < hand.length; i++) { var card = hand[i]; if (typeof card.value === 'number') { points += card.value; } else if (card.value === 'skip' || card.value === 'reverse' || card.value === 'draw2') { points += 20; } else { points += 50; // Wild cards } } } if (winner === 0) { player1Score += points; } else if (winner === 1) { player2Score += points; } else { player3Score += points; } scoreText.setText('P1: ' + player1Score + ' P2: ' + player2Score + ' P3: ' + player3Score); // Check for game win if (player1Score >= targetScore) { LK.showYouWin(); } else if (player2Score >= targetScore || player3Score >= targetScore) { LK.showGameOver(); } else { // Start new round LK.setTimeout(function () { startNewRound(); }, 2000); } } function startNewRound() { // Clear hands and discard pile for (var i = 0; i < player1Hand.length; i++) { player1Hand[i].destroy(); } for (var j = 0; j < player2Hand.length; j++) { player2Hand[j].destroy(); } for (var k = 0; k < player3Hand.length; k++) { player3Hand[k].destroy(); } for (var l = 0; l < discardPile.length; l++) { discardPile[l].destroy(); } player1Hand = []; player2Hand = []; player3Hand = []; discardPile = []; drawPile = []; currentPlayer = 0; gameDirection = 1; pendingWildCard = null; colorChooser.visible = false; dealCards(); } // UNO button handler unoButton.down = function (x, y, obj) { var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand; if (currentHand.length === 1) { LK.getSound('unoCall').play(); } }; // Draw card area (right side of screen) game.down = function (x, y, obj) { if (x > 1500 && x < 2048 && y > 1200 && y < 1600) { // Draw card area clicked var topCard = discardPile[discardPile.length - 1]; var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand; var hasPlayableCard = false; for (var i = 0; i < currentHand.length; i++) { if (currentHand[i].canPlayOn(topCard)) { hasPlayableCard = true; break; } } if (!hasPlayableCard) { drawCards(currentPlayer, 1); nextTurn(); } } }; // Initialize game dealCards(); currentPlayerText.setText('Player 1 Turn');
===================================================================
--- original.js
+++ change.js
@@ -55,9 +55,9 @@
if (self.value === topCard.value && typeof self.value === 'number') return true;
return false;
};
self.down = function (x, y, obj) {
- if (self.isPlayable && currentPlayer === 0) {
+ if (self.isPlayable) {
playCard(self);
}
};
return self;
@@ -266,25 +266,37 @@
}
function updatePlayableCards() {
if (discardPile.length === 0) return;
var topCard = discardPile[discardPile.length - 1];
- // Update player 1 cards
+ // Reset all cards to not playable first
for (var i = 0; i < player1Hand.length; i++) {
- var canPlay = player1Hand[i].canPlayOn(topCard);
- player1Hand[i].setPlayable(canPlay);
+ player1Hand[i].setPlayable(false);
}
+ for (var j = 0; j < player2Hand.length; j++) {
+ player2Hand[j].setPlayable(false);
+ }
+ for (var k = 0; k < player3Hand.length; k++) {
+ player3Hand[k].setPlayable(false);
+ }
+ // Update current player's cards
+ var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand;
+ for (var i = 0; i < currentHand.length; i++) {
+ var canPlay = currentHand[i].canPlayOn(topCard);
+ currentHand[i].setPlayable(canPlay);
+ }
}
function playCard(card) {
- if (currentPlayer !== 0) return;
- var cardIndex = player1Hand.indexOf(card);
+ var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand;
+ var cardIndex = currentHand.indexOf(card);
if (cardIndex === -1) return;
// Remove card from hand
- player1Hand.splice(cardIndex, 1);
+ currentHand.splice(cardIndex, 1);
// Add to discard pile
discardPile.push(card);
// Position card on discard pile
card.x = 1024;
card.y = 1366;
+ card.rotation = 0;
LK.getSound('cardPlay').play();
// Handle special cards
if (card.color === 'wild') {
pendingWildCard = card;
@@ -292,21 +304,21 @@
return;
}
executeCardEffect(card);
// Check for UNO
- if (player1Hand.length === 1) {
+ if (currentHand.length === 1) {
// Player should call UNO
LK.setTimeout(function () {
- if (player1Hand.length === 1) {
+ if (currentHand.length === 1) {
// Penalty for not calling UNO
- drawCards(0, 2);
+ drawCards(currentPlayer, 2);
LK.getSound('penalty').play();
}
}, 3000);
}
// Check for win
- if (player1Hand.length === 0) {
- endRound(0);
+ if (currentHand.length === 0) {
+ endRound(currentPlayer);
return;
}
arrangeCards();
nextTurn();
@@ -382,63 +394,13 @@
if (currentPlayer === 0) {
currentPlayerText.setText('Player 1 Turn');
} else if (currentPlayer === 1) {
currentPlayerText.setText('Player 2 Turn');
- // AI turn
- LK.setTimeout(function () {
- playAITurn();
- }, 1000);
} else {
currentPlayerText.setText('Player 3 Turn');
- // AI turn
- LK.setTimeout(function () {
- playAITurn();
- }, 1000);
}
updatePlayableCards();
}
-function playAITurn() {
- if (currentPlayer !== 1 && currentPlayer !== 2) return;
- var topCard = discardPile[discardPile.length - 1];
- var playableCards = [];
- var currentHand = currentPlayer === 1 ? player2Hand : player3Hand;
- // Find playable cards
- for (var i = 0; i < currentHand.length; i++) {
- if (currentHand[i].canPlayOn(topCard)) {
- playableCards.push(i);
- }
- }
- if (playableCards.length > 0) {
- // Play a random playable card
- var randomIndex = playableCards[Math.floor(Math.random() * playableCards.length)];
- var card = currentHand[randomIndex];
- // Remove from hand
- currentHand.splice(randomIndex, 1);
- // Add to discard pile
- discardPile.push(card);
- card.x = 1024;
- card.y = 1366;
- card.rotation = 0;
- LK.getSound('cardPlay').play();
- // Handle wild cards
- if (card.color === 'wild') {
- var colors = ['red', 'blue', 'green', 'yellow'];
- card.color = colors[Math.floor(Math.random() * 4)];
- }
- executeCardEffect(card);
- // Check for win
- if (currentHand.length === 0) {
- endRound(currentPlayer);
- return;
- }
- arrangeCards();
- nextTurn();
- } else {
- // Draw a card
- drawCards(currentPlayer, 1);
- nextTurn();
- }
-}
function endRound(winner) {
// Calculate points from all other players' hands
var points = 0;
var allHands = [player1Hand, player2Hand, player3Hand];
@@ -502,26 +464,28 @@
dealCards();
}
// UNO button handler
unoButton.down = function (x, y, obj) {
- if (player1Hand.length === 1) {
+ var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand;
+ if (currentHand.length === 1) {
LK.getSound('unoCall').play();
}
};
// Draw card area (right side of screen)
game.down = function (x, y, obj) {
- if (x > 1500 && x < 2048 && y > 1200 && y < 1600 && currentPlayer === 0) {
+ if (x > 1500 && x < 2048 && y > 1200 && y < 1600) {
// Draw card area clicked
var topCard = discardPile[discardPile.length - 1];
+ var currentHand = currentPlayer === 0 ? player1Hand : currentPlayer === 1 ? player2Hand : player3Hand;
var hasPlayableCard = false;
- for (var i = 0; i < player1Hand.length; i++) {
- if (player1Hand[i].canPlayOn(topCard)) {
+ for (var i = 0; i < currentHand.length; i++) {
+ if (currentHand[i].canPlayOn(topCard)) {
hasPlayableCard = true;
break;
}
}
if (!hasPlayableCard) {
- drawCards(0, 1);
+ drawCards(currentPlayer, 1);
nextTurn();
}
}
};