Timed Events (system clock, millis, frameCount)

The first assignment using Fisica will be a clock/time visualization app.

This is how to use time functions (you also have day(), month(), year()).

int s = second();  // Values from 0 - 59
int m = minute();  // Values from 0 - 59
int h = hour();    // Values from 0 - 23

They simply read your operating system’s clock.

This sketch prints 3 bars proportional to seconds minutes and hours.

int s;
int m;
int h;
 
void setup()
{
  size(250, 250);
}
 
//this function is called 60 times per second
void draw()
{
  background(0);
 
  //update variables with time and date
  s = second();
  m = minute();
  h = hour();
 
  //change fill
  fill(255, 0, 0);
  //map the lenght of my bar according to my seconds
  float sWidth = map(s, 0, 60, 0, 200);
  //draw a rectangle
  rect(0, 0, sWidth, 50);
 
  //do the same for minutes and hours
  fill(0, 255, 0);
  float mWidth = map(m, 0, 60, 0, 200);
  rect(0,100, mWidth, 50);
 
  fill(0, 0, 255);
  float hWidth = map(h, 0, 23, 0, 200);
  rect(0,200, hWidth, 50);
 
}

How to make something happen every second

int s;
int lastSecond;
 
void setup()
{
  size(200, 200);
}
 
//this function is called 60 times per second
void draw()
{
  s = second();
 
  //if the second was updated then do something once
  if (s != lastSecond)
  {
    println("A second elapsed");
    //update the last second
    lastSecond = s;
    //this variables will be the same until
    //the next second change in the clock
  }
}

Timing events using frame count
frameCount is a processing variable keeping track of the number of seconds since the launch of the program.

The Modulo operator % calculates the remainder of a division so it can be used to repeat event every -multiples of x-

void setup()
{
size(300, 300);
frameRate(60);
}
 
void draw()
{
if(frameCount%60 == 0)
  {
  background(random(255), 255, 255);
  }
 
println(frameRate);
}

millis: how to make something happen between seconds

Common problem: second() is related to the system clock but millis() count starts as you run the applet. Sometimes you need them to be in sync, for example if you want an analog clock with a second arm moving smoothly:

//the function millis() returns the time elapsed since
//the launch of the sketch in milliseconds
 
//millisRolloverTime is the time elapsed since
//the last time a second changed in milliseconds
int millisRolloverTime;
int prevSec;
 
void setup()
{
  size(100, 100);
  millisRolloverTime = 0;
}
 
void draw()
{
  background(0);
 
  if (prevSec != second () ) {
    millisRolloverTime = millis();
  }
 
  prevSec = second();
 
  int milliseconds = millis() - millisRolloverTime;
  text(second() + " " + milliseconds, 10, 20);
 
}

Putting all together in Fisica

Screen Shot 2014-10-06 at 5.00.32 PM

A couple of applications here:

import fisica.*;
 
FWorld world;
 
//declare box as global because I want to be able to access it
FBox b;
 
//same here
FPoly p;
 
//millisRolloverTime is the time elapsed since
//the last time a second changed in milliseconds
int millisRolloverTime;
int lastSecond;
 
void setup() {
  size(800, 600);
 
  Fisica.init(this);
  world = new FWorld();
 
  //creates the edges: 4 static bodies at the edge of the sketch
  world.setEdges();
 
  //their names are world.left, world.right, world.bottom, world.top 
  //set borders invisible (but still active)
  world.top.setDrawable(false);
  world.right.setDrawable(false);
  world.bottom.setDrawable(false);
  world.left.setDrawable(false);
 
  //gravity
  world.setGravity(0, 200);
 
  //create an FBox: a body 30pixels W X 50 pixels H
  b = new FBox(150, 80);
 
  //set its position in the center of the sketch to the left
  b.setPosition(width/2-100, height/2);
 
  //i don't want it to be affected by other bodies
  b.setStatic(true);
 
  //fill
  b.setFill(252, 138, 199);
  //no stroke
  b.setNoStroke();
 
  //add it to the world
  world.add(b);
 
  //create the polygon
  p = new FPoly();
  p.setNoStroke();
 
  //draw like a processing vertex point by point
  p.vertex(0, -50);
  p.vertex(14, -20);
  p.vertex(47, -15);
  p.vertex(23, 7);
  p.vertex(29, 40);
  p.vertex(0, 25);
  p.vertex(-29, 40);
  p.vertex(-23, 7);
  p.vertex(-47, -15);
  p.vertex(-14, -20);
 
  p.setFill(252, 138, 199);
 
  //the center is the position 0, 0
  p.setPosition(200, height-100);
 
  world.add(p);
}
 
 
void draw() {
 
  //change bg according to seconds using HSB mode
  colorMode(HSB, 100); //values from 0 to 99
 
  float bgHue = map(second(), 0, 59, 0, 99);
  color bgColor = color( bgHue, 20, 100);
 
  background(bgColor);
 
  //restore default RGB mode
  colorMode(RGB, 255);
 
  //calculate the current milliseconds
  if (lastSecond != second () ) {
    millisRolloverTime = millis();
  }
 
  int milliseconds = millis() - millisRolloverTime;
 
  //the box moves according to the milliseconds
  float boxRotation = map(milliseconds, 0, 999, -30, 30);
  b.setRotation(radians(boxRotation));
  //note how the rotation doesn't actually push the circles
 
  float boxPosition = map(second(), 0, 59, 200, 600);
  b.setPosition(boxPosition, 400);
 
 
  //every second I create a circle
  if (second() != lastSecond)
  {
  //create new circle 30 pix diameter
  FCircle c = new FCircle(10);
 
  //set its center position
  c.setPosition(width/2, 100);
 
  c.setFill(133, 203, 72);
  c.setNoStroke();
 
  world.add(c);
  }
 
  //every second I also apply a force and a torque to the star
  if (second() != lastSecond)
  {
   p.addImpulse(0, -1000); 
   p.addTorque(1000); 
  }
 
  //obviously update this at the end
  lastSecond = second();
 
  //simulating and drawing are separate steps
  //update the simulation
  world.step();
 
  //draw the physics world
  world.draw();
}
Posted in

Post a comment