Hi, welcome to week 3. We're going to start a brand new project. This is project 3. We're going to call it the ecosystem simulation. Let's look at the premise of what we're going to be doing throughout the whole week. In this project, we really want to exercise the interrelation between classes, but really how they give rise to a dynamic ecosystem. We're going to do it with simple graphics, but I think you could really extrapolate this two whole different ser domains, and a whole series sets of graphic environment. An ecosystem simulation is a computational model that replicates the interactions of the dynamics of living organisms. Also the relationship to the environment. We're going to start with a simple food class that is going to have its own internal logic, like the logic of growth, decay. You could even go further and expand that class on thinking of species. Then we're going to create a herbivore unit that unlike a particle, instead of being ruled by external forces, is going to be ruled by its own internal logic. We're going to bring back the notion of a state machine, what would be the states in which this herbivore will move around the environment and potentially access food, maybe reproduce or potentially, flee away from a carnivore, a predator. We're going to create another entity later. Or for you to explore the interrelationship between the system and how the populations of each one of these different entities might be at risk or change depending on the behavior of the others. Let's start with the simplest, which is our food entity. That's the one we want to write in this video. But for now, we're just going to give it a lifespan similar to a particle. It's going to grow, but it's going to dictate a sense of its own a journey from a small sprout to something that might grow into a tree or something like that. Again, think that I'm not going to be focusing too much on the graphic representation of this food item, which is thought to be a plant of some sort or grass. But for the time being, that's something that you can replace very quickly with some of the knowledge that we've acquired in course 1 and course 2. Let's jump into processing and start writing our ecosystem simulation. Here we are. I'm starting from our boiler plate Canvas so in processing. I've imported the random. I have a Canvas with Canvas width and Canvas height. I'm going to create a new tab here and I'm going to call the tap food. It's going to be the first class we are going to be writing. This class for now, it's going to be rather simple. Let's define its constructor. We're going to have a position that could be just position and then the food size. As we have done with particles, we will have a reference to all foods. I'm skipping ahead a little bit. But what we're doing is creating a position and a size for this food entity. This part, we could actually write it a little bit later, but we'll actually maybe start here. Let's do as we do equalize some of these positions to. There constructure counterpart. The food size as such. Then as we have done before, let's just create a function, which we'll call run, which is going to be a shortcut for all the main functions. What I want to write here is a function for grow, and a function for display. Let's write the display function, which is the simplest one. Let's define display as self. Then we're going to do fill, 0, 255. You can here's some green color, no stroke, and an ellipse. Let's copy paste this. We did a description a little bit longer for position.x, position.y. The size, we're going to use it for the size of this ellipse both the x and y. Nothing really fancy yet, and we could actually call already the display function. Let's replace this comment, so self.display. Great. We have our food. Sorry about that. Great. We have our food. I'm not going to have, in this case, the food called directly into the canvas. As a matter of fact, this is probably a line that you shouldn't have. We want to create a world class, something that would hold the collections. We're going to do it as a new tap. As we have done vector fields in the past, we're going to do world class. We're going to call this the World_Manager, and let's just write our world class. The first thing that our world will have is the class called World_Manager. Let's define its construction. Here, I'm going to pass the variable, so how big the canvas of the screen is for the world to be aware of a certain graphic, main. Here, the manager will be the entity that will be able to create food. For now, it's just probably manage the collections. It will have internally list of all the food, so all the entities from the food class. Being aware that the manager eats a class that will interact with the food class, we're going to import from the food file, import the class, food. Also, let's import random to be able to work with random. Similarly, what we have done with the food class, we're going to create a run function, which is going to be shortcut for all the runtime functions, so self. What we're going to do with the World_Manager, the manager will create food over time and run the food. Just call the run function for each one of the collection. We're going to do that for other entities in this world. Let's start with the food. The creation of the food would be something like create food. Let's define a rate of creation. It's something that is going to happen. If we're adding the creation of the food in the run, that means that we're constantly creating food. This could be a function of food itself. We could start with, let's say, just two or three nodes of food and those food can pollinate and potentially create new food sources. They could have its own internal cycle of reproduction. But for now, just we're going to keep it simple. Out of this world, there's going to be an emergence of food supply that is going to have its own cadence, its own rhythm to exist. Let's create food. We're going to use that rate in an if frame count. If the frame count equals the rate. This is a technique that we've done already a couple times. This modular function is used in conjunction with equal zero, meaning that are we hitting the exact rate? If that rate is five, does five fits perfectly in frame count? Every five frames, we're doing something. If so, we need an x variable, which is a random.uniform from zero to self.size_x. Let's copy all that for y. Create a bit more space. Now we could say that the position equals p vector x, y. The new food would be equals to one entity of the food class with a position, a size of five, and that's it for now, actually, and self.all_food. We're going to append. We're adding to the list of all food, the new food item that we just created. That's the creation of the food. The rate, we cannot do this too quickly because we will end up with too many food items in the screen. When we call this function, create food, let's just do it every 50 frames. Self.create_food. Every 50 frames we create one new food element, and now let's just also add the function for running the food, so if run_food. This is for an entity f in all_food. Let's f.run. Then now this function which executes all the food collection that we have. Basically, we have a world that contains the food list. We have a function that creates some food, and we have a function that just make sure that we call the run function within all this food. The food class here, currently, is just a display. It's a glorified ellipse, that it's a green ellipse that doesn't do much. We're going to add a few more lines here just to have our base food class working, but let's see if we're running into errors. Well, we don't seem to have an error because we're not calling the world yet. We're not constructing a version of this world. Let's just import it from world manager. That's the file. Let's import world manager. With that in mind, we can create a new world now, so my world. It's going to be world manager between the Canvas. Let's just use these variables here. This is going to be the information of the Canvas width and Canvas height, that is going to be passed on to the world in case the world needs that information. Finally, we can call the world.run. We are running into some issues. Let's see the mistakes before we actually execute this correctly. I found a few errors. I think I was missing a self.all_food here, and I think we had, like, a c instead of an x here. Just a few small mistakes here and there. But we should have now our world, as you can see, gradually grows. If this dots are too small for your screen, I think we can just make them bigger, which is 15 for the food size. These are too big. I'm just going to keep them somewhere in 10 or so. We have our food class appearing on the screen. Let's just wrap it up with just making sure that the food has a bit of functionality, which is this grow function that we discussed. The growth function is actually rather simple. We need to give a variable of age. It's going to be zero, self.lifespan. It's going to be let's say 400, and we can create the function grow, by just increasing the age. Self.age += 1. We can make the die function within this, which is if the age gets above the lifespan, we can kill the food item. We're going to do that maybe later. The only thing I want to conclude with is let's just try to map the age of this food item, to the decoloring of. We can actually see dynamically a little bit of this age. We can say that the green color would be a map of the self.age. That goes between zero and the lifespan. That will be mapped to a value of, if the age is zero, meaning it's very young, it's going to be 255, meaning very bright, and if it's get older and older, it's going to go all the way down to 50, and we can use this g value for green, in the green channel of the food item. The final thing is let's make sure that we call the grow. This grow function is so small, but rather we'll continue expanding upon it. That's why actually, I ain't just leaving one line for the grow. What it represents is the grow of age of this food item. Let's see what we have. We have this entity, and you can see the newer entries are very bright, but then they gradually decay. There's this sense of growing older and they decay over time. We're starting to have some information that we can use. Maybe herbivores might be looking for plants that are within a certain range of growth. Meaning, like, some of the better tasting ones. There's a lot of decisions that we can do when we start introducing this information within our classes. We're going to continue working on the different classes in this ecosystem, so I'll see you in the next video.