Nature of Code: Random Walks

For my first homework assignment in Nature of Code, I had to create a random walk of my choosing.  I found Mark Kleback’s self-avoiding walk code (github) to be helpful for having a good example of a clean, easy-to-view walker.

I wanted to practice using the classes and constructors for the movers, so I created my own, using Prof. Shiffman’s examples as guidance.  I also wanted to create multiple movers, so I put them into an array of Mover objects.  For my Movers, I decided to use the Socially-Awkward Penguin from meme-lore.

The thing about SAP is that it lives out all of our insecurities and attempts to avoid looking silly, stupid, or foolish in front of others, often making us resort to ridiculously absurd avoidances of interaction.  So I wanted to see if I could recreate this social awkwardness as part of my Movers.

I think I partly succeeded, though I can tell there’s bugginess in the avoidOthers() function of the constructor because sometimes the penguins get trapped along the sides (probably their velocities have them collide against the walls at a greater speed than they’re pushing off the wall, or something).  I also don’t think the penguins perfectly avoid each other in order to get to the most distant space from each other.  They just reverse their direction whenever they get too close to other penguins.  Still I think the effect worked.

Code and demo at OpenProcessing and code at github, as well as posted below the jump:

/* 
 * Ben Turner
 * Nature of Code, NYU-ITP
 * Daniel Shiffman
 * Homework #1:  Random Walk
 * Social-Awkward Penguins avoiding each other!
 */

Mover[] movers = new Mover[4];

void setup() {
  size(800,600);
  smooth();

  for (int i=0;i < movers.length; i++) {
    movers[i] = new Mover();
  }

}

void draw() {
  background(255,10);
  rect(0,0,width,height);
  for (int i=0; i < movers.length; i++) {
    movers[i].update();
    movers[i].avoidOthers();
    movers[i].checkEdges();
    movers[i].display();
  }
}

PImage penguin;

class Mover {
  PVector location;
  PVector acceleration;
  PVector velocity;
  float fleeMaxSpeed;
  int penguinSize;

  Mover() {
    location = new PVector(random(width), random(height));
    velocity = new PVector(random(-3, 3), random(-3, 3));
    acceleration = new PVector(random(-0.1,0.1),random(-0.1,0.1));
    fleeMaxSpeed = 11;
    penguinSize = 100;
  }

  void display() {
    penguin = loadImage("penguin.jpg");
    image(penguin, location.x-(round(penguinSize/2)), location.y-(round(penguinSize/2)), penguinSize, penguinSize);
  }

  void update() {
    velocity.add(acceleration);
    velocity.limit(fleeMaxSpeed);
    location.add(velocity);
  }

  void checkEdges() {
    if ((location.x > width) || (location.x < 0)) {
      velocity.x = velocity.x * -1;
    }

    if ((location.y > height) || (location.y < 0)) {
      velocity.y = velocity.y * -1;
    }
  }

  void avoidOthers() {
    PVector thisVector = new PVector(location.x, location.y, 0);
    for (int i=0; i < movers.length; i++) {
      PVector testVector = new PVector(movers[i].location.x, movers[i].location.y, 0);
      float d = PVector.dist(thisVector, testVector);
      if (d < 100) {
        movers[i].velocity.x = movers[i].velocity.x * -1;
        movers[i].velocity.y = movers[i].velocity.y * -1;
        velocity.x = velocity.x * -1;
        velocity.y = velocity.y * -1;
      }
    }
  }
}