Evolving Fish Pond 4: Food

Planning
Step 1
In this lesson we will be creating a Plant class and using it as a food supply for our Fish
Temp1551690413
Step 2
Create a new file named Plant.js
Temp1551683595
Step 3
Include this file in index.html just as you did with Fish.js
Temp1551683655
Step 4
Inside Plant.js create a Plant class
class Plant {

}
Step 5
Give this class a constructor that takes an x and a y as input
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

Assign each input to a class property

Step 6
Also give the plant class a food property which starts at 5 and a size property equal to 10
    this.food = 5;
    this.size = 10;
Planning
Step 7
We're going create several Plant class objects and then we'll draw them to the screen
Temp1551687396
Step 8
Switch to index.js
Temp1551683908
Step 9
Create an array to store multiple plants and name it "plantsArray"
Temp1551683949
Challenge
Step 10
Replicate the same loop-structure which you used to create 5 Fish, but this time use it to create 30 plants
Temp1551684305

You can console.log(plantsArray) to check your work.

Planning
Step 11
Next you'll make the plants draw themselves by giving the class a drawSelf() method
Temp1551687363
Step 12
Switch back to Plant.js
Temp1551685532
Step 13
Add a method named `drawSelf()`
Temp1551685642
Challenge
Step 14
Have the drawSelf method draw a green circle at the Plant's x and y location using this.size for width and hieght

Since we are in HSB mode I will tell you that for green:
Hue is 30, Saturation is 100, and Brightness can also be 100.

Remember to use this.x and this.y.

Step 15
Add an update() method to the Plant class
update() {
    this.drawSelf();
}

We'll use this method to call on our Plants to draw themselves instead of calling it directly

Step 16
Switch to index.js
Temp1551685714
Step 17
Just as we did for fishArray, use a for..of loop to tell each Plant object in plantsArray to "update()" each draw frame
Temp1551685843
Check Your Work
Step 18
Your simulation should now start with several Plants
Temp1551687344
Planning
Step 19
Next we're going to teach the Plants to grow before we get the Fish to eat them

Here are the rules for Plant growing:

  1. Every 2 seconds each Plant recovers 1 unit of food.
  2. Every 2 seconds each Plant has a small chance to create a new adjacent Plant
  3. No two Plants may occupy the same space
  4. No plants may grow out of bounds
Step 20
Create a grow() method for the Plant class
grow() {

}
Step 21
Call this method in the Plant's update method
Temp1551685982
Step 22
If the current time is not a multiple of exactly two seconds, we cancel the function by calling 'return'
Temp1551686118
Step 23
If the Plant has less then 5 food, it will recover one unit of food
  if (this.food < 5) {
      this.food += 1;
  }
Step 24
Here is where we will code plant duplication. Create an if statement that passes with a one in ten chance
  if (random(0, 10) < 1) {

  }

Only 10% of the time will a random number between 0 and 10 be less than 1

Planning
Step 25
When we duplicate a plant we want the new plant to land in a random adjacent spot
Temp1551689835

Each "spot" is this.size pixels away. (10)

Step 26
Create a local variable named "adjX"
    var adjX = this.x + ;

If we round a random number between -1 and 1 we will get one of -1, 0, or +1.

Then if we multiply the number by this.size (which is currently 10) we get -10, 0, or +10.

Assign this value to adjX

    var adjX = this.x + round(random(-1, 1)) * this.size;

And so we have this:

Temp1551686378
Step 27
Repeat this process for a second local variable named adjY
   var adjY = this.y + round(random(-1, 1)) * this.size;
Step 28
Create a new Plant at the location (adjX, adjY) and assign this object to a new local variable "adjPlant"
Temp1551686981
Step 29
Push the value of "adjPlant" into the plantsArray
Temp1551687064
Check Your Work
Step 30
You should now see that your plants grow slowly over time.
Planning
Step 31
We have a few more rules we still need to program
  1. Every 2 seconds each Plant recovers 1 unit of food
  2. Every 2 seconds each Plant has a small chance to create a new adjacent Plant
  3. No two Plants may occupy the same space
  4. No plants may grow out of bounds
