Description:
Creating a generative typography/text output.
Inspiration:
For this week’s assignment, I tried to remake the Digital Rain from the Matrix movie which consists of downward-flowing green characters representing the activity of the virtual environment of the Matrix on screen.
Process:
I have used two main classes: the first one represents a single character whereas the second class represents a combination of characters (vertical series of characters).
Let’s start with the first one. The “Letter” class includes a single function in addition to the constructor. The constructor takes two arguments representing both the x and y coordinates and randomly generates a character (Japanese character) using the ASCII table codes. Round() is used to find the closest integer, whereas the create() function prints the character on the display window.
// Letter class class Letter{ // Attributes char character; int xcoord, ycoord; // Constructor Letter(int xcoord, int ycoord){ // x-coordinate this.xcoord=xcoord; // y-coordinate this.ycoord=ycoord; // Randomly generates a Japanese character (letter) character= char(round(random(12448, 12543))); } void create(){ // Prints the character on the display window text(character, xcoord, ycoord); } }
The second class representing the combination of characters includes two functions in addition to the constructor. One of its attributes is an array of “Letter” objects, which gets initialized in the constructor. I used a for loop to add the characters to the array, with the coordinates depending on the font size. The steps variable is used for the combination’s movement on the screen and is randomly chosen (between 5 and 10). The generate() function is mainly a for() loop that goes through the combination (array) and prints every character keeping in mind that the first character’s (the one at the bottom) color is lighter than the other ones. The gradient was achieved using transparency (alpha). The move() function moves the combinations to the bottom of the screen and checks when it disappears so that it can be taken to the top again.
// Combination class class Combination { // Attributes ArrayList<Letter> combinations; int steps, startingpoint; // Constructor Combination(int xcoord, int ycoord){ combinations = new ArrayList<Letter>(); startingpoint = ycoord; // Create the Letters and add them to the array for(int ycoord2=startingpoint; ycoord2<FontSize*round(random(10,25))+startingpoint; ycoord2+=FontSize){ combinations.add(new Letter(xcoord, ycoord2)); } // Steps or Speed of the combination steps = round(random(5,10)); } void generate(){ for(int i=0; i<combinations.size(); i++){ // Change the color of the text to green fill(text_color, i*15); // Make the first char's color lighter if (i==combinations.size()-1){ fill (firstchar_color); } // Print the letters combinations.get(i).create(); // Move the combination move(i); } } void move(int i){ // Check when the combination leaves the screen if (combinations.get(0).ycoord>height){ for(int j=0; j<combinations.size(); j++){ // Get the combination to the top combinations.get(j).ycoord=-FontSize*(combinations.size()-(1+j)); } } // Move the combination combinations.get(i).ycoord += steps; } }
In the Setup() function, I set the size to 854 x 480, and the textAlign to the center top, and I changed the font to “Courier New”. Then using a for loop, I added all the generated combinations to the main array.
void setup(){ size(854, 480); background(background_color); textAlign(CENTER, TOP); F= createFont("Courier New", FontSize); textFont(F); // Add all the combinations to the array Combinations = new ArrayList<Combination>(); for(int i=10; i<width-10; i+=FontSize){ // Set the Y coordinate randomly Combinations.add(new Combination(i,round(random(0,height-200)))); } }
The draw() function resets the background and prints the characters.
void draw(){ // Reset the background background(background_color); // Print all the characters for (int i=0; i<Combinations.size(); i++){ Combinations.get(i).generate(); } }
Full Code:
PFont F; int FontSize = 20; color background_color = #161d20; color text_color = #20c950; color firstchar_color = #82e2a3; ArrayList<Combination> Combinations; // Letter class class Letter{ // Attributes char character; int xcoord, ycoord; // Constructor Letter(int xcoord, int ycoord){ // x-coordinate this.xcoord=xcoord; // y-coordinate this.ycoord=ycoord; // Randomly generates a Japanese character (letter) character= char(round(random(12448, 12543))); } void create(){ // Prints the character on the display window text(character, xcoord, ycoord); } } // Combination class class Combination { // Attributes ArrayList<Letter> combinations; int steps, startingpoint; // Constructor Combination(int xcoord, int ycoord){ combinations = new ArrayList<Letter>(); startingpoint = ycoord; // Create the Letters and add them to the array for(int ycoord2=startingpoint; ycoord2<FontSize*round(random(10,25))+startingpoint; ycoord2+=FontSize){ combinations.add(new Letter(xcoord, ycoord2)); } // Steps or Speed of the combination steps = round(random(5,10)); } void generate(){ for(int i=0; i<combinations.size(); i++){ // Change the color of the text to green fill(text_color, i*15); // Make the first char's color lighter if (i==combinations.size()-1){ fill (firstchar_color); } // Print the letters combinations.get(i).create(); // Move the combination move(i); } } void move(int i){ // Check when the combination leaves the screen if (combinations.get(0).ycoord>height){ for(int j=0; j<combinations.size(); j++){ // Get the combination to the top combinations.get(j).ycoord=-FontSize*(combinations.size()-(1+j)); } } // Move the combination combinations.get(i).ycoord += steps; } } void setup(){ size(854, 480); background(background_color); textAlign(CENTER, TOP); F= createFont("Courier New", FontSize); textFont(F); // Add all the combinations to the array Combinations = new ArrayList<Combination>(); for(int i=10; i<width-10; i+=FontSize){ // Set the Y coordinate randomly Combinations.add(new Combination(i,round(random(0,height-200)))); } } void draw(){ // Reset the background background(background_color); // Print all the characters for (int i=0; i<Combinations.size(); i++){ Combinations.get(i).generate(); } }
Very nice job Badr. Did you use any sources as references or did you write it from scratch? Nice use of the ArrayList (we haven’t covered it) and good job on fading the fill.
Thank you! I have mainly used references from processing.org (store objects in ArrayLists, characters’ Unicode values).