Egyptian King(s)

I am no different than any other Egyptian when it comes to loving the Liverpool forward Mohamed Salah who is known as “The Egyptian King”. This man has done so much for Egypt and the world and I am proud to say he is a role model for me. Nevertheless, another more original “Egyptian King” is very close to my heart, the timeless singer Mohamed Mounir. Seeing that they are both always smiling and have distinctive curly black hair, I decided to manipulate images of them as my assignment for this week.

The most difficult part for starting was actually choosing the images from the internet. I tried very high quality pictures but they had too many pixels in them. I tried very small ones but they were too tiny to be able to deal with them. When I got PNG images with transparent backgrounds the effects I had did not work as intended because of the limited space used. Even after finding proper pictures I had to find ones for both Salah and Mounir which are similar in posture, size, and quality. These are some images which I tried but did not work for me:

 

 

 

 

After several trials and errors, I decided to use these two images after I cropped them to be exactly the same size.


 

 

 

Then I decided to get the best out of some code  found on the Pixels tutorial page on Processing.org and the past geomerative class. I used the idea of getting the colors of the image and filling some rectangles with them as if they were large pixels. I then made on of the images the background (Mounir) which is hidden under the image on top (Salah) and tried the idea of making use of distance to significantly change the z-dimension of the squares as if they were flying away with the movement of the mouse as if the user was using a magnifying glass to have a look at the background. I made sure the picture returns to its original state as soon as the mouse leaves the plane so that the image doesn’t remain distorted afterwards.

This is the code I used for the interactive image manipulation.

//inspired from the pixels tutorial on teh processing website
 
PImage mounir;
PImage salah;       // The source image
int rectify = 4; // Dimensions of each cell in the grid
int cols, rows;   // Number of columns and rows in our system
int offset =255;

void setup() {
  size(460, 275, P3D); 
  salah  = loadImage("salah2.jpeg"); // Load the image
  mounir = loadImage("mounir.jpg");
  cols = width/rectify;             // Calculate # of columns
  rows = height/rectify;            // Calculate # of rows
}

void draw() {

  background(mounir);
  loadPixels();
  // Begin loop for columns
  for ( int i = 0; i < cols;i++) {
    // Begin loop for rows
    for ( int j = 0; j < rows;j++) {
      int xS = i*rectify + rectify/2; // x position
      int yS = j*rectify + rectify/2; // y position
      int locS = xS + yS*width;       // Pixel array location
      float r = red(salah.pixels[locS]);
      float g = green(salah.pixels[locS]);
      float b = blue(salah.pixels[locS]);
     // Grab the color
      //color cM = mounir.pixels[locS];
      offset -= mouseX/500;
      constrain(offset,0,255);
      // Calculate a z position as a function of mouseX and pixel brightness
      float zS =(8000/dist(mouseX, mouseY, xS, yS)) ;
      if (mouseX > 450 || mouseX < 10 || mouseY > 266 || mouseY < 10) {
          zS =30;
      }
      // Translate to the location, set fill and stroke, and draw the rect
      pushMatrix();
      translate(xS,yS, zS);
      tint(255, offset);
      fill(r, g, b);
      noStroke();
      rectMode(CENTER);
      rect(0,0,rectify,rectify);
      popMatrix();
    }
  }
  updatePixels();
}

The logic itself is a bit simple but it conveys the message and the purpose directly and creatively, which is the most important thing for me. It represents who I am and that is why I personally like it and feel it is me.

I tried to make a Mario game?

Prologue

Since the start of the class, I have been really struggling with practicing Processing consistently – I would usually start my homeworks 1-2 days in advance and not practice much outside of class hours. But this week is very special: I started working on the weekly assignment 4 days in advance and have even taken some time to practice geomerative* and come up with the midterm idea! 🥳 So here I am, typing this post on a Saturday afternoon (edit: publishing on Sunday though). Enjoy!

Introduction

Fascinated by last week’s spritesheet example, I could not resist using this idea for my assignment. General idea was to make a small game with a moving character catching objects – diamonds in this case. After browsing the web, I have downloaded this pixelated Mario (?) image and cropped it in Photoshop as it wasn’t a PNG.

Mario Spritesheet

Process

Milestone 0: learning how to use the spritesheet. I have re-visited the class example and have carefully studied it to understand what is going on behind the code. And especially this – confusing at first – part:

