User prompt
Make the cards positioning adjust to the cards size
User prompt
Set to only receive xp for playing when the player beats the memory game
User prompt
Set the game to be pet game to be paused while playing the memory game
User prompt
Using this aproach create a memory game ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fix the error trying all that issues
Code edit (5 edits merged)
Please save this source code
User prompt
Refactor the code in the creation of the cards only for the memory game, dont change anything else
Code edit (2 edits merged)
Please save this source code
User prompt
The cards are not showing with the memory game window
User prompt
Set the cards game title to always be at the top of the memoryGame background window and the window x to close to bet outside the top right position of the memory game window background ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Make the playPwt window Bigger and squared, and set to show the cards centered above to the playPetWindow
User prompt
Create and add images for the cards in the memory game
Code edit (5 edits merged)
Please save this source code
User prompt
When the player clicks the play with pet action button it should appear a small window in front of the game with the memory game, and the player has to conclude that game to give the pet played xp, the new window should be set like this: var playPetWindow = new Container(); //Create the elements for the memory game; playPetWindow.AddChild(memoryGameElements); When canPlayPet and player clicks in the playpet action button playPetWindow.setVisible = true; When player beats the game playPetWindow.setVisible = false; Each time the player plays that memory game the cards must be frontside down, and in a different random places
Code edit (1 edits merged)
Please save this source code
User prompt
You must save the poop, hunger and bored state of the pet ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Remake the whole function to allow to play with pet. It should have a bool variable canplay, if true, the play with pet button works, if false the button doesnt perform the action. It starts as true, then the player can play, when player plays it it sets to false, and only sets to true again when the bored message appears
User prompt
Remake the whole function to allow to feed pet. It should have a bool variable canFeedPet, if true, the feed pet button works, if false the button doesnt perform the action. It starts as true, then the player can feed, when player feeds it it sets to false, and only sets to true again when hunger message appears
User prompt
The pet can be fed once if not hungry
User prompt
The can feed the pet once before the pet is hungry
User prompt
Set to be able to feed the pet once before the hunger message appears
User prompt
Set to only be able to play with pet once before the bored speech bubble appears
User prompt
Set to only be able to clean the pet after it poops
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { petLevel: 1, petXp: 0, lastFed: 0, lastCleaned: 0, lastPlayed: 0 }); /**** * Classes ****/ var ActionButton = Container.expand(function (actionType, position) { var self = Container.call(this); var buttonShape; if (actionType === 'feed') { buttonShape = self.attachAsset('foodItem', { anchorX: 0.5, anchorY: 0.5 }); } else if (actionType === 'clean') { buttonShape = self.attachAsset('cleaningItem', { anchorX: 0.5, anchorY: 0.5 }); } else if (actionType === 'play') { buttonShape = self.attachAsset('playItem', { anchorX: 0.5, anchorY: 0.5 }); } self.buttonType = actionType; self.interactive = true; self.down = function (x, y, obj) { tween(buttonShape, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(buttonShape, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { if (self.buttonType === 'feed') { performFeedAction(); } else if (self.buttonType === 'clean') { performCleanAction(); } else if (self.buttonType === 'play') { performPlayAction(); } } }); }; return self; }); var BubbleSpeech = Container.expand(function (text) { var self = Container.call(this); // Create the bubble background var bubbleBackground = LK.getAsset('bubble_speech', { anchorX: 0.5, anchorY: 0.5, width: 600, height: 600, tint: 0xFFFFFF }); // Round the corners by scaling bubbleBackground.scale.set(1); self.addChild(bubbleBackground); // Add text to bubble var bubbleText = new Text2(text || "", { size: 80, fill: 0x000000, align: "center", // You can set alignment to "left", "center", or "right" wordWrap: true, wordWrapWidth: 800 // Set this to control where text will wra }); bubbleText.anchor.set(0.5, 0.5); self.addChild(bubbleText); // Public methods self.setText = function (newText) { bubbleText.setText(newText); }; // Show with animation self.show = function (duration) { self.alpha = 0; self.scale.set(0.5); tween(self, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: duration || 300, easing: tween.easeOutBack }); }; // Hide with animation self.hide = function (duration, callback) { tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: duration || 300, easing: tween.easeInBack, onFinish: function onFinish() { if (callback) { callback(); } } }); }; return self; }); var MainMenu = Container.expand(function () { var self = Container.call(this); // Background image var background = self.attachAsset('menu_background', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; // Game logo var gameLogo = self.attachAsset('game_logo', { anchorX: 0.5, anchorY: 0.5 }); gameLogo.x = 2048 / 2; gameLogo.y = 800; // Play button image var playButton = self.attachAsset('play_button', { anchorX: 0.5, anchorY: 0.5 }); playButton.x = 2048 / 2; playButton.y = 2732 / 2 + 200; playButton.interactive = true; // Reset button var resetButton = new Text2("Reset Game", { size: 60, fill: 0xFFFFFF }); resetButton.anchor.set(0.5, 0.5); resetButton.x = 2048 / 2; resetButton.y = 2732 / 2 + 400; resetButton.interactive = true; self.addChild(resetButton); // Button animations and interaction playButton.down = function (x, y, obj) { tween(playButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; playButton.up = function (x, y, obj) { tween(playButton, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { if (self.onStartGame) { self.onStartGame(); } } }); }; // Reset button interactions resetButton.down = function (x, y, obj) { tween(resetButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; resetButton.up = function (x, y, obj) { tween(resetButton, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { if (self.onResetGame) { self.onResetGame(); } } }); }; // Add some animation to the logo function animateLogo() { tween(gameLogo, { y: gameLogo.y - 15 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(gameLogo, { y: gameLogo.y + 15 }, { duration: 1500, easing: tween.easeInOut, onFinish: animateLogo }); } }); } // Start the animation animateLogo(); return self; }); var MemoryCard = Container.expand(function (cardValue, cardBack) { var self = Container.call(this); self.value = cardValue; // Card match value self.revealed = false; // Is card face up self.matched = false; // Is card matched // Create card front (colored shape) self.front = LK.getAsset('memory_card_' + cardValue, { anchorX: 0.5, anchorY: 0.5 }); self.front.visible = false; self.addChild(self.front); // Create card back self.back = LK.getAsset('memory_card_back', { anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.back); // Make card interactive self.interactive = true; // Flip card to show front self.reveal = function () { if (self.matched || self.revealed) return; // Already revealed or matched self.revealed = true; // Animate card flip tween(self.scale, { x: 0 }, { duration: 150, easing: tween.easeInQuad, onFinish: function onFinish() { self.front.visible = true; self.back.visible = false; tween(self.scale, { x: 1 }, { duration: 150, easing: tween.easeOutQuad }); } }); if (self.onReveal) { self.onReveal(self); } }; // Flip card to hide front self.hide = function () { if (self.matched) return; // Don't hide if matched // Animate card flip tween(self.scale, { x: 0 }, { duration: 150, easing: tween.easeInQuad, onFinish: function onFinish() { self.front.visible = false; self.back.visible = true; self.revealed = false; tween(self.scale, { x: 1 }, { duration: 150, easing: tween.easeOutQuad }); } }); }; // Mark card as matched self.setMatched = function () { self.matched = true; self.interactive = false; // Flash effect for matching tween(self, { alpha: 0.5 }, { duration: 200, easing: tween.easeInQuad, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 200, easing: tween.easeOutQuad }); } }); }; // Handle card click self.down = function (x, y, obj) { if (self.matched || self.revealed || !self.interactive) return; tween(self, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; self.up = function (x, y, obj) { if (self.matched || !self.interactive) return; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { self.reveal(); } }); }; return self; }); var MemoryGame = Container.expand(function () { var self = Container.call(this); // Game state variables var selectedCards = []; var matchedPairs = 0; var totalPairs = 8; var canSelect = true; var movesMade = 0; // Create cards array var cards = []; // Create semi-transparent background var gameBackground = LK.getAsset('memory_card_back', { anchorX: 0.5, anchorY: 0.5, width: 2000, height: 1600, tint: 0x000000 }); gameBackground.alpha = 0.7; self.addChild(gameBackground); // Title text var titleText = new Text2("Memory Game", { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.y = -600; self.addChild(titleText); // Moves counter var movesText = new Text2("Moves: 0", { size: 60, fill: 0xFFFFFF }); movesText.anchor.set(0.5, 0.5); movesText.y = -500; self.addChild(movesText); // Setup the game self.startGame = function () { // Reset game state selectedCards = []; matchedPairs = 0; movesMade = 0; canSelect = true; // Create card values (pairs of 1-8) var values = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]; // Shuffle the array for (var i = values.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = values[i]; values[i] = values[j]; values[j] = temp; } // Create and position cards in a 4x4 grid var gridSize = 4; // Create a temp card to measure actual size var tempCard = new MemoryCard(1); // Calculate spacing based on actual card dimensions var cardWidth = tempCard.back.width; var cardHeight = tempCard.back.height; var cardSpacing = cardWidth * 1.2; // Add 20% of width as spacing // Calculate starting coordinates using actual card dimensions var startX = -((gridSize - 1) * cardSpacing) / 2; var startY = -((gridSize - 1) * cardSpacing) / 2; // Clean up temp card tempCard = null; for (var row = 0; row < gridSize; row++) { for (var col = 0; col < gridSize; col++) { var index = row * gridSize + col; var card = new MemoryCard(values[index]); // Position card in grid using dynamic spacing based on card size card.x = startX + col * cardSpacing; card.y = startY + row * cardSpacing; // Set up reveal callback card.onReveal = handleCardReveal; // Add to game self.addChild(card); cards.push(card); } } // Update moves display updateMovesText(); // Fade in animation self.alpha = 0; tween(self, { alpha: 1 }, { duration: 500 }); }; // Handle card reveal function handleCardReveal(card) { if (!canSelect) return; // Add card to selected cards selectedCards.push(card); // If we have 2 cards selected if (selectedCards.length === 2) { canSelect = false; movesMade++; updateMovesText(); // Check for match if (selectedCards[0].value === selectedCards[1].value) { // Match found! selectedCards[0].setMatched(); selectedCards[1].setMatched(); matchedPairs++; // Clear selection selectedCards = []; canSelect = true; // Check if game is complete if (matchedPairs === totalPairs) { // Game won! LK.setTimeout(function () { endGame(); }, 500); } } else { // No match, flip cards back after a delay LK.setTimeout(function () { selectedCards[0].hide(); selectedCards[1].hide(); selectedCards = []; canSelect = true; }, 1000); } } } // Update moves text function updateMovesText() { movesText.setText("Moves: " + movesMade); } // End the game function endGame() { // Calculate score (higher for fewer moves) var baseScore = 100; var movesPenalty = Math.min(80, movesMade * 2); var finalScore = Math.max(20, baseScore - movesPenalty); // Show winning message var winText = new Text2("Memory Game Complete!\nScore: " + finalScore, { size: 80, fill: 0xFFFFFF, align: "center" }); winText.anchor.set(0.5, 0.5); self.addChild(winText); // Animate text winText.scale.set(0); tween(winText.scale, { x: 1, y: 1 }, { duration: 500, easing: tween.elasticOut }); // Close after delay LK.setTimeout(function () { // Fade out animation tween(self, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (self.onComplete) { self.onComplete(finalScore); } // Remove all cards for (var i = 0; i < cards.length; i++) { self.removeChild(cards[i]); } cards = []; // Remove win text self.removeChild(winText); // Remove self from parent if (self.parent) { self.parent.removeChild(self); } } }); }, 2000); } // Close button var closeButton = new Text2("X", { size: 80, fill: 0xFFFFFF }); closeButton.anchor.set(0.5, 0.5); closeButton.x = 900; closeButton.y = -700; closeButton.interactive = true; self.addChild(closeButton); closeButton.down = function () { tween(closeButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; closeButton.up = function () { tween(closeButton, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { // Fade out and close tween(self, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { // Calculate partial score var partialScore = Math.max(5, matchedPairs * 10); if (self.onComplete) { self.onComplete(partialScore); } // Remove all cards for (var i = 0; i < cards.length; i++) { self.removeChild(cards[i]); } cards = []; // Remove self from parent if (self.parent) { self.parent.removeChild(self); } } }); } }); }; // Center the game on screen self.x = 2048 / 2; self.y = 2732 / 2; // Start the game self.startGame(); return self; }); var Pet = Container.expand(function () { var self = Container.call(this); var currentLevel = storage.petLevel || 1; var petAssetId = 'pet_baby'; // Determine which asset to use based on level if (currentLevel === 1) { petAssetId = 'pet_baby'; } else if (currentLevel === 2) { petAssetId = 'pet_child'; } else if (currentLevel === 3) { petAssetId = 'pet_teen'; } else if (currentLevel >= 4) { petAssetId = 'pet_adult'; } var petGraphics = self.attachAsset(petAssetId, { anchorX: 0.5, anchorY: 0.5 }); self.happy = function () { // Bounce animation tween(self, { y: self.y - 50 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: self.y + 50 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { petPosition.x = self.x; petPosition.y = self.y; } }); } }); }; self.evolve = function () { // Evolution animation LK.getSound('evolve').play(); // Flash and grow LK.effects.flashObject(self, 0xFFFFFF, 1000); tween(petGraphics, { scaleX: 1.5, scaleY: 1.5 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Update to new visual based on new level currentLevel = storage.petLevel; var newPetAssetId; if (currentLevel === 2) { newPetAssetId = 'pet_child'; } else if (currentLevel === 3) { newPetAssetId = 'pet_teen'; } else if (currentLevel >= 4) { newPetAssetId = 'pet_adult'; } // Remove old graphic and add new one self.removeChild(petGraphics); petGraphics = self.attachAsset(newPetAssetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); // Reset scale with animation tween(petGraphics, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); } }); }; return self; }); var Poop = Container.expand(function () { var self = Container.call(this); // Create poop visual using a single image var poopGraphics = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, tint: 0x8B4513 // Brown color }); // Add appear animation self.appear = function () { self.scale.set(0); tween(self, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.bounceOut }); }; // Add cleanup animation self.cleanup = function (callback) { tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeInBack, onFinish: function onFinish() { if (callback) { callback(); } } }); }; return self; }); var StatusText = Text2.expand(function (initialText) { var self = Text2.call(this, initialText, { size: 60, fill: 0xFFFFFF }); self.anchor.set(0.5, 0.5); self.showMessage = function (message) { self.setText(message); self.alpha = 1; tween(self, { alpha: 0 }, { duration: 3000, easing: tween.linear }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x7ED6DF }); /**** * Game Code ****/ // Game state - load these first var petLevel = storage.petLevel || 1; var petXp = storage.petXp || 0; var lastFed = storage.lastFed || 0; var lastCleaned = storage.lastCleaned || 0; var lastPlayed = storage.lastPlayed || 0; // Load pet state flags from storage var isHungry = storage.isHungry !== undefined ? storage.isHungry : false; var isBored = storage.isBored !== undefined ? storage.isBored : false; var hasActivePoop = storage.hasActivePoop !== undefined ? storage.hasActivePoop : false; var canFeedPet = !isHungry; // Initialize feeding state based on hunger var canPlayPet = !isBored; // Initialize play state based on boredom var speechBubble; // Variable for the speech bubble var hungerTimer; // Timer for hunger message var timeToHungry = 15000; var xpLossTimer; // Timer for XP loss after not feeding var XP_LOSS_TIMEOUT = 120000; // 5 minutes (300000ms) var XP_LOSS_AMOUNT = 50; // Amount of XP to lose var poopTimer; // Timer for when pet will poop var poopSpawnTime = 30000; // 2 minutes (120000ms) var activePoop = null; // Reference to the active poop object var poopSpeechTimer; // Timer for poop speech bubble var poopXpLossTimer; // Timer for XP loss from uncleaned poop var POOP_SPEECH_TIMEOUT = 60000; // 1 minute (60000ms) var POOP_XP_LOSS_TIMEOUT = 120000; // 2 minutes (120000ms) var boredTimer; // Timer for boredom message var timeToBored = 45000; // 1.5 minutes (90000ms) var boredXpLossTimer; // Timer for XP loss when bored var BORED_XP_LOSS_TIMEOUT = 90000; // 4 minutes (240000ms) // Define game constants - calculate after loading state var BASE_XP_PER_LEVEL = 500; var XP_PER_LEVEL = BASE_XP_PER_LEVEL * Math.pow(2, petLevel - 1); // Doubles with each level var XP_GAIN_FEED = 20; var XP_GAIN_CLEAN = 15; var XP_GAIN_PLAY = 25; var COOLDOWN_TIME = 10000; // 10 seconds cooldown between actions var XP_LOSS_INTERVAL = 180000; // 3 minutes interval for XP loss if player doesn't play with pet var PLAY_INACTIVITY_XP_LOSS = 15; // Amount of XP to lose from play inactivity var playInactivityInterval; // Interval for recurring XP loss due to play inactivity var hpText; // Define hpText in global scope var barFill; // Define barFill in global scope var barBackground; // Define barBackground in global scope // Vector2 positions for pet at different evolution levels var petBabyPosition = { x: 2048 / 2, y: 2732 / 2 + 250 }; var petChildPosition = { x: 2048 / 2, y: 2732 / 2 + 200 }; var petTeenPosition = { x: 2048 / 2, y: 2732 / 2 + 150 }; var petAdultPosition = { x: 2048 / 2, y: 2732 / 2 + 150 }; // Track current game state var progressBar = new Container(); var currentScreen = "menu"; var mainMenu, pet, progressBar, statusText, levelText; var feedButton, cleanButton, playButton; var progressBarContainer = new Container(); // Current pet position based on level var petPosition = petBabyPosition; // Initialize menu function initMainMenu() { // Clear previous game elements if they exist clearGameElements(); // Create and setup main menu mainMenu = new MainMenu(); game.addChild(mainMenu); // Set up start game callback mainMenu.onStartGame = function () { currentScreen = "game"; initGameScreen(); }; // Set up reset game callback mainMenu.onResetGame = function () { // Reset all storage values storage.petLevel = 1; storage.petXp = 0; storage.lastFed = 0; storage.lastCleaned = 0; storage.lastPlayed = 0; storage.isHungry = false; storage.isBored = false; storage.hasActivePoop = false; // Show confirmation text var confirmText = new Text2("Game data reset!", { size: 60, fill: 0xFFFFFF }); confirmText.anchor.set(0.5, 0.5); confirmText.x = 2048 / 2; confirmText.y = 2732 / 2 + 500; mainMenu.addChild(confirmText); // Fade out confirmation text tween(confirmText, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { mainMenu.removeChild(confirmText); } }); }; // Play background music LK.playMusic('bgmusic'); } // Initialize game screen function initGameScreen() { console.log("Initializing game screen"); // Clear previous elements clearGameElements(); // Add game background var gameBackground = LK.getAsset('game_background', { anchorX: 0.5, anchorY: 0.5 }); gameBackground.x = 2048 / 2; gameBackground.y = 2732 / 2; game.addChild(gameBackground); // Create game elements pet = new Pet(); pet.x = petPosition.x; pet.y = petPosition.y; game.addChild(pet); // Level text levelText = new Text2("Level " + petLevel, { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = 2048 / 2; levelText.y = 200; game.addChild(levelText); // Create action buttons feedButton = new ActionButton('feed'); feedButton.x = 2048 / 4; feedButton.y = 2732 - 400; game.addChild(feedButton); cleanButton = new ActionButton('clean'); cleanButton.x = 2048 / 2; cleanButton.y = 2732 - 400; game.addChild(cleanButton); playButton = new ActionButton('play'); playButton.x = 2048 * 3 / 4; playButton.y = 2732 - 400; game.addChild(playButton); // Recalculate XP_PER_LEVEL based on current level XP_PER_LEVEL = BASE_XP_PER_LEVEL * Math.pow(2, petLevel - 1); console.log("Current petLevel:", petLevel, "XP_PER_LEVEL:", XP_PER_LEVEL); // Make sure all values are calculated before updating progress bar XP_PER_LEVEL = BASE_XP_PER_LEVEL * Math.pow(2, petLevel - 1); // Update the progress bar on start console.log("Initial progress bar update with petXp:", petXp, "XP_PER_LEVEL:", XP_PER_LEVEL); // Make sure variables are initialized properly petXp = petXp || 0; XP_PER_LEVEL = XP_PER_LEVEL || BASE_XP_PER_LEVEL; // Now create HP text after progress bar exists hpText = new Text2("XP: " + petXp + "/" + XP_PER_LEVEL, { size: 60, fill: 0xFFFFFF }); hpText.anchor.set(0, 0.5); hpText.x = progressBar.x + 10; hpText.y = progressBar.y - 50; game.addChild(hpText); // Create HP text display console.log("Creating HP text with petXp:", petXp, "XP_PER_LEVEL:", XP_PER_LEVEL); hpText = new Text2("XP: " + petXp + "/" + XP_PER_LEVEL, { size: 60, fill: 0xFFFFFF }); hpText.anchor.set(0, 0.5); game.addChild(hpText); console.log("Game screen initialization complete"); createProgressBar(); addBarFillXp(); // Status text statusText = new StatusText(""); statusText.x = 2048 / 2; statusText.y = progressBar.y + 100; statusText.alpha = 0; game.addChild(statusText); // Create speech bubble for hunger message speechBubble = new BubbleSpeech("I'm hungry!"); speechBubble.x = pet.x + 450; speechBubble.y = pet.y - 450; // Position above pet speechBubble.alpha = 0; // Start invisible game.addChild(speechBubble); // Initialize state based on saved values if (isHungry) { speechBubble.setText("I'm hungry!"); speechBubble.show(500); canFeedPet = true; } if (isBored) { speechBubble.setText("I'm bored! \n Play with me!"); speechBubble.show(500); canPlayPet = true; } if (hasActivePoop) { // Create poop if it was active when game was closed activePoop = new Poop(); activePoop.x = pet.x + Math.random() * 1000; activePoop.y = pet.y + 100 + Math.random() * 50; game.addChild(activePoop); activePoop.appear(); } // Clear any existing timer if (hungerTimer) { LK.clearTimeout(hungerTimer); } // Set timer to show hunger bubble after 1 minute (60000ms) hungerTimer = LK.setTimeout(function () { // Show speech bubble with animation game.addChild(speechBubble); // Make sure it's in the display tree // Set canFeedPet to true when hunger message appears canFeedPet = true; // Save hunger state in storage storage.isHungry = true; speechBubble.show(500); console.log("Pet is now hungry - canFeedPet set to true"); }, timeToHungry); // Set timer for XP loss after 5 minutes of not feeding xpLossTimer = LK.setTimeout(function () { // Only deduct XP if pet has any if (petXp > 0) { addXp(-XP_LOSS_AMOUNT); // Deduct XP statusText.showMessage("Pet is hungry! Lost " + XP_LOSS_AMOUNT + " XP!"); } }, XP_LOSS_TIMEOUT); // Set timer to show boredom bubble after 1.5 minutes boredTimer = LK.setTimeout(function () { // Change speech bubble text to boredom message speechBubble.setText("I'm bored! \n Play with me!"); // Set canPlayPet to true when boredom message appears canPlayPet = true; // Update boredom state in storage storage.isBored = true; // Show speech bubble with animation speechBubble.show(500); console.log("Pet is bored - canPlayPet set to true"); }, timeToBored); // Set timer for XP loss after 4 minutes of not playing boredXpLossTimer = LK.setTimeout(function () { // Only deduct XP if pet has any if (petXp > 0) { addXp(-XP_LOSS_AMOUNT); // Deduct XP statusText.showMessage("Pet is bored! Lost " + XP_LOSS_AMOUNT + " XP!"); } }, BORED_XP_LOSS_TIMEOUT); // Set up recurring XP loss every 3 minutes if player doesn't play with pet playInactivityInterval = LK.setInterval(function () { // Calculate time since last played var currentTime = Date.now(); var timeSinceLastPlayed = currentTime - lastPlayed; // If it's been more than 5 minutes since last played if (timeSinceLastPlayed > 300000 && petXp > 0) { // Deduct XP addXp(-PLAY_INACTIVITY_XP_LOSS); statusText.showMessage("Your pet misses you! Lost " + PLAY_INACTIVITY_XP_LOSS + " XP!"); // Show speech bubble about missing play time speechBubble.setText("I miss playing with you!"); speechBubble.show(500); // Hide speech bubble after 3 seconds LK.setTimeout(function () { speechBubble.hide(300); }, 3000); } }, XP_LOSS_INTERVAL); } //[3J] // Clear all game elements function clearGameElements() { // Clear hunger timer if exists if (hungerTimer) { LK.clearTimeout(hungerTimer); hungerTimer = null; } // Clear XP loss timer if exists if (xpLossTimer) { LK.clearTimeout(xpLossTimer); xpLossTimer = null; } // Clear poop timer if exists if (poopTimer) { LK.clearTimeout(poopTimer); poopTimer = null; } // Clear poop speech timer if exists if (poopSpeechTimer) { LK.clearTimeout(poopSpeechTimer); poopSpeechTimer = null; } // Clear poop XP loss timer if exists if (poopXpLossTimer) { LK.clearTimeout(poopXpLossTimer); poopXpLossTimer = null; } // Clear bored timer if exists if (boredTimer) { LK.clearTimeout(boredTimer); boredTimer = null; } // Clear bored XP loss timer if exists if (boredXpLossTimer) { LK.clearTimeout(boredXpLossTimer); boredXpLossTimer = null; } // Clear play inactivity interval if exists if (playInactivityInterval) { LK.clearInterval(playInactivityInterval); playInactivityInterval = null; } // Reset active poop reference activePoop = null; while (game.children.length > 0) { game.removeChild(game.children[0]); } //[3K] } //[3L] // Start with main menu initMainMenu(); // Play background music LK.playMusic('bgmusic'); function performFeedAction() { console.log("performFeedAction called"); var currentTime = Date.now(); //[3O] // Check if pet is recently fed (on cooldown) if (currentTime - lastFed < COOLDOWN_TIME) { statusText.showMessage("Pet is still full! Wait a moment."); console.log("Action on cooldown, can't feed yet"); return; //[3P] } //[3Q] // Check if feeding is allowed using canFeedPet variable if (!canFeedPet) { statusText.showMessage("Pet isn't hungry yet!"); console.log("Pet can't be fed yet - canFeedPet is false"); return; } // If hunger message is showing, we can feed the pet if (speechBubble && speechBubble.alpha > 0 && speechBubble.text === "I'm hungry!") { // Pet is hungry with message showing, continue with feeding } else if (!canFeedPet) { statusText.showMessage("Pet isn't hungry yet!"); console.log("Pet isn't hungry yet"); return; } console.log("Feeding pet, adding XP:", XP_GAIN_FEED); LK.getSound('feed').play(); pet.happy(); //[3R] lastFed = currentTime; storage.lastFed = lastFed; addXp(XP_GAIN_FEED); console.log("After addXp call"); statusText.showMessage("Pet fed! +20 XP"); // Set canFeedPet to false after feeding canFeedPet = false; // Update hunger state in storage storage.isHungry = false; // Hide hunger speech bubble if visible if (speechBubble && speechBubble.alpha > 0) { speechBubble.hide(300); } // Reset hunger timer if (hungerTimer) { LK.clearTimeout(hungerTimer); } hungerTimer = LK.setTimeout(function () { // Show speech bubble with animation speechBubble.show(500); // Set canFeedPet to true when hunger message appears again canFeedPet = true; // Update hunger state in storage storage.isHungry = true; console.log("Pet is hungry again - canFeedPet set to true"); }, 60000); // Reset XP loss timer when feeding if (xpLossTimer) { LK.clearTimeout(xpLossTimer); } xpLossTimer = LK.setTimeout(function () { if (petXp > 0) { addXp(-XP_LOSS_AMOUNT); statusText.showMessage("Pet is hungry! Lost " + XP_LOSS_AMOUNT + " XP!"); } }, XP_LOSS_TIMEOUT); // Set timer for pet to poop after being fed if (poopTimer) { LK.clearTimeout(poopTimer); } poopTimer = LK.setTimeout(function () { // Only create poop if there isn't one already if (!activePoop) { // Create new poop slightly behind the pet activePoop = new Poop(); activePoop.x = pet.x + Math.random() * 1000; // Random position near pet activePoop.y = pet.y + 100 + Math.random() * 50; game.addChild(activePoop); activePoop.appear(); // Update poop state in storage storage.hasActivePoop = true; // Create a speech bubble for the poop event speechBubble.setText("I made a mess!"); speechBubble.show(500); // Hide speech bubble after 3 seconds LK.setTimeout(function () { speechBubble.hide(300); }, 3000); // Set timer to show clean up reminder after 1 minute if (poopSpeechTimer) { LK.clearTimeout(poopSpeechTimer); } poopSpeechTimer = LK.setTimeout(function () { speechBubble.setText("Please clean \nthis mess!"); speechBubble.show(500); }, POOP_SPEECH_TIMEOUT); // Set timer for XP loss after 2 minutes of not cleaning if (poopXpLossTimer) { LK.clearTimeout(poopXpLossTimer); } poopXpLossTimer = LK.setTimeout(function () { // Set up recurring XP loss every 2 minutes until cleaned var loseXpInterval = LK.setInterval(function () { if (activePoop) { if (petXp > 0) { addXp(-XP_LOSS_AMOUNT); statusText.showMessage("Pet uncomfortable! Lost " + XP_LOSS_AMOUNT + " XP!"); // Show speech bubble about being uncomfortable speechBubble.setText("This mess is making me lose XP!"); speechBubble.show(500); LK.setTimeout(function () { speechBubble.hide(300); }, 3000); } } else { // Clear interval if poop is gone LK.clearInterval(loseXpInterval); } }, POOP_XP_LOSS_TIMEOUT); }, POOP_XP_LOSS_TIMEOUT); } }, poopSpawnTime); } //[3S] function performCleanAction() { var currentTime = Date.now(); if (currentTime - lastCleaned < COOLDOWN_TIME) { statusText.showMessage("Pet is already clean! Wait a moment."); return; } // Check if there's poop to clean if (activePoop) { LK.getSound('clean').play(); pet.happy(); lastCleaned = currentTime; storage.lastCleaned = lastCleaned; // Add extra XP for cleaning poop addXp(XP_GAIN_CLEAN * 2); statusText.showMessage("Poop cleaned! +30 XP"); // Animate poop cleanup activePoop.cleanup(function () { if (activePoop && activePoop.parent) { activePoop.parent.removeChild(activePoop); } // Clear poop speech bubble timer if (poopSpeechTimer) { LK.clearTimeout(poopSpeechTimer); poopSpeechTimer = null; } // Clear poop XP loss timer if (poopXpLossTimer) { LK.clearTimeout(poopXpLossTimer); poopXpLossTimer = null; } activePoop = null; // Update poop state in storage storage.hasActivePoop = false; }); // Pet is happy about cleaning LK.setTimeout(function () { speechBubble.setText("Thank you!"); speechBubble.show(500); // Hide speech bubble after 2 seconds LK.setTimeout(function () { speechBubble.hide(300); }, 2000); }, 500); } else { // Don't allow cleaning if there's no poop statusText.showMessage("Nothing to clean right now!"); } } function performPlayAction() { var currentTime = Date.now(); if (currentTime - lastPlayed < COOLDOWN_TIME) { statusText.showMessage("Pet is tired! Wait a moment."); return; } // Check if playing is allowed using canPlayPet variable if (!canPlayPet) { statusText.showMessage("Pet isn't bored yet!"); console.log("Pet can't be played with yet - canPlayPet is false"); return; } // If pet is bored with message showing, proceed with playing // Otherwise, we'll still allow one play action before requiring the boredom message LK.getSound('play').play(); pet.happy(); lastPlayed = currentTime; storage.lastPlayed = lastPlayed; // Launch memory game instead of immediately adding XP speechBubble.setText("Let's play a memory game!"); speechBubble.show(500); // Pause all timers before starting memory game var savedTimers = { hungerTimer: hungerTimer, xpLossTimer: xpLossTimer, boredTimer: boredTimer, boredXpLossTimer: boredXpLossTimer, poopTimer: poopTimer, poopSpeechTimer: poopSpeechTimer, poopXpLossTimer: poopXpLossTimer }; // Clear all active timers if (hungerTimer) LK.clearTimeout(hungerTimer); if (xpLossTimer) LK.clearTimeout(xpLossTimer); if (boredTimer) LK.clearTimeout(boredTimer); if (boredXpLossTimer) LK.clearTimeout(boredXpLossTimer); if (poopTimer) LK.clearTimeout(poopTimer); if (poopSpeechTimer) LK.clearTimeout(poopSpeechTimer); if (poopXpLossTimer) LK.clearTimeout(poopXpLossTimer); if (playInactivityInterval) LK.clearInterval(playInactivityInterval); // Create and start memory game var memoryGame = new MemoryGame(); game.addChild(memoryGame); // Handle game completion memoryGame.onComplete = function (score) { // Only add XP if the player actually completes the memory game with a non-zero score if (score > 0) { // Add XP based on score (higher score = more XP) var earnedXp = XP_GAIN_PLAY + score; addXp(earnedXp); statusText.showMessage("Played memory game! +" + earnedXp + " XP"); // Tell player how they did speechBubble.setText("That was fun! You earned " + earnedXp + " XP!"); } else { // Player quit or didn't earn any points statusText.showMessage("Try again to earn XP!"); speechBubble.setText("Let's try again next time!"); } // Pet is happy after game pet.happy(); speechBubble.show(500); // Hide speech bubble after a few seconds LK.setTimeout(function () { speechBubble.hide(300); }, 3000); // Set canPlayPet to false after playing canPlayPet = false; // Update boredom state in storage storage.isBored = false; // Reset boredom timer if (boredTimer) { LK.clearTimeout(boredTimer); } boredTimer = LK.setTimeout(function () { // Show speech bubble with animation speechBubble.setText("I'm bored! \n Play with me!"); speechBubble.show(500); // Set canPlayPet to true when boredom message appears canPlayPet = true; // Update boredom state in storage storage.isBored = true; console.log("Pet is bored again - canPlayPet set to true"); }, timeToBored); }; // Reset bored XP loss timer if (boredXpLossTimer) { LK.clearTimeout(boredXpLossTimer); } boredXpLossTimer = LK.setTimeout(function () { if (petXp > 0) { addXp(-XP_LOSS_AMOUNT); statusText.showMessage("Pet is bored! Lost " + XP_LOSS_AMOUNT + " XP!"); } }, BORED_XP_LOSS_TIMEOUT); // Reset play inactivity interval to prevent additional XP loss if (playInactivityInterval) { LK.clearInterval(playInactivityInterval); playInactivityInterval = LK.setInterval(function () { var currentTime = Date.now(); var timeSinceLastPlayed = currentTime - lastPlayed; if (timeSinceLastPlayed > 300000 && petXp > 0) { addXp(-PLAY_INACTIVITY_XP_LOSS); statusText.showMessage("Your pet misses you! Lost " + PLAY_INACTIVITY_XP_LOSS + " XP!"); speechBubble.setText("I miss playing `\n with you!"); speechBubble.show(500); LK.setTimeout(function () { speechBubble.hide(300); }, 3000); } }, XP_LOSS_INTERVAL); } } function addXp(amount) { console.log("addXp called with amount:", amount); petXp += amount; storage.petXp = petXp; // Check for level up if (petXp >= XP_PER_LEVEL) { console.log("Level up condition met!"); petLevel += 1; petXp = 0; storage.petLevel = petLevel; storage.petXp = petXp; // Recalculate XP_PER_LEVEL for next level - doubles with each level XP_PER_LEVEL = BASE_XP_PER_LEVEL * Math.pow(2, petLevel - 1); console.log("New level:", petLevel, "New XP_PER_LEVEL:", XP_PER_LEVEL); // Update pet position based on new level if (petLevel === 2) { petPosition = petChildPosition; } else if (petLevel === 3) { petPosition = petTeenPosition; } else if (petLevel >= 4) { petPosition = petAdultPosition; } // Update pet position pet.x = petPosition.x; pet.y = petPosition.y; levelText.setText("Level " + petLevel); pet.evolve(); if (petLevel >= 4) { statusText.showMessage("Maximum level reached!"); } else { statusText.showMessage("Pet evolved to level " + petLevel + "! Next level: " + XP_PER_LEVEL + " XP"); } } // Update the HP text with current XP if (hpText) { hpText.setText("XP: " + petXp + "/" + XP_PER_LEVEL); } else { console.log("hpText is undefined or null"); } addBarFillXp(); } function createProgressBar() { // Initialize position first progressBar.x = 2048 / 2 - 400; // Center it progressBar.y = 2732 - 200; // Near bottom barBackground = LK.getAsset('progressBar_bg', { anchorX: 0, anchorY: 0.5 }); progressBar.addChild(barBackground); barFill = LK.getAsset('progressBar_fill', { anchorX: 0, anchorY: 0.5 }); progressBar.addChild(barFill); // Add progress bar to game game.addChild(progressBar); // Update hpText position now that progressBar exists if (hpText) { hpText.x = progressBar.x + 10; hpText.y = progressBar.y - 50; } } function addBarFillXp() { // Store current width to animate from var currentWidth = barFill.width; // Calculate target width var targetWidth = petXp / XP_PER_LEVEL * barBackground.width; // Animate the width change tween(barFill, { width: targetWidth }, { duration: 800, easing: tween.easeOutQuad }); } // Game update function game.update = function () { // Screen-specific updates if (currentScreen === "game") { // Ensure we're not continuously updating the progress bar every frame // This was the source of the undefined parameters call } };
===================================================================
--- original.js
+++ change.js
@@ -384,16 +384,24 @@
values[j] = temp;
}
// Create and position cards in a 4x4 grid
var gridSize = 4;
- var cardSpacing = 170;
+ // Create a temp card to measure actual size
+ var tempCard = new MemoryCard(1);
+ // Calculate spacing based on actual card dimensions
+ var cardWidth = tempCard.back.width;
+ var cardHeight = tempCard.back.height;
+ var cardSpacing = cardWidth * 1.2; // Add 20% of width as spacing
+ // Calculate starting coordinates using actual card dimensions
var startX = -((gridSize - 1) * cardSpacing) / 2;
var startY = -((gridSize - 1) * cardSpacing) / 2;
+ // Clean up temp card
+ tempCard = null;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var index = row * gridSize + col;
var card = new MemoryCard(values[index]);
- // Position card in grid
+ // Position card in grid using dynamic spacing based on card size
card.x = startX + col * cardSpacing;
card.y = startY + row * cardSpacing;
// Set up reveal callback
card.onReveal = handleCardReveal;
create a cute creature baby. In-Game asset. 2d. High contrast. No shadows
create a cute logo with Pocket Creature written. In-Game asset. 2d. High contrast. No shadows
create a cute button with play written inside. In-Game asset. 2d. High contrast. No shadows
create a cute room, lo fi room. In-Game asset. 2d. High contrast. No shadows
create a cute icon for cleaning item. In-Game asset. 2d. High contrast. No shadows
reimagine as a food item
Generate a smaller younger version of this character
Generate a smaller younger and cute version of this
Zoom out so it doesnt cut any elements off screen
Reimagine as younger cute version of this character
Reimagine as a younger cute version of this character
Reimagine as a cute younger version of this character
zoom out so it doesnt cut any elements off screen, make the outline thicker
Make a drawing of a cute poop. In-Game asset. 2d. High contrast. No shadows
Create an image for a memory game's card's back. In-Game asset. 2d. High contrast. No shadows
Create an image for a memory game's card's front with an icon of a play ball. In-Game asset. 2d. High contrast. No shadows
Create an image for a memory game's card's front with an icon of a chicken leg food. In-Game asset. 2d. High contrast. No shadows
Create an image for a memory game's card's front with an icon of a cute poop. In-Game asset. 2d. High contrast. No shadows
Create an image for a memory game's card's front with an icon of a cute pocket creature. In-Game asset. 2d. High contrast. No shadows
create a cute egg with some pattern and a peach and bege colors. In-Game asset. 2d. High contrast. No shadows
create a cute egg with some pattern and a light orange and light red colors. In-Game asset. 2d. High contrast. No shadows
simplify the eyes
Create a cute speech bubble with a heart. In-Game asset. 2d. High contrast. No shadows