Characteristics of your simulator:
Your simulator should act on this group of keyboard commands:
Centering: off Collisions: off Velocity matching: on Wandering: on
In addition to the three forces from Reynolds, each of your creatures should have a small randomness factor (wandering) added to their motion. There are two reasons for this. First, this will cause your creatures to look more natural in their motion. Second, when all of the other three forces have been turned off, this slight randomness will prevent them from moving in exactly a straight line. Also, you should have a minimum and maximum value that you use to clamp the velocity of each creature. This will keep your creatures from sitting still or zooming too fast across the window.
As usual, we will use "Processing" to carry out this assignment:
For any large project such as this, I recommend backing up your work often. You don't want to put in a ton of work and then accidentally delete all of it. I suggest making a new copy of your entire work folder every hour or so, and giving each new copy a higher number. Don't worry about file sizes -- source files are tiny. I also recommend copying all of your backups to a different computer once each day for extra safety.
Before you begin on this assignment, I recommend that you review how to create classes and lists in Processing/Java. Here are some tutorials on these:
Tutorial on Classes #1
Tutorial on Classes #2
Tutorial on ArrayLists
You should begin by deciding what attributes each creature should have. This will include at least position and velocity. Then create a class that includes these attributes. Next, make an arraylist of such creatures. Then create a routine that draws all of your creatures from this list of creatures. Initially this can be as simple as drawing a single circle at the correct position. Initialize your set of creatures to contain just one creature, for the purpose of initially debugging creature motion. Test your drawing routine on this one, un-moving creature.
Next initialize this test creature to have some non-zero velocity. Create a simulation update routine that moves each creature a small distance according to their velocity and your delta_time value. Have the draw() routine call this simulation update routine and draw the creatures. You will have to adjust the velocity and the delta_time values in order to get this first creature to move at a speed that is reasonable. Don't bother with avoiding walls yet. Once you've got one creature working, modify your initialization routine to create 10 creatures with random positions and velocities. Run your simulator on this collection of creatures. Now add a wandering force to their motions, and watch their behavior. You may find it useful to NOT clear the screen at each time-step, so you can watch their paths of motion.
Once you've got several creatures moving, return to working with one creature. Decide whether the edges of the window will wrap toroidally (left/right and top/bottom) or if they will act as hard walls. Then figure out how to make your creature behave correctly when it reaches the edge of the window. If you want hard walls, easiest way to do this is have them "bounce" by negating their x velocity when they are within a short range of the left or right edge, and similarly negate the y velocity near the top or bottom of the window. Drawing the creatures in a manner that shows their direction of motion will help at this point.
If you decide to have your window edges wrap toroidally, you will want to transport your creature from one side to the other the moment it tries to step outside the window. This is easy. What is harder is calculating distances between two creatures (which will come later). One creature that is way over on the left of the window should be considered to be close to a creature at the same height but that is at the far right of the window.
Now you should begin to implement each of the three flocking forces, one at a time. The main issue here is to decide, for each creature, what that creatures nearest neighbors are. That is, which creatures are within a particular distance of the creature in question. Then you can create the flock centering force from this. Just using flock centering will give a behavior that is not exactly like flocking, but they will group in a swarming fashion. You will have to "tune" the strength of the flock centering force in order to get reasonable behavior. You will definitely want to clamp the velocity to the minimum and maximum values while debugging this.
After getting the creatures to use flock centering, add in one of the other two forces. Debug each new force on its own first, without either of the other two flocking forces acting with it. Then start to mix the forces together to see what happens. Part of this mixing process will be tuning the relative strengths of the different forces. Eventually you should have a flocking simulator that has reasonable behavior no matter which of the forces are on or off. Naturally, the most realistic flocking behavior should happen when all of the forces are "on".
Finish up the assignment by adding mouse click behavior and the various keyboard commands. You may have to experiment a fair amount before you can get the creatures to follow or run away from the cursor when the mouse button is held down. These can be implemented in a way that is similar to the flock centering and collision avoidance behaviors, but with just a single "neighbor" (the cursor position).