/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { created: "undefined", lastVisit: "undefined", hunger: 100, happiness: 100, cleanliness: 100, health: 100, alive: true, discoveredCodes: [] }); /**** * Classes ****/ var Button = Container.expand(function (text, color) { var self = Container.call(this); var bg = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); if (color) { bg.tint = color; } var label = new Text2(text, { size: 60, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.down = function () { tween(bg.scale, { x: 0.95, y: 0.95 }, { duration: 100, easing: tween.easeOut }); }; self.up = function () { tween(bg.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); }; return self; }); var CodeInput = Container.expand(function () { var self = Container.call(this); var bg = self.attachAsset('codeInput', { anchorX: 0.5, anchorY: 0.5 }); self.currentCode = ""; var codeText = new Text2("CODE: ", { size: 60, fill: 0x333333 }); codeText.anchor.set(0.5, 0.5); self.addChild(codeText); self.updateText = function () { codeText.setText("CODE: " + self.currentCode); }; self.addCharacter = function (_char) { if (self.currentCode.length < 10) { self.currentCode += _char; self.updateText(); } }; self.backspace = function () { if (self.currentCode.length > 0) { self.currentCode = self.currentCode.slice(0, -1); self.updateText(); } }; self.clear = function () { self.currentCode = ""; self.updateText(); }; self.checkCode = function () { var lowerCode = self.currentCode.toLowerCase(); // Check if code has already been discovered if (storage.discoveredCodes.indexOf(lowerCode) !== -1) { return false; } // Validate code against known codes var isValid = false; if (lowerCode === "revenge") { showMessage("The dead shall rise..."); isValid = true; } else if (lowerCode === "sun" && storage.discoveredCodes.indexOf("revenge") !== -1) { showMessage("The power of life is yours!"); isValid = true; if (!pet.alive) { pet.resurrect(); } } else if (lowerCode === "eternity") { showMessage("Time stands still..."); isValid = true; } else if (lowerCode === "genesis") { showMessage("A new beginning..."); isValid = true; } else if (lowerCode === "void") { showMessage("Emptiness consumes..."); isValid = true; } if (isValid) { // Save the discovered code storage.discoveredCodes.push(lowerCode); LK.getSound('secretFound').play(); return true; } return false; }; return self; }); var Keyboard = Container.expand(function (codeInput) { var self = Container.call(this); var keys = ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM⌫"]; var keySize = 80; var spacing = 10; var currentY = 0; keys.forEach(function (row, rowIndex) { var rowWidth = row.length * (keySize + spacing) - spacing; var startX = -rowWidth / 2; for (var i = 0; i < row.length; i++) { var key = row[i]; var keyButton = new Container(); var keyBg = LK.getAsset('button', { anchorX: 0.5, anchorY: 0.5, width: keySize, height: keySize, tint: 0x555555 }); keyButton.addChild(keyBg); var keyText = new Text2(key, { size: 40, fill: 0xFFFFFF }); keyText.anchor.set(0.5, 0.5); keyButton.addChild(keyText); keyButton.x = startX + i * (keySize + spacing) + keySize / 2; keyButton.y = currentY; keyButton.key = key; keyButton.interactive = true; keyButton.buttonMode = true; keyButton.down = function () { if (this.key === "⌫") { codeInput.backspace(); } else { codeInput.addCharacter(this.key); } LK.getSound('codeEntered').play(); tween(this.scale, { x: 0.9, y: 0.9 }, { duration: 100, easing: tween.easeOut }); }; keyButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); }; self.addChild(keyButton); } currentY += keySize + spacing; }); // Add submit button var submitButton = new Button("SUBMIT", 0x4CAF50); submitButton.y = currentY + 20; submitButton.down = function () { tween(this.scale, { x: 0.95, y: 0.95 }, { duration: 100, easing: tween.easeOut }); }; submitButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); if (codeInput.checkCode()) { codeInput.clear(); } }; self.addChild(submitButton); // Add clear button var clearButton = new Button("CLEAR", 0xF44336); clearButton.x = -180; clearButton.y = currentY + 20; clearButton.down = function () { tween(this.scale, { x: 0.95, y: 0.95 }, { duration: 100, easing: tween.easeOut }); }; clearButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); codeInput.clear(); }; self.addChild(clearButton); return self; }); var Pet = Container.expand(function () { var self = Container.call(this); // Variables to track pet state self.hunger = storage.hunger; self.happiness = storage.happiness; self.cleanliness = storage.cleanliness; self.health = storage.health; self.alive = storage.alive; self.moods = ["normal", "happy", "sad", "sick", "dead"]; self.currentMood = "normal"; self.blinkTimer = 0; self.mouthMoveTimer = 0; self.mouthOpen = false; // Create pet body var body = self.attachAsset('petBody', { anchorX: 0.5, anchorY: 0.5 }); // Define leftEye and rightEye as assets for the pet self.leftEye = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: -100, // Adjust position as needed y: -100 // Adjust position as needed }); self.rightEye = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: 100, // Adjust position as needed y: -100 // Adjust position as needed }); // Define mouth as an asset for the pet self.mouth = self.attachAsset('petMouth', { anchorX: 0.5, anchorY: 0.5, y: 100 // Adjust position as needed }); // Create pet face self.body = body; // Interactions self.feed = function () { if (!self.alive) { return; } self.hunger = Math.min(100, self.hunger + 30); self.health = Math.min(100, self.health + 5); // Animate eating self.mouthOpen = true; self.updateMouthState(); LK.setTimeout(function () { self.mouthOpen = false; self.updateMouthState(); }, 500); LK.getSound('eat').play(); self.updateStats(); }; self.play = function () { if (!self.alive) { return; } self.happiness = Math.min(100, self.happiness + 30); self.hunger = Math.max(0, self.hunger - 5); // Animate playing tween(self, { rotation: 0.1 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: -0.1 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: 0 }, { duration: 200, easing: tween.easeInOut }); } }); } }); LK.getSound('play').play(); self.updateStats(); }; self.clean = function () { if (!self.alive) { return; } self.cleanliness = Math.min(100, self.cleanliness + 30); // Animate cleaning tween(self.body, { tint: 0x87CEEB }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.body, { tint: 0xF5DEB3 }, { duration: 500, easing: tween.easeInOut }); } }); LK.getSound('wash').play(); self.updateStats(); }; self.updateStats = function () { // Update all stats in storage storage.hunger = self.hunger; storage.happiness = self.happiness; storage.cleanliness = self.cleanliness; storage.health = self.health; storage.alive = self.alive; // Calculate health based on other stats if (self.alive) { self.health = Math.max(0, self.health - (self.hunger < 20 ? 10 : 0) - (self.happiness < 20 ? 10 : 0) - (self.cleanliness < 20 ? 10 : 0)); if (self.health <= 0) { self.die(); } } // Update mood self.updateMood(); }; self.updateMood = function () { var oldMood = self.currentMood; if (!self.alive) { self.currentMood = "dead"; } else if (self.health < 30) { self.currentMood = "sick"; } else if (self.hunger < 30 || self.happiness < 30 || self.cleanliness < 30) { self.currentMood = "sad"; } else if (self.hunger > 80 && self.happiness > 80 && self.cleanliness > 80) { self.currentMood = "happy"; } else { self.currentMood = "normal"; } // Update visual appearance based on mood if (oldMood !== self.currentMood) { self.updateAppearance(); } }; self.updateAppearance = function () { // Reset any previous animations or effects tween.stop(self.body); tween.stop(self.leftEye); tween.stop(self.rightEye); tween.stop(self.mouth); self.body.tint = 0xF5DEB3; self.body.scale.set(1, 1); self.leftEye.scale.set(1, 1); self.rightEye.scale.set(1, 1); self.mouth.scale.set(1, 0.5); // Apply mood-specific appearance switch (self.currentMood) { case "happy": self.mouth.scale.set(1, 0.75); self.mouth.y = 120; LK.getSound('happy').play(); break; case "sad": self.mouth.scale.set(1, 0.25); self.mouth.y = 150; LK.getSound('sad').play(); break; case "sick": self.body.tint = 0xADD8E6; break; case "dead": self.leftEye.scale.set(1, 0.1); self.rightEye.scale.set(1, 0.1); self.mouth.scale.set(1, 0.1); self.body.tint = 0xCCCCCC; self.mouth.rotation = Math.PI; break; default: // normal self.mouth.scale.set(1, 0.5); self.mouth.y = 100; break; } }; self.updateMouthState = function () { if (self.mouthOpen) { self.mouth.scale.set(1, 1); } else { self.updateAppearance(); // Reset to mood-appropriate appearance } }; self.animateBlink = function () { tween(self.leftEye.scale, { y: 0.1 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(self.leftEye.scale, { y: 1 }, { duration: 100, easing: tween.linear }); } }); tween(self.rightEye.scale, { y: 0.1 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(self.rightEye.scale, { y: 1 }, { duration: 100, easing: tween.linear }); } }); }; self.die = function () { if (!self.alive) { return; } self.alive = false; storage.alive = false; // Show death animation LK.effects.flashScreen(0xFF0000, 1000); // Update appearance to show dead pet self.updateMood(); }; self.resurrect = function () { self.alive = true; storage.alive = true; self.hunger = 100; storage.hunger = 100; self.happiness = 100; storage.happiness = 100; self.cleanliness = 100; storage.cleanliness = 100; self.health = 100; storage.health = 100; // Show resurrection animation LK.effects.flashScreen(0xFFFF00, 1000); // Update appearance self.updateMood(); }; self.update = function () { if (!self.alive) { return; } // Decrease stats over time (slower rate) if (LK.ticks % 60 === 0) { // Once per second self.hunger = Math.max(0, self.hunger - 0.1); self.happiness = Math.max(0, self.happiness - 0.1); self.cleanliness = Math.max(0, self.cleanliness - 0.05); self.updateStats(); } // Occasional blinking self.blinkTimer++; if (self.blinkTimer > 180 && Math.random() < 0.02) { self.animateBlink(); self.blinkTimer = 0; } // Random mouth movements when happy if (self.currentMood === "happy" && Math.random() < 0.005) { self.mouthOpen = !self.mouthOpen; self.updateMouthState(); } }; // Initialize appearance self.updateMood(); return self; }); var StatBar = Container.expand(function (label) { var self = Container.call(this); var bg = self.attachAsset('statBar', { anchorX: 0, anchorY: 0.5 }); var fill = self.attachAsset('statFill', { anchorX: 0, anchorY: 0.5, x: 5, y: 0 }); var text = new Text2(label, { size: 40, fill: 0xFFFFFF }); text.anchor.set(0, 0.5); text.x = 10; self.addChild(text); self.setValue = function (value) { // Calculate fill width based on percentage var maxWidth = 490; var newWidth = Math.max(0, Math.min(maxWidth, maxWidth * (value / 100))); // Animate the transition tween(fill, { width: newWidth }, { duration: 300, easing: tween.easeOut }); // Update fill color based on value if (value > 70) { fill.tint = 0x4CAF50; // Green } else if (value > 30) { fill.tint = 0xFFC107; // Yellow } else { fill.tint = 0xF44336; // Red } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xE0F7FA }); /**** * Game Code ****/ // Track game state var isDragging = false; var dragObject = null; var isCodeMode = false; var messageTimeout = null; // Create pet instance var pet = game.addChild(new Pet()); pet.x = 2048 / 2; pet.y = 900; // Check time between sessions var currentTime = Date.now(); if (storage.lastVisit !== null) { var timeDifference = (currentTime - storage.lastVisit) / 1000 / 60; // in minutes // Reduce stats based on time away if (pet.alive && timeDifference > 5) { // Decay stats based on time away (capped at certain values to prevent instant death) var hungerDecay = Math.min(80, timeDifference / 15); var happinessDecay = Math.min(80, timeDifference / 20); var cleanlinessDecay = Math.min(80, timeDifference / 30); pet.hunger = Math.max(10, pet.hunger - hungerDecay); pet.happiness = Math.max(10, pet.happiness - happinessDecay); pet.cleanliness = Math.max(10, pet.cleanliness - cleanlinessDecay); // If away too long, health decreases dramatically if (timeDifference > 1440) { // More than 24 hours pet.health = Math.max(0, pet.health - 80); } else if (timeDifference > 720) { // More than 12 hours pet.health = Math.max(0, pet.health - 40); } else if (timeDifference > 360) { // More than 6 hours pet.health = Math.max(0, pet.health - 20); } pet.updateStats(); } } // Update the last visit time storage.lastVisit = currentTime; // If this is the first run, set created time if (storage.created === null) { storage.created = currentTime; } // Create stat bars var hungerBar = game.addChild(new StatBar("Hunger")); hungerBar.x = 200; hungerBar.y = 200; hungerBar.setValue(pet.hunger); var happinessBar = game.addChild(new StatBar("Happiness")); happinessBar.x = 200; happinessBar.y = 300; happinessBar.setValue(pet.happiness); var cleanlinessBar = game.addChild(new StatBar("Cleanliness")); cleanlinessBar.x = 200; cleanlinessBar.y = 400; cleanlinessBar.setValue(pet.cleanliness); var healthBar = game.addChild(new StatBar("Health")); healthBar.x = 200; healthBar.y = 500; healthBar.setValue(pet.health); // Create interaction buttons var feedButton = game.addChild(new Button("Feed", 0xE74C3C)); feedButton.x = 400; feedButton.y = 650; feedButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); if (!isCodeMode) { pet.feed(); } }; var playButton = game.addChild(new Button("Play", 0xF1C40F)); playButton.x = 1024; playButton.y = 650; playButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); if (!isCodeMode) { pet.play(); } }; var cleanButton = game.addChild(new Button("Clean", 0x3498DB)); cleanButton.x = 1648; cleanButton.y = 650; cleanButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); if (!isCodeMode) { pet.clean(); } }; // Create code button var codeButton = game.addChild(new Button("Codes", 0x9B59B6)); codeButton.x = 1024; codeButton.y = 2550; codeButton.up = function () { tween(this.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut }); toggleCodeMode(); }; // Create code input interface (initially hidden) var codeInput = game.addChild(new CodeInput()); codeInput.x = 1024; codeInput.y = 1600; codeInput.visible = false; var keyboard = game.addChild(new Keyboard(codeInput)); keyboard.x = 1024; keyboard.y = 1800; keyboard.visible = false; // Create info text var infoText = new Text2("Care for your pet or it will die permanently!", { size: 50, fill: 0x333333 }); infoText.anchor.set(0.5, 0); infoText.x = 1024; infoText.y = 50; game.addChild(infoText); // Create message text (for code responses) var messageText = new Text2("", { size: 60, fill: 0xFF0000 }); messageText.anchor.set(0.5, 0); messageText.x = 1024; messageText.y = 120; messageText.visible = false; game.addChild(messageText); // Function to toggle code input mode function toggleCodeMode() { isCodeMode = !isCodeMode; codeInput.visible = isCodeMode; keyboard.visible = isCodeMode; // If exiting code mode, clear the input if (!isCodeMode) { codeInput.clear(); } } // Function to show a temporary message function showMessage(text) { messageText.setText(text); messageText.visible = true; if (messageTimeout) { LK.clearTimeout(messageTimeout); } messageTimeout = LK.setTimeout(function () { messageText.visible = false; }, 3000); } // Define event handlers game.down = function (x, y, obj) { isDragging = true; }; game.up = function (x, y, obj) { isDragging = false; dragObject = null; }; game.move = function (x, y, obj) { // Pet can be petted by dragging across it if (isDragging && !isCodeMode && pet.alive) { var localPos = pet.toLocal({ x: x, y: y }); // Check if mouse/touch is over the pet body if (Math.abs(localPos.x) < pet.body.width / 2 && Math.abs(localPos.y) < pet.body.height / 2) { // Small happiness boost when being petted if (LK.ticks % 10 === 0) { pet.happiness = Math.min(100, pet.happiness + 0.5); pet.updateStats(); } // Show visual feedback tween(pet.body, { tint: 0xFFD700 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(pet.body, { tint: 0xF5DEB3 }, { duration: 100, easing: tween.linear }); } }); } } }; // Main game update loop game.update = function () { // Update stat bars to reflect current values hungerBar.setValue(pet.hunger); happinessBar.setValue(pet.happiness); cleanlinessBar.setValue(pet.cleanliness); healthBar.setValue(pet.health); // Update info text based on pet state if (!pet.alive) { infoText.setText("Your pet has died! Find the secret codes to resurrect it."); } else if (pet.health < 30) { infoText.setText("Your pet is very sick! Take better care of it!"); } else if (pet.hunger < 30) { infoText.setText("Your pet is starving! Feed it quickly!"); } else if (pet.happiness < 30) { infoText.setText("Your pet is sad! Play with it!"); } else if (pet.cleanliness < 30) { infoText.setText("Your pet is dirty! Clean it!"); } else { infoText.setText("Take good care of your pet or it will die permanently!"); } }; // Start background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
created: "undefined",
lastVisit: "undefined",
hunger: 100,
happiness: 100,
cleanliness: 100,
health: 100,
alive: true,
discoveredCodes: []
});
/****
* Classes
****/
var Button = Container.expand(function (text, color) {
var self = Container.call(this);
var bg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
if (color) {
bg.tint = color;
}
var label = new Text2(text, {
size: 60,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.down = function () {
tween(bg.scale, {
x: 0.95,
y: 0.95
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function () {
tween(bg.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
};
return self;
});
var CodeInput = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('codeInput', {
anchorX: 0.5,
anchorY: 0.5
});
self.currentCode = "";
var codeText = new Text2("CODE: ", {
size: 60,
fill: 0x333333
});
codeText.anchor.set(0.5, 0.5);
self.addChild(codeText);
self.updateText = function () {
codeText.setText("CODE: " + self.currentCode);
};
self.addCharacter = function (_char) {
if (self.currentCode.length < 10) {
self.currentCode += _char;
self.updateText();
}
};
self.backspace = function () {
if (self.currentCode.length > 0) {
self.currentCode = self.currentCode.slice(0, -1);
self.updateText();
}
};
self.clear = function () {
self.currentCode = "";
self.updateText();
};
self.checkCode = function () {
var lowerCode = self.currentCode.toLowerCase();
// Check if code has already been discovered
if (storage.discoveredCodes.indexOf(lowerCode) !== -1) {
return false;
}
// Validate code against known codes
var isValid = false;
if (lowerCode === "revenge") {
showMessage("The dead shall rise...");
isValid = true;
} else if (lowerCode === "sun" && storage.discoveredCodes.indexOf("revenge") !== -1) {
showMessage("The power of life is yours!");
isValid = true;
if (!pet.alive) {
pet.resurrect();
}
} else if (lowerCode === "eternity") {
showMessage("Time stands still...");
isValid = true;
} else if (lowerCode === "genesis") {
showMessage("A new beginning...");
isValid = true;
} else if (lowerCode === "void") {
showMessage("Emptiness consumes...");
isValid = true;
}
if (isValid) {
// Save the discovered code
storage.discoveredCodes.push(lowerCode);
LK.getSound('secretFound').play();
return true;
}
return false;
};
return self;
});
var Keyboard = Container.expand(function (codeInput) {
var self = Container.call(this);
var keys = ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM⌫"];
var keySize = 80;
var spacing = 10;
var currentY = 0;
keys.forEach(function (row, rowIndex) {
var rowWidth = row.length * (keySize + spacing) - spacing;
var startX = -rowWidth / 2;
for (var i = 0; i < row.length; i++) {
var key = row[i];
var keyButton = new Container();
var keyBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: keySize,
height: keySize,
tint: 0x555555
});
keyButton.addChild(keyBg);
var keyText = new Text2(key, {
size: 40,
fill: 0xFFFFFF
});
keyText.anchor.set(0.5, 0.5);
keyButton.addChild(keyText);
keyButton.x = startX + i * (keySize + spacing) + keySize / 2;
keyButton.y = currentY;
keyButton.key = key;
keyButton.interactive = true;
keyButton.buttonMode = true;
keyButton.down = function () {
if (this.key === "⌫") {
codeInput.backspace();
} else {
codeInput.addCharacter(this.key);
}
LK.getSound('codeEntered').play();
tween(this.scale, {
x: 0.9,
y: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
keyButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
};
self.addChild(keyButton);
}
currentY += keySize + spacing;
});
// Add submit button
var submitButton = new Button("SUBMIT", 0x4CAF50);
submitButton.y = currentY + 20;
submitButton.down = function () {
tween(this.scale, {
x: 0.95,
y: 0.95
}, {
duration: 100,
easing: tween.easeOut
});
};
submitButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
if (codeInput.checkCode()) {
codeInput.clear();
}
};
self.addChild(submitButton);
// Add clear button
var clearButton = new Button("CLEAR", 0xF44336);
clearButton.x = -180;
clearButton.y = currentY + 20;
clearButton.down = function () {
tween(this.scale, {
x: 0.95,
y: 0.95
}, {
duration: 100,
easing: tween.easeOut
});
};
clearButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
codeInput.clear();
};
self.addChild(clearButton);
return self;
});
var Pet = Container.expand(function () {
var self = Container.call(this);
// Variables to track pet state
self.hunger = storage.hunger;
self.happiness = storage.happiness;
self.cleanliness = storage.cleanliness;
self.health = storage.health;
self.alive = storage.alive;
self.moods = ["normal", "happy", "sad", "sick", "dead"];
self.currentMood = "normal";
self.blinkTimer = 0;
self.mouthMoveTimer = 0;
self.mouthOpen = false;
// Create pet body
var body = self.attachAsset('petBody', {
anchorX: 0.5,
anchorY: 0.5
});
// Define leftEye and rightEye as assets for the pet
self.leftEye = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: -100,
// Adjust position as needed
y: -100 // Adjust position as needed
});
self.rightEye = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
// Adjust position as needed
y: -100 // Adjust position as needed
});
// Define mouth as an asset for the pet
self.mouth = self.attachAsset('petMouth', {
anchorX: 0.5,
anchorY: 0.5,
y: 100 // Adjust position as needed
});
// Create pet face
self.body = body;
// Interactions
self.feed = function () {
if (!self.alive) {
return;
}
self.hunger = Math.min(100, self.hunger + 30);
self.health = Math.min(100, self.health + 5);
// Animate eating
self.mouthOpen = true;
self.updateMouthState();
LK.setTimeout(function () {
self.mouthOpen = false;
self.updateMouthState();
}, 500);
LK.getSound('eat').play();
self.updateStats();
};
self.play = function () {
if (!self.alive) {
return;
}
self.happiness = Math.min(100, self.happiness + 30);
self.hunger = Math.max(0, self.hunger - 5);
// Animate playing
tween(self, {
rotation: 0.1
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: -0.1
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
});
LK.getSound('play').play();
self.updateStats();
};
self.clean = function () {
if (!self.alive) {
return;
}
self.cleanliness = Math.min(100, self.cleanliness + 30);
// Animate cleaning
tween(self.body, {
tint: 0x87CEEB
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.body, {
tint: 0xF5DEB3
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
LK.getSound('wash').play();
self.updateStats();
};
self.updateStats = function () {
// Update all stats in storage
storage.hunger = self.hunger;
storage.happiness = self.happiness;
storage.cleanliness = self.cleanliness;
storage.health = self.health;
storage.alive = self.alive;
// Calculate health based on other stats
if (self.alive) {
self.health = Math.max(0, self.health - (self.hunger < 20 ? 10 : 0) - (self.happiness < 20 ? 10 : 0) - (self.cleanliness < 20 ? 10 : 0));
if (self.health <= 0) {
self.die();
}
}
// Update mood
self.updateMood();
};
self.updateMood = function () {
var oldMood = self.currentMood;
if (!self.alive) {
self.currentMood = "dead";
} else if (self.health < 30) {
self.currentMood = "sick";
} else if (self.hunger < 30 || self.happiness < 30 || self.cleanliness < 30) {
self.currentMood = "sad";
} else if (self.hunger > 80 && self.happiness > 80 && self.cleanliness > 80) {
self.currentMood = "happy";
} else {
self.currentMood = "normal";
}
// Update visual appearance based on mood
if (oldMood !== self.currentMood) {
self.updateAppearance();
}
};
self.updateAppearance = function () {
// Reset any previous animations or effects
tween.stop(self.body);
tween.stop(self.leftEye);
tween.stop(self.rightEye);
tween.stop(self.mouth);
self.body.tint = 0xF5DEB3;
self.body.scale.set(1, 1);
self.leftEye.scale.set(1, 1);
self.rightEye.scale.set(1, 1);
self.mouth.scale.set(1, 0.5);
// Apply mood-specific appearance
switch (self.currentMood) {
case "happy":
self.mouth.scale.set(1, 0.75);
self.mouth.y = 120;
LK.getSound('happy').play();
break;
case "sad":
self.mouth.scale.set(1, 0.25);
self.mouth.y = 150;
LK.getSound('sad').play();
break;
case "sick":
self.body.tint = 0xADD8E6;
break;
case "dead":
self.leftEye.scale.set(1, 0.1);
self.rightEye.scale.set(1, 0.1);
self.mouth.scale.set(1, 0.1);
self.body.tint = 0xCCCCCC;
self.mouth.rotation = Math.PI;
break;
default:
// normal
self.mouth.scale.set(1, 0.5);
self.mouth.y = 100;
break;
}
};
self.updateMouthState = function () {
if (self.mouthOpen) {
self.mouth.scale.set(1, 1);
} else {
self.updateAppearance(); // Reset to mood-appropriate appearance
}
};
self.animateBlink = function () {
tween(self.leftEye.scale, {
y: 0.1
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
tween(self.leftEye.scale, {
y: 1
}, {
duration: 100,
easing: tween.linear
});
}
});
tween(self.rightEye.scale, {
y: 0.1
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
tween(self.rightEye.scale, {
y: 1
}, {
duration: 100,
easing: tween.linear
});
}
});
};
self.die = function () {
if (!self.alive) {
return;
}
self.alive = false;
storage.alive = false;
// Show death animation
LK.effects.flashScreen(0xFF0000, 1000);
// Update appearance to show dead pet
self.updateMood();
};
self.resurrect = function () {
self.alive = true;
storage.alive = true;
self.hunger = 100;
storage.hunger = 100;
self.happiness = 100;
storage.happiness = 100;
self.cleanliness = 100;
storage.cleanliness = 100;
self.health = 100;
storage.health = 100;
// Show resurrection animation
LK.effects.flashScreen(0xFFFF00, 1000);
// Update appearance
self.updateMood();
};
self.update = function () {
if (!self.alive) {
return;
}
// Decrease stats over time (slower rate)
if (LK.ticks % 60 === 0) {
// Once per second
self.hunger = Math.max(0, self.hunger - 0.1);
self.happiness = Math.max(0, self.happiness - 0.1);
self.cleanliness = Math.max(0, self.cleanliness - 0.05);
self.updateStats();
}
// Occasional blinking
self.blinkTimer++;
if (self.blinkTimer > 180 && Math.random() < 0.02) {
self.animateBlink();
self.blinkTimer = 0;
}
// Random mouth movements when happy
if (self.currentMood === "happy" && Math.random() < 0.005) {
self.mouthOpen = !self.mouthOpen;
self.updateMouthState();
}
};
// Initialize appearance
self.updateMood();
return self;
});
var StatBar = Container.expand(function (label) {
var self = Container.call(this);
var bg = self.attachAsset('statBar', {
anchorX: 0,
anchorY: 0.5
});
var fill = self.attachAsset('statFill', {
anchorX: 0,
anchorY: 0.5,
x: 5,
y: 0
});
var text = new Text2(label, {
size: 40,
fill: 0xFFFFFF
});
text.anchor.set(0, 0.5);
text.x = 10;
self.addChild(text);
self.setValue = function (value) {
// Calculate fill width based on percentage
var maxWidth = 490;
var newWidth = Math.max(0, Math.min(maxWidth, maxWidth * (value / 100)));
// Animate the transition
tween(fill, {
width: newWidth
}, {
duration: 300,
easing: tween.easeOut
});
// Update fill color based on value
if (value > 70) {
fill.tint = 0x4CAF50; // Green
} else if (value > 30) {
fill.tint = 0xFFC107; // Yellow
} else {
fill.tint = 0xF44336; // Red
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xE0F7FA
});
/****
* Game Code
****/
// Track game state
var isDragging = false;
var dragObject = null;
var isCodeMode = false;
var messageTimeout = null;
// Create pet instance
var pet = game.addChild(new Pet());
pet.x = 2048 / 2;
pet.y = 900;
// Check time between sessions
var currentTime = Date.now();
if (storage.lastVisit !== null) {
var timeDifference = (currentTime - storage.lastVisit) / 1000 / 60; // in minutes
// Reduce stats based on time away
if (pet.alive && timeDifference > 5) {
// Decay stats based on time away (capped at certain values to prevent instant death)
var hungerDecay = Math.min(80, timeDifference / 15);
var happinessDecay = Math.min(80, timeDifference / 20);
var cleanlinessDecay = Math.min(80, timeDifference / 30);
pet.hunger = Math.max(10, pet.hunger - hungerDecay);
pet.happiness = Math.max(10, pet.happiness - happinessDecay);
pet.cleanliness = Math.max(10, pet.cleanliness - cleanlinessDecay);
// If away too long, health decreases dramatically
if (timeDifference > 1440) {
// More than 24 hours
pet.health = Math.max(0, pet.health - 80);
} else if (timeDifference > 720) {
// More than 12 hours
pet.health = Math.max(0, pet.health - 40);
} else if (timeDifference > 360) {
// More than 6 hours
pet.health = Math.max(0, pet.health - 20);
}
pet.updateStats();
}
}
// Update the last visit time
storage.lastVisit = currentTime;
// If this is the first run, set created time
if (storage.created === null) {
storage.created = currentTime;
}
// Create stat bars
var hungerBar = game.addChild(new StatBar("Hunger"));
hungerBar.x = 200;
hungerBar.y = 200;
hungerBar.setValue(pet.hunger);
var happinessBar = game.addChild(new StatBar("Happiness"));
happinessBar.x = 200;
happinessBar.y = 300;
happinessBar.setValue(pet.happiness);
var cleanlinessBar = game.addChild(new StatBar("Cleanliness"));
cleanlinessBar.x = 200;
cleanlinessBar.y = 400;
cleanlinessBar.setValue(pet.cleanliness);
var healthBar = game.addChild(new StatBar("Health"));
healthBar.x = 200;
healthBar.y = 500;
healthBar.setValue(pet.health);
// Create interaction buttons
var feedButton = game.addChild(new Button("Feed", 0xE74C3C));
feedButton.x = 400;
feedButton.y = 650;
feedButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
if (!isCodeMode) {
pet.feed();
}
};
var playButton = game.addChild(new Button("Play", 0xF1C40F));
playButton.x = 1024;
playButton.y = 650;
playButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
if (!isCodeMode) {
pet.play();
}
};
var cleanButton = game.addChild(new Button("Clean", 0x3498DB));
cleanButton.x = 1648;
cleanButton.y = 650;
cleanButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
if (!isCodeMode) {
pet.clean();
}
};
// Create code button
var codeButton = game.addChild(new Button("Codes", 0x9B59B6));
codeButton.x = 1024;
codeButton.y = 2550;
codeButton.up = function () {
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut
});
toggleCodeMode();
};
// Create code input interface (initially hidden)
var codeInput = game.addChild(new CodeInput());
codeInput.x = 1024;
codeInput.y = 1600;
codeInput.visible = false;
var keyboard = game.addChild(new Keyboard(codeInput));
keyboard.x = 1024;
keyboard.y = 1800;
keyboard.visible = false;
// Create info text
var infoText = new Text2("Care for your pet or it will die permanently!", {
size: 50,
fill: 0x333333
});
infoText.anchor.set(0.5, 0);
infoText.x = 1024;
infoText.y = 50;
game.addChild(infoText);
// Create message text (for code responses)
var messageText = new Text2("", {
size: 60,
fill: 0xFF0000
});
messageText.anchor.set(0.5, 0);
messageText.x = 1024;
messageText.y = 120;
messageText.visible = false;
game.addChild(messageText);
// Function to toggle code input mode
function toggleCodeMode() {
isCodeMode = !isCodeMode;
codeInput.visible = isCodeMode;
keyboard.visible = isCodeMode;
// If exiting code mode, clear the input
if (!isCodeMode) {
codeInput.clear();
}
}
// Function to show a temporary message
function showMessage(text) {
messageText.setText(text);
messageText.visible = true;
if (messageTimeout) {
LK.clearTimeout(messageTimeout);
}
messageTimeout = LK.setTimeout(function () {
messageText.visible = false;
}, 3000);
}
// Define event handlers
game.down = function (x, y, obj) {
isDragging = true;
};
game.up = function (x, y, obj) {
isDragging = false;
dragObject = null;
};
game.move = function (x, y, obj) {
// Pet can be petted by dragging across it
if (isDragging && !isCodeMode && pet.alive) {
var localPos = pet.toLocal({
x: x,
y: y
});
// Check if mouse/touch is over the pet body
if (Math.abs(localPos.x) < pet.body.width / 2 && Math.abs(localPos.y) < pet.body.height / 2) {
// Small happiness boost when being petted
if (LK.ticks % 10 === 0) {
pet.happiness = Math.min(100, pet.happiness + 0.5);
pet.updateStats();
}
// Show visual feedback
tween(pet.body, {
tint: 0xFFD700
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
tween(pet.body, {
tint: 0xF5DEB3
}, {
duration: 100,
easing: tween.linear
});
}
});
}
}
};
// Main game update loop
game.update = function () {
// Update stat bars to reflect current values
hungerBar.setValue(pet.hunger);
happinessBar.setValue(pet.happiness);
cleanlinessBar.setValue(pet.cleanliness);
healthBar.setValue(pet.health);
// Update info text based on pet state
if (!pet.alive) {
infoText.setText("Your pet has died! Find the secret codes to resurrect it.");
} else if (pet.health < 30) {
infoText.setText("Your pet is very sick! Take better care of it!");
} else if (pet.hunger < 30) {
infoText.setText("Your pet is starving! Feed it quickly!");
} else if (pet.happiness < 30) {
infoText.setText("Your pet is sad! Play with it!");
} else if (pet.cleanliness < 30) {
infoText.setText("Your pet is dirty! Clean it!");
} else {
infoText.setText("Take good care of your pet or it will die permanently!");
}
};
// Start background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});