/****
* 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
}
});