Final Project: Essay

Although in a pandemic, the condition in China is quite optimistic and many people quit wearing masks. However, Pudong has several cases of infection and our campus is at risk now. We are required to wear masks at school, but there are still a lot of students who don’t pay much attention to it. So I want to make the aim of my project as raising NYUSH community’s awareness of putting their masks on during pandemics. I did a little research and found out that someone recreated Flappy Bird, using Processing. So it’s completely possible to reach such a goal. But Flappy Bird is rather simple and doesn’t have many changes, so I’d like it to be more diverse.

I want to create a video game aiming to raise NYUSH community’s awareness of wearing masks on campus. It’s hard for me, a student with little experience to make an animated game with lots of changes.

 

I’d like it to be a game specially designed for NYUSH community. I’ll make the dominant hue purple and then insert elements from our school like our school badge or make our NYUSH Kylin (Chinese dragon) the main character. The Kylin is chased by a giant virus-monster so it has to run away from it. There are also many small viruses coming towards the Kylin from the other side of the screen. It has to avoid those viruses, when it touched a virus, Kylin gets a fever and the game is over. But masks also randomly appear on the computer screen which can give the player another chance. The input is the user’s distance between the user’s hand and a distance sensor for controlling the location of the Kylin. Maybe I’ll make a paper “hand sanitizer” to contain the sensor and users can move their hands up and down to control, or use a physical object to vary the movement. So when users clean their hands, they complete the first step to “survive from COVID-19”, after the game is started, they need to get a mask as the second thing to do. By Wednesday, I’ll finish the coding; by Thursday, I’ll finish detailing its appearance to make it more delicate.

During preparation, I’ll face difficulties like how to animate the components in my game. For example, my character’s legs can move and sweat when it is running. But I will need time to work this out and maybe need to draw the movement of the character on my own. Also, I need to consider all possibilities (when the game character dies) and how to make an infinite game mode, etc.

Recitation: Serial Communication

For serial communication, as beginners, we need to pay attention to a few things:

  1. What kind of communication is it? (Processing to Arduino/Arduino to Processing)
  2. We need to transfer one value/multiple values. (help us decide the format)
  3. Which serial port is the one we use?

Exercise 1: Ellipse

This step is not hard. I analyzed that this is a communication that Arduino sends two analog values to Processing.

Diagram:

 

Arduino:
void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);
  
  Serial.print(sensor1);
  Serial.print(",");  // put comma between sensor values
  Serial.print(sensor2);
  Serial.println(); // add linefeed after sending the last sensor value
  delay(10);
}
Processing:
import processing.serial.*;

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] sensorValues;      /** this array stores values from Arduino **/
float xPosition;
float yPosition;

void setup() {
  size(500, 500);
  setupSerial();
}


void draw() {
  updateSerial();
  printArray(sensorValues);
  background(0);
  xPosition = map(sensorValues[0], 0, 1023, 0, width);
  yPosition = map(sensorValues[1], 0, 1023, 0, height);
  ellipse(250, 250, xPosition, yPosition);
}


void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 1 ], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  sensorValues = new int[NUM_OF_VALUES];
}



void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}
Video:

 

Exercise 2:

This is a communication that Arduino sends two analog values to Processing. The hard part is “keep track of the previous x and y values”. So I created xPosition2 and yPosition2 to help. Another thing is that at first, my drawing started at (0,0) no matter what. It’s because the computer takes time to process and using boolean can change the starting position.

Arduino:

(Same code in Exercise 1)

Processing:
import processing.serial.*;

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] sensorValues;      /** this array stores values from Arduino **/

float xPosition;
float yPosition;
float xPosition2;
float yPosition2;

boolean firstRead = false;

void setup() {
  size(500, 500);
  background(0);
  setupSerial();
}


void draw() {
  updateSerial();
  printArray(sensorValues);

  xPosition = map(sensorValues[0], 0, 1024, 0, width);
  yPosition = map(sensorValues[1], 0, 1024, 0, height);

  if (!firstRead && xPosition > 0.0) {
    xPosition2 = xPosition;
    yPosition2 = yPosition;
    firstRead = true;
  }
  stroke(255);
  line(xPosition2, yPosition2, xPosition, yPosition); 
  
  xPosition2 = xPosition;
  yPosition2 = yPosition;
}


void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  sensorValues = new int[NUM_OF_VALUES];
}

