WB4: 6-Flocking: Flocking Assignment

# Programming Assignment: Lots of Flying Objects

This page (and it's exercise and bonus problems) are more about graphics programming than fundamental graphics concepts.

If you want to play with the end results, try some circa-2008 sample code here. Because your computer is probably 10,000 faster than the one I had in 2008, you probably want to lower the velocity. I don't recommend trying to read the code! It's archaic JavaScript.

Basically, the methods you're going to experiment with have a bunch of simple objects that each make individual "steering" decisions, and maintain their speeds. This is sometimes referred to as "flocking." The first person to really write about it in the graphics literature was Craig Reynolds who not only wrote the original 1987 paper , but also maintains a good web page with information about it.

By the way the "creatures" that flock are sometimes referred to as "boids" since they aren't always birds (sometimes they are fish, or pedestrians, or ...).

Creating flocking was a project in the old games class (in 2010 and 2012). In fact, some of those old 2010 projects still run (the joy of web programming!) (Ian and Irene's Asteroids Game) (Jeff and Chris' Sheep Herder Game).

Those projects were multi-week things, with pairs of students. This assignment has lower ambitions. But, if you want to learn more about flocking, it can be fun.

The goal in this page is to build a program that has a collection of simple objects that move around with "flocking behavior". Along the way, we'll try out some more JavaScript stuff.

## Flying Boids

As an initial step, we'll keep a collection of objects. Each one has a position, and a velocity. Unlike in previous Workbooks, I will create this using an actual JavaScript class. The code is in flock.js - you will do this exercise by changing this file (and possibly the 7-flock.html file).

Throughout this assignment, we'll maintain that each object (1) stays within the Canvas, and (2) has a constant speed (the magnitude of the velocity vector should remain constant). We'll do this by making the velocity vector always be a unit vector. Note: the real speed of movement will depend on the browser's redraw speed, so it might not actually be constant. It should be close enough.

Right now, this is really simple. My initial boids just fly straight and wrap around. But you can make it cooler.

First make these 3 simple changes - they will help you learn the code.

• Change the "Add" button such that when it is clicked, 10 new boids are placed at random locations with random directions (remember, the velocity vectors must have unit magnitude).
• Change the "Clear" button such that when it is clicked, all the boids are removed (this will be useful for starting over).
• Change things such that the boids are not drawn just as circles or squares. The objects should point in the direction they are going. You could add a marker to the circles (see my old demo), or change the shape to a triangle (that points in the direction of the velocity), or something fancier.

Then make this first real improvement:

• Right now, the objects "wrap around" when they hit the edge. Change it so they "bounce" off the edge instead. So, for example, when an object hits the right edge, its velocity changes to that its moving to the left instead. If it hits a side wall, only the horizontal component of the velocity needs to change.

Then another small change:

• After an object hits something, it changes color briefly. (e.g., they turn red after they hit something). They definitely hit walls, but later, you have them hit other things. This will require you to add state to the Boids. They should stay the "alternate" color for a few frames.

Now for the more challenging things. Implementing these will earn bonus points. You can implement any (or all) of these things. (the old demo does the first two).

• If two objects collide, have them go off in opposite directions. You don't need to get the physics exact (since we're maintaining velocities) - a simple version is to draw a line between the center of the two objects, and have the objects move away from each other in the directions of the line. This should go into the steer method of the boids.

These additions are "steering" behaviors. They are implemented by having a boid on each step make a small adjustment to its direction vector. These decisions are completely local: there is no planning (it only decides what to do immediately), there is no central decision making (each boid decides on its own), and the boid can only make small changes to its direction (it keeps its velocity and cannot turn too sharply). Despite the fact that these steering behaviors are so limited, interesting effects (like flock formation) can emerge. All of these can be added to the steer method of the Boids.

• Implement "alignment" steering. On each step, the boid looks at the other nearby Boids and turns to go in the same direction as the average. This works best if the average is weighted (nearby ones have more weight).
• Implement "separation" steering. On each step, the boid tries to turn away from its neighbors to avoid hitting them.
• Implement "cohesion" steering. On each step, the boid looks at its neighbors and tries to steer to be in the middle of them.
• Implement "chasing" - some boids (it cannot be all of them), choose a target (another boid) and steer to follow it. You should draw the chaser and follower in some way that distinguishes them from the rest. You can make the chaser go a little bit faster than the others (rather than having a unit velocity vector, it could have one with length 2).
• Mouse attraction - have boids turn towards the mouse. They should turn gradually (there should be a limit to how fast they turn).

The steering behaviors require tweaking - you need to tune the parameters to get them to work well. (try it with my old demo). You will probably want to add sliders to help you experiment with the parameters. For example, in my testing (to try out the assignment), I limited the turning to 1 or 2 degrees per step.

A different category of enhancements is to add obstacles to the scene. You could put shapes into the Canvas (circles or rectangles are good enough), and have the boids stay outside of these regions. This means you need to have the boids collide with the edges (just as they do with the boundaries of the Canvas). You also need to make sure your method for randomly placing boids doesn't put things inside the shapes.

Again, the requirements are:

2. implement the clear button
3. change the drawing to have things facing forward
4. bounce off the walls
5. change color briefly after bouncing

The bonus point opportunities are:

1. Have objects bounce off of each other
2. Implement one or more steering behaviors (you can get multiple bonus points for multiple steering behaviors)
3. Implement obstacles

You can do as many (or as few) of the bonus point challenges as you want.

Be sure to describe what you did (especially if you implemented any bonus point features). Put instructions into the html (the file is 7-flock.html and your README.md.

You should do this exercise by editing the file flock.js and 7-flock.html. Things actually run in the 7-flock.html. The graders will look at these files.

Some hints:

1. Do the required changes in the order suggested. This will help you learn the code.
2. Read the references on Craig Reynold's pages for ideas on how to do steering. Here is an advanced article (that includes the basic ideas).
3. Many of the steering behaviors are easier if you represent the velocity as orientation, speed (rather than as x velocity, y velocity). You could change over all of the code. I found I was converting back and forth within the steer function. Math.atan2 is your friend.
4. When working with angles, be careful about wraparound! (angle + 360 degrees = angle)
5. Be sure to document what you are trying to do so we appreciate what you did! (give a list of which requirements you did and which bonus things you did).

## Summary

This is the last page of this workbook (other than the page with flocking on it). Don't forget to do the README.md and QUESTIONS.md