User prompt
add a start button to the game, first of all there should be an option to start that game first and when you press it the game will start
User prompt
add game start button
User prompt
Place the M button in a visible place in the middle of the screen
User prompt
My cards should be in the bottom middle of the screen.
User prompt
change the screen ratio from 2048x2732 to 720x1280
User prompt
Don't show the bonus given by the place in the middle, show it in the top left, let's get rid of the crowded appearance of the middle part
User prompt
At the beginning of the game, a location card should be revealed first, and in each round, the location card should appear first, then we can throw a card.
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of null (reading 'name')' in or related to this line: 'if (location.name.toLowerCase() === 'castle') {' Line Number: 275
User prompt
At the beginning of the game, a location card should be revealed first, and in each round, the location card should appear first, then we can throw a card.
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of null (reading 'name')' in or related to this line: 'if (location.name.toLowerCase() === 'castle') {' Line Number: 275
User prompt
In each round, first the venue card is shown and then we throw a card.
User prompt
The venue card should not cover the entire background, but should be on top.
User prompt
The same location card cannot come twice. Set this, so all 3 locations will come in 3 rounds.
User prompt
Whichever place you come to in the tour, castle, forest and cave, there is an asset with the same name, that asset should cover the background of that tour.
User prompt
Turn the cards of other players except me 90 degrees when the cards are thrown on the ground.
User prompt
Ben Dariç turn other players' cards 90 degrees
User prompt
One player should be on the right and the other on the left.
User prompt
The player opposite me should move to the right side
User prompt
Until the CARDS of the OTHER PLAYERS, EXCEPT ME, are thrown on the ground, their assets shall be cardBG. When they are thrown on the ground, the asset in the name shall be that asset.
User prompt
Also use the assets of the cards, for example, for elf-archer, use the asset named elf-archer
User prompt
Create a system that allows me to wait after each round in the game and press to move on to the next round
User prompt
Add an asset named "next-round-button" to the corner of the game. Use the existing asset and keep it there.
User prompt
Add an asset named "next-round-button" to the bottom right corner of the game. Use the existing asset and keep it there.
User prompt
Add the next-round-button to the bottom right corner of the game, use the existing asset and keep it there.
User prompt
There is a next-round-button asset, do it using it so that I can see it on the screen and press it continuously so that we can move on to the next round.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Card class: represents a single card (type, subtype, owner, value, etc) var Card = Container.expand(function () { var self = Container.call(this); // Card properties (set after creation) self.cardType = null; // 'human', 'elf', 'orc' self.subType = null; // 'warrior', 'archer', 'wizard' self.owner = null; // 'player', 'bot1', 'bot2' self.value = 0; // base value (for future expansion) self.isFaceUp = false; self.cardIndex = -1; // 0-8, for unique identification // Card visuals // Card background var bg = self.attachAsset('cardBg', { width: 320, height: 480, color: 0xeeeeee, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); // Card type color overlay var typeColor = { 'human': 0x6fa8dc, 'elf': 0x93c47d, 'orc': 0xe06666 }; var overlay = self.attachAsset('cardOverlay', { width: 300, height: 460, color: 0xffffff, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); // Card text var txt = new Text2('', { size: 60, fill: 0x222222 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; self.addChild(txt); // Set card data and visuals self.setCard = function (cardType, subType, owner, cardIndex) { self.cardType = cardType; self.subType = subType; self.owner = owner; self.cardIndex = cardIndex; // Set overlay color overlay.tint = typeColor[cardType]; // Set text txt.setText(cardType.charAt(0).toUpperCase() + cardType.slice(1) + "\n" + subType.charAt(0).toUpperCase() + subType.slice(1)); }; // Show/hide card face self.setFaceUp = function (isUp) { self.isFaceUp = isUp; if (isUp) { overlay.alpha = 1; txt.alpha = 1; } else { overlay.alpha = 0.2; txt.alpha = 0; } }; // For click/tap detection self.down = function (x, y, obj) { // Allow player to play a card by tapping a card in their hand if (self.owner === 'player' && self.isFaceUp && canPlayCard && !roundCards.player) { playPlayerCard(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x22223a }); /**** * Game Code ****/ // --- Game Data --- var cardTypes = ['human', 'elf', 'orc']; var subTypes = ['warrior', 'archer', 'wizard']; // All 9 unique cards var allCards = []; for (var i = 0; i < cardTypes.length; i++) { for (var j = 0; j < subTypes.length; j++) { allCards.push({ cardType: cardTypes[i], subType: subTypes[j], cardIndex: i * 3 + j }); } } // Location data // Each location has a name, color, and a list of cardType+subType combos that get +1 point var locations = [{ name: 'Castle', color: 0x607d8b, bonuses: [{ cardType: 'human', subType: 'archer' }, { cardType: 'human', subType: 'mage' }, { cardType: 'human', subType: 'warrior' }, { cardType: 'elf', subType: 'warrior' }, { cardType: 'orc', subType: 'warrior' }] }, { name: 'Forest', color: 0x4caf50, bonuses: [{ cardType: 'elf', subType: 'archer' }, { cardType: 'elf', subType: 'mage' }, { cardType: 'elf', subType: 'archer' }, // duplicate, but harmless { cardType: 'human', subType: 'archer' }, { cardType: 'orc', subType: 'archer' }] }, { name: 'Cave', color: 0x795548, bonuses: [{ cardType: 'orc', subType: 'mage' }, { cardType: 'orc', subType: 'warrior' }, { cardType: 'orc', subType: 'archer' }, { cardType: 'human', subType: 'mage' }, { cardType: 'elf', subType: 'mage' }] }]; // --- Game State --- var playerHand = []; var bot1Hand = []; var bot2Hand = []; var playerScore = 0; var bot1Score = 0; var bot2Score = 0; var round = 1; var maxRounds = 3; var canPlayCard = false; var roundCards = { player: null, bot1: null, bot2: null }; var roundLocation = null; var allCardObjs = []; // All Card instances for cleanup var locationNode = null; var infoText = null; var scoreText = null; var roundText = null; // --- GUI Setup --- // Info text (center top) infoText = new Text2('Triad Arena: Card Clash', { size: 90, fill: "#fff" }); infoText.anchor.set(0.5, 0); LK.gui.top.addChild(infoText); // Score text (center bottom) scoreText = new Text2('', { size: 70, fill: "#fff" }); scoreText.anchor.set(0.5, 1); LK.gui.bottom.addChild(scoreText); // Round text (center) roundText = new Text2('', { size: 80, fill: "#fff" }); roundText.anchor.set(0.5, 0.5); LK.gui.center.addChild(roundText); // --- Helper Functions --- function shuffle(arr) { // Fisher-Yates shuffle for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var t = arr[i]; arr[i] = arr[j]; arr[j] = t; } return arr; } function dealHands() { var deck = allCards.slice(); shuffle(deck); playerHand = deck.slice(0, 3); bot1Hand = deck.slice(3, 6); bot2Hand = deck.slice(6, 9); } function updateScoreText() { scoreText.setText("You: " + playerScore + " Bot1: " + bot1Score + " Bot2: " + bot2Score); } function updateRoundText(msg) { if (msg) { roundText.setText(msg); } else { roundText.setText("Round " + round + " / " + maxRounds); } } function clearBoard() { for (var i = 0; i < allCardObjs.length; i++) { allCardObjs[i].destroy(); } allCardObjs = []; if (locationNode) { locationNode.destroy(); locationNode = null; } if (typeof nextRoundButton !== "undefined" && nextRoundButton) { nextRoundButton.destroy(); nextRoundButton = null; } } function showLocation(location) { // Show location in center locationNode = LK.getAsset('locationBg', { width: 600, height: 200, color: location.color, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 350 }); game.addChild(locationNode); var locText = new Text2(location.name, { size: 90, fill: "#fff" }); locText.anchor.set(0.5, 0.5); locText.x = 0; locText.y = 0; locationNode.addChild(locText); // Bonus info var bonusStr = "Bonuses:"; for (var i = 0; i < location.bonuses.length; i++) { var b = location.bonuses[i]; bonusStr += "\n" + b.cardType.charAt(0).toUpperCase() + b.cardType.slice(1) + "-" + b.subType.charAt(0).toUpperCase() + b.subType.slice(1); } var bonusText = new Text2(bonusStr, { size: 50, fill: "#fff" }); bonusText.anchor.set(0.5, 0.5); bonusText.x = 0; bonusText.y = 70; locationNode.addChild(bonusText); } function layoutHands() { // Player hand (bottom) var spacing = 400; var startX = 2048 / 2 - spacing; var y = 2732 - 400; for (var i = 0; i < playerHand.length; i++) { var c = new Card(); c.setCard(playerHand[i].cardType, playerHand[i].subType, 'player', playerHand[i].cardIndex); c.x = startX + i * spacing; c.y = y; // Show player's hand face up so the player can see their cards c.setFaceUp(true); game.addChild(c); allCardObjs.push(c); } // Bot1 hand (top) y = 400; for (var i = 0; i < bot1Hand.length; i++) { var c = new Card(); c.setCard(bot1Hand[i].cardType, bot1Hand[i].subType, 'bot1', bot1Hand[i].cardIndex); c.x = startX + i * spacing; c.y = y; c.setFaceUp(false); game.addChild(c); allCardObjs.push(c); } // Bot2 hand (left) var x = 400; var spacingY = 400; var startY = 2732 / 2 - spacingY; for (var i = 0; i < bot2Hand.length; i++) { var c = new Card(); c.setCard(bot2Hand[i].cardType, bot2Hand[i].subType, 'bot2', bot2Hand[i].cardIndex); c.x = x; c.y = startY + i * spacingY; c.setFaceUp(false); game.addChild(c); allCardObjs.push(c); } } function playPlayerCard(cardObj) { if (!canPlayCard || roundCards.player) return; canPlayCard = false; roundCards.player = cardObj; cardObj.setFaceUp(true); // Animate to center tween(cardObj, { x: 2048 / 2 - 300, y: 2732 / 2 + 250 }, { duration: 400, easing: tween.cubicOut }); // Remove from hand for (var i = 0; i < playerHand.length; i++) { if (playerHand[i].cardIndex === cardObj.cardIndex) { playerHand.splice(i, 1); break; } } // Bots play after short delay LK.setTimeout(function () { playBotCards(); }, 500); } function playBotCards() { // Bot1: pick random card var idx1 = Math.floor(Math.random() * bot1Hand.length); var card1 = null; for (var i = 0; i < allCardObjs.length; i++) { if (allCardObjs[i].owner === 'bot1' && allCardObjs[i].cardIndex === bot1Hand[idx1].cardIndex) { card1 = allCardObjs[i]; break; } } roundCards.bot1 = card1; card1.setFaceUp(true); tween(card1, { x: 2048 / 2, y: 2732 / 2 - 250 }, { duration: 400, easing: tween.cubicOut }); bot1Hand.splice(idx1, 1); // Bot2: pick random card var idx2 = Math.floor(Math.random() * bot2Hand.length); var card2 = null; for (var i = 0; i < allCardObjs.length; i++) { if (allCardObjs[i].owner === 'bot2' && allCardObjs[i].cardIndex === bot2Hand[idx2].cardIndex) { card2 = allCardObjs[i]; break; } } roundCards.bot2 = card2; card2.setFaceUp(true); tween(card2, { x: 2048 / 2 + 300, y: 2732 / 2 + 250 }, { duration: 400, easing: tween.cubicOut }); bot2Hand.splice(idx2, 1); // Reveal location after short delay LK.setTimeout(function () { revealLocationAndScore(); }, 700); } function revealLocationAndScore() { // Pick random location roundLocation = locations[Math.floor(Math.random() * locations.length)]; showLocation(roundLocation); // Calculate points var pts = { player: 0, bot1: 0, bot2: 0 }; var bonus = roundLocation.bonus; // Each card: 1 point base, +1 if matches a bonus combo for this location function calcCardPoints(card) { var p = 1; for (var i = 0; i < roundLocation.bonuses.length; i++) { var b = roundLocation.bonuses[i]; if (card.cardType === b.cardType && card.subType === b.subType) { p += 1; break; } } return p; } pts.player = calcCardPoints(roundCards.player); pts.bot1 = calcCardPoints(roundCards.bot1); pts.bot2 = calcCardPoints(roundCards.bot2); // Animate cards (flash winner) var maxPts = Math.max(pts.player, pts.bot1, pts.bot2); if (pts.player === maxPts) { LK.effects.flashObject(roundCards.player, 0xffff00, 700); } if (pts.bot1 === maxPts) { LK.effects.flashObject(roundCards.bot1, 0xffff00, 700); } if (pts.bot2 === maxPts) { LK.effects.flashObject(roundCards.bot2, 0xffff00, 700); } // Update scores playerScore += pts.player; bot1Score += pts.bot1; bot2Score += pts.bot2; updateScoreText(); // Show round result var msg = "You: +" + pts.player + " Bot1: +" + pts.bot1 + " Bot2: +" + pts.bot2; updateRoundText(msg); // Next round or end: wait for player to press Next Round button function showNextRoundButton() { // Remove if already exists if (typeof nextRoundButton !== "undefined" && nextRoundButton) { nextRoundButton.destroy(); nextRoundButton = null; } nextRoundButton = LK.getAsset('next-round-button', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 600 }); var btnText = new Text2("Next Round", { size: 70, fill: "#fff" }); btnText.anchor.set(0.5, 0.5); btnText.x = 0; btnText.y = 0; nextRoundButton.addChild(btnText); nextRoundButton.interactive = true; nextRoundButton.buttonMode = true; nextRoundButton.visible = true; nextRoundButton.alpha = 1; nextRoundButton.down = function (x, y, obj) { if (nextRoundButton) { nextRoundButton.destroy(); nextRoundButton = null; } round++; if (round > maxRounds) { endGame(); } else { startRound(); } }; LK.gui.center.addChild(nextRoundButton); } showNextRoundButton(); } function startRound() { clearBoard(); roundCards = { player: null, bot1: null, bot2: null }; roundLocation = null; canPlayCard = true; updateScoreText(); updateRoundText(); layoutHands(); infoText.setText("Pick a card to play!"); } function endGame() { clearBoard(); canPlayCard = false; var winner = ''; if (playerScore > bot1Score && playerScore > bot2Score) { winner = "You win!"; LK.showYouWin(); } else if (playerScore === bot1Score && playerScore === bot2Score) { winner = "It's a 3-way tie!"; LK.showGameOver(); } else if (playerScore === bot1Score && playerScore > bot2Score) { winner = "Tie with Bot1!"; LK.showGameOver(); } else if (playerScore === bot2Score && playerScore > bot1Score) { winner = "Tie with Bot2!"; LK.showGameOver(); } else if (bot1Score > playerScore && bot1Score > bot2Score) { winner = "Bot1 wins!"; LK.showGameOver(); } else if (bot2Score > playerScore && bot2Score > bot1Score) { winner = "Bot2 wins!"; LK.showGameOver(); } else { winner = "Game Over!"; LK.showGameOver(); } infoText.setText(winner); updateRoundText(''); if (typeof nextRoundButton !== "undefined" && nextRoundButton) { nextRoundButton.destroy(); nextRoundButton = null; } } // --- Game Start --- // Track which locations have been used this game var availableLocations = []; function newGame() { playerScore = 0; bot1Score = 0; bot2Score = 0; round = 1; canPlayCard = false; roundCards = { player: null, bot1: null, bot2: null }; roundLocation = null; clearBoard(); dealHands(); updateScoreText(); updateRoundText(); infoText.setText("Pick a card to play!"); layoutHands(); canPlayCard = true; // Reset available locations for the new game availableLocations = locations.slice(); // Show M button for location reveal showMButton(); } // M button for revealing location var mButton = null; var nextRoundButton = null; function showMButton() { if (mButton) { mButton.destroy(); mButton = null; } mButton = new Text2('M', { size: 120, fill: "#fff" }); mButton.anchor.set(0.5, 0.5); // Place at center top, but not in top left 100x100 mButton.x = 2048 / 2; mButton.y = 200; mButton.interactive = true; mButton.buttonMode = true; mButton.alpha = 1; mButton.visible = true; mButton.down = function (x, y, obj) { // Only allow if all cards are played and location not yet revealed if (roundCards.player && roundCards.bot1 && roundCards.bot2 && !roundLocation) { mButton.visible = false; mButton.alpha = 0; revealLocationAndScore(); } }; LK.gui.top.addChild(mButton); } // Override revealLocationAndScore to ensure unique locations per round newGame(); // --- Game move handler (for drag, not used here) --- game.move = function (x, y, obj) { // No drag in this game };
===================================================================
--- original.js
+++ change.js
@@ -246,8 +246,12 @@
if (locationNode) {
locationNode.destroy();
locationNode = null;
}
+ if (typeof nextRoundButton !== "undefined" && nextRoundButton) {
+ nextRoundButton.destroy();
+ nextRoundButton = null;
+ }
}
function showLocation(location) {
// Show location in center
locationNode = LK.getAsset('locationBg', {
@@ -437,17 +441,48 @@
updateScoreText();
// Show round result
var msg = "You: +" + pts.player + " Bot1: +" + pts.bot1 + " Bot2: +" + pts.bot2;
updateRoundText(msg);
- // Next round or end after delay
- LK.setTimeout(function () {
- round++;
- if (round > maxRounds) {
- endGame();
- } else {
- startRound();
+ // Next round or end: wait for player to press Next Round button
+ function showNextRoundButton() {
+ // Remove if already exists
+ if (typeof nextRoundButton !== "undefined" && nextRoundButton) {
+ nextRoundButton.destroy();
+ nextRoundButton = null;
}
- }, 1500);
+ nextRoundButton = LK.getAsset('next-round-button', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 2048 / 2,
+ y: 2732 / 2 + 600
+ });
+ var btnText = new Text2("Next Round", {
+ size: 70,
+ fill: "#fff"
+ });
+ btnText.anchor.set(0.5, 0.5);
+ btnText.x = 0;
+ btnText.y = 0;
+ nextRoundButton.addChild(btnText);
+ nextRoundButton.interactive = true;
+ nextRoundButton.buttonMode = true;
+ nextRoundButton.visible = true;
+ nextRoundButton.alpha = 1;
+ nextRoundButton.down = function (x, y, obj) {
+ if (nextRoundButton) {
+ nextRoundButton.destroy();
+ nextRoundButton = null;
+ }
+ round++;
+ if (round > maxRounds) {
+ endGame();
+ } else {
+ startRound();
+ }
+ };
+ LK.gui.center.addChild(nextRoundButton);
+ }
+ showNextRoundButton();
}
function startRound() {
clearBoard();
roundCards = {
@@ -489,8 +524,12 @@
LK.showGameOver();
}
infoText.setText(winner);
updateRoundText('');
+ if (typeof nextRoundButton !== "undefined" && nextRoundButton) {
+ nextRoundButton.destroy();
+ nextRoundButton = null;
+ }
}
// --- Game Start ---
// Track which locations have been used this game
var availableLocations = [];
@@ -519,8 +558,9 @@
showMButton();
}
// M button for revealing location
var mButton = null;
+var nextRoundButton = null;
function showMButton() {
if (mButton) {
mButton.destroy();
mButton = null;
@@ -551,13 +591,5 @@
newGame();
// --- Game move handler (for drag, not used here) ---
game.move = function (x, y, obj) {
// No drag in this game
-};
-// --- Next Round Button (always visible, top right corner) ---
-var nextRoundButton = LK.getAsset('next-round-button', {
- anchorX: 1,
- anchorY: 0,
- x: 2048 - 20,
- y: 20
-});
-LK.gui.topRight.addChild(nextRoundButton);
\ No newline at end of file
+};
\ No newline at end of file