Here is my reimplementation of TextRain. I am offering more of a proof of concept solution, so I could really keep things simple. The implementation process is the following: reading a text file with famous quotes on every line, at start initializing an ArrayList of all the letters from every loaded text line, positioned regarding their order in the sentence. Then on every frame I get a live video feed from my webcam and going through all “flying” letters, I check if they collide with these areas of the image that are darker then my “collisionThreshold”, if they collide, I keep the letter still, if not the letter continues down the road.
Code: https://github.com/kamend/IACD_TextRain
import processing.video.*;
// objects
class Letter {
PVector vel;
PVector pos;
char ch;
color col;
};
// global vars
int videoWidth = 640;
int videoHeight = 480;
Capture cap; // video capture device
ArrayList(Letter) LetterList = new ArrayList(Letter)(); // the list that will hold the particles
float letterXOffset = 10; // how far we should draw the individual letters
float letterYOffset = 400; // how far every sentence should be
float collisionThreshold = 30; // haw dark the areas of collision must be
PFont font;
void setup() {
size(640, 480);
// initalizes video capture
cap = new Capture(this, videoWidth, videoHeight);
cap.start();
// read text and launch "particles"
launchSentences();
// setup display font
font = createFont("Helvetica Bold", 16, true);
textFont(font, 16);
}
void launchSentences() {
// read sentences from a file
String lines[] = loadStrings("text.txt");
for (int lineNum = 0;lineNum < lines.length;lineNum++) {
String sentence = lines[lineNum];
int setanceLength = sentence.length();
for (int i=0;i height) {
l.pos.y -= height+letterYOffset;
}
}
}
boolean isColliding(PVector pos) {
float radius = 10.0;
if (pos.y > radius && pos.y < = videoHeight-radius && pos.x >=0 && pos.x < videoWidth) {
PVector pixelPos = pos.get();
pixelPos.add(0.0, radius, 0.0);
int pixelIndex = floor(pixelPos.x) + floor(pixelPos.y)*videoWidth;
color pixelColor = cap.pixels[pixelIndex];
if (brightness(pixelColor) < collisionThreshold)
return true;
}
return false;
}
void draw() {
update();
background(0);
image(cap, 0, 0);
for (int i=0;i= 0.0) {
fill(l.col, 255 - abs(map(l.pos.y, 0, height, -200, 200)));
text(l.ch, l.pos.x, l.pos.y);
}
}
}