To implement text rain I created a class called Letter which contains a position, velocity, char, and some functions to move the letter and check if it is sitting on dark pixels. To move the letters up I check another pixel above the first, and if it is also dark enough, the letter moves up to that position. After changing the video to grey scale I simply check the red values (r,g, and b are now all the same) and if they are below a threshold, which i determined experimentally, they cause the letter to stop moving downward, or even move upward.
https://github.com/jlopezbi/textRainImplementation
import processing.video.*; Capture video; int[] backgroundPixels; int numPixels; int numLetters = 300; float threshold = 31; ArrayList rain; void setup() { size(600, 450, P2D); smooth(); video = new Capture(this, 160, 120); video.start(); numPixels = video.width * video.height; backgroundPixels = new int[numPixels]; loadPixels(); rain = new ArrayList(); for (int i = 0; i< numLetters;i++) { genRandLtr(); } } void draw() { if (video.available()) { video.read(); video.filter(GRAY); image(video, 0, 0, width, height); } loadPixels(); for (int i =0;i<rain.size()-1;i++) { Letter l = (Letter) rain.get(i); l.updatePos(); l.display(); if (l.finished()) { rain.remove(i); genRandLtr(); } } color pix = pixels[mouseY*width+mouseX]; println(red(pix) +" "+ green(pix)+" "+ blue(pix)); updatePixels(); } void genRandLtr() { PVector pos = new PVector(random(0, width), 30); PVector vel = new PVector(0, random(0.5, 1)); int lowerUpper = (int)random(2); int ascii; if (lowerUpper == 0) { ascii = (int) random(65, 90.1); } else { ascii = (int) random(97, 122.1); } char ltr = char(ascii); Letter letter = new Letter(pos, vel, ltr); rain.add(letter); } class Letter { //GLOBAL VARIABLES PVector pos; PVector vel; char ltr; int aboveCheck = 4; //CONTRUCTOR Letter(PVector _pos, PVector _vel, char _ltr){ pos = _pos; vel = _vel; ltr = _ltr; } //FUNCTIONS void display(){ textAlign(CENTER,BOTTOM); text(ltr, pos.x,pos.y); noFill(); //ellipse(pos.x,pos.y,5,5); } void setRandPos(){ pos = new PVector(random(0,width), 0); } void updatePos(){ float xPos = pos.x; float yPos = pos.y; int indexAhead = int(xPos)+int(yPos)*width; int indexAbove = int(xPos)+int(yPos-aboveCheck)*width; float aheadCol = red(pixels[indexAhead]); float aboveCol = red(pixels[indexAbove]); if(aheadCol>threshold){ pos.set(xPos+vel.x, yPos+vel.y,0); } else if(aboveCol<=threshold){ pos.set(xPos, yPos-aboveCheck,0); } } boolean finished(){ return(pos.y>=height-1 || pos.y<=aboveCheck); } } |