Good timing, I just finished a demo sketch answering your questions...
I anticipated them in my previous answer!
Now, I might have overdone it a bit (adding the Matcher interface), but it was fun...
For clarity and organization, I made three files:
SearchWordClass.pde Code:int DISPLAY_FONT_SIZE = 50;
int DISPLAY_TIME = 120; // 2 seconds at 60 FPS
color BACK_COLOR = color(200);
int currentSentenceIdx;
int startFrameCount;
int currentFrameCount;
String currentSentence;
Drawer currentDrawer;
class MatcherAndDrawer
{
Matcher matcher;
Drawer drawer;
MatcherAndDrawer(Matcher m, Drawer d)
{
matcher = m;
drawer = d;
}
}
MatcherAndDrawer[] triggers =
{
new MatcherAndDrawer(
new WordInside("grow"), new Growing()),
new MatcherAndDrawer(
new RegExMatcher("(tiny|small|little)", true),
new Shrinking()),
new MatcherAndDrawer(
new RegExMatcher("fade.*black"),
new Fade(BACK_COLOR, #000000)),
new MatcherAndDrawer(
new RegExMatcher("fade.*gr[ea]y"),
new Fade(BACK_COLOR, #7F7F7F)),
// Only if at start of sentence!
new MatcherAndDrawer(
new RegExMatcher("black.*"), new PlainColor(#000000)),
new MatcherAndDrawer(
new WordInside("white"), new PlainColor(#FFFFFF)),
new MatcherAndDrawer(
new WordInside("blue"), new PlainColor(#0000FF)),
new MatcherAndDrawer(
new WordInside("green"), new PlainColor(#00FF00)),
new MatcherAndDrawer(
new WordInside("red"), new PlainColor(#FF0000)),
// Only as a separate word, but anywhere in the sentence
new MatcherAndDrawer(
new RegExMatcher("\\bcyan\\b", true),
new PlainColor(#00FFFF)),
new MatcherAndDrawer(
new WordInside("magenta"), new PlainColor(#FF00FF)),
new MatcherAndDrawer(
new WordInside("yellow"), new PlainColor(#FFFF00))
};
String[] sentences =
{
"Black Magic Woman",
"Blue Velvet",
"Fade to black",
"Yellow Submarine",
"Growing and Multiplying",
"Cyanide and Hapiness",
"White Christmas",
"Brown Sugar", // Voluntarily not matching
"Little House on the pairie",
"My Baby (Cyan Sleep)",
"The Black Belt Ninja", // Voluntarily doesn't match "black" matcher
"The Yellow Brick Road",
"The Blues Brothers",
"Steven Spielberg Presents... Tiny Toon Adventures",
"Greensleeves",
"Fade to gray",
"The Red Line",
"Magenta is rare in song and film names..."
};
void setup()
{
size(1000, 100);
background(200);
PFont f = createFont("Arial Bold", DISPLAY_FONT_SIZE);
textFont(f);
UpdateData();
}
void draw()
{
background(BACK_COLOR);
currentDrawer.Draw(currentSentence, 10, height - 10, currentFrameCount);
currentFrameCount++;
if (frameCount - startFrameCount > DISPLAY_TIME) // Display a message for a given duration
{
currentSentenceIdx++;
if (currentSentenceIdx == sentences.length)
{
background(BACK_COLOR);
noLoop();
return;
}
UpdateData();
}
}
void UpdateData()
{
currentSentence = sentences[currentSentenceIdx];
println(currentSentence);
currentDrawer = defaultDrawer;
for (int t = 0; t < triggers.length; t++)
{
if (triggers[t].matcher.IsMatching(currentSentence))
{
currentDrawer = triggers[t].drawer;
break;
}
}
currentFrameCount = 0;
startFrameCount = frameCount;
}
Matchers.pde Code:interface Matcher
{
boolean IsMatching(String sentence);
}
class WordInside implements Matcher
{
String word;
WordInside(String w)
{
word = w;
}
boolean IsMatching(String sentence)
{
return sentence.toLowerCase().contains(word);
}
}
class RegExMatcher implements Matcher
{
String regex;
RegExMatcher(String re)
{
regex = re;
}
RegExMatcher(String re, boolean bLoose)
{
if (bLoose)
{
regex = ".*" + re + ".*";
}
else
{
regex = re;
}
}
boolean IsMatching(String sentence)
{
return sentence.toLowerCase().matches(regex);
}
}
/*
Other possible variants (can be combined):
- strict: doesn't use toLowerCase
- at start: uses sentence.startsWith()
- at end (endsWith())
- and so on
*/
Drawers.pde Code:Drawer defaultDrawer = new PlainColor(#7F7F7F);
interface Drawer
{
void Draw(String message, int x, int y, int frame);
}
class PlainColor implements Drawer
{
color col;
PlainColor(color c)
{
col = c;
}
void Draw(String message, int x, int y, int frame)
{
fill(col);
text(message, x, y);
// I don't use frame here
}
}
class Fade implements Drawer
{
color col1, col2;
Fade(color c1, color c2)
{
col1 = c1;
col2 = c2;
}
void Draw(String message, int x, int y, int frame)
{
fill(lerpColor(col1, col2, frame / (float) DISPLAY_TIME));
text(message, x, y);
}
}
class Growing implements Drawer
{
Growing()
{
}
void Draw(String message, int x, int y, int frame)
{
fill(0);
textSize(lerp(0, DISPLAY_FONT_SIZE, frame / (float) DISPLAY_TIME));
text(message, x, y);
}
}
class Shrinking implements Drawer
{
Shrinking()
{
}
void Draw(String message, int x, int y, int frame)
{
float a = frame / (float) DISPLAY_TIME;
pushStyle();
fill(0);
textSize(lerp(DISPLAY_FONT_SIZE, 0, a));
float posX = lerp(width - textWidth(message), x, a);
float posY = lerp(height - DISPLAY_FONT_SIZE, y, a);
text(message, posX, posY);
popStyle();
}
}
You can simplify (get rid of the matchers, using "contains" as before) or expand (adding a time of display per word) this code...