void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Video:

Exercise 3: 

This is a communication that Processing sends two analog values to Arduino.

Diagram:

 

Processing:

import processing.serial.*;

int NUM_OF_VALUES = 2;  /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/


Serial myPort;
String myString;

// This is the array of values you might want to send to Arduino.
int values[] = new int[2];

void setup() {
  size(500, 500);
  background(0);

  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 1 ], 9600);

  myPort.clear();
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;
}


void draw() {
  background(0);

  values[0] = mouseX;
  
  values[1] = mouseY;
  
  sendSerialData();

  echoSerialData(200);
}

void sendSerialData() {
  String data = "";
  for (int i=0; i<values.length; i++) {
    data += values[i];
    //if i is less than the index number of the last element in the values array
    if (i < values.length-1) {
      data += ","; // add splitter character "," between each values element
    } 
    //if it is the last element in the values array
    else {
      data += "n"; // add the end of data character "n"
    }
  }
  //write to Arduino
  myPort.write(data);
}


void echoSerialData(int frequency) {
  //write character 'e' at the given frequency
  //to request Arduino to send back the values array
  if (frameCount % frequency == 0) myPort.write('e');

  String incomingBytes = "";
  while (myPort.available() > 0) {
    //add on all the characters received from the Arduino to the incomingBytes string
    incomingBytes += char(myPort.read());
  }
  //print what Arduino sent back to Processing
  print( incomingBytes );
}
Arduino:
#define NUM_OF_VALUES 2    /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/


/** DO NOT REMOVE THESE **/
int tempValue = 0;
int valueIndex = 0;


/* This is the array of values storing the data from Processing. */
int values[NUM_OF_VALUES];


void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  getSerialData();
  //int thisPitch = map(values[0], 400, 1000, 120, 1500);
  tone(9, values[0], values[1]);
  delay(1);
  
}

void getSerialData() {
  if (Serial.available()) {
    char c = Serial.read();
    switch (c) {
      case '0'...'9':
        tempValue = tempValue * 10 + c - '0';
        break;
      case ',':
        values[valueIndex] = tempValue;
        tempValue = 0;
        valueIndex++;
        break;
      case 'n':
        values[valueIndex] = tempValue;
        tempValue = 0;
        valueIndex = 0;
        break;
    
        for (int i = 0; i < NUM_OF_VALUES; i++) {
          Serial.print(values[i]);
          if (i < NUM_OF_VALUES - 1) {
            Serial.print(',');
          }
          else {
            Serial.println();
          }
        }
        break;
    }
  }
}
Video:

 

Homework:

This is a communication that Arduino sends two digital values to Processing. Initially, I can only let the star be on canvas when I press, but cannot keep it. I went to the workshop again and Winny used showed us how the boolean function works in this process. I think it’s a bit similar to the use of “boolean function” in exercise 2 (drawing with two potentiometers). Let the statement be false at the very beginning, and then use “if statement” to verify the condition and tell the computer what to do.

Diagram:

 

Arduino:
void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensor1 = digitalRead(7);
  int sensor2 = digitalRead(8);
  
  Serial.print(sensor1);
  Serial.print(",");  // put comma between sensor values
  
  Serial.print(sensor2);
  Serial.println(); // add linefeed after sending the last sensor value

  delay(100);
}
Processing:
import processing.serial.*;

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] Values;      /** this array stores values from Arduino **/
int previousValues0 = 0;
int previousValues1 = 0;

boolean star1 = false;
boolean star2 = false;

void setup() {
  size(600, 600);
  background(0);
  setupSerial();
}


void draw() {
  updateSerial();
  printArray(Values);
  background(0);
  
  if (Values[0] == 1 && Values[0] != previousValues0) {
    star1 = !star1;    
  }
  
  if (Values[1] == 1 && Values[1] != previousValues1) {
    star2 = !star2;   
  }
    
  if(star1 == true){
  pushMatrix();
  translate(width*0.3, height*0.3);
  rotate(frameCount / 400.0);
  star(0, 0, 30, 70, 5); 
  popMatrix();
  }
  
  if (star2 == true) {
  pushMatrix();
  translate(width*0.7, height*0.7);
  rotate(frameCount / -100.0);
  star(0, 0, 80, 100, 40); 
  popMatrix();
}
  
  previousValues0 = Values[0];
  previousValues1 = Values[1];

}


