For my final project, I wanted to experiment with "flocking", a method of animating/imitating animal motion similar to bird flocks or fish schools. This phenomenon was first exhibited with the use of 'boids'; computer generated objects created by Craig Reynolds. The 'boids' followed three methods of steering to accomplish flocking: separation, alignment, and cohesion:
Each boid also possessed an immediate field of vision, known as a 'neighborhood'. This field of vision could be adjusted accordingly to create larger flocks.
Because I have never experiment with 'flocking' before, I decided to follow a step-by-step tutorial of Dan Shiffman's 'Nature of Code', where he explained the basics of applying motion to 2D objects. I will go over some important sections of the 'flocking' code here: 
First, I created a humanoid object (my variation of a boid) with position, velocity, and acceleration vectors. I also set a maxForce variable (to limit the length of the desired velocity vector later on), as well as a maxSpeed variable (speed of the humanoid object).
Since 'flock' is an array, I made sure to add new humanoid objects to 'flock', and limited the number to 100 humanoids. Then, I loop through each humanoid in 'flock' array, and deploy the necessary functions.
To satisfy the first requirement of 'flocking', I needed to achieve alignment. This means that one humanoid must steer itself towards the average direction of the other humanoids in its immediate vicinity. I created a 'fieldofView' variable which acts as the humanoid's neighborhood, and a desiredVel variable (desired velocity). Because the desired velocity is the velocity that I want the humanoid to attain, this means that is can also be seen as the average velocity, since the humanoid should be striving to match the average velocity of the others in the neighborhood. I then iterate through the humanoids, find the distance of the ellipses/humanoids, and deduce if they are within the neighborhood. If so, the 'desired velocity' is added to the velocity of the other nearby humanoids, and then divided by the total number of humanoids to get the average velocity. Lastly, in order to generate a 'steering force', according to Reynolds, simply subtract the desired velocity by the current velocity.  
Then, I created an edges function that made sure the humanoid objects reappeared within the frame if they moved off canvas.
Moving on to Reynold's second requirement, cohesion. Cohesion is similar to alignment, but also different in that rather than attaining the average velocity, a humanoid should be able to match the direction of the other humanoids in the neighborhood. In other words, I needed to get the average position of the flock. Therefore, we do the same thing in alignment by calculating the positions of the other humanoids to determine if they are in the neighborhood, and then instead of adding the other humanoids' velocities to the avg velocity, I add the other humanoids' positions (because we are concerned only with direction). Then, to get a vector in the desired direction, I subtract the average location of the flock by the current position of the humanoid.  
Now, to set the acceleration of the humanoids in the flock to both alignment and cohesion parameters, we just add them together. The last two functions, update() and show() are simply to move and draw the humanoids respectively. 
Lastly, since maxSpeed and maxForce are set as the limits to the avg velocity vector and speed, I decided to make them manipulatable by sliders, so that users can have the freedom to experiment. I also set the field of vision to slider value as well, so that users can adjust the neighborhood size.
Here is a short video of me experimenting with the sliders to achieve various effects:
The whole experience of trying to mimic 'flocking' was really fun and challenging. It really opened my eyes to the powerful capabilities of p5js, and I hope to explore this method even more, since I did not manage to achieve the last requirement, separation. However, I feel that the sliders allow for some interesting results as well. 
Here is the link to the sketch:
Back to Top