Processing Spring Tutorial

I must admit that Flash guys solved all the animation capabilities that can be done with the code. They gained my respect after started reading this book. Foundation Actionscript 3.0 Animation is a great book and contains practices that can be applied may languages which i decided to apply what i learned to processing. here is a drag drop spring (reminds me flux capacitor) example.

class Ball {

  float r;   // radius
  float x,y; // location
  float xspeed,yspeed; // speed
  float vx = 0.0;
  float vy = 0.0;
  color bgcolor;

  // Constructor
  Ball(float tempR) {
    r = tempR;
    x = random(5);
    y = random(5);
    bgcolor = color(random(100), 30, 30);
  }

  // Draw the ball
  void display() {
    stroke(0);
    fill(bgcolor);
    ellipse(x,y,r*2,r*2);
  }

}

What is above code doing. Its a ball factory or ball constructor if you want to express it in programming jargon. This code should be saved a secondary PDE file for the main project. Keep reading it just for now, dont copy paste it yet. I'm defining a ball with some properties. Radious, x position, y position, x velocity, y velocity and color in order to call this ball factory constructor function to produce a ball in our main programming file.

class Ball {}

This line defines the object that i want to produce.

float r;   // radius
float x,y; // location
float xspeed,yspeed; // speed
float vx = 0.0;
float vy = 0.0;
color bgcolor;

These lines are the object properties.

// Constructor
Ball(float tempR) {
r = tempR;
x = random(5);
y = random(5);
bgcolor = color(random(100), 30, 30);
}

this code is the factory / contractor code. which makes the properties alive/real. i'm calling Ball constructor with a radius value and equalizing it to the "r" value in the constructor. x,y are defined with the random(5) method of processing's inner methods which takes a number between 0 to 5. bgcolor is equalized to a color object which its red value is randomized between 0 and 100.

// Draw the ball
  void display() {
    stroke(0);
    fill(bgcolor);
    ellipse(x,y,r*2,r*2);
  }

And i'm calling the processing draw method on this class to draw a instantiated object. Now Lets move to the main code.

int handleCount = 3;
Ball[] handles = new Ball[handleCount];
Ball ball;

float spring = 0.01;
float friction = 0.8;

void setup() {
  size(600,600);
  colorMode(HSB, 100);
  smooth();

  ball = new Ball(20);

  for(int i=0; i < handleCount; i++){
    Ball handle = new Ball(50);
    handle.x = random(0,1) * width;
    handle.y = random(0,1) * height;

    handles[i] = handle;
  }
}

void draw() {

  background(255);

  for(int i=0; i< handleCount; i++){
    Ball handle = handles[i];
    float dx = handle.x - ball.x;
    float dy = handle.y - ball.y;

    ball.vx += dx * spring;
    ball.vy += dy * spring;
  }

  ball.vx *= friction;
  ball.vy *= friction;
  ball.x += ball.vx;
  ball.y += ball.vy;

  for(int i=0; i<handleCount; i++){
    line(ball.x, ball.y, handles[i].x, handles[i].y);
    handles[i].display();

    if (dist(handles[i].x,handles[i].y, mouseX, mouseY) < (handles[i].r)) {
      if(mousePressed){
        cursor(MOVE);
        handles[i].x = lerp(handles[i].x, mouseX, .2);
        handles[i].y = lerp(handles[i].y, mouseY, .2);
      }else{
        cursor(HAND);
      }
    } else {
      cursor(ARROW);
    }
  }

  ball.display();

}

So i'm thinking about doing something like this : The thing i'll draw seems will have 3 handles and a ball in the middle. i should drag and drop the handles for fun, also the handles are connected to the center ball with elastic rope. I dont know why am i thinking these weird things. But that Flash book made me think. So lets move :

int handleCount = 3;
Ball[] handles = new Ball[handleCount];
Ball ball;

float spring = 0.01;
float friction = 0.8;

i have three handles. (line 1!), i need to reach three handles as a memory reference in the computer so i need to put them in an array. (line 2). and i need a ball (line 3!). Line 3 references to our Ball.pde file which we need to create after saving our main project file so open a new file and name it as "WhatEverYouWant", then create a new file within this new project and name it as Ball.pde. This is important. Processing classnames, filenames and constructor name should be consistent around project in order to use them so we have 2 files. One is "WhatEverYouWant", other one is Ball. Now copy paste our Ball code in the Ball.pde and save it. Then continue with our main program.

void setup() {
  size(600,600);
  colorMode(HSB, 100);
  smooth();

  ball = new Ball(20);

  for(int i=0; i < handleCount; i++){
    Ball handle = new Ball(50);
    handle.x = random(0,1) * width;
    handle.y = random(0,1) * height;

    handles[i] = handle;
  }
}

i'm calling setup function next. its preparing the stuff i need before program starts. defining the project size(600,600), color mode as HSB, and activating smooth for the eye candy visuals. AND! I''m instantiating a Ball! WoW. Programming is damn hard. You'll reach the most fun stuff at the end. The more i enter into programming the more i see and feel it has resemblances with masochism. Beyond that, sometimes you cant find the most fun stuff at the end. It really strengthens your die-trying instincts. Ok enough of thoughts. Back to springs!. I need to instantiate handles which are big balls in this project but you can make a rectangle class and make them all rectangle if you want. Within the for loop which loops 3 times, i'm instantiating a new handle(Big Ball [Balls of Steel!]) at a random position inside the width and height, and putting into that famous handles[] array. Yes! the disgusting part didnt started yet :)

void draw() {

  background(255);

  for(int i=0; i< handleCount; i++){
    Ball handle = handles[i];
    float dx = handle.x - ball.x;
    float dy = handle.y - ball.y;

    ball.vx += dx * spring;
    ball.vy += dy * spring;
  }
  

i'm defining the draw function for the main sketch. defining the background in order to refresh it every frame, then a new FOR LOOP! it'll run for 3 times, because we have 3 handles, so inside that for loop i'm defining a handle variable and equalizing it to every item in handles array. when loop runs first time handle variable will be handles[0], second time handles[1] and so on... I'm measuring handle and ball and storing them in the dx,dy variables to reach following lines. And i'll multiply spring value with the distance value to calculate the velocity of ball.

ball.vx *= friction;
ball.vy *= friction;
ball.x += ball.vx;
ball.y += ball.vy;

i'm multiplying the velocities to fake the friction in the real world and adding the ball.x and ball.y values to this vx,vy values to make the ball move.

for(int i=0; i<handleCount; i++){
    line(ball.x, ball.y, handles[i].x, handles[i].y);
    handles[i].display();

    if (dist(handles[i].x,handles[i].y, mouseX, mouseY) < (handles[i].r)) {
      if(mousePressed){
        cursor(MOVE);
        handles[i].x = lerp(handles[i].x, mouseX, .2);
        handles[i].y = lerp(handles[i].y, mouseY, .2);
      }else{
        cursor(HAND);
      }
    } else {
      cursor(ARROW);
    }
  }

  ball.display();
}

another for loop!. For loops are for making same things over and over again for multiple items. They are like LIFE. They contain complexity and boringness of life at the same time. So i'm drawing 3 lines to 3 handles which starts from the center of the ball and displaying the handles. And next an if/else statement for checking if mouse is over the handles or not. I'm changing the cursor every time a condition is met and using a lerp function i'm moving the handles if you click them inside.

Thats all! You have another meaningless exercise.

comments powered by Disqus