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) {
var self = Container.call(this);
// Card properties
self.cardValue = cardValue;
self.isFlipped = false;
self.isMatched = false;
// Card back (shown when card is face down)
var cardBack = self.attachAsset('memory_card_back', {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 150
});
// Card front (shows the card value)
var cardFront = self.attachAsset('memory_card_' + cardValue, {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 150
});
cardFront.alpha = 0; // Hidden initially
// Make card interactive
self.interactive = true;
// Flip card function
self.flip = function (callback) {
self.isFlipped = !self.isFlipped;
// Scale down in X direction
tween(self, {
scaleX: 0
}, {
duration: 150,
easing: tween.easeInQuad,
onFinish: function onFinish() {
// Change visibility of front/back
cardBack.alpha = self.isFlipped ? 0 : 1;
cardFront.alpha = self.isFlipped ? 1 : 0;
// Scale back up in X direction
tween(self, {
scaleX: 1
}, {
duration: 150,
easing: tween.easeOutQuad,
onFinish: callback
});
}
});
};
// Handle card selection
self.down = function (x, y, obj) {
// Only respond if card is face down and not already matched
if (!self.isFlipped && !self.isMatched && memoryGame.canFlip) {
self.flip(function () {
// Notify game that this card was flipped
if (memoryGame && memoryGame.onCardFlipped) {
memoryGame.onCardFlipped(self);
}
});
}
};
// Mark card as matched
self.setMatched = function () {
self.isMatched = true;
// Highlight matched card with a subtle animation
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
};
// Get appropriate image for card value
function getCardImage(value) {
return 'memory_card_' + value;
}
return self;
});
var MemoryGame = Container.expand(function () {
var self = Container.call(this);
// Game properties
var cardValues = [];
var cards = [];
var firstCard = null;
var secondCard = null;
var matchesFound = 0;
var totalPairs = 0;
var isCheckingMatch = false;
self.canFlip = true;
// Game container
var gameContainer = new Container();
self.addChild(gameContainer);
// Background
var background = self.attachAsset('pet_playing', {
anchorX: 0.5,
anchorY: 0.5,
width: 1500,
height: 2000,
tint: 0x2c3e50 // Dark blue background
});
// Title
var gameTitle = new Text2("Match the Cards", {
size: 50,
fill: 0xFFFFFF,
align: "center"
});
gameTitle.anchor.set(0.5, 0);
gameTitle.y = -background.height / 2 + 50; // Position at the top of the window
self.addChild(gameTitle);
// Close button
var closeButton = new Text2("X", {
size: 50,
fill: 0xFFFFFF
});
closeButton.anchor.set(0.5, 0.5);
closeButton.x = background.width / 2 + 50; // Position outside the top right of the window
closeButton.y = -background.height / 2 + 50; // Align with the title
closeButton.interactive = true;
self.addChild(closeButton);
// Close button interaction
closeButton.down = function () {
if (self.onClose) {
self.onClose(false); // False means player didn't win
}
};
// Create memory game with given difficulty (number of pairs)
self.createGame = function (numPairs) {
// Reset game state
totalPairs = numPairs;
matchesFound = 0;
firstCard = null;
secondCard = null;
self.canFlip = true;
// Clear existing cards
while (gameContainer.children.length > 0) {
gameContainer.removeChild(gameContainer.children[0]);
}
// Create card values (pairs of numbers)
cardValues = [];
for (var i = 1; i <= numPairs; i++) {
cardValues.push(i);
cardValues.push(i);
}
// Shuffle card values
shuffleArray(cardValues);
// Create cards
cards = [];
var cols = numPairs <= 4 ? 4 : 4;
var rows = Math.ceil(numPairs * 2 / cols);
var cardWidth = 160;
var cardHeight = 160;
var startX = -((cols - 1) * cardWidth) / 2;
var startY = -((rows - 1) * cardHeight) / 2;
for (var i = 0; i < cardValues.length; i++) {
var col = i % cols;
var row = Math.floor(i / cols);
var card = new MemoryCard(cardValues[i]);
card.x = startX + col * cardWidth;
card.y = startY + row * cardHeight;
cards.push(card);
gameContainer.addChild(card);
}
};
// Card flipped handler
self.onCardFlipped = function (card) {
// If we're currently checking a match or card is already part of a match, ignore
if (isCheckingMatch || card.isMatched) {
return;
}
// First card flipped
if (firstCard === null) {
firstCard = card;
return;
}
// Second card flipped
secondCard = card;
// Can't flip more cards while checking
self.canFlip = false;
isCheckingMatch = true;
// Check if cards match
if (firstCard.cardValue === secondCard.cardValue) {
// Match found
firstCard.setMatched();
secondCard.setMatched();
matchesFound++;
// Check if game is complete
if (matchesFound === totalPairs) {
// Game won
LK.setTimeout(function () {
if (self.onGameComplete) {
self.onGameComplete();
}
}, 1000);
}
// Reset for next pair
firstCard = null;
secondCard = null;
isCheckingMatch = false;
self.canFlip = true;
} else {
// No match - flip cards back after delay
LK.setTimeout(function () {
firstCard.flip();
secondCard.flip();
firstCard = null;
secondCard = null;
isCheckingMatch = false;
self.canFlip = true;
}, 1000);
}
};
// Fisher-Yates shuffle algorithm
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
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)
// Memory game variables
var memoryGame = null;
var playPetWindow = new Container();
var isPlayingMemoryGame = false;
// 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;
// Clean up memory game
isPlayingMemoryGame = false;
memoryGame = null;
if (playPetWindow.parent) {
playPetWindow.parent.removeChild(playPetWindow);
}
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();
// Check if already playing the memory game
if (isPlayingMemoryGame) {
return;
}
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;
}
// Show memory game window instead of immediately completing play action
isPlayingMemoryGame = true;
// Create memory game if it doesn't exist
memoryGame = new MemoryGame();
memoryGame.x = 2048 / 2;
memoryGame.y = 2732 / 2;
// Set number of pairs based on pet level (increasing difficulty)
var numPairs = Math.min(8, petLevel + 3);
memoryGame.createGame(numPairs);
// Handle game completion
memoryGame.onGameComplete = function () {
// Complete play action
completePlayAction(currentTime);
// Show success message
var successText = new Text2("Great job!", {
size: 80,
fill: 0xFFFFFF
});
successText.anchor.set(0.5, 0.5);
successText.x = 0;
successText.y = 0;
memoryGame.addChild(successText);
// Hide game after delay
LK.setTimeout(function () {
hideMemoryGame(true);
}, 1500);
};
// Handle manual close
memoryGame.onClose = function (playerWon) {
hideMemoryGame(playerWon);
};
// Add memory game to window
playPetWindow.removeChildren();
playPetWindow.addChild(memoryGame);
// Show window
playPetWindow.x = 0;
playPetWindow.y = 0;
playPetWindow.alpha = 0;
playPetWindow.scale.set(0.5);
game.addChild(playPetWindow);
// Animate window appearance
tween(playPetWindow, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOutBack
});
}
// Function to hide memory game window
function hideMemoryGame(playerWon) {
// Animate window disappearance
tween(playPetWindow, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeInBack,
onFinish: function onFinish() {
if (playPetWindow.parent) {
playPetWindow.parent.removeChild(playPetWindow);
}
isPlayingMemoryGame = false;
}
});
}
// Function to complete the play action after winning memory game
function completePlayAction(currentTime) {
LK.getSound('play').play();
pet.happy();
lastPlayed = currentTime;
storage.lastPlayed = lastPlayed;
addXp(XP_GAIN_PLAY);
statusText.showMessage("Played with pet! +25 XP");
// Set canPlayPet to false after playing
canPlayPet = false;
// Update boredom state in storage
storage.isBored = false;
// Hide boredom speech bubble if visible
if (speechBubble && speechBubble.alpha > 0) {
speechBubble.hide(300);
}
// 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
@@ -321,10 +321,10 @@
// Background
var background = self.attachAsset('pet_playing', {
anchorX: 0.5,
anchorY: 0.5,
- width: 800,
- height: 600,
+ width: 1500,
+ height: 2000,
tint: 0x2c3e50 // Dark blue background
});
// Title
var gameTitle = new Text2("Match the Cards", {
@@ -332,18 +332,18 @@
fill: 0xFFFFFF,
align: "center"
});
gameTitle.anchor.set(0.5, 0);
- gameTitle.y = -250;
+ gameTitle.y = -background.height / 2 + 50; // Position at the top of the window
self.addChild(gameTitle);
// Close button
var closeButton = new Text2("X", {
size: 50,
fill: 0xFFFFFF
});
closeButton.anchor.set(0.5, 0.5);
- closeButton.x = 350;
- closeButton.y = -250;
+ closeButton.x = background.width / 2 + 50; // Position outside the top right of the window
+ closeButton.y = -background.height / 2 + 50; // Align with the title
closeButton.interactive = true;
self.addChild(closeButton);
// Close button interaction
closeButton.down = function () {
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