User prompt
Make the display more like cookie clicker, actually make the entire game just like cookie clicker, but with my ideas like farting on the dog also make it fit at least an iPhone 12 mini. I don’t need anything off my screen. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1 Also make it petting your dog instead of farting in any mention of farting replace with pet also the synonyms it says remove those ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Do it
User prompt
I’m pressing on it for my finger on my mobile device and nothing’s happening
User prompt
The portal does nothing when I click it make something happen like the secret ending you just mentioned
User prompt
Fix the coding error
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'showGrandPortal();' Line Number: 669
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'showGrandPortal();' Line Number: 669
User prompt
Make said true ending start when the portal is clicked
User prompt
Make the portal next to the dog
User prompt
Add the grand thing to this update something that will make everything else I’ve added look horrible. Don’t even suggest it just do the one thing that will save this game
User prompt
Do some of those
User prompt
Make it to the dog and walk in Infinitely and will stop when they go home button is clicked and bones Will spawn randomly let🦴 stand for the bones ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Make the walk event not just be a tiny speck make something good and also there’s no bones make it so the entire game disappears when the walk event happens just focusing on the walk and then everything goes back to normal after You click the go home button for all your progress is saved, and nothing has changed except for the number of bones that you have
User prompt
Make a button on the Right of the fart button That triggers, the the walk event
User prompt
Make it so the dog walk event is the most common
User prompt
Make the odds the same, but make it so the react one is the rarest
User prompt
Make one of the events happen when I click the dog it’ll be an rng of events
User prompt
Make it so the food menu is minimized at the start
User prompt
Make more achievements
User prompt
Make more achievements ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make the dog walk even more common
User prompt
Make this event more common
User prompt
Add more gameplay aspects don’t even recommend anything just do it
User prompt
Add more gameplay aspects don’t even recommend it just do it
User prompt
Move the food store away
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // --- Dog Walk & Collectible Bones Gameplay --- // Dog will occasionally go for a walk and bones will appear to collect for bonus farts // Bone class var Bone = Container.expand(function () { var self = Container.call(this); var boneShape = self.attachAsset('person_phone', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.3, tint: 0xffffff }); self.collected = false; self.update = function () { // Bones can have a little bounce self.y += Math.sin(LK.ticks / 10 + self.x) * 0.5; }; return self; }); // Dog walk state // Dog face class var DogFace = Container.expand(function () { var self = Container.call(this); // Normal face var normalFace = self.attachAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5 }); // React face var reactFace = self.attachAsset('dog_react', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Show normal face self.showNormal = function () { normalFace.alpha = 1; reactFace.alpha = 0; }; // Show react face self.showReact = function () { normalFace.alpha = 0; reactFace.alpha = 1; }; // Flash react face for a short time, then return to normal self.react = function () { self.showReact(); // Return to normal face after 500ms LK.setTimeout(function () { self.showNormal(); // Always teleport dog to center after animation, even if spammed self.x = 2048 / 2; }, 500); }; self.showNormal(); return self; }); // Floating text class for score popups var FloatingText = Container.expand(function () { var self = Container.call(this); self.textObj = new Text2('', { size: 80, fill: 0xffffff, stroke: 0x222222, strokeThickness: 4, align: 'center' }); self.textObj.anchor.set(0.5, 0.5); self.addChild(self.textObj); self.life = 2.0; self.maxLife = 2.0; self.vy = -2; self.setText = function (text) { self.textObj.setText(text); }; self.update = function () { self.y += self.vy; self.life -= 0.03; self.alpha = self.life / self.maxLife; if (self.life <= 0 && self.parent) { self.parent.removeChild(self); } }; return self; }); // Food Store class var FoodStore = Container.expand(function () { var self = Container.call(this); // Food items data var foods = [{ name: "Dog Biscuit", cost: 50, hunger: 10, assetId: 'person_leg' }, { name: "Meat Bowl", cost: 200, hunger: 25, assetId: 'person_phone' }, { name: "Fancy Meal", cost: 1000, hunger: 50, assetId: 'centerCircle' }]; // Chef data var chef = { name: "Auto Chef", cost: 5000, feedInterval: 3000 }; // Feeds every 3 seconds // Store background var storeBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.8, scaleY: 2.2, x: 0, y: 0 }); self.addChild(storeBg); // Store title var storeTitle = new Text2('Food Store', { size: 70, fill: 0x7A5C00, align: 'center' }); storeTitle.anchor.set(0.5, 0.5); storeTitle.x = 0; storeTitle.y = -250; self.addChild(storeTitle); // Create food buttons foods.forEach(function (food, index) { var foodBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: 0, y: -150 + index * 100 }); foodBtn.interactive = true; self.addChild(foodBtn); // Food icon var foodIcon = LK.getAsset(food.assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: -120, y: 0, tint: 0x8B4513 // Brown color for food }); foodBtn.addChild(foodIcon); var foodTxt = new Text2(food.name + '\nCost: ' + food.cost + ' Pets\nHunger: +' + food.hunger, { size: 40, fill: 0x7A5C00, align: 'center' }); foodTxt.anchor.set(0.5, 0.5); foodTxt.x = 40; foodTxt.y = 0; foodBtn.addChild(foodTxt); foodBtn.down = function () { if (fartCount >= food.cost) { fartCount -= food.cost; dogHunger = Math.min(100, dogHunger + food.hunger); // Track dog feeding window._dogFeedCount = (window._dogFeedCount || 0) + 1; updateUI(); // Show feeding animation createFloatingText(dogFace.x, dogFace.y - 100, "+" + food.hunger + " Hunger!", 0x00ff00); // Dog says happy food words if (dogFace.speechBubble) { var happyWords = ["Yummy!", "Delicious!", "Tasty!", "Nom nom!", "So good!", "More please!", "Thank you!", "Amazing!", "Perfect!"]; var word = happyWords[Math.floor(Math.random() * happyWords.length)]; dogFace.speechBubble.setText(word); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); } // Flash food store briefly LK.effects.flashObject(foodBtn, 0x00ff00, 200); } }; }); // Chef button var chefBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 0, y: 200 }); chefBtn.interactive = true; self.addChild(chefBtn); // Chef icon var chefIcon = LK.getAsset('Chef', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, x: -80, y: 0, tint: 0xFFFFFF }); chefBtn.addChild(chefIcon); var chefTxt = new Text2(chef.name + '\nCost: ' + chef.cost + ' Farts\nAuto-feeds dog', { size: 45, fill: 0x7A5C00, align: 'center' }); chefTxt.anchor.set(0.5, 0.5); chefTxt.x = 50; chefTxt.y = 0; chefBtn.addChild(chefTxt); chefBtn.down = function () { if (fartCount >= chef.cost && !chefBought) { fartCount -= chef.cost; chefBought = true; storage.chefBought = true; updateUI(); // Start chef auto-feeding chefTimer = LK.setInterval(function () { if (dogHunger < 100) { dogHunger = Math.min(100, dogHunger + 15); createFloatingText(dogFace.x + 100, dogFace.y - 100, "Chef feeds +15!", 0x00ff00); } }, chef.feedInterval); createFloatingText(chefBtn.x, chefBtn.y - 100, "Chef Hired!", 0xffd700); LK.effects.flashObject(chefBtn, 0xffd700, 300); // Update button text to show it's bought chefTxt.setText(chef.name + '\nBOUGHT!\nAuto-feeding...'); chefBtn.alpha = 0.7; chefBtn.interactive = false; } }; // Update chef button based on purchase status self.updateChefButton = function () { if (chefBought) { chefTxt.setText(chef.name + '\nBOUGHT!\nAuto-feeding...'); chefBtn.alpha = 0.7; chefBtn.interactive = false; } else { chefBtn.alpha = fartCount >= chef.cost ? 1 : 0.5; chefBtn.interactive = fartCount >= chef.cost; } }; return self; }); // Hat Store class var HatStore = Container.expand(function () { var self = Container.call(this); // Initialize hat data var hats = [{ name: "Top Hat", cost: 100, multiplier: 1.5, assetId: 'Tophat' }]; // Currently equipped hat self.equippedHat = null; // Create store UI var storeBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, x: 2048 / 2, y: 2732 / 2 }); self.addChild(storeBg); var storeTitle = new Text2('Hat Store', { size: 80, fill: 0x7A5C00, align: 'center' }); storeTitle.anchor.set(0.5, 0.5); storeTitle.x = 0; storeTitle.y = -200; self.addChild(storeTitle); // Create hat buttons hats.forEach(function (hat, index) { var hatBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 0, y: -100 + index * 150 }); hatBtn.interactive = true; self.addChild(hatBtn); var hatTxt = new Text2(hat.name + '\nCost: ' + hat.cost + ' Pets', { size: 50, fill: 0x7A5C00, align: 'center' }); hatTxt.anchor.set(0.5, 0.5); hatTxt.x = 0; hatTxt.y = 0; hatBtn.addChild(hatTxt); hatBtn.down = function () { if (fartCount >= hat.cost) { fartCount -= hat.cost; // Track first hat purchase if (!window._firstHatBought) { window._firstHatBought = true; } equipHat(hat); updateUI(); } }; }); // Equip hat on the dog function equipHat(hat) { if (self.equippedHat) { dogFace.removeChild(self.equippedHat); } self.equippedHat = LK.getAsset(hat.assetId, { anchorX: 0.5, anchorY: 1, x: 0, y: -400 }); dogFace.addChild(self.equippedHat); fartPerClick *= hat.multiplier; } return self; }); // Hunger Bar class var HungerBar = Container.expand(function () { var self = Container.call(this); // Background bar var bgBar = LK.getAsset('fart_btn', { anchorX: 0, anchorY: 0.5, scaleX: 1.5, scaleY: 0.3, x: 0, y: 0, tint: 0x444444 }); self.addChild(bgBar); // Hunger fill bar var fillBar = LK.getAsset('fart_btn', { anchorX: 0, anchorY: 0.5, scaleX: 1.5, scaleY: 0.3, x: 0, y: 0, tint: 0x00ff00 }); self.addChild(fillBar); // Hunger text var hungerTxt = new Text2('Hunger: 100%', { size: 50, fill: 0x222222 }); hungerTxt.anchor.set(0.5, 0.5); hungerTxt.x = bgBar.width / 2; hungerTxt.y = 0; self.addChild(hungerTxt); self.updateHunger = function (hungerValue) { var percentage = hungerValue / 100; fillBar.scaleX = 1.5 * percentage; // Update color based on hunger level if (hungerValue > 60) { fillBar.tint = 0x00ff00; // Green } else if (hungerValue > 30) { fillBar.tint = 0xffff00; // Yellow } else { fillBar.tint = 0xff0000; // Red } hungerTxt.setText('Hunger: ' + Math.floor(hungerValue) + '%'); }; return self; }); // Particle class for explosive visual effects var Particle = Container.expand(function () { var self = Container.call(this); // Create particle visual using a shape var particleShape = self.attachAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); // Particle properties self.vx = 0; self.vy = 0; self.life = 1.0; self.maxLife = 1.0; self.update = function () { // Move particle self.x += self.vx; self.y += self.vy; // Apply gravity self.vy += 0.5; // Reduce life self.life -= 0.02; // Fade out based on life self.alpha = self.life / self.maxLife; // Remove when dead if (self.life <= 0 && self.parent) { self.parent.removeChild(self); } }; return self; }); // Person standing and recording class var PersonRecording = Container.expand(function () { var self = Container.call(this); // Single square for the person var personSquare = self.attachAsset('person_leg', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Pet button class var PetButton = Container.expand(function () { var self = Container.call(this); // Button shape var btn = self.attachAsset('pet_btn', { anchorX: 0.5, anchorY: 0.5 }); // "PET" text var petTxt = new Text2('PET', { size: 120, fill: 0x7A5C00 }); petTxt.anchor.set(0.5, 0.5); petTxt.x = 0; petTxt.y = 0; self.addChild(petTxt); // Pet cloud effect (hidden by default) - Keeping for fun var petCloud = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 1, scaleX: 1.2, scaleY: 0.7, x: 0, y: -110, alpha: 0, tint: 0xeeeecc }); petCloud.width = btn.width * 0.7; petCloud.height = btn.height * 0.7; // Show pet cloud with animation - Keeping for fun self.showPetCloud = function () { petCloud.alpha = 0.85; petCloud.scaleX = 1.2; petCloud.scaleY = 0.7; petCloud.y = -110; tween(petCloud, { alpha: 0, y: petCloud.y - 80, scaleX: 1.5, scaleY: 1.1 }, { duration: 420, easing: tween.cubicOut }); }; // Simple press animation self.animatePress = function () { tween(self, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); self.showPetCloud(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xE3F6FF }); /**** * Game Code ****/ // Initialize total bones collected for achievement tracking window._bonesCollected = typeof storage.bones === "number" ? storage.bones : 0; var hatStore = new HatStore(); // Move hat store to top right, below the top right UI, out of the way of dog and fart button hatStore.x = 2048 - 400; hatStore.y = 600; game.addChild(hatStore); if (fartCount > 0 && fartCount % 5000 === 0) { var milestonePopup = new Container(); var milestoneBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 1.3, x: 2048 / 2, y: 2732 / 2 }); milestonePopup.addChild(milestoneBg); var milestoneTxt = new Text2('Milestone!\n' + fartCount + ' Farts!\nDog is amazed!', { size: 80, fill: 0x7A5C00, align: 'center' }); milestoneTxt.anchor.set(0.5, 0.5); milestoneTxt.x = 2048 / 2; milestoneTxt.y = 2732 / 2 - 40; milestonePopup.addChild(milestoneTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(milestonePopup); }; milestonePopup.addChild(okBtn); game.addChild(milestonePopup); LK.effects.flashObject(milestoneBg, 0xfff7b2, 120); } // --- Achievements: First 100 Farts --- // (Removed: click counter button and handler, as clicks are now counted via the FART button); // --- Leaderboard Button removed ---; // --- Daily Reward System --- // Use storage plugin to track last claim date var lastDailyReward = storage.lastDailyReward || null; var now = Date.now(); var oneDay = 24 * 60 * 60 * 1000; var showDailyReward = false; if (!lastDailyReward || now - lastDailyReward > oneDay) { showDailyReward = true; storage.lastDailyReward = now; } if (showDailyReward) { // Show a popup in the center of the screen var rewardPopup = new Container(); var popupBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, x: 2048 / 2, y: 2732 - 350 //{15} // Move to bottom center, above screen edge }); rewardPopup.addChild(popupBg); var rewardTxt = new Text2('Daily Reward!\n+100 Farts', { size: 90, fill: 0x7A5C00, align: 'center' }); rewardTxt.anchor.set(0.5, 0.5); rewardTxt.x = 2048 / 2; rewardTxt.y = 2732 - 390; rewardPopup.addChild(rewardTxt); var claimBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 - 250 //{1g} // Move claim button below popup, but still above bottom }); var claimTxt = new Text2('Claim!', { size: 70, fill: 0x7A5C00 }); claimTxt.anchor.set(0.5, 0.5); claimTxt.x = 0; claimTxt.y = 0; claimBtn.addChild(claimTxt); claimBtn.interactive = true; claimBtn.down = function () { fartCount += 100; updateUI(); game.removeChild(rewardPopup); LK.effects.flashScreen(0x83de44, 400); }; rewardPopup.addChild(claimBtn); game.addChild(rewardPopup); } // Cartoon dog face (shocked/disgusted) // Big fart button // Fart sound var dogFace = new DogFace(); dogFace.x = 2048 / 2; dogFace.y = 1100; dogFace.lastX = dogFace.x; // Track lastX for edge detection game.addChild(dogFace); // --- Grand Portal next to the dog --- var portalNextToDog = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2, x: dogFace.x + 420, y: dogFace.y + 40, tint: 0x7e3ff2, alpha: 0.82 }); portalNextToDog.interactive = true; portalNextToDog.down = function (x, y, obj) { // Defensive: get event coordinates for mobile/desktop var event = obj && obj.event ? obj.event : null; var local = portalNextToDog.toLocal({ x: x, y: y }); // Always show the grand portal when tapped, unless already showing if (!window._grandPortalShown) { window._grandPortalShown = true; // Always use the global showGrandPortal if available if (typeof window.showGrandPortal === "function") { window.showGrandPortal(); } else if (typeof showGrandPortal === "function") { showGrandPortal(); } } }; game.addChild(portalNextToDog); // Portal swirl (rotating, subtle) var portalSwirlNextToDog = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.7, scaleY: 1.7, x: portalNextToDog.x, y: portalNextToDog.y, tint: 0xffffff, alpha: 0.18 }); game.addChild(portalSwirlNextToDog); // Portal label var portalLabelNextToDog = new Text2("PORTAL", { size: 70, fill: 0xffe066, align: 'center' }); portalLabelNextToDog.anchor.set(0.5, 0.5); portalLabelNextToDog.x = portalNextToDog.x; portalLabelNextToDog.y = portalNextToDog.y - 120; game.addChild(portalLabelNextToDog); // Animate portal swirl if (!game._portalNextToDogUpdateAttached) { var _oldPortalNextToDogUpdate = game.update; game.update = function () { _oldPortalNextToDogUpdate && _oldPortalNextToDogUpdate(); if (portalSwirlNextToDog) { portalSwirlNextToDog.rotation += 0.03; } // Keep portal next to dog if dog moves (e.g. after teleport) if (portalNextToDog && dogFace) { portalNextToDog.x = dogFace.x + 420; portalNextToDog.y = dogFace.y + 40; portalSwirlNextToDog.x = portalNextToDog.x; portalSwirlNextToDog.y = portalNextToDog.y; portalLabelNextToDog.x = portalNextToDog.x; portalLabelNextToDog.y = portalNextToDog.y - 120; } }; game._portalNextToDogUpdateAttached = true; } // Add tap-to-dog random event handler dogFace.interactive = true; dogFace.down = function (x, y, obj) { // Only allow if not dead or napping if (isDead || dogNapping) return; // Pick a random event: 0=walk (most common), 1=nap, 2=poop, 3=react (rarest) var eventRng = Math.random(); // Make walk the most common (50%), nap and poop less common (20% each), react rarest (10%) if (eventRng < 0.5 && !dogWalking) { // Start dog walk if not already walking startDogWalk(); } else if (eventRng < 0.7 && !dogNapping) { // Trigger nap event if (!dogNapping) { dogNapping = true; window._dogNapCount = (window._dogNapCount || 0) + 1; if (!dogFace.napOverlay) { dogFace.napOverlay = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 1.2, x: 0, y: 0, alpha: 0.5, tint: 0xccccff }); dogFace.addChild(dogFace.napOverlay); } dogFace.napOverlay.alpha = 0.7; if (!dogFace.napZzz) { dogFace.napZzz = new Text2("Zzz...", { size: 120, fill: 0x4444ff }); dogFace.napZzz.anchor.set(0.5, 0.5); dogFace.napZzz.x = 0; dogFace.napZzz.y = -300; dogFace.addChild(dogFace.napZzz); } dogFace.napZzz.alpha = 1; createFloatingText(dogFace.x, dogFace.y - 200, "Dog is napping!", 0x4444ff); napTimeout = LK.setTimeout(function () { dogNapping = false; if (dogFace.napOverlay) dogFace.napOverlay.alpha = 0; if (dogFace.napZzz) dogFace.napZzz.alpha = 0; createFloatingText(dogFace.x, dogFace.y - 200, "Dog woke up!", 0x83de44); }, 3000 + Math.random() * 3000); } } else if (eventRng < 0.9 && !game._poopActive) { // Trigger poop event if not already active game._poopActive = true; var poop = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.3, tint: 0x964B00 }); poop.x = dogFace.x + 80 - Math.random() * 160; poop.y = dogFace.y + 220 + Math.random() * 40; poop.interactive = true; game.addChild(poop); createFloatingText(poop.x, poop.y - 60, "Tap to clean!", 0x964B00); poop.down = function () { if (!game._poopActive) return; createFloatingText(poop.x, poop.y - 60, "+100 Farts (Clean!)", 0x83de44); fartCount += 100; window._poopsCleaned = (window._poopsCleaned || 0) + 1; updateUI(); LK.effects.flashObject(dogFace, 0x83de44, 200); if (poop.parent) poop.parent.removeChild(poop); game._poopActive = false; }; LK.setTimeout(function () { if (game._poopActive) { if (poop.parent) poop.parent.removeChild(poop); game._poopActive = false; } }, 8000); } else { // Default: dog reacts (rarest event) dogFace.react(); } }; // Add person standing and recording at the left side var person = new PersonRecording(); person.x = 400; person.y = 1200; game.addChild(person); // Dog walk state var dogWalking = false; var walkTargetX = 2048 / 2; var walkTargetY = 1100; var walkStartX = 2048 / 2; var walkStartY = 1100; var walkProgress = 0; var walkDuration = 180; // 3 seconds at 60fps var walkBone = null; var walkBoneCollected = false; var walkCooldown = 0; // Helper to start a dog walk function startDogWalk() { if (dogWalking || isDead) return; dogWalking = true; walkStartX = dogFace.x; walkStartY = dogFace.y; walkProgress = 0; walkBoneCollected = false; // --- IMMERSIVE WALK SCENE --- // Hide all main game elements (store references to restore) if (!window._walkSceneRestore) window._walkSceneRestore = {}; var toHide = [dogFace, fartBtn, walkBtn, hatStore, foodStore, foodStoreMinBtn, hungerBar, shareBtn, autismModeBtn, instrTxt, fartCountTxt, fartPerClickTxt, comboTxt, shopBtn, prestigeBtn, challengeTxt, prestigeTxt, achievementsBtn, leaderboardBtn, updateLogBtn]; window._walkSceneRestore.hidden = []; for (var i = 0; i < toHide.length; ++i) { if (toHide[i] && toHide[i].parent) { window._walkSceneRestore.hidden.push(toHide[i]); toHide[i].parent.removeChild(toHide[i]); } } // Hide all upgrade/autoClicker buttons window._walkSceneRestore.upgradeButtons = []; for (var i = 0; i < (upgradeButtons || []).length; ++i) { if (upgradeButtons[i] && upgradeButtons[i].parent) { window._walkSceneRestore.upgradeButtons.push(upgradeButtons[i]); upgradeButtons[i].parent.removeChild(upgradeButtons[i]); } } window._walkSceneRestore.autoClickerButtons = []; for (var i = 0; i < (autoClickerButtons || []).length; ++i) { if (autoClickerButtons[i] && autoClickerButtons[i].parent) { window._walkSceneRestore.autoClickerButtons.push(autoClickerButtons[i]); autoClickerButtons[i].parent.removeChild(autoClickerButtons[i]); } } // Hide person recording if (person && person.parent) { window._walkSceneRestore.person = person; person.parent.removeChild(person); } // Hide crown/disco overlays if present if (crownTrophyContainer && crownTrophyContainer.parent) { window._walkSceneRestore.crown = crownTrophyContainer; crownTrophyContainer.parent.removeChild(crownTrophyContainer); } if (discoOverlay && discoOverlay.parent) { window._walkSceneRestore.disco = discoOverlay; discoOverlay.parent.removeChild(discoOverlay); } // Remove all floating texts and particles for (var i = (floatingTexts || []).length - 1; i >= 0; --i) { if (floatingTexts[i] && floatingTexts[i].parent) floatingTexts[i].parent.removeChild(floatingTexts[i]); } floatingTexts = []; for (var i = (particles || []).length - 1; i >= 0; --i) { if (particles[i] && particles[i].parent) particles[i].parent.removeChild(particles[i]); } particles = []; // Remove any poop, nap overlays, stickers, mustaches, accessories, hats, etc. for (var i = game.children.length - 1; i >= 0; --i) { var ch = game.children[i]; if (ch && ch !== game && ch !== LK.gui && ch !== LK.gui.top && ch !== LK.gui.topRight) { if (ch !== window._walkSceneContainer) game.removeChild(ch); } } // Create walk scene container var walkScene = new Container(); window._walkSceneContainer = walkScene; game.addChild(walkScene); // Set background color for walk scene game.setBackgroundColor(0xB2E6FF); // Add a big "park" background (just a colored rectangle) var parkBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 4.2, x: 2048 / 2, y: 2732 / 2, tint: 0xA3E4A6 }); walkScene.addChild(parkBg); // Add a "Dog Walk" title var walkTitle = new Text2("Dog Walk!", { size: 160, fill: 0x2D2D2D, align: 'center' }); walkTitle.anchor.set(0.5, 0); walkTitle.x = 2048 / 2; walkTitle.y = 180; walkScene.addChild(walkTitle); // Add a big dog at the left var walkDog = LK.getAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, x: 600, y: 1500 }); walkScene.addChild(walkDog); // --- Infinite Walk Logic --- // Bones array for spawned bones var walkBones = []; // Timer for bone spawn var walkBoneSpawnTimer = 0; // Distance dog has walked (for fun, not shown) var walkDistance = 0; // Add a "Tap the bones!" text var tapBoneTxt = new Text2("Tap the bones!", { size: 100, fill: 0x7A5C00, align: 'center' }); tapBoneTxt.anchor.set(0.5, 0.5); tapBoneTxt.x = 2048 / 2; tapBoneTxt.y = 1500 - 320; walkScene.addChild(tapBoneTxt); // Go Home button (hidden until shown) function showGoHomeBtn() { if (walkScene._goHomeBtn) return; var goHomeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, x: 2048 / 2, y: 2200, tint: 0x83de44 }); var goHomeTxt = new Text2("Go Home", { size: 110, fill: 0xffffff, align: 'center' }); goHomeTxt.anchor.set(0.5, 0.5); goHomeTxt.x = 0; goHomeTxt.y = 0; goHomeBtn.addChild(goHomeTxt); goHomeBtn.interactive = true; goHomeBtn.down = function () { // Increment bones (tracked in storage) var bonesThisWalk = walkBones.filter(function (b) { return b._collectedThisWalk; }).length; storage.bones = (typeof storage.bones === "number" ? storage.bones : 0) + bonesThisWalk; // Track total bones collected for achievement window._bonesCollected = (window._bonesCollected || 0) + bonesThisWalk; // Show a floating text for bones var bonesCount = storage.bones; var bonesTxt = new Text2("Bones: " + bonesCount, { size: 90, fill: 0xffd700, align: 'center' }); bonesTxt.anchor.set(0.5, 0.5); bonesTxt.x = 2048 / 2; bonesTxt.y = 2100; walkScene.addChild(bonesTxt); tween(bonesTxt, { y: bonesTxt.y - 100, alpha: 0 }, { duration: 900, easing: tween.cubicOut, onFinish: function onFinish() { if (bonesTxt.parent) bonesTxt.parent.removeChild(bonesTxt); } }); // Restore all hidden elements if (window._walkSceneRestore) { for (var i = 0; i < (window._walkSceneRestore.hidden || []).length; ++i) { if (window._walkSceneRestore.hidden[i]) game.addChild(window._walkSceneRestore.hidden[i]); } for (var i = 0; i < (window._walkSceneRestore.upgradeButtons || []).length; ++i) { if (window._walkSceneRestore.upgradeButtons[i]) game.addChild(window._walkSceneRestore.upgradeButtons[i]); } for (var i = 0; i < (window._walkSceneRestore.autoClickerButtons || []).length; ++i) { if (window._walkSceneRestore.autoClickerButtons[i]) game.addChild(window._walkSceneRestore.autoClickerButtons[i]); } if (window._walkSceneRestore.person) game.addChild(window._walkSceneRestore.person); if (window._walkSceneRestore.crown) game.addChild(window._walkSceneRestore.crown); if (window._walkSceneRestore.disco) game.addChild(window._walkSceneRestore.disco); window._walkSceneRestore = {}; } // Remove walk scene if (window._walkSceneContainer && window._walkSceneContainer.parent) { window._walkSceneContainer.parent.removeChild(window._walkSceneContainer); window._walkSceneContainer = null; } // Restore background color game.setBackgroundColor(0xE3F6FF); // End walk state dogWalking = false; walkProgress = 0; walkBoneCollected = false; walkCooldown = 600 + Math.floor(Math.random() * 600); // Update UI to reflect new bones updateUI && updateUI(); }; walkScene.addChild(goHomeBtn); walkScene._goHomeBtn = goHomeBtn; } // --- Infinite walk update logic --- walkScene.update = function () { // Move dog to the right, loop back to left when off screen walkDog.x += 6; walkDistance += 6; if (walkDog.x > 2048 + 200) { walkDog.x = -200; // Optionally, animate a little hop when looping tween(walkDog, { y: walkDog.y - 60 }, { duration: 120, yoyo: true, repeat: 1, easing: tween.cubicOut }); } // Animate dog up and down for a little walk bounce walkDog.y = 1500 + Math.sin(walkDistance / 80) * 30; // Spawn bones at random intervals if (walkBoneSpawnTimer <= 0 && walkBones.length < 5) { // Random X between 400 and 2048-400, but not too close to dog var boneX = 400 + Math.random() * (2048 - 800); // Avoid spawning too close to dog if (Math.abs(boneX - walkDog.x) < 200) boneX = walkDog.x + 300; if (boneX > 2048 - 400) boneX = 2048 - 400; if (boneX < 400) boneX = 400; var bone = LK.getAsset('person_phone', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5 + Math.random() * 0.7, scaleY: 0.7 + Math.random() * 0.3, x: boneX, y: 1500 + (Math.random() - 0.5) * 120, tint: 0xffffff }); bone.collected = false; bone._collectedThisWalk = false; bone.interactive = true; bone.down = function () { if (this.collected) return; this.collected = true; this._collectedThisWalk = true; // Animate bone collection var self = this; tween(self, { scaleX: self.scaleX * 1.7, scaleY: self.scaleY * 1.3, alpha: 0 }, { duration: 400, easing: tween.cubicOut, onFinish: function onFinish() { self.visible = false; } }); // Show "+1 Bone!" floating text var boneText = new Text2("+1 Bone!", { size: 120, fill: 0xffd700, align: 'center' }); boneText.anchor.set(0.5, 0.5); boneText.x = self.x; boneText.y = self.y - 120; walkScene.addChild(boneText); tween(boneText, { y: boneText.y - 120, alpha: 0 }, { duration: 900, easing: tween.cubicOut, onFinish: function onFinish() { if (boneText.parent) boneText.parent.removeChild(boneText); } }); // Animate dog jumping for joy tween(walkDog, { y: walkDog.y - 180 }, { duration: 220, yoyo: true, repeat: 1, easing: tween.cubicOut }); }; walkScene.addChild(bone); walkBones.push(bone); walkBoneSpawnTimer = 40 + Math.floor(Math.random() * 60); // 0.7-1.7s } else { walkBoneSpawnTimer--; } // Remove bones that are off screen or collected for (var i = walkBones.length - 1; i >= 0; --i) { var b = walkBones[i]; if (b.collected && (!b.parent || b.alpha <= 0.01)) { if (b.parent) b.parent.removeChild(b); walkBones.splice(i, 1); } // Bones move left as dog walks right, for parallax effect else if (!b.collected) { b.x -= 2; // If bone goes off left, remove if (b.x < -200) { if (b.parent) b.parent.removeChild(b); walkBones.splice(i, 1); } } } // Show Go Home button always if (!walkScene._goHomeBtn) showGoHomeBtn(); }; // Attach walkScene update to main game update if (!walkScene._updateAttached) { var _oldWalkGameUpdate = game.update; game.update = function () { _oldWalkGameUpdate && _oldWalkGameUpdate(); if (window._walkSceneContainer && window._walkSceneContainer.update) { window._walkSceneContainer.update(); } }; walkScene._updateAttached = true; } } // Helper to end a dog walk function endDogWalk() { dogWalking = false; walkProgress = 0; if (walkBone && walkBone.parent) walkBone.parent.removeChild(walkBone); walkBone = null; walkCooldown = 600 + Math.floor(Math.random() * 600); // 10-20s cooldown } // Add to game.update var _oldGameUpdate = game.update; game.update = function () { _oldGameUpdate && _oldGameUpdate(); // Dog walk logic if (!dogWalking && !isDead && walkCooldown <= 0 && Math.random() < 0.02) { startDogWalk(); } if (walkCooldown > 0) walkCooldown--; if (dogWalking && !isDead) { walkProgress++; // Move dog towards target var t = Math.min(1, walkProgress / walkDuration); dogFace.x = walkStartX + (walkTargetX - walkStartX) * t; dogFace.y = walkStartY + (walkTargetY - walkStartY) * t; // Check for bone collection (dog intersects bone) if (walkBone && !walkBoneCollected && dogFace.intersects(walkBone)) { walkBoneCollected = true; walkBone.collected = true; createFloatingText(walkBone.x, walkBone.y - 60, "+250 Farts!", 0xffd700); fartCount += 250; // Track bones collected window._bonesCollected = (window._bonesCollected || 0) + 1; updateUI(); LK.effects.flashObject(dogFace, 0xffd700, 300); if (walkBone && walkBone.parent) walkBone.parent.removeChild(walkBone); walkBone = null; } // End walk when reached target if (walkProgress >= walkDuration) { // Animate dog back to center tween(dogFace, { x: 2048 / 2, y: 1100 }, { duration: 400, easing: tween.cubicOut, onFinish: function onFinish() { dogFace.x = 2048 / 2; dogFace.y = 1100; } }); endDogWalk(); } } }; // --- Dog sliding and teleport logic --- dogFace.slideSpeed = -12; // Negative: slides left game.update = function () { // Save lastX for edge detection dogFace.lastX = dogFace.x; // Only slide dog left if it is not at the center (prevents repeated sliding after rapid clicks) if (Math.abs(dogFace.x - 2048 / 2) > 1) { dogFace.x += dogFace.slideSpeed; // If dog reaches the left edge, teleport to center and react if (dogFace.lastX > 120 && dogFace.x <= 120) { // Teleport to center dogFace.x = 2048 / 2; // Fun: dog reacts dogFace.react(); // --- Fun: Every 888th fart, dog face gets a sparkle effect --- if (fartCount > 0 && fartCount % 888 === 0) { var sparkleCount = 0; var maxSparkles = 12; var _sparkle = function sparkle() { if (sparkleCount >= maxSparkles) return; var sparkleStar = new Text2("✨", { size: 80 + Math.floor(Math.random() * 40), fill: 0xffffff, align: 'center' }); sparkleStar.anchor.set(0.5, 0.5); sparkleStar.x = -200 + Math.random() * 400; sparkleStar.y = -200 + Math.random() * 400; sparkleStar.alpha = 1; dogFace.addChild(sparkleStar); tween(sparkleStar, { alpha: 0, y: sparkleStar.y - 60 }, { duration: 700, easing: tween.cubicOut, onFinish: function onFinish() { if (sparkleStar.parent) sparkleStar.parent.removeChild(sparkleStar); } }); sparkleCount++; LK.setTimeout(_sparkle, 80); }; _sparkle(); } // Optional: flash screen for drama LK.effects.flashScreen(0xff0000, 300); } } else { // Always keep dog exactly centered if not sliding dogFace.x = 2048 / 2; } //;{2j} // Update particles for (var p = particles.length - 1; p >= 0; p--) { particles[p].update(); if (particles[p].life <= 0) { particles.splice(p, 1); } } // Update floating texts for (var f = floatingTexts.length - 1; f >= 0; f--) { floatingTexts[f].update(); if (floatingTexts[f].life <= 0) { floatingTexts.splice(f, 1); } } // Apply screen shake if (shakeIntensity > 0) { game.x = (Math.random() - 0.5) * shakeIntensity; game.y = (Math.random() - 0.5) * shakeIntensity; shakeIntensity *= shakeDecay; if (shakeIntensity < 0.5) { shakeIntensity = 0; game.x = 0; game.y = 0; } } // Update power-ups for (var p = activePowerUps.length - 1; p >= 0; p--) { activePowerUps[p].timeLeft -= 16.67; // 60 FPS if (activePowerUps[p].timeLeft <= 0) { createFloatingText(2048 / 2, 1700, activePowerUps[p].name + " Expired", 0x888888); activePowerUps.splice(p, 1); } } // Rainbow mode effect if (autismMode && hasPowerUp('RAINBOW_MODE') && LK.ticks % 3 === 0) { var rainbowColors = [0xff0000, 0xff8000, 0xffff00, 0x00ff00, 0x0080ff, 0x8000ff]; var color = rainbowColors[Math.floor(LK.ticks / 3) % rainbowColors.length]; LK.effects.flashScreen(color, 50); } // --- Disco Light Effect (if active) --- if (discoEffectActive && discoOverlay) { // Slowly cycle through hues for a disco effect discoColorPhase += 0.012; // Slow, not too overdue if (discoColorPhase > 1) discoColorPhase -= 1; // Convert phase to RGB (HSV to RGB) var h = discoColorPhase; var s = 0.85; var v = 1.0; var i = Math.floor(h * 6); var f = h * 6 - i; var p = v * (1 - s); var q = v * (1 - f * s); var t = v * (1 - (1 - f) * s); var r, g, b; if (i % 6 === 0) { r = v; g = t; b = p; } else if (i === 1) { r = q; g = v; b = p; } else if (i === 2) { r = p; g = v; b = t; } else if (i === 3) { r = p; g = q; b = v; } else if (i === 4) { r = t; g = p; b = v; } else { r = v; g = p; b = q; } var discoColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255); discoOverlay.tint = discoColor; } // --- Hunger System Logic --- if (!isDead) { // Decrease hunger over time dogHunger -= hungerDecayRate / 60; // Convert to per-frame rate dogHunger = Math.max(0, dogHunger); // Update hunger bar hungerBar.updateHunger(dogHunger); // Check if dog dies from starvation if (dogHunger <= 0 && !isDead) { isDead = true; // Show death popup var deathPopup = new Container(); var deathBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, x: 2048 / 2, y: 2732 / 2, tint: 0x000000 }); deathPopup.addChild(deathBg); var deathTxt = new Text2('DOG DIED FROM STARVATION!\nYou lost all your progress!\nFeed your dog next time!', { size: 80, fill: 0xff0000, align: 'center' }); deathTxt.anchor.set(0.5, 0.5); deathTxt.x = 2048 / 2; deathTxt.y = 2732 / 2 - 40; deathPopup.addChild(deathTxt); var restartBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: 2048 / 2, y: 2732 / 2 + 120 }); var restartTxt = new Text2('Start Over', { size: 70, fill: 0x7A5C00 }); restartTxt.anchor.set(0.5, 0.5); restartTxt.x = 0; restartTxt.y = 0; restartBtn.addChild(restartTxt); restartBtn.interactive = true; restartBtn.down = function () { // Reset all progress fartCount = 0; fartPerClick = 1; dogHunger = 100; isDead = false; // Reset upgrades for (var i = 0; i < upgradesBought.length; i++) { upgradesBought[i] = 0; } // Reset auto-clickers for (var i = 0; i < autoClickersBought.length; i++) { autoClickersBought[i] = 0; if (autoClickerTimers[i]) { LK.clearInterval(autoClickerTimers[i]); autoClickerTimers[i] = null; } } // Reset chef chefBought = false; if (chefTimer) { LK.clearInterval(chefTimer); chefTimer = null; } // Clear storage storage.dogHunger = 100; storage.chefBought = false; // Remove death popup game.removeChild(deathPopup); // Update UI updateUI(); hungerBar.updateHunger(dogHunger); foodStore.updateChefButton(); // Flash screen to indicate restart LK.effects.flashScreen(0x00ff00, 500); }; deathPopup.addChild(restartBtn); game.addChild(deathPopup); // Stop all auto-clickers and chef for (var i = 0; i < autoClickerTimers.length; i++) { if (autoClickerTimers[i]) { LK.clearInterval(autoClickerTimers[i]); autoClickerTimers[i] = null; } } if (chefTimer) { LK.clearInterval(chefTimer); chefTimer = null; } // Flash screen red LK.effects.flashScreen(0xff0000, 1000); } // Warn player when hunger is low if (dogHunger <= 20 && dogHunger > 19.5 && LK.ticks % 180 === 0) { createFloatingText(dogFace.x, dogFace.y - 150, "FEED ME!", 0xff0000); if (dogFace.speechBubble) { dogFace.speechBubble.setText("I'm starving!"); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); } } } // --- Dog spins forever if all achievements except dog teleport are unlocked --- if (allAchievementsExceptDogTeleportUnlocked()) { if (typeof dogFace.spinAngle === "undefined") { dogFace.spinAngle = 0; } dogFace.spinAngle += 0.12; dogFace.rotation = dogFace.spinAngle % (2 * Math.PI); } // --- Random Poop Event & Cleanup Mini-task --- if (!isDead && Math.random() < 0.001 && !game._poopActive) { // Dog poops randomly, must be cleaned for bonus game._poopActive = true; var poop = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.3, tint: 0x964B00 }); poop.x = dogFace.x + 80 - Math.random() * 160; poop.y = dogFace.y + 220 + Math.random() * 40; poop.interactive = true; game.addChild(poop); // Floating text createFloatingText(poop.x, poop.y - 60, "Tap to clean!", 0x964B00); poop.down = function () { if (!game._poopActive) return; createFloatingText(poop.x, poop.y - 60, "+100 Farts (Clean!)", 0x83de44); fartCount += 100; // Track poops cleaned window._poopsCleaned = (window._poopsCleaned || 0) + 1; updateUI(); LK.effects.flashObject(dogFace, 0x83de44, 200); if (poop.parent) poop.parent.removeChild(poop); game._poopActive = false; }; // Auto-clean after 8 seconds if not tapped (no bonus) LK.setTimeout(function () { if (game._poopActive) { if (poop.parent) poop.parent.removeChild(poop); game._poopActive = false; } }, 8000); } // Fart storm effect if (hasPowerUp('FART_STORM') && LK.ticks % 30 === 0) { fartCount += 10; createParticleExplosion(Math.random() * 2048, Math.random() * 2732, 0x0080ff, 5); updateUI(); } }; // Place fart button below dog face var fartBtn = new FartButton(); fartBtn.x = 2048 / 2; fartBtn.y = 2000; game.addChild(fartBtn); // --- Walk Button --- // Place to the right of the fart button var walkBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.9, scaleY: 0.9, x: fartBtn.x + fartBtn.width * 0.7 + 80, // right of fartBtn, with a gap y: fartBtn.y }); var walkTxt = new Text2('Walk', { size: 90, fill: 0x7A5C00 }); walkTxt.anchor.set(0.5, 0.5); walkTxt.x = 0; walkTxt.y = 0; walkBtn.addChild(walkTxt); walkBtn.interactive = true; walkBtn.down = function () { // Only allow if not dead, not napping, and not already walking if (isDead || dogNapping || dogWalking) return; startDogWalk(); LK.effects.flashObject(walkBtn, 0xfff7b2, 120); }; game.addChild(walkBtn); // --- Social Share & Viral Challenge Button --- // Place to the right of the fart button var shareBtn = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 3.2, x: 2048 - 250, // Move to bottom right, away from dog/fart button y: 2732 - 250 }); var shareTxt = new Text2('Share', { size: 70, fill: 0x7A5C00 }); shareTxt.anchor.set(0.5, 0.5); shareTxt.x = 0; shareTxt.y = 0; shareBtn.addChild(shareTxt); shareBtn.interactive = true; shareBtn.down = function () { // Show a viral challenge popup with leaderboard and share var popup = new Container(); var bg = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 7.5, scaleY: 7.5, x: 2048 / 2, y: 2732 / 2 }); popup.addChild(bg); var viralTitle = new Text2('🌎 FartDog Viral Challenge 🌎', { size: 80, fill: 0xff8000, align: 'center' }); viralTitle.anchor.set(0.5, 0.5); viralTitle.x = 2048 / 2; viralTitle.y = 2732 / 2 - 320; popup.addChild(viralTitle); // Simulate a global leaderboard (local only, but looks viral!) var fakeScores = [{ name: "You", score: fartCount }, { name: "Chris", score: 123456 }, { name: "John", score: 98765 }, { name: "DogLover99", score: 54321 }, { name: "FartKing", score: 42000 }, { name: "CatQueen", score: 31415 }, { name: "Guest", score: 10000 + Math.floor(Math.random() * 9000) }]; fakeScores.sort(function (a, b) { return b.score - a.score; }); for (var i = 0; i < fakeScores.length; ++i) { var entry = fakeScores[i]; var entryTxt = new Text2(i + 1 + ". " + entry.name + " - " + entry.score + " farts", { size: 54, fill: entry.name === "You" ? 0x83de44 : 0x7A5C00, align: 'left' }); entryTxt.anchor.set(0.5, 0.5); entryTxt.x = 2048 / 2; entryTxt.y = 2732 / 2 - 200 + i * 60; popup.addChild(entryTxt); } var viralTxt = new Text2('I made my dog react to ' + fartCount + ' farts!\nCan you beat me?\n#FartDog', { size: 70, fill: 0x7A5C00, align: 'center' }); viralTxt.anchor.set(0.5, 0.5); viralTxt.x = 2048 / 2; viralTxt.y = 2732 / 2 + 180; popup.addChild(viralTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2 - 180, y: 2732 / 2 + 320 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(popup); }; popup.addChild(okBtn); // Add a "Challenge Friends" button var challengeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2 + 180, y: 2732 / 2 + 320 }); var challengeTxt = new Text2('Challenge Friends', { size: 54, fill: 0xff8000 }); challengeTxt.anchor.set(0.5, 0.5); challengeTxt.x = 0; challengeTxt.y = 0; challengeBtn.addChild(challengeTxt); challengeBtn.interactive = true; challengeBtn.down = function () { // Show a popup with a "copy" message var sharePopup = new Container(); var shareBg = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 5.5, scaleY: 2.5, x: 2048 / 2, y: 2732 / 2 }); sharePopup.addChild(shareBg); var shareMsg = new Text2("Copy this challenge to your friends:\n\nI made my dog react to " + fartCount + " farts! Can you beat me? Play on FartDog! #FartDog", { size: 54, fill: 0x7A5C00, align: 'center' }); shareMsg.anchor.set(0.5, 0.5); shareMsg.x = 2048 / 2; shareMsg.y = 2732 / 2 - 40; sharePopup.addChild(shareMsg); var closeShareBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var closeShareTxt = new Text2('OK', { size: 54, fill: 0x7A5C00 }); closeShareTxt.anchor.set(0.5, 0.5); closeShareTxt.x = 0; closeShareTxt.y = 0; closeShareBtn.addChild(closeShareTxt); closeShareBtn.interactive = true; closeShareBtn.down = function () { game.removeChild(sharePopup); }; sharePopup.addChild(closeShareBtn); game.addChild(sharePopup); LK.effects.flashObject(shareBg, 0xfff7b2, 120); }; popup.addChild(challengeBtn); game.addChild(popup); LK.effects.flashObject(bg, 0xfff7b2, 120); }; game.addChild(shareBtn); // --- Autism Mode Toggle Button --- var autismModeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.65, scaleY: 0.65, x: 250, y: 2732 - 350 }); var autismModeTxt = new Text2('Autism Mode\nOFF', { size: 50, fill: 0x7A5C00, align: 'center' }); autismModeTxt.anchor.set(0.5, 0.5); autismModeTxt.x = 0; autismModeTxt.y = 0; autismModeBtn.addChild(autismModeTxt); autismModeBtn.interactive = true; autismModeBtn.down = function () { autismMode = !autismMode; storage.autismMode = autismMode; autismModeTxt.setText('Autism Mode\n' + (autismMode ? 'ON' : 'OFF')); autismModeTxt.fill = autismMode ? 0xff0000 : 0x7A5C00; LK.effects.flashObject(autismModeBtn, autismMode ? 0xff0000 : 0x83de44, 200); if (autismMode) { // Flash screen rainbow to indicate chaos mode is on var rainbowColors = [0xff0000, 0xffa500, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0xee82ee]; var idx = 0; var _rainbowFlash = function rainbowFlash() { if (idx >= rainbowColors.length) return; LK.effects.flashScreen(rainbowColors[idx], 120); idx++; LK.setTimeout(_rainbowFlash, 120); }; _rainbowFlash(); // Start auto clicking every 200ms for maximum chaos (only if player has bought auto-clickers) var hasAutoClickers = false; for (var aci = 0; aci < autoClickersBought.length; ++aci) { if (autoClickersBought[aci] > 0) { hasAutoClickers = true; break; } } if (hasAutoClickers) { autismModeAutoClickTimer = LK.setInterval(function () { if (autismMode && fartBtn.down) { fartBtn.down(0, 0, {}); } }, 200); } } else { // Stop auto clicking when autism mode is turned off if (autismModeAutoClickTimer) { LK.clearInterval(autismModeAutoClickTimer); autismModeAutoClickTimer = null; } } }; game.addChild(autismModeBtn); // Update autism mode button text on load autismModeTxt.setText('Autism Mode\n' + (autismMode ? 'ON' : 'OFF')); autismModeTxt.fill = autismMode ? 0xff0000 : 0x7A5C00; // Prevent accidental tap in top left (menu area): nothing is placed there // Instructions text (top center, GUI) var instrTxt = new Text2('Tap the FART button!', { size: 90, fill: 0x2D2D2D }); instrTxt.anchor.set(0.5, 0); LK.gui.top.addChild(instrTxt); // --- Clicker Game State --- var fartCount = 0; var fartPerClick = 1; // --- Hunger System Variables --- var dogHunger = typeof storage.dogHunger === "number" ? storage.dogHunger : 100; // Start with full hunger var hungerDecayRate = 0.5; // Hunger decreases by 0.5 per second (at 60fps) var chefBought = !!storage.chefBought; var chefTimer = null; var isDead = false; // --- Food Store Minimize/Show Logic --- var foodStoreVisible = true; var foodStoreMinBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, // Move further up and right from the very bottom left, so it doesn't overlap achievements or the menu x: 600, y: 2732 - 1000 }); var foodStoreMinTxt = new Text2('Minimize', { size: 44, fill: 0x7A5C00 }); foodStoreMinTxt.anchor.set(0.5, 0.5); foodStoreMinTxt.x = 0; foodStoreMinTxt.y = 0; foodStoreMinBtn.addChild(foodStoreMinTxt); foodStoreMinBtn.interactive = true; game.addChild(foodStoreMinBtn); // Create food store, move further up and right, out of the way of achievements and menu var foodStore = new FoodStore(); foodStore.x = 600; foodStore.y = 2732 - 1000; game.addChild(foodStore); // Minimize/Show handler foodStoreMinBtn.down = function () { foodStoreVisible = !foodStoreVisible; foodStore.visible = foodStoreVisible; foodStoreMinTxt.setText(foodStoreVisible ? "Minimize" : "Show Food"); LK.effects.flashObject(foodStoreMinBtn, 0xfff7b2, 120); }; foodStore.visible = false; foodStoreMinTxt.setText("Show Food"); // If you want the food store to start minimized, uncomment below: // foodStore.visible = false; // foodStoreMinTxt.setText("Show Food"); // Create hunger bar var hungerBar = new HungerBar(); hungerBar.x = 2048 / 2 - 350; // Center it above the dog hungerBar.y = 900; game.addChild(hungerBar); // Initialize chef if already bought if (chefBought && !chefTimer) { chefTimer = LK.setInterval(function () { if (dogHunger < 100 && !isDead) { dogHunger = Math.min(100, dogHunger + 15); createFloatingText(dogFace.x + 100, dogFace.y - 100, "Chef feeds +15!", 0x00ff00); } }, 3000); } // --- Prestige System Variables --- var prestigeLevel = storage.prestigeLevel || 0; var prestigePoints = storage.prestigePoints || 0; var prestigeMultiplier = 1 + prestigeLevel * 0.5; // 50% bonus per prestige // --- Weekly Challenge Display (moved here to define before updateUI) --- var weeklyChallenge = { target: 50000, progress: 0, completed: false, timeLeft: 7 * 24 * 60 * 60 * 1000 // 7 days }; var challengeTxt = new Text2('Weekly Challenge: ' + weeklyChallenge.target + ' Farts\nProgress: ' + weeklyChallenge.progress, { size: 50, fill: 0x2D2D2D }); challengeTxt.anchor.set(0, 0); challengeTxt.x = 50; challengeTxt.y = 150; LK.gui.top.addChild(challengeTxt); // --- Prestige Info Display (moved here to define before updateUI) --- var prestigeTxt = new Text2('Prestige Level: ' + prestigeLevel + ' (x' + prestigeMultiplier.toFixed(1) + ' bonus)', { size: 50, fill: 0xff4444 }); prestigeTxt.anchor.set(1, 0); prestigeTxt.x = 0; prestigeTxt.y = 150; LK.gui.topRight.addChild(prestigeTxt); // --- Prestige Button --- var prestigeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: 2048 / 2, y: 250 }); var prestigeBtnTxt = new Text2('PRESTIGE\n(Reset for Bonus)', { size: 60, fill: 0xff4444, align: 'center' }); prestigeBtnTxt.anchor.set(0.5, 0.5); prestigeBtnTxt.x = 0; prestigeBtnTxt.y = 0; prestigeBtn.addChild(prestigeBtnTxt); prestigeBtn.interactive = true; game.addChild(prestigeBtn); prestigeBtn.down = function () { if (fartCount >= 1000000) { // Can only prestige with 1M+ farts var newPrestigePoints = Math.floor(fartCount / 100000); prestigePoints += newPrestigePoints; prestigeLevel++; // Reset progress but keep prestige bonuses fartCount = 0; fartPerClick = 1; for (var i = 0; i < upgradesBought.length; i++) { upgradesBought[i] = 0; } for (var i = 0; i < autoClickersBought.length; i++) { autoClickersBought[i] = 0; if (autoClickerTimers[i]) { LK.clearInterval(autoClickerTimers[i]); autoClickerTimers[i] = null; } } // Apply prestige multiplier prestigeMultiplier = 1 + prestigeLevel * 0.5; // Save to storage storage.prestigeLevel = prestigeLevel; storage.prestigePoints = prestigePoints; // Celebration LK.effects.flashScreen(0xffd700, 1000); createFloatingText(2048 / 2, 1400, "PRESTIGE LEVEL " + prestigeLevel + "!\n+" + newPrestigePoints + " Prestige Points!", 0xffd700); updateUI(); } }; // --- Particle System --- var particles = []; // --- Dog Nap Event Logic --- if (!dogNapping && !isDead && Math.random() < 0.003) { dogNapping = true; // Track dog naps window._dogNapCount = (window._dogNapCount || 0) + 1; // Show nap overlay on dog if (!dogFace.napOverlay) { dogFace.napOverlay = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 1.2, x: 0, y: 0, alpha: 0.5, tint: 0xccccff }); dogFace.addChild(dogFace.napOverlay); } dogFace.napOverlay.alpha = 0.7; // Zzz text if (!dogFace.napZzz) { dogFace.napZzz = new Text2("Zzz...", { size: 120, fill: 0x4444ff }); dogFace.napZzz.anchor.set(0.5, 0.5); dogFace.napZzz.x = 0; dogFace.napZzz.y = -300; dogFace.addChild(dogFace.napZzz); } dogFace.napZzz.alpha = 1; createFloatingText(dogFace.x, dogFace.y - 200, "Dog is napping!", 0x4444ff); // Nap lasts 3-6 seconds napTimeout = LK.setTimeout(function () { dogNapping = false; if (dogFace.napOverlay) dogFace.napOverlay.alpha = 0; if (dogFace.napZzz) dogFace.napZzz.alpha = 0; createFloatingText(dogFace.x, dogFace.y - 200, "Dog woke up!", 0x83de44); }, 3000 + Math.random() * 3000); } var floatingTexts = []; // Create particle explosion at position function createParticleExplosion(x, y, color, count) { count = count || 15; for (var i = 0; i < count; i++) { var particle = new Particle(); particle.x = x; particle.y = y; // Random velocity var angle = Math.random() * 2 * Math.PI; var speed = 5 + Math.random() * 10; particle.vx = Math.cos(angle) * speed; particle.vy = Math.sin(angle) * speed - 5; // Upward bias // Set color particle.children[0].tint = color || 0xffffff; // Random life particle.maxLife = 0.8 + Math.random() * 0.4; particle.life = particle.maxLife; particles.push(particle); game.addChild(particle); } } // Create floating score text function createFloatingText(x, y, text, color) { var floatText = new FloatingText(); floatText.x = x; floatText.y = y; floatText.setText(text); floatText.textObj.fill = color || 0xffffff; floatingTexts.push(floatText); game.addChild(floatText); } // --- Screen shake system var shakeIntensity = 0; var shakeDecay = 0.9; function addScreenShake(intensity) { shakeIntensity = Math.max(shakeIntensity, intensity); } // --- Power-up System --- var activePowerUps = []; // Power-up types var powerUpTypes = { DOUBLE_FARTS: { name: "Double Farts", duration: 10000, color: 0x00ff00 }, MEGA_COMBO: { name: "Mega Combo", duration: 15000, color: 0xff8000 }, RAINBOW_MODE: { name: "Rainbow Mode", duration: 8000, color: 0xff00ff }, FART_STORM: { name: "Fart Storm", duration: 12000, color: 0x0080ff } }; // Trigger random power-up function triggerRandomPowerUp() { var types = Object.keys(powerUpTypes); var randomType = types[Math.floor(Math.random() * types.length)]; var powerUp = powerUpTypes[randomType]; // Add to active power-ups activePowerUps.push({ type: randomType, name: powerUp.name, timeLeft: powerUp.duration, color: powerUp.color }); // Check for 3 power-ups achievement if (!window._threePowerUpsAchievement && activePowerUps.length >= 3) { window._threePowerUpsAchievement = true; } // Visual feedback createFloatingText(2048 / 2, 1600, "POWER-UP!\n" + powerUp.name, powerUp.color); LK.effects.flashScreen(powerUp.color, 500); createParticleExplosion(2048 / 2, 1600, powerUp.color, 30); addScreenShake(20); } // Check if power-up is active function hasPowerUp(type) { for (var i = 0; i < activePowerUps.length; i++) { if (activePowerUps[i].type === type) return true; } return false; } // --- Autism Mode State --- var autismMode = storage.autismMode || false; var autismModeAutoClickTimer = null; // --- Combo System --- var comboCount = 0; var comboMultiplier = 1; var lastClickTime = 0; var comboTimeout = null; // Reset combo after 2 seconds of no clicking function resetCombo() { if (comboCount > 1) { createFloatingText(2048 / 2, 1400, "Combo Reset!", 0xff6b6b); } comboCount = 0; comboMultiplier = 1; updateComboUI(); } function updateComboMultiplier() { if (comboCount >= 50) comboMultiplier = 5;else if (comboCount >= 25) comboMultiplier = 3;else if (comboCount >= 10) comboMultiplier = 2;else comboMultiplier = 1; } // Upgrade definitions: [amount, base cost, cost multiplier] // Add Chris upgrade as the last upgrade (can only buy once) var upgrades = [{ amount: 1, base: 10, mult: 1.15, label: "x1" }, { amount: 10, base: 20, mult: 1.18, label: "x10" }, { amount: 50, base: 120, mult: 1.22, label: "x50" }, { amount: 100, base: 600, mult: 1.28, label: "x100" }, { amount: 1000, base: 4000, mult: 1.35, label: "x1000" }, { amount: 0, // Chris doesn't increase fartPerClick, but triggers special effect base: 100000, mult: 1, // Not used, can only buy once label: "Chris (CAT!)" }, { // New John upgrade amount: 10000, // Drastically increase points per click base: 50000, mult: 1, label: "John (BOOST!)" }]; // Track how many times each upgrade was bought var upgradesBought = [0, 0, 0, 0, 0, 0]; // Add slot for Chris // --- UI Elements --- var fartCountTxt = new Text2('Farts: 0', { size: 150, fill: 0x2D2D2D, fontWeight: 'bold' }); // Anchor to top right (right edge, top) fartCountTxt.anchor.set(1, 0); // Place at top right using LK.gui.topRight, which will always fit the right border regardless of device size fartCountTxt.x = 0; fartCountTxt.y = 40; LK.gui.topRight.addChild(fartCountTxt); var fartPerClickTxt = new Text2('Farts/click: 1', { size: 60, fill: 0x444444 }); fartPerClickTxt.anchor.set(0.5, 0); fartPerClickTxt.x = 2048 / 2; fartPerClickTxt.y = 340; LK.gui.top.addChild(fartPerClickTxt); // Combo display var comboTxt = new Text2('Combo: 0x', { size: 70, fill: 0xff6b6b, stroke: 0x222222, strokeThickness: 3 }); comboTxt.anchor.set(0.5, 0); comboTxt.x = 2048 / 2; comboTxt.y = 420; LK.gui.top.addChild(comboTxt); function updateComboUI() { comboTxt.setText('Combo: ' + comboCount + 'x (Multiplier: ' + comboMultiplier + 'x)'); if (comboCount >= 50) comboTxt.fill = 0xff0080; // Pink for mega combo else if (comboCount >= 25) comboTxt.fill = 0x8000ff; // Purple for super combo else if (comboCount >= 10) comboTxt.fill = 0xff8000; // Orange for combo else comboTxt.fill = 0xff6b6b; // Red for small combo } // --- Upgrades UI --- var upgradeButtons = []; var upgradeTxts = []; var upgradeCostTxts = []; var upgradeYStart = 550; var upgradeSpacing = 120; // Shop toggle state var shopVisible = false; // Start with shop closed // Create upgrade shop toggle button var shopBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.45, scaleY: 0.45, // Make square: scaleX and scaleY are equal x: 400, y: upgradeYStart - 120 }); shopBtn.interactive = true; var shopBtnTxt = new Text2('Upgrade Shop', { size: 70, fill: 0x7A5C00 }); shopBtnTxt.anchor.set(0.5, 0.5); shopBtnTxt.x = 0; shopBtnTxt.y = 0; shopBtn.addChild(shopBtnTxt); game.addChild(shopBtn); // Create upgrade buttons (initially hidden) for (var i = 0; i < upgrades.length; ++i) { // Button var btn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 400, y: upgradeYStart + i * upgradeSpacing }); btn.interactive = true; // Label var labelText = i === upgrades.length - 2 ? "John (BOOST!)" : i === upgrades.length - 1 ? "Chris (CAT!)" : 'Upgrade ' + upgrades[i].label; var txt = new Text2(labelText, { size: 60, fill: 0x7A5C00 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = -20; btn.addChild(txt); // Cost var costTxt = new Text2('', { size: 44, fill: 0x444444 }); costTxt.anchor.set(0.5, 0.5); costTxt.x = 0; costTxt.y = 50; btn.addChild(costTxt); // Add to game game.addChild(btn); btn.visible = false; // Hide upgrade buttons initially upgradeButtons.push(btn); upgradeTxts.push(txt); upgradeCostTxts.push(costTxt); } // --- Chris Cat Upgrade State --- var chrisCatSpawned = false; var chrisCatContainer = null; // --- John Upgrade State --- var johnSpawned = false; var johnContainer = null; var isShowingAchievement = false; // Flag to prevent multiple achievement popups // --- Crown Trophy & Disco Effect State --- var crownTrophyContainer = null; var discoEffectActive = false; var discoColorPhase = 0; var discoOverlay = null; // Shop toggle logic shopBtn.down = function (x, y, obj) { shopVisible = !shopVisible; for (var i = 0; i < upgradeButtons.length; ++i) { upgradeButtons[i].visible = shopVisible; } // Feedback: flash the shop button LK.effects.flashObject(shopBtn, 0xfff7b2, 120); }; // --- Helper: Calculate upgrade cost --- function getUpgradeCost(idx) { var u = upgrades[idx]; var n = upgradesBought[idx]; // Exponential cost scaling return idx === upgrades.length - 1 ? 100000 : Math.floor(u.base * Math.pow(u.mult, n)); } // --- Helper: Update all UI --- function updateUI() { fartCountTxt.setText('Farts: ' + fartCount); fartPerClickTxt.setText('Farts/click: ' + Math.floor(fartPerClick * prestigeMultiplier)); // Update prestige button if (fartCount >= 1000000) { prestigeBtn.alpha = 1; prestigeBtn.interactive = true; var newPoints = Math.floor(fartCount / 100000); prestigeBtnTxt.setText('PRESTIGE\n(+' + newPoints + ' Points)'); } else { prestigeBtn.alpha = 0.5; prestigeBtn.interactive = false; prestigeBtnTxt.setText('PRESTIGE\n(Need 1M Farts)'); } // Update challenge display challengeTxt.setText('Weekly Challenge: ' + weeklyChallenge.target + ' Farts\nProgress: ' + Math.min(weeklyChallenge.progress, weeklyChallenge.target) + '/' + weeklyChallenge.target); // Update prestige info prestigeTxt.setText('Prestige Level: ' + prestigeLevel + ' (x' + prestigeMultiplier.toFixed(1) + ' bonus)\nLogin Streak: ' + loginStreak + ' days'); // Save hunger, chefBought, and bones collected to storage if (!isDead) { storage.dogHunger = dogHunger; storage.chefBought = chefBought; storage.bones = typeof storage.bones === "number" ? storage.bones : window._bonesCollected || 0; } else { // If dead, reset hunger and chefBought in storage storage.dogHunger = 100; storage.chefBought = false; } // Update food store chef button if (foodStore && foodStore.updateChefButton) { foodStore.updateChefButton(); } // Always keep food store minimize button on top if (foodStoreMinBtn && foodStoreMinBtn.parent) { foodStoreMinBtn.parent.removeChild(foodStoreMinBtn); game.addChild(foodStoreMinBtn); } for (var i = 0; i < upgrades.length; ++i) { var cost = getUpgradeCost(i); // Apply prestige discount var adjustedCost = Math.floor(cost / Math.max(1, prestigeLevel * 0.1 + 1)); upgradeCostTxts[i].setText('Cost: ' + (isNaN(adjustedCost) || adjustedCost === Infinity ? '100,000' : adjustedCost)); upgradeButtons[i].alpha = fartCount >= adjustedCost ? 1 : 0.5; upgradeButtons[i].interactive = fartCount >= adjustedCost; } // Show cat if Chris bought if (chrisCatSpawned && chrisCatContainer && !chrisCatContainer.parent) { game.addChild(chrisCatContainer); } // Show John if bought if (johnSpawned && johnContainer && !johnContainer.parent) { game.addChild(johnContainer); } // --- Show Crown Trophy and Disco Effect if all achievements except dog teleport are unlocked --- if (allAchievementsExceptDogTeleportUnlocked()) { // Only create once if (!crownTrophyContainer) { crownTrophyContainer = new Container(); // Trophy base (use person_leg as base) var trophyBase = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 0.7, x: 0, y: 180, tint: 0xffd700 // gold }); crownTrophyContainer.addChild(trophyBase); // Trophy cup (use centerCircle as cup) var trophyCup = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 1.5, x: 0, y: 60, tint: 0xffe066 // lighter gold }); crownTrophyContainer.addChild(trophyCup); // Dog face inside trophy var dogInTrophy = LK.getAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 0, y: 40 }); crownTrophyContainer.addChild(dogInTrophy); // Crown (use person_phone as crown, yellow tint) var crown = LK.getAsset('person_phone', { anchorX: 0.5, anchorY: 1, scaleX: 1.2, scaleY: 0.7, x: 0, y: -60, tint: 0xffd700 }); crownTrophyContainer.addChild(crown); // Place trophy above dog face crownTrophyContainer.x = 2048 / 2; crownTrophyContainer.y = 800; game.addChild(crownTrophyContainer); } // Start disco effect if not already running if (!discoEffectActive) { discoEffectActive = true; discoColorPhase = 0; // Create overlay if not present if (!discoOverlay) { discoOverlay = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20, x: 2048 / 2, y: 1366, alpha: 0.18, tint: 0xff00ff }); game.addChild(discoOverlay); } } } else { // Remove trophy and disco if not all achievements if (crownTrophyContainer && crownTrophyContainer.parent) { crownTrophyContainer.parent.removeChild(crownTrophyContainer); } crownTrophyContainer = null; discoEffectActive = false; if (discoOverlay && discoOverlay.parent) { discoOverlay.parent.removeChild(discoOverlay); } discoOverlay = null; } } updateUI(); // Start relaxing piano background music LK.playMusic('relaxing_piano', { loop: true, fade: { start: 0, end: 0.3, duration: 2000 } }); // --- Music Control Button --- var musicPlaying = true; var musicBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.45, scaleY: 0.45, x: 180, y: 2732 - 120 }); var musicBtnTxt = new Text2('Music: ON', { size: 50, fill: 0x7A5C00 }); musicBtnTxt.anchor.set(0.5, 0.5); musicBtnTxt.x = 0; musicBtnTxt.y = 0; musicBtn.addChild(musicBtnTxt); musicBtn.interactive = true; musicBtn.down = function () { musicPlaying = !musicPlaying; if (musicPlaying) { LK.playMusic('relaxing_piano', { loop: true, fade: { start: 0, end: 0.3, duration: 1000 } }); musicBtnTxt.setText('Music: ON'); musicBtnTxt.fill = 0x7A5C00; } else { LK.stopMusic(); musicBtnTxt.setText('Music: OFF'); musicBtnTxt.fill = 0x888888; } LK.effects.flashObject(musicBtn, 0xfff7b2, 120); }; game.addChild(musicBtn); // --- Upgrade Button Handlers --- for (var i = 0; i < upgrades.length; ++i) { (function (idx) { upgradeButtons[idx].down = function (x, y, obj) { var cost = getUpgradeCost(idx); // Chris upgrade (last one) if (idx === upgrades.length - 1) { if (fartCount >= cost) { fartCount -= cost; upgradesBought[idx]++; // Spawn cat if (!chrisCatSpawned) { chrisCatSpawned = true; // Create cat container chrisCatContainer = new Container(); // Use Chris asset for cat body var catBody = LK.getAsset('Chris', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 2.2 }); chrisCatContainer.addChild(catBody); // Cat face (text) - Removed // var catFace = new Text2('😼', { // size: 160, // fill: 0x222222 // }); // catFace.anchor.set(0.5, 0.5); // catFace.x = 0; // catFace.y = -10; // chrisCatContainer.addChild(catFace); // Cat label var catLabel = new Text2('Chris the Cat!', { size: 60, fill: 0x444444 }); catLabel.anchor.set(0.5, 0); catLabel.x = 0; catLabel.y = 110; chrisCatContainer.addChild(catLabel); // Place cat right under the fart button chrisCatContainer.x = 2048 / 2; chrisCatContainer.y = 2000 + 170; // Position below fart button game.addChild(chrisCatContainer); // Animate cat in chrisCatContainer.alpha = 0; tween(chrisCatContainer, { alpha: 1 }, { duration: 600, easing: tween.cubicOut }); // Drastically increase auto fart rate: multiply all autoClickers' amount by 5 for (var aci = 0; aci < autoClickers.length; ++aci) { autoClickers[aci].amount *= 5; } // If any autoClicker is already running, clear and restart to apply new rate for (var aci = 0; aci < autoClickers.length; ++aci) { if (autoClickersBought[aci] > 0 && autoClickerTimers[aci]) { LK.clearInterval(autoClickerTimers[aci]); (function (aci2) { autoClickerTimers[aci2] = LK.setInterval(function () { fartCount += autoClickers[aci2].amount * autoClickersBought[aci2] * fartPerClick; updateUI(); dogFace.react(); // Dog says a random gross word if (!dogFace.speechBubble) { var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } var grossWords = ["Yuck!", "Ew!", "Disgusting!", "Nasty!", "Foul!", "Repulsive!", "Stinky!", "Revolting!", "Pee-yew!", "Ugh!", "Gross!", "Barf!", "Ick!", "Putrid!", "Rank!", "Vile!", "Sickening!", "Odious!", "No way!", "Bleh!", "Cringe!", "Yikes!", "Gag!", "Pungent!", "Awful!", "Horrid!", "Stench!", "What is that?!", "Oh no!", "Why?!", "Ewww!", "Yeesh!", "Blech!", "GROSS!", "Noxious!", "Obnoxious!", "Yowza!", "Oof!", "Gnar!", "Yow!", "Eek!", "Yowch!", "Ooze!", "Funky!", "Rancid!", "Rotten!", "Whew!", "Stank!", "Phew!", "GROSS-out!", "Repugnant!", "Skunky!", "Malodorous!", "Putrescent!", "Fetid!", "Mephitic!", "Moldy!", "Dank!", "Manky!", "Cruddy!", "Crud!", "Yuuuck!", "Ew, dude!", "Stale!", "Funky town!", "Reek!", "Stale cheese!", "Cheesy!", "Mold!", "Ew, stinky!", "Ew, gross!", "Ew, nasty!", "Ew, barf!", "Ew, icky!", "Ew, yuck!", "Ew, blech!", "Ew, pew!", "Ew, phew!", "Ew, stank!", "Ew, rotten!", "Ew, rancid!", "Ew, vile!", "Ew, sick!", "Ew, odious!", "Ew, horrid!", "Ew, foul!", "Ew, revolting!", "Ew, repulsive!", "Ew, stench!", "Ew, noxious!", "Ew, obnoxious!", "Ew, gnarly!", "Ew, yowza!", "Ew, oof!", "Ew, yow!", "Ew, eek!", "Ew, yowch!", "Ew, ooze!", "Ew, funky!", "Ew, whew!", "Ew, gross-out!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, yeesh!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, awful!", "Ew, stank!", "Ew, phew!", "Ew, barf!", "Ew, ick!", "Ew, putrid!", "Ew, rank!", "Ew, vile!", "Ew, sickening!", "Ew, odious!", "Ew, bleh!", "Ew, gross!", "Ew, stench!", "Ew, no way!", "Ew, yuck!", "Ew, ewww!", "Ew, blech!", "Ew, GROSS!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, horrid!", "Ew, stench!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, yeesh!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, awful!", "Ew, horrid!", "Ew, stench!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, ewww!", "Ew, yeesh!", "Ew, blech!", "Ew, GROSS!", "Ew, noxious!", "Ew, obnoxious!", "Ew, yowza!", "Ew, oof!", "Ew, gnar!", "Ew, yow!", "Ew, eek!", "Ew, yowch!", "Ew, ooze!", "Ew, funky!", "Ew, rancid!", "Ew, rotten!", "Ew, whew!", "Ew, stank!", "Ew, phew!", "Ew, GROSS-out!"]; var word = grossWords[Math.floor(Math.random() * grossWords.length)]; dogFace.speechBubble.setText(word); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); dogFace.x = 2048 / 2; dogFace.lastX = dogFace.x; LK.getSound('fart_snd').play(); }, autoClickers[aci2].interval); })(aci); } } } updateUI(); LK.effects.flashObject(upgradeButtons[idx], 0xeeeecc, 120); } return; } // John upgrade (second last one) if (idx === upgrades.length - 2) { if (fartCount >= cost) { fartCount -= cost; upgradesBought[idx]++; // Spawn John if (!johnSpawned) { johnSpawned = true; // Create John container johnContainer = new Container(); // Use John asset for body var johnBody = LK.getAsset('John', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 2.2 }); johnContainer.addChild(johnBody); // John label var johnLabel = new Text2('John the Booster!', { size: 60, fill: 0x444444 }); johnLabel.anchor.set(0.5, 0); johnLabel.x = 0; johnLabel.y = 110; johnContainer.addChild(johnLabel); // Place John next to Chris under the fart button johnContainer.x = 2048 / 2 + 150; // Position John next to Chris johnContainer.y = 2000 + 170; // Align with Chris's Y position game.addChild(johnContainer); // Animate John in johnContainer.alpha = 0; tween(johnContainer, { alpha: 1 }, { duration: 600, easing: tween.cubicOut }); } updateUI(); LK.effects.flashObject(upgradeButtons[idx], 0xeeeecc, 120); } return; } // Normal upgrades if (fartCount >= cost) { fartCount -= cost; upgradesBought[idx]++; fartPerClick += upgrades[idx].amount; updateUI(); // Feedback LK.effects.flashObject(upgradeButtons[idx], 0xeeeecc, 120); } }; })(i); } // --- Fart Button Handler (Clicker) --- // Dog nap event: sometimes the dog naps and you can't fart for a few seconds var dogNapping = false; var napTimeout = null; fartBtn.down = function (x, y, obj) { if (dogNapping) { createFloatingText(fartBtn.x, fartBtn.y - 120, "Dog is napping!", 0x888888); LK.effects.flashObject(fartBtn, 0x888888, 120); return; } // Animate button fartBtn.animatePress(); // Button color flash for feedback LK.effects.flashObject(fartBtn, 0xfff7b2, 120); // Play fart sound LK.getSound('fart_snd').play(); // --- COMBO SYSTEM --- var now = Date.now(); if (now - lastClickTime < 2000) { // Within 2 seconds comboCount++; } else { comboCount = 1; } // Track speed clicking (10 clicks in 2 seconds) if (!window._speedClickAchievement) { window._speedClickHistory = window._speedClickHistory || []; window._speedClickHistory.push(now); // Remove clicks older than 2 seconds window._speedClickHistory = window._speedClickHistory.filter(function (time) { return now - time < 2000; }); if (window._speedClickHistory.length >= 10) { window._speedClickAchievement = true; } } lastClickTime = now; // Clear existing combo timeout if (comboTimeout) { LK.clearTimeout(comboTimeout); } // Set new combo timeout comboTimeout = LK.setTimeout(resetCombo, 2000); updateComboMultiplier(); updateComboUI(); // Add particle explosion at button createParticleExplosion(fartBtn.x, fartBtn.y - 50, 0xfff7b2, 8 + Math.min(comboCount, 20)); // Add screen shake based on combo addScreenShake(2 + Math.min(comboCount * 0.5, 15)); // Show combo floating text for milestone combos if (comboCount % 10 === 0 && comboCount >= 10) { createFloatingText(fartBtn.x + 150, fartBtn.y - 100, "COMBO x" + comboCount + "!", 0xff8000); } // Check combo achievements if (!window._combo50Achievement && comboCount >= 50) { window._combo50Achievement = true; } if (!window._combo100Achievement && comboCount >= 100) { window._combo100Achievement = true; } // --- CHAOS MODE: Every fart triggers a storm of effects when autism mode is ON! --- if (autismMode) { // Track autism mode farts window._autismModeFarts = (window._autismModeFarts || 0) + 1; // 1. Rapid screen shake var chaosShakeTimes = 16 + Math.floor(Math.random() * 8); var _chaosShake = function chaosShake(n) { if (n <= 0) { game.x = 0; return; } game.x = n % 2 === 0 ? 40 + Math.random() * 30 : -40 - Math.random() * 30; game.y = n % 3 === 0 ? 30 + Math.random() * 20 : -30 - Math.random() * 20; LK.setTimeout(function () { _chaosShake(n - 1); }, 18 + Math.floor(Math.random() * 10)); }; _chaosShake(chaosShakeTimes); // 2. Random color strobe on dog face and fart button var chaosStrobeColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff, 0xffffff, 0x7ec850, 0xf06292, 0xffeb3b, 0x9c27b0, 0xff5722, 0x00bcd4, 0xe91e63]; var chaosStrobeIdx = 0; var chaosStrobeMax = 10 + Math.floor(Math.random() * 6); var chaosDogParts = []; if (dogFace.children && dogFace.children.length > 0) { for (var i = 0; i < dogFace.children.length; ++i) { if (dogFace.children[i] && typeof dogFace.children[i].tint !== "undefined") { chaosDogParts.push(dogFace.children[i]); } } } var chaosBtnParts = []; if (fartBtn.children && fartBtn.children.length > 0) { for (var i = 0; i < fartBtn.children.length; ++i) { if (fartBtn.children[i] && typeof fartBtn.children[i].tint !== "undefined") { chaosBtnParts.push(fartBtn.children[i]); } } } var chaosOriginalDogTints = []; for (var i = 0; i < chaosDogParts.length; ++i) { chaosOriginalDogTints.push(chaosDogParts[i].tint); } var chaosOriginalBtnTints = []; for (var i = 0; i < chaosBtnParts.length; ++i) { chaosOriginalBtnTints.push(chaosBtnParts[i].tint); } var _chaosStrobe = function chaosStrobe() { if (chaosStrobeIdx >= chaosStrobeMax) { // Restore original tints for (var i = 0; i < chaosDogParts.length; ++i) { chaosDogParts[i].tint = chaosOriginalDogTints[i]; } for (var i = 0; i < chaosBtnParts.length; ++i) { chaosBtnParts[i].tint = chaosOriginalBtnTints[i]; } return; } var color = chaosStrobeColors[Math.floor(Math.random() * chaosStrobeColors.length)]; for (var i = 0; i < chaosDogParts.length; ++i) { chaosDogParts[i].tint = color; } for (var i = 0; i < chaosBtnParts.length; ++i) { chaosBtnParts[i].tint = color; } // Quick screen flash for extra chaos LK.effects.flashScreen(color, 40 + Math.floor(Math.random() * 30)); chaosStrobeIdx++; LK.setTimeout(_chaosStrobe, 40 + Math.floor(Math.random() * 30)); }; _chaosStrobe(); // 3. Emoji explosion: spawn a burst of random emojis from the dog face var chaosEmojis = ["💥", "💨", "😂", "🤪", "😱", "😜", "🤯", "🔥", "💩", "🐶", "🌈", "⭐", "✨", "😵", "😆", "😹", "😛", "😲", "😬", "😺", "😻", "😈", "👻", "🦴", "🍔", "🍕", "🍟", "🍭", "🍦", "🍉", "🍌", "🍩", "🍪", "🥨", "🥓", "🥚", "🥑", "🥕", "🥦", "🥒", "🥬", "🥥", "🥜", "🥨", "🥯", "🥞", "🥩", "🥠", "🥡", "🥢", "🥤", "🥣", "🥧", "🥨", "🥚", "🥓", "🥩", "🥞", "🥯", "🥠", "🥡", "🥢", "🥤", "🥣", "🥧"]; var chaosEmojiCount = 0; var chaosEmojiMax = 12 + Math.floor(Math.random() * 8); var _chaosEmoji = function chaosEmoji() { if (chaosEmojiCount >= chaosEmojiMax) return; var emoji = chaosEmojis[Math.floor(Math.random() * chaosEmojis.length)]; var emojiTxt = new Text2(emoji, { size: 90 + Math.floor(Math.random() * 60), fill: 0xffffff, align: 'center' }); emojiTxt.anchor.set(0.5, 0.5); emojiTxt.x = dogFace.x + (-120 + Math.random() * 240); emojiTxt.y = dogFace.y + (-120 + Math.random() * 240); emojiTxt.alpha = 1; game.addChild(emojiTxt); // Animate flying out in a random direction var dx = -400 + Math.random() * 800; var dy = -600 + Math.random() * 1200; tween(emojiTxt, { x: emojiTxt.x + dx, y: emojiTxt.y + dy, alpha: 0 }, { duration: 700 + Math.random() * 400, easing: tween.cubicOut, onFinish: function onFinish() { if (emojiTxt.parent) emojiTxt.parent.removeChild(emojiTxt); } }); chaosEmojiCount++; LK.setTimeout(_chaosEmoji, 30 + Math.floor(Math.random() * 30)); }; _chaosEmoji(); // 4. Randomly pulse the background color var chaosBgColors = [0xffe066, 0x7ec850, 0x4fc3f7, 0xf06292, 0xffeb3b, 0x9c27b0, 0xff5722, 0x00bcd4, 0x8bc34a, 0xe91e63, 0xffffff, 0x000000]; var chaosBgIdx = 0; var chaosBgMax = 6 + Math.floor(Math.random() * 4); var originalBgChaos = 0xE3F6FF; var _chaosBgPulse = function chaosBgPulse() { if (chaosBgIdx >= chaosBgMax) { game.setBackgroundColor(originalBgChaos); return; } var color = chaosBgColors[Math.floor(Math.random() * chaosBgColors.length)]; game.setBackgroundColor(color); chaosBgIdx++; LK.setTimeout(_chaosBgPulse, 50 + Math.floor(Math.random() * 40)); }; _chaosBgPulse(); // 5. Randomly scale and rotate the dog face for a moment var chaosScale = 0.7 + Math.random() * 1.6; var chaosRot = -Math.PI + Math.random() * (2 * Math.PI); tween(dogFace, { scaleX: chaosScale, scaleY: chaosScale, rotation: chaosRot }, { duration: 120, easing: tween.cubicIn, onFinish: function onFinish() { tween(dogFace, { scaleX: 1, scaleY: 1, rotation: 0 }, { duration: 180, easing: tween.cubicOut }); } }); // 6. Randomly move the fart button for a moment var fartBtnOrigX = fartBtn.x; var fartBtnOrigY = fartBtn.y; var chaosBtnDX = -80 + Math.random() * 160; var chaosBtnDY = -60 + Math.random() * 120; tween(fartBtn, { x: fartBtnOrigX + chaosBtnDX, y: fartBtnOrigY + chaosBtnDY }, { duration: 90, easing: tween.cubicIn, onFinish: function onFinish() { tween(fartBtn, { x: fartBtnOrigX, y: fartBtnOrigY }, { duration: 120, easing: tween.cubicOut }); } }); // 7. Occasionally (10% chance) spawn a huge emoji in the center that fades out if (Math.random() < 0.1) { var bigEmoji = chaosEmojis[Math.floor(Math.random() * chaosEmojis.length)]; var bigEmojiTxt = new Text2(bigEmoji, { size: 400 + Math.floor(Math.random() * 200), fill: 0xffffff, align: 'center' }); bigEmojiTxt.anchor.set(0.5, 0.5); bigEmojiTxt.x = 2048 / 2; bigEmojiTxt.y = 2732 / 2; bigEmojiTxt.alpha = 1; game.addChild(bigEmojiTxt); tween(bigEmojiTxt, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 700, easing: tween.cubicOut, onFinish: function onFinish() { if (bigEmojiTxt.parent) bigEmojiTxt.parent.removeChild(bigEmojiTxt); } }); } } // End autism mode chaos effects // --- MEGA FART SPECIAL EFFECTS --- if (comboCount >= 100) { // MEGA FART at 100+ combo! LK.effects.flashScreen(0xffffff, 300); createParticleExplosion(dogFace.x, dogFace.y, 0xffffff, 50); addScreenShake(30); // Bonus farts for mega combo fartCount += 1000; createFloatingText(dogFace.x, dogFace.y - 200, "MEGA FART BONUS!\n+1000 Farts!", 0xffffff); // Dog reaction if (!dogFace.speechBubble) { var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } dogFace.speechBubble.setText("MEGA FART!!!\nI CAN'T TAKE IT!"); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 1500, delay: 1000, easing: tween.cubicIn }); } // Dog reacts // --- Fun: Randomize dog face (normal, react, or silly) and rare golden fart event --- var goldenFart = false; if (Math.random() < 0.01) { // 1% chance for golden fart goldenFart = true; fartCount += 1000; // Track golden fart achievement if (!window._goldenFartAchievement) { window._goldenFartAchievement = true; } // Golden fart effect: flash screen gold, show special text LK.effects.flashScreen(0xffe066, 800); if (!dogFace.speechBubble) { var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } dogFace.speechBubble.setText("💛 GOLDEN FART! 💛\n+1000 Farts!"); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 1200, delay: 800, easing: tween.cubicIn }); // Dog face flashes gold tween(dogFace, { alpha: 0.5 }, { duration: 100, yoyo: true, repeat: 1, onFinish: function onFinish() { dogFace.alpha = 1; } }); } else { // 10% chance for silly face (react stays longer) if (Math.random() < 0.1) { dogFace.showReact(); LK.setTimeout(function () { dogFace.showNormal(); dogFace.x = 2048 / 2; }, 1200); } else { dogFace.react(); } } // Dog says a random synonym for 'gross' if (!dogFace.speechBubble) { // Create speech bubble if not already present var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } // Check if dog is wearing the top hat (fancy mode) var isWearingTopHat = false; if (hatStore && hatStore.equippedHat) { isWearingTopHat = true; } var grossWords; if (isWearingTopHat) { // Fancy synonyms for gross while wearing top hat grossWords = ["Absolutely abhorrent!", "Utterly reprehensible!", "Quite unsavory!", "Most disagreeable!", "Thoroughly distasteful!", "Decidedly unpalatable!", "Exceedingly offensive!", "Remarkably repugnant!", "Profoundly disturbing!", "Extraordinarily vile!", "Supremely loathsome!", "Undeniably detestable!", "Monumentally revolting!", "Categorically objectionable!", "Fundamentally deplorable!", "Intrinsically nauseating!", "Quintessentially abominable!", "Indubitably repulsive!", "Unquestionably offensive!", "Irrefutably disgusting!", "Good heavens!", "My word!", "How unseemly!", "Quite dreadful!", "Most unbecoming!", "Rather appalling!", "Terribly vulgar!", "Frightfully crude!", "Awfully uncouth!", "Shockingly improper!", "Disgracefully crass!", "Regrettably tactless!", "Lamentably coarse!", "Woefully inappropriate!", "Deplorably unrefined!", "Insufferably boorish!", "Intolerably barbaric!", "Unacceptably gauche!", "Abhorrently uncivilized!", "Contemptibly lowbrow!"]; } else { // Regular gross words for normal mode grossWords = ["Yuck!", "Ew!", "Disgusting!", "Nasty!", "Foul!", "Repulsive!", "Stinky!", "Revolting!", "Pee-yew!", "Ugh!", "Gross!", "Barf!", "Ick!", "Putrid!", "Rank!", "Vile!", "Sickening!", "Odious!", "No way!", "Bleh!", "Cringe!", "Yikes!", "Gag!", "Pungent!", "Awful!", "Horrid!", "Stench!", "What is that?!", "Oh no!", "Why?!", "Ewww!", "Yeesh!", "Blech!", "GROSS!", "Noxious!", "Obnoxious!", "Yowza!", "Oof!", "Gnar!", "Yow!", "Eek!", "Yowch!", "Ooze!", "Funky!", "Rancid!", "Rotten!", "Whew!", "Stank!", "Phew!", "GROSS-out!", // More synonyms "Repugnant!", "Skunky!", "Malodorous!", "Putrescent!", "Fetid!", "Mephitic!", "Moldy!", "Dank!", "Manky!", "Cruddy!", "Crud!", "Yuuuck!", "Ew, dude!", "Stale!", "Funky town!", "Reek!", "Stale cheese!", "Cheesy!", "Mold!", "Ew, stinky!", "Ew, gross!", "Ew, nasty!", "Ew, barf!", "Ew, icky!", "Ew, yuck!", "Ew, blech!", "Ew, pew!", "Ew, phew!", "Ew, stank!", "Ew, rotten!", "Ew, rancid!", "Ew, vile!", "Ew, sick!", "Ew, odious!", "Ew, horrid!", "Ew, foul!", "Ew, revolting!", "Ew, repulsive!", "Ew, stench!", "Ew, noxious!", "Ew, obnoxious!", "Ew, gnarly!", "Ew, yowza!", "Ew, oof!", "Ew, yow!", "Ew, eek!", "Ew, yowch!", "Ew, ooze!", "Ew, funky!", "Ew, whew!", "Ew, gross-out!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, yeesh!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, awful!", "Ew, stank!", "Ew, phew!", "Ew, barf!", "Ew, ick!", "Ew, putrid!", "Ew, rank!", "Ew, vile!", "Ew, sickening!", "Ew, odious!", "Ew, bleh!", "Ew, gross!", "Ew, stench!", "Ew, no way!", "Ew, yuck!", "Ew, ewww!", "Ew, blech!", "Ew, GROSS!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, horrid!", "Ew, stench!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, yeesh!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, awful!", "Ew, horrid!", "Ew, stench!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, ewww!", "Ew, yeesh!", "Ew, blech!", "Ew, GROSS!", "Ew, noxious!", "Ew, obnoxious!", "Ew, yowza!", "Ew, oof!", "Ew, gnar!", "Ew, yow!", "Ew, eek!", "Ew, yowch!", "Ew, ooze!", "Ew, funky!", "Ew, rancid!", "Ew, rotten!", "Ew, whew!", "Ew, stank!", "Ew, phew!", "Ew, GROSS-out!"]; } var word = grossWords[Math.floor(Math.random() * grossWords.length)]; dogFace.speechBubble.setText(word); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); // Dog teleports to center and stops sliding for a moment dogFace.x = 2048 / 2; dogFace.lastX = dogFace.x; // --- Fun: Rare rainbow fart event (0.5% chance) --- if (Math.random() < 0.005) { // Track rainbow fart achievement if (!window._rainbowFartAchievement) { window._rainbowFartAchievement = true; } // Rainbow fart: flash screen rainbow, show rainbow text, dog face rainbow overlay var rainbowColors = [0xff0000, 0xffa500, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0xee82ee]; var idx = 0; var _rainbowFlash = function rainbowFlash() { if (idx >= rainbowColors.length) return; LK.effects.flashScreen(rainbowColors[idx], 120); idx++; LK.setTimeout(_rainbowFlash, 120); }; _rainbowFlash(); if (!dogFace.speechBubble) { var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } dogFace.speechBubble.setText("🌈 RAINBOW FART! 🌈"); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 1200, delay: 800, easing: tween.cubicIn }); // Rainbow overlay on dog face if (!dogFace.rainbowOverlay) { dogFace.rainbowOverlay = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 8, x: 0, y: 0, alpha: 0.4, tint: 0xffffff }); dogFace.addChild(dogFace.rainbowOverlay); } dogFace.rainbowOverlay.alpha = 0.7; var rainbowIdx = 0; var _rainbowTint = function rainbowTint() { if (rainbowIdx >= rainbowColors.length) { dogFace.rainbowOverlay.alpha = 0; return; } dogFace.rainbowOverlay.tint = rainbowColors[rainbowIdx]; rainbowIdx++; LK.setTimeout(_rainbowTint, 120); }; _rainbowTint(); } // --- Rare Event System --- var rareEvents = ['GOLDEN_DOG', 'FART_TORNADO', 'RAINBOW_EXPLOSION', 'TIME_WARP', 'MEGA_MULTIPLIER']; var rareEventChance = 0.001 + prestigeLevel * 0.0005; // Increases with prestige if (Math.random() < rareEventChance) { var event = rareEvents[Math.floor(Math.random() * rareEvents.length)]; switch (event) { case 'GOLDEN_DOG': fartCount += 10000 * prestigeMultiplier; createFloatingText(dogFace.x, dogFace.y - 200, "GOLDEN DOG EVENT!\n+10,000 Farts!", 0xffd700); LK.effects.flashScreen(0xffd700, 800); // Turn dog golden temporarily for (var i = 0; i < dogFace.children.length; i++) { if (dogFace.children[i] && typeof dogFace.children[i].tint !== "undefined") { var part = dogFace.children[i]; var oldTint = part.tint; part.tint = 0xffd700; LK.setTimeout(function (p, t) { return function () { p.tint = t; }; }(part, oldTint), 3000); } } break; case 'FART_TORNADO': comboCount += 50; updateComboMultiplier(); createFloatingText(2048 / 2, 1500, "FART TORNADO!\n+50 Combo!", 0x0080ff); // Create tornado effect for (var t = 0; t < 20; t++) { (function (index) { LK.setTimeout(function () { createParticleExplosion(2048 / 2 + Math.cos(index * 0.3) * 200, 1500 + Math.sin(index * 0.3) * 100, 0x0080ff, 8); }, index * 50); })(t); } break; case 'TIME_WARP': // Boost all auto-clickers for 30 seconds createFloatingText(2048 / 2, 1600, "TIME WARP!\nAuto-Clickers x5 for 30s!", 0xff00ff); activePowerUps.push({ type: 'TIME_WARP', name: 'Time Warp', timeLeft: 30000, color: 0xff00ff }); break; } } // Apply combo multiplier and power-up bonuses to fart gain calculation var totalGain = fartPerClick * comboMultiplier * prestigeMultiplier; // Double farts power-up if (hasPowerUp('DOUBLE_FARTS')) { totalGain *= 2; } // Mega combo power-up if (hasPowerUp('MEGA_COMBO')) { totalGain *= 1 + comboCount * 0.1; } // Time warp bonus if (hasPowerUp('TIME_WARP')) { totalGain *= 3; } // Weekly challenge progress weeklyChallenge.progress += Math.floor(totalGain); if (weeklyChallenge.progress >= weeklyChallenge.target && !weeklyChallenge.completed) { weeklyChallenge.completed = true; var reward = 50000 + prestigeLevel * 10000; fartCount += reward; createFloatingText(2048 / 2, 1200, "WEEKLY CHALLENGE COMPLETE!\n+" + reward + " Farts!", 0x00ff00); storage.weeklyCompleted = true; } fartCount += Math.floor(totalGain); // Show floating score for big gains if (totalGain > fartPerClick) { createFloatingText(fartBtn.x - 150, fartBtn.y - 100, "+" + totalGain + " Farts!", 0x83de44); } // Trigger random power-up chance (2% base, increases with combo) var powerUpChance = 0.02 + comboCount * 0.001; if (Math.random() < powerUpChance) { triggerRandomPowerUp(); } // --- Fun: Every 17th fart, color strobe and screen flash for visual stimulation --- // Only trigger this effect in autism mode! if (autismMode && fartCount > 0 && fartCount % 17 === 0) { // Color strobe on dog face var strobeColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff, 0xffffff]; var strobeIdx = 0; var strobeMax = 7; var strobeDogParts = []; if (dogFace.children && dogFace.children.length > 0) { for (var i = 0; i < dogFace.children.length; ++i) { if (dogFace.children[i] && typeof dogFace.children[i].tint !== "undefined") { strobeDogParts.push(dogFace.children[i]); } } } var strobeOriginalTints = []; for (var i = 0; i < strobeDogParts.length; ++i) { strobeOriginalTints.push(strobeDogParts[i].tint); } var _doStrobe = function doStrobe() { // Check if autism mode is still active before continuing strobe if (!autismMode || strobeIdx >= strobeMax) { // Restore original tints for (var i = 0; i < strobeDogParts.length; ++i) { strobeDogParts[i].tint = strobeOriginalTints[i]; } return; } var color = strobeColors[strobeIdx % strobeColors.length]; for (var i = 0; i < strobeDogParts.length; ++i) { strobeDogParts[i].tint = color; } // Quick screen flash for extra stimulation LK.effects.flashScreen(color, 60); strobeIdx++; LK.setTimeout(_doStrobe, 60); }; _doStrobe(); } // --- Fun: Every 33rd fart, dog face wiggles side to side --- if (fartCount > 0 && fartCount % 33 === 0) { var _doWiggle = function doWiggle() { if (wiggleCount >= maxWiggles) { dogFace.x = originalX; return; } var offset = wiggleCount % 2 === 0 ? 40 : -40; tween(dogFace, { x: originalX + offset }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(dogFace, { x: originalX }, { duration: 60, easing: tween.cubicOut, onFinish: function onFinish() { wiggleCount++; _doWiggle(); } }); } }); }; // Wiggle dog face left and right 4 times var wiggleCount = 0; var maxWiggles = 4; var originalX = dogFace.x; _doWiggle(); } // --- Fun: Every 25th fart, dog face gets a random color for a while --- if (fartCount > 0 && fartCount % 25 === 0) { // Pick a fun random color (not too dark) var funColors = [0xffb347, 0x7ec850, 0x4fc3f7, 0xf06292, 0xffeb3b, 0x9c27b0, 0xff5722, 0x00bcd4, 0x8bc34a, 0xe91e63]; var color = funColors[Math.floor(Math.random() * funColors.length)]; // Animate both faces if present if (dogFace.children && dogFace.children.length > 0) { for (var i = 0; i < dogFace.children.length; ++i) { if (dogFace.children[i] && typeof dogFace.children[i].tint !== "undefined") { var facePart = dogFace.children[i]; var oldTint = facePart.tint; facePart.tint = color; // Animate back to normal after 1.2s LK.setTimeout(function (part, tint) { return function () { part.tint = tint; }; }(facePart, oldTint), 1200); } } } } // --- Fun: Every 50th fart, dog gets a random hat or glasses for a while --- if (fartCount > 0 && fartCount % 50 === 0) { if (!dogFace.accessory) { dogFace.accessory = new Container(); dogFace.addChild(dogFace.accessory); } // Remove old accessory dogFace.accessory.removeChildren(); var accType = Math.random() < 0.5 ? "hat" : "glasses"; if (accType === "hat") { // Use person_phone as a silly hat var hat = LK.getAsset('person_phone', { anchorX: 0.5, anchorY: 1, scaleX: 2.2, scaleY: 1.2, x: 0, y: -420, tint: 0x7A5C00 }); dogFace.accessory.addChild(hat); } else { // Use person_leg as glasses var glasses = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 0.4, x: 0, y: -120, tint: 0x222222 }); dogFace.accessory.addChild(glasses); } // Remove accessory after 2 seconds LK.setTimeout(function () { if (dogFace.accessory) dogFace.accessory.removeChildren(); }, 2000); } // --- Fun: Every 99th fart, background color pulse for visual stimulation --- if (fartCount > 0 && fartCount % 99 === 0) { var bgPulseColors = [0xffe066, 0x7ec850, 0x4fc3f7, 0xf06292, 0xffeb3b, 0x9c27b0, 0xff5722, 0x00bcd4, 0x8bc34a, 0xe91e63]; var bgPulseIdx = 0; var bgPulseMax = 8; var originalBg = 0xE3F6FF; var _doBgPulse = function doBgPulse() { if (bgPulseIdx >= bgPulseMax) { game.setBackgroundColor(originalBg); return; } var color = bgPulseColors[bgPulseIdx % bgPulseColors.length]; game.setBackgroundColor(color); bgPulseIdx++; LK.setTimeout(_doBgPulse, 80); }; _doBgPulse(); } // --- Fun: Every 150th fart, dog face gets a random funny mustache for a while --- if (fartCount > 0 && fartCount % 150 === 0) { if (!dogFace.mustache) { dogFace.mustache = new Container(); dogFace.addChild(dogFace.mustache); } // Remove old mustache dogFace.mustache.removeChildren(); // Use person_leg as a mustache, randomize color and position var mustacheColors = [0x222222, 0x7A5C00, 0x964B00, 0xFFD700, 0xC0C0C0]; var color = mustacheColors[Math.floor(Math.random() * mustacheColors.length)]; var mustache = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1 + Math.random() * 0.7, scaleY: 0.35 + Math.random() * 0.2, x: 0, y: 120 + Math.random() * 30, tint: color }); dogFace.mustache.addChild(mustache); // Remove mustache after 2.2 seconds LK.setTimeout(function () { if (dogFace.mustache) dogFace.mustache.removeChildren(); }, 2200); } // --- Fun: Every 77th fart, emoji rain for visual stimulation --- if (fartCount > 0 && fartCount % 77 === 0) { var emojiRainEmojis = ["🌈", "⭐", "💖", "✨", "🎉", "😃", "🐶", "🦄", "🍀", "🎈", "😺", "😎", "🥳", "😆", "😻"]; var emojiRainCount = 0; var emojiRainMax = 18; var _emojiRain = function emojiRain() { if (emojiRainCount >= emojiRainMax) return; var emoji = emojiRainEmojis[Math.floor(Math.random() * emojiRainEmojis.length)]; var emojiTxt = new Text2(emoji, { size: 120 + Math.floor(Math.random() * 40), fill: 0xffffff, align: 'center' }); emojiTxt.anchor.set(0.5, 0.5); emojiTxt.x = 400 + Math.random() * (2048 - 800); emojiTxt.y = -100; emojiTxt.alpha = 1; game.addChild(emojiTxt); // Animate falling down tween(emojiTxt, { y: 2732 + 100, alpha: 0.7 + Math.random() * 0.3 }, { duration: 1200 + Math.random() * 400, easing: tween.cubicIn, onFinish: function onFinish() { if (emojiTxt.parent) emojiTxt.parent.removeChild(emojiTxt); } }); emojiRainCount++; LK.setTimeout(_emojiRain, 60); }; _emojiRain(); } // --- Fun: Every 75th fart, dog face flips upside down for a moment --- if (fartCount > 0 && fartCount % 75 === 0) { // Animate dog face rotation to upside down and back tween(dogFace, { rotation: Math.PI }, { duration: 220, easing: tween.cubicIn, onFinish: function onFinish() { LK.setTimeout(function () { tween(dogFace, { rotation: 0 }, { duration: 220, easing: tween.cubicOut }); }, 900); } }); } // --- Fun: Every 333rd fart, dog face spins 360 degrees --- if (fartCount > 0 && fartCount % 333 === 0) { tween(dogFace, { rotation: 2 * Math.PI }, { duration: 700, easing: tween.cubicInOut, onFinish: function onFinish() { dogFace.rotation = 0; } }); } updateUI(); // --- Fun: Every 111th fart, dog sneezes and face flashes white --- if (fartCount > 0 && fartCount % 111 === 0) { // Sneeze text if (!dogFace.speechBubble) { var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } dogFace.speechBubble.setText("ACHOO!"); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); // Face flashes white for (var i = 0; i < dogFace.children.length; ++i) { if (dogFace.children[i] && typeof dogFace.children[i].tint !== "undefined") { var facePart = dogFace.children[i]; var oldTint = facePart.tint; facePart.tint = 0xffffff; LK.setTimeout(function (part, tint) { return function () { part.tint = tint; }; }(facePart, oldTint), 400); } } } // --- Fun: Every 555th fart, dog face gets a random emoji sticker for a while --- if (fartCount > 0 && fartCount % 555 === 0) { if (!dogFace.sticker) { dogFace.sticker = new Container(); dogFace.addChild(dogFace.sticker); } // Remove old sticker dogFace.sticker.removeChildren(); // Pick a random emoji var emojis = ["😂", "😎", "🤪", "😍", "😱", "🥳", "😜", "😇", "🤩", "😏", "😬", "😳", "😺", "🐶", "💩", "🌈", "🔥", "⭐", "🎉"]; var emoji = emojis[Math.floor(Math.random() * emojis.length)]; var stickerTxt = new Text2(emoji, { size: 160 + Math.floor(Math.random() * 40), fill: 0xffffff, align: 'center' }); stickerTxt.anchor.set(0.5, 0.5); stickerTxt.x = -180 + Math.random() * 360; stickerTxt.y = -180 + Math.random() * 360; dogFace.sticker.addChild(stickerTxt); // Remove sticker after 2.5 seconds LK.setTimeout(function () { if (dogFace.sticker) dogFace.sticker.removeChildren(); }, 2500); } // --- Fun: Every 444th fart, dog face grows and shrinks --- if (fartCount > 0 && fartCount % 444 === 0) { tween(dogFace, { scaleX: 1.5, scaleY: 1.5 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(dogFace, { scaleX: 1, scaleY: 1 }, { duration: 180, easing: tween.cubicIn }); } }); } // --- Fun: Every 222nd fart, dog face bounces up and down --- if (fartCount > 0 && fartCount % 222 === 0) { var originalY = dogFace.y; var bounceCount = 0; var maxBounces = 4; var _doBounce = function doBounce() { if (bounceCount >= maxBounces) { dogFace.y = originalY; return; } var offset = bounceCount % 2 === 0 ? -60 : 60; tween(dogFace, { y: originalY + offset }, { duration: 70, easing: tween.cubicIn, onFinish: function onFinish() { tween(dogFace, { y: originalY }, { duration: 70, easing: tween.cubicOut, onFinish: function onFinish() { bounceCount++; _doBounce(); } }); } }); }; _doBounce(); } // --- Fun: Every 200th fart, dog barks and screen shakes --- if (fartCount > 0 && fartCount % 200 === 0) { // Bark text if (!dogFace.speechBubble) { var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } dogFace.speechBubble.setText("🐶 WOOF! 🐶"); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); // Screen shake effect var shakeTimes = 10; var _shake = function shake(n) { if (n <= 0) { game.x = 0; return; } game.x = n % 2 === 0 ? 20 : -20; LK.setTimeout(function () { _shake(n - 1); }, 30); }; _shake(shakeTimes); } // --- Achievements: First 100 Farts --- if (!window._first100FartsShown && fartCount >= 100 && !isShowingAchievement) { window._first100FartsShown = true; isShowingAchievement = true; // Show achievement popup var achPopup = new Container(); var achBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2732 / 2 }); achPopup.addChild(achBg); var achTxt = new Text2('Achievement Unlocked!\nFirst 100 Farts!', { size: 80, fill: 0x7A5C00, align: 'center' }); achTxt.anchor.set(0.5, 0.5); achTxt.x = 2048 / 2; achTxt.y = 2732 / 2 - 40; achPopup.addChild(achTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(achPopup); isShowingAchievement = false; }; achPopup.addChild(okBtn); game.addChild(achPopup); LK.effects.flashObject(achBg, 0xfff7b2, 120); } // --- Achievements: 1000 Farts --- if (!window._first1000FartsShown && fartCount >= 1000 && !isShowingAchievement) { window._first1000FartsShown = true; isShowingAchievement = true; var achPopup = new Container(); var achBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2732 / 2 }); achPopup.addChild(achBg); var achTxt = new Text2('Achievement Unlocked!\n1000 Farts!\nDog is a Fart Legend!', { size: 80, fill: 0x7A5C00, align: 'center' }); achTxt.anchor.set(0.5, 0.5); achTxt.x = 2048 / 2; achTxt.y = 2732 / 2 - 40; achPopup.addChild(achTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(achPopup); isShowingAchievement = false; }; achPopup.addChild(okBtn); game.addChild(achPopup); LK.effects.flashObject(achBg, 0xfff7b2, 120); } // --- Achievements: 10,000 Farts --- if (!window._first10kFartsShown && fartCount >= 10000 && !isShowingAchievement) { window._first10kFartsShown = true; isShowingAchievement = true; var achPopup = new Container(); var achBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2732 / 2 }); achPopup.addChild(achBg); var achTxt = new Text2('Achievement Unlocked!\n10,000 Farts!\nDog is a Fart GOD!', { size: 80, fill: 0x7A5C00, align: 'center' }); achTxt.anchor.set(0.5, 0.5); achTxt.x = 2048 / 2; achTxt.y = 2732 / 2 - 40; achPopup.addChild(achTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(achPopup); isShowingAchievement = false; }; achPopup.addChild(okBtn); game.addChild(achPopup); LK.effects.flashObject(achBg, 0xfff7b2, 120); } // --- Achievements: 1,000,000 Farts --- if (!window._first1MFartsShown && fartCount >= 1000000 && !isShowingAchievement) { window._first1MFartsShown = true; isShowingAchievement = true; var achPopup = new Container(); var achBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2732 / 2 }); achPopup.addChild(achBg); var achTxt = new Text2('Achievement Unlocked!\n1,000,000 Farts!\nDog Ascends to Fart Heaven!', { size: 80, fill: 0x7A5C00, align: 'center' }); achTxt.anchor.set(0.5, 0.5); achTxt.x = 2048 / 2; achTxt.y = 2732 / 2 - 40; achPopup.addChild(achTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(achPopup); isShowingAchievement = false; // === GRAND PORTAL EVENT === if (!window._grandPortalShown) { window._grandPortalShown = true; setTimeout(function () { showGrandPortal(); }, 800); } }; achPopup.addChild(okBtn); game.addChild(achPopup); LK.effects.flashObject(achBg, 0xfff7b2, 120); } // === GRAND PORTAL: The Ultimate Event === // Always define showGrandPortal in the global scope for event triggers window.showGrandPortal = function showGrandPortal() { // Defensive: Only allow one portal at a time if (window._grandPortalContainer && window._grandPortalContainer.parent) return; var portal = new Container(); window._grandPortalContainer = portal; game.addChild(portal); // Fade out all main UI/game elements var toHide = [typeof dogFace !== "undefined" ? dogFace : null, typeof fartBtn !== "undefined" ? fartBtn : null, typeof walkBtn !== "undefined" ? walkBtn : null, typeof hatStore !== "undefined" ? hatStore : null, typeof foodStore !== "undefined" ? foodStore : null, typeof foodStoreMinBtn !== "undefined" ? foodStoreMinBtn : null, typeof hungerBar !== "undefined" ? hungerBar : null, typeof shareBtn !== "undefined" ? shareBtn : null, typeof autismModeBtn !== "undefined" ? autismModeBtn : null, typeof instrTxt !== "undefined" ? instrTxt : null, typeof fartCountTxt !== "undefined" ? fartCountTxt : null, typeof fartPerClickTxt !== "undefined" ? fartPerClickTxt : null, typeof comboTxt !== "undefined" ? comboTxt : null, typeof shopBtn !== "undefined" ? shopBtn : null, typeof prestigeBtn !== "undefined" ? prestigeBtn : null, typeof challengeTxt !== "undefined" ? challengeTxt : null, typeof prestigeTxt !== "undefined" ? prestigeTxt : null, typeof achievementsBtn !== "undefined" ? achievementsBtn : null, typeof leaderboardBtn !== "undefined" ? leaderboardBtn : null, typeof updateLogBtn !== "undefined" ? updateLogBtn : null]; for (var i = 0; i < toHide.length; ++i) { if (toHide[i] && toHide[i].parent) { tween(toHide[i], { alpha: 0 }, { duration: 600, onFinish: function (obj) { if (obj.parent) obj.parent.removeChild(obj); }.bind(null, toHide[i]) }); } } // Fade out all particles/floating texts if (typeof floatingTexts !== "undefined" && floatingTexts) { for (var i = (floatingTexts || []).length - 1; i >= 0; --i) { if (floatingTexts[i] && floatingTexts[i].parent) tween(floatingTexts[i], { alpha: 0 }, { duration: 400, onFinish: function (obj) { if (obj.parent) obj.parent.removeChild(obj); }.bind(null, floatingTexts[i]) }); } } if (typeof particles !== "undefined" && particles) { for (var i = (particles || []).length - 1; i >= 0; --i) { if (particles[i] && particles[i].parent) tween(particles[i], { alpha: 0 }, { duration: 400, onFinish: function (obj) { if (obj.parent) obj.parent.removeChild(obj); }.bind(null, particles[i]) }); } } // Dramatic background game.setBackgroundColor(0x1a0033); // Portal visual (giant glowing ellipse) var portalBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 10, x: 2048 / 2, y: 2732 / 2, tint: 0x7e3ff2, alpha: 0.85 }); portal.addChild(portalBg); // Portal swirl (rotating) var portalSwirl = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 7.5, scaleY: 7.5, x: 2048 / 2, y: 2732 / 2, tint: 0xffffff, alpha: 0.18 }); portal.addChild(portalSwirl); // Portal title var portalTitle = new Text2("THE GRAND PORTAL", { size: 160, fill: 0xffe066, align: 'center' }); portalTitle.anchor.set(0.5, 0.5); portalTitle.x = 2048 / 2; portalTitle.y = 700; portal.addChild(portalTitle); // Portal subtitle var portalSub = new Text2("You have reached the end.\nWill you step through?", { size: 80, fill: 0xffffff, align: 'center' }); portalSub.anchor.set(0.5, 0.5); portalSub.x = 2048 / 2; portalSub.y = 900; portal.addChild(portalSub); // Portal dog (floating, glowing) var portalDog = LK.getAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2, x: 2048 / 2, y: 1500, tint: 0xffffff }); portal.addChild(portalDog); // Portal dog glow var portalDogGlow = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5, x: 2048 / 2, y: 1500, tint: 0xffe066, alpha: 0.25 }); portal.addChild(portalDogGlow); // Portal swirling animation portal.update = function () { portalSwirl.rotation += 0.03; portalDogGlow.alpha = 0.18 + Math.sin(LK.ticks / 30) * 0.12; portalDog.y = 1500 + Math.sin(LK.ticks / 20) * 30; }; if (!portal._updateAttached) { var _oldPortalGameUpdate = game.update; game.update = function () { _oldPortalGameUpdate && _oldPortalGameUpdate(); if (window._grandPortalContainer && window._grandPortalContainer.update) { window._grandPortalContainer.update(); } }; portal._updateAttached = true; } // Step Through button var stepBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 1.3, x: 2048 / 2, y: 2100, tint: 0x83de44 }); var stepTxt = new Text2("Step Through", { size: 110, fill: 0xffffff, align: 'center' }); stepTxt.anchor.set(0.5, 0.5); stepTxt.x = 0; stepTxt.y = 0; stepBtn.addChild(stepTxt); stepBtn.interactive = true; stepBtn.down = function () { // Dramatic flash LK.effects.flashScreen(0xffffff, 800); // Fade out portal, fade in ending tween(portal, { alpha: 0 }, { duration: 900, onFinish: function onFinish() { if (portal.parent) portal.parent.removeChild(portal); if (typeof showGrandEnding === "function") { showGrandEnding(); } } }); }; portal.addChild(stepBtn); // Refuse button var refuseBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2300, tint: 0xcd544e }); var refuseTxt = new Text2("Refuse", { size: 90, fill: 0xffffff, align: 'center' }); refuseTxt.anchor.set(0.5, 0.5); refuseTxt.x = 0; refuseTxt.y = 0; refuseBtn.addChild(refuseTxt); refuseBtn.interactive = true; refuseBtn.down = function () { // Fade out portal, restore game tween(portal, { alpha: 0 }, { duration: 700, onFinish: function onFinish() { if (portal.parent) portal.parent.removeChild(portal); // Restore UI/game elements for (var i = 0; i < toHide.length; ++i) { if (toHide[i] && !toHide[i].parent) { toHide[i].alpha = 1; game.addChild(toHide[i]); } } if (typeof updateUI === "function") updateUI(); } }); }; portal.addChild(refuseBtn); }; // === GRAND ENDING: The True Ending === function showGrandEnding() { var ending = new Container(); game.addChild(ending); // Fade in white var whiteBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20, x: 2048 / 2, y: 2732 / 2, tint: 0xffffff, alpha: 1 }); ending.addChild(whiteBg); tween(whiteBg, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { whiteBg.alpha = 0; } }); // Ending text var endTxt = new Text2("You and your dog have ascended.\n\nAll farts, all bones, all walks...\n\nIt was about love, joy, and laughter.\n\nThank you for playing.", { size: 90, fill: 0x2D2D2D, align: 'center' }); endTxt.anchor.set(0.5, 0.5); endTxt.x = 2048 / 2; endTxt.y = 900; ending.addChild(endTxt); // Dog and player together var endDog = LK.getAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2, x: 2048 / 2 - 200, y: 1700, tint: 0xffffff }); ending.addChild(endDog); var endPerson = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, x: 2048 / 2 + 200, y: 1700, tint: 0x222222 }); ending.addChild(endPerson); // Final thanks var thanksTxt = new Text2("THE END", { size: 160, fill: 0x7e3ff2, align: 'center' }); thanksTxt.anchor.set(0.5, 0.5); thanksTxt.x = 2048 / 2; thanksTxt.y = 2200; ending.addChild(thanksTxt); // Restart button var restartBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2450, tint: 0x83de44 }); var restartTxt = new Text2("Play Again", { size: 90, fill: 0xffffff, align: 'center' }); restartTxt.anchor.set(0.5, 0.5); restartTxt.x = 0; restartTxt.y = 0; restartBtn.addChild(restartTxt); restartBtn.interactive = true; restartBtn.down = function () { // Remove ending, reset game state, restore everything if (ending.parent) ending.parent.removeChild(ending); // Reset progress, but keep achievements and bones fartCount = 0; fartPerClick = 1; dogHunger = 100; isDead = false; for (var i = 0; i < upgradesBought.length; i++) upgradesBought[i] = 0; for (var i = 0; i < autoClickersBought.length; i++) autoClickersBought[i] = 0; for (var i = 0; i < autoClickerTimers.length; i++) { if (autoClickerTimers[i]) { LK.clearInterval(autoClickerTimers[i]); autoClickerTimers[i] = null; } } chefBought = false; if (chefTimer) { LK.clearInterval(chefTimer); chefTimer = null; } storage.dogHunger = 100; storage.chefBought = false; // Restore UI/game elements var toRestore = [dogFace, fartBtn, walkBtn, hatStore, foodStore, foodStoreMinBtn, hungerBar, shareBtn, autismModeBtn, instrTxt, fartCountTxt, fartPerClickTxt, comboTxt, shopBtn, prestigeBtn, challengeTxt, prestigeTxt, achievementsBtn, leaderboardBtn, updateLogBtn]; for (var i = 0; i < toRestore.length; ++i) { if (toRestore[i] && !toRestore[i].parent) { toRestore[i].alpha = 1; game.addChild(toRestore[i]); } } updateUI && updateUI(); game.setBackgroundColor(0xE3F6FF); window._grandPortalContainer = null; window._grandPortalShown = false; }; ending.addChild(restartBtn); // Subtle fade in ending.alpha = 0; tween(ending, { alpha: 1 }, { duration: 900 }); } // --- Fun: Achievement for buying Chris the Cat --- if (!window._chrisCatAchievement && chrisCatSpawned && !isShowingAchievement) { window._chrisCatAchievement = true; isShowingAchievement = true; var achPopup = new Container(); var achBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2732 / 2 }); achPopup.addChild(achBg); var achTxt = new Text2('Achievement Unlocked!\nChris the Cat!\nFeline Fart Power!', { size: 80, fill: 0x7A5C00, align: 'center' }); achTxt.anchor.set(0.5, 0.5); achTxt.x = 2048 / 2; achTxt.y = 2732 / 2 - 40; achPopup.addChild(achTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(achPopup); isShowingAchievement = false; }; achPopup.addChild(okBtn); game.addChild(achPopup); LK.effects.flashObject(achBg, 0xfff7b2, 120); } // --- Fun: Achievement for buying John the Booster --- if (!window._johnAchievement && johnSpawned && !isShowingAchievement) { window._johnAchievement = true; isShowingAchievement = true; var achPopup = new Container(); var achBg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 1.1, x: 2048 / 2, y: 2732 / 2 }); achPopup.addChild(achBg); var achTxt = new Text2('Achievement Unlocked!\nJohn the Booster!\nFart Power Overload!', { size: 80, fill: 0x7A5C00, align: 'center' }); achTxt.anchor.set(0.5, 0.5); achTxt.x = 2048 / 2; achTxt.y = 2732 / 2 - 40; achPopup.addChild(achTxt); var okBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 120 }); var okTxt = new Text2('OK', { size: 70, fill: 0x7A5C00 }); okTxt.anchor.set(0.5, 0.5); okTxt.x = 0; okTxt.y = 0; okBtn.addChild(okTxt); okBtn.interactive = true; okBtn.down = function () { game.removeChild(achPopup); isShowingAchievement = false; }; achPopup.addChild(okBtn); game.addChild(achPopup); LK.effects.flashObject(achBg, 0xfff7b2, 120); } }; // Make the button big and easy to tap: handle press anywhere on the button fartBtn.interactive = true; // --- Auto Clicker Upgrades --- // Each auto clicker has: label, base cost, cost multiplier, interval (ms), amount per tick var autoClickers = [{ label: "Auto 1s", base: 100, mult: 1.18, interval: 1000, amount: 1 }, { label: "Auto 0.5s", base: 500, mult: 1.22, interval: 500, amount: 2 }, { label: "Auto 0.2s", base: 2000, mult: 1.28, interval: 200, amount: 5 }]; var autoClickersBought = [0, 0, 0]; var autoClickerTimers = [null, null, null]; // --- UI for Auto Clickers --- var autoClickerButtons = []; var autoClickerTxts = []; var autoClickerCostTxts = []; var autoClickerYStart = upgradeYStart + upgrades.length * upgradeSpacing + 80; var autoClickerSpacing = 120; for (var i = 0; i < autoClickers.length; ++i) { var btn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 400, y: autoClickerYStart + i * autoClickerSpacing }); btn.interactive = true; var txt = new Text2(autoClickers[i].label, { size: 60, fill: 0x7A5C00 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = -20; btn.addChild(txt); var costTxt = new Text2('', { size: 44, fill: 0x444444 }); costTxt.anchor.set(0.5, 0.5); costTxt.x = 0; costTxt.y = 50; btn.addChild(costTxt); game.addChild(btn); btn.visible = false; autoClickerButtons.push(btn); autoClickerTxts.push(txt); autoClickerCostTxts.push(costTxt); } // --- Helper: Calculate auto clicker cost --- function getAutoClickerCost(idx) { var ac = autoClickers[idx]; var n = autoClickersBought[idx]; return Math.floor(ac.base * Math.pow(ac.mult, n)); } // --- Update UI: add auto clickers --- var _oldUpdateUI = updateUI; updateUI = function updateUI() { _oldUpdateUI(); for (var i = 0; i < autoClickers.length; ++i) { var cost = getAutoClickerCost(i); autoClickerCostTxts[i].setText('Cost: ' + cost + ' | Owned: ' + autoClickersBought[i]); if (fartCount >= cost) { autoClickerButtons[i].alpha = 1; } else { autoClickerButtons[i].alpha = 0.5; } } }; // --- Shop toggle: show/hide auto clickers too --- var _oldShopBtnDown = shopBtn.down; shopBtn.down = function (x, y, obj) { _oldShopBtnDown(x, y, obj); for (var i = 0; i < autoClickerButtons.length; ++i) { autoClickerButtons[i].visible = shopVisible; } }; // Weekly challenge target adjusted by prestige level weeklyChallenge.target = 50000 + prestigeLevel * 10000; weeklyChallenge.progress = storage.weeklyProgress || 0; weeklyChallenge.completed = storage.weeklyCompleted || false; weeklyChallenge.timeLeft = storage.weeklyTimeLeft || 7 * 24 * 60 * 60 * 1000; // --- Streak System --- var loginStreak = storage.loginStreak || 0; var lastLoginDate = storage.lastLoginDate || null; // Check login streak var today = new Date().toDateString(); if (lastLoginDate !== today) { var yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); if (lastLoginDate === yesterday.toDateString()) { loginStreak++; } else if (lastLoginDate !== today) { loginStreak = 1; } storage.lastLoginDate = today; storage.loginStreak = loginStreak; // Streak bonus if (loginStreak > 1) { var streakBonus = loginStreak * 100; fartCount += streakBonus; createFloatingText(2048 / 2, 1300, "Login Streak x" + loginStreak + "!\n+" + streakBonus + " Farts!", 0xffd700); } } // --- Auto Clicker Button Handlers --- for (var i = 0; i < autoClickers.length; ++i) { (function (idx) { autoClickerButtons[idx].down = function (x, y, obj) { var cost = getAutoClickerCost(idx); if (fartCount >= cost) { fartCount -= cost; autoClickersBought[idx]++; updateUI(); LK.effects.flashObject(autoClickerButtons[idx], 0xeeeecc, 120); // Level up celebration for every 5th purchase if (autoClickersBought[idx] % 5 === 0) { createParticleExplosion(autoClickerButtons[idx].x, autoClickerButtons[idx].y, 0xffd700, 20); createFloatingText(autoClickerButtons[idx].x, autoClickerButtons[idx].y - 100, "LEVEL UP!", 0xffd700); LK.effects.flashScreen(0xffd700, 300); } // If this is the first purchase, start the timer if (autoClickersBought[idx] === 1) { autoClickerTimers[idx] = LK.setInterval(function () { // Each auto clicker tick: add (amount * owned * fartPerClick) to fartCount fartCount += autoClickers[idx].amount * autoClickersBought[idx] * fartPerClick; updateUI(); // Fun: dog reacts every time dogFace.react(); // Dog says a random synonym for 'gross' (same as fartBtn.down) if (!dogFace.speechBubble) { // Create speech bubble if not already present var bubble = new Text2('', { size: 90, fill: 0xffffff, stroke: 0x222222, strokeThickness: 8, wordWrap: true, wordWrapWidth: 600, align: 'center' }); bubble.anchor.set(0.5, 1); bubble.x = 0; bubble.y = -420; bubble.alpha = 0; dogFace.addChild(bubble); dogFace.speechBubble = bubble; } // Check if dog is wearing the top hat (fancy mode) var isWearingTopHat = false; if (hatStore && hatStore.equippedHat) { isWearingTopHat = true; } var grossWords; if (isWearingTopHat) { // Fancy synonyms for gross while wearing top hat grossWords = ["Absolutely abhorrent!", "Utterly reprehensible!", "Quite unsavory!", "Most disagreeable!", "Thoroughly distasteful!", "Decidedly unpalatable!", "Exceedingly offensive!", "Remarkably repugnant!", "Profoundly disturbing!", "Extraordinarily vile!", "Supremely loathsome!", "Undeniably detestable!", "Monumentally revolting!", "Categorically objectionable!", "Fundamentally deplorable!", "Intrinsically nauseating!", "Quintessentially abominable!", "Indubitably repulsive!", "Unquestionably offensive!", "Irrefutably disgusting!", "Good heavens!", "My word!", "How unseemly!", "Quite dreadful!", "Most unbecoming!", "Rather appalling!", "Terribly vulgar!", "Frightfully crude!", "Awfully uncouth!", "Shockingly improper!", "Disgracefully crass!", "Regrettably tactless!", "Lamentably coarse!", "Woefully inappropriate!", "Deplorably unrefined!", "Insufferably boorish!", "Intolerably barbaric!", "Unacceptably gauche!", "Abhorrently uncivilized!", "Contemptibly lowbrow!"]; } else { // Regular gross words for normal mode grossWords = ["Yuck!", "Ew!", "Disgusting!", "Nasty!", "Foul!", "Repulsive!", "Stinky!", "Revolting!", "Pee-yew!", "Ugh!", "Gross!", "Barf!", "Ick!", "Putrid!", "Rank!", "Vile!", "Sickening!", "Odious!", "No way!", "Bleh!", "Cringe!", "Yikes!", "Gag!", "Pungent!", "Awful!", "Horrid!", "Stench!", "What is that?!", "Oh no!", "Why?!", "Ewww!", "Yeesh!", "Blech!", "GROSS!", "Noxious!", "Obnoxious!", "Yowza!", "Oof!", "Gnar!", "Yow!", "Eek!", "Yowch!", "Ooze!", "Funky!", "Rancid!", "Rotten!", "Whew!", "Stank!", "Phew!", "GROSS-out!", // More synonyms "Repugnant!", "Skunky!", "Malodorous!", "Putrescent!", "Fetid!", "Mephitic!", "Moldy!", "Dank!", "Manky!", "Cruddy!", "Crud!", "Yuuuck!", "Ew, dude!", "Stale!", "Funky town!", "Reek!", "Stale cheese!", "Cheesy!", "Mold!", "Ew, stinky!", "Ew, gross!", "Ew, nasty!", "Ew, barf!", "Ew, icky!", "Ew, yuck!", "Ew, blech!", "Ew, pew!", "Ew, phew!", "Ew, stank!", "Ew, rotten!", "Ew, rancid!", "Ew, vile!", "Ew, sick!", "Ew, odious!", "Ew, horrid!", "Ew, foul!", "Ew, revolting!", "Ew, repulsive!", "Ew, stench!", "Ew, noxious!", "Ew, obnoxious!", "Ew, gnarly!", "Ew, yowza!", "Ew, oof!", "Ew, yow!", "Ew, eek!", "Ew, yowch!", "Ew, ooze!", "Ew, funky!", "Ew, whew!", "Ew, gross-out!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, yeesh!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, awful!", "Ew, stank!", "Ew, phew!", "Ew, barf!", "Ew, ick!", "Ew, putrid!", "Ew, rank!", "Ew, vile!", "Ew, sickening!", "Ew, odious!", "Ew, bleh!", "Ew, gross!", "Ew, stench!", "Ew, no way!", "Ew, yuck!", "Ew, ewww!", "Ew, blech!", "Ew, GROSS!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, horrid!", "Ew, stench!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, yeesh!", "Ew, yikes!", "Ew, cringe!", "Ew, gag!", "Ew, pungent!", "Ew, awful!", "Ew, horrid!", "Ew, stench!", "Ew, what is that?!", "Ew, oh no!", "Ew, why?!", "Ew, ewww!", "Ew, yeesh!", "Ew, blech!", "Ew, GROSS!", "Ew, noxious!", "Ew, obnoxious!", "Ew, yowza!", "Ew, oof!", "Ew, gnar!", "Ew, yow!", "Ew, eek!", "Ew, yowch!", "Ew, ooze!", "Ew, funky!", "Ew, rancid!", "Ew, rotten!", "Ew, whew!", "Ew, stank!", "Ew, phew!", "Ew, GROSS-out!"]; } var word = grossWords[Math.floor(Math.random() * grossWords.length)]; dogFace.speechBubble.setText(word); dogFace.speechBubble.alpha = 1; tween(dogFace.speechBubble, { alpha: 0 }, { duration: 900, delay: 500, easing: tween.cubicIn }); // Dog teleports to center and stops sliding for a moment dogFace.x = 2048 / 2; dogFace.lastX = dogFace.x; LK.getSound('fart_snd').play(); }, autoClickers[idx].interval); } } }; })(i); } // --- Simple Click Counter Button --- // (Removed: click counter button and handler, as clicks are now counted via the FART button); // --- Social Competition Features --- var dailyLeaderboard = [{ name: "You", score: fartCount, prestige: prestigeLevel }, { name: "FartMaster", score: 2500000 + Math.floor(Math.random() * 500000), prestige: 5 }, { name: "GoldenDog", score: 1800000 + Math.floor(Math.random() * 400000), prestige: 4 }, { name: "ComboKing", score: 1200000 + Math.floor(Math.random() * 300000), prestige: 3 }, { name: "ChrisFan", score: 900000 + Math.floor(Math.random() * 200000), prestige: 2 }, { name: "JohnLover", score: 600000 + Math.floor(Math.random() * 150000), prestige: 1 }, { name: "NewPlayer", score: 100000 + Math.floor(Math.random() * 50000), prestige: 0 }]; // Sort leaderboard dailyLeaderboard.sort(function (a, b) { if (a.prestige !== b.prestige) return b.prestige - a.prestige; return b.score - a.score; }); // Add leaderboard button var leaderboardBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: 2048 - 400, y: 2732 - 350 }); var leaderboardBtnTxt = new Text2('Leaderboard', { size: 54, fill: 0x7A5C00 }); leaderboardBtnTxt.anchor.set(0.5, 0.5); leaderboardBtnTxt.x = 0; leaderboardBtnTxt.y = 0; leaderboardBtn.addChild(leaderboardBtnTxt); leaderboardBtn.interactive = true; game.addChild(leaderboardBtn); leaderboardBtn.down = function () { // Update your score in leaderboard dailyLeaderboard[0] = { name: "You", score: fartCount, prestige: prestigeLevel }; dailyLeaderboard.sort(function (a, b) { if (a.prestige !== b.prestige) return b.prestige - a.prestige; return b.score - a.score; }); // Show leaderboard popup (similar to viral challenge) var popup = new Container(); var bg = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 7.5, scaleY: 7.5, x: 2048 / 2, y: 2732 / 2 }); popup.addChild(bg); var title = new Text2('Daily Leaderboard', { size: 80, fill: 0xff8000, align: 'center' }); title.anchor.set(0.5, 0.5); title.x = 2048 / 2; title.y = 2732 / 2 - 320; popup.addChild(title); for (var i = 0; i < Math.min(7, dailyLeaderboard.length); i++) { var entry = dailyLeaderboard[i]; var rankColor = entry.name === "You" ? 0x83de44 : 0x7A5C00; var entryTxt = new Text2(i + 1 + ". " + entry.name + " - " + entry.score + " farts (P" + entry.prestige + ")", { size: 54, fill: rankColor, align: 'left' }); entryTxt.anchor.set(0.5, 0.5); entryTxt.x = 2048 / 2; entryTxt.y = 2732 / 2 - 200 + i * 60; popup.addChild(entryTxt); } var closeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 280 }); var closeTxt = new Text2('Close', { size: 70, fill: 0x7A5C00 }); closeTxt.anchor.set(0.5, 0.5); closeTxt.x = 0; closeTxt.y = 0; closeBtn.addChild(closeTxt); closeBtn.interactive = true; closeBtn.down = function () { game.removeChild(popup); }; popup.addChild(closeBtn); game.addChild(popup); }; // --- Special Milestone Celebrations --- if (fartCount > 0 && fartCount % 100000 === 0) { // Major milestone celebration createFloatingText(2048 / 2, 1300, "MAJOR MILESTONE!\n" + fartCount + " FARTS!\nYou're a legend!", 0xffd700); // Fireworks effect for (var f = 0; f < 15; f++) { (function (index) { LK.setTimeout(function () { createParticleExplosion(400 + Math.random() * 1200, 400 + Math.random() * 800, [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff][index % 6], 25); }, index * 100); })(f); } LK.effects.flashScreen(0xffffff, 500); } // --- Leaderboard Button removed ---; // --- Achievements List UI --- // Define all achievements with their unlock condition and description var achievements = [{ key: "first100Farts", name: "First 100 Farts", desc: "Reach 100 farts.", unlocked: function unlocked() { return fartCount >= 100 || !!window._first100FartsShown; } }, { key: "first1000Farts", name: "Fart Legend", desc: "Reach 1,000 farts.", unlocked: function unlocked() { return fartCount >= 1000 || !!window._first1000FartsShown; } }, { key: "first10kFarts", name: "Fart GOD", desc: "Reach 10,000 farts.", unlocked: function unlocked() { return fartCount >= 10000 || !!window._first10kFartsShown; } }, { key: "first1MFarts", name: "Fart Heaven", desc: "Reach 1,000,000 farts.", unlocked: function unlocked() { return fartCount >= 1000000 || !!window._first1MFartsShown; } }, { key: "dogTeleport", name: "Dog Teleport", desc: "Make the dog run away (hit left edge).", unlocked: function unlocked() { return !!window._firstDogTeleport; } }, { key: "chrisCat", name: "Chris the Cat", desc: "Buy Chris the Cat upgrade.", unlocked: function unlocked() { return chrisCatSpawned || !!window._chrisCatAchievement; } }, { key: "johnBooster", name: "John the Booster", desc: "Buy John the Booster upgrade.", unlocked: function unlocked() { return johnSpawned || !!window._johnAchievement; } }, { key: "comboMaster", name: "Combo Master", desc: "Reach a 50x combo.", unlocked: function unlocked() { return !!window._combo50Achievement; } }, { key: "megaCombo", name: "Mega Combo", desc: "Reach a 100x combo.", unlocked: function unlocked() { return !!window._combo100Achievement; } }, { key: "goldenFart", name: "Golden Discovery", desc: "Get your first golden fart.", unlocked: function unlocked() { return !!window._goldenFartAchievement; } }, { key: "rainbowFart", name: "Rainbow Magic", desc: "Get your first rainbow fart.", unlocked: function unlocked() { return !!window._rainbowFartAchievement; } }, { key: "boneCollector", name: "Bone Collector", desc: "Collect 10 bones during dog walks.", unlocked: function unlocked() { // Check both window._bonesCollected and storage.bones for robustness return (window._bonesCollected || 0) >= 10 || typeof storage.bones === "number" && storage.bones >= 10; } }, { key: "poopCleaner", name: "Poop Cleaner", desc: "Clean up 20 dog poops.", unlocked: function unlocked() { return (window._poopsCleaned || 0) >= 20; } }, { key: "prestigeMaster", name: "Prestige Master", desc: "Reach prestige level 5.", unlocked: function unlocked() { return prestigeLevel >= 5; } }, { key: "autismChampion", name: "Autism Champion", desc: "Fart 1000 times in autism mode.", unlocked: function unlocked() { return (window._autismModeFarts || 0) >= 1000; } }, { key: "feedingExpert", name: "Feeding Expert", desc: "Feed the dog 100 times.", unlocked: function unlocked() { return (window._dogFeedCount || 0) >= 100; } }, { key: "chefHired", name: "Chef Hired", desc: "Buy the auto chef.", unlocked: function unlocked() { return chefBought || !!storage.chefBought; } }, { key: "hatCollector", name: "Hat Collector", desc: "Buy your first hat.", unlocked: function unlocked() { return !!window._firstHatBought; } }, { key: "speedClicker", name: "Speed Clicker", desc: "Click 10 times in 2 seconds.", unlocked: function unlocked() { return !!window._speedClickAchievement; } }, { key: "dogNapper", name: "Dog Napper", desc: "Witness the dog napping 10 times.", unlocked: function unlocked() { return (window._dogNapCount || 0) >= 10; } }, { key: "dailyPlayer", name: "Daily Player", desc: "Login for 7 days in a row.", unlocked: function unlocked() { return loginStreak >= 7; } }, { key: "powerUpKing", name: "Power-Up King", desc: "Have 3 power-ups active at once.", unlocked: function unlocked() { return !!window._threePowerUpsAchievement; } }, { key: "weeklyChampion", name: "Weekly Champion", desc: "Complete a weekly challenge.", unlocked: function unlocked() { return weeklyChallenge.completed || !!storage.weeklyCompleted; } }]; // --- Helper: Check if all achievements except dog teleport are unlocked --- // Ensure achievements is defined before this function is used function allAchievementsExceptDogTeleportUnlocked() { if (typeof achievements === "undefined" || !achievements) return false; // dogTeleport is removed, so check all others for (var i = 0; i < achievements.length; ++i) { if (achievements[i].key === "dogTeleport") continue; if (!achievements[i].unlocked()) return false; } return true; } // Achievements list popup container (hidden by default) var achievementsPopup = null; // Achievements button (bottom left, out of dog's way) var achievementsBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, // Move up and right from the very bottom left, so it doesn't overlap food store or menu x: 180, y: 2732 - 400 }); var achievementsBtnTxt = new Text2('Achievements', { size: 54, fill: 0x7A5C00 }); achievementsBtnTxt.anchor.set(0.5, 0.5); achievementsBtnTxt.x = 0; achievementsBtnTxt.y = 0; achievementsBtn.addChild(achievementsBtnTxt); achievementsBtn.interactive = true; game.addChild(achievementsBtn); // Show/hide achievements popup achievementsBtn.down = function () { if (isShowingAchievement) { return; } if (achievementsPopup && achievementsPopup.parent) { game.removeChild(achievementsPopup); return; } if (achievementsPopup) { game.addChild(achievementsPopup); updateAchievementsList(); return; } // Create popup achievementsPopup = new Container(); var bg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.7, x: 2048 / 2, y: 2732 / 2 }); achievementsPopup.addChild(bg); var title = new Text2('Achievements', { size: 90, fill: 0x7A5C00, align: 'center' }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 2732 / 2 - 540; achievementsPopup.addChild(title); // --- SCROLLABLE LIST CONTAINER --- var listContainer = new Container(); listContainer.x = 0; listContainer.y = 0; achievementsPopup.addChild(listContainer); // List container Y start and row height var listY = 2732 / 2 - 400; var rowHeight = 120; achievementsPopup.achRows = []; for (var i = 0; i < achievements.length; ++i) { var ach = achievements[i]; var row = new Container(); row.x = 2048 / 2 - 500; row.y = listY + i * rowHeight; var status = new Text2('', { size: 60, fill: 0x7A5C00 }); status.anchor.set(0, 0.5); status.x = 0; status.y = 0; row.status = status; row.addChild(status); var name = new Text2(ach.name, { size: 60, fill: 0x222222 }); name.anchor.set(0, 0.5); name.x = 90; name.y = 0; row.addChild(name); var desc = new Text2(ach.desc, { size: 38, fill: 0x444444 }); desc.anchor.set(0, 0.5); desc.x = 90; desc.y = 38; row.addChild(desc); listContainer.addChild(row); achievementsPopup.achRows.push(row); } // --- SCROLL LOGIC --- var maxVisibleRows = 7; var totalRows = achievements.length; var visibleHeight = maxVisibleRows * rowHeight; var minY = listY; var maxY = listY + Math.max(0, (totalRows - maxVisibleRows) * rowHeight); listContainer.y = 0; achievementsPopup._scrollOffset = 0; achievementsPopup._dragStartY = null; achievementsPopup._dragLastY = null; achievementsPopup.interactive = true; achievementsPopup.down = function (x, y, obj) { achievementsPopup._dragStartY = y; achievementsPopup._dragLastY = y; achievementsPopup._startScrollOffset = achievementsPopup._scrollOffset; }; achievementsPopup.move = function (x, y, obj) { if (achievementsPopup._dragStartY !== null) { var dy = y - achievementsPopup._dragLastY; achievementsPopup._dragLastY = y; achievementsPopup._scrollOffset += dy; // Clamp scroll if (achievementsPopup._scrollOffset > 0) achievementsPopup._scrollOffset = 0; if (achievementsPopup._scrollOffset < -(maxY - minY)) achievementsPopup._scrollOffset = -(maxY - minY); listContainer.y = achievementsPopup._scrollOffset; } }; achievementsPopup.up = function (x, y, obj) { achievementsPopup._dragStartY = null; achievementsPopup._dragLastY = null; }; // Close button var closeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 600 }); var closeTxt = new Text2('Close', { size: 70, fill: 0x7A5C00 }); closeTxt.anchor.set(0.5, 0.5); closeTxt.x = 0; closeTxt.y = 0; closeBtn.addChild(closeTxt); closeBtn.interactive = true; closeBtn.down = function () { game.removeChild(achievementsPopup); isShowingAchievement = false; }; achievementsPopup.addChild(closeBtn); game.addChild(achievementsPopup); isShowingAchievement = true; updateAchievementsList(); }; // Helper to update achievements list UI function updateAchievementsList() { if (!achievementsPopup || !achievementsPopup.achRows) return; for (var i = 0; i < achievements.length; ++i) { var ach = achievements[i]; var row = achievementsPopup.achRows[i]; // Remove old background if present if (row.achBg) { row.removeChild(row.achBg); row.achBg = null; } // Add red square background behind status icon var achBg = LK.getAsset('person_leg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, x: 30, y: 0, tint: 0xd83318 // strong red }); row.addChildAt(achBg, 0); row.achBg = achBg; if (ach.unlocked()) { row.status.setText("✔️"); row.status.fill = 0x83de44; row.alpha = 1; } else { row.status.setText("❌"); row.status.fill = 0xcd544e; row.alpha = 0.5; } } } // Update achievements list UI whenever UI updates var _oldUpdateUI_ach = updateUI; updateUI = function updateUI() { _oldUpdateUI_ach(); updateAchievementsList(); }; // --- Prestige System Variables --- var prestigeLevel = storage.prestigeLevel || 0; var prestigePoints = storage.prestigePoints || 0; var prestigeMultiplier = 1 + prestigeLevel * 0.5; // 50% bonus per prestige // --- Prestige Button --- var prestigeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: 2048 / 2, y: 250 }); var prestigeBtnTxt = new Text2('PRESTIGE\n(Reset for Bonus)', { size: 60, fill: 0xff4444, align: 'center' }); prestigeBtnTxt.anchor.set(0.5, 0.5); prestigeBtnTxt.x = 0; prestigeBtnTxt.y = 0; prestigeBtn.addChild(prestigeBtnTxt); prestigeBtn.interactive = true; game.addChild(prestigeBtn); prestigeBtn.down = function () { if (fartCount >= 1000000) { // Can only prestige with 1M+ farts var newPrestigePoints = Math.floor(fartCount / 100000); prestigePoints += newPrestigePoints; prestigeLevel++; // Reset progress but keep prestige bonuses fartCount = 0; fartPerClick = 1; for (var i = 0; i < upgradesBought.length; i++) { upgradesBought[i] = 0; } for (var i = 0; i < autoClickersBought.length; i++) { autoClickersBought[i] = 0; if (autoClickerTimers[i]) { LK.clearInterval(autoClickerTimers[i]); autoClickerTimers[i] = null; } } // Apply prestige multiplier prestigeMultiplier = 1 + prestigeLevel * 0.5; // Save to storage storage.prestigeLevel = prestigeLevel; storage.prestigePoints = prestigePoints; // Celebration LK.effects.flashScreen(0xffd700, 1000); createFloatingText(2048 / 2, 1400, "PRESTIGE LEVEL " + prestigeLevel + "!\n+" + newPrestigePoints + " Prestige Points!", 0xffd700); updateUI(); } }; // --- Weekly Challenge Display (moved earlier to prevent undefined error) --- // Update Log Button and Popup --- var updateLogBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: 2048 - 180, // Bottom right, near share button y: 2732 - 220 }); var updateLogBtnTxt = new Text2('Update Log', { size: 54, fill: 0x7A5C00 }); updateLogBtnTxt.anchor.set(0.5, 0.5); updateLogBtnTxt.x = 0; updateLogBtnTxt.y = 0; updateLogBtn.addChild(updateLogBtnTxt); updateLogBtn.interactive = true; game.addChild(updateLogBtn); // --- Music Control Button --- var musicPlaying = true; var musicBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.45, scaleY: 0.45, x: 180, y: 2732 - 120 }); var musicBtnTxt = new Text2('Music: ON', { size: 50, fill: 0x7A5C00 }); musicBtnTxt.anchor.set(0.5, 0.5); musicBtnTxt.x = 0; musicBtnTxt.y = 0; musicBtn.addChild(musicBtnTxt); musicBtn.interactive = true; musicBtn.down = function () { musicPlaying = !musicPlaying; if (musicPlaying) { LK.playMusic('relaxing_piano', { loop: true, fade: { start: 0, end: 0.3, duration: 1000 } }); musicBtnTxt.setText('Music: ON'); musicBtnTxt.fill = 0x7A5C00; } else { LK.stopMusic(); musicBtnTxt.setText('Music: OFF'); musicBtnTxt.fill = 0x888888; } LK.effects.flashObject(musicBtn, 0xfff7b2, 120); }; game.addChild(musicBtn); var updateLogPopup = null; var updateLogEntries = ["v1.0: Initial Release!", "v1.1: Added dog reactions and fart sound.", "v1.2: Implemented basic clicker functionality.", "v1.3: Added fart button and UI.", "v1.4: Added sliding dog and teleport.", "v1.5: Added Person standing and recording.", "v1.6: Introduced achievements.", "v1.7: Added particle system and floating text.", "v1.8: Added combo system and UI.", "v1.9: Implemented screen shake.", "v2.0: Added Mega Fart special effect.", "v2.1: Introduced power-up system.", "v2.2: Added daily reward.", "v2.3: Implemented upgrade shop.", "v2.4: Added Auto Clicker upgrades.", "v2.5: Added Chris the Cat upgrade and special effect.", "v2.6: Added John the Booster upgrade and effect.", "v2.7: Added Autism Mode with chaos effects.", "v2.8: Added social share/viral challenge popup.", "v2.9: Added achievement list UI.", "v3.0: Minor bug fixes and performance improvements."]; updateLogBtn.down = function () { if (updateLogPopup && updateLogPopup.parent) { game.removeChild(updateLogPopup); return; } if (updateLogPopup) { game.addChild(updateLogPopup); return; } updateLogPopup = new Container(); var bg = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.7, x: 2048 / 2, y: 2732 / 2 }); updateLogPopup.addChild(bg); var title = new Text2('Update Log', { size: 90, fill: 0x7A5C00, align: 'center' }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 2732 / 2 - 540; updateLogPopup.addChild(title); // --- SCROLLABLE LIST CONTAINER --- var listContainer = new Container(); listContainer.x = 2048 / 2 - 500; // Align left edge of the text listContainer.y = 2732 / 2 - 400; updateLogPopup.addChild(listContainer); var rowHeight = 60; // Smaller row height for log entries updateLogPopup.logRows = []; for (var i = 0; i < updateLogEntries.length; ++i) { var entry = updateLogEntries[i]; var row = new Container(); row.y = i * rowHeight; var entryTxt = new Text2(entry, { size: 54, fill: 0x222222, align: 'left' }); entryTxt.anchor.set(0, 0.5); // Anchor left center entryTxt.x = 0; entryTxt.y = 0; row.addChild(entryTxt); listContainer.addChild(row); updateLogPopup.logRows.push(row); } // --- SCROLL LOGIC --- var maxVisibleRows = 10; // Adjust based on the log length var totalRows = updateLogEntries.length; var visibleHeight = maxVisibleRows * rowHeight; var minY = 2732 / 2 - 400; // Start Y of the list container var maxY = minY + Math.max(0, (totalRows - maxVisibleRows) * rowHeight); updateLogPopup._scrollOffset = 0; updateLogPopup._dragStartY = null; updateLogPopup._dragLastY = null; updateLogPopup.interactive = true; // Use the popup's interactive area for dragging updateLogPopup.down = function (x, y, obj) { // Convert global tap coordinates to local popup coordinates var localPos = updateLogPopup.toLocal({ x: x, y: y }); updateLogPopup._dragStartY = localPos.y; updateLogPopup._dragLastY = localPos.y; updateLogPopup._startScrollOffset = listContainer.y; // Use listContainer.y for scroll offset }; updateLogPopup.move = function (x, y, obj) { if (updateLogPopup._dragStartY !== null) { // Convert global drag coordinates to local popup coordinates var localPos = updateLogPopup.toLocal({ x: x, y: y }); var dy = localPos.y - updateLogPopup._dragLastY; updateLogPopup._dragLastY = localPos.y; listContainer.y += dy; // Clamp scroll if (listContainer.y > minY) listContainer.y = minY; // Clamp to the initial Y if (listContainer.y < minY - (totalRows * rowHeight - visibleHeight)) { listContainer.y = minY - (totalRows * rowHeight - visibleHeight); } // If total rows are less than visible rows, don't allow scrolling below initial position if (totalRows <= maxVisibleRows) { if (listContainer.y < minY) listContainer.y = minY; } } }; updateLogPopup.up = function (x, y, obj) { updateLogPopup._dragStartY = null; updateLogPopup._dragLastY = null; }; // Close button var closeBtn = LK.getAsset('fart_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 2048 / 2, y: 2732 / 2 + 600 }); var closeTxt = new Text2('Close', { size: 70, fill: 0x7A5C00 }); closeTxt.anchor.set(0.5, 0.5); closeTxt.x = 0; closeTxt.y = 0; closeBtn.addChild(closeTxt); closeBtn.interactive = true; closeBtn.down = function () { game.removeChild(updateLogPopup); }; updateLogPopup.addChild(closeBtn); game.addChild(updateLogPopup); };
===================================================================
--- original.js
+++ change.js
@@ -63,76 +63,8 @@
};
self.showNormal();
return self;
});
-// Fart button class
-var FartButton = Container.expand(function () {
- var self = Container.call(this);
- // Button shape
- var btn = self.attachAsset('fart_btn', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // "FART" text
- var fartTxt = new Text2('FART', {
- size: 120,
- fill: 0x7A5C00
- });
- fartTxt.anchor.set(0.5, 0.5);
- fartTxt.x = 0;
- fartTxt.y = 0;
- self.addChild(fartTxt);
- // Fart cloud effect (hidden by default)
- var fartCloud = self.attachAsset('centerCircle', {
- anchorX: 0.5,
- anchorY: 1,
- scaleX: 1.2,
- scaleY: 0.7,
- x: 0,
- y: -110,
- alpha: 0,
- tint: 0xeeeecc
- });
- fartCloud.width = btn.width * 0.7;
- fartCloud.height = btn.height * 0.7;
- // Show fart cloud with animation
- self.showFartCloud = function () {
- fartCloud.alpha = 0.85;
- fartCloud.scaleX = 1.2;
- fartCloud.scaleY = 0.7;
- fartCloud.y = -110;
- tween(fartCloud, {
- alpha: 0,
- y: fartCloud.y - 80,
- scaleX: 1.5,
- scaleY: 1.1
- }, {
- duration: 420,
- easing: tween.cubicOut
- });
- };
- // Simple press animation
- self.animatePress = function () {
- tween(self, {
- scaleX: 0.92,
- scaleY: 0.92
- }, {
- duration: 60,
- easing: tween.cubicIn,
- onFinish: function onFinish() {
- tween(self, {
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 80,
- easing: tween.cubicOut
- });
- }
- });
- self.showFartCloud();
- };
- return self;
-});
// Floating text class for score popups
var FloatingText = Container.expand(function () {
var self = Container.call(this);
self.textObj = new Text2('', {
@@ -228,9 +160,9 @@
y: 0,
tint: 0x8B4513 // Brown color for food
});
foodBtn.addChild(foodIcon);
- var foodTxt = new Text2(food.name + '\nCost: ' + food.cost + ' Farts\nHunger: +' + food.hunger, {
+ var foodTxt = new Text2(food.name + '\nCost: ' + food.cost + ' Pets\nHunger: +' + food.hunger, {
size: 40,
fill: 0x7A5C00,
align: 'center'
});
@@ -373,9 +305,9 @@
y: -100 + index * 150
});
hatBtn.interactive = true;
self.addChild(hatBtn);
- var hatTxt = new Text2(hat.name + '\nCost: ' + hat.cost + ' Farts', {
+ var hatTxt = new Text2(hat.name + '\nCost: ' + hat.cost + ' Pets', {
size: 50,
fill: 0x7A5C00,
align: 'center'
});
@@ -501,8 +433,76 @@
anchorY: 0.5
});
return self;
});
+// Pet button class
+var PetButton = Container.expand(function () {
+ var self = Container.call(this);
+ // Button shape
+ var btn = self.attachAsset('pet_btn', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // "PET" text
+ var petTxt = new Text2('PET', {
+ size: 120,
+ fill: 0x7A5C00
+ });
+ petTxt.anchor.set(0.5, 0.5);
+ petTxt.x = 0;
+ petTxt.y = 0;
+ self.addChild(petTxt);
+ // Pet cloud effect (hidden by default) - Keeping for fun
+ var petCloud = self.attachAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 1,
+ scaleX: 1.2,
+ scaleY: 0.7,
+ x: 0,
+ y: -110,
+ alpha: 0,
+ tint: 0xeeeecc
+ });
+ petCloud.width = btn.width * 0.7;
+ petCloud.height = btn.height * 0.7;
+ // Show pet cloud with animation - Keeping for fun
+ self.showPetCloud = function () {
+ petCloud.alpha = 0.85;
+ petCloud.scaleX = 1.2;
+ petCloud.scaleY = 0.7;
+ petCloud.y = -110;
+ tween(petCloud, {
+ alpha: 0,
+ y: petCloud.y - 80,
+ scaleX: 1.5,
+ scaleY: 1.1
+ }, {
+ duration: 420,
+ easing: tween.cubicOut
+ });
+ };
+ // Simple press animation
+ self.animatePress = function () {
+ tween(self, {
+ scaleX: 0.92,
+ scaleY: 0.92
+ }, {
+ duration: 60,
+ easing: tween.cubicIn,
+ onFinish: function onFinish() {
+ tween(self, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 80,
+ easing: tween.cubicOut
+ });
+ }
+ });
+ self.showPetCloud();
+ };
+ return self;
+});
/****
* Initialize Game
****/