void star(float x, float y, float radius1, float radius2, int npoints) {
  float angle = TWO_PI / npoints;
  float halfAngle = angle/2.0;
  beginShape();
  for (float a = 0; a < TWO_PI; a += angle) {
    float sx = x + cos(a) * radius2;
    float sy = y + sin(a) * radius2;
    vertex(sx, sy);
    sx = x + cos(a+halfAngle) * radius1;
    sy = y + sin(a+halfAngle) * radius1;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 1 ], 9600);

  myPort.clear();
  
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  Values = new int[NUM_OF_VALUES];
}



void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          Values[i] = int(serialInArray[i]);
        }
      }
    }
  }
}
Video:

 

Final Project: Project Proposal

1. The Beauty of Emotion

 

mood rings

For many of us, we may have seen mood ring in our childhood and different colors represent different emotions. Sadness, anxiety, anger are usually considered bad moods, but they are part of us and make our life diverse. I’d like to use my project to make people think that their bad mood can also be “beautiful”. When we’re angry, we like to punch or hit something. I think I can use how frequently the button is hit by the user or our voice volume to represent people’s emotions. 

 

2. Music-mixer

For lots of teenagers, it is really cool to create or mix music like DJ. But the facilities they use are too complicated so I was thinking maybe using some simpler variation, such as the magnitude of current, distance and pressure, etc to make changes to pitches and volumes. So inserting different kinds of sensors into my project is a good measurement, like ultrasonic sensors and magnetometers.

3. Survive from COVID-19

The ability to create animation with Processing makes me think of creating a little game for raising people’s awareness of putting their masks on during pandemics. The input is our voice volume or the distance between the user and the computer for controlling the location of the main game character. And I’d like the barriers to be moving coronavirus or some still walls or columns covered with coronavirus, and there will be masks randomly appear on the screen so that players can catch the mask to get another chance from dying.

Recitation 7: Functions and Arrays

In-class practice

Step 1:

void setup() {
  size(700, 700);
  background(200);
}
void draw() {
  envelope(200, 100, width*0.5, height*0.5, color(145,207,250), color(215, 169, 229));
}

void envelope(int a, int b, float x, float y, color c, color d) {
  stroke(0);
  strokeWeight(3);
  fill(c);  
  rect(x - a/2, y - b/2, a, b);
  fill(255);
  triangle(x - a/2, y - b/2, x + a/2, y - b/2, x, y);
  fill(d);
  circle(x, y, a*0.15);
  
}

I sketched an envelope and separated it into three shapes: a rectangle, a triangle and a circle.

 

Step 2:

  1. Putting for loop in void setup() is like setting the location of those 100 envelopes once. So it turns out to be a still graph.
void setup() {
  size(700, 700);
  background(200);
  for (int i = 0; i < 100; i = i + 1){
   envelope(200, 100, random(width), random(height), color(random(255), random(255), random(255)), color(random(255), random(255), random(255))); 
  }
  
}
void draw() {
  
}

void envelope(int a, int b, float x, float y, color c, color d) {
  stroke(0);
  strokeWeight(3);
  fill(c);  
  rect(x - a/2, y - b/2, a, b);
  fill(255);
  triangle(x - a/2, y - b/2, x + a/2, y - b/2, x, y);
  fill(d);
  circle(x, y, a*0.15);
  
}

 

2. Putting for loop in void draw() is like continuously set the location of those 100 envelopes. void draw() is a loop, which means it repeats the action infinitely, so the graph is animated.

void setup() {
  size(700, 700);
  background(200);
  
}
void draw() {
  for (int i = 0; i < 100; i = i + 1){
   envelope(200, 100, random(width), random(height), color(random(255), random(255), random(255)), color(random(255), random(255), random(255))); 
  }
  
}

void envelope(int a, int b, float x, float y, color c, color d) {
  stroke(0);
  strokeWeight(3);
  fill(c);  
  rect(x - a/2, y - b/2, a, b);
  fill(255);
  triangle(x - a/2, y - b/2, x + a/2, y - b/2, x, y);
  fill(d);
  circle(x, y, a*0.15);
  
}

Step 3: 

In step 3, I used arrays to store colors,  x-coordinates and y-coordinates. I encountered some problems at first, and I think I should remind myself that we can only store one type of information in each array. 

