Here is what I have to share.
Resulting Fully Working P5.JS Game
let farmGrid = ;
let player = { x: 0, y: 0 };
let seeds = 10;
let water = 20;
let money = 50;
let day = 1;
let dayCycle = 0;
const gridSize = 5;
let cropTypes = [
{ name: ‘Wheat’, growthTime: 3, sellPrice: 10 },
{ name: ‘Corn’, growthTime: 5, sellPrice: 20 },
{ name: ‘Carrot’, growthTime: 4, sellPrice: 15 }
];
let selectedCrop = cropTypes[0];
let upgrades = { watering: 1, fertilizer: 0 };
let notifications = ;
function setup() {
createCanvas(600, 400);
for (let i = 0; i < gridSize; i++) {
farmGrid[i] = ;
for (let j = 0; j < gridSize; j++) {
farmGrid[i][j] = { status: ‘empty’, growth: 0, cropType: null };
}
}
}
function draw() {
background(200, 220, 255);
drawFarm();
drawPlayer();
updateDayCycle();
drawUI();
displayNotifications();
drawButtons(); // Draw buttons on top of other elements
}
function drawFarm() {
for (let i = 0; i < gridSize; i++) {
for (let j = 0; j < gridSize; j++) {
let plot = farmGrid[i][j];
stroke(0);
fill(plot.status === ‘empty’ ? 180 : 60, 180, 80);
rect(i * 80, j * 80, 80, 80);
if (plot.growth > 0 && plot.cropType) {
fill(0, 150, 0);
rect(i * 80 + 10, j * 80 + 10, 60, 60);
fill(255);
textSize(12);
textAlign(CENTER);
text(plot.cropType.name, i * 80 + 40, j * 80 + 45);
}
}
}
}
function drawPlayer() {
fill(255, 0, 0);
ellipse(player.x * 80 + 40, player.y * 80 + 40, 30, 30);
}
function mousePressed() {
handleUI();
}
function handleUI() {
// Handle seed purchase
if (isMouseOverButton(500, 10, 80, 40)) {
if (money >= 10) {
seeds += 5;
money -= 10;
notifications.push(“Bought 5 seeds!”);
} else {
notifications.push(“Not enough money!”);
}
}
// Handle watering
if (isMouseOverButton(500, 60, 80, 40)) {
waterPlant();
}
// Handle harvesting
if (isMouseOverButton(500, 110, 80, 40)) {
harvestCrop();
}
// Handle selling
if (isMouseOverButton(500, 160, 80, 40)) {
sellCrops();
}
// Handle planting from UI interaction
if (isMouseOverButton(500, 210, 80, 40)) {
plantCrop();
}
}
// Utility function to check if the mouse is over a button
function isMouseOverButton(x, y, width, height) {
return mouseX > x && mouseX < x + width && mouseY > y && mouseY < y + height;
}
function plantCrop() {
let plot = farmGrid[player.x][player.y];
if (plot.status === ‘empty’ && seeds > 0) {
plot.status = ‘planted’;
plot.growth = 0;
plot.cropType = selectedCrop;
seeds–;
notifications.push(Planted ${selectedCrop.name}!
);
} else if (seeds <= 0) {
notifications.push(“Out of seeds!”);
} else {
notifications.push(“Can’t plant here!”);
}
}
function waterPlant() {
let plot = farmGrid[player.x][player.y];
if (plot.status === ‘planted’ && water > 0 && plot.growth < plot.cropType.growthTime) {
water–;
plot.growth += upgrades.watering;
notifications.push(Watered ${plot.cropType.name}!
);
} else if (plot.status !== ‘planted’) {
notifications.push(“No crop to water!”);
} else {
notifications.push(“Out of water!”);
}
}
function harvestCrop() {
let plot = farmGrid[player.x][player.y];
if (plot.status === ‘ready’) {
money += plot.cropType.sellPrice;
notifications.push(Harvested ${plot.cropType.name} for $${plot.cropType.sellPrice}!
);
plot.status = ‘empty’;
plot.growth = 0;
plot.cropType = null;
} else {
notifications.push(“No crop to harvest!”);
}
}
function sellCrops() {
let totalMoney = 0;
for (let i = 0; i < gridSize; i++) {
for (let j = 0; j < gridSize; j++) {
let plot = farmGrid[i][j];
if (plot.status === ‘ready’) {
totalMoney += plot.cropType.sellPrice;
plot.status = ‘empty’;
plot.growth = 0;
plot.cropType = null;
}
}
}
if (totalMoney > 0) {
money += totalMoney;
notifications.push(Sold crops for $${totalMoney}!
);
} else {
notifications.push(“No crops to sell!”);
}
}
function updateDayCycle() {
dayCycle++;
if (dayCycle > 500) {
day++;
dayCycle = 0;
updateCrops();
}
fill(0);
textSize(16);
text(Day: ${day}
, 10, height - 10);
}
function updateCrops() {
for (let i = 0; i < gridSize; i++) {
for (let j = 0; j < gridSize; j++) {
let plot = farmGrid[i][j];
if (plot.status === ‘planted’ && plot.growth < plot.cropType.growthTime) {
plot.growth += upgrades.watering;
if (plot.growth >= plot.cropType.growthTime) {
plot.status = ‘ready’;
notifications.push(${plot.cropType.name} is ready to harvest!
);
}
}
}
}
}
function drawButtons() {
// Draw buttons with borders for visibility
drawButton(500, 10, 80, 40, “Buy Seeds”, color(255, 200, 200));
drawButton(500, 60, 80, 40, “Water”, color(200, 220, 255));
drawButton(500, 110, 80, 40, “Harvest”, color(200, 255, 200));
drawButton(500, 160, 80, 40, “Sell Crops”, color(240, 220, 200));
drawButton(500, 210, 80, 40, “Plant”, color(220, 220, 240));
}
// Function to draw buttons with hover effect
function drawButton(x, y, width, height, label, baseColor) {
if (isMouseOverButton(x, y, width, height)) {
stroke(0);
fill(150); // Change color on hover for visibility
} else {
stroke(0);
fill(baseColor); // Use the base color when not hovering
}
rect(x, y, width, height, 5); // Rounded corners for better visuals
fill(0);
textSize(14);
textAlign(CENTER, CENTER);
text(label, x + width / 2, y + height / 2);
}
function drawUI() {
fill(0);
textSize(14);
textAlign(LEFT);
// Display resources
text(Money: $${money}
, 10, 20);
text(Seeds: ${seeds}
, 10, 40);
text(Water: ${water}
, 10, 60);
// Display upgrade levels (if any)
text(Watering Level: ${upgrades.watering}
, 10, 80);
text(Fertilizer: ${upgrades.fertilizer}
, 10, 100);
// Display current selected crop type
text(Selected Crop: ${selectedCrop.name}
, 10, 120);
// Additional Instructions for player controls
fill(0, 102, 153);
text(“Press ‘1’, ‘2’, or ‘3’ to change crop type”, 10, 360);
text(“Press ‘P’ to plant crop”, 10, 380);
}
function displayNotifications() {
if (notifications.length > 5) {
notifications.shift(); // Keep only the last 5 notifications
}
fill(255);
notifications.forEach((note, index) => {
text(note, 10, 150 + index * 20);
});
}
function keyPressed() {
// Plant a crop with ‘P’ key
if (key === ‘P’) {
plantCrop();
}
// Crop selection interaction
if (key === ‘1’) selectedCrop = cropTypes[0];
if (key === ‘2’) selectedCrop = cropTypes[1];
if (key === ‘3’) selectedCrop = cropTypes[2];
// Movement
if (keyCode === UP_ARROW) player.y = max(0, player.y - 1);
if (keyCode === DOWN_ARROW) player.y = min(gridSize - 1, player.y + 1);
if (keyCode === LEFT_ARROW) player.x = max(0, player.x - 1);
if (keyCode === RIGHT_ARROW) player.x = min(gridSize - 1, player.x + 1);
}
(My game was 295 bytes. Prompts may fail on subsequent attempts due to non-deterministic behavior.)