Challenge
Step 32
Add an if-statement to prevent Plants from growing out of bounds

Start by adding an empty if-statement around your existing code to push plant into plantsArray

if (                 ) {
    plantsArray.push(plant);
}
  • Use your placeFree function to check if plant is in a free place.
  • If so, we can push plant into plantsArray
  • If not, we should cancel the function with return

Hint: Look at your function definition for placeFree() which should be in index.js

Planning
Step 33
Now we just need to prevent plants from growing on top of each other
Temp1551687771
  1. Every 2 seconds each Plant recovers 1 unit of food
  2. Every 2 seconds each Plant has a small chance to create a new adjacent Plant
  3. No two Plants may occupy the same space
  4. No plants may grow out of bounds
Planning
Step 34
If we can FIND a plant who is less than one plant-length away from the new plant, we should discard the new plant
Temp1551688045
Step 35
We're going to use the Array.find method which is very similar to Array.filter
Temp1551688127

Start by calling the find method on plantsArray

Step 36
We'll call each Plant in the array "otherPlant" and search them one at a time
   //this is the same line as the last step
   //we are adding to it here...
   plantsArray.find((otherPlant) )
Step 37
Place a fat-arrow here to say that we are looking for another Plant object "SUCH THAT" ...
   plantsArray.find((otherPlant) => )
Step 38
...the distance between the new plant and this otherPlant is less than one plant-length away
plantsArray.find((otherPlant) =>
    dist(this.x, this.y. otherPlant.x, otherPlant.y) < this.size
)
Step 39
Use this as a condition in an if-statement and IF we FIND an otherPlant that is too close, we cancel the function
Temp1551689223
Check Your Work
Step 40
Now we should have plants which do not grow on top of each other or out of bounds
Planning
Step 41
Finally we are ready to teach our Fish to eat
Temp1551688795

If a Fish touches a Plant object, it will take away some of its food and add it to the Fish's food

Step 42
Switch to Fish.js
Temp1551688818
Step 43
Add a method named "eat"
eat() {

}
Step 44
We could use a for..of loop to check each plant if they are touching the Fish, but I'm going to show you a forEach loop

It's an array method so we say:

Temp1551689304
Step 45
I read this as "for each plant we do this ... "

Hopefully this fat-arrow syntax is looking recognizable by now...

plantsArray.forEach((plant) => {

})
Step 46
First if the plant doesn't have any food, we give up and return
plantsArray.forEach((plant => 
    if (plant.food <= 0) { return; }
)
Step 47
Then if the distance from the fish to this plant is close enough (less than the sum of their sizes) ...
//still inside the forEach loop...
if (dist(this.x, this.y, plant.x, plant.y) < this.size + plant.size) { 

}
Step 48
We subtract some food from the plant and add it to the fish's food property
//still inside the forEach loop...
if (dist(this.x, this.y, plant.x, plant.y) < this.size + plant.size) { 
    plant.food--;
    this.food++;
}
Step 49
Now we call this method when we update eachFish in "index.js"
Temp1551690141
Step 50
Lastly it's important here to say that if the fish obtains more food than it can hold, we set it's food to the maximum
Temp1551690466
Check Your Work
Step 51
You should now see that your fish can eat plants to recover food
Step 52
As an added effect I like to add some transparency to the Plants so that they fade as food runs out
Temp1551689962
Check Your Work
Step 53
Plants with less food are now slightly transparent
Evolving Fish Pond 4: Food Info

Account

MVCode Clubs

Created By

Newprofile jamie

Course:

Evolving Fish Pond

Access Level

premium

For Teachers and Schools

Teach coding to your students with MVCode Teach

MVCode offers an integrated product designed to teach coding to students.

Learn more about MVCode Teach