User prompt
Delete Automatic Collect
User prompt
Delete the shop.
User prompt
To restore automatic pickup, re-enable the detection zone or trigger around the player that senses nearby collectible items. This area should detect items within a certain radius and automatically add them to the player’s inventory when they come close. Make sure the trigger or collider responsible for this function is active again, and any related scripts controlling the pickup logic are running. This will bring back the seamless automatic collection feature.
User prompt
undo
User prompt
To make the automatic pickup radius smaller, reduce the size of the detection area or trigger zone around the player that detects nearby items. This can be done by scaling down the size of the collision box, sphere, or region used for automatic collection. A smaller pickup area means players will need to be closer to items before they are collected automatically, which adds a bit more challenge and control to item gathering.
User prompt
When the player clicks to open the Shop, the game should pause, preventing all player movement and interactions. This can be achieved by temporarily disabling the player's movement controls or input handlers while the Shop UI is active. For example, in Roblox, you can disable the player's Humanoid movement by setting WalkSpeed and JumpPower to zero or by toggling a custom movement script off. This ensures the player cannot move or perform actions until they close the Shop, maintaining focus on the shopping experience and preventing gameplay interruptions.
User prompt
The Shop section should be positioned even further toward the far right edge of the screen.
User prompt
The Shop section should be positioned further to the right side of the screen.
User prompt
A little straighter
User prompt
The Shop button should be positioned at the center-right of the screen, aligned flush against the right edge of the screen.
User prompt
The Shop button should be positioned to the right of the center.
User prompt
The Shop button, labeled “Shop,” should be positioned on the right side of the center of the screen—not at the far edge, but rather in the middle-right region. This means it will be slightly offset from the exact center, toward the right, creating a balanced layout that keeps the button easily accessible and visually prominent without crowding the center of the screen. This location is ideal for drawing attention without interfering with gameplay, especially for mobile users who naturally interact with the right side of the screen more frequently. The button should maintain a modern, clean design with subtle visual effects to stand out, while remaining consistent across all screen sizes and resolutions.
User prompt
The Shop button, labeled simply as “Shop,” should be placed on the right side of the screen, ideally in the upper-right or middle-right corner depending on your game’s layout. Its position should be fixed so it remains consistently visible regardless of the player’s resolution or device type. This placement ensures it’s easy to access but does not interfere with core gameplay elements that usually happen in the center of the screen. The button should have a clean, modern design—perhaps with rounded corners and a subtle glow—to make it stand out without being distracting.
User prompt
The shop UI should be positioned on the right side of the screen, aligned slightly toward the center-right area rather than being pushed completely to the edge. This placement ensures that it remains clearly visible without obstructing the main gameplay area in the center of the screen. It should appear as a floating panel or frame with a modern, semi-transparent dark background, possibly with rounded corners and a subtle drop shadow for depth. The shop should be anchored in a fixed position so it remains consistent across different screen sizes and resolutions, whether on PC or mobile. This layout choice provides a clean and balanced visual structure, allowing the player to access shop options easily while still maintaining focus on gameplay in the central area.
User prompt
The shop system I want to build is designed for smooth and intuitive use across both PC and mobile platforms. When a player clicks the Shop button, the shop interface should slide in or become visible; clicking the same button again should close the shop, using a simple toggle mechanic controlled by a single boolean variable to avoid unintended flickering or auto-closing behavior. The shop should not auto-close unless the player intentionally clicks the button again. Inside the shop, there will be a main category called “Assets”, where I will manually add different types of sickles (oraks) in various colors (e.g., red, blue, gold, neon). Each sickle will be displayed with a visual icon, name, and price. When a player purchases a sickle, it should become their active weapon, automatically equipping it. To maintain consistency and avoid item overlap, if a player already owns a different sickle and decides to buy another one, the previously equipped sickle should be removed from their character and replaced with the newly purchased one. This ensures that players only carry one sickle at a time, and their selection reflects their most recent purchase. To summarize the features: The shop opens and closes by clicking the same button (toggle behavior). It contains an Assets tab where different sickles can be displayed and purchased. Each sickle is unique in color/design and has a price. Only one sickle can be equipped at a time: when a new one is purchased, the old one is automatically removed. The UI will be touch-friendly and clean, with a dark background and vibrant button colors (e.g., cyan and purple) for an immersive and modern look. Optional enhancements could include saving the last selected sickle using DataStore, adding animations when the shop opens/closes, or letting players preview their weapon in a small 3D viewport before buying. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
If the shop interface in your game opens and closes instantly—within one second—when clicking the Shop button, it’s likely due to the toggle logic being triggered multiple times unintentionally. This usually happens when the visibility state of the shop UI is not properly tracked or when multiple scripts are listening to the same button click. To fix this issue, you should implement a simple state management system using a boolean variable (e.g., isShopOpen) to keep track of whether the shop is currently visible or not. When the Shop button is clicked, the script should first check the value of this variable: if the shop is closed, it sets the UI to visible and updates the variable to true; if the shop is already open, it hides the UI and resets the variable to false. This prevents the system from rapidly switching states on a single click and ensures the shop opens and closes smoothly only when intended. Additionally, make sure there are no duplicate event listeners or conflicting scripts that might be causing the toggle function to fire more than once per click.
User prompt
I want to create a detailed and immersive Shop system that is fully compatible with both mobile and PC platforms. The shop will be accessible via a clearly labeled "Shop" button positioned at the top-right corner of the screen. When tapped or clicked, the shop panel will smoothly slide in from the right side and occupy a visible portion of the right half of the screen, without blocking the main gameplay view. Tapping or clicking the "Shop" button again will seamlessly close the panel using the same slide animation. The shop interface will have a sleek, futuristic design with a dark background color (#1e1e2f) and glowing accent elements in cyan (#00ffff) and deep purple (#9b59b6), giving it a vibrant yet premium feel. Fonts will be bold and clean, with white text for item names and price tags, and semi-transparent black for item containers. The interface will be fully responsive, ensuring large, easy-to-tap UI elements for mobile users, and hover effects for PC players. Inside the shop panel, there will be categorized tabs at the top (e.g., "Assets", "Gamepasses", "Limited Offers"). The main content area will be under the "Assets" tab by default. Within this section, a special sub-category will showcase Sickle Assets—a collection of uniquely colored sickles (oraks), such as red, blue, gold, and neon variants. Each sickle will be represented with a high-quality 3D icon or thumbnail, accompanied by a short description and a price displayed in in-game currency. Players will be able to purchase sickles by clicking a "Buy" button under each one, which will trigger a confirmation popup for added clarity. Additional features may include: Preview animations when hovering or tapping an item (e.g., rotating the sickle). A currency display bar at the top of the shop. Lock icons on sickles that require a certain level or achievement to unlock. A notification badge on the "Shop" button when new items are added or when a limited offer is active. The entire shop system will aim to be intuitive, visually appealing, and fully functional across all devices, enhancing the overall user experience while providing meaningful in-game purchases. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
For my game, I want to implement a fully integrated Shop system that works seamlessly on both mobile and PC platforms. The shop interface will feature a clean, modern design with a dark-themed background (#1e1e2f) to reduce eye strain and make colorful elements stand out. Buttons and interactive elements will use a vibrant gradient of cyan and purple (#00ffff to #9b59b6), creating a futuristic look that appeals to all age groups. The layout will adapt responsively: on PC, the shop panel will slide in from the right side of the screen, while on mobile, it will pop up from the bottom with larger touch-friendly buttons. The shop will include tabs for items, skins, game passes, and limited-time offers, each with smooth transitions and animated icons to keep the interface dynamic. Tooltips and price tags will be clearly visible with white text on semi-transparent black backgrounds. Overall, the system will prioritize usability, visual consistency, and a premium feel across all devices.
User prompt
To optimize Automatic Collect and keep performance smooth, make sure the system only runs its collection logic at controlled intervals instead of every frame. Use efficient timers or event triggers to perform harvest actions periodically. Minimize calculations and avoid unnecessary updates—only update the UI or game state when there’s an actual change. Also, handle data changes in batches if possible to reduce processing load. By doing this, Automatic Collect won’t slow down the game or use excessive resources, ensuring smooth gameplay performance.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { equippedSickle: "sickle", ownedSickles: ["sickle"] }); /**** * Classes ****/ // Removed plugin import to fix 'Unable to load plugins' error var Animal = Container.expand(function () { var self = Container.call(this); self.animalAsset = null; self.setAnimalImage = function (imageId) { if (self.animalAsset) { self.animalAsset.destroy(); } self.animalAsset = self.attachAsset(imageId, { anchorX: 0.5, anchorY: 0.5 }); }; return self; }); // Bird class var Bird = Container.expand(function () { var self = Container.call(this); // Create the bird asset var birdAsset = self.attachAsset('Bird', { anchorX: 0.5, anchorY: 0.5, alpha: 1, scaleX: 0.8, scaleY: 0.8 }); // Variables for movement self.speed = 1.0; // Faster than clouds self.lifeTime = 3000; // 50 seconds at 60fps self.lifeCounter = 0; // Track how long bird has been visible self.flyHeight = 0; // Vertical position offset for flying pattern // Initialize bird self.init = function () { self.lifeCounter = 0; self.alpha = 1; // Start movement animation using tween self.startMoving(); }; // Start the left to right movement with slight up/down wave pattern self.startMoving = function () { // Move bird to the right side of screen var targetX = 2048 + birdAsset.width / 2; // Move past right edge // Create the movement tween tween(self, { x: targetX }, { duration: 20000, // Faster than clouds - 20 seconds to cross screen easing: tween.linear }); }; // Update function called every frame - optimized self.update = function () { // Early return if invisible or not visible - prevents unnecessary calculations if (self.alpha <= 0 || !self.visible) return; // Increment life counter first for potential early returns self.lifeCounter++; // Only check edge crossing if we're near the edge - optimization var edgeX = 2048 + birdAsset.width / 2; if (self.x >= edgeX) { // Stop any existing tweens on this bird tween.stop(self); // Fade out animation tween(self, { alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Remove bird from game self.visible = false; // Hide instead of destroy birds.push(self); // Return to pool } }); return; // Early return after starting fade out animation } // Create a small wavy flight pattern - only for visible, active birds self.y = self.y + Math.sin(self.lifeCounter * 0.03) * 1.5; }; return self; }); // CarrotSlot class for area 2 var CarrotSlot = Container.expand(function () { var self = Container.call(this); self.slotAsset = self.attachAsset('carrot', { anchorX: 0.5, anchorY: 1 }); var sproutAsset = self.attachAsset('sprout', { anchorX: 0.5, anchorY: 1, alpha: 0, scaleX: 0.5, scaleY: 0.5 }); self.harvested = false; self.regrowTime = 1800; // 30 seconds at 60fps self.regrowCounter = 0; self.fieldIndex = 1; // Area 2 self.regrowing = false; // Show/hide carrot and handle regrow animation self.setHarvested = function (harvested) { self.harvested = harvested; if (harvested) { // Hide carrot with animation tween(self.slotAsset, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); // Show sprout with animation sproutAsset.alpha = 1; sproutAsset.scaleX = 0.1; sproutAsset.scaleY = 0.1; // Animate sprout appearing tween(sproutAsset, { scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); self.regrowCounter = self.regrowTime; self.regrowing = true; } else { // Show carrot with animation tween(self.slotAsset, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); // Hide sprout with animation tween(sproutAsset, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); self.regrowing = false; } }; // Regrow logic self.update = function () { if (self.harvested && self.regrowing) { if (self.regrowCounter > 0) { // Animate sprout growing to carrot size var t = 1 - self.regrowCounter / self.regrowTime; sproutAsset.scaleX = 0.5 + 0.5 * t; sproutAsset.scaleY = 0.5 + 0.5 * t; self.regrowCounter--; } else { // Sprout is now full size, switch back to carrot and allow harvest again sproutAsset.scaleX = 1; sproutAsset.scaleY = 1; self.setHarvested(false); self.regrowing = false; // Stop regrowing process } } }; // For hit detection self.isHarvestable = function () { return !self.harvested; }; return self; }); // Cloud class var Cloud = Container.expand(function () { var self = Container.call(this); // Create the cloud asset var cloudAsset = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 // Semi-transparent clouds }); // Variables for movement self.speed = 0.2; // Very slow speed for smooth movement self.lifeTime = 6000; // 100 seconds at 60fps - longer lifetime self.lifeCounter = 0; // Track how long cloud has been visible self.layer = 0; // Layer for visual depth (0 = front, 1 = back) // Initialize cloud self.init = function () { self.lifeCounter = 0; self.alpha = 1; // Apply layer-specific settings if (self.layer === 1) { // Back layer cloud (slightly smaller and more transparent) self.scale.set(0.8, 0.8); self.alpha = 0.7; } // Start movement animation using tween self.startMoving(); }; // Start the left to right movement only self.startMoving = function () { // Move cloud to the right side of screen var targetX = 2048 + cloudAsset.width / 2; // Move past right edge // Create the movement tween tween(self, { x: targetX }, { duration: 60000, // Slower movement - 60 seconds to cross screen easing: tween.linear }); }; // Update function called every frame - optimized self.update = function () { // Early return if invisible or not visible - saves processing if (self.alpha <= 0 || !self.visible) return; // Track lastX for edge detection - initialize once if undefined if (typeof self.lastX === "undefined") self.lastX = self.x; // Only check edge crossing if we're near the edge - optimization var edgeX = 2048 + cloudAsset.width / 2; if (self.x >= edgeX && self.lastX < edgeX) { // Stop any existing tweens on this cloud to prevent conflicts tween.stop(self); // Fade out animation tween(self, { alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Remove cloud from game self.visible = false; // Hide instead of destroy clouds.push(self); // Return to pool } }); } // Update lastX for next frame self.lastX = self.x; }; return self; }); // EggplantSlot class for area 4 var EggplantSlot = Container.expand(function () { var self = Container.call(this); self.slotAsset = self.attachAsset('eggplant', { anchorX: 0.5, anchorY: 1 }); var sproutAsset = self.attachAsset('sprout', { anchorX: 0.5, anchorY: 1, alpha: 0, scaleX: 0.5, scaleY: 0.5 }); self.harvested = false; self.regrowTime = 1800; // 30 seconds at 60fps self.regrowCounter = 0; self.fieldIndex = 3; // Area 4 self.regrowing = false; // Show/hide eggplant and handle regrow animation self.setHarvested = function (harvested) { self.harvested = harvested; if (harvested) { // Hide eggplant with animation tween(self.slotAsset, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); // Show sprout with animation sproutAsset.alpha = 1; sproutAsset.scaleX = 0.1; sproutAsset.scaleY = 0.1; // Animate sprout appearing tween(sproutAsset, { scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); self.regrowCounter = self.regrowTime; self.regrowing = true; } else { // Show eggplant with animation tween(self.slotAsset, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); // Hide sprout with animation tween(sproutAsset, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); self.regrowing = false; } }; // Regrow logic self.update = function () { if (self.harvested && self.regrowing) { if (self.regrowCounter > 0) { // Animate sprout growing to eggplant size var t = 1 - self.regrowCounter / self.regrowTime; sproutAsset.scaleX = 0.5 + 0.5 * t; sproutAsset.scaleY = 0.5 + 0.5 * t; self.regrowCounter--; } else { // Sprout is now full size, switch back to eggplant and allow harvest again sproutAsset.scaleX = 1; sproutAsset.scaleY = 1; self.setHarvested(false); self.regrowing = false; // Stop regrowing process } } }; // For hit detection self.isHarvestable = function () { return !self.harvested; }; return self; }); // Farmer class var Farmer = Container.expand(function () { var self = Container.call(this); // Create animation frames var idleFrame = self.attachAsset('farmer', { anchorX: 0.5, anchorY: 0.5, alpha: 1 }); // Frame 2 (running) var runningFrame = self.attachAsset('farmer_walk', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Frame 3 (right step) var rightStepFrame = self.attachAsset('farmer_walk', { anchorX: 0.5, anchorY: 0.5, alpha: 0, rotation: 0.1 }); self.speed = 18; // px per move self.targetX = self.x; self.targetY = self.y; self.moving = false; self.lastMoving = false; self.animationTimer = 0; self.animationFrame = 0; self.frameTime = 18; // 0.3 seconds at 60fps // Animation frame switching self.switchToFrame = function (frameNum) { idleFrame.alpha = 0; runningFrame.alpha = 0; rightStepFrame.alpha = 0; if (frameNum === 0) { // Idle idleFrame.alpha = 1; } else if (frameNum === 1) { // Running runningFrame.alpha = 1; } else if (frameNum === 2) { // Right step rightStepFrame.alpha = 1; } }; // Move farmer towards target self.update = function () { // Track movement direction and update image if (self.moving) { var dx = self.targetX - self.x; // Check if moving right or left if (dx > 0) { // Moving right - use player_right asset idleFrame.scaleX = 1; runningFrame.scaleX = 1; rightStepFrame.scaleX = 1; // Switch to player_right image if (self.currentAsset !== idleFrame || idleFrame.texture !== LK.getAsset('player_right', {}).texture) { if (self.currentAsset) { self.currentAsset.alpha = 0; } var rightAsset = LK.getAsset('player_right', { anchorX: 0.5, anchorY: 0.5 }); rightAsset.alpha = 1; self.addChild(rightAsset); self.currentAsset = rightAsset; } } else if (dx < 0) { // Moving left - use player_left asset idleFrame.scaleX = -1; runningFrame.scaleX = -1; rightStepFrame.scaleX = -1; // Switch to player_left image if (self.currentAsset !== idleFrame || idleFrame.texture !== LK.getAsset('player_left', {}).texture) { if (self.currentAsset) { self.currentAsset.alpha = 0; } var leftAsset = LK.getAsset('player_left', { anchorX: 0.5, anchorY: 0.5 }); leftAsset.alpha = 1; self.addChild(leftAsset); self.currentAsset = leftAsset; } } // Animation handling self.animationTimer++; if (self.animationTimer >= self.frameTime) { self.animationTimer = 0; self.animationFrame = self.animationFrame === 1 ? 2 : 1; // Toggle between frames 1 and 2 self.switchToFrame(self.animationFrame); } } else if (!self.moving && self.lastMoving) { // Just stopped moving - switch to idle self.switchToFrame(0); } self.lastMoving = self.moving; if (!self.moving) return; var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.speed) { self.x = self.targetX; self.y = self.targetY; self.moving = false; // Switch to idle frame when stopping self.switchToFrame(0); } else { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } }; // Set movement target self.moveTo = function (x, y) { self.targetX = x; self.targetY = y; // Start movement if (!self.moving) { self.moving = true; self.animationFrame = 1; self.animationTimer = 0; self.switchToFrame(self.animationFrame); } }; // Attach sickle to farmer's hand var sickle = self.attachAsset('sickle', { anchorX: 0.2, // hand position, left side of ellipse anchorY: 0.7, // slightly below center x: 0, y: 30 }); sickle.alpha = 1; // Add attack animation for sickle self.attack = function () { tween(sickle, { rotation: Math.PI * 2 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { sickle.rotation = 0; } }); }; return self; }); // Field class var Field = Container.expand(function () { var self = Container.call(this); self.index = 0; // 0-3 self.locked = false; self.lockCost = 0; self.lockNode = null; self.fenceNodes = []; self.wheats = []; self.unlockBtn = null; // Draw fences - Empty implementation to eliminate fences self.drawFences = function (x, y, w, h) { self.fenceNodes = []; // No fences or gates are created }; // Place wheat self.placeWheats = function (x, y, w, h, count) { self.wheats = []; // Define grid size var rows = 5; var cols = 10; // Choose vegetable asset per area var vegAssetId = 'wheat'; if (self.index === 1) vegAssetId = 'carrot'; if (self.index === 2) vegAssetId = 'tomato'; if (self.index === 3) vegAssetId = 'eggplant'; // Fallback if asset not found, use wheat if (!LK.assets || !LK.assets[vegAssetId]) vegAssetId = 'wheat'; // Calculate asset size for spacing (use wheat size as reference for all) var vegAsset = LK.getAsset('wheat', { anchorX: 0.5, anchorY: 1 }); var wheatW = vegAsset.width; var wheatH = vegAsset.height; // Padding from fences var padX = 60; var padY = 60; // Compute available area for wheat grid var gridW = w - 2 * padX; var gridH = h - 2 * padY; // Compute spacing between wheat plants var spacingX = (gridW - wheatW) / (cols - 1); var spacingY = (gridH - wheatH) / (rows - 1); // Place appropriate vegetable in grid based on field index for (var row = 0; row < rows; ++row) { for (var col = 0; col < cols; ++col) { var wx = x + padX + col * spacingX + wheatW / 2; var wy = y + padY + row * spacingY + wheatH; var veg; // Create appropriate vegetable based on area/field index if (self.index === 1) { veg = new CarrotSlot(); } else if (self.index === 2) { veg = new TomatoSlot(); } else if (self.index === 3) { veg = new EggplantSlot(); } else { veg = new Wheat(); veg.fieldIndex = self.index; veg.vegAssetId = vegAssetId; veg.setVegAsset && veg.setVegAsset(vegAssetId); } veg.x = wx; veg.y = wy; self.addChild(veg); self.wheats.push(veg); } } }; // Lock overlay self.showLock = function (centerX, centerY) { if (self.lockNode) return; self.lockNode = LK.getAsset('lock', { anchorX: 0.5, anchorY: 0.5, x: centerX, y: centerY }); self.addChild(self.lockNode); // Unlock text var unlockTxt = new Text2('Unlock\n$' + self.lockCost, { size: 60, fill: "#fff" }); unlockTxt.anchor.set(0.5, 0.5); unlockTxt.x = centerX; unlockTxt.y = centerY + 70; self.unlockBtn = unlockTxt; self.addChild(unlockTxt); }; self.hideLock = function () { if (self.lockNode) { self.lockNode.destroy(); self.lockNode = null; } if (self.unlockBtn) { self.unlockBtn.destroy(); self.unlockBtn = null; } }; return self; }); // Rooster class with 4-frame animation cycling smoothly var Rooster = Container.expand(function () { var self = Container.call(this); // Animation frame asset ids var frameIds = ['rooster_1', 'rooster_2', 'rooster_3', 'rooster_4']; self.roosterFrames = []; self.currentFrame = 0; self.frameTimer = 0; self.frameInterval = 10; // ~0.16s per frame at 60fps (smooth) // Attach all frames, only show the first for (var i = 0; i < frameIds.length; ++i) { var frame = self.attachAsset(frameIds[i], { anchorX: 0.5, anchorY: 0.5, alpha: i === 0 ? 1 : 0 }); self.roosterFrames.push(frame); } // Animation update self.update = function () { self.frameTimer++; if (self.frameTimer >= self.frameInterval) { // Hide current frame self.roosterFrames[self.currentFrame].alpha = 0; // Advance to next frame self.currentFrame = (self.currentFrame + 1) % self.roosterFrames.length; // Show new frame self.roosterFrames[self.currentFrame].alpha = 1; self.frameTimer = 0; } }; return self; }); // Shop class for managing sickle purchases and equipment var Shop = Container.expand(function () { var self = Container.call(this); // Shop state self.isOpen = false; self.sickleItems = []; // Available sickles with their properties self.availableSickles = [{ id: 'sickle', name: 'Classic Sickle', price: 0, color: 0xC0C0C0, unlocked: true }, { id: 'red_sickle', name: 'Red Sickle', price: 5000, color: 0xFF4444, unlocked: false }, { id: 'blue_sickle', name: 'Blue Sickle', price: 10000, color: 0x4444FF, unlocked: false }, { id: 'gold_sickle', name: 'Gold Sickle', price: 25000, color: 0xFFD700, unlocked: false }, { id: 'neon_sickle', name: 'Neon Sickle', price: 50000, color: 0x00FF88, unlocked: false }]; // Shop background self.shopBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 18, scaleY: 25, tint: 0x2C2C2C, alpha: 0.95, x: 2048 / 2, y: 2732 / 2 }); self.shopBg.visible = false; self.addChild(self.shopBg); // Shop title self.shopTitle = new Text2('SHOP - ASSETS', { size: 120, fill: 0xFFFFFF }); self.shopTitle.anchor.set(0.5, 0.5); self.shopTitle.x = 2048 / 2; self.shopTitle.y = 400; self.shopTitle.visible = false; self.addChild(self.shopTitle); // Initialize shop items self.createShopItems = function () { // Clear existing items for (var i = 0; i < self.sickleItems.length; i++) { if (self.sickleItems[i] && self.sickleItems[i].parent) { self.sickleItems[i].destroy(); } } self.sickleItems = []; var startY = 600; var itemHeight = 300; for (var i = 0; i < self.availableSickles.length; i++) { var sickleData = self.availableSickles[i]; var itemY = startY + i * itemHeight; // Item background var itemBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 4, tint: 0x404040, alpha: 0.8, x: 2048 / 2, y: itemY }); itemBg.visible = false; self.addChild(itemBg); // Sickle icon (with color tint) var sickleIcon = LK.getAsset('sickle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, tint: sickleData.color, x: 2048 / 2 - 400, y: itemY }); sickleIcon.visible = false; self.addChild(sickleIcon); // Sickle name var nameText = new Text2(sickleData.name, { size: 80, fill: 0xFFFFFF }); nameText.anchor.set(0, 0.5); nameText.x = 2048 / 2 - 200; nameText.y = itemY - 30; nameText.visible = false; self.addChild(nameText); // Price/Status text var priceText = new Text2('', { size: 60, fill: 0xFFFF00 }); priceText.anchor.set(0, 0.5); priceText.x = 2048 / 2 - 200; priceText.y = itemY + 30; priceText.visible = false; self.addChild(priceText); // Update price text based on ownership/equipment status self.updatePriceText(priceText, sickleData); // Buy/Equip button var actionButton = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 2, tint: 0x00CCFF, alpha: 0.9, x: 2048 / 2 + 400, y: itemY }); actionButton.visible = false; actionButton.sickleData = sickleData; self.addChild(actionButton); var buttonText = new Text2('', { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = actionButton.x; buttonText.y = actionButton.y; buttonText.visible = false; self.addChild(buttonText); // Update button text and functionality self.updateActionButton(actionButton, buttonText, sickleData); // Store references var shopItem = { bg: itemBg, icon: sickleIcon, nameText: nameText, priceText: priceText, actionButton: actionButton, buttonText: buttonText, sickleData: sickleData }; self.sickleItems.push(shopItem); } }; // Update price text based on sickle status self.updatePriceText = function (priceText, sickleData) { var ownedSickles = storage.ownedSickles || ['sickle']; var equippedSickle = storage.equippedSickle || 'sickle'; if (ownedSickles.indexOf(sickleData.id) !== -1) { if (equippedSickle === sickleData.id) { priceText.setText('EQUIPPED'); priceText.tint = 0x00FF00; } else { priceText.setText('OWNED'); priceText.tint = 0xFFFF00; } } else { priceText.setText('$' + sickleData.price); priceText.tint = 0xFFFF00; } }; // Update action button based on sickle status self.updateActionButton = function (actionButton, buttonText, sickleData) { var ownedSickles = storage.ownedSickles || ['sickle']; var equippedSickle = storage.equippedSickle || 'sickle'; if (ownedSickles.indexOf(sickleData.id) !== -1) { if (equippedSickle === sickleData.id) { buttonText.setText('EQUIPPED'); actionButton.tint = 0x00FF00; actionButton.interactive = false; } else { buttonText.setText('EQUIP'); actionButton.tint = 0x9900FF; actionButton.interactive = true; actionButton.down = function () { self.equipSickle(sickleData.id); }; } } else { buttonText.setText('BUY'); actionButton.tint = 0x00CCFF; actionButton.interactive = true; actionButton.down = function () { self.buySickle(sickleData); }; } }; // Buy a sickle self.buySickle = function (sickleData) { if (money >= sickleData.price) { money -= sickleData.price; _updateMoneyDisplay(); // Add to owned sickles and equip immediately var ownedSickles = storage.ownedSickles || ['sickle']; if (ownedSickles.indexOf(sickleData.id) === -1) { ownedSickles.push(sickleData.id); storage.ownedSickles = ownedSickles; } // Equip the new sickle self.equipSickle(sickleData.id); // Flash green effect LK.effects.flashScreen(0x00FF00, 300); // Refresh shop display self.refreshShopItems(); } else { // Flash red - not enough money LK.effects.flashScreen(0xFF0000, 300); } }; // Equip a sickle self.equipSickle = function (sickleId) { storage.equippedSickle = sickleId; // Update farmer's sickle visually self.updateFarmerSickle(); // Refresh shop display self.refreshShopItems(); // Flash blue effect LK.effects.flashObject(farmer, 0x0088FF, 300); }; // Update farmer's sickle appearance self.updateFarmerSickle = function () { var equippedSickleId = storage.equippedSickle || 'sickle'; var sickleData = null; // Find the equipped sickle data for (var i = 0; i < self.availableSickles.length; i++) { if (self.availableSickles[i].id === equippedSickleId) { sickleData = self.availableSickles[i]; break; } } if (sickleData && farmer) { // Find farmer's sickle and update its color var farmerSickle = null; for (var i = 0; i < farmer.children.length; i++) { var child = farmer.children[i]; if (child && child.texture && child.texture.baseTexture) { // Check if this is a sickle asset var textureUrl = child.texture.baseTexture.imageUrl || ''; if (textureUrl.indexOf('sickle') !== -1 || child._assetId === 'sickle') { farmerSickle = child; break; } } } if (farmerSickle) { farmerSickle.tint = sickleData.color; } } }; // Refresh shop items display self.refreshShopItems = function () { for (var i = 0; i < self.sickleItems.length; i++) { var item = self.sickleItems[i]; self.updatePriceText(item.priceText, item.sickleData); self.updateActionButton(item.actionButton, item.buttonText, item.sickleData); } }; // Toggle shop visibility self.toggleShop = function () { self.isOpen = !self.isOpen; if (self.isOpen) { self.openShop(); } else { self.closeShop(); } }; // Open shop with animation self.openShop = function () { self.isOpen = true; // Show all shop elements self.shopBg.visible = true; self.shopTitle.visible = true; for (var i = 0; i < self.sickleItems.length; i++) { var item = self.sickleItems[i]; item.bg.visible = true; item.icon.visible = true; item.nameText.visible = true; item.priceText.visible = true; item.actionButton.visible = true; item.buttonText.visible = true; } // Animate shop sliding in self.shopBg.alpha = 0; self.shopTitle.alpha = 0; tween(self.shopBg, { alpha: 0.95 }, { duration: 300, easing: tween.easeOut }); tween(self.shopTitle, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); // Animate items appearing for (var i = 0; i < self.sickleItems.length; i++) { var item = self.sickleItems[i]; item.bg.alpha = 0; item.icon.alpha = 0; item.nameText.alpha = 0; item.priceText.alpha = 0; item.actionButton.alpha = 0; item.buttonText.alpha = 0; var delay = i * 100; tween(item.bg, { alpha: 0.8 }, { duration: 300, easing: tween.easeOut }); tween(item.icon, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(item.nameText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(item.priceText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(item.actionButton, { alpha: 0.9 }, { duration: 300, easing: tween.easeOut }); tween(item.buttonText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); } }; // Close shop with animation self.closeShop = function () { self.isOpen = false; // Animate shop sliding out tween(self.shopBg, { alpha: 0 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { self.shopBg.visible = false; self.shopTitle.visible = false; for (var i = 0; i < self.sickleItems.length; i++) { var item = self.sickleItems[i]; item.bg.visible = false; item.icon.visible = false; item.nameText.visible = false; item.priceText.visible = false; item.actionButton.visible = false; item.buttonText.visible = false; } } }); tween(self.shopTitle, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); // Animate items disappearing for (var i = 0; i < self.sickleItems.length; i++) { var item = self.sickleItems[i]; tween(item.bg, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); tween(item.icon, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); tween(item.nameText, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); tween(item.priceText, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); tween(item.actionButton, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); tween(item.buttonText, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); } }; return self; }); // TomatoSlot class for area 3 var TomatoSlot = Container.expand(function () { var self = Container.call(this); self.slotAsset = self.attachAsset('tomato', { anchorX: 0.5, anchorY: 1 }); var sproutAsset = self.attachAsset('sprout', { anchorX: 0.5, anchorY: 1, alpha: 0, scaleX: 0.5, scaleY: 0.5 }); self.harvested = false; self.regrowTime = 1800; // 30 seconds at 60fps self.regrowCounter = 0; self.fieldIndex = 2; // Area 3 self.regrowing = false; // Show/hide tomato and handle regrow animation self.setHarvested = function (harvested) { self.harvested = harvested; if (harvested) { // Hide tomato with animation tween(self.slotAsset, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); // Show sprout with animation sproutAsset.alpha = 1; sproutAsset.scaleX = 0.1; sproutAsset.scaleY = 0.1; // Animate sprout appearing tween(sproutAsset, { scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); self.regrowCounter = self.regrowTime; self.regrowing = true; } else { // Show tomato with animation tween(self.slotAsset, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); // Hide sprout with animation tween(sproutAsset, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); self.regrowing = false; } }; // Regrow logic self.update = function () { if (self.harvested && self.regrowing) { if (self.regrowCounter > 0) { // Animate sprout growing to tomato size var t = 1 - self.regrowCounter / self.regrowTime; sproutAsset.scaleX = 0.5 + 0.5 * t; sproutAsset.scaleY = 0.5 + 0.5 * t; self.regrowCounter--; } else { // Sprout is now full size, switch back to tomato and allow harvest again sproutAsset.scaleX = 1; sproutAsset.scaleY = 1; self.setHarvested(false); self.regrowing = false; // Stop regrowing process } } }; // For hit detection self.isHarvestable = function () { return !self.harvested; }; return self; }); // Wheat class var Wheat = Container.expand(function () { var self = Container.call(this); self.vegAssetId = 'wheat'; self.wheatAsset = self.attachAsset('wheat', { anchorX: 0.5, anchorY: 1 }); var sproutAsset = self.attachAsset('sprout', { anchorX: 0.5, anchorY: 1, alpha: 0, scaleX: 0.5, scaleY: 0.5 }); self.harvested = false; self.regrowTime = 1800; // 30 seconds at 60fps self.regrowCounter = 0; self.fieldIndex = 0; // which field this wheat belongs to self.regrowing = false; self.removeAfter = 0; // Change vegetable asset if needed self.setVegAsset = function (assetId) { if (self.wheatAsset) { self.wheatAsset.destroy(); } self.vegAssetId = assetId || 'wheat'; // Only allow wheat, carrot, tomato, eggplant var validAssets = { wheat: 1, carrot: 1, tomato: 1, eggplant: 1 }; if (!validAssets[self.vegAssetId]) self.vegAssetId = 'wheat'; self.wheatAsset = self.attachAsset(self.vegAssetId, { anchorX: 0.5, anchorY: 1 }); // Make sure sprout is on top self.removeChild(sproutAsset); self.addChild(sproutAsset); }; // Show/hide wheat and handle regrow animation self.setHarvested = function (harvested) { self.harvested = harvested; if (harvested) { // Hide wheat, show sprout if (self.wheatAsset) { // Animate wheat harvesting with tween tween(self.wheatAsset, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); } // Show and animate sprout growing from nothing sproutAsset.alpha = 1; sproutAsset.scaleX = 0.1; sproutAsset.scaleY = 0.1; // Animate sprout appearing tween(sproutAsset, { scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); self.regrowCounter = self.regrowTime; self.regrowing = true; } else { // Show wheat/veg, hide sprout with animation if (self.wheatAsset) { tween(self.wheatAsset, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); } // Fade out sprout tween(sproutAsset, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); self.regrowing = false; } }; // Regrow logic and removal after 5 seconds - highly optimized self.update = function () { // Early return if not harvested or not regrowing - prevents unnecessary checks if (!self.harvested || !self.regrowing) return; if (self.regrowCounter > 0) { // Optimize calculations by using cached values and only calculating once var t = 1 - self.regrowCounter / self.regrowTime; var newScale = 0.5 + 0.5 * t; sproutAsset.scaleX = newScale; sproutAsset.scaleY = newScale; self.regrowCounter--; } else { // Sprout is now full size, switch back to wheat/veg and allow harvest again sproutAsset.scaleX = 1; sproutAsset.scaleY = 1; self.setHarvested(false); self.regrowing = false; // Stop regrowing process } }; // For hit detection self.isHarvestable = function () { return !self.harvested; }; return self; }); var Zombie = Container.expand(function () { var self = Container.call(this); // Create the zombie frames (two different assets) var zombieFrame1 = self.attachAsset('zombie_1', { anchorX: 0.5, anchorY: 0.5, alpha: 1 }); var zombieFrame2 = self.attachAsset('zombie_2', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Animation variables self.currentFrame = 0; self.frameTimer = 0; self.frameInterval = 15; // Frame switch interval self.speed = 2; // Movement speed self.lastX = 0; // Track previous X for collision detection self.lastY = 0; // Track previous Y for collision detection self.lastWasIntersecting = false; // Track previous intersection state self.isDead = false; // Track if zombie is dead // Handle click/tap on zombie self.down = function (x, y, obj) { // Mark zombie as clicked and initiate death sequence if (!self.isDead) { self.isDead = true; // Flash zombie yellow to indicate hit LK.effects.flashObject(self, 0xFFFF00, 300); // Death animation - fade out and scale down tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { // Remove zombie from game self.destroy(); // Create new zombie after a 40s delay LK.setTimeout(createZombie, 40000); } }); // Prevent event from bubbling to game (stop farmer movement) return true; } }; // Zombie animation and movement self.update = function () { // Don't update if dead or not visible if (self.isDead || !self.visible) return; // Save previous position for collision detection self.lastX = self.x; self.lastY = self.y; // Frame animation self.frameTimer++; if (self.frameTimer >= self.frameInterval) { // Toggle between frames self.currentFrame = self.currentFrame === 0 ? 1 : 0; // Show current frame zombieFrame1.alpha = self.currentFrame === 0 ? 1 : 0; zombieFrame2.alpha = self.currentFrame === 1 ? 1 : 0; self.frameTimer = 0; } // Move zombie toward the farmer if (farmer) { var dx = farmer.x - self.x; var dy = farmer.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > self.speed) { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } } // Check if zombie is off-screen and return to pool if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) { self.visible = false; // Hide instead of destroy zombies.push(self); // Return to pool } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x4caf50 // Grass green }); /**** * Game Code ****/ // Rooster animation frames (replace id values with your own image ids) // --- Game constants --- // Field fence (rectangle) // Wheat (ellipse) // Farmer (box) // House (box) // Sickle (ellipse, yellow) // Lock icon (ellipse, gray) // Area 2 // Area 3 // Area 4 var FIELD_W = 900; var FIELD_H = 900; var FIELD_GAP = 120; // Increased gap to move fences further from center var FIELD_COUNT = 4; var WHEAT_PER_FIELD = 10; // Area unlock prices and reward multipliers var FIELD_LOCK_COSTS = [0, 20000, 40000, 60000]; // Area 1 open, others locked var FIELD_REWARD_MULT = [1, 2, 3, 4]; // Area 1=1x, 2=2x, 3=3x, 4=4x // --- Area constants --- // Define the distance from center for all areas (equal distance) var AREA_DISTANCE = 600; // Create an array to hold the areas var areas = []; var animals = []; // --- Game state --- var fields = []; var farmer = null; var money = storage.money || 0; var moneyTxt = null; var sickle = null; var dragging = false; var dragOffsetX = 0; var dragOffsetY = 0; var unlockFieldIndex = -1; var playerMovementBlockedByUIClick = false; // Flag to indicate UI handled the click // --- Layout calculation --- // Fields: 2x2 grid, with house in center // [0][1] // [2][3] var fieldPositions = [{ x: 0, y: 0 }, // top-left { x: FIELD_W + FIELD_GAP, y: 0 }, // top-right { x: 0, y: FIELD_H + FIELD_GAP }, // bottom-left { x: FIELD_W + FIELD_GAP, y: FIELD_H + FIELD_GAP } // bottom-right ]; // Center everything in game area var totalW = FIELD_W * 2 + FIELD_GAP; var totalH = FIELD_H * 2 + FIELD_GAP; var offsetX = Math.floor((2048 - totalW) / 2); var offsetY = Math.floor((2732 - totalH) / 2); // --- Create fields --- // Load unlocked fields from storage, default to [true, false, false, false] (only first field unlocked) // Defensive: ensure unlockedFields is an array of length 4 var unlockedFields = storage.unlockedFields; if (!Array.isArray(unlockedFields) || unlockedFields.length !== 4) { unlockedFields = [true, false, false, false]; storage.unlockedFields = unlockedFields; } for (var i = 0; i < FIELD_COUNT; ++i) { var f = new Field(); f.index = i; // Use unlockedFields to determine locked state f.locked = !unlockedFields[i]; f.lockCost = FIELD_LOCK_COSTS[i]; var pos = fieldPositions[i]; var fx = offsetX + pos.x; var fy = offsetY + pos.y; // Skip drawing fences f.placeWheats(fx, fy, FIELD_W, FIELD_H, WHEAT_PER_FIELD); if (f.locked) { // Center of field f.showLock(fx + FIELD_W / 2, fy + FIELD_H / 2); } game.addChild(f); fields.push(f); } // Center reference point for positions var centerX = offsetX + FIELD_W; var centerY = offsetY + FIELD_H - 250; // --- Create farmer --- farmer = new Farmer(); farmer.x = storage.farmerX || centerX; farmer.y = storage.farmerY || centerY - 120; // Start at center area game.addChild(farmer); // --- Create sickle (attached to farmer's hand) --- sickle = LK.getAsset('sickle', { anchorX: 0.2, // hand position, left side of ellipse anchorY: 0.7, // slightly below center x: 0, y: 30 }); sickle.alpha = 1; // --- Money display --- moneyTxt = new Text2('$' + money, { size: 100, fill: "#fff" }); moneyTxt.anchor.set(0.5, 0); LK.gui.top.addChild(moneyTxt); // --- Shop System --- var shop = new Shop(); game.addChild(shop); // Create shop items shop.createShopItems(); // Shop Button var shopButton = LK.getAsset('centerCircle', { anchorX: 1.0, anchorY: 0.5, scaleX: 3, scaleY: 1.5, tint: 0x00CCFF, alpha: 0.9, x: 2048, y: 2732 / 2 }); game.addChild(shopButton); var shopButtonText = new Text2('SHOP', { size: 70, fill: 0xFFFFFF }); shopButtonText.anchor.set(0.5, 0.5); shopButtonText.x = shopButton.x - shopButton.width / 2; shopButtonText.y = shopButton.y; game.addChild(shopButtonText); // Shop button click handler shopButton.down = function (x, y, obj) { shop.toggleShop(); // Update button color to show state if (shop.isOpen) { shopButton.tint = 0x9900FF; shopButtonText.setText('CLOSE'); } else { shopButton.tint = 0x00CCFF; shopButtonText.setText('SHOP'); } // Block player movement when clicking shop button playerMovementBlockedByUIClick = true; }; // --- Information message on right side --- // Create the info message text var infoMsgTxt = new Text2('Game controls: Use mouse to move.\nFor mobile, tap to move.', { size: 80, fill: "#fff" }); infoMsgTxt.anchor.set(1, 0.5); // Right align, vertically centered // Position at right side, vertically centered (avoid top 100px for menu) infoMsgTxt.x = 2048 - 40; // 40px padding from right edge infoMsgTxt.y = 2732 / 2; game.addChild(infoMsgTxt); // Hide after 30 seconds (1800 frames at 60fps) LK.setTimeout(function () { if (infoMsgTxt && infoMsgTxt.parent) { infoMsgTxt.destroy(); } }, 30000); // --- Instruction message for Automatic Collect --- // Create the instruction message text var instructionMsgTxt = new Text2('To use Automatic Collect, move your mouse over the wheat.', { size: 50, // Smaller font size for better visibility fill: 0xFFCC00 // Bright yellow for contrast }); instructionMsgTxt.anchor.set(0.5, 0.5); // Center align instructionMsgTxt.x = 2048 / 2; // Center horizontally instructionMsgTxt.y = 2732 / 2; // Center vertically instructionMsgTxt.visible = false; // Initially hidden game.addChild(instructionMsgTxt); // Show instruction message after 30 seconds LK.setTimeout(function () { instructionMsgTxt.visible = true; // Hide instruction message after 30 seconds LK.setTimeout(function () { if (instructionMsgTxt && instructionMsgTxt.parent) { instructionMsgTxt.destroy(); } }, 30000); }, 30000); // --- Message for unlocking Automatic Collect --- // Create the unlock message text var unlockMsgTxt = new Text2('You need 30,000 money to unlock Automatic Collect.', { size: 70, // Medium font size fill: 0xFFFFFF // White color for contrast }); unlockMsgTxt.anchor.set(0.5, 0.5); // Center align unlockMsgTxt.x = 2048 / 2; // Center horizontally unlockMsgTxt.y = 2732 / 2; // Center vertically unlockMsgTxt.visible = false; // Initially hidden game.addChild(unlockMsgTxt); // Show unlock message after 60 seconds LK.setTimeout(function () { unlockMsgTxt.visible = true; // Hide unlock message after 30 seconds LK.setTimeout(function () { if (unlockMsgTxt && unlockMsgTxt.parent) { unlockMsgTxt.destroy(); } }, 30000); }, 60000); // --- Missions UI --- // "Missions" title var missionsTitle = new Text2('Missions', { size: 90, fill: "#fff" }); missionsTitle.anchor.set(0, 0); // Left align, top // Place on the left side of the center part of the screen var missionAreaX = 180; // 180px from left edge, safe from menu var missionAreaY = 120; // Below top menu area missionsTitle.x = missionAreaX; missionsTitle.y = missionAreaY; game.addChild(missionsTitle); // Mission bar background (smaller, left side) var missionBarBg = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0, x: missionAreaX, y: missionsTitle.y + missionsTitle.height + 18, scaleX: 2.2, scaleY: 0.5, alpha: 0.25 }); game.addChild(missionBarBg); // Mission bar fill (progress) var missionBarFill = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0, x: missionAreaX, y: missionsTitle.y + missionsTitle.height + 18, scaleX: 0, // Will be set dynamically scaleY: 0.5, tint: 0xFFD700, // Gold color alpha: 0.85 }); game.addChild(missionBarFill); // Mission text var missionText = new Text2('Reach $100,000', { size: 60, fill: "#fff" }); missionText.anchor.set(0, 0); missionText.x = missionAreaX + 10; missionText.y = missionBarBg.y + missionBarBg.height + 8; game.addChild(missionText); // Store for update var missionBarMaxWidth = 200; // px, visually (not used, but kept for reference) var missionBarFillMaxScale = 2.2; // --- Helper: update money display --- function _updateMoneyDisplay() { moneyTxt.setText('$' + money); // --- Missions progress update --- if (typeof missionBarFill !== "undefined") { // Clamp progress between 0 and 1 var progress = Math.max(0, Math.min(1, money / 100000)); missionBarFill.scaleX = missionBarFillMaxScale * progress; } // --- Mission complete: You Win! --- if (money >= 100000 && !game._missionWinShown) { game._missionWinShown = true; LK.showYouWin(); // Reset player position and money farmer.x = centerX; farmer.y = centerY - 120; money = 0; _updateMoneyDisplay(); } } // --- Helper: unlock field if enough money --- function tryUnlockField(fieldIdx) { var f = fields[fieldIdx]; if (!f.locked) return; if (money >= f.lockCost) { money -= f.lockCost; _updateMoneyDisplay(); f.locked = false; f.hideLock(); // Update unlockedFields in storage only if changed var unlockedFields = storage.unlockedFields || [true, false, false, false]; if (!unlockedFields[fieldIdx]) { unlockedFields[fieldIdx] = true; storage.unlockedFields = unlockedFields; } // Flash field green for (var i = 0; i < f.fenceNodes.length; ++i) { LK.effects.flashObject(f.fenceNodes[i], 0x00ff00, 600); } } else { // Not enough money, flash red LK.effects.flashScreen(0xff0000, 400); } } // --- Touch/mouse handling --- var lastDownX = 0, lastDownY = 0; var harvestMode = false; var harvestWheat = null; var harvestedCrops = []; // Track harvested crops during swipe // Helper: find harvestable vegetable under (x, y) in unlocked fields function findHarvestableWheat(x, y) { for (var i = 0; i < fields.length; ++i) { var f = fields[i]; if (f.locked) continue; for (var j = 0; j < f.wheats.length; ++j) { var w = f.wheats[j]; if (w.isHarvestable()) { // Use bounding box for hit var wx = w.x, wy = w.y; var ww = 60, wh = 80; if (x >= wx - ww / 2 && x <= wx + ww / 2 && y >= wy - wh && y <= wy) { return w; } } } } return null; } // Helper: find locked field under (x, y) function findLockedField(x, y) { for (var i = 0; i < fields.length; ++i) { var f = fields[i]; if (!f.locked) continue; // Use field area var pos = fieldPositions[i]; var fx = offsetX + pos.x; var fy = offsetY + pos.y; if (x >= fx && x <= fx + FIELD_W && y >= fy && y <= fy + FIELD_H) { return i; } } return -1; } // --- Game event handlers --- // Move farmer or harvest wheat game.down = function (x, y, obj) { // If UI handled this click, do nothing for game movement. if (playerMovementBlockedByUIClick) { playerMovementBlockedByUIClick = false; // Reset flag for next input return; } // Check if clicking on shop area when shop is open if (shop && shop.isOpen) { // Check if clicking on shop background area var shopCenterX = 2048 / 2; var shopCenterY = 2732 / 2; var shopWidth = 900; var shopHeight = 1200; if (x >= shopCenterX - shopWidth / 2 && x <= shopCenterX + shopWidth / 2 && y >= shopCenterY - shopHeight / 2 && y <= shopCenterY + shopHeight / 2) { // Click is within shop area, don't move farmer return; } else { // Click outside shop area, close shop shop.closeShop(); shopButton.tint = 0x00CCFF; shopButtonText.setText('SHOP'); } } lastDownX = x; lastDownY = y; // Check if tapping on locked field unlock button var lockedIdx = findLockedField(x, y); if (lockedIdx >= 0) { var f = fields[lockedIdx]; // If tap is near lock icon or unlock text var centerX = offsetX + fieldPositions[lockedIdx].x + FIELD_W / 2; var centerY = offsetY + fieldPositions[lockedIdx].y + FIELD_H / 2; var dist = Math.sqrt((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY)); if (dist < 120) { tryUnlockField(lockedIdx); return; } } // Check for wheat var w = findHarvestableWheat(x, y); if (w) { harvestMode = true; harvestWheat = w; // Change player to face forward during harvest // Switch to player_down for harvesting if (farmer.currentAsset) { farmer.currentAsset.alpha = 0; } var playerDown = LK.getAsset('player_down', { anchorX: 0.5, anchorY: 0.5 }); playerDown.alpha = 1; farmer.addChild(playerDown); farmer.currentAsset = playerDown; // Trigger sickle attack animation farmer.attack(); // Show harvest animation effect var harvestEffect = LK.getAsset('sprout', { anchorX: 0.5, anchorY: 0.5, x: w.x, y: w.y - 50, alpha: 0.8, scaleX: 2, scaleY: 2 }); game.addChild(harvestEffect); // Animate the harvest effect tween(harvestEffect, { alpha: 0, y: harvestEffect.y - 100 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { harvestEffect.destroy(); } }); // Harvest w.setHarvested(true); var reward = 100 * (FIELD_REWARD_MULT[w.fieldIndex] || 1); money += reward; _updateMoneyDisplay(); // Flash wheat LK.effects.flashObject(w, 0xffff00, 300); // No setHarvested(false) here; regrow/removal handled in Wheat.update harvestMode = false; harvestWheat = null; return; } // Move farmer with animation farmer.moveTo(x, y); dragging = true; dragOffsetX = x - farmer.x; dragOffsetY = y - farmer.y; }; // Drag farmer game.move = function (x, y, obj) { // If UI interaction blocked the start of a drag, this helps. if (playerMovementBlockedByUIClick) { // Flag will be reset by the next 'down' event, or could be reset here if necessary, // but typically 'move' follows a 'down' that wasn't blocked. return; } // Shop system completely removed // if (dragging) { farmer.moveTo(x - dragOffsetX, y - dragOffsetY); } if (swipeModeActive) { sickle.x = x; sickle.y = y; // Check for new harvestable crops under the swipe var newHarvestWheat = findHarvestableWheat(x, y); if (newHarvestWheat && !harvestedCrops.includes(newHarvestWheat)) { harvestedCrops.push(newHarvestWheat); newHarvestWheat.setHarvested(true); var reward = 100 * (FIELD_REWARD_MULT[newHarvestWheat.fieldIndex] || 1); money += reward; _updateMoneyDisplay(); LK.effects.flashObject(newHarvestWheat, 0xffff00, 300); } } }; // End drag/harvest game.up = function (x, y, obj) { // If UI interaction blocked the 'down' event, 'up' should also be controlled. if (playerMovementBlockedByUIClick) { playerMovementBlockedByUIClick = false; // Reset flag here as well return; } // Shop system completely removed // // dragging = false; harvestMode = false; harvestWheat = null; harvestedCrops = []; // Reset harvested crops tracking // swipeModeActive = false; // Optional: Deactivate swipe mode on release }; // --- Main update loop --- // Defensive: If game is reset, clear win timer game.update = function () { // Update farmer farmer.update(); // Update wheat regrow for (var i = 0; i < fields.length; ++i) { var f = fields[i]; f.wheats.forEach(function (wheat) { wheat.update(); }); } // Update clouds for (var i = 0; i < clouds.length; i++) { clouds[i].update(); } // Update birds for (var i = 0; i < birds.length; i++) { birds[i].update(); } // Update zombies for (var i = 0; i < zombies.length; i++) { zombies[i].update(); } }; // --- Create areas and place animals --- // Calculate center of game screen var gameWidth = 2048; var gameHeight = 2732; var gameCenterX = gameWidth / 2; var gameCenterY = gameHeight / 2; // Create the four areas at equal distances from center // Area_Left var areaLeft = new Container(); areaLeft.x = gameCenterX - AREA_DISTANCE; areaLeft.y = gameCenterY; areaLeft.name = "Area_Left"; game.addChild(areaLeft); areas.push(areaLeft); // Area_Right var areaRight = new Container(); areaRight.x = gameCenterX + AREA_DISTANCE; areaRight.y = gameCenterY; areaRight.name = "Area_Right"; game.addChild(areaRight); areas.push(areaRight); // Area_Top var areaTop = new Container(); areaTop.x = gameCenterX; areaTop.y = gameCenterY - AREA_DISTANCE; areaTop.name = "Area_Top"; game.addChild(areaTop); areas.push(areaTop); // Area_Bottom var areaBottom = new Container(); areaBottom.x = gameCenterX; areaBottom.y = gameCenterY + AREA_DISTANCE; areaBottom.name = "Area_Bottom"; game.addChild(areaBottom); areas.push(areaBottom); // Place animals in the areas // Animal_Right at bottom right of screen var animalRight = new Animal(); animalRight.setAnimalImage('animal_right'); animalRight.name = "Animal_Right"; // Place at bottom right, accounting for anchor (0.5, 0.5) and asset size var animalRightAsset = LK.getAsset('animal_right', { anchorX: 0.5, anchorY: 0.5 }); animalRight.x = gameWidth - animalRightAsset.width / 2 - 10; // 10px padding from right animalRight.y = gameHeight - animalRightAsset.height / 2 - 10; // 10px padding from bottom game.addChild(animalRight); animals.push(animalRight); // Area_Bottom has no animal // --- Create clouds --- var clouds = []; // Create clouds at different positions with increased delay function createClouds() { // Reuse existing clouds or create new ones if pool is empty var cloud; if (clouds.length > 0) { cloud = clouds.pop(); cloud.alpha = 1; // Reset alpha for visibility cloud.visible = true; // Ensure cloud is visible cloud.init(); // Reinitialize cloud properties } else { cloud = new Cloud(); game.addChild(cloud); cloud.init(); // Initialize cloud properties } // Cloud width for calculations - cached outside for performance var cloudWidth = 500; cloud.x = -cloudWidth / 2; // Start from off-screen left cloud.y = 180; // Higher position near the top cloud.layer = 0; // Front layer - this will be in front cloud.init(); // Initialize movement and timing clouds.push(cloud); // Schedule creation of new clouds after these disappear - extended time LK.setTimeout(createClouds, 180000); // 180 seconds to spread out cloud creation more } // Start creating clouds createClouds(); // Shop system completely removed // --- Create zombie --- var zombie = null; var zombieDamageTimer = 0; // Timer to prevent continuous damage var zombieDamageAmount = 500; // Initial zombie damage/cost var zombieAppearCount = 0; // How many times zombie has appeared // --- Create birds --- var zombies = []; var birds = []; // Create a bird that starts at the top, flies across, disappears, and restarts in a loop function createBird() { // Avoid overlapping timers - clear any existing if (window._birdCreationTimer) { LK.clearTimeout(window._birdCreationTimer); window._birdCreationTimer = null; } // Reuse existing birds or create new ones if pool is empty var bird; if (birds.length > 0) { bird = birds.pop(); bird.alpha = 1; // Reset alpha for visibility bird.visible = true; // Ensure bird is visible bird.init(); // Reinitialize bird properties } else { bird = new Bird(); game.addChild(bird); bird.init(); // Initialize bird properties } // Cache bird dimensions for better performance var birdWidth = 350; // Use known width instead of creating temporary asset var birdHeight = 350; // Use known height bird.x = -birdWidth / 2; bird.y = birdHeight / 2 + 20; // 20px padding from the very top bird.init(); birds.push(bird); // Simple flag to prevent duplicate scheduling bird._nextBirdScheduled = false; // Optimized check function that runs less frequently bird._birdLoopCheck = function () { // Only schedule new bird once if this one is gone if ((!bird.parent || bird.alpha <= 0) && !bird._nextBirdScheduled) { bird._nextBirdScheduled = true; // Create new bird after a longer delay to reduce processing frequency window._birdCreationTimer = LK.setTimeout(createBird, 240000); // 240 seconds (4 min) delay for less frequent processing } else if (bird.parent && bird.alpha > 0) { // Check much less frequently to reduce timer overhead LK.setTimeout(bird._birdLoopCheck, 30000); // Check every 30 seconds instead of 15 } }; // Start the check after a longer delay LK.setTimeout(bird._birdLoopCheck, 30000); } // Start creating birds after 1 minute (60000 ms) LK.setTimeout(createBird, 60000); // Play background music in a loop LK.playMusic('backgroundMusic', { loop: true }); // --- Initial money display --- _updateMoneyDisplay(); // --- Initialize farmer's sickle appearance --- if (shop) { shop.updateFarmerSickle(); } // --- Place trees at corners --- // Tree size var treeWidth = 400; var treeHeight = 532; // Top left corner tree var topLeftTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: offsetX / 2, y: offsetY / 2 }); game.addChild(topLeftTree); // Top right corner tree var topRightTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: 2048 - offsetX / 2, y: offsetY / 2 }); game.addChild(topRightTree); // Bottom left corner tree var bottomLeftTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: offsetX / 2, y: 2732 - offsetY / 2 }); game.addChild(bottomLeftTree); // Bottom right corner tree var bottomRightTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: 2048 - offsetX / 2, y: 2732 - offsetY / 2 }); game.addChild(bottomRightTree); // --- Place trees at middle sides aligned with corner trees --- // Tree to the left of center var leftCenterTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: offsetX / 2, y: topRightTree.y }); game.addChild(leftCenterTree); // Tree to the right of center var rightCenterTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: 2048 - offsetX / 2, y: topRightTree.y }); game.addChild(rightCenterTree); // --- Add Rooster that moves left-to-right, disappears at right edge, reappears after 40s and repeats --- var rooster = null; var roosterTimeout = null; function spawnRooster() { // Remove any existing rooster - with robust null check if (rooster) { // Only try to destroy if rooster exists and has a parent if (rooster && rooster.parent) { try { rooster.destroy(); } catch (e) { console.log("Error destroying rooster:", e); } } rooster = null; } rooster = new Rooster(); // Start at the left center of the screen rooster.y = 2732 / 2; rooster.x = rooster.roosterFrames[0].width / 2 + 10; game.addChild(rooster); // Rooster path: left-to-right, horizontally centered var roosterStartX = rooster.roosterFrames[0].width / 2 + 10; var roosterEndX = 2048 - rooster.roosterFrames[0].width / 2 - 10; var roosterSpeed = 1; // px per frame, very slow movement rooster.targetX = roosterEndX; rooster.direction = 1; // 1: moving right rooster.updateRoosterMovement = function () { // Track lastX for edge detection if (typeof rooster.lastX === "undefined") rooster.lastX = rooster.x; // Move only horizontally in the center var dx = rooster.targetX - rooster.x; var dist = Math.abs(dx); if (dist < roosterSpeed) { rooster.x = rooster.targetX; } else { rooster.x += roosterSpeed * (dx > 0 ? 1 : -1); } // Call animation update if (typeof rooster.update === "function") { rooster.update(); } // Check if rooster just reached the right edge (disappear trigger) if (rooster.lastX < roosterEndX && rooster.x >= roosterEndX) { // Fade out and destroy, then respawn after 40s tween(rooster, { alpha: 0 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { if (rooster && rooster.parent) { rooster.destroy(); } roosterTimeout = LK.setTimeout(spawnRooster, 40000); // 40 seconds } }); } // Update lastX for next frame rooster.lastX = rooster.x; }; } // Add rooster update to main game loop var oldGameUpdate = game.update; game.update = function () { if (typeof oldGameUpdate === "function") oldGameUpdate(); if (rooster && rooster.parent && typeof rooster.updateRoosterMovement === "function") { rooster.updateRoosterMovement(); } // Update zombie if (zombie && zombie.parent) { zombie.update(); // Collision detection with player (only triggers on state change) var isIntersecting = zombie.intersects(farmer); // Check if we just started intersecting if (!zombie.lastWasIntersecting && isIntersecting && zombieDamageTimer <= 0) { // Zombie just touched the player, deduct gold money = Math.max(0, money - zombieDamageAmount); _updateMoneyDisplay(); // Flash both zombie and farmer red LK.effects.flashObject(zombie, 0xff0000, 500); LK.effects.flashObject(farmer, 0xff0000, 500); // Set cooldown timer to prevent continuous damage (3 second cooldown) zombieDamageTimer = 180; } // Update intersection state zombie.lastWasIntersecting = isIntersecting; // Update damage cooldown timer if (zombieDamageTimer > 0) { zombieDamageTimer--; } } storage.farmerX = farmer.x; storage.farmerY = farmer.y; storage.money = money; }; // Create the zombie function createZombie() { // Reuse existing zombie or create new one if pool is empty var zombie; if (zombies.length > 0) { zombie = zombies.pop(); zombie.alpha = 1; // Reset alpha for visibility zombie.visible = true; // Ensure zombie is visible zombie.isDead = false; // Reset dead state zombie.init(); // Reinitialize zombie properties } else { zombie = new Zombie(); game.addChild(zombie); } // Reset zombie properties for reuse zombie.alpha = 1; zombie.isDead = false; // Position zombie off-screen to the left zombie.x = -100; zombie.y = 2732 / 2; // Initialize tracking variables zombie.lastX = zombie.x; zombie.lastY = zombie.y; zombie.lastWasIntersecting = false; // Increase zombie damage each time it spawns zombieAppearCount++; if (zombieAppearCount === 1) { zombieDamageAmount = 500; } else { zombieDamageAmount = zombieDamageAmount * 2; } // Schedule next zombie creation with increased delay LK.setTimeout(createZombie, 120000); // 120 seconds delay for next zombie } // Start the first rooster and create zombie spawnRooster(); // Delay the first zombie spawn by 40 seconds after game start LK.setTimeout(createZombie, 40000); // Zombie respawn is now handled after being killed by the player; // --- Time and Season System --- // --- Day and Season Variables --- var currentDay = storage.currentDay || 1; var currentSeason = storage.currentSeason || "Summer"; var SEASONS = ["Summer", "Autumn"]; var seasonIndex = SEASONS.indexOf(currentSeason); if (seasonIndex === -1) seasonIndex = 0; var autumnColors = [0xC97A3A, 0xB94E2A, 0xA65C1B, 0xE07B39, 0xD2691E, 0xB22222, 0x8B4513]; var autumnLeafAssets = []; // Will hold leaf particles var autumnLeavesActive = false; var autumnCropSlowdown = 2; // Crops grow 2x slower in autumn var autumnNightStartHour = 18; // Night starts earlier (not implemented, placeholder) var autumnGrassColor = 0xB97A56; // Dry grass color // --- UI Elements for Day and Season --- var dayTxt = new Text2('Day ' + currentDay, { size: 80, fill: "#fff" }); dayTxt.anchor.set(1, 0); dayTxt.x = 2048 - 40; // Right side, 40px padding dayTxt.y = 40; // Top, 40px padding game.addChild(dayTxt); var seasonTxt = new Text2(SEASONS[seasonIndex], { size: 80, fill: "#fff" }); seasonTxt.anchor.set(1, 0); seasonTxt.x = 2048 - 40; // Right side, 40px padding seasonTxt.y = 120; // Below day text game.addChild(seasonTxt); // --- Autumn Effects: Falling Leaves --- function spawnAutumnLeaves() { if (autumnLeavesActive) return; autumnLeavesActive = true; // Remove any old leaves for (var i = 0; i < autumnLeafAssets.length; ++i) { if (autumnLeafAssets[i] && autumnLeafAssets[i].parent) { try { autumnLeafAssets[i].destroy(); } catch (e) {} } } autumnLeafAssets = []; // Spawn 20 leaves at random positions at the top for (var i = 0; i < 20; ++i) { var color = autumnColors[Math.floor(Math.random() * autumnColors.length)]; var leaf = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.25 + Math.random() * 0.2, scaleY: 0.12 + Math.random() * 0.1, tint: color, alpha: 0.7 + Math.random() * 0.3, x: Math.random() * 2048, y: -30 - Math.random() * 100 }); leaf._fallSpeed = 1.5 + Math.random() * 1.5; leaf._drift = (Math.random() - 0.5) * 2; leaf._spin = (Math.random() - 0.5) * 0.1; game.addChild(leaf); autumnLeafAssets.push(leaf); } } // --- Remove Autumn Leaves --- function removeAutumnLeaves() { autumnLeavesActive = false; for (var i = 0; i < autumnLeafAssets.length; ++i) { if (autumnLeafAssets[i] && autumnLeafAssets[i].parent) { try { autumnLeafAssets[i].destroy(); } catch (e) {} } } autumnLeafAssets = []; } // --- Update Autumn Leaves --- function updateAutumnLeaves() { if (!autumnLeavesActive) return; for (var i = 0; i < autumnLeafAssets.length; ++i) { var leaf = autumnLeafAssets[i]; if (!leaf) continue; leaf.y += leaf._fallSpeed; leaf.x += leaf._drift; leaf.rotation += leaf._spin; // Respawn leaf at top if it falls below screen if (leaf.y > 2732 + 30) { leaf.y = -30 - Math.random() * 100; leaf.x = Math.random() * 2048; leaf._fallSpeed = 1.5 + Math.random() * 1.5; leaf._drift = (Math.random() - 0.5) * 2; leaf._spin = (Math.random() - 0.5) * 0.1; } } } // --- Crop Growth Slowdown Helper --- function getCropGrowthModifier() { return SEASONS[seasonIndex] === "Autumn" ? autumnCropSlowdown : 1; } // --- Update Day and Season --- function updateDayAndSeason() { currentDay++; // Change season every 3 days if (currentDay > 3) { currentDay = 1; seasonIndex = (seasonIndex + 1) % SEASONS.length; currentSeason = SEASONS[seasonIndex]; // Visual changes for each season if (currentSeason === "Autumn") { game.setBackgroundColor(autumnGrassColor); spawnAutumnLeaves(); } else { // Summer: restore green grass, remove leaves game.setBackgroundColor(0x4caf50); removeAutumnLeaves(); } } dayTxt.setText('Day ' + currentDay); seasonTxt.setText(currentSeason); storage.currentDay = currentDay; storage.currentSeason = currentSeason; } // --- Apply Crop Growth Slowdown in Autumn --- // Patch all crop regrowTime on season change function applySeasonalCropGrowth() { for (var i = 0; i < fields.length; ++i) { var f = fields[i]; for (var j = 0; j < f.wheats.length; ++j) { var crop = f.wheats[j]; if (typeof crop._baseRegrowTime === "undefined") { crop._baseRegrowTime = crop.regrowTime; } crop.regrowTime = crop._baseRegrowTime * getCropGrowthModifier(); } } } // --- Patch updateDayAndSeason to also update crop growth --- var _oldUpdateDayAndSeason = updateDayAndSeason; updateDayAndSeason = function updateDayAndSeason() { _oldUpdateDayAndSeason(); applySeasonalCropGrowth(); }; // --- Initial Season Visuals and Crop Growth --- if (currentSeason === "Autumn") { game.setBackgroundColor(autumnGrassColor); spawnAutumnLeaves(); } else { game.setBackgroundColor(0x4caf50); removeAutumnLeaves(); } applySeasonalCropGrowth(); // --- Set interval to update day and season every minute (for testing) --- LK.setInterval(updateDayAndSeason, 60000); // --- Patch main game update to animate autumn leaves --- var _oldGameUpdateForSeason = game.update; game.update = function () { if (typeof _oldGameUpdateForSeason === "function") _oldGameUpdateForSeason(); updateAutumnLeaves(); }; // Add Swipe Mode Button to the game UI var swipeModeButton = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, // Centered horizontally y: 2732 - 150, // 150 pixels above the bottom edge for better visibility // 100 pixels above the bottom edge scaleX: 4.5, // Width: 450 px for better visibility scaleY: 2.0, // Height: 200 px for better visibility // Height: 150 px tint: 0xFFD700, // Gold color alpha: 0.85, visible: money >= 10000 // Initially hidden if money is less than 10,000 }); game.addChild(swipeModeButton); var swipeModeText = new Text2('Automatic Collect\n$30,000', { size: 80, fill: 0x32CD32 // Bright green color }); swipeModeText.anchor.set(0.5, 0.5); swipeModeText.x = swipeModeButton.x; swipeModeText.y = swipeModeButton.y; swipeModeText.visible = money >= 10000; // Initially hidden if money is less than 10,000 game.addChild(swipeModeText); var swipeModeActive = false; var swipeModeUnlocked = false; // Track if the feature has been unlocked // Toggle Automatic Harvest Mode on button click swipeModeButton.down = function (x, y, obj) { if (!swipeModeUnlocked && money >= 30000) { money -= 30000; _updateMoneyDisplay(); swipeModeUnlocked = true; swipeModeActive = true; // Removed persistent storage update for swipeModeUnlocked swipeModeButton.tint = 0x00FF00; // Change to green when active swipeModeText.setText('Automatic Collect'); console.log("Automatic Collection Mode Activated"); } else if (swipeModeUnlocked) { swipeModeActive = !swipeModeActive; swipeModeButton.tint = swipeModeActive ? 0x00FF00 : 0xFFD700; // Toggle color swipeModeText.setText('Automatic Collect'); console.log(swipeModeActive ? "Automatic Collection Mode Activated" : "Automatic Collection Mode Deactivated"); } else { console.log("Not enough money to unlock Automatic Collection"); } }; // Update visibility of the button based on money function updateButtonVisibility() { if (swipeModeUnlocked) { swipeModeButton.visible = true; swipeModeText.visible = true; swipeModeText.setText('Automatic Collect'); } else if (money >= 30000) { swipeModeButton.visible = true; swipeModeText.visible = true; swipeModeText.setText('Unlock - $30,000'); } else { swipeModeButton.visible = false; swipeModeText.visible = false; } } // Call updateButtonVisibility whenever money changes _updateMoneyDisplay = function updateMoneyDisplay() { moneyTxt.setText('$' + money); if (typeof missionBarFill !== "undefined") { var progress = Math.max(0, Math.min(1, money / 100000)); missionBarFill.scaleX = missionBarFillMaxScale * progress; } if (money >= 100000 && !game._missionWinShown) { game._missionWinShown = true; LK.showYouWin(); farmer.x = centerX; farmer.y = centerY - 120; money = 0; _updateMoneyDisplay(); } updateButtonVisibility(); // Check button visibility };
===================================================================
--- original.js
+++ change.js
@@ -1363,19 +1363,19 @@
/****
* Game Code
****/
-// Area 4
-// Area 3
-// Area 2
-// Lock icon (ellipse, gray)
-// Sickle (ellipse, yellow)
-// House (box)
-// Farmer (box)
-// Wheat (ellipse)
-// Field fence (rectangle)
-// --- Game constants ---
// Rooster animation frames (replace id values with your own image ids)
+// --- Game constants ---
+// Field fence (rectangle)
+// Wheat (ellipse)
+// Farmer (box)
+// House (box)
+// Sickle (ellipse, yellow)
+// Lock icon (ellipse, gray)
+// Area 2
+// Area 3
+// Area 4
var FIELD_W = 900;
var FIELD_H = 900;
var FIELD_GAP = 120; // Increased gap to move fences further from center
var FIELD_COUNT = 4;
@@ -1486,24 +1486,24 @@
// Create shop items
shop.createShopItems();
// Shop Button
var shopButton = LK.getAsset('centerCircle', {
- anchorX: 0.5,
+ anchorX: 1.0,
anchorY: 0.5,
scaleX: 3,
scaleY: 1.5,
tint: 0x00CCFF,
alpha: 0.9,
- x: 2048 / 2 + 300,
+ x: 2048,
y: 2732 / 2
});
game.addChild(shopButton);
var shopButtonText = new Text2('SHOP', {
size: 70,
fill: 0xFFFFFF
});
shopButtonText.anchor.set(0.5, 0.5);
-shopButtonText.x = shopButton.x;
+shopButtonText.x = shopButton.x - shopButton.width / 2;
shopButtonText.y = shopButton.y;
game.addChild(shopButtonText);
// Shop button click handler
shopButton.down = function (x, y, obj) {