# Week 4: Spell-Binding Incantations (Generative Text)

I solemnly swear I was up to no good with this assignment.

I have been back into a Harry Potter phase of sorts so of course I had to project that agenda onto this assignment. My urge for this week had always been to make text representative of its meaning, because I love when that is done in media. And when I thought of linking it to Harry Potter, I thought that spells would be the perfect way to achieve this effect.

I ran through a lot of ideas and settled on three relatively well-known spells: Wingardium Leviosa, Accio, and Lumos. Wingardium Leviosa (LeviOsa not LeviosAR) is the levitating charm many people might remember from the first movie, which does exactly what you would expect a levitating charm to do. So, I wanted this text to float up from the bottom and then once it had reached around the top, keep hovering over there. This was simple enough with a function to change the y value according to a particular speed.

The Accio spell can summon any object you take the name of (unless of course it has some anti-summoning protection). To put this effect in text I wanted to have the letters floating around the screen randomly, and then have them abruptly come to their final location. For this, I re-used the Letter class we had done in class, and some of the code from the circular orbit example, because I basically wanted to achieve the opposite flow of it. I made some minor changes to the Letter class, which is here:

```class Letter { //copied from in-class code with very slight changes
float x, y;
float xSpeed, ySpeed;
char letter;

Letter(float _x, float _y, char _c) {
x = _x;
y = _y;
xSpeed = ySpeed = 0;
letter = _c;
}

void update() {
x += xSpeed;
y += ySpeed;
}

void display() {
text(letter,x,y);
}

void checkEdges() {
if (y>height) {
y=0;
}
if (y<0) {
y=height;
}
if (x>width) {
x=0;
}
if (x<0) {
x=width;
}
}
}```

Here’s a random screenshot of the moving letters:

And finally, Lumos would produce a small glowing white light at the tip of your wand, useful for seeing in the darkness. This was pretty simple to achieve, by drawing white text instead of the yellow when a certain time had passed, but also having some yellow transparent bigger text in the background. The idea was that the colour change from yellow to white would give the lighting up effect.

Having decided the overall placement and executing the spells, I thought of inserting a background for a more Harry Potter-esque experience, and decided there could be nothing better than the Hogwarts castle itself.

And then I added a darker tint and added an alpha value to make it faded, and I was done!

I haven’t talked a lot about my process so I’ll mention the highlights here. First of all, I had to download the font and it was not a monospaced one, as I realised in my very first test. So I had to figure out a way to make them it look regularly spaced in the spells where I was separating characters, and for this I used arrays. Every element of the two text_width arrays stored the length of the string uptil the current character, and I updated that alongside in the displaying loop. For the Wingardium Leviosa levitation, I also added the noise code from class to make it look more natural.

For each spell, I made a function which carried out their meaning, and timed them using frameCount. I also included the functionality that on clicking the mouse, frameCount would be reset to -1, hence essentially restarting the sketch. I was thinking of adding Hedwig’s theme as an audio file to run in the background, but then I thought it wouldn’t run long enough and would sound weird. I do plan to check out if I can keep the audio running without it resetting with the mouse click. And of course, the background image and font file had to be included in the sketch folder in Processing.

This was the main sketch’s code:

```PFont f;
PImage img;
String spell1 = "Wingardium Leviosa"; //spell for levitation
String spell2 = "Accio"; //spell for summoning something
String spell3 = "Lumos"; //spell for lighting the tip of the wand
int posx1;
int posy1;
float posx2;
int posy2;
int speed = 2;
float[] text_widths1; //will help in determining the width of substrings
float[] text_widths2;
int x_offset = 250;
Letter letters[] = new Letter[spell2.length()];

void setup(){
size(640, 640);
f = createFont("HARRYP__.TTF", 72); //Harry Potter font used in the movies
textFont(f);
textAlign(CENTER);
posx1 = width/2 - x_offset;
posy1 = height - 72;
posx2 = width/2 - textWidth(spell2)/2;
posy2 = height/2 - 36;
text_widths1 =  new float[spell1.length()];
text_widths2 =  new float[spell2.length()];
for(int i = 0; i<spell2.length(); i++){ //initialising the moving letters for Accio
letters[i] = new Letter(random(640), random(640), spell2.charAt(i));
letters[i].xSpeed = random(-5,5);
letters[i].ySpeed = random(-5,5);
}
}

void draw(){
background(0);
tint(136, 152, 155, 80); //dark, faded effect
image(img, 0, 0);

fill(245, 206, 49);
for(int i=0; i<spell1.length(); i++)
{
//as it is not a monospaced font, text_widths arrays help in storing the width of the string upto
// that character. Here I calculate this by adding the previous element of the array to the width of the current letter
if(i==0)
text_widths1[i] = textWidth(spell1.charAt(i));
else
text_widths1[i] = text_widths1[i-1] + textWidth(spell1.charAt(i));

text(spell1.charAt(i), posx1 + (i==0? text_widths1[0]-13: text_widths1[i]), posy1 + noise(frameCount*.01+i*0.01)*100 - 50);

}
levitate(); //starts the levitating effect

if(frameCount > 250 && frameCount < 400) //for the passage of time
{
for(int i = 0; i<spell2.length(); i++){ //random movement
letters[i].update();
letters[i].display();
letters[i].checkEdges();
}
}

if(frameCount >= 400)
summon(); //to bring the letters into place

if(frameCount >= 450 && frameCount < 525){
//fill(181, 192, 193); - discarded idea for turning grey to yellow
fill(245, 206, 49);
text(spell3, width/2 + 100, height-height/4);
}

if(frameCount >= 525){
lightItUp(); //to give the effect of the yellow being lit up into white
}

}

void levitate(){
if(posy1 - speed > 120) //to levitate upwards uptil a certain point below the border is reached
posy1 -= speed;
}

void summon(){
for(int i = 0; i<spell2.length(); i++){ //stops the random movement by fixing x and y values
if(i==0)
text_widths2[i] = textWidth(spell1.charAt(i));
else
text_widths2[i] = text_widths2[i-1] + textWidth(spell1.charAt(i));

letters[i].x = posx2 + (i==0? text_widths2[0]-13: text_widths2[i]); //same logic for character widths
letters[i].y = posy2;
letters[i].display();
}
}

void lightItUp(){
fill(245, 206, 49, 90); //to give a faint yellow glow from behind
textSize(79);
text(spell3, width/2 + 100, height-height/4);
fill(255);
textSize(72);
text(spell3, width/2 + 100, height-height/4);
}

void mouseClicked(){
frameCount = -1; //resets everything because setup() is called at frameCount = 0
}```

And with all that said, here is the video with all the animations I have been talking about:

I hope this was able to achieve even a little bit of a magical effect. And there’s nothing more to add from my side, so I’ll just say:

Mischief Managed.

## 2 thoughts on “Week 4: Spell-Binding Incantations (Generative Text)”

1. Aaron says:

Love the humor Bhavicka. Nice job all around, especially with figuring out how to work with a non-monospaced font.