color[] c = new color[100];
color[] o = new color[100];
float[] x = new float[100];
float[] y = new float[100];

void setup() {
  size(700, 700);
  for (int i = 0; i < 100; i++){
   c[i] = color(random(255), random(255), random(255));
   o[i] = color(random(255), random(255), random(255));
   x[i] = random(width);
   y[i] = random(height);
  }
  
}
void draw() {
  background(200);
  for (int i = 0; i < 100; i = i + 1){
   envelope(200, 100, x[i], y[i], c[i], o[i]); 
  }
}

void envelope(int a, int b, float x, float y, color c, color d) {
  stroke(0);
  strokeWeight(3);
  fill(c);  
  rect(x - a/2, y - b/2, a, b);
  fill(255);
  triangle(x - a/2, y - b/2, x + a/2, y - b/2, x, y);
  fill(d);
  circle(x, y, a*0.15);
  
}

 

Comparing step 2.2 [putting the for loop in void draw()] and step 3, I gained some further understanding about arrays. 

 

First, with the help of arrays, I don’t need to copy the functions for over and over agian.

Second, array has memory, array is like a cabinet with many storage space in it. The picture Professor Rudi showed in his slide is a great metaphor. And for instance, in  void setup(), step 3, each storage space was packed with one specific data. And then void draw()  repetitively showed us the stored data. Becuase the data in the arrays are memorized, and it can’t be stored without arrays, the graph of step 3 is still but the graph of step 2.2 is animated.

Step 4:

At last, I added some movement for the envelopes. If statement helped me set boundaries to the envelopes so that they won’t move out of the canvas.

color[] c = new color[100];
color[] o = new color[100];
float[] x = new float[100];
float[] y = new float[100];
float[] X = new float[100];
float[] Y = new float[100];

void setup() {
  size(700, 700);
  for (int i = 0; i < 100; i++){
   c[i] = color(random(255), random(255), random(255));
   o[i] = color(random(255), random(255), random(255));
   x[i] = random(width);
   y[i] = random(height);
   X[i] = random(-4,4);
   Y[i] = random(-4,4);
  }
  
  
}
void draw() {
  background(200);
  for (int i = 0; i < 100; i = i + 1){
   envelope(200, 100, x[i], y[i], c[i], o[i]); 
   if (x[i] + X[i] > width || x[i] + X[i]< 0){
    X[i] = -X[i];
   }
   if (y[i] + Y[i] > height || y[i] + Y[i]< 0){
    Y[i] = -Y[i];
   }
   x[i] = x[i] + X[i];
   y[i] = y[i] + Y[i]; 
  
  }
}

void envelope(int a, int b, float x, float y, color c, color d) {
  stroke(0);
  strokeWeight(3);
  fill(c);  
  rect(x - a/2, y - b/2, a, b);
  fill(255);
  triangle(x - a/2, y - b/2, x + a/2, y - b/2, x, y);
  fill(d);
  circle(x, y, a*0.15);
  
}

 

Homework:

To be honest, this week’s homework is quite hard for me, so I attended our study session on Tuesday.

For the first 3 steps, I sought help from Milly. And I individually added up something to make step 4 work.

Step 1:

int row = 25;
int column = 25;
int total = row*column;
int padding = 150;

float[] xPosition = new float[total];
float[] yPosition = new float[total];
float[] size = new float[total];

void setup() {
  size(800, 800);
  for (int j = 0; j < row; j++){
    for (int i = 0; i < column; i++){
      int index = i + j*column;
      xPosition [index] = map(i, 0, column-1, padding, width-padding);
      yPosition [index] = map(j, 0, row-1, padding, height-padding);
      size[index] = 1.0;
  }
 }
  
}
void draw(){
  background(255);
  for (int n = 0; n < total; n++){
   drawCircle(xPosition[n], yPosition[n], size[n]);
  }
  
}

void drawCircle(float x, float y, float scale){
  pushMatrix();
  pushStyle();
  translate(x, y);
  scale(scale);
  fill(0);
  noStroke();
  circle(0, 0, 10);
  popMatrix();
  popStyle(); 
}

 

Here I learnt that pushMatrix() & popMatrix(), pushStyle() & popStyle() are a bit like individual command, so that the command between push and pop won’t affect other commands.

Step 2:

int row = 25;
int column = 25;
int total = row*column;
int padding = 150;

