Code edit (1 edits merged)
Please save this source code
User prompt
change it so that the plots that are unlocked are the center two and not on the outside of the farm
User prompt
Move the plots button over to the right just a little bit more
User prompt
Can you move the plots button to the bottom left of the farm plots
User prompt
remove the restart button
User prompt
Set up the farm so that players begin with only 2 unlocked plots of farmland, which they can use immediately for planting and harvesting. The rest of the farm plots should be locked and visually indicated as unavailable. Add a system where players can unlock additional plots one at a time by spending 200 coins per plot. When a player has at least 200 coins and clicks on a locked plot, prompt them to confirm the purchase; if they confirm, deduct 200 coins and unlock that plot for use. Update the UI to show the number of unlocked plots and the player’s current coin balance. Make sure this system works seamlessly with the existing planting, tilling, and harvesting mechanics. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
restart the game
Code edit (1 edits merged)
Please save this source code
User prompt
give me 500 coins so I can try everything
User prompt
increase the text size of all the uis its way to small to read
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'statusText.style.fill = 0x00FF00;' Line Number: 1074
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'y' in null' in or related to this line: 'tween(cropGraphic, {' Line Number: 311
User prompt
restart the game
Code edit (1 edits merged)
Please save this source code
User prompt
Move the town button to the bottom right corner of the farm
User prompt
Add a tooltip feature to the game. When the player hovers the mouse over any planted crop on the farm, a small informational box (tooltip) should appear near the cursor. This tooltip should display two pieces of information: the current water level of the crop (e.g., 'Low', 'Medium', 'High') and the time remaining until the crop is fully grown (e.g., '2 days'). For example, hovering over a tomato plant might show 'Water Level: Medium' and 'Time Till Grown: 3 days'. This feature should be implemented for all six crops: wheat, corn, tomato, carrot, potato, and strawberry. The tooltip should be visible only while the mouse is over the crop and should disappear when the mouse moves away. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Generate sound effects for actions: tilling (shovel sound), planting (rustle), watering (splash), harvesting (pluck)
User prompt
Generate sprites for each crop at three growth stages: seed, growing, mature. Generate sprites for tools: Hoe, Shovel, Water Bucket, Seed Bag, Irrigation System, etc.
User prompt
Prompt: “The irrigation system automatically waters crops in a 3x3 area. The auto-tilling tool tills multiple cells at once.” Details: Ensure interactions are intuitive, with visual feedback (e.g., soil changing appearance when tilled)
User prompt
With the seed bag selected, clicking on a tilled cell opens a menu to choose from six crop seeds to plant
User prompt
Add a town interface accessible via a button, containing Tool Shop, Seed Shop, and Market.” Details: The town serves as a hub for economic interactions.
User prompt
Add tools to the player’s inventory: Hoe (tills soil), Shovel (digs holes), Water Bucket (waters plants), Seed Bag (plants seeds). Include advanced tools: Irrigation System, Better Harvesting Tools, Auto-Tilling Tool.” Details: Basic tools are available from the start; advanced tools are unlocked through purchases ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add six crop types: Wheat, Corn, Tomato, Carrot, Potato, Strawberry. Each has growth stages: seed, growing, mature, with specific growth times and water needs. Wheat- 2 days, corn 3 days, tomato 4 days, carrot 3 days, potato 5 days, and strawberry 6 days
User prompt
Action: Use Upit’s drag-and-drop editor to create a farm grid. Prompt: “Create a 10x10 grid for the farm where each cell represents a plot of land that can be tilled, planted, watered, and harvested.” Details: Ensure each grid cell can change states (e.g., untilled, tilled, planted, watered, mature) based on player actions.
Code edit (1 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 0,
unlockedSeeds: ["wheat", "corn", "tomato", "carrot", "potato", "strawberry"],
unlockedTools: {}
});
/****
* Classes
****/
var CoinDisplay = Container.expand(function () {
var self = Container.call(this);
var coinIcon = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
x: -60
});
var coinText = new Text2("0", {
size: 50,
fill: 0xFFFFFF
});
coinText.anchor.set(0, 0.5);
coinText.x = -30;
self.addChild(coinText);
self.updateCoins = function (amount) {
coinText.setText(amount.toString());
};
return self;
});
var FarmPlot = Container.expand(function () {
var self = Container.call(this);
self.state = PlotState.EMPTY;
self.growthTimer = 0;
self.seedType = null;
var soilGraphic = self.attachAsset('soil', {
anchorX: 0.5,
anchorY: 0.5
});
var cropGraphic = null;
self.till = function () {
if (self.state === PlotState.EMPTY) {
self.state = PlotState.TILLED;
soilGraphic.destroy();
soilGraphic = self.attachAsset('tilled_soil', {
anchorX: 0.5,
anchorY: 0.5
});
LK.getSound('till').play();
return true;
}
return false;
};
self.plant = function (seedType) {
if (self.state === PlotState.TILLED) {
self.state = PlotState.SEEDED;
self.seedType = seedType;
if (cropGraphic) {
cropGraphic.destroy();
}
// Use the seed asset with a small tint variation based on seed type
var seedAsset = cropGraphic = self.attachAsset('seed', {
anchorX: 0.5,
anchorY: 0.5,
y: -20
});
// Apply different tint based on seed type
switch (seedType) {
case SeedType.WHEAT:
seedAsset.tint = 0xF5DEB3; // Wheat color
break;
case SeedType.CORN:
seedAsset.tint = 0xFFF44F; // Corn color
break;
case SeedType.TOMATO:
seedAsset.tint = 0xFF6347; // Tomato color
break;
case SeedType.CARROT:
seedAsset.tint = 0xFFA500; // Carrot color
break;
case SeedType.POTATO:
seedAsset.tint = 0xA0522D; // Potato color
break;
case SeedType.STRAWBERRY:
seedAsset.tint = 0xFF3366; // Strawberry color
break;
}
LK.getSound('plant').play();
return true;
}
return false;
};
self.water = function () {
if (self.state === PlotState.SEEDED) {
self.state = PlotState.WATERED;
self.growthTimer = 0;
var waterDroplet = self.attachAsset('water_drop', {
anchorX: 0.5,
anchorY: 0.5,
y: -50,
alpha: 0.8
});
tween(waterDroplet, {
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
waterDroplet.destroy();
}
});
LK.getSound('water').play();
return true;
}
return false;
};
self.grow = function () {
// Get crop configuration based on seed type
var cropConfig = CropConfig[self.seedType] || CropConfig.carrot;
var growthTime = cropConfig.growthTime;
// Calculate growth stage thresholds
var stage1Time = growthTime * 0.25; // 25% of total growth time
var stage2Time = growthTime * 0.5; // 50% of total growth time
var stage3Time = growthTime * 0.75; // 75% of total growth time
var harvestTime = growthTime; // 100% of total growth time
if (self.state === PlotState.WATERED) {
self.growthTimer++;
if (self.growthTimer >= stage1Time) {
self.state = PlotState.GROWING1;
if (cropGraphic) {
cropGraphic.destroy();
}
cropGraphic = self.attachAsset('crop_stage1', {
anchorX: 0.5,
anchorY: 1.0,
y: 0
});
}
} else if (self.state === PlotState.GROWING1) {
self.growthTimer++;
if (self.growthTimer >= stage2Time) {
self.state = PlotState.GROWING2;
if (cropGraphic) {
cropGraphic.destroy();
}
cropGraphic = self.attachAsset('crop_stage2', {
anchorX: 0.5,
anchorY: 1.0,
y: 0
});
}
} else if (self.state === PlotState.GROWING2) {
self.growthTimer++;
if (self.growthTimer >= stage3Time) {
self.state = PlotState.GROWING3;
if (cropGraphic) {
cropGraphic.destroy();
}
cropGraphic = self.attachAsset('crop_stage3', {
anchorX: 0.5,
anchorY: 1.0,
y: 0
});
}
} else if (self.state === PlotState.GROWING3) {
self.growthTimer++;
if (self.growthTimer >= harvestTime) {
self.state = PlotState.READY;
if (cropGraphic) {
cropGraphic.destroy();
}
cropGraphic = self.attachAsset('harvest_ready', {
anchorX: 0.5,
anchorY: 1.0,
y: 0
});
// Add bouncing animation for ready crops
tween(cropGraphic, {
y: -10
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cropGraphic, {
y: 0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (cropGraphic && cropGraphic.parent) {
self.bounceAnimation();
}
}
});
}
});
}
}
};
self.bounceAnimation = function () {
if (self.state === PlotState.READY && cropGraphic && cropGraphic.parent) {
tween(cropGraphic, {
y: -10
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cropGraphic, {
y: 0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (cropGraphic && cropGraphic.parent) {
self.bounceAnimation();
}
}
});
}
});
}
};
self.harvest = function () {
if (self.state === PlotState.READY) {
var harvestValue = 0;
if (self.seedType && CropConfig[self.seedType]) {
harvestValue = CropConfig[self.seedType].value;
} else {
harvestValue = 3; // Default value if seedType is invalid
}
self.reset();
LK.getSound('harvest').play();
return harvestValue;
}
return 0;
};
self.reset = function () {
self.state = PlotState.EMPTY;
self.growthTimer = 0;
self.seedType = null;
if (cropGraphic) {
cropGraphic.destroy();
cropGraphic = null;
}
if (soilGraphic) {
soilGraphic.destroy();
}
soilGraphic = self.attachAsset('soil', {
anchorX: 0.5,
anchorY: 0.5
});
};
self.down = function (x, y, obj) {
var toolAction = false;
// Handle both basic and advanced tools
switch (currentTool) {
case ToolType.HOE:
case "Auto-Tilling Tool":
toolAction = self.till();
// If using auto-tiller and action succeeded, till adjacent plots
if (toolAction && currentTool === "Auto-Tilling Tool") {
// Find nearby plots
var nearbyPlots = findNearbyPlots(self, 1);
nearbyPlots.forEach(function (plot) {
plot.till();
// Visual feedback for each plot
LK.effects.flashObject(plot, 0xAA7722, 300);
});
}
break;
case ToolType.SEEDS:
// If the plot is tilled, show seed selector
if (self.state === PlotState.TILLED) {
// Position seed selector over this plot
seedSelector.x = self.x;
seedSelector.y = self.y - 200;
seedSelector.show();
// Set the target plot for planting
seedSelector.targetPlot = self;
} else {
// If not tilled, try to plant with current seed
toolAction = self.plant(selectedSeedType);
}
break;
case ToolType.WATER:
case "Irrigation System":
toolAction = self.water();
// If using irrigation system and action succeeded, water adjacent plots
if (toolAction && currentTool === "Irrigation System") {
// Find nearby plots
var nearbyPlots = findNearbyPlots(self, 1);
nearbyPlots.forEach(function (plot) {
var waterSuccess = plot.water();
if (waterSuccess) {
// Visual feedback for each watered plot
LK.effects.flashObject(plot, 0x1E90FF, 300);
}
});
}
break;
case ToolType.HARVEST:
case "Better Harvesting Tools":
var harvestValue = self.harvest();
if (harvestValue > 0) {
toolAction = true;
// Give bonus yield if using better harvesting tools
if (currentTool === "Better Harvesting Tools") {
harvestValue = Math.floor(harvestValue * 1.5); // 50% bonus
}
addCoins(harvestValue);
}
break;
case ToolType.SHOVEL:
// Shovel resets the plot to empty state
if (self.state !== PlotState.EMPTY) {
self.reset();
toolAction = true;
}
break;
}
if (toolAction) {
// Visual feedback
LK.effects.flashObject(self, 0xFFFFFF, 300);
}
};
self.update = function () {
if (self.state >= PlotState.WATERED && self.state < PlotState.READY) {
self.grow();
}
};
return self;
});
var SeedSelector = Container.expand(function () {
var self = Container.call(this);
// Target plot to plant on after selection
self.targetPlot = null;
// Create background
var background = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 1.5,
tint: 0x8b5a2b,
alpha: 0.8
});
self.addChild(background);
// Title
var titleText = new Text2("Select Seed", {
size: 40,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -70;
self.addChild(titleText);
// Create seed buttons
var seedButtons = [];
var seedTypes = [{
type: SeedType.WHEAT,
name: "Wheat",
color: 0xF5DEB3
}, {
type: SeedType.CORN,
name: "Corn",
color: 0xFFF44F
}, {
type: SeedType.TOMATO,
name: "Tomato",
color: 0xFF6347
}, {
type: SeedType.CARROT,
name: "Carrot",
color: 0xFFA500
}, {
type: SeedType.POTATO,
name: "Potato",
color: 0xA0522D
}, {
type: SeedType.STRAWBERRY,
name: "Strawberry",
color: 0xFF3366
}];
var buttonSize = 60;
var spacing = 80;
var startX = -(spacing * (seedTypes.length - 1)) / 2;
seedTypes.forEach(function (seedInfo, index) {
var button = new Container();
// Seed visual
var seedVisual = LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5,
tint: seedInfo.color
});
button.addChild(seedVisual);
// Seed name
var nameText = new Text2(seedInfo.name, {
size: 25,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = 40;
button.addChild(nameText);
// Growth time text
var growthDays = CropConfig[seedInfo.type].growthTime / (60 * 60);
var growthText = new Text2(growthDays + " days", {
size: 18,
fill: 0xCCCCCC
});
growthText.anchor.set(0.5, 0);
growthText.y = 70;
button.addChild(growthText);
// Position button
button.x = startX + index * spacing;
button.y = 0;
button.interactive = true;
// Selection highlight
var highlight = LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFFFF00,
alpha: 0
});
button.addChildAt(highlight, 0);
// Set button data
button.seedType = seedInfo.type;
button.highlight = highlight;
// Add to container and array
self.addChild(button);
seedButtons.push(button);
// Button event
button.down = function (x, y, obj) {
// Set the selected seed type
selectedSeedType = button.seedType;
updateSelectedSeed();
// If we have a target plot, plant the seed and hide the selector
if (self.targetPlot) {
// Try to plant the selected seed
var success = self.targetPlot.plant(selectedSeedType);
if (success) {
// Visual feedback
LK.effects.flashObject(self.targetPlot, 0xFFFFFF, 300);
}
// Hide selector regardless of success
self.visible = false;
self.targetPlot = null;
}
};
});
// Update visual selection
function updateSelectedSeed() {
seedButtons.forEach(function (button) {
if (button.seedType === selectedSeedType) {
button.highlight.alpha = 0.3;
} else {
button.highlight.alpha = 0;
}
});
}
// Close button
var closeButton = new Container();
var closeVisual = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
tint: 0xFF5555
});
closeButton.addChild(closeVisual);
var closeText = new Text2("X", {
size: 40,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeButton.addChild(closeText);
closeButton.x = background.width / 2 - 30;
closeButton.y = -background.height / 2 + 30;
self.addChild(closeButton);
// Close event
closeButton.down = function (x, y, obj) {
self.visible = false;
self.targetPlot = null; // Clear target plot when closing
};
self.show = function () {
self.visible = true;
updateSelectedSeed();
};
// Initialize with default selection
updateSelectedSeed();
return self;
});
var Tool = Container.expand(function (toolType, isAdvanced, toolData) {
var self = Container.call(this);
self.toolType = toolType;
self.isAdvanced = isAdvanced || false;
self.toolData = toolData || null;
// Determine which asset to use
var assetId = self.isAdvanced && self.toolData ? self.toolData.icon : ToolType.HOE === toolType ? 'tool_hoe' : ToolType.SEEDS === toolType ? 'tool_seeds' : ToolType.WATER === toolType ? 'tool_water' : ToolType.HARVEST === toolType ? 'tool_harvest' : 'tool_hoe';
var toolGraphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply tint if it's an advanced tool with tint
if (self.isAdvanced && self.toolData && self.toolData.tint) {
toolGraphic.tint = self.toolData.tint;
}
// Create tool name label
var toolName = new Text2(self.isAdvanced && self.toolData ? self.toolData.name : ToolType.HOE === toolType ? "Hoe" : ToolType.SEEDS === toolType ? "Seeds" : ToolType.WATER === toolType ? "Water" : ToolType.HARVEST === toolType ? "Harvest" : "Tool", {
size: 20,
fill: 0xFFFFFF
});
toolName.anchor.set(0.5, 0);
toolName.y = 80;
self.addChild(toolName);
// Add lock icon or price for locked tools
self.lockIcon = null;
self.priceText = null;
self.updateLockStatus = function () {
// Remove existing lock/price if any
if (self.lockIcon) {
self.lockIcon.destroy();
self.lockIcon = null;
}
if (self.priceText) {
self.priceText.destroy();
self.priceText = null;
}
// If it's an advanced tool and not unlocked, show lock or price
if (self.isAdvanced && self.toolData && !self.toolData.unlocked) {
// Show price
self.priceText = new Text2(self.toolData.price.toString(), {
size: 24,
fill: 0xFFDD00
});
self.priceText.anchor.set(0.5, 0);
self.priceText.y = -70;
self.addChild(self.priceText);
// Dim the tool
toolGraphic.alpha = 0.5;
} else {
toolGraphic.alpha = 1;
}
};
// Highlight border when selected
var selectedBorder = null;
self.setSelected = function (selected) {
if (selected) {
if (!selectedBorder) {
selectedBorder = new Container();
var borderSize = 10;
var borderAsset = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFFF00,
alpha: 0.5
});
selectedBorder.addChild(borderAsset);
self.addChildAt(selectedBorder, 0);
}
} else {
if (selectedBorder) {
selectedBorder.destroy();
selectedBorder = null;
}
}
};
self.down = function (x, y, obj) {
// If it's a locked advanced tool, try to purchase
if (self.isAdvanced && self.toolData && !self.toolData.unlocked) {
if (coins >= self.toolData.price) {
// Purchase the tool
coins -= self.toolData.price;
storage.coins = coins;
coinDisplay.updateCoins(coins);
self.toolData.unlocked = true;
// Save unlocked status
var unlockedTools = storage.unlockedTools || {};
unlockedTools[self.toolData.name] = true;
storage.unlockedTools = unlockedTools;
// Update visuals
self.updateLockStatus();
// Show success animation
LK.effects.flashObject(self, 0x00FF00, 500);
} else {
// Not enough coins
LK.effects.flashObject(self, 0xFF0000, 500);
}
} else {
// Normal tool selection
selectTool(self.isAdvanced ? self.toolData.name : self.toolType);
}
};
// Initialize lock/price display
if (self.isAdvanced) {
self.updateLockStatus();
}
return self;
});
var Town = Container.expand(function () {
var self = Container.call(this);
// Create town background
var background = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 10,
tint: 0x8B4513,
alpha: 0.9
});
self.addChild(background);
// Town title
var titleText = new Text2("Town", {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -450;
self.addChild(titleText);
// Create shops
var shops = [{
name: "Tool Shop",
description: "Upgrade your farming tools",
y: -300
}, {
name: "Seed Shop",
description: "Buy new seed varieties",
y: -100
}, {
name: "Market",
description: "Sell your crops for coins",
y: 100
}];
var shopButtons = [];
shops.forEach(function (shop) {
var shopButton = new Container();
// Shop button background
var buttonBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 1.5,
tint: 0x6B4226
});
shopButton.addChild(buttonBg);
// Shop name
var nameText = new Text2(shop.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -25;
shopButton.addChild(nameText);
// Shop description
var descText = new Text2(shop.description, {
size: 25,
fill: 0xCCCCCC
});
descText.anchor.set(0.5, 0.5);
descText.y = 25;
shopButton.addChild(descText);
// Position and add
shopButton.y = shop.y;
shopButton.shopType = shop.name;
shopButton.interactive = true;
self.addChild(shopButton);
shopButtons.push(shopButton);
// Click handler
shopButton.down = function (x, y, obj) {
self.openShop(shop.name);
};
});
// Close button
var closeButton = new Container();
var closeVisual = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: 0xFF5555
});
closeButton.addChild(closeVisual);
var closeText = new Text2("X", {
size: 40,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeButton.addChild(closeText);
closeButton.x = background.width / 2 - 30;
closeButton.y = -background.height / 2 + 30;
closeButton.interactive = true;
self.addChild(closeButton);
// Close event
closeButton.down = function (x, y, obj) {
self.hide();
};
// Currently open shop content
var currentShopContent = null;
// Shop handlers
self.openShop = function (shopType) {
// Clear current shop content if any
if (currentShopContent) {
currentShopContent.destroy();
currentShopContent = null;
}
// Create new shop content based on type
currentShopContent = new Container();
self.addChild(currentShopContent);
// Shop title
var shopTitle = new Text2(shopType, {
size: 50,
fill: 0xFFD700
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.y = -350;
currentShopContent.addChild(shopTitle);
// Shop specific content
if (shopType === "Tool Shop") {
createToolShop(currentShopContent);
} else if (shopType === "Seed Shop") {
createSeedShop(currentShopContent);
} else if (shopType === "Market") {
createMarket(currentShopContent);
}
// Update shop buttons visibility
shops.forEach(function (shop, index) {
shopButtons[index].visible = false;
});
// Add back button
var backButton = new Container();
var backVisual = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1,
tint: 0x4B0082
});
backButton.addChild(backVisual);
var backText = new Text2("Back", {
size: 30,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
backButton.y = 400;
backButton.interactive = true;
currentShopContent.addChild(backButton);
backButton.down = function (x, y, obj) {
if (currentShopContent) {
currentShopContent.destroy();
currentShopContent = null;
}
// Show shop buttons again
shops.forEach(function (shop, index) {
shopButtons[index].visible = true;
});
};
};
// Create Tool Shop content
function createToolShop(container) {
var toolsPerRow = 3;
var spacing = 200;
var startX = -(spacing * (toolsPerRow - 1)) / 2;
var startY = -200;
var advancedTools = [];
Object.keys(ToolConfig.advanced).forEach(function (key) {
advancedTools.push(ToolConfig.advanced[key]);
});
advancedTools.forEach(function (toolData, index) {
var row = Math.floor(index / toolsPerRow);
var col = index % toolsPerRow;
var toolButton = new Container();
// Tool icon
var toolIcon = LK.getAsset(toolData.icon, {
anchorX: 0.5,
anchorY: 0.5,
tint: toolData.tint || 0xFFFFFF
});
toolButton.addChild(toolIcon);
// Tool name
var nameText = new Text2(toolData.name, {
size: 24,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = 70;
toolButton.addChild(nameText);
// Tool description
var descText = new Text2(toolData.description, {
size: 18,
fill: 0xCCCCCC
});
descText.anchor.set(0.5, 0);
descText.y = 100;
toolButton.addChild(descText);
// Price or status
var statusText = new Text2(toolData.unlocked ? "Owned" : toolData.price + " coins", {
size: 24,
fill: toolData.unlocked ? 0x00FF00 : 0xFFD700
});
statusText.anchor.set(0.5, 0.5);
statusText.y = -60;
toolButton.addChild(statusText);
// Position and add
toolButton.x = startX + col * spacing;
toolButton.y = startY + row * 220;
toolButton.toolData = toolData;
toolButton.interactive = !toolData.unlocked;
container.addChild(toolButton);
// Click handler only for locked tools
if (!toolData.unlocked) {
toolButton.down = function (x, y, obj) {
if (coins >= toolData.price) {
// Purchase the tool
coins -= toolData.price;
storage.coins = coins;
coinDisplay.updateCoins(coins);
toolData.unlocked = true;
// Save unlocked status
var unlockedTools = storage.unlockedTools || {};
unlockedTools[toolData.name] = true;
storage.unlockedTools = unlockedTools;
// Update tool panel
for (var i = 0; i < tools.length; i++) {
if (tools[i].isAdvanced && tools[i].toolData && tools[i].toolData.name === toolData.name) {
tools[i].updateLockStatus();
break;
}
}
// Update button
statusText.setText("Owned");
statusText.style.fill = 0x00FF00;
toolButton.interactive = false;
// Show success animation
LK.effects.flashObject(toolButton, 0x00FF00, 500);
} else {
// Not enough coins
LK.effects.flashObject(toolButton, 0xFF0000, 500);
}
};
}
});
}
// Create Seed Shop content
function createSeedShop(container) {
var seedsPerRow = 3;
var spacing = 200;
var startX = -(spacing * (seedsPerRow - 1)) / 2;
var startY = -200;
var seedTypes = [{
type: SeedType.WHEAT,
name: "Wheat",
color: 0xF5DEB3,
growthDays: 2,
price: 2
}, {
type: SeedType.CORN,
name: "Corn",
color: 0xFFF44F,
growthDays: 3,
price: 3
}, {
type: SeedType.TOMATO,
name: "Tomato",
color: 0xFF6347,
growthDays: 4,
price: 5
}, {
type: SeedType.CARROT,
name: "Carrot",
color: 0xFFA500,
growthDays: 3,
price: 3
}, {
type: SeedType.POTATO,
name: "Potato",
color: 0xA0522D,
growthDays: 5,
price: 6
}, {
type: SeedType.STRAWBERRY,
name: "Strawberry",
color: 0xFF3366,
growthDays: 6,
price: 8
}];
seedTypes.forEach(function (seedInfo, index) {
var row = Math.floor(index / seedsPerRow);
var col = index % seedsPerRow;
var seedButton = new Container();
// Seed visual
var seedVisual = LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5,
tint: seedInfo.color,
scaleX: 1.5,
scaleY: 1.5
});
seedButton.addChild(seedVisual);
// Seed name
var nameText = new Text2(seedInfo.name, {
size: 24,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = 50;
seedButton.addChild(nameText);
// Growth time
var timeText = new Text2(seedInfo.growthDays + " days", {
size: 18,
fill: 0xCCCCCC
});
timeText.anchor.set(0.5, 0);
timeText.y = 80;
seedButton.addChild(timeText);
// Price
var priceText = new Text2(seedInfo.price + " coins", {
size: 24,
fill: 0xFFD700
});
priceText.anchor.set(0.5, 0.5);
priceText.y = -60;
seedButton.addChild(priceText);
// Value text
var valueText = new Text2("Value: " + CropConfig[seedInfo.type].value + " coins", {
size: 18,
fill: 0x00FF00
});
valueText.anchor.set(0.5, 0);
valueText.y = 110;
seedButton.addChild(valueText);
// Position and add
seedButton.x = startX + col * spacing;
seedButton.y = startY + row * 220;
seedButton.seedType = seedInfo.type;
seedButton.price = seedInfo.price;
seedButton.interactive = true;
container.addChild(seedButton);
// Click handler
seedButton.down = function (x, y, obj) {
if (coins >= seedButton.price) {
// Purchase the seed
coins -= seedButton.price;
storage.coins = coins;
coinDisplay.updateCoins(coins);
// Show success animation
LK.effects.flashObject(seedButton, 0x00FF00, 500);
// Select this seed type
selectedSeedType = seedButton.seedType;
selectTool(ToolType.SEEDS);
} else {
// Not enough coins
LK.effects.flashObject(seedButton, 0xFF0000, 500);
}
};
});
}
// Create Market content
function createMarket(container) {
var marketTitle = new Text2("Sell your harvested crops at the Market", {
size: 30,
fill: 0xFFFFFF
});
marketTitle.anchor.set(0.5, 0.5);
marketTitle.y = -250;
container.addChild(marketTitle);
var marketDesc = new Text2("Current market prices:", {
size: 24,
fill: 0xCCCCCC
});
marketDesc.anchor.set(0.5, 0.5);
marketDesc.y = -180;
container.addChild(marketDesc);
// Show prices for each crop
var cropsPerRow = 3;
var spacing = 200;
var startX = -(spacing * (cropsPerRow - 1)) / 2;
var startY = -100;
var cropTypes = [{
type: SeedType.WHEAT,
name: "Wheat",
color: 0xF5DEB3
}, {
type: SeedType.CORN,
name: "Corn",
color: 0xFFF44F
}, {
type: SeedType.TOMATO,
name: "Tomato",
color: 0xFF6347
}, {
type: SeedType.CARROT,
name: "Carrot",
color: 0xFFA500
}, {
type: SeedType.POTATO,
name: "Potato",
color: 0xA0522D
}, {
type: SeedType.STRAWBERRY,
name: "Strawberry",
color: 0xFF3366
}];
cropTypes.forEach(function (cropInfo, index) {
var row = Math.floor(index / cropsPerRow);
var col = index % cropsPerRow;
var cropDisplay = new Container();
// Crop visual
var cropVisual = LK.getAsset('harvest_ready', {
anchorX: 0.5,
anchorY: 0.5,
tint: cropInfo.color,
scaleX: 0.8,
scaleY: 0.8
});
cropDisplay.addChild(cropVisual);
// Crop name
var nameText = new Text2(cropInfo.name, {
size: 24,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = 80;
cropDisplay.addChild(nameText);
// Crop value
var valueText = new Text2(CropConfig[cropInfo.type].value + " coins", {
size: 30,
fill: 0xFFD700
});
valueText.anchor.set(0.5, 0.5);
valueText.y = 30;
cropDisplay.addChild(valueText);
// Position
cropDisplay.x = startX + col * spacing;
cropDisplay.y = startY + row * 200;
container.addChild(cropDisplay);
});
var marketNotice = new Text2("Harvest crops with the Harvest Tool to earn coins!", {
size: 24,
fill: 0xFFFFFF
});
marketNotice.anchor.set(0.5, 0.5);
marketNotice.y = 300;
container.addChild(marketNotice);
}
// Show/hide methods
self.show = function () {
self.visible = true;
// Reset to main town view
if (currentShopContent) {
currentShopContent.destroy();
currentShopContent = null;
}
// Show shop buttons
shops.forEach(function (shop, index) {
shopButtons[index].visible = true;
});
};
self.hide = function () {
self.visible = false;
};
// Initialize as hidden
self.visible = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
****/
// Game variables
var PlotState = {
EMPTY: 0,
TILLED: 1,
SEEDED: 2,
WATERED: 3,
GROWING1: 4,
GROWING2: 5,
GROWING3: 6,
READY: 7
};
// Tool configurations
var ToolConfig = {
// Basic tools (available from start)
basic: {
HOE: {
name: "Hoe",
description: "Tills soil for planting",
icon: 'tool_hoe',
unlocked: true
},
SHOVEL: {
name: "Shovel",
description: "Digs holes in the soil",
icon: 'tool_hoe',
tint: 0x666666,
unlocked: true
},
WATER: {
name: "Water Bucket",
description: "Waters your plants",
icon: 'tool_water',
unlocked: true
},
SEEDS: {
name: "Seed Bag",
description: "Plants seeds in tilled soil",
icon: 'tool_seeds',
unlocked: true
},
HARVEST: {
name: "Harvest Tool",
description: "Harvests mature crops",
icon: 'tool_harvest',
unlocked: true
}
},
// Advanced tools (unlocked through purchases)
advanced: {
IRRIGATION: {
name: "Irrigation System",
description: "Waters multiple plots at once",
icon: 'tool_water',
tint: 0x00AAFF,
price: 100,
unlocked: false
},
BETTER_HARVEST: {
name: "Better Harvesting Tools",
description: "Harvest crops faster with bonus yields",
icon: 'tool_harvest',
tint: 0xFFAA00,
price: 150,
unlocked: false
},
AUTO_TILLER: {
name: "Auto-Tilling Tool",
description: "Tills multiple plots at once",
icon: 'tool_hoe',
tint: 0xAA00FF,
price: 200,
unlocked: false
}
}
};
var ToolType = {
HOE: 0,
SEEDS: 1,
WATER: 2,
HARVEST: 3,
SHOVEL: 4,
IRRIGATION: 5,
BETTER_HARVEST: 6,
AUTO_TILLER: 7
};
var SeedType = {
WHEAT: "wheat",
CORN: "corn",
TOMATO: "tomato",
CARROT: "carrot",
POTATO: "potato",
STRAWBERRY: "strawberry"
};
// Crop configuration with growth times in ticks (60 ticks = 1 second)
var CropConfig = {
wheat: {
growthTime: 2 * 60 * 60,
// 2 days (2 min in game time)
value: 4
},
corn: {
growthTime: 3 * 60 * 60,
// 3 days (3 min in game time)
value: 7
},
tomato: {
growthTime: 4 * 60 * 60,
// 4 days (4 min in game time)
value: 10
},
carrot: {
growthTime: 3 * 60 * 60,
// 3 days (3 min in game time)
value: 6
},
potato: {
growthTime: 5 * 60 * 60,
// 5 days (5 min in game time)
value: 12
},
strawberry: {
growthTime: 6 * 60 * 60,
// 6 days (6 min in game time)
value: 15
}
};
var farmPlots = [];
var tools = [];
var currentTool = ToolType.HOE;
var gameWidth = 2048;
var gameHeight = 2732;
var gridSize = 10;
var plotSize = 180;
var plotSpacing = 10;
var coins = storage.coins || 0;
var coinDisplay;
var selectedSeedType = SeedType.CARROT; // Default selected seed
var seedSelector; // Global seed selector for accessing from plot click
// Create game title
var titleText = new Text2("Harvest Haven", {
size: 100,
fill: 0x006400
});
titleText.anchor.set(0.5, 0);
titleText.x = gameWidth / 2;
titleText.y = 30;
game.addChild(titleText);
// Create farm grid
function createFarmGrid() {
var gridWidth = gridSize;
var gridHeight = gridSize;
var startX = (gameWidth - (plotSize * gridWidth + plotSpacing * (gridWidth - 1))) / 2;
var startY = 200;
for (var row = 0; row < gridHeight; row++) {
for (var col = 0; col < gridWidth; col++) {
var plot = new FarmPlot();
plot.x = startX + col * (plotSize + plotSpacing) + plotSize / 2;
plot.y = startY + row * (plotSize + plotSpacing) + plotSize / 2;
farmPlots.push(plot);
game.addChild(plot);
}
}
}
// Create tool selection panel
function createToolPanel() {
var toolbarY = gameHeight - 120;
var toolSpacing = 130;
// Load unlocked tools from storage
var unlockedTools = storage.unlockedTools || {};
// Update tool configs with saved unlock status
Object.keys(ToolConfig.advanced).forEach(function (key) {
if (unlockedTools[ToolConfig.advanced[key].name]) {
ToolConfig.advanced[key].unlocked = true;
}
});
// Create basic tools panel
var basicToolCount = Object.keys(ToolConfig.basic).length;
var startX = (gameWidth - toolSpacing * basicToolCount) / 2 + 65;
// Add basic tools
Object.keys(ToolConfig.basic).forEach(function (key, i) {
var toolData = ToolConfig.basic[key];
var tool = new Tool(ToolType[key], false, toolData);
tool.x = startX + i * toolSpacing;
tool.y = toolbarY;
tools.push(tool);
game.addChild(tool);
});
// Add "Advanced Tools" label
var advLabel = new Text2("Advanced Tools", {
size: 30,
fill: 0xFFFFFF
});
advLabel.anchor.set(0.5, 0.5);
advLabel.x = gameWidth / 2;
advLabel.y = toolbarY - 150;
game.addChild(advLabel);
// Create advanced tools panel
var advancedToolCount = Object.keys(ToolConfig.advanced).length;
startX = (gameWidth - toolSpacing * advancedToolCount) / 2 + 65;
var advToolbarY = toolbarY - 220;
// Add advanced tools
Object.keys(ToolConfig.advanced).forEach(function (key, i) {
var toolData = ToolConfig.advanced[key];
var tool = new Tool(ToolType[key], true, toolData);
tool.x = startX + i * toolSpacing;
tool.y = advToolbarY;
tools.push(tool);
game.addChild(tool);
});
// Set initial selected tool
selectTool(currentTool);
// Add panel backgrounds
var basicPanelBackground = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: gameWidth / 200,
scaleY: 2,
tint: 0x4b0082,
alpha: 0.5
});
basicPanelBackground.x = gameWidth / 2;
basicPanelBackground.y = toolbarY;
game.addChildAt(basicPanelBackground, 0);
var advPanelBackground = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: gameWidth / 200,
scaleY: 2,
tint: 0x4b0082,
alpha: 0.5
});
advPanelBackground.x = gameWidth / 2;
advPanelBackground.y = advToolbarY;
game.addChildAt(advPanelBackground, 0);
// Add seed selector button next to seeds tool
var seedButton = tools.find(function (tool) {
return !tool.isAdvanced && tool.toolType === ToolType.SEEDS;
});
var seedSelectButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
tint: 0x8b5a2b
});
seedSelectButton.x = seedButton.x + 60;
seedSelectButton.y = toolbarY;
game.addChild(seedSelectButton);
var arrowText = new Text2("▼", {
size: 40,
fill: 0xFFFFFF
});
arrowText.anchor.set(0.5, 0.5);
arrowText.x = seedSelectButton.x;
arrowText.y = toolbarY;
game.addChild(arrowText);
// Create seed selector (using game-wide variable)
seedSelector = new SeedSelector();
seedSelector.x = gameWidth / 2;
seedSelector.y = toolbarY - 200;
seedSelector.visible = false;
game.addChild(seedSelector);
// Seed selector button event
seedSelectButton.interactive = true;
seedSelectButton.down = function (x, y, obj) {
seedSelector.show();
};
// Add town button on the top right
var townButton = new Container();
var townButtonBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: 0x4b0082
});
townButton.addChild(townButtonBg);
var townText = new Text2("Town", {
size: 30,
fill: 0xFFFFFF
});
townText.anchor.set(0.5, 0.5);
townButton.addChild(townText);
townButton.x = gameWidth - 120;
townButton.y = 150;
townButton.interactive = true;
game.addChild(townButton);
// Town button event
townButton.down = function (x, y, obj) {
town.show();
};
}
// Create coin display
function createCoinDisplay() {
coinDisplay = new CoinDisplay();
coinDisplay.x = gameWidth - 100;
coinDisplay.y = 80;
coinDisplay.updateCoins(coins);
game.addChild(coinDisplay);
}
// Add coins to player's balance
function addCoins(amount) {
coins += amount;
storage.coins = coins;
// Update display
coinDisplay.updateCoins(coins);
// Show floating coin animation
for (var i = 0; i < amount; i++) {
var coin = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Random starting position near cursor
coin.x = 200 + Math.random() * 100;
coin.y = 200 + Math.random() * 100;
game.addChild(coin);
// Animate coin floating up and towards coin display
tween(coin, {
x: coinDisplay.x,
y: coinDisplay.y,
alpha: 0.8,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 800 + Math.random() * 400,
easing: tween.easeOut,
onFinish: function onFinish() {
coin.destroy();
// Flash coin display
LK.effects.flashObject(coinDisplay, 0xFFFF00, 300);
}
});
}
}
// Find plots near a given plot within a specified radius
function findNearbyPlots(centerPlot, radius) {
var nearby = [];
// Calculate approximate grid position of centerPlot
var plotSize = 180;
var plotSpacing = 10;
var totalSize = plotSize + plotSpacing;
// For irrigation system (3x3 area) special handling
if (currentTool === "Irrigation System" && radius === 1) {
// Use a more rectangular/grid-like pattern for irrigation
farmPlots.forEach(function (plot) {
if (plot === centerPlot) {
return;
} // Skip the center plot
// Get plots in a 3x3 grid (check if they're within 1 grid cell)
var dx = Math.abs(plot.x - centerPlot.x);
var dy = Math.abs(plot.y - centerPlot.y);
// If within a single grid cell horizontally and vertically
if (dx <= totalSize + 10 && dy <= totalSize + 10) {
nearby.push(plot);
}
});
return nearby;
}
// Regular radius-based search for other tools
farmPlots.forEach(function (plot) {
if (plot === centerPlot) {
return;
} // Skip the center plot
// Calculate distance (using squared distance for efficiency)
var dx = plot.x - centerPlot.x;
var dy = plot.y - centerPlot.y;
var distanceSquared = dx * dx + dy * dy;
// Compare with radius (converted to pixels)
var radiusPixels = totalSize * radius + plotSize / 2;
if (distanceSquared <= radiusPixels * radiusPixels) {
nearby.push(plot);
}
});
return nearby;
}
function selectTool(toolType) {
currentTool = toolType;
// Update tool visuals
for (var i = 0; i < tools.length; i++) {
var isSelected = false;
if (typeof toolType === "string") {
// For advanced tools which use string names
isSelected = tools[i].isAdvanced && tools[i].toolData && tools[i].toolData.name === toolType;
} else {
// For basic tools which use ToolType enum
isSelected = !tools[i].isAdvanced && tools[i].toolType === toolType;
}
tools[i].setSelected(isSelected);
}
// Show visual indication of tool's effect area if it's an advanced tool
if (toolType === "Irrigation System") {
// Show irrigation system effect indicator - not implemented in tool info text
var titleText = new Text2("Irrigation System: Waters in a 3x3 area", {
size: 30,
fill: 0x1E90FF
});
titleText.anchor.set(0.5, 0);
titleText.x = gameWidth / 2;
titleText.y = 150;
// Remove after delay
game.addChild(titleText);
LK.setTimeout(function () {
titleText.destroy();
}, 3000);
} else if (toolType === "Auto-Tilling Tool") {
// Show auto-tilling effect indicator
var titleText = new Text2("Auto-Tilling Tool: Tills in a 3x3 area", {
size: 30,
fill: 0xAA00FF
});
titleText.anchor.set(0.5, 0);
titleText.x = gameWidth / 2;
titleText.y = 150;
// Remove after delay
game.addChild(titleText);
LK.setTimeout(function () {
titleText.destroy();
}, 3000);
}
}
// Initialize game
createFarmGrid();
createToolPanel();
createCoinDisplay();
// Create and add town
var town = new Town();
town.x = gameWidth / 2;
town.y = gameHeight / 2;
game.addChild(town);
// Play background music
LK.playMusic('farm_music', {
fade: {
start: 0,
end: 0.3,
duration: 2000
}
});
// Game update loop
game.update = function () {
// Update all plots
for (var i = 0; i < farmPlots.length; i++) {
// Farm plots have their own update method called by LK engine
}
};
// Game input handling
var lastTouchPosition = {
x: 0,
y: 0
};
game.down = function (x, y, obj) {
lastTouchPosition.x = x;
lastTouchPosition.y = y;
};
game.move = function (x, y, obj) {
lastTouchPosition.x = x;
lastTouchPosition.y = y;
};
game.up = function (x, y, obj) {
// We don't need to do anything special here
}; ===================================================================
--- original.js
+++ change.js
@@ -263,8 +263,10 @@
// Find nearby plots
var nearbyPlots = findNearbyPlots(self, 1);
nearbyPlots.forEach(function (plot) {
plot.till();
+ // Visual feedback for each plot
+ LK.effects.flashObject(plot, 0xAA7722, 300);
});
}
break;
case ToolType.SEEDS:
@@ -288,9 +290,13 @@
if (toolAction && currentTool === "Irrigation System") {
// Find nearby plots
var nearbyPlots = findNearbyPlots(self, 1);
nearbyPlots.forEach(function (plot) {
- plot.water();
+ var waterSuccess = plot.water();
+ if (waterSuccess) {
+ // Visual feedback for each watered plot
+ LK.effects.flashObject(plot, 0x1E90FF, 300);
+ }
});
}
break;
case ToolType.HARVEST:
@@ -1410,8 +1416,26 @@
// Calculate approximate grid position of centerPlot
var plotSize = 180;
var plotSpacing = 10;
var totalSize = plotSize + plotSpacing;
+ // For irrigation system (3x3 area) special handling
+ if (currentTool === "Irrigation System" && radius === 1) {
+ // Use a more rectangular/grid-like pattern for irrigation
+ farmPlots.forEach(function (plot) {
+ if (plot === centerPlot) {
+ return;
+ } // Skip the center plot
+ // Get plots in a 3x3 grid (check if they're within 1 grid cell)
+ var dx = Math.abs(plot.x - centerPlot.x);
+ var dy = Math.abs(plot.y - centerPlot.y);
+ // If within a single grid cell horizontally and vertically
+ if (dx <= totalSize + 10 && dy <= totalSize + 10) {
+ nearby.push(plot);
+ }
+ });
+ return nearby;
+ }
+ // Regular radius-based search for other tools
farmPlots.forEach(function (plot) {
if (plot === centerPlot) {
return;
} // Skip the center plot
@@ -1440,8 +1464,38 @@
isSelected = !tools[i].isAdvanced && tools[i].toolType === toolType;
}
tools[i].setSelected(isSelected);
}
+ // Show visual indication of tool's effect area if it's an advanced tool
+ if (toolType === "Irrigation System") {
+ // Show irrigation system effect indicator - not implemented in tool info text
+ var titleText = new Text2("Irrigation System: Waters in a 3x3 area", {
+ size: 30,
+ fill: 0x1E90FF
+ });
+ titleText.anchor.set(0.5, 0);
+ titleText.x = gameWidth / 2;
+ titleText.y = 150;
+ // Remove after delay
+ game.addChild(titleText);
+ LK.setTimeout(function () {
+ titleText.destroy();
+ }, 3000);
+ } else if (toolType === "Auto-Tilling Tool") {
+ // Show auto-tilling effect indicator
+ var titleText = new Text2("Auto-Tilling Tool: Tills in a 3x3 area", {
+ size: 30,
+ fill: 0xAA00FF
+ });
+ titleText.anchor.set(0.5, 0);
+ titleText.x = gameWidth / 2;
+ titleText.y = 150;
+ // Remove after delay
+ game.addChild(titleText);
+ LK.setTimeout(function () {
+ titleText.destroy();
+ }, 3000);
+ }
}
// Initialize game
createFarmGrid();
createToolPanel();
carrot seed. In-Game asset. 2d. High contrast. No shadows
farming hoe. In-Game asset. 2d. High contrast. No shadows
harvesting tool. In-Game asset. 2d. High contrast. No shadows
Irrigation tool. In-Game asset. 2d. High contrast. No shadows
watering can. In-Game asset. 2d. High contrast. No shadows
shovel. In-Game asset. 2d. High contrast. No shadows
Seed bag. In-Game asset. 2d. High contrast. No shadows
Auto harvester. In-Game asset. 2d. High contrast. No shadows
Auto Tiller. In-Game asset. 2d. High contrast. No shadows
water drop. In-Game asset. 2d. High contrast. No shadows
money sign. In-Game asset. 2d. High contrast. No shadows
corn seed. In-Game asset. 2d. High contrast. No shadows
carrot in dirt. In-Game asset. 2d. High contrast. No shadows
Carrot growing in dirt. In-Game asset. 2d. High contrast. No shadows
corn stage 2 growth. In-Game asset. 2d. High contrast. No shadows
Corn growth stage final. In-Game asset. 2d. High contrast. No shadows
Potato seed. In-Game asset. 2d. High contrast. No shadows
Potato growth stage 2. In-Game asset. 2d. High contrast. No shadows
potato growth stage final. In-Game asset. 2d. High contrast. No shadows
Wheat growing stage 2. In-Game asset. 2d. High contrast. No shadows
Wheat growth stage final. In-Game asset. 2d. High contrast. No shadows