Using the time functions Processing can be used to create clocks. I enjoy making clocks as a simple exercise in design, interactivity, and simple data visualization. It’s also a horrible pastime as I am always aware of exactly how much time I’ve wasted. This demonstration will walk through creating this applet, showing the implementation of the time functions, the pushMatrix() and popMatrix() functions, modulo function (%), and the basic construction of an array of custom objects.

Like many key programming languages Processing is an Object Oriented Programming Language, sometimes referred to as an OOP. The concept might be a little bit hard to grasp for some, however, it is an invaluable tool which cuts down on script lengths and allows for far more interesting an complex programs without a lot of repetitive code. An “Object” (also called a class) is simply a collection of variables and functions. New instances of objects can be created with different values for all the variables and functions of the object can be easily executed to modify the instance. Although objects often have a graphical component or representation within a program it is important to remember that they are only collections of data and functions which can be manipulated in any way for whatever need. Another advantage is that a program, like this example, can contain arrays of objects, allowing them to all be changed within a “for loop”. The result is an elegant code which is very easy to construct and easier to edit.

In this program we will use a custom object to create each column of numbers. Using multiple instances of the column we will only have to set a few parameters for each rather than rewriting the whole script with new variables each time. The first thing to do is to create our object. It will need variables for the location, vertical and horizontal position, and one to indicate which number is highlighted. It also need a function that will draw it on the screen. I named it column, but as long as your consistent and the name doesn’t already represent something else an object can be called anything you want.

class column { //define our column object
  int x,y,n; //define object variables
  column(int xpos, int ypos, int num) {
    x=xpos; // gets variables and puts them into the objects variables
    y=ypos;
    n=num;
  }

  void render(){ //create the function to display each
    pushMatrix(); //push matrix isplates the transformations
    translate(x,y); //translate to the proper position
    for (int i=0; i<10;i++) { //print each letter
      if (n==i) { //if the letter eaquals variable n then make it white
        fill(250);
        text(i,0,i*15);
      }
      else{ // else a dark grey
        fill(255,50); //color white, opacity 50 of 255
        text(i,0,i*15);
      }
    }
    popMatrix(); //escape our isolated transformation
  }
}

“Class” defines a new object and the next five lines create the objects variables and get the values from each new instance. Our render function will be called each frame for each of our instances. It contains a for loop to draw each number in the column. A gray fill is applied unless the number in the drawing loop equals the “n” parameter of the instance, in which case the fill is white. The function also includes a translate function to move the column to the correct position. The translation occurs within a pushed matrix.

Normally any transformations would be applied to everything they precede. In order to apply them to only particular graphics place them between pushMatrix(); and popMatrix();. These functions can be nested but bust always be in pairs. There is also a limit to how many times matrices can be applied. This usually won’t be a problem but for some situations which require extensive iteration there may be a better solution.

column[] ARR=new column[14]; //create the array of column objects
void setup(){
  background(0);
  size(280,200);
  fill(255,50);
  smooth();
  noStroke();
  PFont font; //create a variable for the font and define it's parameters
  font=loadFont("CourierNew36.vlw");
  textFont(font,12);
  for (int i=0; i<ARR.length; i++) {
    ARR[i]=new column(i*15+40,35,0); //set the parameters for all the objects
  }
  frameRate(1); //the program only changes once a second so the framerate can be one
}

Now setting up our environment we need to first create our array of columns. This declaration needs to be outside of the setup function as would any other global variables. Otherwise they would only be usable within that function. Our Setup Function contains the typical environment attributes. smooth(); anti-aliases the graphics. To use different fonts the font first has to be converted to a .vlw font and placed in the data folder of the sketch. This will be done automatically by Processing with the Create Font tool (in the tools menu). The frame rate does not need to be higher than one frame per second since the applet only changes once per second.