float[] xPosition = new float[total];
float[] yPosition = new float[total];
float[] size = new float[total];

void setup() {
  size(800, 800);
  for (int j = 0; j < row; j++){
    for (int i = 0; i < column; i++){
      int index = i + j*column;
      xPosition [index] = map(i, 0, column-1, padding, width-padding);
      yPosition [index] = map(j, 0, row-1, padding, height-padding);
      size[index] = 1.0;
  }
 }
  
}
void draw(){
  background(255);
  for (int n = 0; n < total; n++){
    float circleRadius = dist (mouseX, mouseY, xPosition[n], yPosition[n]);
    circleRadius = max(circleRadius, 0.01);
    
    size[n] = 100/circleRadius;
    size[n] = max(size[n], 0.4);
    size[n] = min(size[n],2);
   drawCircle(xPosition[n], yPosition[n], size[n]);
  }
  
}

void drawCircle(float x, float y, float scale){
  pushMatrix();
  pushStyle();
  translate(x, y);
  scale(scale);
  fill(0);
  noStroke();
  circle(0, 0, 10);
  popMatrix();
  popStyle(); 
}

 

dist() can calculate the distance between two points. Circles that are closer to my arrow are bigger. While it’s important to let max() help us set the minimum of the circle’s size and let min() help us set the maximum of the circle’s size.

(e.g. Because max() is to choose the bigger number, so it’s for setting the lower limit. Pay attention to the logic here!)

Step 3:

int row = 25;
int column = 25;
int total = row*column;
int padding = 150;

float[] xPosition = new float[total];
float[] yPosition = new float[total];
float[] size = new float[total];
float[] xPosition1 = new float[total];
float[] yPosition1 = new float[total];

void setup() {
  size(800, 800);
  for (int j = 0; j < row; j++){
    for (int i = 0; i < column; i++){
      int index = i + j*column;
      xPosition [index] = map(i, 0, column-1, padding, width-padding);
      yPosition [index] = map(j, 0, row-1, padding, height-padding);
      size[index] = 1.0;
  }
 }
  
}
void draw(){
  background(255);
  for (int n = 0; n < total; n++){
    float circleRadius = dist (mouseX, mouseY, xPosition[n], yPosition[n]);
    //circleRadius = max(circleRadius, 0.01);
    
    xPosition1[n]=xPosition[n] - (25/circleRadius)*(mouseX - xPosition[n]);
    yPosition1[n]=yPosition[n] - (25/circleRadius)*(mouseY - yPosition[n]);
    
    size[n] = 100/circleRadius;
    size[n] = max(size[n], 0.5);
    size[n] = min(size[n],2);
    drawCircle(xPosition1[n], yPosition1[n], size[n]);
  }
  
}

void drawCircle(float x, float y, float scale){
  pushMatrix();
  //pushStyle();
  translate(x, y);
  scale(scale);
  fill(0);
  noStroke();
  circle(0, 0, 10);
  popMatrix();
  //popStyle(); 
}

 

The main point here is to open two more arrays for new x- and y-coordinates.

Step 4:

int row = 25;
int column = 25;
int total = row*column;
int padding = 150;

float[] xPosition = new float[total];
float[] yPosition = new float[total];
float[] size = new float[total];
float[] xPosition1 = new float[total];
float[] yPosition1 = new float[total];
float[] xPosition2 = new float[total];
float[] yPosition2 = new float[total];

void setup() {
  size(800, 800);
  for (int j = 0; j < row; j++){
    for (int i = 0; i < column; i++){
      int index = i + j*column;
      xPosition [index] = map(i, 0, column-1, padding, width-padding);
      yPosition [index] = map(j, 0, row-1, padding, height-padding);
      
      xPosition2[index] = xPosition[index];
      yPosition2[index] = yPosition[index];
      
      size[index] = 1.0;
  }
 }
  
}
void draw(){
  background(255);
  for (int n = 0; n < total; n++){
    float circleRadius = dist (mouseX, mouseY, xPosition[n], yPosition[n]);
    circleRadius = max(circleRadius, 0.01);
    
    xPosition1[n]=xPosition[n] - (25/circleRadius)*(mouseX - xPosition[n]);
    yPosition1[n]=yPosition[n] - (25/circleRadius)*(mouseY - yPosition[n]);
    
    size[n] = 100/circleRadius;
    size[n] = max(size[n], 0.4);
    size[n] = min(size[n],2);
 
    xPosition2[n] = lerp(xPosition2[n], xPosition1[n], 0.02);
    yPosition2[n] = lerp(yPosition2[n], yPosition1[n], 0.02);
    
    drawCircle(xPosition2[n], yPosition2[n], size[n]);
  }
  
}