// loops through each step and returns to image 0 after reaching image 3
    if(frameCount%speed==0){
      step = (step+1)%col;
    }

Milestone 1: placing the diamond and building a collision detection function. It took me a good day (coding on and off) to figure out what is going on wrong with my collision detection function. Oh, I have repeated the same mistake as I did when building the OOP assignment! 😅 Good thing now I finally know how to detect collision between two rectangular objects:

// Mario right corner > diamond left AND Mario left corner < diamond right
  if ((posX + person.width/16) > diamondX && posX < (diamondX + diamond.width/4) && (posY+person.height/16) > diamondY && posY < (diamondY + diamond.height/4)){

Milestone 2: collision detection debugging  – spritesheet’s width and height. OK, the function was built, BUT it didn’t work out the way I wanted it to. I took all of the creative debugging ways I had in mind and just started printing out line by line what the function is doing…After a few coordinate manipulations, it FINALLY hit me that I am uploading my spritesheet in the original size and then I manually resize the image without providing the new size coordinates to my collision function. So, after fixing the sizes I thought that the problem was fixed…Not quite!

trying to detect the right coordinates

Milestone 3: The spritesheet’s dimensions aren’t perfect! 🤦‍♀️😅 After fixing the sizes in Processing I actually went to the original image to see what might be wrong – and there it was: there were a lot of blank spaces between spritesheet’s movements that counted towards the current image’s width and height. Yay, now I finally understand what is happening in my program!

Milestone 4: Beautifying the program. After the main logic of the program was done, I decided to add some functions, such as counting and displaying the score, checking for win, and checking borders for Mario’s movement around the screen.

Epilogue 

I actually never thought that building small games can be this fun and … actually simple? Definitely am proud for working consistently on this throughout the week and can also see some room for improvement (see milestone 3 and demo – there is a moment when Mario catches a diamond despite being a few pixels away from it xD)

Result

Code:

PImage diamond;
PImage person;
PImage[][] movement;
PImage background;
PFont font;

int direction = 1;
int step, score = 0;
int posX, posY;
int diamondX, diamondY;
int speed = 5;
int row = 4;
int col = 4;
int currentWidth, currentHeight;
String textScore = "Score: ";

void setup(){
  
  // output window
  size (600, 600);
  
  // define font
  font = createFont("VT323-Regular", 40);
  textFont(font);
  
  // get images
  diamond = loadImage("diamond.png");
  person = loadImage("person.png");
  background = loadImage("background.png");
  
  // place each direction in 2-dimensional array
  movement = new PImage[row][col];
  
  // divide each step according to each step's dimenstions
  currentWidth = person.width/row;
  currentHeight = person.height/col;
  
  // place each step into the right location
  for(int posY = 0; posY < 4; posY++){
    for(int posX = 0; posX < 4; posX++){
      movement[posY][posX] = person.get(posX*currentWidth, posY*currentHeight, currentWidth, currentHeight);
    }
  }
  
  // always start with these coordinates
  posX = 0;
  posY = height-person.width/8+50;
  
  // dimanod location
  diamondX = (int)random(width-diamond.width-100);
  diamondY = (int)random(height-diamond.height-100);
  
}

void draw(){
  
  background(255);
  image(background, 0, 0, width, height);
  
  // place the character onto the board
  image(movement[direction][step], posX, posY, width/4, height/4);
  
  // move the character
  movePerson();
  checkBorder();
  
  // place the diamond
  image(diamond, diamondX, diamondY, diamond.width/4, diamond.height/4);
  
  // check for collision
  detectDiamond();
  
  // display score:
  displayScore();
  
  // check for win
  checkWin();
}

// move the character
void movePerson(){
  
  // activate if key is pressed
  if(keyPressed){
    
    // move DOWN
    if(keyCode == DOWN){
      // select the corresponding row
      direction = 0;
      // animate the steps to go DOWN in the y-dir (increase)
      posY+=speed;
    }
    
    // move UP
    if(keyCode == UP){
      // select the corresponding row
      direction = 1;
      // animate the steps to go UP in the y-dir (decrease)
      posY-=speed;
    }
    
    // move LEFT
    if(keyCode == LEFT){
      // select the corresponding row
      direction = 2;
      // animate the steps to go LEFT in the x-dir (decrease)
      posX-=speed;
    }
    
    // move RIGHT
    if(keyCode == RIGHT){
      // select the corresponding row
      direction = 3;
      // animate the steps to go RIGHT in the x-dir (increase)
      posX+=speed;
    }
    
    // loops through each step and returns to image 0 after reaching image 3
    if(frameCount%speed==0){
      step = (step+1)%col;
    }
  }
}

// needs some bug fixing
void checkBorder() {
  
  // return from the left
  if (posX >= width) {
    posX = -currentWidth;
  }
  
  // return from the right
  if (posX+currentWidth < 0) {
    posX = width;
  }
  
  // return from the bottom
  if (posY+currentHeight < 0) {
    posY = height;
  }
  
  // return from the top
  if (posY > height) {
    posY = -currentHeight;
  }
}

// check for the image collision (diamond collection)
void detectDiamond(){
  
  // Mario right corner > diamond left AND Mario left corner < diamond right
  if ((posX + person.width/16) > diamondX && posX < (diamondX + diamond.width/4) && (posY+person.height/16) > diamondY && posY < (diamondY + diamond.height/4)){
 
    // increment the score
    score++;
    
    // replace diamond
    diamondX = (int)random(width-diamond.width-100);
    diamondY = (int)random(height-diamond.height-100);
  }
}


// display the score
void displayScore(){
  push();
    fill(0);
    text("Score: " + score, width-180, 40);
  pop();
}

void checkWin(){
  if (score == 5) {
    background(103, 212, 239);
    push();
      textAlign(CENTER);
      fill(random(255), random(255), random(255));
      textSize(100);
      text("You WON!", width/2, height/2);
    pop();
  }
}

 

Week 5: Image Manipulation

I’ve got to say, I was really disappointed when I was writing this title and I realized we were only on week 5 :/

I was really excited for this assignment, and the idea I wanted to create. I wanted to create a Mosaic Image. Unfortunately, because of time constraints and also << talent >> constraints, I decided to go for a more simple Interactive Image.

I had a few issues with creating the Mosaic image:

  1. I could not find enough filler images on time – Especially ones that matched the final images
  2.  I had technical constraints, such as I didn’t know how to create a code that could go through several images and find a small (but not too small) section in one with an average RGB value to match the original image.
  3. To accomplish this, it would have to be so many images that i would be able to zoom on each pixel and see the image, but when I zoom out I should still be able to make out what the original photo was

I had more, but these were some. I took a lot of time reading other codes online, but they were difficult to understand. I do still have it as a goal to accomplish a code like this, and hopefully, I’ll manage to do it.

For my actual assignment, my main obstacle was trying to understand the mechanism of my idea: which was to change the image upon hover. After I figured it out it seemed so simple, but sometimes I overthink things.

I also added interactivity where you can change the size of the ‘window’ you are viewing from, using the right or left arrows, which I thought added a nice touch.

Special thanks for my dog Coco, for being this week’s Model:

 

The second image is when she was younger (and no doubt much cuter, sorry Coco).  It was also nice to play around with either using pixels/ellipses,  and this image looked very…  classy?

Week 5: Image Processing

The more I learn about something, the more beauty I find in it. Learning more about images and pixel manipulation in processing allows me to incorporate processes I already enjoyed working with before which sparked my motivation to learn the code needed for what I want to do. This weeks work is inspired by a project of a friend who introduced me to the color fade timer. I incorporated random() and mapped mouseX and mouseY to use their values to manipulate color and opacity. This “filter” is good to use on images with high contrast between lighter and darker areas and the threshold would then need to be adjusted to the specific image. For this work I used an image with white background so I was able to use a relative high threshold to have clear shapes.

PImage hands;
int threshold = 230; //needed to apply different "filters" to fore- and background
color black = color(0, 0, 0);
FadeColorTimer fc;


void setup() {
  // basic settings
  fc = new FadeColorTimer( color(255, 255, 255), color(255, 0, 0), 4000, 1000); //start from white and fade to red
  size(640, 640);


  // load an image
  hands = loadImage("hands.png");
  // resize
  hands.resize(220, 220);
  // load pixels of source-image
  hands.loadPixels();
}

void draw() {
  //ellipse behind the hands
  fill(fc.c()); // use current color
  noStroke();
  ellipse(width/2, height/2, 400, 400); 

  //two different "filters" for fore/backgroud determined by pixel brightness
  // iterate over image-pixels
  //code informed from https://processing.org/discourse/beta/num_1265567803.html
  for (int i=0; i<hands.pixels.length; i++ ) {
    // get the color
    int col = hands.pixels[i];
    //fill with different, randomly changing colors depending on brightness of the original pixels
    //darker foreground/hands
    if (brightness(col) < threshold) {
      int x = i%hands.width * 3;
      int y = i/hands.width * 3 +3;
      map(mouseX, 0, width, 0, 255);
      map(mouseY, 0, width, 0, 255);
      fill(color(random(0, mouseY), random(0, 50), random (0, 150), mouseX)); //mapping color/opacity to mouseX/mouseY creates different effects here
      rect(x, y, 5, 10); //bigger numbers draw longer "shadow" under hands
    } 
    //lighter background
    else if (brightness(col) >=threshold) {
      int x = i%hands.width * 3;
      int y = i/hands.width * 3 +3;
      fill(color(random(200, 255), random(150, 210), random (50, 180)));
      text("..", x, y); //using differnt numbers/letters here will create a different pattern for the background
    }
  }
  hands.updatePixels();
}

void keyReleased() {
  color cr = color(random(255), random(255), random(255));
  // change the target color to a random color (and restart timer)
  fc.set(cr);
}

//this code is from https://forum.processing.org/two/discussion/20861/change-between-colors-over-time
class FadeColorTimer {
  color c1, c2, c;
  int start, duration;
  FadeColorTimer(color _c1, color _c2, int _start, int _duration) {
    c = _c1;
    c1 = _c1;
    c2 = _c2;
    start = _start;
    duration = _duration;
  }
  void set(color _c2) {
    set(c, _c2, millis(), duration);
  }
  void set(color _c2, int _duration) {
    set(c, _c2, millis(), _duration);
  }
  void set(color _c2, int _start, int _duration) {
    set(c, _c2, _start, _duration);
  }
  void set(color _c1, color _c2, int _start, int _duration) {
    c1 = _c1;
    c2 = _c2;
    start = _start;
    duration = _duration;
  }
  void update() {
    println(c1, c2, map(millis(), start, start+duration, 0.0, 1.0));
    c = lerpColor( c1, c2, map(millis(), start, start+duration, 0.0, 1.0));
  }
  color c() {
    this.update();
    return c;
  }
}

 

Candy colored spiral visual effect

This has gone through many iterations of trial and error to get the coolest effect.

Im using spiraled ellipses as a main element for my mid term, so I have been experimenting with it.

Code for creating the spiral:

float angle;

float x;
float y;
void setup() {
  size(800, 800);
  noFill();
  shapeMode(CENTER);
}

void draw() {

  //fill(255);
   fill(255,200,200); //pale rose, change the color of the candy.
  ellipse(height/2, width/2, 600, 600);
  
  int hundred=100;
  //rotate(angle);

  for (int i=0; i<500; i+=100)

  { 
    strokeWeight(20);
    stroke(0); //change the color of the spiral
    noFill();
    ;
    arc(height/2, width/2, hundred+i, hundred+i, radians(180), radians(360) );
    arc(height/2-25, width/2, hundred*1.5+i, hundred*1.5+i, radians(0), radians(180));
  }
  //angle=angle+0.1;
  //save("mySpiral.jpg");
};

I exported the code above to a .jpg format to use as an image in the sketch below.

Code for the animation:

float angle;
PImage img;
void setup() {
  size(900, 900);
  img = loadImage("mySpiral.png");
};
void draw() {
    background(255);
  for (int i=0; i<width; i++) {
 
     translate(width/2+i, height/2+i);
  imageMode(CENTER);
  rotate(angle);
  image(img, 0, 0,300,300);
  
 
  }
 angle=angle+1*1;
}

 

Next step :

I would like each candy spiral to go through several colored versions of itself:

 

  for (int a= 0; a<1; a++) {
     save(random(20)+"spiral");
  }

This code allows different colored versions from random to be saved as a new version of itself , I plan on using the saved photos as part of a sprite sheet to add to the animation above.

Generative text assignment

In last week’s class, I was really interested in the circle of letters code, so I wanted to do something similar for my generative text assignment. I borrowed a lot of code from the circle code document, and in this week’s assignment, a lot of my time was put into studying the code in order to apply the additions that I wanted to.

Regarding my idea, the circle of letters reminded me of Iron man 1, when Pepper gave Tony the gift that said: “Proof that Tony Stark has a heart.” Our assignment was to create generative texts, so I couldn’t just create a stagnant version of the gift. Instead, I decided to make it blink, like how tony’s reactor would blink sometimes.

Code wise, some lines in the code was really helpful in helping me understand arrays and objects. For instance:

Circle letters[] = new Circle[s.length()];

I was still unfamiliar with calling multiple objects and putting them into arrays, so this line helped clear things up for me well. The use of trigonometry was also inspiring for my future approaches to OOP.

Here is my full code:

String s = "        PROOF THAT TONY STARK                    TRAEH A SAH            "; 
PImage img;
float speed = 2;

Circle letters[] = new Circle[s.length()];
PFont f;
float r = 250;
float dir = 1;
float font_size = 30;

void setup(){
  size(640, 640);
  img = loadImage("Tony.png");
}

void draw(){
  background(0);
  f = createFont("Arial", font_size);
  textFont(f);
  float radius = r;
  float startingAngle = PI;
  float circleCenterX = width/2;
  float circleCenterY = height/2;
  
  for (int i =0; i<s.length();i++){
     float angle = startingAngle + i*TWO_PI/s.length();
     float x = cos(angle)*radius + circleCenterX;
     float y = sin(angle)*radius + circleCenterY;
     letters[i] = new Circle(x, y, s.charAt(i));
  }

  for (int i =0; i<s.length();i++){
     letters[i].display(); 
  }  

  if (r >=  250){
    dir = -dir;
  }
  else if (r <= 20){
    dir = 1;
  }
  imageMode(CENTER);
  image(img, width/2+font_size/3, height/2-font_size/3,  r*2-font_size, r*2-font_size);
  
  if (dir == -1){
  font_size = font_size - speed/8;
  }
  else if (dir == 1){
  font_size = font_size + speed/8;
  }
  
  
  r = r + speed * dir;

}

Circle class:

class Circle {
  float x, y;
  char letter;

  Circle(float _x, float _y, char _c) {
    x = _x;
    y = _y;
    letter = _c;
  }

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

Video:

Help Needed! – Spotify Top 20 Visualization

Well, I’ve been trying to get different versions of this program to work for a while, but it’s not perfect yet. It’s far from it actually. I’m going to walk you through my thought process and show you my code, any suggestions would be much appreciated!

 

So, for this week, I noticed that Spotify allows users to access their own data as well as the charts from every day in CSV format (which is very cool). Unfortunately, personal data takes a long time to be prepared and sent to you, so even after asking for it on Thursday, I didn’t receive it so I couldn’t use it. Honestly, that was kind of a relief, I’m not ready to share my Spotify stats with you guys yet…a lot of embarrassing guilty pleasures on there.

Anyways, I decided to use the top 20 songs from the first week in September, and then create a data visualization of how well these songs were doing throughout the month. I downloaded all four CSV files that contain the Top 200 and recorded the values relevant to me (streams for week 1 top 20) in my own CSV file.

Process

Using a multi-row/column CSV file meant I needed different functions than the ones we used in class (loadStrings). I looked up loadTable() and watched a bunch of tutorials on it.

For my visualization, I wanted to achieve to main things. One, present the data using musical symbolism.  Two, use user text input to “search” one of the top 20 songs.

For one, I came up with a system where each note value represents a range of streams, and hence if the data in the CSV file corresponds to a certain range a certain note will be displayed on the staff I drew on screen.

So, through looking at a display of 4 notes on the screen one can evaluate how a certain song did throughout the month. which week had the most streams etc.

 

 

Example of a Visualization for a Song

 

 

 

 

 

 

 

 

Then, for 2, I looked in the processing reference for an input function and didn’t find anything relevant to what I needed. I ended up finding a very helpful code on learningprocessing.com, which allowed me to save the user input in a variable. However, my main struggle and the reason my code isn’t complete is that I am unable to compare the string in this variable with the song titles. I tried doing it through a for loop in the keypressed function and a for loop in the draw function, but it did not work. However, when I access a specific song and a specific week, it displays the corresponding note.

Song Class

For this program, I created a song class that takes the song title and the 4-week streaming values as arguments. The functions of this class consist mainly of display functions for different weeks and different kinds of notes.

Alternatives

I considered alternative options, such as simply clicking on the song title to display its data or pressing a number on the keyboard that corresponds to the song number on the chart, but I felt like I’ve already used these methods in previous assignments and was very stubborn about wanting user input to work.

Demonstration

Here’s a clip of my code failing :-(( :

Here’s an example of my program displaying the streams for a song after I specifically called the display function in draw() (not user input):

 

 

 

 

 

Take a look at my main code:

// text input code from http://learningprocessing.com/examples/chp18/example-18-01-userinput
//Treble Clef png by Vasily Gedzun from the Noun Project

//loading image for treble clef
PImage treble;

PFont f;
// Variable to store text currently being typed
String typing = "";

// Variable to store saved text when enter is hit
String searchInput = ""; 
Table top20; //creating table
Song[] allSongs; //object list

void setup() {
  size(1024,768);
  f = createFont("Kayak Sans Bold (Italic).otf",20);
  textFont(f);
  top20 = loadTable("TOP 20.csv", "header"); //loading table excluding the first row, which are the headers
  treble = loadImage("Treble Clef.png");
  allSongs = new Song[20]; //creating the list
  for (int i=0; i<19; i++){
   allSongs[i] = new Song(top20.getString(i,0), top20.getFloat(i,1),top20.getFloat(i,2),top20.getFloat(i,3),top20.getFloat(i,4)); //creating the object list, the arguments get their vals from acessing CSV file data
  }
  
}
int indent = 25; // indentation for text

void draw() {
  background(255);
  
  
  
  fill(0);
  
  // Display initial text
  textSize(20);
  text("Type a Top 10 Song Title to View September Streams \n Hit enter ", indent, 40);
  text("Typing: " + typing,indent,190);
  text("Searching: " + searchInput,indent,230);
  displayMusicStaff(); // calling the function that draws the staff
  textSize(15);
  //displaying the search options
  text("WAP (feat. Megan Thee Stallion) \n Hawaii \n Mood (feat. Iann Dior) \n Dynamite \n Ice Cream (with Selena Gomez) \n Savage Love (Laxed - Siren Beat) \n Watermelon Sugar \n Blinding Lights \n ROCKSTAR (feat. Roddy Ricch) \n Laugh Now Cry Later (feat. Lil Durk)", width/2, 550);
  text("Roses - Imanbek Remix \n Mood Swings (feat. Lil Tjay) \n Breaking Me \n Ay, DiOs Mío! \n For The Night (feat. Lil Baby & DaBaby) \n UN DIA (One Day) (Feat. Tainy) \n Head & Heart (feat. MNEK) \n Heather \n La Curiosidad", width/2 + 250, 550); 
     // loop that compares user input to song list
   for (int i = 0; i<19; i++){
   if (searchInput == allSongs[i].songTitle){
     allSongs[i].week1Display(); 
     allSongs[i].week2Display();
     allSongs[i].week3Display();
     allSongs[i].week4Display();
   }
  }

  
  
     
   
   
 
 
}


void keyPressed() {
  //Code for user input
  // If the enter key is pressed, the user input is saved in a variable called searchInput
  if (key == '\n' ) {
    searchInput = typing;
    
    //the user is no longer typing, so we clear the typing variable
    typing = ""; 
  } else {
    // if enter isn't pressed keep adding characters to the typing variable
    typing = typing + key;
    
  }
  
}

void displayMusicStaff(){
  //drawing the staff
  strokeWeight(2);
  line(250,250,840,250);
  line(250,300,840,300);
  line(250,350,840,350);
  line(250,400,840,400);
  line(250,450,840,450);
  image(treble,250,250);
  
}

My Song Class:

class Song{
 //declaring variables
String songTitle;
float streams;
int locX, locY;
int ellipseW, ellipseH;
float wk1Streams, wk2Streams, wk3Streams, wk4Streams;



Song(String tempTitle, float tempwk1Streams, float tempwk2Streams, float tempwk3Streams, float tempwk4Streams){
 locX = 380;
 locY = 450;
 ellipseW = 35;
 ellipseH = 25;
 songTitle = tempTitle;
 wk1Streams = tempwk1Streams;
 wk2Streams = tempwk2Streams;
 wk3Streams = tempwk3Streams;
 wk4Streams = tempwk4Streams;
 
  
}

//function checks the value of week 1 streams and displays the note shape accordingly by calling that note shape's function
void week1Display(){
    if (wk1Streams > 10000000 && wk1Streams < 20000000){
     thrityTwoNote(locX,locY);
  }
  else if ((wk1Streams > 20000000 && wk1Streams < 25000000)){
    sixteenNote(locX,locY);
  }
  else if (wk1Streams> 25000000 && wk1Streams < 30000000){
    eightNote(locX,locY); 
  }
 else if (wk1Streams > 30000000 && wk1Streams < 35000000){
  quarterNote(locX,locY);
   
 }
 
 else if (wk1Streams > 35000000 && wk1Streams < 40000000){
   halfNote(locX,locY);
 }
 else if (wk1Streams > 40000000 && wk1Streams < 46000000){
   wholeNote(locX,locY);
   
 }
}
 //week2
 
 void week2Display(){
   //x and y values here are dependent on the week 1 x and y, to keep the code dynamic
 if (wk2Streams > 10000000 && wk2Streams < 20000000){
     thrityTwoNote(locX+100,locY-50);
  }
  else if ((wk2Streams > 20000000 && wk2Streams < 25000000)){
    sixteenNote(locX+100,locY-50);
  }
  else if (wk2Streams> 25000000 && wk2Streams < 30000000){
    eightNote(locX+100,locY-50); 
  }
 else if (wk2Streams > 30000000 && wk2Streams < 35000000){
  quarterNote(locX+100,locY-50);
   
 }
 
 else if (wk2Streams > 35000000 && wk2Streams < 40000000){
   halfNote(locX+100,locY-50);
 }
 else if (wk2Streams > 40000000 && wk2Streams < 46000000){
   wholeNote(locX+100,locY-50);
   
 }
 }
 
 //week3
 void week3Display(){
  if (wk3Streams > 10000000 && wk3Streams < 20000000){
     thrityTwoNote(locX+200,locY-100);
  }
  else if ((wk3Streams > 20000000 && wk3Streams < 25000000)){
    sixteenNote(locX+200,locY-100);
  }
  else if (wk3Streams> 25000000 && wk3Streams < 30000000){
    eightNote(locX+100,locY-100); 
  }
 else if (wk3Streams > 30000000 && wk3Streams < 35000000){
  quarterNote(locX+200,locY-100);
   
 }
 
 else if (wk3Streams > 35000000 && wk3Streams < 40000000){
   halfNote(locX+200,locY-100);
 }
 else if (wk3Streams > 40000000 && wk3Streams < 46000000){
   wholeNote(locX+200,locY-100);
   
 }
 }
 void week4Display(){
 //week4
 if (wk4Streams > 10000000 && wk4Streams < 20000000){
     thrityTwoNote(locX+300,locY-150);
  }
  else if ((wk4Streams > 20000000 && wk4Streams < 25000000)){
    sixteenNote(locX+300,locY-150);
  }
  else if (wk4Streams> 25000000 && wk4Streams < 30000000){
    eightNote(locX+300,locY-150); 
  }
 else if (wk4Streams > 30000000 && wk4Streams < 35000000){
  quarterNote(locX+300,locY-150);
   
 }
 
 else if (wk4Streams > 35000000 && wk4Streams < 40000000){
   halfNote(locX+300,locY-150);
 }
 else if (wk4Streams > 40000000 && wk4Streams < 46000000){
   wholeNote(locX+300,locY-150);
   
 }
 
}



//smallest stream range note shape
void thrityTwoNote(int x, int y){
  fill(0);
  ellipse(x,y,ellipseW,ellipseH);
  line(x+17.5, y, x+17.5, y -70);
  line(x+17.5, y-70, x+35, y-60);
  line(x+17.5, y-60, x+35, y-50);
  line(x+17.5, y-50, x+35, y-40);
}
  
void sixteenNote(int x, int y){
  fill(0);
  ellipse(x,y,ellipseW,ellipseH);
  line(x+17.5, y, x+17.5, y -70);
  line(x+17.5, y-70, x+35, y-60);
  line(x+17.5, y-60, x+35, y-50);
  
  
}

void eightNote(int x, int y){
 fill(0);
  ellipse(x,y,ellipseW,ellipseH);
  line(x+17.5, y, x+17.5, y -70);
  line(x+17.5, y-70, x+35, y-60);
}

void quarterNote(int x, int y){
 fill(0);
  ellipse(x,y,ellipseW,ellipseH);
  line(x+17.5, y, x+17.5, y -70);
}

void halfNote (int x, int y){
 noFill();
  ellipse(x,y,ellipseW,ellipseH);
  line(x+17.5, y, x+17.5, y -70);
  line(x+17.5, y-70, x+35, y-60);
  
  }
  
  void wholeNote(int x, int y){
   noFill();
  ellipse(380,450,35,25);
  
  }
  
  
  
  
}

 

Week 5 Class – Pixels

Images to download

Sketches used:

class SimpleMover {
  float x, y, homeX, homeY;
  float xSpeed, ySpeed;
  float diam;
  boolean seek;
  char letter;

  SimpleMover(float _x, float _y, float _diam ) {
    homeX = x = _x;
    homeY = y = _y;
    xSpeed = ySpeed = 0;
    diam = _diam;
    seek = true;
  }

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

  void display() {
    ellipse(x, y, diam, diam);
  }

  void seekHome() {
    if (seek) {
      float dirX = homeX-x;
      float dirY = homeY-y;
      dirX*=.005;
      dirY*=.005;
      xSpeed+=dirX;
      ySpeed+=dirY;
    }
  }

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

 

Text alteration

For this weeks assignment I decided to further upgrade my scrolling text program. During class time I managed to get it to display a single line of text continuously, with a restriction that the line had to be shorter than the width of the screen. I have upgraded my code, so that now it displays texts of various lengths without any issue. I have also added a new functionality. The input for the news bar is taken directly from a text file, so you can simply type all the great news and they will be displayed automatically.

During coding, the hardest part was to get the moment of switching right. When one string has already left the screen and the other one needs to overwrite the main movement variable OffsetX. This happens when the last letters of the first string leave the screen. I had to add some padding in form of a constant, so that it would appear even smoother.

PFont f;
PImage img;
String myString;
int offsetX;
int textHeight = 370;
int spaceConst = 40;

void setup(){
  size(400, 400);
  f = createFont("Monaco", 40);
  textFont(f);
  myString = "";
  textAlign(LEFT);
  offsetX = width;
  noStroke();
  
  img = loadImage("news.jpg");
  
  String[] lines = loadStrings("text.txt");
  for (int i=0 ; i < lines.length; i++) {
    myString += "| " + lines[i] + " ";
  }
  
  image(img, 0, 0, width, 320);
}

void draw(){
  fill(255,255,0);
  rect(0, 320, width, 80);
  fill(0);
  for (int i=0; i< myString.length(); i++){
    if (offsetX+textWidth(myString) < (width)){
      text(myString.charAt(i), offsetX+textWidth(myString)+spaceConst+textWidth(myString.charAt(i))*i, textHeight);
    }
    text(myString.charAt(i), offsetX+textWidth(myString.charAt(i))*(i+1), textHeight);
    
    if (offsetX+textWidth(myString) < -spaceConst) {
      offsetX = offsetX+int(textWidth(myString))+int(textWidth(myString.charAt(i))*(i+1));
    }
  }
  offsetX -= 2;
}

 

Assignment #4: Generative Text

For this week’s assignment, I attempted to make an interactive art utilizing text. My art piece for this week is pretty straightforward. A text is displayed initially and the user can maneuver their cursor onto the test. Then, once the cursor is within the range of the text, the text starts to move away like it is trying to avoid you. I also created a sort of shivering effect to really make it seem like the text is hating the cursor.

The text keeps moving as it tries to avoid the cursor, and if the text moves away from the width and the height of the screen, then the text is called back into the screen.

I am eager to improve this piece and I am working on creating numerous more identical texts within the screen so that it creates a more mass-movement kind of effect when a cursor is placed anywhere on the screen.

Below is the video of my creation in action:

String message = "Go Away~"; // to calculate the string's length
float x,y,hr,vr;

void setup(){
  size(320,320);
  textFont(createFont("Monaco",36));
  textAlign(CENTER, CENTER);
  hr = textWidth(message);
  vr = (textAscent() + textDescent())/2;
  noStroke();
  x = random(hr, width - hr);
  y = random(vr, height - vr);
}

void draw() {
  fill(255, 120);
  rect(0, 0, width, height);

  // Once the mouse is on the text
  if (abs(mouseX-x) < hr && abs(mouseY - y) < vr){
    x += random(-10,10);
    y += random(-10,10);
    if (x+hr/2 > width || x-hr/2 < 0 || y+vr > height || y-vr < 0){
      x = random(hr, width-hr);
      y = random(vr, height-vr);
    }
  }
  fill(0);
  text("Go Away~",x,y);
}