The last thing in a setup is a “for loop” to create the objects within our array (arbitrarily named ARR) and define their initial state. Without this the program would give a “null pointer exception” because the objects it is being told to manipulate do not exist. The three parameters which must all be defined are the x position, the y position, and the highlighted number.

void draw() {
  background(0); //clear the pixel buffer each frame
  ARR[0].n=second()/10; //set the variable n to the proper number for each object
  ARR[1].n=second()%10;
  ARR[2].n=minute()/10;
  ARR[3].n=minute()%10;
  ARR[4].n=hour()/10;
  ARR[5].n=hour()%10;
  ARR[6].n=day()/10;
  ARR[7].n=day()%10;
  ARR[8].n=month()/10;
  ARR[9].n=month()%10;
  ARR[10].n=year()/1000;
  ARR[11].n=year()%1000/100;
  ARR[12].n=year()%100/10;
  ARR[13].n=year()%10;
  for (int i=0; i<ARR.length; i++) {
    ARR[i].render();  //render all of our objects
  }
}

The final component is our draw function, to be rendered once per second as we defined in our setup. First it clears the buffer with a white background, then redefines the ‘n’ value for each instance. To access a variable of an instance use the syntax “instance_name.variable”. In our case our instances are within an array so “array_name[index].variable”. The time functions are self explanatory and simply output the integer of the current value. The modulo function (%) helps break up each digit. It outputs the remainder when the two values are divided in the case of “variable%10″ it will give the last digit.

Finally to render the columns use the same syntax as accessing the variables to use the render function. Placing it within a for loop will render it for each object in the array. Notice that the loop only extends to one less than the length of the array ( using the < rather than <=). This is because the index of the first element of the array is 0 not 1.

And that is just it. I hope this is a useful guide to using objects within Processing as well as manipulating data and getting data from the clock. Processing also allows the creation of multiple tabs via the right most button the in the scripting button. All the tabs will be read as one script, and it is a great way to organize your code. It’s often helpful to place an object or function in it’s own tab. Here is our complete script:

column[] ARR=new column[14]; //create the array of column objects

void setup(){
  background(0);
  size(280,200);
  fill(255,50);
  smooth();
  noStroke();
  PFont font; //create a variable for the font and define it's parameters
  font=loadFont("CourierNew36.vlw");
  textFont(font,12);
  for (int i=0; i<ARR.length; i++) {
    ARR[i]=new column(i*15+40,35,0); //set the parameters for all the objects
  }
  frameRate(1); //the program only changes once a second so the framerate can be one
}

void draw() {
  background(0); //clear the pixel buffer each frame
  ARR[0].n=second()/10; //set the variable n to the proper number for each object
  ARR[1].n=second()%10;
  ARR[2].n=minute()/10;
  ARR[3].n=minute()%10;
  ARR[4].n=hour()/10;
  ARR[5].n=hour()%10;
  ARR[6].n=day()/10;
  ARR[7].n=day()%10;
  ARR[8].n=month()/10;
  ARR[9].n=month()%10;
  ARR[10].n=year()/1000;
  ARR[11].n=year()%1000/100;
  ARR[12].n=year()%100/10;
  ARR[13].n=year()%10;
  for (int i=0; i<ARR.length; i++) {
    ARR[i].render();  //render all of our objects
  }
}

class column { //define our column object
  int x,y,n; //define object variables
  column(int xpos, int ypos, int num) {
    x=xpos; // gets variables and puts them into the objects variables
    y=ypos;
    n=num;
  }

  void render(){ //create the function to display each
    pushMatrix(); //push matrix isplates the transformations
    translate(x,y); //translate to the proper position
    for (int i=0; i<10;i++) { //print each letter
      if (n==i) { //if the letter eaquals variable n then make it white
        fill(250);
        text(i,0,i*15);
      }
      else{ // else a dark grey
        fill(255,50); //color white, opacity 50 of 255
        text(i,0,i*15);
      }
    }
    popMatrix(); //escape our isolated transformation
  }
}