void drawCircle(float x, float y, float scale){
  pushMatrix();
  //pushStyle();
  translate(x, y);
  scale(scale);
  fill(0);
  noStroke();
  circle(0, 0, 10);
  //popStyle(); 
  popMatrix();
}

There were some accidents happened. I did some change, that is, matching x/yPosition2 and x/yPosition together in void setup() so that processing can immediately know the connection between position2 and position in setup, which is before void draw(), so it won’t get confused.

lerp() can be used for delaying the action. I want to remind myself that it should the format of the function is lerp(float start, float end, percentage) and keep in mind which is the action I want to slow down.  And here I would like movement between the previous position (xPosition1 & yPosition1) and the current position (xPosition2 & yPosition2) to slow down. 

 

Final Project: Research and Analysis

From Group Project and my readings, I initially defined interaction as a process of input, analysis and output, or listening, thinking and speaking.

To be honest, though it’s right, it’s shallow and general, so I refresh it as a direct, ongoing process of input, analysis and output, focusing on building up connections between users and other things (objects/people/…).

I drew conclusion from two projects:

The first project is called MeMix, an interactive mixing instrument. It’s quite similar to our midterm project. But comparing it with our Music Pumpkin, there are more variations in MeMix, like different rhythms. While we only have spinning pumpkin and flashing LEDs.

I think what makes the project successful is what our project lacks. MeMix’s interaction is easy to get and its users’ engagement is powerful. MeMix makes its users like DJs, which means users can self-design the music by simply changing their gestures and moving cubes on the box. MeMix also combines Processing and Arduino together, Processing sketch provides a virtual keyboard showing the variation of the beats. I think it inspires me that my final project can choose either Arduino or Processing sketching as the main body, and let the other one tool (Arduino/Processing) serves for the main part.

The second one is a wooden mirror in NYU New York. The wooden mirror has a tiny camera, capturing people’s movement and inputting it to the computer. The computer then “tells” the servo motors under those wooden pixels how many degrees they need to rotate. The technical idea of the wooden mirror inspires me that the project uses the environment (the light on the mirror’s top) so well and it’s very creative for the designer to use the degree of the servo motors to represent what’s in front of the mirror. So maybe I can really spend some time thinking about what components I should use to better function the whole thing.

Here are some further explanations about interaction:

  1. Direct:

During our classes, Professors let us keep in mind that a successful interaction shouldn’t include a further explanation from the designers. The initial version of our midterm project showed this problem. Users didn’t get what we were trying to show with the Joystick and they didn’t know how to use the Joystick. Good interaction needs to be clear and easy to understand in the first place.

2. Engagement

The users’ responses to our midterm project also show the importance of attracting, sustaining and relating to the users’ experiences, which is claimed by Edmonds in his article (12). Edmonds, in his work Communication Game, transferred “the viewer into an active participant in creating the artwork” (Edmonds 5). We somehow need to let the interactive system we built capture users’ behaviors essentially and make them play an active role in the interactive process. 

3. On-going

Another reading about interaction design I read makes some good points about this. Designers need to pay attention to “the amount of time a user spends interacting with the product: can users track their progress, or resume their interaction some time later? ”

So I think a good interaction certainly needs to include more than a one-time communication, it needs to be a loop, a systematic and long-term engagement, in other words, how to develop a continuous interest from the audience. This makes me realize the great importance of user testing. Through their feedback, we can improve our project to keep it from boredom and to make it more relevant to them.

According to Edmonds’ art system “the matrix”, our group project about the growing robot is more like Dynamic-Interactive (Varying), it’s more ideal because it can respond to almost any type of inputs. While most of the time, as elementary designers, we can only reach Dynamic-Passive level of interaction, which mostly analyze predictable inputs. So if we think more about what will users encounter when using it, it’ll help with the designing process.

Works Cited:

Art, Interaction and Engagement, by Ernest Edmonds

What is interaction design?

MeMix

Wooden Mirror