User prompt
remove the maze
User prompt
let me drag the charecter in the maze (player)
User prompt
the player wont move with arrows, the monster spawned outside of the maze and the player spawned in the wall
User prompt
the cat is spawning in the wall
User prompt
make the maze pop up when all bars hit 0% and make the maze cat smaller and make the maze playable
User prompt
It's not popping up
User prompt
Modify stats checker to only trigger nightmare maze if all bars exept for corruption are at 0%
User prompt
Modify stats checker to only trigger nightmare if all bars exept for corruption are at 0%
User prompt
make the ignore text bigger bolder and above the phone
User prompt
make the ignore button an asset of its own
User prompt
make the maze bigger and remove the you die if stats are too low unless evoluition bar is at 100%
User prompt
move the ignore button to the left-middle
User prompt
add an ignore button that is an Iphone that if you press it, it brings down all stats to be very low
User prompt
if everything gets too low make it put you into a maze that you have to ecape while the pet is hunting you down and if you get caught, a jumpscare will play and make a checkstats class that checks for very low stats to activate nightmare mode maze
User prompt
make the vaccum spawn by itself
User prompt
make the vaccuum appear every time you click the clean button
User prompt
now, remove the big blue cube from the sprite
User prompt
remove the flashing dot from the vaccum sprite
User prompt
make the vaccuum not flash
User prompt
make the vaccum an asset of its own
User prompt
make the play ball a sprite
User prompt
make the arcade game bring happiness up a bit more and not bring down hunger
User prompt
make less things spawn
User prompt
make the arrow buttons bigger
User prompt
make the charecter move more and make the target and charecter an asse in arcade
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AbandonButton = Container.expand(function () { var self = Container.call(this); var buttonShape = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, tint: 0xcc0000 // Red color for warning }); var label = new Text2("ABANDON", { size: 40, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.interactive = true; self.down = function (x, y, obj) { tween(buttonShape, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { tween(buttonShape, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); // Trigger nightmare mode self.triggerNightmareMode(); }; self.triggerNightmareMode = function () { // Add massive corruption to instantly transform pet if (pet) { // Maximum corruption pet.addCorruption(100); // Make everything scary // Dark background game.setBackgroundColor(0x110011); // Intense glitch effects for (var i = 0; i < 20; i++) { LK.setTimeout(function () { triggerGlitch(); }, i * 100); } // Make pet eyes red and distorted if (pet.leftEye && pet.rightEye) { pet.leftEye.tint = 0xff0000; pet.rightEye.tint = 0xff0000; // Distort eyes tween(pet.leftEye, { scaleX: 1.8, scaleY: 0.6 }, { duration: 500 }); tween(pet.rightEye, { scaleX: 0.6, scaleY: 1.8 }, { duration: 500 }); } // Distort mouth if (pet.mouth) { pet.mouth.tint = 0xff0000; tween(pet.mouth, { scaleX: 2.0, scaleY: 0.5, rotation: 0.5 }, { duration: 500 }); } // Reduce all pet stats to minimum pet.hunger = 1; pet.happiness = 1; pet.cleanliness = 1; updateStatusBars(); // Play glitch sound rapidly for (var i = 0; i < 5; i++) { LK.setTimeout(function () { LK.getSound('glitch').play(); }, i * 200); } } }; return self; }); var ArcadeGame = Container.expand(function () { var self = Container.call(this); // Game state self.active = false; self.score = 0; self.gameOver = false; self.playerX = 0; self.targets = []; self.timeRemaining = 30; // 30 second game self.lastCountdownTime = 0; self.lives = 3; // Player has 3 lives // Create game background var background = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, // Increased size scaleY: 9, // Increased size tint: 0x000000 }); // Create player - use pet body asset instead of generic shape var player = self.attachAsset('petBody', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, y: 200, tint: 0x44FF44 }); // Create score text var scoreText = new Text2("Score: 0", { size: 40, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0.5); scoreText.y = -350; self.addChild(scoreText); // Create countdown text var countdownText = new Text2("Time: 30", { size: 40, fill: 0xFFFFFF }); countdownText.anchor.set(0.5, 0.5); countdownText.y = -300; self.addChild(countdownText); // Create lives display var livesText = new Text2("Lives: 3", { size: 40, fill: 0xFFFFFF }); livesText.anchor.set(0.5, 0.5); livesText.y = -250; self.addChild(livesText); // Create game controls var leftButton = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: -150, y: 300, tint: 0x4488FF }); var rightButton = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: 150, y: 300, tint: 0x4488FF }); // Add arrow indicators to buttons var leftArrow = new Text2("<", { size: 50, fill: 0xFFFFFF }); leftArrow.anchor.set(0.5, 0.5); leftButton.addChild(leftArrow); var rightArrow = new Text2(">", { size: 50, fill: 0xFFFFFF }); rightArrow.anchor.set(0.5, 0.5); rightButton.addChild(rightArrow); // Make buttons interactive leftButton.interactive = true; rightButton.interactive = true; leftButton.down = function () { self.movePlayer(-10); }; rightButton.down = function () { self.movePlayer(10); }; // Initialize targets for (var i = 0; i < 5; i++) { var target = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5, x: (Math.random() - 0.5) * 300, y: -150 - Math.random() * 100, scaleX: 0.7, scaleY: 0.7, visible: false }); self.targets.push({ sprite: target, active: false, speed: 2 + Math.random() * 1.5 // Reduced from 3+random*2 to make it easier }); } self.movePlayer = function (amount) { if (!self.active || self.gameOver) { return; } self.playerX += amount; // Keep player within bounds self.playerX = Math.max(-150, Math.min(150, self.playerX)); // Use tween for smoother movement tween(player, { x: self.playerX, rotation: amount > 0 ? 0.1 : amount < 0 ? -0.1 : 0 // Tilt in direction of movement }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Return to neutral rotation if (amount !== 0) { tween(player, { rotation: 0 }, { duration: 100 }); } } }); }; self.updateTargets = function () { var activeCount = 0; // Update existing targets for (var i = 0; i < self.targets.length; i++) { var target = self.targets[i]; if (target.active) { activeCount++; // Move target down target.sprite.y += target.speed; // Check if player caught the target var dx = target.sprite.x - player.x; var dy = target.sprite.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { // Caught target - increase score self.score += 10; scoreText.setText("Score: " + self.score); // Deactivate target target.active = false; target.sprite.visible = false; } // Check if target reached bottom if (target.sprite.y > 250) { // Target missed target.active = false; target.sprite.visible = false; // Decrease lives instead of ending game immediately self.lives--; livesText.setText("Lives: " + self.lives); // Flash lives text red tween(livesText, { tint: 0xFF0000 }, { duration: 200, onFinish: function onFinish() { tween(livesText, { tint: 0xFFFFFF }, { duration: 200 }); } }); // End game if no lives left if (self.lives <= 0) { self.gameOver = true; self.endGame(); } } } } // Spawn new target if needed - reduced spawn rate from 0.05 to 0.02 if (activeCount < 2 && Math.random() < 0.02 && !self.gameOver) { var randomTarget = self.targets[Math.floor(Math.random() * self.targets.length)]; if (!randomTarget.active) { randomTarget.active = true; randomTarget.sprite.visible = true; randomTarget.sprite.x = (Math.random() - 0.5) * 300; randomTarget.sprite.y = -200; } } }; self.startGame = function () { self.visible = true; self.active = true; self.gameOver = false; self.score = 0; self.playerX = 0; player.x = 0; scoreText.setText("Score: 0"); // Reset countdown self.timeRemaining = 30; self.lastCountdownTime = 0; countdownText.setText("Time: 30"); // Reset lives self.lives = 3; livesText.setText("Lives: 3"); // Reset all targets for (var i = 0; i < self.targets.length; i++) { self.targets[i].active = false; self.targets[i].sprite.visible = false; } }; self.endGame = function () { // Show game over message var gameOverText = new Text2("Game Over!", { size: 60, fill: 0xFF4444 }); gameOverText.anchor.set(0.5, 0.5); self.addChild(gameOverText); // Show final score with any time bonus var finalScore = self.score; if (self.timeRemaining > 0) { // Add bonus points for remaining time var timeBonus = self.timeRemaining * 5; finalScore += timeBonus; // Show bonus message var bonusText = new Text2("Time Bonus: +" + timeBonus, { size: 40, fill: 0x44FF44 }); bonusText.anchor.set(0.5, 0.5); bonusText.y = 60; gameOverText.addChild(bonusText); // Update score display scoreText.setText("Final Score: " + finalScore); } // Hide game over and give reward after delay LK.setTimeout(function () { self.deactivate(); // Increase pet happiness based on score if (pet) { var happinessBoost = Math.min(50, finalScore / 10); pet.happiness = Math.min(100, pet.happiness + happinessBoost); updateStatusBars(); } }, 3000); }; self.update = function () { if (!self.active) { return; } self.updateTargets(); // Update countdown timer (every second) var currentTime = Math.floor(LK.ticks / 60); if (currentTime > self.lastCountdownTime) { self.lastCountdownTime = currentTime; self.timeRemaining--; countdownText.setText("Time: " + self.timeRemaining); // Flash countdown text when time is running out (less than 10 seconds) if (self.timeRemaining <= 10) { tween(countdownText, { tint: 0xFF0000 }, { duration: 200, onFinish: function onFinish() { tween(countdownText, { tint: 0xFFFFFF }, { duration: 200 }); } }); } // End game when time runs out if (self.timeRemaining <= 0) { self.gameOver = true; self.endGame(); } } }; self.deactivate = function () { self.active = false; tween(self, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.visible = false; self.alpha = 1; } }); }; self.visible = false; return self; }); var Ball = Container.expand(function () { var self = Container.call(this); // Create ball using existing buttonIcon asset var ballGraphics = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF4444 // Red ball }); // Add some decoration to make it look more like a ball var highlight = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: -15, y: -15, tint: 0xFFFFFF, alpha: 0.7 }); self.interactive = true; self.visible = false; self.active = false; self.originalX = 0; self.originalY = 0; self.down = function (x, y, obj) { // Scale down when pressed tween(ballGraphics, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { // Restore scale when released tween(ballGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); if (self.active) { // Check if ball is near pet var dx = self.x - pet.x; var dy = self.y - pet.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { // Play with pet using the ball pet.play(); self.deactivate(); } else { // Return to original position self.returnToPosition(); } } }; self.activate = function () { self.visible = true; self.active = true; self.originalX = playButton.x; self.originalY = playButton.y - 150; self.x = self.originalX; self.y = self.originalY; // Animation to indicate it's ready tween(ballGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(ballGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); }; self.deactivate = function () { self.active = false; // Fade out tween(self, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.visible = false; self.alpha = 1; } }); }; self.returnToPosition = function () { tween(self, { x: self.originalX, y: self.originalY }, { duration: 300 }); }; return self; }); var Button = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.onCooldown = false; self.cooldownDuration = 2000; // 2 seconds cooldown var buttonShape = self.attachAsset(type + 'Button', { anchorX: 0.5, anchorY: 0.5 }); var icon = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); var label = new Text2(type.charAt(0).toUpperCase() + type.slice(1), { size: 40, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); label.y = 70; self.addChild(label); self.interactive = true; self.startCooldown = function () { if (self.onCooldown) { return; } self.onCooldown = true; // Grey out the button during cooldown tween(buttonShape, { tint: 0x888888 }, { duration: 100 }); // Set a timeout to end the cooldown LK.setTimeout(function () { self.onCooldown = false; // Restore button color tween(buttonShape, { tint: 0xFFFFFF }, { duration: 100 }); }, self.cooldownDuration); }; self.down = function (x, y, obj) { tween(buttonShape, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { tween(buttonShape, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); // Only act if not on cooldown if (!self.onCooldown) { LK.getSound(self.type).play(); self.startCooldown(); switch (self.type) { case 'feed': // Activate food instead of directly feeding if (food) { food.activate(); } break; case 'play': // Show play options popup if (playOptionsMenu && !playOptionsMenu.visible) { playOptionsMenu.show(); } else { // Fallback to direct play if menu isn't available pet.play(); } break; case 'clean': pet.clean(); break; } } }; return self; }); var CorruptionParticle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('corruptionEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 }); self.lifespan = 0; self.maxLife = 0; self.speedX = 0; self.speedY = 0; self.active = false; self.initialize = function (x, y, duration) { self.x = x; self.y = y; self.maxLife = duration; self.lifespan = duration; self.speedX = (Math.random() - 0.5) * 3; self.speedY = (Math.random() - 0.5) * 3; self.rotation = Math.random() * Math.PI * 2; self.active = true; self.visible = true; self.alpha = 0.6; // Color selection depends on corruption level - darker as corruption increases var randomColor = Math.random(); var corruptionLevel = pet ? pet.corruption : 0; var darkerColors = corruptionLevel > 50; var nightmareMode = corruptionLevel >= 95; if (nightmareMode) { // Extremely dark, scary colors for nightmare mode if (randomColor < 0.33) { particleGraphics.tint = 0xff0000; // Blood red } else if (randomColor < 0.66) { particleGraphics.tint = 0x660000; // Dark red } else { particleGraphics.tint = 0x330000; // Very dark red } // Larger and more intense for nightmare mode particleGraphics.scaleX = particleGraphics.scaleY = 1.5 + Math.random(); } else if (darkerColors) { // Darker, more ominous colors when corruption is higher if (randomColor < 0.33) { particleGraphics.tint = 0x4455aa; // Dark blue } else if (randomColor < 0.66) { particleGraphics.tint = 0x335566; // Dark teal } else { particleGraphics.tint = 0x556677; // Dark slate } } else { // Original brighter colors for lower corruption if (randomColor < 0.33) { particleGraphics.tint = 0x88aaff; // Light blue } else if (randomColor < 0.66) { particleGraphics.tint = 0x55ddaa; // Teal } else { particleGraphics.tint = 0xaaddff; // Sky blue } } }; self.update = function () { if (!self.active) { return; } self.lifespan--; self.x += self.speedX; self.y += self.speedY; self.alpha = self.lifespan / self.maxLife * 0.6; if (self.lifespan <= 0) { self.active = false; self.visible = false; } }; self.visible = false; self.active = false; return self; }); var Food = Container.expand(function () { var self = Container.call(this); var foodGraphics = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); self.interactive = true; self.visible = false; self.active = false; self.down = function (x, y, obj) { // Scale down when pressed tween(foodGraphics, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { // Restore scale when released tween(foodGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); if (self.active) { // Check if food is near pet's mouth var dx = self.x - pet.x; var dy = self.y - (pet.y + pet.mouth.y); var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 100) { // Feed the pet pet.feed(); self.deactivate(); } else { // Return to original position self.returnToPosition(); } } }; self.activate = function () { self.visible = true; self.active = true; self.originalX = feedButton.x; self.originalY = feedButton.y - 150; self.x = self.originalX; self.y = self.originalY; // Animation to indicate it's ready tween(foodGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(foodGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); }; self.deactivate = function () { self.active = false; // Fade out tween(self, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.visible = false; self.alpha = 1; } }); }; self.returnToPosition = function () { tween(self, { x: self.originalX, y: self.originalY }, { duration: 300 }); }; return self; }); var GlitchEffect = Container.expand(function () { var self = Container.call(this); var glitchGraphics = self.attachAsset('glitchEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.startGlitch = function () { self.visible = true; self.x = Math.random() * 2048; self.y = Math.random() * 2732; self.rotation = Math.random() * Math.PI * 2; self.alpha = 0.7; tween(self, { alpha: 0 }, { duration: 300 + Math.random() * 700, onFinish: function onFinish() { self.visible = false; } }); }; self.visible = false; return self; }); var Pet = Container.expand(function () { var self = Container.call(this); // Stats self.hunger = 100; self.happiness = 100; self.cleanliness = 100; self.corruption = 0; self.stage = 0; // 0 = normal, 1 = starting to corrupt, 2 = more corrupt, 3 = nightmare // Visual components var body = self.attachAsset('petBody', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); // Make these properties accessible from outside for the abandon button self.leftEye = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: -70, y: -50 }); self.rightEye = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: 70, y: -50 }); self.mouth = self.attachAsset('petMouth', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); // Food item that appears when feeding var foodItem = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5, visible: false, x: 0, y: -200 }); // Toy that appears when playing var toyItem = self.attachAsset('toy', { anchorX: 0.5, anchorY: 0.5, visible: false, x: 200, y: 0 }); // Dirt patches that appear when pet is dirty var dirtPatches = []; for (var i = 0; i < 5; i++) { var dirt = self.attachAsset('dirt', { anchorX: 0.5, anchorY: 0.5, visible: false, x: (Math.random() - 0.5) * 200, y: (Math.random() - 0.5) * 200 }); dirtPatches.push(dirt); } self.blink = function () { tween(self.leftEye, { scaleY: 0.1 }, { duration: 100, onFinish: function onFinish() { tween(self.leftEye, { scaleY: 1 }, { duration: 100 }); } }); tween(self.rightEye, { scaleY: 0.1 }, { duration: 100, onFinish: function onFinish() { tween(self.rightEye, { scaleY: 1 }, { duration: 100 }); } }); }; self.breathe = function () { tween(body, { scaleY: 1.05 }, { duration: 1000, onFinish: function onFinish() { tween(body, { scaleY: 1 }, { duration: 1000 }); } }); }; self.feed = function () { self.hunger = Math.min(100, self.hunger + 30); // Decrease cleanliness when feeding self.cleanliness = Math.max(0, self.cleanliness - 15); updateStatusBars(); // Make pet happy from feeding with more animated reaction // Move slightly up with excitement tween(self, { y: self.y - 30 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: self.y + 30 }, { duration: 300, easing: tween.easeIn }); } }); // More expressive mouth animation tween(self.mouth, { scaleX: 1.5, scaleY: 1.5, rotation: 0.1 }, { duration: 300, onFinish: function onFinish() { tween(self.mouth, { scaleX: 1, scaleY: 1, rotation: 0 }, { duration: 300 }); } }); // Sometimes add corruption from feeding in later stages if (self.corruption > 40 && Math.random() < 0.3) { self.addCorruption(5); triggerGlitch(); } }; self.play = function () { toyItem.visible = true; toyItem.x = 200; tween(toyItem, { x: 0 }, { duration: 500, onFinish: function onFinish() { self.happiness = Math.min(100, self.happiness + 30); // Decrease hunger when playing with the pet self.hunger = Math.max(0, self.hunger - 15); updateStatusBars(); // Bounce toy tween(toyItem, { y: -100 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(toyItem, { y: 0, alpha: 0 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { toyItem.visible = false; toyItem.alpha = 1; } }); } }); // Make pet happy from playing tween(body, { rotation: 0.1 }, { duration: 200, onFinish: function onFinish() { tween(body, { rotation: -0.1 }, { duration: 200, onFinish: function onFinish() { tween(body, { rotation: 0 }, { duration: 200 }); } }); } }); } }); // Sometimes add corruption from playing in later stages if (self.corruption > 40 && Math.random() < 0.3) { self.addCorruption(5); triggerGlitch(); } }; self.clean = function () { // Activate vacuum cleaner instead of directly cleaning if (vacuum && !vacuum.active) { vacuum.x = cleanButton.x; vacuum.y = cleanButton.y; vacuum.activate(); return; // Exit early - actual cleaning happens when vacuum is dragged to pet } // This section only executes when cleaning is triggered by the vacuum self.cleanliness = Math.min(100, self.cleanliness + 30); // Reduce happiness more significantly when cleaning with vacuum self.happiness = Math.max(0, self.happiness - 25); updateStatusBars(); // Hide dirt patches for (var i = 0; i < dirtPatches.length; i++) { dirtPatches[i].visible = false; } // Sparkle effect tween(body, { alpha: 0.7 }, { duration: 200, onFinish: function onFinish() { tween(body, { alpha: 1 }, { duration: 200 }); } }); // Sometimes add corruption from cleaning in later stages if (self.corruption > 40 && Math.random() < 0.3) { self.addCorruption(5); triggerGlitch(); } }; self.updateStats = function () { // Decrease stats over time - increased decay rates self.hunger = Math.max(0, self.hunger - 0.3); self.happiness = Math.max(0, self.happiness - 0.4); self.cleanliness = Math.max(0, self.cleanliness - 0.35); // Show dirt when dirty for (var i = 0; i < dirtPatches.length; i++) { dirtPatches[i].visible = self.cleanliness < 50 + i * 10; } // Corruption increases when needs are low if (self.hunger < 30 || self.happiness < 30 || self.cleanliness < 30) { self.addCorruption(0.05); if (Math.random() < 0.1) { triggerGlitch(); } } // Random movement to make the pet more lively if (Math.random() < 0.05) { // Move in a random direction var moveX = (Math.random() - 0.5) * 30; var moveY = (Math.random() - 0.5) * 30; // Animate the movement tween(self, { x: self.x + moveX, y: self.y + moveY }, { duration: 800, easing: tween.easeInOut }); // Also add a small bounce effect tween(body, { scaleY: 1.1 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { tween(body, { scaleY: 1 }, { duration: 400, easing: tween.easeIn }); } }); } // Update visual based on corruption level self.updateAppearance(); }; self.addCorruption = function (amount) { var oldCorruption = self.corruption; self.corruption = Math.min(100, self.corruption + amount); if (oldCorruption < 33 && self.corruption >= 33) { self.evolve(1); } else if (oldCorruption < 66 && self.corruption >= 66) { self.evolve(2); } else if (oldCorruption < 100 && self.corruption >= 100) { self.evolve(3); } updateStatusBars(); // If corruption is crossing 50%, add extra visual effects if (oldCorruption < 50 && self.corruption >= 50 || amount > 5) { // Create more intense visual distortion for (var i = 0; i < 3; i++) { LK.setTimeout(function () { triggerGlitch(); }, i * 100); } // Create a momentary darkness effect var originalBg = game.backgroundColor; game.setBackgroundColor(0x333344); LK.setTimeout(function () { game.setBackgroundColor(originalBg); }, 200); } }; self.evolve = function (stage) { self.stage = stage; LK.getSound('transform').play(); // Create a strong glitch effect for evolution for (var i = 0; i < 10; i++) { LK.setTimeout(function () { triggerGlitch(); }, i * 200); } // Show strong visual change tween(body, { scaleX: 1.3, scaleY: 1.3, alpha: 0.5 }, { duration: 500, onFinish: function onFinish() { self.updateAppearance(); tween(body, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 500 }); } }); }; self.updateAppearance = function () { // Base form - cute and blue if (self.stage === 0) { body.tint = 0xaae1fc; // Make eyes red when any stat gets too low (below 20) if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) { self.leftEye.tint = 0xff0000; self.rightEye.tint = 0xff0000; // NIGHTMARE MODE when stats are critically low if (self.hunger < 10 && self.happiness < 10 && self.cleanliness < 10) { // Turn pet body dark red body.tint = 0x330000; // Distort eyes to look evil self.leftEye.scaleX = 1.8; self.leftEye.scaleY = 0.4; self.rightEye.scaleX = 1.8; self.rightEye.scaleY = 0.4; // Make mouth distorted and evil self.mouth.tint = 0xff0000; self.mouth.scaleX = 2.0; self.mouth.scaleY = 0.3; self.mouth.rotation = 0.8; self.mouth.y = 70; // Make title text change if (titleText) { titleText.setText("DIGITAL PET NIGHTMARE"); titleText.fill = 0xff0000; // Make it shake titleText.x = 2048 / 2 + (Math.random() - 0.5) * 10; titleText.y = 100 + (Math.random() - 0.5) * 10; // Add a glowing effect titleText.alpha = 0.7 + Math.random() * 0.3; // Flicker effect } // Make evolution/corruption text change if (corruptionLabel) { corruptionLabel.setText("DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE"); corruptionLabel.fill = 0xff0000; corruptionLabel.alpha = 1.0; // Make sure it's fully visible } } } else { self.leftEye.tint = 0x000000; self.rightEye.tint = 0x000000; } self.mouth.tint = 0x9966cc; self.leftEye.x = -70; self.rightEye.x = 70; self.leftEye.y = self.rightEye.y = -50; self.mouth.y = 30; // Reset any distortions if not in nightmare mode if (!(self.hunger < 10 && self.happiness < 10 && self.cleanliness < 10)) { self.leftEye.scaleX = self.leftEye.scaleY = 1; self.rightEye.scaleX = self.rightEye.scaleY = 1; self.mouth.scaleX = self.mouth.scaleY = 1; self.mouth.rotation = 0; } } // Stage 1 - starting to evolve else if (self.stage === 1) { body.tint = 0x99ddaa; // More green tint // Make eyes red when any stat gets too low (below 20) if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) { self.leftEye.tint = 0xff0000; self.rightEye.tint = 0xff0000; } else { self.leftEye.tint = 0x000000; self.rightEye.tint = 0x000000; } self.mouth.tint = 0x6655cc; // Slight asymmetry self.leftEye.x = -75; self.rightEye.x = 68; self.leftEye.scaleX = 1.1; self.rightEye.scaleX = 0.9; self.mouth.rotation = 0.1; } // Stage 2 - adolescent form else if (self.stage === 2) { body.tint = 0x77aacc; // More vibrant blue // Make eyes red when any stat gets too low (below 20) if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) { self.leftEye.tint = 0xff0000; self.rightEye.tint = 0xff0000; } else { self.leftEye.tint = 0x000088; // Blue eyes self.rightEye.tint = 0x000088; } self.mouth.tint = 0x5566dd; // More distinct features self.leftEye.x = -80; self.rightEye.x = 65; self.leftEye.y = -55; self.rightEye.y = -45; self.leftEye.scaleX = 1.2; self.leftEye.scaleY = 0.9; self.rightEye.scaleX = 0.9; self.rightEye.scaleY = 1.2; self.mouth.y = 60; self.mouth.scaleX = 1.2; self.mouth.rotation = 0.2; } // Stage 3 - final form else if (self.stage === 3) { body.tint = 0x5577cc; // Deeper blue // Make eyes red when any stat gets too low (below 20) if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) { self.leftEye.tint = 0xff0000; self.rightEye.tint = 0xff0000; } else { self.leftEye.tint = 0x0000ff; // Brighter blue eyes self.rightEye.tint = 0x0000ff; } self.mouth.tint = 0x6644dd; // Adult features self.leftEye.x = -85; self.rightEye.x = 65; self.leftEye.y = -60; self.rightEye.y = -40; self.leftEye.scaleX = 1.4; self.leftEye.scaleY = 0.8; self.rightEye.scaleX = 0.8; self.rightEye.scaleY = 1.4; self.mouth.y = 70; self.mouth.scaleX = 1.4; self.mouth.scaleY = 0.8; self.mouth.rotation = 0.3; } }; // Idle animations LK.setInterval(function () { self.blink(); }, 3000 + Math.random() * 2000); LK.setInterval(function () { self.breathe(); }, 2000); return self; }); var PlayOptionsMenu = Container.expand(function () { var self = Container.call(this); // Create menu background var background = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3, tint: 0x333333, alpha: 0.9 }); // Title text var titleText = new Text2("Play Options", { size: 60, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.y = -180; self.addChild(titleText); // Option buttons var ballButton = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, x: -100, y: 0, tint: 0xFF4444 }); var ballLabel = new Text2("Play Ball", { size: 40, fill: 0xFFFFFF }); ballLabel.anchor.set(0.5, 0.5); ballLabel.y = 100; ballButton.addChild(ballLabel); var arcadeButton = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, x: 100, y: 0, tint: 0x44AAFF }); var arcadeLabel = new Text2("Arcade", { size: 40, fill: 0xFFFFFF }); arcadeLabel.anchor.set(0.5, 0.5); arcadeLabel.y = 100; arcadeButton.addChild(arcadeLabel); // Make buttons interactive ballButton.interactive = true; arcadeButton.interactive = true; ballButton.down = function () { // Choose ball play option self.hide(); if (ball) { ball.activate(); } }; arcadeButton.down = function () { // Choose arcade play option self.hide(); if (arcadeGame) { arcadeGame.startGame(); } }; // Close button var closeButton = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, x: 180, y: -180, scaleX: 0.5, scaleY: 0.5, tint: 0xFF4444 }); var closeLabel = new Text2("X", { size: 40, fill: 0xFFFFFF }); closeLabel.anchor.set(0.5, 0.5); closeButton.addChild(closeLabel); closeButton.interactive = true; closeButton.down = function () { self.hide(); }; self.show = function () { self.visible = true; self.alpha = 0; tween(self, { alpha: 1 }, { duration: 200 }); }; self.hide = function () { tween(self, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { self.visible = false; } }); }; self.visible = false; return self; }); var Vacuum = Container.expand(function () { var self = Container.call(this); // Create vacuum base using existing assets var vacuumBody = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, tint: 0x666666 // Dark gray for vacuum body }); // Create vacuum nozzle var nozzle = self.attachAsset('cleanButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.2, x: 50, y: -20, tint: 0x444444 // Darker gray for nozzle }); // Create visual suction effect var suctionEffect = self.attachAsset('buttonIcon', { anchorX: 0.5, anchorY: 0.5, x: 80, y: -20, scaleX: 0.6, scaleY: 0.6, alpha: 0.6, tint: 0xaaaaff // Blue-ish suction effect }); self.startupPosition = { x: 0, y: 0 }; self.active = false; self.cleaning = false; // Animation for the suction effect self.animateSuction = function () { if (!self.active) { return; } tween(suctionEffect, { scaleX: 0.3, scaleY: 0.3, alpha: 0.3 }, { duration: 300, onFinish: function onFinish() { if (self.active) { tween(suctionEffect, { scaleX: 0.6, scaleY: 0.6, alpha: 0.6 }, { duration: 300, onFinish: self.animateSuction }); } } }); }; self.activate = function () { self.active = true; self.visible = true; // Store original position to return to self.startupPosition = { x: self.x, y: self.y }; // Move vacuum above the button and make it bigger self.y = self.y - 250; // Start suction animation self.animateSuction(); // Visual feedback that it's active - make it 2x bigger and apply tweening tween(self, { scaleX: 2.0, scaleY: 2.0 }, { duration: 200 }); }; self.deactivate = function () { self.active = false; // Return to original position with animation tween(self, { x: self.startupPosition.x, y: self.startupPosition.y }, { duration: 500, onFinish: function onFinish() { self.visible = false; // Reset scale vacuumBody.scaleX = vacuumBody.scaleY = 1.0; } }); }; self.cleanPet = function () { if (self.cleaning) { return; } self.cleaning = true; // Visual feedback for cleaning tween(suctionEffect, { scaleX: 1.0, scaleY: 1.0, alpha: 0.9 }, { duration: 300 }); // After cleaning is done, deactivate LK.setTimeout(function () { self.cleaning = false; self.deactivate(); }, 1000); }; self.visible = false; self.active = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game variables var pet; var feedButton, playButton, cleanButton; var statusBars = {}; var corruptionMeter; var gameTime = 0; var glitchEffects = []; var corruptionParticles = []; var gameStarted = false; var corruptionTextGlitching = false; var textGlitchTimer = null; var corruptionLabel; var titleText; var vacuum; var draggedItem = null; var food; var ball; var arcadeGame; var playOptionsMenu; // Initialize game elements function initGame() { // Setup background game.setBackgroundColor(0x66aadd); // Create pet pet = new Pet(); pet.x = 2048 / 2; pet.y = 2732 / 2 - 200; game.addChild(pet); // Create UI controls feedButton = new Button('feed'); feedButton.x = 2048 / 4; feedButton.y = 2732 - 200; game.addChild(feedButton); playButton = new Button('play'); playButton.x = 2048 / 2; playButton.y = 2732 - 200; game.addChild(playButton); cleanButton = new Button('clean'); cleanButton.x = 2048 * 3 / 4; cleanButton.y = 2732 - 200; game.addChild(cleanButton); // Add the Abandon button var abandonButton = new AbandonButton(); abandonButton.x = 2048 - 100; abandonButton.y = 100; game.addChild(abandonButton); // Create status bars createStatusBars(); // Create glitch effects for (var i = 0; i < 10; i++) { var glitch = new GlitchEffect(); game.addChild(glitch); glitchEffects.push(glitch); } // Create corruption particles for (var i = 0; i < 50; i++) { var particle = new CorruptionParticle(); game.addChild(particle); corruptionParticles.push(particle); } // Create vacuum cleaner vacuum = new Vacuum(); vacuum.x = cleanButton.x; vacuum.y = cleanButton.y - 100; vacuum.visible = false; game.addChild(vacuum); // Create draggable food food = new Food(); food.x = feedButton.x; food.y = feedButton.y - 150; game.addChild(food); // Create play ball ball = new Ball(); ball.x = playButton.x; ball.y = playButton.y - 150; game.addChild(ball); // Create arcade game arcadeGame = new ArcadeGame(); arcadeGame.x = 2048 / 2; arcadeGame.y = 2732 / 2 - 200; game.addChild(arcadeGame); // Create play options menu playOptionsMenu = new PlayOptionsMenu(); playOptionsMenu.x = 2048 / 2; playOptionsMenu.y = 2732 / 2 - 200; game.addChild(playOptionsMenu); // Create and add title titleText = new Text2("Digital Pet Friend", { size: 100, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 2048 / 2; titleText.y = 100; LK.gui.addChild(titleText); // Create game instructions var instructionsText = new Text2("Feed, play with, and clean your pet to keep it happy. Watch how it evolves over time!", { size: 40, fill: 0xDDDDDD }); instructionsText.anchor.set(0.5, 0); instructionsText.x = 2048 / 2; instructionsText.y = 220; instructionsText.width = 1800; LK.gui.addChild(instructionsText); // Start game music LK.playMusic('petMusic', { fade: { start: 0, end: 0.8, duration: 1000 } }); gameStarted = true; } function createStatusBars() { // Create container for all status bars var statusContainer = new Container(); statusContainer.x = 2048 / 2; statusContainer.y = 400; game.addChild(statusContainer); // Create each status bar var statusTypes = [{ name: 'hunger', label: 'Hunger', color: 0x22cc88 }, { name: 'happiness', label: 'Happiness', color: 0xff8822 }, { name: 'cleanliness', label: 'Cleanliness', color: 0x2288ff }]; var yOffset = 0; for (var i = 0; i < statusTypes.length; i++) { var type = statusTypes[i]; // Create label var label = new Text2(type.label, { size: 40, fill: 0xFFFFFF }); label.anchor.set(1, 0.5); label.x = -20; label.y = yOffset; statusContainer.addChild(label); // Create background bar var barBg = LK.getAsset('feedButton', { anchorX: 0, anchorY: 0.5, x: 0, y: yOffset, scaleX: 4, scaleY: 0.5, tint: 0x444444 }); statusContainer.addChild(barBg); // Create value bar var bar = LK.getAsset('feedButton', { anchorX: 0, anchorY: 0.5, x: 0, y: yOffset, scaleX: 4, scaleY: 0.5, tint: type.color }); statusContainer.addChild(bar); // Store reference to bar statusBars[type.name] = bar; yOffset += 60; } // Create evolution meter corruptionLabel = new Text2("Evolution", { size: 40, fill: 0xFFFFFF // Change from blue to white for better visibility }); var corruptionTextGlitching = false; var textGlitchTimer = null; corruptionLabel.anchor.set(1, 0.5); corruptionLabel.x = -20; corruptionLabel.y = yOffset; statusContainer.addChild(corruptionLabel); var corruptionBg = LK.getAsset('feedButton', { anchorX: 0, anchorY: 0.5, x: 0, y: yOffset, scaleX: 4, scaleY: 0.5, tint: 0x444444 }); statusContainer.addChild(corruptionBg); corruptionMeter = LK.getAsset('feedButton', { anchorX: 0, anchorY: 0.5, x: 0, y: yOffset, scaleX: 0, scaleY: 0.5, tint: 0x44AAFF }); statusContainer.addChild(corruptionMeter); } function updateStatusBars() { if (!gameStarted) { return; } // Update status bars based on pet stats statusBars.hunger.scaleX = pet.hunger / 25; statusBars.happiness.scaleX = pet.happiness / 25; statusBars.cleanliness.scaleX = pet.cleanliness / 25; // Update corruption meter corruptionMeter.scaleX = pet.corruption / 25; // Calculate average status to determine visual darkness var avgStatus = (pet.hunger + pet.happiness + pet.cleanliness) / 3; // Adjust game visuals based on average status - darker and less vibrant as stats decrease var darknessLevel = 1 - avgStatus / 100; var saturationReduction = darknessLevel * 0.5; var brightnessReduction = darknessLevel * 0.5; // Adjust background color (from light blue to darker desaturated blue) var r = Math.round(102 * (1 - brightnessReduction)); var g = Math.round(170 * (1 - brightnessReduction - saturationReduction)); var b = Math.round(221 * (1 - brightnessReduction)); game.setBackgroundColor(r << 16 | g << 8 | b); // Adjust visual elements opacity based on status pet.alpha = 0.5 + avgStatus / 200; // Fade pet slightly as status decreases } function triggerGlitch() { // Play sparkle sound LK.getSound('glitch').play(); // Check for nightmare mode var nightmareMode = pet && pet.hunger < 10 && pet.happiness < 10 && pet.cleanliness < 10; // Visual glitch effects - intensify based on corruption level or nightmare mode var intensity = nightmareMode ? 10 : pet.corruption > 50 ? 5 : 3; for (var i = 0; i < intensity; i++) { var glitch = glitchEffects[Math.floor(Math.random() * glitchEffects.length)]; glitch.startGlitch(); } // If corruption is above 50%, add stronger visual distortions if (pet.corruption > 50 && Math.random() < 0.5) { // Briefly distort the entire game view var originalScale = game.scale.x; tween(game.scale, { x: originalScale * (1 + (Math.random() - 0.5) * 0.1), y: originalScale * (1 + (Math.random() - 0.5) * 0.1) }, { duration: 100, onFinish: function onFinish() { tween(game.scale, { x: originalScale, y: originalScale }, { duration: 100 }); } }); } // Temporarily distort pet if (Math.random() < 0.3) { var originalRotation = pet.rotation; tween(pet, { rotation: originalRotation + (Math.random() - 0.5) * 0.3 }, { duration: 150, onFinish: function onFinish() { tween(pet, { rotation: originalRotation }, { duration: 150 }); } }); } // Screen shake if (Math.random() < 0.2) { var originalX = game.x; var originalY = game.y; tween(game, { x: originalX + (Math.random() - 0.5) * 20 }, { duration: 100, onFinish: function onFinish() { tween(game, { x: originalX }, { duration: 100 }); } }); } } function spawnCorruptionParticle() { // Find an inactive particle for (var i = 0; i < corruptionParticles.length; i++) { var particle = corruptionParticles[i]; if (!particle.active) { // Calculate position relative to pet var offsetX = (Math.random() - 0.5) * 300; var offsetY = (Math.random() - 0.5) * 300; particle.initialize(pet.x + offsetX, pet.y + offsetY, 60 + Math.floor(Math.random() * 60)); break; } } } // Add event handlers for dragging game.down = function (x, y, obj) { // Get event position directly // Check if we clicked on the vacuum when it's active if (vacuum && vacuum.active && vacuum.visible) { // Use direct hit testing instead of bounds checking if (x >= vacuum.x - vacuum.width / 2 && x <= vacuum.x + vacuum.width / 2 && y >= vacuum.y - vacuum.height / 2 && y <= vacuum.y + vacuum.height / 2) { draggedItem = vacuum; } } // Check if we clicked on the food when it's active if (food && food.active && food.visible) { // Use direct hit testing if (x >= food.x - food.width / 2 && x <= food.x + food.width / 2 && y >= food.y - food.height / 2 && y <= food.y + food.height / 2) { draggedItem = food; } } // Check if we clicked on the ball when it's active if (ball && ball.active && ball.visible) { // Use direct hit testing if (x >= ball.x - ball.width / 2 && x <= ball.x + ball.width / 2 && y >= ball.y - ball.height / 2 && y <= ball.y + ball.height / 2) { draggedItem = ball; } } }; game.up = function (x, y, obj) { if (draggedItem === vacuum) { // Use simplified distance-based collision detection for better results var dx = vacuum.x - pet.x; var dy = vacuum.y - pet.y; var distance = Math.sqrt(dx * dx + dy * dy); // If vacuum is within 200px of pet center, consider it a hit if (distance < 200) { // Vacuum is over the pet - clean it! vacuum.cleanPet(); pet.clean(); // This now has modified behavior for vacuum } else { // Not over pet, return vacuum vacuum.deactivate(); } draggedItem = null; } else if (draggedItem === food) { // Check if food is near pet's mouth var dx = food.x - pet.x; var dy = food.y - (pet.y + pet.mouth.y); var distance = Math.sqrt(dx * dx + dy * dy); // If food is within 100px of pet's mouth, consider it a hit if (distance < 100) { // Feed the pet pet.feed(); food.deactivate(); } else { // Return food to original position food.returnToPosition(); } draggedItem = null; } else if (draggedItem === ball) { // Check if ball is near pet var dx = ball.x - pet.x; var dy = ball.y - pet.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { // Play with pet using the ball pet.play(); ball.deactivate(); } else { // Return ball to original position ball.returnToPosition(); } draggedItem = null; } }; game.move = function (x, y, obj) { if (draggedItem) { // Use coordinates directly - no need to convert with toLocal draggedItem.x = x; draggedItem.y = y; } }; // Game Update Logic game.update = function () { if (!gameStarted) { initGame(); return; } gameTime++; // Update pet stats if (gameTime % 30 === 0) { pet.updateStats(); updateStatusBars(); // Check for nightmare mode var nightmareMode = pet.hunger < 10 && pet.happiness < 10 && pet.cleanliness < 10; // If in nightmare mode, apply special effects continuously if (nightmareMode) { // Occasional screen flashes if (Math.random() < 0.1) { LK.effects.flashScreen(0xff0000, 200); } // Random background color flashes if (Math.random() < 0.1) { var originalBg = game.backgroundColor; game.setBackgroundColor(0x330000); LK.setTimeout(function () { game.setBackgroundColor(originalBg); }, 100); } // Random glitches if (Math.random() < 0.2) { triggerGlitch(); } // Make title text shake constantly if (titleText) { titleText.x = 2048 / 2 + (Math.random() - 0.5) * 20; titleText.y = 100 + (Math.random() - 0.5) * 20; } // Make DIE text flash if (corruptionLabel && Math.random() < 0.5) { corruptionLabel.setText("DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE"); corruptionLabel.fill = Math.random() < 0.5 ? 0xff0000 : 0xffff00; // Add pulsing effect for more intensity corruptionLabel.scaleX = corruptionLabel.scaleY = 1 + Math.random() * 0.3; } } // Handle corruption text glitching when corruption is around halfway and not in nightmare mode else if (pet.corruption >= 40 && pet.corruption <= 60) { if (!corruptionTextGlitching) { corruptionTextGlitching = true; textGlitchTimer = LK.setInterval(function () { // Toggle between "Evolution" and "Corruption" if (corruptionLabel.text === "Evolution") { corruptionLabel.setText("Corruption"); // Add slight visual glitch effect tween(corruptionLabel, { rotation: (Math.random() - 0.5) * 0.1 }, { duration: 100 }); } else { corruptionLabel.setText("Evolution"); // Reset rotation tween(corruptionLabel, { rotation: 0 }, { duration: 100 }); } }, 400); } } else if (corruptionTextGlitching && !nightmareMode) { // Stop glitching when out of the 40-60 range corruptionTextGlitching = false; LK.clearInterval(textGlitchTimer); corruptionLabel.setText(pet.corruption < 50 ? "Evolution" : "Corruption"); corruptionLabel.rotation = 0; } } // Spawn corruption particles based on corruption level if (pet.corruption > 30 && gameTime % Math.max(5, 30 - pet.corruption / 5) === 0) { spawnCorruptionParticle(); } // Update all corruption particles for (var i = 0; i < corruptionParticles.length; i++) { corruptionParticles[i].update(); } // Update arcade game if active if (arcadeGame && arcadeGame.active) { arcadeGame.update(); } // Random glitches when heavily corrupted if (pet.corruption > 70 && Math.random() < 0.005) { triggerGlitch(); } // Check for game over condition if (pet.corruption >= 100 && pet.hunger <= 0 && pet.happiness <= 0 && pet.cleanliness <= 0) { // Nightmare complete for (var i = 0; i < 20; i++) { LK.setTimeout(function () { triggerGlitch(); }, i * 100); } LK.setTimeout(function () { LK.showGameOver(); }, 2000); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AbandonButton = Container.expand(function () {
var self = Container.call(this);
var buttonShape = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xcc0000 // Red color for warning
});
var label = new Text2("ABANDON", {
size: 40,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.interactive = true;
self.down = function (x, y, obj) {
tween(buttonShape, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
tween(buttonShape, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
// Trigger nightmare mode
self.triggerNightmareMode();
};
self.triggerNightmareMode = function () {
// Add massive corruption to instantly transform pet
if (pet) {
// Maximum corruption
pet.addCorruption(100);
// Make everything scary
// Dark background
game.setBackgroundColor(0x110011);
// Intense glitch effects
for (var i = 0; i < 20; i++) {
LK.setTimeout(function () {
triggerGlitch();
}, i * 100);
}
// Make pet eyes red and distorted
if (pet.leftEye && pet.rightEye) {
pet.leftEye.tint = 0xff0000;
pet.rightEye.tint = 0xff0000;
// Distort eyes
tween(pet.leftEye, {
scaleX: 1.8,
scaleY: 0.6
}, {
duration: 500
});
tween(pet.rightEye, {
scaleX: 0.6,
scaleY: 1.8
}, {
duration: 500
});
}
// Distort mouth
if (pet.mouth) {
pet.mouth.tint = 0xff0000;
tween(pet.mouth, {
scaleX: 2.0,
scaleY: 0.5,
rotation: 0.5
}, {
duration: 500
});
}
// Reduce all pet stats to minimum
pet.hunger = 1;
pet.happiness = 1;
pet.cleanliness = 1;
updateStatusBars();
// Play glitch sound rapidly
for (var i = 0; i < 5; i++) {
LK.setTimeout(function () {
LK.getSound('glitch').play();
}, i * 200);
}
}
};
return self;
});
var ArcadeGame = Container.expand(function () {
var self = Container.call(this);
// Game state
self.active = false;
self.score = 0;
self.gameOver = false;
self.playerX = 0;
self.targets = [];
self.timeRemaining = 30; // 30 second game
self.lastCountdownTime = 0;
self.lives = 3; // Player has 3 lives
// Create game background
var background = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
// Increased size
scaleY: 9,
// Increased size
tint: 0x000000
});
// Create player - use pet body asset instead of generic shape
var player = self.attachAsset('petBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
y: 200,
tint: 0x44FF44
});
// Create score text
var scoreText = new Text2("Score: 0", {
size: 40,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0.5);
scoreText.y = -350;
self.addChild(scoreText);
// Create countdown text
var countdownText = new Text2("Time: 30", {
size: 40,
fill: 0xFFFFFF
});
countdownText.anchor.set(0.5, 0.5);
countdownText.y = -300;
self.addChild(countdownText);
// Create lives display
var livesText = new Text2("Lives: 3", {
size: 40,
fill: 0xFFFFFF
});
livesText.anchor.set(0.5, 0.5);
livesText.y = -250;
self.addChild(livesText);
// Create game controls
var leftButton = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
x: -150,
y: 300,
tint: 0x4488FF
});
var rightButton = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
x: 150,
y: 300,
tint: 0x4488FF
});
// Add arrow indicators to buttons
var leftArrow = new Text2("<", {
size: 50,
fill: 0xFFFFFF
});
leftArrow.anchor.set(0.5, 0.5);
leftButton.addChild(leftArrow);
var rightArrow = new Text2(">", {
size: 50,
fill: 0xFFFFFF
});
rightArrow.anchor.set(0.5, 0.5);
rightButton.addChild(rightArrow);
// Make buttons interactive
leftButton.interactive = true;
rightButton.interactive = true;
leftButton.down = function () {
self.movePlayer(-10);
};
rightButton.down = function () {
self.movePlayer(10);
};
// Initialize targets
for (var i = 0; i < 5; i++) {
var target = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 300,
y: -150 - Math.random() * 100,
scaleX: 0.7,
scaleY: 0.7,
visible: false
});
self.targets.push({
sprite: target,
active: false,
speed: 2 + Math.random() * 1.5 // Reduced from 3+random*2 to make it easier
});
}
self.movePlayer = function (amount) {
if (!self.active || self.gameOver) {
return;
}
self.playerX += amount;
// Keep player within bounds
self.playerX = Math.max(-150, Math.min(150, self.playerX));
// Use tween for smoother movement
tween(player, {
x: self.playerX,
rotation: amount > 0 ? 0.1 : amount < 0 ? -0.1 : 0 // Tilt in direction of movement
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Return to neutral rotation
if (amount !== 0) {
tween(player, {
rotation: 0
}, {
duration: 100
});
}
}
});
};
self.updateTargets = function () {
var activeCount = 0;
// Update existing targets
for (var i = 0; i < self.targets.length; i++) {
var target = self.targets[i];
if (target.active) {
activeCount++;
// Move target down
target.sprite.y += target.speed;
// Check if player caught the target
var dx = target.sprite.x - player.x;
var dy = target.sprite.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
// Caught target - increase score
self.score += 10;
scoreText.setText("Score: " + self.score);
// Deactivate target
target.active = false;
target.sprite.visible = false;
}
// Check if target reached bottom
if (target.sprite.y > 250) {
// Target missed
target.active = false;
target.sprite.visible = false;
// Decrease lives instead of ending game immediately
self.lives--;
livesText.setText("Lives: " + self.lives);
// Flash lives text red
tween(livesText, {
tint: 0xFF0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(livesText, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
// End game if no lives left
if (self.lives <= 0) {
self.gameOver = true;
self.endGame();
}
}
}
}
// Spawn new target if needed - reduced spawn rate from 0.05 to 0.02
if (activeCount < 2 && Math.random() < 0.02 && !self.gameOver) {
var randomTarget = self.targets[Math.floor(Math.random() * self.targets.length)];
if (!randomTarget.active) {
randomTarget.active = true;
randomTarget.sprite.visible = true;
randomTarget.sprite.x = (Math.random() - 0.5) * 300;
randomTarget.sprite.y = -200;
}
}
};
self.startGame = function () {
self.visible = true;
self.active = true;
self.gameOver = false;
self.score = 0;
self.playerX = 0;
player.x = 0;
scoreText.setText("Score: 0");
// Reset countdown
self.timeRemaining = 30;
self.lastCountdownTime = 0;
countdownText.setText("Time: 30");
// Reset lives
self.lives = 3;
livesText.setText("Lives: 3");
// Reset all targets
for (var i = 0; i < self.targets.length; i++) {
self.targets[i].active = false;
self.targets[i].sprite.visible = false;
}
};
self.endGame = function () {
// Show game over message
var gameOverText = new Text2("Game Over!", {
size: 60,
fill: 0xFF4444
});
gameOverText.anchor.set(0.5, 0.5);
self.addChild(gameOverText);
// Show final score with any time bonus
var finalScore = self.score;
if (self.timeRemaining > 0) {
// Add bonus points for remaining time
var timeBonus = self.timeRemaining * 5;
finalScore += timeBonus;
// Show bonus message
var bonusText = new Text2("Time Bonus: +" + timeBonus, {
size: 40,
fill: 0x44FF44
});
bonusText.anchor.set(0.5, 0.5);
bonusText.y = 60;
gameOverText.addChild(bonusText);
// Update score display
scoreText.setText("Final Score: " + finalScore);
}
// Hide game over and give reward after delay
LK.setTimeout(function () {
self.deactivate();
// Increase pet happiness based on score
if (pet) {
var happinessBoost = Math.min(50, finalScore / 10);
pet.happiness = Math.min(100, pet.happiness + happinessBoost);
updateStatusBars();
}
}, 3000);
};
self.update = function () {
if (!self.active) {
return;
}
self.updateTargets();
// Update countdown timer (every second)
var currentTime = Math.floor(LK.ticks / 60);
if (currentTime > self.lastCountdownTime) {
self.lastCountdownTime = currentTime;
self.timeRemaining--;
countdownText.setText("Time: " + self.timeRemaining);
// Flash countdown text when time is running out (less than 10 seconds)
if (self.timeRemaining <= 10) {
tween(countdownText, {
tint: 0xFF0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(countdownText, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
}
// End game when time runs out
if (self.timeRemaining <= 0) {
self.gameOver = true;
self.endGame();
}
}
};
self.deactivate = function () {
self.active = false;
tween(self, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.visible = false;
self.alpha = 1;
}
});
};
self.visible = false;
return self;
});
var Ball = Container.expand(function () {
var self = Container.call(this);
// Create ball using existing buttonIcon asset
var ballGraphics = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFF4444 // Red ball
});
// Add some decoration to make it look more like a ball
var highlight = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
x: -15,
y: -15,
tint: 0xFFFFFF,
alpha: 0.7
});
self.interactive = true;
self.visible = false;
self.active = false;
self.originalX = 0;
self.originalY = 0;
self.down = function (x, y, obj) {
// Scale down when pressed
tween(ballGraphics, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
// Restore scale when released
tween(ballGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
if (self.active) {
// Check if ball is near pet
var dx = self.x - pet.x;
var dy = self.y - pet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
// Play with pet using the ball
pet.play();
self.deactivate();
} else {
// Return to original position
self.returnToPosition();
}
}
};
self.activate = function () {
self.visible = true;
self.active = true;
self.originalX = playButton.x;
self.originalY = playButton.y - 150;
self.x = self.originalX;
self.y = self.originalY;
// Animation to indicate it's ready
tween(ballGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(ballGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
};
self.deactivate = function () {
self.active = false;
// Fade out
tween(self, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.visible = false;
self.alpha = 1;
}
});
};
self.returnToPosition = function () {
tween(self, {
x: self.originalX,
y: self.originalY
}, {
duration: 300
});
};
return self;
});
var Button = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.onCooldown = false;
self.cooldownDuration = 2000; // 2 seconds cooldown
var buttonShape = self.attachAsset(type + 'Button', {
anchorX: 0.5,
anchorY: 0.5
});
var icon = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var label = new Text2(type.charAt(0).toUpperCase() + type.slice(1), {
size: 40,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
label.y = 70;
self.addChild(label);
self.interactive = true;
self.startCooldown = function () {
if (self.onCooldown) {
return;
}
self.onCooldown = true;
// Grey out the button during cooldown
tween(buttonShape, {
tint: 0x888888
}, {
duration: 100
});
// Set a timeout to end the cooldown
LK.setTimeout(function () {
self.onCooldown = false;
// Restore button color
tween(buttonShape, {
tint: 0xFFFFFF
}, {
duration: 100
});
}, self.cooldownDuration);
};
self.down = function (x, y, obj) {
tween(buttonShape, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
tween(buttonShape, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
// Only act if not on cooldown
if (!self.onCooldown) {
LK.getSound(self.type).play();
self.startCooldown();
switch (self.type) {
case 'feed':
// Activate food instead of directly feeding
if (food) {
food.activate();
}
break;
case 'play':
// Show play options popup
if (playOptionsMenu && !playOptionsMenu.visible) {
playOptionsMenu.show();
} else {
// Fallback to direct play if menu isn't available
pet.play();
}
break;
case 'clean':
pet.clean();
break;
}
}
};
return self;
});
var CorruptionParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('corruptionEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6
});
self.lifespan = 0;
self.maxLife = 0;
self.speedX = 0;
self.speedY = 0;
self.active = false;
self.initialize = function (x, y, duration) {
self.x = x;
self.y = y;
self.maxLife = duration;
self.lifespan = duration;
self.speedX = (Math.random() - 0.5) * 3;
self.speedY = (Math.random() - 0.5) * 3;
self.rotation = Math.random() * Math.PI * 2;
self.active = true;
self.visible = true;
self.alpha = 0.6;
// Color selection depends on corruption level - darker as corruption increases
var randomColor = Math.random();
var corruptionLevel = pet ? pet.corruption : 0;
var darkerColors = corruptionLevel > 50;
var nightmareMode = corruptionLevel >= 95;
if (nightmareMode) {
// Extremely dark, scary colors for nightmare mode
if (randomColor < 0.33) {
particleGraphics.tint = 0xff0000; // Blood red
} else if (randomColor < 0.66) {
particleGraphics.tint = 0x660000; // Dark red
} else {
particleGraphics.tint = 0x330000; // Very dark red
}
// Larger and more intense for nightmare mode
particleGraphics.scaleX = particleGraphics.scaleY = 1.5 + Math.random();
} else if (darkerColors) {
// Darker, more ominous colors when corruption is higher
if (randomColor < 0.33) {
particleGraphics.tint = 0x4455aa; // Dark blue
} else if (randomColor < 0.66) {
particleGraphics.tint = 0x335566; // Dark teal
} else {
particleGraphics.tint = 0x556677; // Dark slate
}
} else {
// Original brighter colors for lower corruption
if (randomColor < 0.33) {
particleGraphics.tint = 0x88aaff; // Light blue
} else if (randomColor < 0.66) {
particleGraphics.tint = 0x55ddaa; // Teal
} else {
particleGraphics.tint = 0xaaddff; // Sky blue
}
}
};
self.update = function () {
if (!self.active) {
return;
}
self.lifespan--;
self.x += self.speedX;
self.y += self.speedY;
self.alpha = self.lifespan / self.maxLife * 0.6;
if (self.lifespan <= 0) {
self.active = false;
self.visible = false;
}
};
self.visible = false;
self.active = false;
return self;
});
var Food = Container.expand(function () {
var self = Container.call(this);
var foodGraphics = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
self.interactive = true;
self.visible = false;
self.active = false;
self.down = function (x, y, obj) {
// Scale down when pressed
tween(foodGraphics, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
// Restore scale when released
tween(foodGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
if (self.active) {
// Check if food is near pet's mouth
var dx = self.x - pet.x;
var dy = self.y - (pet.y + pet.mouth.y);
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
// Feed the pet
pet.feed();
self.deactivate();
} else {
// Return to original position
self.returnToPosition();
}
}
};
self.activate = function () {
self.visible = true;
self.active = true;
self.originalX = feedButton.x;
self.originalY = feedButton.y - 150;
self.x = self.originalX;
self.y = self.originalY;
// Animation to indicate it's ready
tween(foodGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(foodGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
};
self.deactivate = function () {
self.active = false;
// Fade out
tween(self, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.visible = false;
self.alpha = 1;
}
});
};
self.returnToPosition = function () {
tween(self, {
x: self.originalX,
y: self.originalY
}, {
duration: 300
});
};
return self;
});
var GlitchEffect = Container.expand(function () {
var self = Container.call(this);
var glitchGraphics = self.attachAsset('glitchEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.startGlitch = function () {
self.visible = true;
self.x = Math.random() * 2048;
self.y = Math.random() * 2732;
self.rotation = Math.random() * Math.PI * 2;
self.alpha = 0.7;
tween(self, {
alpha: 0
}, {
duration: 300 + Math.random() * 700,
onFinish: function onFinish() {
self.visible = false;
}
});
};
self.visible = false;
return self;
});
var Pet = Container.expand(function () {
var self = Container.call(this);
// Stats
self.hunger = 100;
self.happiness = 100;
self.cleanliness = 100;
self.corruption = 0;
self.stage = 0; // 0 = normal, 1 = starting to corrupt, 2 = more corrupt, 3 = nightmare
// Visual components
var body = self.attachAsset('petBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
// Make these properties accessible from outside for the abandon button
self.leftEye = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: -70,
y: -50
});
self.rightEye = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: 70,
y: -50
});
self.mouth = self.attachAsset('petMouth', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
// Food item that appears when feeding
var foodItem = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5,
visible: false,
x: 0,
y: -200
});
// Toy that appears when playing
var toyItem = self.attachAsset('toy', {
anchorX: 0.5,
anchorY: 0.5,
visible: false,
x: 200,
y: 0
});
// Dirt patches that appear when pet is dirty
var dirtPatches = [];
for (var i = 0; i < 5; i++) {
var dirt = self.attachAsset('dirt', {
anchorX: 0.5,
anchorY: 0.5,
visible: false,
x: (Math.random() - 0.5) * 200,
y: (Math.random() - 0.5) * 200
});
dirtPatches.push(dirt);
}
self.blink = function () {
tween(self.leftEye, {
scaleY: 0.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(self.leftEye, {
scaleY: 1
}, {
duration: 100
});
}
});
tween(self.rightEye, {
scaleY: 0.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(self.rightEye, {
scaleY: 1
}, {
duration: 100
});
}
});
};
self.breathe = function () {
tween(body, {
scaleY: 1.05
}, {
duration: 1000,
onFinish: function onFinish() {
tween(body, {
scaleY: 1
}, {
duration: 1000
});
}
});
};
self.feed = function () {
self.hunger = Math.min(100, self.hunger + 30);
// Decrease cleanliness when feeding
self.cleanliness = Math.max(0, self.cleanliness - 15);
updateStatusBars();
// Make pet happy from feeding with more animated reaction
// Move slightly up with excitement
tween(self, {
y: self.y - 30
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 30
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// More expressive mouth animation
tween(self.mouth, {
scaleX: 1.5,
scaleY: 1.5,
rotation: 0.1
}, {
duration: 300,
onFinish: function onFinish() {
tween(self.mouth, {
scaleX: 1,
scaleY: 1,
rotation: 0
}, {
duration: 300
});
}
});
// Sometimes add corruption from feeding in later stages
if (self.corruption > 40 && Math.random() < 0.3) {
self.addCorruption(5);
triggerGlitch();
}
};
self.play = function () {
toyItem.visible = true;
toyItem.x = 200;
tween(toyItem, {
x: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.happiness = Math.min(100, self.happiness + 30);
// Decrease hunger when playing with the pet
self.hunger = Math.max(0, self.hunger - 15);
updateStatusBars();
// Bounce toy
tween(toyItem, {
y: -100
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(toyItem, {
y: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
toyItem.visible = false;
toyItem.alpha = 1;
}
});
}
});
// Make pet happy from playing
tween(body, {
rotation: 0.1
}, {
duration: 200,
onFinish: function onFinish() {
tween(body, {
rotation: -0.1
}, {
duration: 200,
onFinish: function onFinish() {
tween(body, {
rotation: 0
}, {
duration: 200
});
}
});
}
});
}
});
// Sometimes add corruption from playing in later stages
if (self.corruption > 40 && Math.random() < 0.3) {
self.addCorruption(5);
triggerGlitch();
}
};
self.clean = function () {
// Activate vacuum cleaner instead of directly cleaning
if (vacuum && !vacuum.active) {
vacuum.x = cleanButton.x;
vacuum.y = cleanButton.y;
vacuum.activate();
return; // Exit early - actual cleaning happens when vacuum is dragged to pet
}
// This section only executes when cleaning is triggered by the vacuum
self.cleanliness = Math.min(100, self.cleanliness + 30);
// Reduce happiness more significantly when cleaning with vacuum
self.happiness = Math.max(0, self.happiness - 25);
updateStatusBars();
// Hide dirt patches
for (var i = 0; i < dirtPatches.length; i++) {
dirtPatches[i].visible = false;
}
// Sparkle effect
tween(body, {
alpha: 0.7
}, {
duration: 200,
onFinish: function onFinish() {
tween(body, {
alpha: 1
}, {
duration: 200
});
}
});
// Sometimes add corruption from cleaning in later stages
if (self.corruption > 40 && Math.random() < 0.3) {
self.addCorruption(5);
triggerGlitch();
}
};
self.updateStats = function () {
// Decrease stats over time - increased decay rates
self.hunger = Math.max(0, self.hunger - 0.3);
self.happiness = Math.max(0, self.happiness - 0.4);
self.cleanliness = Math.max(0, self.cleanliness - 0.35);
// Show dirt when dirty
for (var i = 0; i < dirtPatches.length; i++) {
dirtPatches[i].visible = self.cleanliness < 50 + i * 10;
}
// Corruption increases when needs are low
if (self.hunger < 30 || self.happiness < 30 || self.cleanliness < 30) {
self.addCorruption(0.05);
if (Math.random() < 0.1) {
triggerGlitch();
}
}
// Random movement to make the pet more lively
if (Math.random() < 0.05) {
// Move in a random direction
var moveX = (Math.random() - 0.5) * 30;
var moveY = (Math.random() - 0.5) * 30;
// Animate the movement
tween(self, {
x: self.x + moveX,
y: self.y + moveY
}, {
duration: 800,
easing: tween.easeInOut
});
// Also add a small bounce effect
tween(body, {
scaleY: 1.1
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(body, {
scaleY: 1
}, {
duration: 400,
easing: tween.easeIn
});
}
});
}
// Update visual based on corruption level
self.updateAppearance();
};
self.addCorruption = function (amount) {
var oldCorruption = self.corruption;
self.corruption = Math.min(100, self.corruption + amount);
if (oldCorruption < 33 && self.corruption >= 33) {
self.evolve(1);
} else if (oldCorruption < 66 && self.corruption >= 66) {
self.evolve(2);
} else if (oldCorruption < 100 && self.corruption >= 100) {
self.evolve(3);
}
updateStatusBars();
// If corruption is crossing 50%, add extra visual effects
if (oldCorruption < 50 && self.corruption >= 50 || amount > 5) {
// Create more intense visual distortion
for (var i = 0; i < 3; i++) {
LK.setTimeout(function () {
triggerGlitch();
}, i * 100);
}
// Create a momentary darkness effect
var originalBg = game.backgroundColor;
game.setBackgroundColor(0x333344);
LK.setTimeout(function () {
game.setBackgroundColor(originalBg);
}, 200);
}
};
self.evolve = function (stage) {
self.stage = stage;
LK.getSound('transform').play();
// Create a strong glitch effect for evolution
for (var i = 0; i < 10; i++) {
LK.setTimeout(function () {
triggerGlitch();
}, i * 200);
}
// Show strong visual change
tween(body, {
scaleX: 1.3,
scaleY: 1.3,
alpha: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
self.updateAppearance();
tween(body, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 500
});
}
});
};
self.updateAppearance = function () {
// Base form - cute and blue
if (self.stage === 0) {
body.tint = 0xaae1fc;
// Make eyes red when any stat gets too low (below 20)
if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) {
self.leftEye.tint = 0xff0000;
self.rightEye.tint = 0xff0000;
// NIGHTMARE MODE when stats are critically low
if (self.hunger < 10 && self.happiness < 10 && self.cleanliness < 10) {
// Turn pet body dark red
body.tint = 0x330000;
// Distort eyes to look evil
self.leftEye.scaleX = 1.8;
self.leftEye.scaleY = 0.4;
self.rightEye.scaleX = 1.8;
self.rightEye.scaleY = 0.4;
// Make mouth distorted and evil
self.mouth.tint = 0xff0000;
self.mouth.scaleX = 2.0;
self.mouth.scaleY = 0.3;
self.mouth.rotation = 0.8;
self.mouth.y = 70;
// Make title text change
if (titleText) {
titleText.setText("DIGITAL PET NIGHTMARE");
titleText.fill = 0xff0000;
// Make it shake
titleText.x = 2048 / 2 + (Math.random() - 0.5) * 10;
titleText.y = 100 + (Math.random() - 0.5) * 10;
// Add a glowing effect
titleText.alpha = 0.7 + Math.random() * 0.3; // Flicker effect
}
// Make evolution/corruption text change
if (corruptionLabel) {
corruptionLabel.setText("DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE");
corruptionLabel.fill = 0xff0000;
corruptionLabel.alpha = 1.0; // Make sure it's fully visible
}
}
} else {
self.leftEye.tint = 0x000000;
self.rightEye.tint = 0x000000;
}
self.mouth.tint = 0x9966cc;
self.leftEye.x = -70;
self.rightEye.x = 70;
self.leftEye.y = self.rightEye.y = -50;
self.mouth.y = 30;
// Reset any distortions if not in nightmare mode
if (!(self.hunger < 10 && self.happiness < 10 && self.cleanliness < 10)) {
self.leftEye.scaleX = self.leftEye.scaleY = 1;
self.rightEye.scaleX = self.rightEye.scaleY = 1;
self.mouth.scaleX = self.mouth.scaleY = 1;
self.mouth.rotation = 0;
}
}
// Stage 1 - starting to evolve
else if (self.stage === 1) {
body.tint = 0x99ddaa; // More green tint
// Make eyes red when any stat gets too low (below 20)
if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) {
self.leftEye.tint = 0xff0000;
self.rightEye.tint = 0xff0000;
} else {
self.leftEye.tint = 0x000000;
self.rightEye.tint = 0x000000;
}
self.mouth.tint = 0x6655cc;
// Slight asymmetry
self.leftEye.x = -75;
self.rightEye.x = 68;
self.leftEye.scaleX = 1.1;
self.rightEye.scaleX = 0.9;
self.mouth.rotation = 0.1;
}
// Stage 2 - adolescent form
else if (self.stage === 2) {
body.tint = 0x77aacc; // More vibrant blue
// Make eyes red when any stat gets too low (below 20)
if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) {
self.leftEye.tint = 0xff0000;
self.rightEye.tint = 0xff0000;
} else {
self.leftEye.tint = 0x000088; // Blue eyes
self.rightEye.tint = 0x000088;
}
self.mouth.tint = 0x5566dd;
// More distinct features
self.leftEye.x = -80;
self.rightEye.x = 65;
self.leftEye.y = -55;
self.rightEye.y = -45;
self.leftEye.scaleX = 1.2;
self.leftEye.scaleY = 0.9;
self.rightEye.scaleX = 0.9;
self.rightEye.scaleY = 1.2;
self.mouth.y = 60;
self.mouth.scaleX = 1.2;
self.mouth.rotation = 0.2;
}
// Stage 3 - final form
else if (self.stage === 3) {
body.tint = 0x5577cc; // Deeper blue
// Make eyes red when any stat gets too low (below 20)
if (self.hunger < 20 || self.happiness < 20 || self.cleanliness < 20) {
self.leftEye.tint = 0xff0000;
self.rightEye.tint = 0xff0000;
} else {
self.leftEye.tint = 0x0000ff; // Brighter blue eyes
self.rightEye.tint = 0x0000ff;
}
self.mouth.tint = 0x6644dd;
// Adult features
self.leftEye.x = -85;
self.rightEye.x = 65;
self.leftEye.y = -60;
self.rightEye.y = -40;
self.leftEye.scaleX = 1.4;
self.leftEye.scaleY = 0.8;
self.rightEye.scaleX = 0.8;
self.rightEye.scaleY = 1.4;
self.mouth.y = 70;
self.mouth.scaleX = 1.4;
self.mouth.scaleY = 0.8;
self.mouth.rotation = 0.3;
}
};
// Idle animations
LK.setInterval(function () {
self.blink();
}, 3000 + Math.random() * 2000);
LK.setInterval(function () {
self.breathe();
}, 2000);
return self;
});
var PlayOptionsMenu = Container.expand(function () {
var self = Container.call(this);
// Create menu background
var background = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
tint: 0x333333,
alpha: 0.9
});
// Title text
var titleText = new Text2("Play Options", {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -180;
self.addChild(titleText);
// Option buttons
var ballButton = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: -100,
y: 0,
tint: 0xFF4444
});
var ballLabel = new Text2("Play Ball", {
size: 40,
fill: 0xFFFFFF
});
ballLabel.anchor.set(0.5, 0.5);
ballLabel.y = 100;
ballButton.addChild(ballLabel);
var arcadeButton = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: 0,
tint: 0x44AAFF
});
var arcadeLabel = new Text2("Arcade", {
size: 40,
fill: 0xFFFFFF
});
arcadeLabel.anchor.set(0.5, 0.5);
arcadeLabel.y = 100;
arcadeButton.addChild(arcadeLabel);
// Make buttons interactive
ballButton.interactive = true;
arcadeButton.interactive = true;
ballButton.down = function () {
// Choose ball play option
self.hide();
if (ball) {
ball.activate();
}
};
arcadeButton.down = function () {
// Choose arcade play option
self.hide();
if (arcadeGame) {
arcadeGame.startGame();
}
};
// Close button
var closeButton = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 180,
y: -180,
scaleX: 0.5,
scaleY: 0.5,
tint: 0xFF4444
});
var closeLabel = new Text2("X", {
size: 40,
fill: 0xFFFFFF
});
closeLabel.anchor.set(0.5, 0.5);
closeButton.addChild(closeLabel);
closeButton.interactive = true;
closeButton.down = function () {
self.hide();
};
self.show = function () {
self.visible = true;
self.alpha = 0;
tween(self, {
alpha: 1
}, {
duration: 200
});
};
self.hide = function () {
tween(self, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.visible = false;
}
});
};
self.visible = false;
return self;
});
var Vacuum = Container.expand(function () {
var self = Container.call(this);
// Create vacuum base using existing assets
var vacuumBody = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x666666 // Dark gray for vacuum body
});
// Create vacuum nozzle
var nozzle = self.attachAsset('cleanButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.2,
x: 50,
y: -20,
tint: 0x444444 // Darker gray for nozzle
});
// Create visual suction effect
var suctionEffect = self.attachAsset('buttonIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 80,
y: -20,
scaleX: 0.6,
scaleY: 0.6,
alpha: 0.6,
tint: 0xaaaaff // Blue-ish suction effect
});
self.startupPosition = {
x: 0,
y: 0
};
self.active = false;
self.cleaning = false;
// Animation for the suction effect
self.animateSuction = function () {
if (!self.active) {
return;
}
tween(suctionEffect, {
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.3
}, {
duration: 300,
onFinish: function onFinish() {
if (self.active) {
tween(suctionEffect, {
scaleX: 0.6,
scaleY: 0.6,
alpha: 0.6
}, {
duration: 300,
onFinish: self.animateSuction
});
}
}
});
};
self.activate = function () {
self.active = true;
self.visible = true;
// Store original position to return to
self.startupPosition = {
x: self.x,
y: self.y
};
// Move vacuum above the button and make it bigger
self.y = self.y - 250;
// Start suction animation
self.animateSuction();
// Visual feedback that it's active - make it 2x bigger and apply tweening
tween(self, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 200
});
};
self.deactivate = function () {
self.active = false;
// Return to original position with animation
tween(self, {
x: self.startupPosition.x,
y: self.startupPosition.y
}, {
duration: 500,
onFinish: function onFinish() {
self.visible = false;
// Reset scale
vacuumBody.scaleX = vacuumBody.scaleY = 1.0;
}
});
};
self.cleanPet = function () {
if (self.cleaning) {
return;
}
self.cleaning = true;
// Visual feedback for cleaning
tween(suctionEffect, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.9
}, {
duration: 300
});
// After cleaning is done, deactivate
LK.setTimeout(function () {
self.cleaning = false;
self.deactivate();
}, 1000);
};
self.visible = false;
self.active = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game variables
var pet;
var feedButton, playButton, cleanButton;
var statusBars = {};
var corruptionMeter;
var gameTime = 0;
var glitchEffects = [];
var corruptionParticles = [];
var gameStarted = false;
var corruptionTextGlitching = false;
var textGlitchTimer = null;
var corruptionLabel;
var titleText;
var vacuum;
var draggedItem = null;
var food;
var ball;
var arcadeGame;
var playOptionsMenu;
// Initialize game elements
function initGame() {
// Setup background
game.setBackgroundColor(0x66aadd);
// Create pet
pet = new Pet();
pet.x = 2048 / 2;
pet.y = 2732 / 2 - 200;
game.addChild(pet);
// Create UI controls
feedButton = new Button('feed');
feedButton.x = 2048 / 4;
feedButton.y = 2732 - 200;
game.addChild(feedButton);
playButton = new Button('play');
playButton.x = 2048 / 2;
playButton.y = 2732 - 200;
game.addChild(playButton);
cleanButton = new Button('clean');
cleanButton.x = 2048 * 3 / 4;
cleanButton.y = 2732 - 200;
game.addChild(cleanButton);
// Add the Abandon button
var abandonButton = new AbandonButton();
abandonButton.x = 2048 - 100;
abandonButton.y = 100;
game.addChild(abandonButton);
// Create status bars
createStatusBars();
// Create glitch effects
for (var i = 0; i < 10; i++) {
var glitch = new GlitchEffect();
game.addChild(glitch);
glitchEffects.push(glitch);
}
// Create corruption particles
for (var i = 0; i < 50; i++) {
var particle = new CorruptionParticle();
game.addChild(particle);
corruptionParticles.push(particle);
}
// Create vacuum cleaner
vacuum = new Vacuum();
vacuum.x = cleanButton.x;
vacuum.y = cleanButton.y - 100;
vacuum.visible = false;
game.addChild(vacuum);
// Create draggable food
food = new Food();
food.x = feedButton.x;
food.y = feedButton.y - 150;
game.addChild(food);
// Create play ball
ball = new Ball();
ball.x = playButton.x;
ball.y = playButton.y - 150;
game.addChild(ball);
// Create arcade game
arcadeGame = new ArcadeGame();
arcadeGame.x = 2048 / 2;
arcadeGame.y = 2732 / 2 - 200;
game.addChild(arcadeGame);
// Create play options menu
playOptionsMenu = new PlayOptionsMenu();
playOptionsMenu.x = 2048 / 2;
playOptionsMenu.y = 2732 / 2 - 200;
game.addChild(playOptionsMenu);
// Create and add title
titleText = new Text2("Digital Pet Friend", {
size: 100,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 100;
LK.gui.addChild(titleText);
// Create game instructions
var instructionsText = new Text2("Feed, play with, and clean your pet to keep it happy. Watch how it evolves over time!", {
size: 40,
fill: 0xDDDDDD
});
instructionsText.anchor.set(0.5, 0);
instructionsText.x = 2048 / 2;
instructionsText.y = 220;
instructionsText.width = 1800;
LK.gui.addChild(instructionsText);
// Start game music
LK.playMusic('petMusic', {
fade: {
start: 0,
end: 0.8,
duration: 1000
}
});
gameStarted = true;
}
function createStatusBars() {
// Create container for all status bars
var statusContainer = new Container();
statusContainer.x = 2048 / 2;
statusContainer.y = 400;
game.addChild(statusContainer);
// Create each status bar
var statusTypes = [{
name: 'hunger',
label: 'Hunger',
color: 0x22cc88
}, {
name: 'happiness',
label: 'Happiness',
color: 0xff8822
}, {
name: 'cleanliness',
label: 'Cleanliness',
color: 0x2288ff
}];
var yOffset = 0;
for (var i = 0; i < statusTypes.length; i++) {
var type = statusTypes[i];
// Create label
var label = new Text2(type.label, {
size: 40,
fill: 0xFFFFFF
});
label.anchor.set(1, 0.5);
label.x = -20;
label.y = yOffset;
statusContainer.addChild(label);
// Create background bar
var barBg = LK.getAsset('feedButton', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: yOffset,
scaleX: 4,
scaleY: 0.5,
tint: 0x444444
});
statusContainer.addChild(barBg);
// Create value bar
var bar = LK.getAsset('feedButton', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: yOffset,
scaleX: 4,
scaleY: 0.5,
tint: type.color
});
statusContainer.addChild(bar);
// Store reference to bar
statusBars[type.name] = bar;
yOffset += 60;
}
// Create evolution meter
corruptionLabel = new Text2("Evolution", {
size: 40,
fill: 0xFFFFFF // Change from blue to white for better visibility
});
var corruptionTextGlitching = false;
var textGlitchTimer = null;
corruptionLabel.anchor.set(1, 0.5);
corruptionLabel.x = -20;
corruptionLabel.y = yOffset;
statusContainer.addChild(corruptionLabel);
var corruptionBg = LK.getAsset('feedButton', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: yOffset,
scaleX: 4,
scaleY: 0.5,
tint: 0x444444
});
statusContainer.addChild(corruptionBg);
corruptionMeter = LK.getAsset('feedButton', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: yOffset,
scaleX: 0,
scaleY: 0.5,
tint: 0x44AAFF
});
statusContainer.addChild(corruptionMeter);
}
function updateStatusBars() {
if (!gameStarted) {
return;
}
// Update status bars based on pet stats
statusBars.hunger.scaleX = pet.hunger / 25;
statusBars.happiness.scaleX = pet.happiness / 25;
statusBars.cleanliness.scaleX = pet.cleanliness / 25;
// Update corruption meter
corruptionMeter.scaleX = pet.corruption / 25;
// Calculate average status to determine visual darkness
var avgStatus = (pet.hunger + pet.happiness + pet.cleanliness) / 3;
// Adjust game visuals based on average status - darker and less vibrant as stats decrease
var darknessLevel = 1 - avgStatus / 100;
var saturationReduction = darknessLevel * 0.5;
var brightnessReduction = darknessLevel * 0.5;
// Adjust background color (from light blue to darker desaturated blue)
var r = Math.round(102 * (1 - brightnessReduction));
var g = Math.round(170 * (1 - brightnessReduction - saturationReduction));
var b = Math.round(221 * (1 - brightnessReduction));
game.setBackgroundColor(r << 16 | g << 8 | b);
// Adjust visual elements opacity based on status
pet.alpha = 0.5 + avgStatus / 200; // Fade pet slightly as status decreases
}
function triggerGlitch() {
// Play sparkle sound
LK.getSound('glitch').play();
// Check for nightmare mode
var nightmareMode = pet && pet.hunger < 10 && pet.happiness < 10 && pet.cleanliness < 10;
// Visual glitch effects - intensify based on corruption level or nightmare mode
var intensity = nightmareMode ? 10 : pet.corruption > 50 ? 5 : 3;
for (var i = 0; i < intensity; i++) {
var glitch = glitchEffects[Math.floor(Math.random() * glitchEffects.length)];
glitch.startGlitch();
}
// If corruption is above 50%, add stronger visual distortions
if (pet.corruption > 50 && Math.random() < 0.5) {
// Briefly distort the entire game view
var originalScale = game.scale.x;
tween(game.scale, {
x: originalScale * (1 + (Math.random() - 0.5) * 0.1),
y: originalScale * (1 + (Math.random() - 0.5) * 0.1)
}, {
duration: 100,
onFinish: function onFinish() {
tween(game.scale, {
x: originalScale,
y: originalScale
}, {
duration: 100
});
}
});
}
// Temporarily distort pet
if (Math.random() < 0.3) {
var originalRotation = pet.rotation;
tween(pet, {
rotation: originalRotation + (Math.random() - 0.5) * 0.3
}, {
duration: 150,
onFinish: function onFinish() {
tween(pet, {
rotation: originalRotation
}, {
duration: 150
});
}
});
}
// Screen shake
if (Math.random() < 0.2) {
var originalX = game.x;
var originalY = game.y;
tween(game, {
x: originalX + (Math.random() - 0.5) * 20
}, {
duration: 100,
onFinish: function onFinish() {
tween(game, {
x: originalX
}, {
duration: 100
});
}
});
}
}
function spawnCorruptionParticle() {
// Find an inactive particle
for (var i = 0; i < corruptionParticles.length; i++) {
var particle = corruptionParticles[i];
if (!particle.active) {
// Calculate position relative to pet
var offsetX = (Math.random() - 0.5) * 300;
var offsetY = (Math.random() - 0.5) * 300;
particle.initialize(pet.x + offsetX, pet.y + offsetY, 60 + Math.floor(Math.random() * 60));
break;
}
}
}
// Add event handlers for dragging
game.down = function (x, y, obj) {
// Get event position directly
// Check if we clicked on the vacuum when it's active
if (vacuum && vacuum.active && vacuum.visible) {
// Use direct hit testing instead of bounds checking
if (x >= vacuum.x - vacuum.width / 2 && x <= vacuum.x + vacuum.width / 2 && y >= vacuum.y - vacuum.height / 2 && y <= vacuum.y + vacuum.height / 2) {
draggedItem = vacuum;
}
}
// Check if we clicked on the food when it's active
if (food && food.active && food.visible) {
// Use direct hit testing
if (x >= food.x - food.width / 2 && x <= food.x + food.width / 2 && y >= food.y - food.height / 2 && y <= food.y + food.height / 2) {
draggedItem = food;
}
}
// Check if we clicked on the ball when it's active
if (ball && ball.active && ball.visible) {
// Use direct hit testing
if (x >= ball.x - ball.width / 2 && x <= ball.x + ball.width / 2 && y >= ball.y - ball.height / 2 && y <= ball.y + ball.height / 2) {
draggedItem = ball;
}
}
};
game.up = function (x, y, obj) {
if (draggedItem === vacuum) {
// Use simplified distance-based collision detection for better results
var dx = vacuum.x - pet.x;
var dy = vacuum.y - pet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If vacuum is within 200px of pet center, consider it a hit
if (distance < 200) {
// Vacuum is over the pet - clean it!
vacuum.cleanPet();
pet.clean(); // This now has modified behavior for vacuum
} else {
// Not over pet, return vacuum
vacuum.deactivate();
}
draggedItem = null;
} else if (draggedItem === food) {
// Check if food is near pet's mouth
var dx = food.x - pet.x;
var dy = food.y - (pet.y + pet.mouth.y);
var distance = Math.sqrt(dx * dx + dy * dy);
// If food is within 100px of pet's mouth, consider it a hit
if (distance < 100) {
// Feed the pet
pet.feed();
food.deactivate();
} else {
// Return food to original position
food.returnToPosition();
}
draggedItem = null;
} else if (draggedItem === ball) {
// Check if ball is near pet
var dx = ball.x - pet.x;
var dy = ball.y - pet.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
// Play with pet using the ball
pet.play();
ball.deactivate();
} else {
// Return ball to original position
ball.returnToPosition();
}
draggedItem = null;
}
};
game.move = function (x, y, obj) {
if (draggedItem) {
// Use coordinates directly - no need to convert with toLocal
draggedItem.x = x;
draggedItem.y = y;
}
};
// Game Update Logic
game.update = function () {
if (!gameStarted) {
initGame();
return;
}
gameTime++;
// Update pet stats
if (gameTime % 30 === 0) {
pet.updateStats();
updateStatusBars();
// Check for nightmare mode
var nightmareMode = pet.hunger < 10 && pet.happiness < 10 && pet.cleanliness < 10;
// If in nightmare mode, apply special effects continuously
if (nightmareMode) {
// Occasional screen flashes
if (Math.random() < 0.1) {
LK.effects.flashScreen(0xff0000, 200);
}
// Random background color flashes
if (Math.random() < 0.1) {
var originalBg = game.backgroundColor;
game.setBackgroundColor(0x330000);
LK.setTimeout(function () {
game.setBackgroundColor(originalBg);
}, 100);
}
// Random glitches
if (Math.random() < 0.2) {
triggerGlitch();
}
// Make title text shake constantly
if (titleText) {
titleText.x = 2048 / 2 + (Math.random() - 0.5) * 20;
titleText.y = 100 + (Math.random() - 0.5) * 20;
}
// Make DIE text flash
if (corruptionLabel && Math.random() < 0.5) {
corruptionLabel.setText("DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE DIE");
corruptionLabel.fill = Math.random() < 0.5 ? 0xff0000 : 0xffff00;
// Add pulsing effect for more intensity
corruptionLabel.scaleX = corruptionLabel.scaleY = 1 + Math.random() * 0.3;
}
}
// Handle corruption text glitching when corruption is around halfway and not in nightmare mode
else if (pet.corruption >= 40 && pet.corruption <= 60) {
if (!corruptionTextGlitching) {
corruptionTextGlitching = true;
textGlitchTimer = LK.setInterval(function () {
// Toggle between "Evolution" and "Corruption"
if (corruptionLabel.text === "Evolution") {
corruptionLabel.setText("Corruption");
// Add slight visual glitch effect
tween(corruptionLabel, {
rotation: (Math.random() - 0.5) * 0.1
}, {
duration: 100
});
} else {
corruptionLabel.setText("Evolution");
// Reset rotation
tween(corruptionLabel, {
rotation: 0
}, {
duration: 100
});
}
}, 400);
}
} else if (corruptionTextGlitching && !nightmareMode) {
// Stop glitching when out of the 40-60 range
corruptionTextGlitching = false;
LK.clearInterval(textGlitchTimer);
corruptionLabel.setText(pet.corruption < 50 ? "Evolution" : "Corruption");
corruptionLabel.rotation = 0;
}
}
// Spawn corruption particles based on corruption level
if (pet.corruption > 30 && gameTime % Math.max(5, 30 - pet.corruption / 5) === 0) {
spawnCorruptionParticle();
}
// Update all corruption particles
for (var i = 0; i < corruptionParticles.length; i++) {
corruptionParticles[i].update();
}
// Update arcade game if active
if (arcadeGame && arcadeGame.active) {
arcadeGame.update();
}
// Random glitches when heavily corrupted
if (pet.corruption > 70 && Math.random() < 0.005) {
triggerGlitch();
}
// Check for game over condition
if (pet.corruption >= 100 && pet.hunger <= 0 && pet.happiness <= 0 && pet.cleanliness <= 0) {
// Nightmare complete
for (var i = 0; i < 20; i++) {
LK.setTimeout(function () {
triggerGlitch();
}, i * 100);
}
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
};
dirt speck. In-Game asset. 2d. High contrast. No shadows
chicken leg. In-Game asset. 2d. High contrast. No shadows
sitting cat with no eyes and mouth. In-Game asset. 2d. High contrast. No shadows
closed black cat mouth by itself. In-Game asset. 2d. High contrast. No shadows
glitch effect by itself. In-Game asset. 2d. High contrast. No shadows
ball. In-Game asset. 2d. High contrast. No shadows
vaccum. In-Game asset. 2d. High contrast. No shadows
Iphone. In-Game asset. 2d. High contrast. No shadows