// FLOWER GARDEN DISCOVERY SUPREME //
// by Peter Francis //
// Just hold the mouse to water your beloved garden.
// Wow! Plants grow so fast!
// What wonders will you uncover???
color bgColour=color(185, 232, 245);
boolean watering;
//Sets the watering can's spout point to follow the mouse
PVector spoutPoint= new PVector(mouseX+52, mouseY-27);
//defines the array 'water' which stores all the individual droplets
Droplet[] water = new Droplet[250];
Flower[] blooms = new Flower[20];
// defining some clouds
Cloud cloud1;
Cloud cloud2;
Cloud cloud3;
Cloud cloud4;
Cloud cloud5;
Cloud cloud6;
void setup() {
size(800, 400);
// INITIALIZING ARRAYS
//...for water droplets...
for (int i=0; i<water.length; i++) {
water[i] = new Droplet();
}
//... and for our randomized flowers!
for (int i=0; i<blooms.length; i++) {
blooms[i] = new Flower();
}
//INITIALIZING THE CLOUDS
cloud1 = new Cloud();
cloud2= new Cloud();
cloud3= new Cloud();
cloud4 = new Cloud();
cloud5= new Cloud();
cloud6= new Cloud();
}
void draw() {
//Every frame, the "spout point" is reset according to the mouse
spoutPoint.x= mouseX+52;
spoutPoint.y= mouseY-27;
//UPDATES
//updating clouds
cloud1.updateCloud();
cloud2.updateCloud();
cloud3.updateCloud();
cloud4.updateCloud();
cloud5.updateCloud();
cloud6.updateCloud();
// going through the arrays and drawing/updating each drop
for (int i=0; i<water.length; i++) {
water[i].updateDroplet();
}
//updating each flower
for (int i=0; i<blooms.length; i++) {
blooms[i].updateFlower();
}
//DRAWS
//Background Drawings
background(bgColour);
//drawing clouds
cloud1.drawCloud();
cloud2.drawCloud();
cloud3.drawCloud();
drawHillsNTrees();
//some clouds are in the foreground
cloud4.drawCloud();
cloud5.drawCloud();
cloud6.drawCloud();
drawBackgroundSoil();
// an array of draw functions for each water droplet
for (int i=0; i<water.length; i++) {
water[i].drawDroplet();
}
drawWateringCan(mouseX, mouseY);
// an array of draw functions for each flower
for (int i=0; i<blooms.length; i++) {
blooms[i].drawLeaves();
blooms[i].drawFlower();
}
drawForegroundSoil();
// Establish that when the mouse is held, the WATERING variable is true
if (mousePressed) {
watering=true;
} else {
watering = false;
}
}
// The function for drawing the background scenery
void drawHillsNTrees() {
fill(193, 222, 175);
ellipse(780, 380, 320, 560);
ellipse(20, 380, 320, 560);
fill(163, 206, 135);
ellipse(800, 400, 560, 320);
ellipse(0, 400, 560, 320);
}
// The function for drawing the cursor watering can
void drawWateringCan(float centerX, float centerY) {
colorMode(RGB);
stroke(54+100, 134-100, 79+20);
strokeWeight(7);
noFill();
ellipse(centerX-20, centerY-5, 40, 40);
noStroke();
fill(54+100, 134-100, 79+20);
rectMode(CENTER);
rect(centerX, centerY-5, 40, 50, 10);
ellipse(centerX, centerY+15, 40, 20);
quad(centerX+15, centerY, centerX+20, centerY+15, centerX+50, centerY-20, centerX+40, centerY-20);
bezier(centerX+40, centerY-30, centerX+43, centerY-13, centerX+50, centerY-17, centerX+60, centerY-20);
fill(24+100, 104-100, 49+20);
bezier(centerX-15, centerY-25, centerX-14, centerY-15, centerX-5, centerY-15, centerX+10, centerY-25);
strokeWeight(5);
stroke(24+100, 104-100, 49+20);
line(centerX+40, centerY-32, centerX+60, centerY-20);
}
// The function for drawing the soil
void drawForegroundSoil() {
fill(118, 75, 48);
rectMode(CENTER);
noStroke();
float dirtLumpPosition=20;
for (int i=0; i<20; i++) {
ellipse(dirtLumpPosition, 380, 40, 40);
rect(dirtLumpPosition, 390, 40, 20);
dirtLumpPosition+=40;
}
}
// The function for drawing even more soil
void drawBackgroundSoil() {
fill(85, 54, 34);
rectMode(CENTER);
noStroke();
float dirtLumpPosition=0;
for (int i=0; i<21; i++) {
ellipse(dirtLumpPosition, 360, 40, 40);
rect(dirtLumpPosition, 370, 40, 20);
dirtLumpPosition+=40;
}
}class Cloud {
//I chose not to use a PVector here since clouds only move on the X axis.
float cloudplaceY;
float cloudPositionX;
float cloudSpeed;
float cloudWidth;
float cloudHeight;
Cloud() {
cloudplaceY=random(40, 240);
cloudSpeed=random(0.25, 1);
cloudWidth=random(80, 400);
cloudHeight=random(30, 80);
cloudPositionX=random(-500,800);
}
// Updates clouds' random movement
void updateCloud() {
cloudPositionX+= cloudSpeed;
if (cloudPositionX>1000) {
cloudplaceY=random(40, 280);
cloudSpeed=random(0.25, 1);
cloudWidth=random(80, 400);
cloudHeight=random(30, 80);
cloudPositionX= -200;
}
}
void drawCloud() {
rectMode(CENTER);
fill(255, 100);
rect(cloudPositionX, cloudplaceY, cloudWidth, cloudHeight, 10);
rect(cloudPositionX+5, cloudplaceY-5, cloudWidth-10, cloudHeight-10, 10);
}
}class Droplet {
float dropletColour;
float dropletSize;
PVector dropletPosition = new PVector();
PVector dropletSpeed = new PVector();
PVector dropletAcc = new PVector();
Droplet() {
//When the drop initially spawns, it's offscreen
// so the user doesn't see it until they click
dropletPosition.x=850;
dropletPosition.y=spoutPoint.y;
dropletSpeed.x=random(3.5, 5.5);
dropletSpeed.y=random(-2.5, -.75);
dropletAcc.x= random(-0.25, -0.05);
dropletAcc.y= random(0.5, 1.5);
dropletSize= random(3, 6);
dropletColour= random(220, 255);
}
//Updates droplets on their random path towards the thirsty soil
void updateDroplet() {
dropletPosition.x+= dropletSpeed.x;
dropletPosition.y+= dropletSpeed.y;
dropletSpeed.x+= dropletAcc.x;
dropletSpeed.y+= dropletAcc.y;
// Droplets are re-randomized and jump back to the spout of the watering can
// when they fall of screen - but only if the player is still watering!
if (dropletPosition.y>400) {
if (watering==true) {
dropletPosition.x=spoutPoint.x;
dropletPosition.y=spoutPoint.y;
dropletSpeed.x=random(3.0, 5.5);
dropletSpeed.y=random(-2.5, -.75);
dropletAcc.x= random(-0.25, -0.05);
dropletAcc.y= random(0.5, 1.5);
dropletSize= random(3, 6);
dropletColour= random(220, 255);
}
}
}
void drawDroplet() {
colorMode(HSB);
noStroke();
fill(150, 85, dropletColour);
ellipse(dropletPosition.x, dropletPosition.y, dropletSize, dropletSize);
}
}class Flower {
float stemLength;
float flowerPosition;
float flowerMaxHeight;
float stemColor;
float leafVisibility;
float leafDeterminer;
float leafSpacing;
float flowerBloomSize;
float flowerMaxBloomSize;
float flowerHue;
int bloomType;
Flower() {
stemLength=10;
flowerPosition=random(20, 780);
flowerMaxHeight=random(100, 500);
leafVisibility=(0);
stemColor=random(100, 200);
leafDeterminer=1;
leafSpacing= random(15, 45);
//flower variables
flowerMaxBloomSize=random(25, 45);
flowerBloomSize=0;
flowerHue=random(0, 255);
bloomType=int(random(0,2));
}
void drawFlower() {
rectMode(CENTER);
colorMode(HSB);
fill(93, 170, stemColor);
noStroke();
rect(flowerPosition, 360, 5, stemLength);
//Bloom-related stuff
// There are a few types of flower blooms; the variable bloomType
// decides which one is drawn
fill(flowerHue, 200, 230);
if (bloomType==0) {
strokeWeight(2);
stroke(flowerHue, 220, 200);
ellipse(flowerPosition, 350-flowerMaxHeight/2, flowerBloomSize, flowerBloomSize);
float stamenSize=flowerBloomSize-15;
fill(0, 70);
while (stamenSize>5) {
ellipse(flowerPosition, 350-flowerMaxHeight/2, stamenSize, stamenSize);
stamenSize-=10;
}
} else if (bloomType==1) {
fill(flowerHue, 220, 180);
ellipse(flowerPosition+flowerBloomSize*.3, (350-flowerMaxHeight/2), flowerBloomSize*.5, flowerBloomSize*.7);
ellipse(flowerPosition-flowerBloomSize*.3, (350-flowerMaxHeight/2), flowerBloomSize*.5, flowerBloomSize*.7);
fill(flowerHue, 200, 230);
ellipse(flowerPosition, (350-flowerMaxHeight/2)-flowerBloomSize*.3, flowerBloomSize*.7, flowerBloomSize*.5);
ellipse(flowerPosition, (350-flowerMaxHeight/2)+flowerBloomSize*.3, flowerBloomSize*.7, flowerBloomSize*.5);
fill(flowerHue+130, 100, 250);
ellipse(flowerPosition, 350-flowerMaxHeight/2, flowerBloomSize*.3, flowerBloomSize*.3);
}
colorMode(RGB);
}
void updateFlower() {
//this if statement makes flower grow when the watering can is
//spraying water over them.
if (mouseX<flowerPosition-70 && mouseX>flowerPosition-140 && watering==true) {
stemLength+=1;
leafVisibility+=3;
stemLength=constrain(stemLength, 0, flowerMaxHeight);
}
// Update the Bloom
// This if statement makes the flower bloom grow to a point when the stalk is
// at its max height.
if (stemLength==flowerMaxHeight && flowerBloomSize<flowerMaxBloomSize) {
flowerBloomSize++;
}
}
void drawLeaves() {
colorMode(HSB);
float leafHeight=360;
float leafSide=leafDeterminer;
// This variable means each higher leaf appears later
int leafVisibilityModifier=0;
strokeWeight(3);
for (int i=0; i<(flowerMaxHeight/(leafSpacing*2)); i++) {
fill(93, 170, stemColor, leafVisibility-leafVisibilityModifier);
stroke(93, 170, stemColor, leafVisibility-leafVisibilityModifier);
bezier(flowerPosition, leafHeight, flowerPosition-(2)*leafSide, leafHeight-13, flowerPosition-(10)*leafSide, leafHeight-15, flowerPosition-(20)*leafSide, leafHeight-20);
bezier(flowerPosition, leafHeight, flowerPosition-(13)*leafSide, leafHeight-2, flowerPosition-(15)*leafSide, leafHeight-10, flowerPosition-(20)*leafSide, leafHeight-20);
leafHeight-=leafSpacing;
leafVisibilityModifier+=130+leafSpacing*2;
leafSide= leafSide*-1;
}
colorMode(RGB);
}
}