We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi folks,
New to Processing and coding in general. Trying to put something together where a user (various users) input text which goes through a number of processes. I've created 3 screens/cases (?) Screen 0 = User inputs text via keyboard. Hitting control saves a file for print and advances to next screen. Screen 1 = User's text is animated - and here come the sticky part... I want it to animate for a certain amount of time, say 8 seconds, save a PNG and then advance automatically to the next screen. Screen 2 = is a work in progress.
I asked this before and got some great code to do this from screen 0 to screen 1, but the problems arise when I try to implement it from screen 1 to 2 (i.e. in the middle of the programme). After getting loads of different examples for timers and counters, using millis and frame-counts, I realise that the time or frame count is being measured from the start of the programme, not the start of Screen 1 - d'uh! Because some users will be inputting longer texts than others, I can't use an absolute measurement from the start of the programme.
So, I need a way to capture the time from when Screen 1 is called, and get it to advance 8 or so seconds after that. I've tried multiple ways, but there's obviously something wrong with my logic or my code. Any help gratefully accepted.
FYI: eventually (if I ever finish this bloody thing) screen 2 will go back to screen 0, and the whole cycle will start all over again for a new user with the last line of the previous user's text still visible - in other words it will be a sort of crowd-sourced chain narrative...hopefully.
//Code adapted from examples by Amnon available at: https://amnonp5.wordpress.com/2012/01/28/25-life-saving-tips-for-processing/ 
//and Daniel Shiffman available at: http://www.learningprocessing.com/examples/chapter-18/example-18-1/
//and John Park, University Oregon available at: http://pages.uoregon.edu/park/Processing/AdvancedSplit/applet/AdvancedSplit.pde
//and Kyuha Shim, available at: http://visualizing-data.org/index.php?/class-code/52-stringcharatascii-/
import java.util.Calendar;
int currentScreen;
String myText = "Your story..."; //for Screen 0
String yourText = ""; // Variable to store text currently being typed
String savedText = ""; // Variable to store saved text when Control is hit
//------------------
int x=0; //for Screen 1
float rotater = 0;
String [] rotateText = split (savedText, " "); // array of words contained in savedText
//------------------
int[] letterCounts = new int[26]; //for Screen 2
int maxCount = 0;
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ,.;:!? ";
int[] counters = new int[alphabet.length()];
boolean[] drawLetters = new boolean[alphabet.length()];
boolean drawText = true;
String joinedText; 
float charSize; //for Screen 2
color charColor = 0;
int posX = 20;
int posY = 50;
float easing = 0.05;
int timer;
//------------------
PrintWriter textFile; //for Screen 0
// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}
void setup() {
  size(800, 600);
  smooth();
  PFont f = createFont("AGaramondPro-Regular", 140); 
  textFont(f);
  smooth();
  fill (0);
  textAlign(CENTER, CENTER);
  for (int t = 0; t < alphabet.length(); t++) {
  drawLetters[t] = true;
  }
  countCharacters();
}
void draw() {
  switch(currentScreen) {
  case 0: drawScreenZero(); break;
  case 1: drawScreenOne(); break;
  case 2: drawScreenTwo(); break;
  default: background(255); break;
  }
}
void drawScreenZero() {
  background(255);
  textSize (30);
  fill (0);
  text (myText, 0, 0, width, height);
  text (yourText, 0, 0, width, height);
} 
void drawScreenOne() { 
float r;
float g;
float b;
float a;
  r = random(255);
  g = random(150);
  b = random(200);
  a = 20;
    String [] rotateText = split (savedText, " ");
    textSize (140);
    fill(r,g,b,a);
    rotater += 1;
    x++; 
    if(x> (rotateText.length-1)){
      x=0;
    }  
    translate(width/2, height/2);
    rotate (rotater);
    text(rotateText[x],0,0);
    delay(40); // in milliseconds
   // if (frameCount > 599) {
   // saveFrame("rotate_images/"+timestamp()+".png"); //creates a PNG in the sketch directory
   // }
    //if(frameCount > 800) {
     // currentScreen = 2;
    //}
     //if (millis() - timer >= 1799) {
     //  saveFrame("rotate_images/"+timestamp()+".png"); //creates a PNG in the sketch directory
     //   timer = millis();
    //}   
    if (millis() - timer >= 18000) {
      saveFrame("rotate_images/"+timestamp()+".png"); //creates a PNG in the sketch directory
      currentScreen = 2; 
      timer = millis();
    }
}
void drawScreenTwo() { 
  for (int t = 0; t < alphabet.length(); t++) {
  drawLetters[t] = true;
  }  
  background (0); 
  fill (255);
  posX = 20;
  posY = 200;
  float oldX = 0;
  float oldY = 0;
  // go through all characters in the text to draw them  
  for (int t = 0; t < savedText.length(); t++) {
    // find the index of the current letter in the alphabet
    String u = str(savedText.charAt(t)).toUpperCase();
    char uppercaseChar = u.charAt(0);
    int index = alphabet.indexOf(uppercaseChar);
    if (index < 0) continue;
    textSize(20);
    smooth ();
    float sortY = index*20+40;
    float newX =  (frameCount*40) % width; //animates - increases x co-ordinate
    float dx = newX - x; //easing
    if(abs(dx) > 1) {
    newX += dx * easing;
    }
    float m = map(newX, 50,width-50, 0,1); //alphabetises
    m = constrain(m, 0, 1);
    float interY = lerp(posY, sortY, m);
    if (drawLetters[index]) {
        oldX = posX;
        oldY = interY;
      }
/*      
   if (newX > 750) {
      oldX = 750;
    }
    if (sortY > 600) {
      oldY = 600;
    }
*/  
if (drawText) text(savedText.charAt(t), posX, interY);
    else {
      oldX = 0;
      oldY = 0;
    }
posX += textWidth(savedText.charAt(t));
if (posX >= width-200 && uppercaseChar == ' ') {
posY += 40;
posX = 20;
    }
}
      String[] list = splitTokens(savedText, ".?!"); //splits inputted text into lines.
      colorMode(HSB);
      translate(10, height/2);
      //translates each character into an elipse colour coded by its ASCII number
      for (int i=0; i<list.length; i++) {
      for (int j=0; j<list[i].length(); j++) {
      char num = list[i].charAt(j);
      fill(map(int(num), 0, 128, 0, 255)); 
      ellipse(j*15, i*15, 15, 15);
      }
      saveFrame("dot_images/"+timestamp()+".png"); //creates a PNG in the sketch directory
      //noLoop();
  }
}
void keyPressed() {
  if (keyCode == BACKSPACE) {
    if (yourText.length() > 0) {
      yourText = yourText.substring(0, yourText.length()-1);
    }
      } else if (keyCode == DELETE) {
        yourText = "";
      } else if (keyCode != SHIFT && keyCode != CONTROL && keyCode != ALT) {
        myText = "";
        yourText = yourText + key;
      }
  // If the Control key is pressed save the String and write it to text file
  if (key == CODED) 
  {
    if (keyCode == CONTROL) {
      savedText = yourText;
      textFile = createWriter("stories/"+timestamp()+".txt");
      textFile.println(savedText);
      textFile.flush();
      textFile.close();
      rect (0,0,width, height); //PROBLEM sometimes visible when screen is switched.
      noStroke ();
      currentScreen++;
  if (currentScreen > 2) { currentScreen = 0; } //switches to next screen
  } 
 else {
      // Otherwise, concatenate the String
      // Each character typed by the user is added to the end of the String variable.
      yourText = yourText + key;
    }
  }
}
void countCharacters(){
  for (int t = 0; t < savedText.length(); t++) {
    // get one char from the text, convert it to a string and turn it to uppercase
    String u = str(savedText.charAt(t)).toUpperCase();
    // convert it back to a char
    char uppercaseChar = u.charAt(0);
    // get the position of this char inside the alphabet string
    int index = alphabet.indexOf(uppercaseChar);
    // increase the respective counter
    if (index >= 0) counters[index]++;
  }
}
            
Answers
Just store current millis() (or frameCount) in a variable as the start of the new cycle! :-B