> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.KX$-Cqoozjo/rev.13
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/** 
 * Rotating Cars (v2.03)
 * by  TFGuy44 (2013/Aug)
 * mod GoToLoop
 * 
 * http://forum.processing.org/topic/adding-in-acceleration-and-momentum
 * http://studio.processingtogether.com/sp/pad/export/ro.9NBw8x3YGExwu/latest
 */

static int gw, gh;
static float x, y, z, v;
static boolean north, south, west, east;

final static float SPD = .2, ROT = .1, ACCEL = .98;

final static short CARS = 50;
final Car[] cars = new Car[CARS];

void setup() {
  size(640, 480);
  smooth();

  gw = width;
  gh = height;

  x = gw>>1;
  y = gh>>1;

  for ( int i = 0; i != CARS; cars[i++] = new Car() );
}

void draw() {
  background(0300);

  for (Car c: cars)  c.go();

  update();
  display();
}

void keyPressed() {
  setKeys(keyCode, true);
}

void keyReleased() {
  setKeys(keyCode, false);
}

static final void setKeys(int k, boolean decision) {
  if      (k == UP    | k == 'W')   north = decision;
  else if (k == DOWN  | k == 'S')   south = decision;
  else if (k == LEFT  | k == 'A')   west  = decision;
  else if (k == RIGHT | k == 'D')   east  = decision;
}

static final void update() {
  v += (north? SPD : 0) - (south? SPD : 0);
  z += (east?  ROT : 0) - (west?  ROT : 0);

  x = (x + gw + cos(z)*v) % gw;
  y = (y + gh + sin(z)*v) % gh;

  v *= ACCEL;
}

void display() {
  translate(x, y);
  rotate(z);

  noStroke();
  fill(-1); 
  rect(-20, -20, 40, 40);

  stroke(0);
  noFill();
  triangle(-15, -15, 15, 0, -15, 15);

  resetMatrix();
}

final class Car {
  boolean a, b, c;
  float x, y;
  float z = random(TWO_PI), v = random(5);
  final color k = (color) random(#000000);

  Car() {
    x = width>>1;
    y = height>>1;
  }

  void go() {
    update();
    display();
  }

  void update() {
    if (random(1) > .98)   a = !a;
    if (random(1) > .95)   b = !b;
    if (random(1) > .95)   c = !c;

    if (a)   v += SPD;
    z += (b? ROT : 0) - (c? ROT : 0);

    x = (x + width  + cos(z)*v) % width;
    y = (y + height + sin(z)*v) % height;

    v *= ACCEL;
  }

  void display() {
    translate(x, y);
    rotate(z);

    noStroke();
    fill(k); 
    rect(-10, -10, 20, 20);

    stroke(0);
    noFill();
    triangle(-8, -8, 7, 0, -8, 8);

    resetMatrix();
  }
}