User prompt
Increase the size of the mower shop panel
User prompt
Move the shop button to the bottom right
User prompt
Can you move the mower shop close button to the top right
User prompt
Move the main menu button to the top right corner
User prompt
Add multiple grass types to the game, each with unique characteristics and challenges to increase variety and replayability. For example: - Kentucky Bluegrass: standard density, easy to mow. - Bermuda Grass: grows in thick patches, slows mower speed. - Zoysia: regrows quickly, requiring repeated mowing. - Ryegrass: clogs the mower collector faster, needs more frequent emptying. - Fescue: harder to see, blends into the environment. Assign grass types to different zones or biomes, with new types unlocking as the player progresses. Each grass type should have distinct visuals, sounds, and mowing effects. Cutting more challenging grass types should reward players with extra money or bonuses. Display a small icon or tooltip when hovering over a patch to identify its type and challenge. Encourage players to experiment with different mower attachments or strategies to handle specific grass types.
User prompt
Can you increase the text size of the money and move it right above the lawn plots
User prompt
Move the shop button to the bottom right corner
User prompt
Add a shop feature where players can spend earned money on a variety of special mower attachments and consumable power-ups (not just permanent upgrades). Examples include: • A grass collector that lets players mow longer before emptying clippings • A turbo booster for temporary speed bursts • Decorative mower skins and trail effects for personalization • A mulching attachment that gives bonus money for perfectly trimmed lawns • Temporary magnet power-ups that pull in nearby grass clippings automatically • Fun gadgets like a robotic helper or pet that follows the player and collects stray clippings Make these items unlock progressively as the player advances, and display them in an appealing in-game shop menu. Each attachment or power-up should have a clear, satisfying effect on gameplay and encourage players to try new strategies or play styles. Include visual and sound feedback when items are equipped or activated to boost the sense of reward. Ensure that players can mix and match attachments for different effects
User prompt
Can you move the upgrade mower button the the bottom center now
User prompt
Can you move it to the bottom left corner of the screen
User prompt
Can you make the upgrade mower button bigger
User prompt
Please fix the bug: 'Can't find variable: upgradeButton' in or related to this line: 'upgradeButton.setEnabled(money >= upgradeButton.price);' Line Number: 228
User prompt
Can we swap out the Mower button for a shop button
User prompt
move the upgrade button to the top right corner under the money ui
User prompt
add in more plots
User prompt
move the mower above both grass layers
User prompt
Make it so that the mower is above the plots
User prompt
add in more plots and center them again
User prompt
add in more plots and center it
User prompt
Create a shop where players can buy better mowers (Good - mows 2 spots and the bag holds 20, better - mows 4 spots and the bag holds 30, best - mows 8 spots and the bag holds 100 but it cost 10000)
Code edit (1 edits merged)
Please save this source code
User prompt
Infinite Lawn Master
Initial prompt
Create a point and click grass cutting simulator where players cut grass infinitely, empty out the bag when full, and earn money for each plot of grass cut after cut the grass will grow back after a short time players will use the money earned to buy mowers that will cover bigger areas and not need to be dumped as often
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
money: 0,
mowerLevel: 1,
bagCapacity: 10,
cutArea: 1
});
/****
* Classes
****/
var EmptyBagButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x44aa44
});
self.buttonText = new Text2("Empty Bag", {
size: 40,
fill: 0xFFFFFF
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
self.down = function (x, y, obj) {
if (currentBag > 0) {
currentBag = 0;
LK.getSound('emptyBag').play();
updateUI();
}
};
return self;
});
var GrassTile = Container.expand(function () {
var self = Container.call(this);
self.isGrowing = false;
self.isCut = false;
self.growthTime = 0;
self.maxGrowthTime = 300;
var grassGraphics = self.attachAsset('grass', {
anchorX: 0.5,
anchorY: 0.5
});
self.cut = function () {
if (!self.isCut) {
self.isCut = true;
self.isGrowing = false;
self.growthTime = 0;
grassGraphics.alpha = 0.3;
return true;
}
return false;
};
self.startGrowing = function () {
if (self.isCut && !self.isGrowing) {
self.isGrowing = true;
}
};
self.update = function () {
if (self.isGrowing) {
self.growthTime++;
if (self.growthTime >= self.maxGrowthTime) {
self.isGrowing = false;
self.isCut = false;
grassGraphics.alpha = 1;
}
}
};
self.down = function (x, y, obj) {
if (!self.isCut && currentBag < bagCapacity) {
var success = self.cut();
if (success) {
currentBag += 1;
money += moneyPerCut;
LK.getSound('mow').play();
updateUI();
// Start growing after a short delay
LK.setTimeout(function () {
self.startGrowing();
}, 2000);
}
}
};
return self;
});
// ShopButton: Opens the shop menu
var ShopButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x3366cc
});
self.buttonText = new Text2("Shop", {
size: 48,
fill: 0xFFFFFF
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
self.down = function (x, y, obj) {
openShopMenu();
};
return self;
});
// ShopMenu: Displays shop items and handles purchases
var ShopMenu = Container.expand(function () {
var self = Container.call(this);
self.bg = self.attachAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 10,
x: 0,
y: 0,
tint: 0x222244
});
self.bg.alpha = 0.95;
self.title = new Text2("Mower Shop", {
size: 80,
fill: "#fff"
});
self.title.anchor.set(0.5, 0);
self.title.x = 0;
self.title.y = -500;
self.addChild(self.title);
// Shop items will be dynamically created
self.itemButtons = [];
// Close button
var closeBtn = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7,
x: 0,
y: 600,
tint: 0x444444
});
var closeText = new Text2("Close", {
size: 48,
fill: 0xffffff
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 0;
closeText.y = 600;
self.addChild(closeText);
closeBtn.interactive = true;
closeBtn.down = function () {
self.visible = false;
self.parent.removeChild(self);
};
self.addShopItems = function (items) {
// Remove old buttons
for (var i = 0; i < self.itemButtons.length; i++) {
self.removeChild(self.itemButtons[i]);
}
self.itemButtons = [];
// Layout items vertically
for (var i = 0; i < items.length; i++) {
var item = items[i];
var btn = new Container();
var btnBg = btn.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.1,
scaleY: 1.1,
y: 0,
tint: item.owned ? 0x888888 : 0x2288ff
});
var txt = new Text2(item.name + (item.owned ? " (Owned)" : " - $" + item.price), {
size: 40,
fill: item.owned ? "#cccccc" : "#ffffff"
});
txt.anchor.set(0.5, 0.5);
btn.addChild(txt);
btn.x = 0;
btn.y = -300 + i * 180;
btn.interactive = true;
(function (item, btn, btnBg, txt) {
btn.down = function () {
if (item.owned) {
// If consumable, allow to buy again
if (item.type === "consumable" && money >= item.price) {
money -= item.price;
item.onBuy();
updateUI();
btnBg.tint = 0x888888;
txt.setText(item.name + " (Owned)");
LK.effects.flashObject(btn, 0x00ff00, 400);
}
return;
}
if (money >= item.price) {
money -= item.price;
item.owned = true;
item.onBuy();
updateUI();
btnBg.tint = 0x888888;
txt.setText(item.name + " (Owned)");
LK.effects.flashObject(btn, 0x00ff00, 400);
LK.getSound('upgrade').play();
} else {
LK.effects.flashObject(btn, 0xff0000, 400);
}
};
})(item, btn, btnBg, txt);
self.addChild(btn);
self.itemButtons.push(btn);
}
};
return self;
});
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.buttonText = new Text2("Upgrade Mower: $100", {
size: 40,
fill: 0xFFFFFF
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
self.price = 100;
self.enabled = true;
self.updatePrice = function (price) {
self.price = price;
self.buttonText.setText("Upgrade Mower: $" + price);
};
self.setEnabled = function (enabled) {
self.enabled = enabled;
if (enabled) {
buttonGraphics.alpha = 1;
} else {
buttonGraphics.alpha = 0.5;
}
};
self.down = function (x, y, obj) {
if (self.enabled && money >= self.price) {
money -= self.price;
mowerLevel += 1;
// Increase mower capabilities based on level
bagCapacity = 10 + (mowerLevel - 1) * 5;
cutArea = 1 + Math.floor((mowerLevel - 1) / 2);
moneyPerCut = 1 + Math.floor((mowerLevel - 1) / 3);
// Store progress
storage.money = money;
storage.mowerLevel = mowerLevel;
storage.bagCapacity = bagCapacity;
storage.cutArea = cutArea;
// Increase price for next upgrade
self.price = Math.floor(self.price * 1.5);
self.updatePrice(self.price);
LK.getSound('upgrade').play();
updateUI();
// Update mower appearance
updateMower();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
game.setBackgroundColor(0x87ceeb);
// Game variables
var gridSize = 15; // Increased from 12 to 15 for more plots
var tileSize = 80; // Reduced tile size further to fit more plots
var gridSpacing = 8; // Decreased spacing further to fit more tiles
var grassTiles = [];
var money = storage.money || 0;
var mowerLevel = storage.mowerLevel || 1;
var bagCapacity = storage.bagCapacity || 10;
var currentBag = 0;
var cutArea = storage.cutArea || 1;
var moneyPerCut = 1 + Math.floor((mowerLevel - 1) / 3);
// Set up UI elements
var moneyText = new Text2("$" + money, {
size: 60,
fill: 0xFFFFFF
});
moneyText.anchor.set(1, 0);
LK.gui.topRight.addChild(moneyText);
// Add ShopButton below money UI
var shopButton = new ShopButton();
shopButton.x = -160; // Offset to appear below moneyText
shopButton.y = 120;
LK.gui.topRight.addChild(shopButton);
// --- Shop logic ---
var shopItems = [{
id: "collector",
name: "Grass Collector",
price: 150,
owned: storage.collectorOwned || false,
unlockLevel: 1,
type: "attachment",
onBuy: function onBuy() {
collectorEquipped = true;
storage.collectorOwned = true;
bagCapacity += 10;
updateUI();
LK.effects.flashObject(bagContainer, 0x44ff44, 600);
}
}, {
id: "turbo",
name: "Turbo Booster",
price: 120,
owned: false,
unlockLevel: 2,
type: "consumable",
onBuy: function onBuy() {
turboActive = true;
turboTicks = 300;
LK.effects.flashObject(mower, 0x00ffff, 600);
}
}, {
id: "skin1",
name: "Red Flame Skin",
price: 80,
owned: storage.skin1Owned || false,
unlockLevel: 1,
type: "skin",
onBuy: function onBuy() {
mowerSkin = 1;
storage.skin1Owned = true;
updateMower();
LK.effects.flashObject(mower, 0xff2222, 600);
}
}, {
id: "mulcher",
name: "Mulching Attachment",
price: 200,
owned: storage.mulcherOwned || false,
unlockLevel: 3,
type: "attachment",
onBuy: function onBuy() {
mulcherEquipped = true;
storage.mulcherOwned = true;
LK.effects.flashObject(mower, 0x22ff22, 600);
}
}, {
id: "magnet",
name: "Magnet Power-Up",
price: 100,
owned: false,
unlockLevel: 2,
type: "consumable",
onBuy: function onBuy() {
magnetActive = true;
magnetTicks = 360;
LK.effects.flashObject(mower, 0x8888ff, 600);
}
}, {
id: "pet",
name: "Robotic Pet Helper",
price: 300,
owned: storage.petOwned || false,
unlockLevel: 4,
type: "attachment",
onBuy: function onBuy() {
petEquipped = true;
storage.petOwned = true;
LK.effects.flashObject(mower, 0xffff00, 600);
}
}];
// Track equipped/active powerups
var collectorEquipped = storage.collectorOwned || false;
var turboActive = false;
var turboTicks = 0;
var mowerSkin = 0;
var mulcherEquipped = storage.mulcherOwned || false;
var magnetActive = false;
var magnetTicks = 0;
var petEquipped = storage.petOwned || false;
// Open shop menu
function openShopMenu() {
// Only show items unlocked by mowerLevel
var unlocked = [];
for (var i = 0; i < shopItems.length; i++) {
if (mowerLevel >= shopItems[i].unlockLevel) {
unlocked.push(shopItems[i]);
}
}
var shopMenu = new ShopMenu();
shopMenu.x = 2048 / 2;
shopMenu.y = 2732 / 2;
shopMenu.addShopItems(unlocked);
game.addChild(shopMenu);
}
var bagContainer = new Container();
var bagBackground = bagContainer.attachAsset('bagIndicator', {
anchorX: 0,
anchorY: 0.5
});
var bagFillBar = bagContainer.attachAsset('bagFill', {
anchorX: 0,
anchorY: 0.5,
x: 2,
y: 0
});
var bagText = new Text2("Bag: 0/" + bagCapacity, {
size: 30,
fill: 0x000000
});
bagText.anchor.set(0.5, 0.5);
bagText.x = 100;
bagContainer.addChild(bagText);
bagContainer.x = 20;
bagContainer.y = 100;
LK.gui.top.addChild(bagContainer);
// Mower graphic (shows cursor position)
var mower = game.attachAsset('mower', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 150
});
// Create upgrade button
var upgradeButton = new UpgradeButton();
// Position at bottom center
upgradeButton.x = 2048 / 2;
upgradeButton.y = 2732 - 180;
upgradeButton.updatePrice(Math.floor(100 * Math.pow(1.5, mowerLevel - 1)));
game.addChild(upgradeButton);
// Create empty bag button
var emptyBagButton = new EmptyBagButton();
emptyBagButton.x = 180;
emptyBagButton.y = 2732 - 180;
game.addChild(emptyBagButton);
// Level text
var levelText = new Text2("Mower Level: " + mowerLevel, {
size: 40,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
levelText.x = 20;
levelText.y = 20;
LK.gui.top.addChild(levelText);
// Create grass grid
function createGrassGrid() {
// Calculate total width and height of the grid
var totalGridWidth = gridSize * tileSize + (gridSize - 1) * gridSpacing;
var totalGridHeight = gridSize * tileSize + (gridSize - 1) * gridSpacing;
// Calculate starting coordinates to center the grid on screen
var startX = (2048 - totalGridWidth) / 2;
var startY = (2732 - totalGridHeight) / 2;
// Make sure the grid is vertically centered with some space for UI
// Adjust vertical position to ensure grid is visible and centered between UI elements
startY = Math.max(startY, 250);
// Ensure grid doesn't go too low
startY = Math.min(startY, 2732 - totalGridHeight - 250);
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var grassTile = new GrassTile();
grassTile.x = startX + col * (tileSize + gridSpacing) + tileSize / 2;
grassTile.y = startY + row * (tileSize + gridSpacing) + tileSize / 2;
game.addChild(grassTile);
grassTiles.push(grassTile);
}
}
}
function updateUI() {
moneyText.setText("$" + money);
// If collector equipped, show bonus capacity
bagText.setText("Bag: " + currentBag + "/" + bagCapacity + (collectorEquipped ? " (Collector)" : ""));
levelText.setText("Mower Level: " + mowerLevel);
// Update bag fill bar
var fillPercent = currentBag / bagCapacity;
bagFillBar.width = Math.max(0, Math.min(196 * fillPercent, 196));
// Update upgrade button state
upgradeButton.setEnabled(money >= upgradeButton.price);
}
function updateMower() {
// Scale mower based on level to indicate its upgraded capabilities
var scale = 1 + (mowerLevel - 1) * 0.1;
tween(mower, {
scaleX: scale,
scaleY: scale
}, {
duration: 500,
easing: tween.easeOut
});
// Change mower color based on level or skin
var level = mowerLevel % 5;
var colors = [0xdd2222, 0xff6600, 0xffcc00, 0x22dd22, 0x2222dd];
if (mowerSkin === 1) {
tween(mower, {
tint: 0xff2222
}, {
duration: 500
});
} else {
tween(mower, {
tint: colors[level]
}, {
duration: 500
});
}
}
// Track mouse/touch position for mower movement
game.move = function (x, y) {
mower.x = x;
mower.y = y;
};
// Handle multi-cut based on mower level
game.down = function (x, y) {
if (currentBag >= bagCapacity) return;
// Find the closest grass tile to the click position
var closestTile = null;
var closestDist = Number.MAX_VALUE;
for (var i = 0; i < grassTiles.length; i++) {
var tile = grassTiles[i];
var dx = tile.x - x;
var dy = tile.y - y;
var dist = dx * dx + dy * dy;
if (dist < closestDist) {
closestDist = dist;
closestTile = tile;
}
}
// Only proceed if we're close enough to a tile
if (closestTile && closestDist < tileSize * tileSize / 2) {
// Find the index of the closest tile
var tileIndex = grassTiles.indexOf(closestTile);
if (tileIndex !== -1) {
var row = Math.floor(tileIndex / gridSize);
var col = tileIndex % gridSize;
// Cut the tile and adjacent tiles based on cutArea
for (var r = Math.max(0, row - cutArea + 1); r <= Math.min(gridSize - 1, row + cutArea - 1); r++) {
for (var c = Math.max(0, col - cutArea + 1); c <= Math.min(gridSize - 1, col + cutArea - 1); c++) {
var targetIndex = r * gridSize + c;
var targetTile = grassTiles[targetIndex];
if (targetTile && !targetTile.isCut && currentBag < bagCapacity) {
var success = targetTile.cut();
if (success) {
currentBag += 1;
money += moneyPerCut;
// Start growing after a short delay
(function (tile) {
LK.setTimeout(function () {
tile.startGrowing();
}, 2000 + Math.random() * 1000);
})(targetTile);
// Flash effect
LK.effects.flashObject(targetTile, 0xffffff, 300);
if (currentBag >= bagCapacity) {
break;
}
}
}
}
if (currentBag >= bagCapacity) {
break;
}
}
updateUI();
// Only play sound once per overall cut action
LK.getSound('mow').play();
}
}
};
game.update = function () {
// Power-up: Turbo Booster
if (turboActive) {
turboTicks--;
if (turboTicks % 10 === 0) {
LK.effects.flashObject(mower, 0x00ffff, 100);
}
if (turboTicks <= 0) {
turboActive = false;
}
}
// Power-up: Magnet
if (magnetActive) {
magnetTicks--;
// Pull in nearby grass clippings (simulate: auto-cut nearby uncut tiles)
for (var i = 0; i < grassTiles.length; i++) {
var tile = grassTiles[i];
if (!tile.isCut && currentBag < bagCapacity) {
var dx = tile.x - mower.x;
var dy = tile.y - mower.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 200) {
var success = tile.cut();
if (success) {
currentBag += 1;
money += moneyPerCut;
LK.effects.flashObject(tile, 0x8888ff, 200);
LK.getSound('mow').play();
updateUI();
LK.setTimeout(function (t) {
t.startGrowing();
}, 2000, tile);
if (currentBag >= bagCapacity) break;
}
}
}
}
if (magnetTicks <= 0) {
magnetActive = false;
}
}
// Pet Helper: Collects stray clippings (simulate: auto-empty bag if full)
if (petEquipped && currentBag >= bagCapacity) {
currentBag = 0;
LK.effects.flashObject(bagContainer, 0xffff00, 400);
LK.getSound('emptyBag').play();
updateUI();
}
// Mulcher: Bonus money for perfect lawns (simulate: if all cut, bonus)
if (mulcherEquipped) {
var allCut = true;
for (var i = 0; i < grassTiles.length; i++) {
if (!grassTiles[i].isCut) {
allCut = false;
break;
}
}
if (allCut) {
money += 20;
LK.effects.flashObject(mower, 0x22ff22, 600);
updateUI();
// Prevent repeat bonus until regrowth
mulcherEquipped = false;
LK.setTimeout(function () {
mulcherEquipped = storage.mulcherOwned;
}, 3000);
}
}
// Update all grass tiles
for (var i = 0; i < grassTiles.length; i++) {
grassTiles[i].update();
}
};
// Initialize the game
createGrassGrid();
updateUI();
updateMower();
// Play background music
LK.playMusic('bgmusic', {
loop: true
}); ===================================================================
--- original.js
+++ change.js
@@ -85,8 +85,136 @@
}
};
return self;
});
+// ShopButton: Opens the shop menu
+var ShopButton = Container.expand(function () {
+ var self = Container.call(this);
+ var buttonGraphics = self.attachAsset('upgradeButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.2,
+ scaleY: 1.2,
+ tint: 0x3366cc
+ });
+ self.buttonText = new Text2("Shop", {
+ size: 48,
+ fill: 0xFFFFFF
+ });
+ self.buttonText.anchor.set(0.5, 0.5);
+ self.addChild(self.buttonText);
+ self.down = function (x, y, obj) {
+ openShopMenu();
+ };
+ return self;
+});
+// ShopMenu: Displays shop items and handles purchases
+var ShopMenu = Container.expand(function () {
+ var self = Container.call(this);
+ self.bg = self.attachAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 10,
+ scaleY: 10,
+ x: 0,
+ y: 0,
+ tint: 0x222244
+ });
+ self.bg.alpha = 0.95;
+ self.title = new Text2("Mower Shop", {
+ size: 80,
+ fill: "#fff"
+ });
+ self.title.anchor.set(0.5, 0);
+ self.title.x = 0;
+ self.title.y = -500;
+ self.addChild(self.title);
+ // Shop items will be dynamically created
+ self.itemButtons = [];
+ // Close button
+ var closeBtn = self.attachAsset('upgradeButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.7,
+ scaleY: 0.7,
+ x: 0,
+ y: 600,
+ tint: 0x444444
+ });
+ var closeText = new Text2("Close", {
+ size: 48,
+ fill: 0xffffff
+ });
+ closeText.anchor.set(0.5, 0.5);
+ closeText.x = 0;
+ closeText.y = 600;
+ self.addChild(closeText);
+ closeBtn.interactive = true;
+ closeBtn.down = function () {
+ self.visible = false;
+ self.parent.removeChild(self);
+ };
+ self.addShopItems = function (items) {
+ // Remove old buttons
+ for (var i = 0; i < self.itemButtons.length; i++) {
+ self.removeChild(self.itemButtons[i]);
+ }
+ self.itemButtons = [];
+ // Layout items vertically
+ for (var i = 0; i < items.length; i++) {
+ var item = items[i];
+ var btn = new Container();
+ var btnBg = btn.attachAsset('upgradeButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.1,
+ scaleY: 1.1,
+ y: 0,
+ tint: item.owned ? 0x888888 : 0x2288ff
+ });
+ var txt = new Text2(item.name + (item.owned ? " (Owned)" : " - $" + item.price), {
+ size: 40,
+ fill: item.owned ? "#cccccc" : "#ffffff"
+ });
+ txt.anchor.set(0.5, 0.5);
+ btn.addChild(txt);
+ btn.x = 0;
+ btn.y = -300 + i * 180;
+ btn.interactive = true;
+ (function (item, btn, btnBg, txt) {
+ btn.down = function () {
+ if (item.owned) {
+ // If consumable, allow to buy again
+ if (item.type === "consumable" && money >= item.price) {
+ money -= item.price;
+ item.onBuy();
+ updateUI();
+ btnBg.tint = 0x888888;
+ txt.setText(item.name + " (Owned)");
+ LK.effects.flashObject(btn, 0x00ff00, 400);
+ }
+ return;
+ }
+ if (money >= item.price) {
+ money -= item.price;
+ item.owned = true;
+ item.onBuy();
+ updateUI();
+ btnBg.tint = 0x888888;
+ txt.setText(item.name + " (Owned)");
+ LK.effects.flashObject(btn, 0x00ff00, 400);
+ LK.getSound('upgrade').play();
+ } else {
+ LK.effects.flashObject(btn, 0xff0000, 400);
+ }
+ };
+ })(item, btn, btnBg, txt);
+ self.addChild(btn);
+ self.itemButtons.push(btn);
+ }
+ };
+ return self;
+});
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgradeButton', {
anchorX: 0.5,
@@ -167,8 +295,114 @@
fill: 0xFFFFFF
});
moneyText.anchor.set(1, 0);
LK.gui.topRight.addChild(moneyText);
+// Add ShopButton below money UI
+var shopButton = new ShopButton();
+shopButton.x = -160; // Offset to appear below moneyText
+shopButton.y = 120;
+LK.gui.topRight.addChild(shopButton);
+// --- Shop logic ---
+var shopItems = [{
+ id: "collector",
+ name: "Grass Collector",
+ price: 150,
+ owned: storage.collectorOwned || false,
+ unlockLevel: 1,
+ type: "attachment",
+ onBuy: function onBuy() {
+ collectorEquipped = true;
+ storage.collectorOwned = true;
+ bagCapacity += 10;
+ updateUI();
+ LK.effects.flashObject(bagContainer, 0x44ff44, 600);
+ }
+}, {
+ id: "turbo",
+ name: "Turbo Booster",
+ price: 120,
+ owned: false,
+ unlockLevel: 2,
+ type: "consumable",
+ onBuy: function onBuy() {
+ turboActive = true;
+ turboTicks = 300;
+ LK.effects.flashObject(mower, 0x00ffff, 600);
+ }
+}, {
+ id: "skin1",
+ name: "Red Flame Skin",
+ price: 80,
+ owned: storage.skin1Owned || false,
+ unlockLevel: 1,
+ type: "skin",
+ onBuy: function onBuy() {
+ mowerSkin = 1;
+ storage.skin1Owned = true;
+ updateMower();
+ LK.effects.flashObject(mower, 0xff2222, 600);
+ }
+}, {
+ id: "mulcher",
+ name: "Mulching Attachment",
+ price: 200,
+ owned: storage.mulcherOwned || false,
+ unlockLevel: 3,
+ type: "attachment",
+ onBuy: function onBuy() {
+ mulcherEquipped = true;
+ storage.mulcherOwned = true;
+ LK.effects.flashObject(mower, 0x22ff22, 600);
+ }
+}, {
+ id: "magnet",
+ name: "Magnet Power-Up",
+ price: 100,
+ owned: false,
+ unlockLevel: 2,
+ type: "consumable",
+ onBuy: function onBuy() {
+ magnetActive = true;
+ magnetTicks = 360;
+ LK.effects.flashObject(mower, 0x8888ff, 600);
+ }
+}, {
+ id: "pet",
+ name: "Robotic Pet Helper",
+ price: 300,
+ owned: storage.petOwned || false,
+ unlockLevel: 4,
+ type: "attachment",
+ onBuy: function onBuy() {
+ petEquipped = true;
+ storage.petOwned = true;
+ LK.effects.flashObject(mower, 0xffff00, 600);
+ }
+}];
+// Track equipped/active powerups
+var collectorEquipped = storage.collectorOwned || false;
+var turboActive = false;
+var turboTicks = 0;
+var mowerSkin = 0;
+var mulcherEquipped = storage.mulcherOwned || false;
+var magnetActive = false;
+var magnetTicks = 0;
+var petEquipped = storage.petOwned || false;
+// Open shop menu
+function openShopMenu() {
+ // Only show items unlocked by mowerLevel
+ var unlocked = [];
+ for (var i = 0; i < shopItems.length; i++) {
+ if (mowerLevel >= shopItems[i].unlockLevel) {
+ unlocked.push(shopItems[i]);
+ }
+ }
+ var shopMenu = new ShopMenu();
+ shopMenu.x = 2048 / 2;
+ shopMenu.y = 2732 / 2;
+ shopMenu.addShopItems(unlocked);
+ game.addChild(shopMenu);
+}
var bagContainer = new Container();
var bagBackground = bagContainer.attachAsset('bagIndicator', {
anchorX: 0,
anchorY: 0.5
@@ -241,9 +475,10 @@
}
}
function updateUI() {
moneyText.setText("$" + money);
- bagText.setText("Bag: " + currentBag + "/" + bagCapacity);
+ // If collector equipped, show bonus capacity
+ bagText.setText("Bag: " + currentBag + "/" + bagCapacity + (collectorEquipped ? " (Collector)" : ""));
levelText.setText("Mower Level: " + mowerLevel);
// Update bag fill bar
var fillPercent = currentBag / bagCapacity;
bagFillBar.width = Math.max(0, Math.min(196 * fillPercent, 196));
@@ -259,16 +494,24 @@
}, {
duration: 500,
easing: tween.easeOut
});
- // Change mower color based on level
+ // Change mower color based on level or skin
var level = mowerLevel % 5;
var colors = [0xdd2222, 0xff6600, 0xffcc00, 0x22dd22, 0x2222dd];
- tween(mower, {
- tint: colors[level]
- }, {
- duration: 500
- });
+ if (mowerSkin === 1) {
+ tween(mower, {
+ tint: 0xff2222
+ }, {
+ duration: 500
+ });
+ } else {
+ tween(mower, {
+ tint: colors[level]
+ }, {
+ duration: 500
+ });
+ }
}
// Track mouse/touch position for mower movement
game.move = function (x, y) {
mower.x = x;
@@ -331,8 +574,75 @@
}
}
};
game.update = function () {
+ // Power-up: Turbo Booster
+ if (turboActive) {
+ turboTicks--;
+ if (turboTicks % 10 === 0) {
+ LK.effects.flashObject(mower, 0x00ffff, 100);
+ }
+ if (turboTicks <= 0) {
+ turboActive = false;
+ }
+ }
+ // Power-up: Magnet
+ if (magnetActive) {
+ magnetTicks--;
+ // Pull in nearby grass clippings (simulate: auto-cut nearby uncut tiles)
+ for (var i = 0; i < grassTiles.length; i++) {
+ var tile = grassTiles[i];
+ if (!tile.isCut && currentBag < bagCapacity) {
+ var dx = tile.x - mower.x;
+ var dy = tile.y - mower.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 200) {
+ var success = tile.cut();
+ if (success) {
+ currentBag += 1;
+ money += moneyPerCut;
+ LK.effects.flashObject(tile, 0x8888ff, 200);
+ LK.getSound('mow').play();
+ updateUI();
+ LK.setTimeout(function (t) {
+ t.startGrowing();
+ }, 2000, tile);
+ if (currentBag >= bagCapacity) break;
+ }
+ }
+ }
+ }
+ if (magnetTicks <= 0) {
+ magnetActive = false;
+ }
+ }
+ // Pet Helper: Collects stray clippings (simulate: auto-empty bag if full)
+ if (petEquipped && currentBag >= bagCapacity) {
+ currentBag = 0;
+ LK.effects.flashObject(bagContainer, 0xffff00, 400);
+ LK.getSound('emptyBag').play();
+ updateUI();
+ }
+ // Mulcher: Bonus money for perfect lawns (simulate: if all cut, bonus)
+ if (mulcherEquipped) {
+ var allCut = true;
+ for (var i = 0; i < grassTiles.length; i++) {
+ if (!grassTiles[i].isCut) {
+ allCut = false;
+ break;
+ }
+ }
+ if (allCut) {
+ money += 20;
+ LK.effects.flashObject(mower, 0x22ff22, 600);
+ updateUI();
+ // Prevent repeat bonus until regrowth
+ mulcherEquipped = false;
+ LK.setTimeout(function () {
+ mulcherEquipped = storage.mulcherOwned;
+ }, 3000);
+ }
+ }
// Update all grass tiles
for (var i = 0; i < grassTiles.length; i++) {
grassTiles[i].update();
}
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Infinite Lawn Master" and with the description "A satisfying grass-cutting simulator where players click to mow lawns, empty collection bags when full, and earn money to upgrade their equipment. Watch as cut grass regrows, creating an endless cycle of lawn maintenance and mower upgrades that increase efficiency and earning potential.". No text on banner!
top down view of long grass. In-Game asset. 2d. High contrast. No shadows
Simple yet pleasing rectangle that can be used for a UI. In-Game asset. 2d. High contrast. No shadows
long grass bar. In-Game asset. 2d. High contrast. No shadows