Interaction Lab Final Project: Bobby (Ding Wang)

  • Name: Ding Wang
  • Professor: Eric&Young
  • Partner: Frank


CONCEPTION AND DESIGN

Conception

After Frank and I decided to choose “sustainability” as a significant issue for our project. We started from this point and thought about how can we raise the awareness of the environment protection. The first design came to our mind is a game. Because a game is an interesting way to attract people to get access to this problem. Firstly, Frank reminds me of the Pacman. We wanted to make some creative changes for this old game. Later, we thought maybe Pacman is not the most suitable game for us. So we began to design our original game. We integrated the concepts as garbage sorting and recycling and encouraging people to take more stairs into our game. We transformed different concepts into different functions in the game and finally had our final game.


FABRICATION AND PRODUCTION

I think there are three significant and hard steps in the fabrication and production process. The first step is at first when we are building the basic function for our game. Frank and I work on different functions at first. And both of us met many problems in the coding process.

The second step is making the controller. Sometimes the design is not practical as we thought, so we need to adjust our design according to the actual effect.

The third step is that after the user testing, we made some adjustments based on the suggestions from the users. An impressive thing for me is that, when we finished our project, I tried it first, and I told Frank maybe it’s a little easy. But most users reported that game control is too difficult and the instruction is not clear enough. And I think this is a difference between the game designers and users.  Because we are the designers, we are familiar with the game and we also even know many details about it. This difference immediately made me realize the importance of the user test session. So after the user testing, we add a more detailed instruction before the game to guide the user to finish the instruction step by step.


CONCLUSIONS

The goal of our project is by making a game to raise the awareness of environmental protection. From some response in IMA show, I think getting good game experience and participation in the game satisfies my definition of interaction. But I think our control system is not very good at achieving the purpose of interaction. This is also an improvement I want to make adding more interactive elements in the controller.

This is an interesting process for me to learn some further knowledge. And how to connect my knowledge with the practical design. The final project is a lesson for me to be familiar with all the processes from designing to adjusting finally.

import processing.serial.*;
import processing.sound.*;

SoundFile file;


Cleaner frank;
Bad ding, coco, ying, tina; 

PImage[] imgRubbish = new PImage[4];
PImage imgb, imgr, imgg, imgy, imgl1, imgl2, imgl3, imgflr1, imgflr2, imgflr3, imgrbt, imgrbtB, imgppr, imgele, imgmstOrg, imgmstGrn, imgmstBlu, imgmstYlw, imgflrA, back, imgRK1, imgRK2, imgRK3, imgRK4, imgItf; 

color cla = color(255, 0, 0), clb = color(255, 200, 0), clc = color(0, 200, 0), cld = color(20, 100, 255);
float badX, badY;
int m;
int xPos, yPos;
int ladderWidth = 75; 
int food = 0;
int elevatorTimes = 100 ;
int interval = 100;
int start;
int direcS = 1;
int x1 = 400;
int clickCounter = 0;
int currentButtonValue = 0;
int previousButtonValue = 0;


String BGM = "BGM.mp3";
String path;
String[] strings = {"You've been caught", "Time Up"}; 
color[] colors = {cla, clb, clc, cld};

boolean textState = true;
boolean textState1 = true;
boolean carry = false;
boolean freeze = false;
boolean tutorial = true;


//arduino

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 7;  
int[] sensorValues;     


void setup() {

  //set up the music
  path = sketchPath(BGM);
  file = new SoundFile(this, path);
  file.loop();

  fullScreen();
  setupSerial();

  start = millis();


  //setup the good
  frank = new Cleaner(1300, 850);

  //set up the bad
  ding = new Bad( width/2-80, 598, 30);
  coco = new Bad( width/2+100, 346, 30);
  ying = new Bad( width/2-40, 94, 30);
  tina = new Bad( width/2 + 30, 850, 30);

  //set up the image
  imgItf = loadImage("InterFace.png");
  imgRK1 = loadImage("RK1.png");
  imgRK2 = loadImage("RK2.png");
  imgRK3 = loadImage("RK3.png");
  imgb = loadImage("blueTrashcan.png");
  imgr = loadImage("redTrashcan.png");
  imgg = loadImage("greenTrashcan.png");
  imgy = loadImage("yellowTrashcan.png");
  imgl1 = loadImage("lader1.png");
  imgl2 = loadImage("lader2.png");
  imgl3 = loadImage("lader3.png");
  imgflr1 = loadImage("floor.png");
  imgflr2 = loadImage("floor.png");
  imgflr3 = loadImage("floor.png");
  imgrbt = loadImage("rbt copy1.png");
  imgrbtB = loadImage("rbt copy.png");
  imgele = loadImage("elevator.png");
  imgmstOrg = loadImage("monsterOr.png");
  imgmstGrn = loadImage("mosterGr.png");
  imgmstBlu = loadImage("mosterBl.png");
  imgmstYlw = loadImage("mosterYe.png");
  imgflrA = loadImage("brick.png");
  back = loadImage("back.png");
  imgRubbish[0] = loadImage("coca.png");
  imgRubbish[1] = loadImage("bag.png");
  imgRubbish[2] = loadImage("beer.png");
  imgRubbish[3] = loadImage("paper.png");
}
void mouseClicked() {
  clickCounter ++;
}
void draw() {

  frank.keyPressed();
  if (tutorial == true) {
    updateSerial();
    printArray(sensorValues[2]);
    frank.leftRight();
    frank.upDown();
    frank.changefloor();
    switch(clickCounter) {
      //intro1
    case 0:
      background(0);
      textSize(60);
      fill(10, 255, 40);
      text("Bobby –––– The Trash Collector", width/2-400, height/2);
      fill(230, 65, 240);
      text("Bobby –––– The Trash Collector", width/2-405, height/2-5);
      textSize(20);
      fill(255);
      text("Click the Mouse to Continue", width/2 - 400, height-100);
      break;
    case 1:
      background(0);
      textSize(60);
      text("Three steps to learn the game", width/2-400, height/2);
      textSize(20);
      text("Click the Mouse to Continue", width/2 - 400, height-100);
      break;
    case 2:
      background(0);
      textSize(60);
      image(imgItf, 100, 100);
      imgItf.resize(5*1728/7, 3*1296/5);
      textSize(20);
      fill(255);
      text("Click the Mouse to Continue", width/2 - 400, height-100);
      break;
    case 3:
      xPos = 1300;
      yPos = 850;
      back();
      setImage();
      frank.robot();
      frank.floorPic();
      frank.elevatorTrack();
      frank.elevatorPic();
      frank.border();
      textSize(45);
      fill(231, 22, 3);
      text("Elevator Times: " + elevatorTimes, width/2- 700, height/2-230);
      textSize(20);
      text("in the real game, elevator times is limited", width/2- 700, height/2);
      text("You need to collect trash to get more elevator times", width/2- 700, height/2+30);
      textSize(20);
      fill(0);
      text("Click the Mouse to Continue", width/2 - 700, height-100);
      break;
    case 4:
      background(0);
      textSize(60);
      text("Step 2", width/2-100, 60);
      textSize(35);
      fill(255);
      text("Next step, pick up the trashes", width/2-500, height/2-55);
      fill(0, 255, 0);
      text("&&", width/2-450, height/2);
      fill(255);
      text("Throw them into the right trashcans", width/2-500, height/2+ 55);
      textSize(20);
      fill(255);
      text("Click the Mouse to Continue", width/2 - 400, height-100);
      break;

    case 5:
      xPos = 1300;
      yPos = 850;
      back();
      setImage();
      frank.robot();
      frank.elevatorTrack();
      frank.floorPic();
      frank.elevatorPic();
      frank.displayC();
      frank.throwRubbish();
      frank.rubbish();
      frank.border();
      textSize(45);
      fill(231, 22, 3);
      text("Elevator Times: " + elevatorTimes, width/2- 700, height/2-230);
      textSize(20);
      fill(0);
      text("Click the Mouse to Continue", width/2 - 700, height-100);
      break;
    case 6:
      background(0);
      textSize(60);
      text("Step 3", width/2-100, 60);
      fill(255);
      textSize(35);
      text("Now, monsters are on your way", width/2-600, height/2-55);
      fill(255, 0, 0);
      text("Don't be caught", width/2-600, height/2);
      fill(255);
      text("You can hide behind the elevator track or the rocks on each floors", width/2-600, height/2+ 55);
      textSize(20);
      //fill(255);
      //text("Click the Mouse to Continue", width/2 - 400, height-100);
      fill(249, 250, 20);
      textSize(50);
      text(" Press the ENTER. You have 100s", width/2-400, height/2+400);  
      break;
    }
  } else {


    //arduino
    updateSerial();
    printArray(sensorValues);

    m = millis() - start;

    frank.displayC();

    //set up the sence
    back();
    setImage();
    textShow();


    frank.robot();
    frank.elevatorTrack();
    frank.floorPic();
    frank.elevatorPic();
    frank.monsters();
    frank.rocks();
    frank.rubbish();
    frank.displayC();
    frank.keyPressed();
    frank.throwRubbish();
    frank.gameOver1();
    frank.leftRight();
    frank.upDown();
    frank.border();
    frank.changefloor();

    // the bad + end the game
    if (freeze == false) {

      //theBad
      ding.runningAround1();
      coco.runningAround2();
      ying.runningAround3();
      tina.runningAround4();

      timer();
      rank();
    } else {
      timer();
      frank.xPos = frank.xPos;
      carry = false;
      textAlign(CENTER);
      textSize(60);
      fill(233, 43, 123);
      textState1 = false;
      if (textState == true) {
        text(strings[0], width/2, height/2);
        
      }
      if (previousTime >= interval) {
        textState = false;
        //pushMatrix();
        //translate(0, 20);
        text(strings[1], width/2, height/2);
        //popMatrix();
      }
    }
  }
}

//************************************************Text**********************************************


void textShow() {
  textAlign(CENTER);
  textSize(50);
  fill(22, 22, 211);
  text("Trash: " + food, width/2- 500, height/2-280);
  fill(255, 116, 190);
  text("Trash: " + food, width/2- 500-2, height/2-280-2);
  textSize(45);
  fill(22, 22, 211);
  text("Elevator Times: " + elevatorTimes, width/2- 480, height/2-230);
  fill(255, 116, 190);
  text("Elevator Times: " + elevatorTimes, width/2- 480-2, height/2-230-2);
  if ( elevatorTimes == 0) {
    textSize(30);
    fill(231, 22, 3);
    text("Run out of Elevator Times", width/2-500, height/2);
    text("GET MORE TRASH !", width/2-500, height/2+50);
  }
  //showTime = interval - (millis() / 1000)%interval;
  if (textState1 == true) {
    fill(22, 22, 211);
    textSize(50);
    text("Time: " + (interval - (m / 1000)%interval), width/2-500, 115);
    fill(255, 116, 190);
    text("Time: " + (interval - (m / 1000)%interval), width/2-500-2, 115-2);
  }
  if (textState1 == false) {

    fill(39, 240, 60, 200);
    rect(width/2-300, height/2-50, 600, 200);
    //pushMatrix();
    //translate(0, 20);
    textSize(50);
    fill(22, 22, 211);
    text("Best Protector: " +hScore, width/2, height/2 + 100);
    text("Your Score: " + (food + elevatorTimes), width/2, height/2 + 50);
    fill(255, 116, 190);
    text("Best Protector: " +hScore, width/2-2, height/2 + 100-2);
    text("Your Score: " + (food + elevatorTimes), width/2-2, height/2 + 50-2);
    //popMatrix();
  }
}

//************************************************Timer*********************************************

int currentTime;
int previousTime = 0;
int pastTime = 0;
int showTime = interval;
int addTime =0;
int newTime =0;
int time = 0;

void timer() {
  //text("cu" + currentTime, width/2-300, height/2);
  //text("pr" + previousTime, width/2-300, height/2+50);
  //text("sh" + showTime, width/2-300, height/2+100);
  //text("pa" + pastTime, width/2-300, height/2+150);
  //text("ne" + newTime, width/2-300, height/2+200);
  currentTime = (m / 1000)%interval+1;
  if (currentTime - previousTime >= interval) {
    previousTime = currentTime;
  }

  textAlign(CENTER);
  textSize(50);
  fill(colors[0]);

  if (previousTime>= interval) {
    textAlign(CENTER);
    textSize(60);
    fill(233, 43, 123);
    text("Time Up", width/2, height/2);
    freeze = true;
  }

  // add the past time
}

//**********************************************Arduino*********************************************
void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 5 ], 9600);
  // WARNING!
  // You will definitely get an error here.
  // Change the PORT_INDEX to 0 and try running it again.
  // And then, check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index number of the port.

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  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]);
        }
      }
    }
  }
}

//**********************************************back*********************************************
void back() {
  image(back, 0, 0);
}

//*********************************************cleaner*********************************************

class Cleaner {
  //member variables
  float  yPos = 0;
  float xPos = 1000;
  int[] Hcleaner = {6, 258, 510, 762};
  int i = 3;
  int rubbishFloor = int(random(3));
  int currentRubbish =0;
  int formerRubbish = 0;
  int noRubbish = 4;
  int floor1 = 850;
  int floor2 = 596;
  int floor3 = 344;
  int floor4 = 95;
  int climbSpeed = 5;
  int[] Hrubbish = {floor1, floor2, floor3, floor4};
  int r = 0;
  int distThrow = 110;
  int speedC = 8;
  int ladderWidth =100;
  int previousValue3 = 0;
  int previousValue4 = 0;
  int previousValue5 = 0;
  int previousValue6 = 0;


  float Xrubbish = 1200;

  boolean carry = false;
  boolean state = false;
  boolean showImg = false;







  //constructor
  Cleaner(int x, int y) {
    xPos = x;
    yPos = y;
  }

  //functionality

  //show the cleaner
  void displayC() {

    //pick the rubbish
    if (dist(xPos, yPos, Xrubbish, Hrubbish[r])<26 && carry == false) {
      background(255);
      r = (int) random(3);
      Xrubbish = random(455, 1340);
      formerRubbish = currentRubbish;
      currentRubbish = (int) random(3);
      food++;
      elevatorTimes ++;
      carry = true;
      showImg = true;
    }
  }

  //throw into the trashcan
  void throwRubbish() {
    if (colors[formerRubbish] == cla && dist(xPos, yPos, width/2+30, 22*height/25) < distThrow) {
      carry = false;
      showImg = false;
      pushMatrix();
      translate(125, height/2-200);
      noStroke();
      fill(255);
      ellipse(width/2, height/2, 30, 30);
      ellipse(width/2-30, height/2+25, 20, 20);
      ellipse(width/2+60, height/2-40, 100, 50);
      fill(255, 0, 0);
      text("Yummy", width/2+60, height/2-32);
      popMatrix();
    } else if (colors[formerRubbish] == clb && dist(xPos, yPos, 6*width/11+30, 15*height/25) < distThrow) {
      carry = false;
      showImg = false;
      pushMatrix();
      translate(220, 0);
      noStroke();
      fill(255);
      ellipse(width/2, height/2, 30, 30);
      ellipse(width/2-30, height/2+25, 20, 20);
      ellipse(width/2+60, height/2-40, 100, 50);
      fill(252, 219, 28);
      translate(-5, 0);
      text("Yummy", width/2+60, height/2-32);
      popMatrix();
    } else if (colors[formerRubbish] == clc && dist(xPos, yPos, 7*width/12+30, 8*height/25) < distThrow) {
      carry = false;
      showImg = false;
      pushMatrix();
      translate(250, -250);
      noStroke();
      fill(255);
      ellipse(width/2, height/2, 30, 30);
      ellipse(width/2-30, height/2+25, 20, 20);
      ellipse(width/2+60, height/2-40, 100, 50);
      fill(83, 252, 28);
      text("Yummy", width/2+60, height/2-32);
      popMatrix();
    } else if (colors[formerRubbish] == cld && dist(xPos, yPos, 8*width/13, height/25) < distThrow) {
      carry = false;
      showImg = false;
      noStroke();
      fill(255);
      ellipse(width/2, height/2, 30, 30);
    }
  }


  //game over
  void gameOver1() {
    if (xPos > width/2+100+270 || xPos < width/2+270) {
      if (dist(xPos, yPos, ding.badX, ding.badY) < 10 || dist(xPos, yPos, tina.badX, tina.badY) < 30 || dist(xPos, yPos, ying.badX, ying.badY) < 30 || dist(xPos, yPos, coco.badX, coco.badY) < 30 && freeze == false) {
        freeze = true;
        textState = true;
      }
    }
  }
  //moving image


  void robot() {


    if (yPos == 850 || yPos == 596 || yPos == 344 || yPos == 95 ) {
      image (imgrbt, xPos-50, yPos-80);
      imgrbt.resize(3*271/9, 3*356/9);
    } else {    
      image (imgrbtB, xPos-50, yPos-80);
      imgrbtB .resize(3*271/9, 3*356/9);
    }
  }


  void elevatorTrack() {
    noStroke();
    fill(0, 10, 255);
    if (xPos < width/2+100+270 && xPos > width/2+270) {
      fill(255, 0, 0);
    }
    rect(width/2+290, 0, 60, height-30);
    fill(255);
    rect(width/2+305, 0, 30, height-30);
    fill(23);
    fill(188, 42, 255);
    rect(width/2+310, 0, 20, height-30);

    fill(250, 58, 58);
    ellipse(width/2+321-13+12, height/2+250-10, 45, 45);
    fill(255);
    ellipse(width/2+321-13+12, height/2+250-10, 40, 40);
    textSize(25);
    fill(250, 58, 58);
    text("F1", width/2+321-13+12, height/2+250);

    fill(250, 241, 58);
    ellipse(width/2+321-13+12, height/2-10, 45, 45);
    fill(255);
    ellipse(width/2+321-13+12, height/2-10, 40, 40);
    textSize(25);
    fill(250, 241, 58);
    text("F2", width/2+321-13+12, height/2);

    fill(58, 241, 58);
    ellipse(width/2+321-13+12, height/2-250-10, 45, 45);
    fill(255);
    ellipse(width/2+321-13+12, height/2-250-10, 40, 40);
    textSize(25);
    fill(58, 241, 58);
    text("F3", width/2+321-13+12, height/2-250);

    fill(0, 10, 255);
    ellipse(width/2+321-13+12, height/2-400-10, 45, 45);
    fill(255);
    ellipse(width/2+321-13+12, height/2-400-10, 40, 40);
    textSize(25);
    fill(0, 10, 255);
    text("F4", width/2+321-13+12, height/2-400);
  }



  void floorPic() {
    image(imgflr1, 250, height/2-100);
    image(imgflr1, 170, height/2+150);
    image(imgflr1, 350, height/2-350);
    image(imgflr1, 440, height/2-600);
    imgflr1.resize(3*800/2, 9*240/8);
    for (int i = 0; i < 1200; i += 25) {
      image(imgflrA, width/2+i-455, height/2+168);
      imgflrA.resize(260/5, 220/5);
    }
    for (int i = 0; i < 1300; i += 25) {
      image(imgflrA, width/2+i-550, height/2+418);
      imgflrA.resize(260/5, 220/5);
    } 
    for (int i = 0; i < 1200; i += 25) {
      image(imgflrA, width/2+i-380, height/2-82);
      imgflrA.resize(260/5, 220/5);
    }
    for (int i = 0; i < 1200; i += 25) {
      image(imgflrA, width/2+i-280, 118);
      imgflrA.resize(260/5, 220/5);
    }
  }

  void elevatorPic() {
    pushMatrix();
    translate(-width/2+350, 0);
    image (imgele, width-195, Helevator[i]-110);
    imgele.resize(4*612/9, 4*612/9);
    popMatrix();
  }

  void rocks() {
    image(imgRK1, width/2-480, height/2+100);
    imgRK1. resize(1*837/4, 1*257/3);
    image(imgRK2, width/2-550, height/2+340);
    imgRK2. resize(1*837/4, 1*257/3);
    image(imgRK3, width/2-400, height/2-150);
    imgRK3. resize(1*837/4, 1*257/3);
    image(imgRK3, width-160, height/2+100);
    imgRK3. resize(1*837/4, 1*257/3);
    image(imgRK1, width-160, height/2+350);
    imgRK1. resize(1*837/4, 1*257/3);
    image(imgRK2, width-160, height/2-150);
    imgRK2. resize(1*837/4, 1*257/3);
  }


  void rubbish() {
    if (currentRubbish == 0) {    
      image (imgRubbish[0], Xrubbish-80, Hrubbish[r]-45+20);
      imgRubbish[0].resize(2*332/7, 2*152/7);
    }
    if (formerRubbish == 0  && showImg == true) {    
      image (imgRubbish[0], xPos-100, yPos-65+20);
      imgRubbish[0].resize(2*332/7, 2*152/7);
    }

    if (currentRubbish == 1) {    
      image (imgRubbish[1], Xrubbish-50, Hrubbish[r]-70+20);
      imgRubbish[1].resize(2*216/7, 2*233/7);
    }        
    if (formerRubbish == 1 && showImg == true) {    
      image (imgRubbish[1], xPos-80, yPos-70+20);
      imgRubbish[1].resize(2*216/7, 2*233/7);
    }

    if (currentRubbish == 2) {    
      image (imgRubbish[2], Xrubbish-75, Hrubbish[r]-80+20);
      imgRubbish[2].resize(1*800/11, 1*800/11);
    }
    if (formerRubbish == 2 && showImg == true) {    
      image (imgRubbish[2], xPos-80, yPos-80+20);
      imgRubbish[2].resize(1*800/11, 1*800/11);
    }

    if (currentRubbish == 3) {    
      image (imgRubbish[3], Xrubbish-40, Hrubbish[r]-50+20);
      imgRubbish[3].resize(3*267/7, 3*189/7);
    }
    if (formerRubbish == 3 && showImg == true) {    
      image (imgRubbish[3], xPos-80, yPos-70+20);
      imgRubbish[3].resize(3*267/7, 3*189/7);
    }
  }

  void monsters() {
    image(imgmstOrg, tina.badX-100, tina.badY-80);
    imgmstOrg.resize(305/2, 229/2);

    image(imgmstGrn, coco.badX-100, coco.badY-80);
    imgmstGrn.resize(319/2, 220/2);

    image(imgmstBlu, ying.badX-100, ying.badY-80);
    imgmstBlu.resize(306/2, 272/2);

    image(imgmstYlw, ding.badX-100, ding.badY-80);
    imgmstYlw.resize(328/2, 225/2);
  }

  void leftRight() {
    if (yPos == 596 || yPos == 850 || yPos == 344 || yPos == 95) {
      if (sensorValues[0] < 20) {
        xPos -= speedC;
      }
      if (sensorValues[1] < 20) {
        xPos += speedC;
      }
    }
  }

  void upDown () {

    //1 to 2
    if (xPos<width/2-400+ladderWidth && xPos>width/2-400 && yPos <= floor1 && yPos >= floor2) {
      if (sensorValues[2] < 20) {       
        yPos -= climbSpeed;
        if (yPos <= floor2 && yPos >= floor2 - 5) {
          yPos = floor2;
        }
      } else if (sensorValues[0] < 20 && sensorValues[1] < 20) {
        yPos += climbSpeed;
        if (yPos >= floor1 && yPos <= floor1 + 5) {
          yPos = floor1;
        }
      }
    }    
    if (xPos<width/2+630+ladderWidth && xPos>width/2+630 && yPos <= floor1 && yPos >= floor2) {
      if (sensorValues[2] < 20) {       
        yPos -= climbSpeed;
        if (yPos <= floor2 && yPos >= floor2 - 5) {
          yPos = floor2;
        }
      } else if (sensorValues[0] < 20 && sensorValues[1] < 20) {
        yPos += climbSpeed;
        if (yPos >= floor1 && yPos <= floor1 + 5) {
          yPos = floor1;
        }
      }
    }

    //2 to 3
    if (xPos<width/2+200 + ladderWidth && xPos>width/2+200 && yPos <= floor2 && yPos >= floor3 ) {
      if (sensorValues[2] < 20) {       
        yPos -= climbSpeed;
        if (yPos <= floor3 && yPos >= floor3 - 5) {
          yPos = floor3;
        }
      } else if (sensorValues[0] < 20 && sensorValues[1] < 20) {
        yPos += climbSpeed;
        if (yPos >= floor2 && yPos <= floor2 + 5) {
          yPos = floor2;
        }
      }
    }
    if (xPos<width/2-82 + ladderWidth && xPos>width/2-82 && yPos <= floor2 && yPos >= floor3 ) {
      if (sensorValues[2] < 20) {       
        yPos -= climbSpeed;
        if (yPos <= floor3 && yPos >= floor3 - 5) {
          yPos = floor3;
        }
      } else if (sensorValues[0] < 20 && sensorValues[1] < 20) {
        yPos += climbSpeed;
        if (yPos >= floor2 && yPos <= floor2 + 5) {
          yPos = floor2;
        }
      }
    }

    //3 to 4
    if (xPos<2*width/8+100 + ladderWidth && xPos>2*width/8+100 && yPos >= floor4 && yPos <= floor3) {
      if (sensorValues[2] < 20) {       
        yPos -= climbSpeed;
        if (yPos <= floor4 && yPos >= floor4 - 5) {
          yPos = floor4;
        }
      } else if (sensorValues[0] < 20 && sensorValues[1] < 20) {
        yPos += climbSpeed;
        if (yPos >= floor3 && yPos <= floor3 + 5) {
          yPos = floor3;
        }
      }
    }
    if (xPos<width/2+630 + ladderWidth && xPos>width/2+630 && yPos >= floor4 && yPos <= floor3) {
      if (sensorValues[2] < 20) {       
        yPos -= climbSpeed;
        if (yPos <= floor4 && yPos >= floor4 - 5) {
          yPos = floor4;
        }
      } else if (sensorValues[0] < 20 && sensorValues[1] < 20) {
        yPos += climbSpeed;
        if (yPos >= floor3 && yPos <= floor3 + 5) {
          yPos = floor3;
        }
      }
    }
  }

  void changefloor() {

    if (elevatorTimes >0) {
      if (sensorValues[3] ==1 && previousValue3 == 0) {
        i = 3;
        elevatorTimes--;
      } else if (sensorValues[4] ==1 && previousValue4 == 0) {
        i = 2;     
        elevatorTimes--;
      } else if (sensorValues[5] ==1 && previousValue5 == 0) {
        i = 1;
        elevatorTimes--;
      } else if (sensorValues[6] ==1 && previousValue6 == 0) {
        i = 0;
        elevatorTimes--;
      }
    }


    if (xPos < width/2+100+270 && xPos > width/2+270 && elevatorTimes > 0) {
      if (sensorValues[3] ==1 && previousValue3 == 0) {
        i = 3;
        yPos = floor1;
        xPos = width/2+340;
      } else if (sensorValues[4] ==1 && previousValue4 == 0) {
        i = 2;
        yPos = floor2;
        xPos = width/2+340;
      } else if (sensorValues[5] ==1 && previousValue5 == 0) {      
        i = 1;
        yPos = floor3;
        xPos = width/2+340;
      } else if (sensorValues[6] ==1 && previousValue6 == 0) {
        i = 0;
        yPos = floor4;
        xPos = width/2+340;
      }
    }
    previousValue3 = sensorValues[3];
    previousValue4 = sensorValues[4];
    previousValue5 = sensorValues[5];
    previousValue6 = sensorValues[6];
  }
  void border() {

    //border
    if (yPos == floor1 && xPos < width/8+20) {
      xPos = width/8+20;
    } else if (yPos == floor1 && xPos > width - 10) {
      xPos = width - 10;
    } else if (yPos == floor2 && xPos < width/8+110) {
      xPos = width/8+110;
    } else if (yPos == floor2 && xPos > width - 10) {
      xPos = width - 10;
    } else if (yPos == floor3 && xPos < width/8+200) {
      xPos = width/8+200;
    } else if (yPos == floor3 && xPos > width - 10) {
      xPos = width - 10;
    } else if (yPos == floor4 && xPos < width/8+300) {
      xPos = width/8+300;
    } else if (yPos == floor4 && xPos > width - 10) {
      xPos = width - 10;
    }
  }
  void keyPressed() {

    if (keyPressed) {
      if (yPos == 596 || yPos == 850 || yPos == 344 || yPos == 95)
        if (key == CODED) {
          if (keyCode == LEFT) {
            xPos -= speedC;
          } else if (key == CODED) {
            if (keyCode == RIGHT) {
              xPos += speedC;
            }
          }
        }

      //change the floors
      if (xPos < width/2+100+270 && xPos > width/2+270 && elevatorTimes > 0) {
        if (key =='1') {
          i = 3;
          yPos = floor1;
          xPos = width/2+340;
        } else if (key =='2') {
          i = 2;
          yPos = floor2;
          xPos = width/2+340;
        } else if (key =='3') {      
          i = 1;
          yPos = floor3;
          xPos = width/2+340;
        } else if (key =='4' ) {
          i = 0;
          yPos = floor4;
          xPos = width/2+340;
        }
      }

      //step ladders

      //1 to 2
      if (xPos<width/2-400+ladderWidth && xPos>width/2-400 && yPos <= floor1 && yPos >= floor2) {
        if (key == CODED) {
          if (keyCode == UP) {       
            yPos -= climbSpeed;
            if (yPos <= floor2 && yPos >= floor2 - 5) {
              yPos = floor2;
            }
          } else if (keyCode == DOWN) {
            yPos += climbSpeed;
            if (yPos >= floor1 && yPos <= floor1 + 5) {
              yPos = floor1;
            }
          }
        }
      }
      if (xPos<width/2+630+ladderWidth && xPos>width/2+630 && yPos <= floor1 && yPos >= floor2) {
        if (key == CODED) {
          if (keyCode == UP) {       
            yPos -= climbSpeed;
            if (yPos <= floor2 && yPos >= floor2 - 5) {
              yPos = floor2;
            }
          } else if (keyCode == DOWN) {
            yPos += climbSpeed;
            if (yPos >= floor1 && yPos <= floor1 + 5) {
              yPos = floor1;
            }
          }
        }
      }

      //2 to 3
      if (xPos<width/2+200 + ladderWidth && xPos>width/2+200 && yPos <= floor2 && yPos >= floor3 ) {
        if (key == CODED) {
          if (keyCode == UP) {       
            yPos -= climbSpeed;
            if (yPos <= floor3 && yPos >= floor3 - 5) {
              yPos = floor3;
            }
          } else if (keyCode == DOWN) {
            yPos += climbSpeed;
            if (yPos >= floor2 && yPos <= floor2 + 5) {
              yPos = floor2;
            }
          }
        }
      }
      if (xPos<width/2-82 + ladderWidth && xPos>width/2-82 && yPos <= floor2 && yPos >= floor3 ) {
        if (key == CODED) {
          if (keyCode == UP) {       
            yPos -= climbSpeed;
            if (yPos <= floor3 && yPos >= floor3 - 5) {
              yPos = floor3;
            }
          } else if (keyCode == DOWN) {
            yPos += climbSpeed;
            if (yPos >= floor2 && yPos <= floor2 + 5) {
              yPos = floor2;
            }
          }
        }
      }

      //3 to 4
      if (xPos<2*width/8+100 + ladderWidth && xPos>2*width/8+100 && yPos >= floor4 && yPos <= floor3) {
        if (key == CODED) {
          if (keyCode == UP) {       
            yPos -= climbSpeed;
            if (yPos <= floor4 && yPos >= floor4 - 5) {
              yPos = floor4;
            }
          } else if (keyCode == DOWN) {
            yPos += climbSpeed;
            if (yPos >= floor3 && yPos <= floor3 + 5) {
              yPos = floor3;
            }
          }
        }
      }
      if (xPos<width/2+630 + ladderWidth && xPos>width/2+630 && yPos >= floor4 && yPos <= floor3) {
        if (key == CODED) {
          if (keyCode == UP) {       
            yPos -= climbSpeed;
            if (yPos <= floor4 && yPos >= floor4 - 5) {
              yPos = floor4;
            }
          } else if (keyCode == DOWN) {
            yPos += climbSpeed;
            if (yPos >= floor3 && yPos <= floor3 + 5) {
              yPos = floor3;
            }
          }
        }
      }

      if (key ==ENTER) {
        freeze = false;
        textState1 = true;
        previousTime = 0;
        pastTime = currentTime;
        food = 0; 
        elevatorTimes = 3;
        xPos = 1300;
        yPos = 850;
        start = millis();
        tutorial = false;
      }
      if (key == SHIFT) {
        clickCounter = 0;
      }
    }
  }
}

//*********************************************elevator*********************************************
int[] Helevator = {6, 258, 510, 762};
int i = 3;


void keyPressed() {
  if (elevatorTimes >0) {
    if (key =='1') {
      i = 3;
      elevatorTimes--;
    } else if (key =='2') {
      i = 2;     
      elevatorTimes--;
    } else if (key =='3') {
      i = 1;
      elevatorTimes--;
    } else if (key =='4') {
      i = 0;
      elevatorTimes--;
    }
  }
}

//*********************************************image*********************************************

void setImage() {
  

  
  image(imgb, width/2+120, -80);
  imgb.resize(2*210/3, 2*310/3);

  image(imgr, width/2-45, 18*height/25+20 );
  imgr.resize(2*210/3, 2*310/3);

  image(imgg, width/2+80, 5*height/25-10 );
  imgg.resize(2*210/3, 2*310/3);

  image(imgy, width/2+30, 12*height/25-10 );
  imgy.resize(2*210/3, 2*310/3);

  image(imgl1, width/2-400, height/2+190);
  imgl1.resize(4*121/5, 4*564/9);
  image(imgl2, width/2+200, height/2-60);
  imgl2.resize(4*121/5, 4*564/9);
  image(imgl3, 2*width/8+100, height/2-300);
  imgl3.resize(4*121/5, 4*564/9);
  image(imgl1, width/2+630, height/2+190);
  imgl1.resize(4*121/5, 4*564/9);
  image(imgl2, width/2-82, height/2-60);
  imgl2.resize(4*121/5, 4*564/9);
  image(imgl3, width/2+630, height/2-300);
  imgl3.resize(4*121/5, 4*564/9);
}

//*********************************************rank*********************************************
//byte score;
//byte[] highestScore = {score};
int hScore = 29;




int highFood = 14;
int highele = 15;

void rank() {
  hScore = highFood + highele;
  
  if (food >= highFood) {
    highFood = food;
  }
  if(elevatorTimes >= highele) {
  highele = elevatorTimes;
  }
  
}

//*********************************************the bad*********************************************

class Bad {
  //member variables
  float badX, badY, badSize;
  int direction = 1;
  int leftSide = 200;
  int rightSide = 200;
  




  //constructor
  Bad(float x, float y, float s) {
    badX = x;
    badY = y;
    badSize = s;
  }
  //functionalities


  //running around
  void runningAround1() {
    if (badY == 598 && badX < width/8+100 + leftSide || badX > width - rightSide) {
      direction *= -1;
    }
    badX += 4.8*direction;
  }
  void runningAround2() {
    if (badY == 346 && badX < width/8+200 + leftSide || badX > width - rightSide) {
      direction *= -1;
    }
    badX += 4*direction;
  }
  void runningAround3() {
    if (badY == 94 && badX < width/8+300 + leftSide || badX > width - rightSide) {
      direction *= -1;
    }
    badX += 5.3*direction;
  }
  void runningAround4() {
    if (badY == 850 && badX < width/8+ 80 + leftSide || badX > width - rightSide) {
      direction *= -1;
    }
    badX += 5*direction;
  }
}

Recitation 10: Media Controller (Ding Wang)

  • Name: Ding Wang
  • Professor: Young&Eric

Recitation Project

This is the last recitation for us to make the project ourselves. And we were required to use Arduino values controlling the Media in Processing. I think this is a project we need to use all of our knowledge which we have learned this semester including building the Arduino circuit, drawing media in the processing and sending values between Arduino and Processing.

So this time I used the web camera as the media part in Arduino and used two distance sensors as a valve controller. By changing the distance, the media on the screen will show different patterns. One sensor is to control the ellipse drawing on the screen. Based on the distance, the size of these ellipses is different. Another sensor is used to control the rectangle. When the distance is shorter than a certain value, the rectangle will appear.

But one problem I found in this process is that the ultrasonic ranger is not sensitive enough because of its principle. So my partner and I also change the ultrasonic ranger into the infrared distance sensors.

 

Reflection

After reading the Computer Vision for Artist and Designers, firstly I realized that by using computer and computer programing, our work becomes more convenient and can help the artists achieve the artificial effect they want. But in my understanding, the computers are just a tool and the central part for an artist work is still the artificial thinking.

Recitation9 :Serial Communication(Ding Wang)

  • Name: Wang Ding
  • Professor: Eric&Young

Exercise 1

In this exercise, we are required to use two values from Arduino to control the movement of the ellipse. But I used three potentiometers to send three values to processing. Two potentiometers can control the movement of the ellipse(one determine the x, and another determines y). And the third potentiometer can control the size of the ellipse, it means by using this potentiometer, the user can control the width of the flow.

Exercise 2

In this exercise, we are required to send two values from Arduino from processing to Arduino and making an instrument. So I use the position of my mouse to control the note of the buzzer.

Reflection

By using the example code, it’s easier for us to write the code. Because we only need to change a little part based on our own project.

//Exercise 1 processing part
// IMA NYU Shanghai
// Interaction Lab
// For receiving multiple values from Arduino to Processing

/*
 * Based on the readStringUntil() example by Tom Igoe
 * https://processing.org/reference/libraries/serial/Serial_readStringUntil_.html
 */

import processing.serial.*;

String myString = null;
Serial myPort;


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

float x;
float y;
float size;

void setup() {
  size(900,900);
  background(255);
  setupSerial();
}


void draw() {
  float x = map(sensorValues[0],0,1023,0,800);
  float y = map(sensorValues[1],0,1023,0,800);
  float size = map(sensorValues[2],0,1023,5,10);
  
  
  
  
  updateSerial();
  printArray(sensorValues);
  fill(0);
  ellipse(x,y,size,size);
  

  // use the values like this!
  // sensorValues[0] 

  // add your code

  //
}



void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  // WARNING!
  // You will definitely get an error here.
  // Change the PORT_INDEX to 0 and try running it again.
  // And then, check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index number of the port.

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  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]);
        }
      }
    }
  }
}

//Exercise 1 Arduino part

// IMA NYU Shanghai
// Interaction Lab
// For sending multiple values from Arduino to Processing


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

void loop() {
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);
  int sensor3 = analogRead(A2);

  // keep this format
  Serial.print(sensor1);
  Serial.print(",");  // put comma between sensor values
  Serial.print(sensor2);
  Serial.print(",");
  Serial.print(sensor3);
  Serial.println(); // add linefeed after sending the last sensor value

  // too fast communication might cause some latency in Processing
  // this delay resolves the issue.
  delay(100);
}

//Exercise 2 Processing part

// IMA NYU Shanghai
// Interaction Lab


/**
 * This example is to send multiple values from Processing to Arduino.
 * You can find the arduino example file in the same folder which works with this Processing file.
 * Please note that the echoSerialData function asks Arduino to send the data saved in the values array
 * to check if it is receiving the correct bytes.
 **/


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[NUM_OF_VALUES];

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

  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 1 ], 9600);
  // check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index of the port

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  myString = myPort.readStringUntil( 10 );  // 10 = 'n'  Linefeed in ASCII
  myString = null;
}


void draw() {
  background(0);

  // changes the values
  values[0] =  mouseX;
  values[1] = mouseY;
  

  // sends the values to Arduino.
  sendSerialData();

  // This causess the communication to become slow and unstable.
  // You might want to comment this out when everything is ready.
  // The parameter 200 is the frequency of echoing. 
  // The higher this number, the slower the program will be
  // but the higher this number, the more stable it will be.
  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 );
}

//Exercise 2 Arduino Part

// IMA NYU Shanghai
// Interaction Lab


/**
  This example is to send multiple values from Processing to Arduino.
  You can find the Processing example file in the same folder which works with this Arduino file.
  Please note that the echo case (when char c is 'e' in the getSerialData function below)
  checks if Arduino is receiving the correct bytes from the Processing sketch
  by sending the values array back to the Processing sketch.
 **/

#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);
}

void loop() {
  getSerialData();
  tone(7,values[0],100);
  tone(8,values[1],100);

  // add your code here
  // use elements in the values array
  // values[0]
  // values[1]
}


//recieve serial data from Processing
void getSerialData() {
  if (Serial.available()) {
    char c = Serial.read();
    //switch - case checks the value of the variable in the switch function
    //in this case, the char c, then runs one of the cases that fit the value of the variable
    //for more information, visit the reference page: https://www.arduino.cc/en/Reference/SwitchCase
    switch (c) {
      //if the char c from Processing is a number between 0 and 9
      case '0'...'9':
        //save the value of char c to tempValue
        //but simultaneously rearrange the existing values saved in tempValue
        //for the digits received through char c to remain coherent
        //if this does not make sense and would like to know more, send an email to me!
        tempValue = tempValue * 10 + c - '0';
        break;
      //if the char c from Processing is a comma
      //indicating that the following values of char c is for the next element in the values array
      case ',':
        values[valueIndex] = tempValue;
        //reset tempValue value
        tempValue = 0;
        //increment valuesIndex by 1
        valueIndex++;
        break;
      //if the char c from Processing is character 'n'
      //which signals that it is the end of data
      case 'n':
        //save the tempValue
        //this will b the last element in the values array
        values[valueIndex] = tempValue;
        //reset tempValue and valueIndex values
        //to clear out the values array for the next round of readings from Processing
        tempValue = 0;
        valueIndex = 0;
        break;
      //if the char c from Processing is character 'e'
      //it is signalling for the Arduino to send Processing the elements saved in the values array
      //this case is triggered and processed by the echoSerialData function in the Processing sketch
      case 'e': // to echo
        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;
    }
  }
}

Final Project Proposal Essay (Ding Wang)

  • Name: Ding Wang
  • Professor: Young&Eric

A. Project Title

The name of my project is “Jump out of your limit“.


B. Project Statement of Purpose

After focusing on “encouraging people to drink more water” for my midterm project, I still choose “Health” as my central theme for my final project. And this time I want to “encourage people to do more exercise” by designing my final project. In an age of rapid pace of life, people are always busy with work and study and seldom spend time doing exercises. Studies have shown that proper exercise is essential for good health. And if people can spend some time doing exercise after a tight workday, they will be more productive and energetic. So I was wondering whether I can design a device which can let people do some exercise conveniently. After they work in front of the computers for a long time, they can easily stand up and do some exercises. And at the same time, this “game” should be interesting enough to encourage them to do the homework.


C. Project Plan

In short terms, my project is a game. In this game, users need to jump through “obstacles” to keep the game going. This project can be divided into two parts. One is the physical part which is controlled by Arduino. And another part is the visual effect part which can be shown by processing.

My current idea now is that connecting some ultrasonic rangers with different servos and put these sensors on different height levels. These servos can rotate with these servos. Every time when the sensors face to the users, the users need to jump up. And at the same time, they can see the obstacles on the monitor. And the height levels for the obstacles are different every time, the user must jump over this height or he will lose. Before the game, the user needs to wear a heart rate sensor. And their heart rate can be shown as a graph on the monitor.

And for my plan, I will finish my circuit and coding separately, and combine them together. Maybe I will have more ideas in this process.


D. Reference

For my research until now, I did not find some other projects really affect my definition of interaction. I just find some interesting ideas and try to think about how to add them to my project.

Recitation 8: Final Project Preparation (Ding Wang)

  • Name: Ding Wang
  • Professor: Eric&Young

 

A. Go back to your definition of interaction as you defined it during the group project. How has your work in this course involved that definition?

During my group project, my definition of interaction is below.

The simplest way for me to define interaction is a process of mutual communication. It is like a process of “information sharing”. The two sides constantly communicate their information to each other and react to the information given by the other side, thus forming a cycle. It’s just like the formula “loop” in Arduino. And extensiveness is an important feature of interaction, this kind of extensiveness can be embodied in three aspects: the body that participates in the interaction, the way of interaction, the uncertainty of interaction.

So our project is like an AI robot. As an intelligent being, it can interact with the other side of the interaction in a lot of ways. The interaction is also full of uncertainty and interest.

B. Based on the initial definition and your experience developing and executing your midterm project, how has your definition of interaction evolved? Be as specific as possible.

During the midterm project making process, something I understand more about interaction is that the interaction needs to have a theme. In other words, interaction needs to have a direction.

Just like before we begin our project, we need to identify a theme for this project. Although the process of interaction is varied,but it will never deviate from the theme of this interaction.

C. Research two other interactive projects, one that aligns with your definition of interaction and one that differs from it.

This is a project which has a big influence on my midterm project and also the definition of interaction. First, intuitively, this lighting art effect looks pretty fancy. I also use many light effects in my project. Secondly, the theme of this project is obvious that creating an abstract art. Thirdly, this kind of interaction is full of uncertainty and also interests.

This is the second project I found. In this project,  the theme is also obvious and the interaction is also creative. But one thing I don’t like is that the project is less of the frequent interaction. In other words, I think it’s just like a tool for people.

D. Write a “new” definition of interaction in your own words. Draw from your account above and try to evolve your definition beyond the current convention. It should be polished and professional: imagine it will be printed on IMA Interaction Lab’s next course syllabus!

Interaction is the process of sharing information by receiving, processing and outputting information among subjects with communication ability.

 

 

 

Recitation#7 Processing Animation

  • Name: Ding Wang
  • Professor: Young&Eric

Exercise

For this exercise, my inspiration is from the question we meet when we first learn Processing. In the first recitation, some classmates and I all feel that it’s more difficult to use these coding and numbers to draw the picture than using a pen to draw. So I wanted to make a “pen tool” by using which the users can control the direction of the line directly.

So by using this, I draw some abstract pictures.

And later it reminds me of a famous computer game, so I edit the code and make another project.

The problem I meet in this project is that at first, I wrote the if condition as the x and y of the “snake” is same as the x and y of the point. But I found it’s very difficult to let the snake get this point. After I ask Leon for help, I know that the position is only one pixel, so it’ very difficult to let the two positions be same. And I changed the condition. If the snake can get a range near the point, it can get the point.

Homework

Reflection

  1. To let the color change with the change of the size, I used the map function.
  2. After using the colorMode(HSB), it’s important to change it into colorMode(RGB) again, if I want to use the value of RGB below.

Midterm project blog : The song of ice and fire (Ding Wang)

  • Name: Ding Wang
  • Professor: Eric&Young

Part 1: Project Name

The name of our project is ” The song of ice and fire”. First, the name was inspired by the famous novel “A song of ice and fire”. The name fits well with one of the main functions of our product: detecting the temperature of water. And the color of the LED varies from blue to red depending on the temperature from low to high. And the gradual change of color in the process is like the process of ice and fire blending. The “song” here is a visual expression.

Part 2: Project purpose

Water is the source of life. No one can live without water. Now, with the quickening pace of life, many workers or students always forget to drink or drink very little. And sometimes people drink very hot coffee or very cold water, which is a very unhealthy lifestyle. So we choose water as the keyword and make this project aiming to solve the problem above.

To solve these problems we have three functions in our project. The first function is that a LED belt can change its color from blue to red depending on the temperature of the water. Because we are not thermometers and computers. We don’t know the exact temperature of the water, or sometimes, when we try to judge the temperature of water by touching, we are often scalded by water. So we convert the temperature that we can not judge by the visual judgment to the color that can be judged directly. The second function is based on a study that the most suitable water for people to drink is the water with a temperature of 20-30 degree. So if the temperature of the water is not in this range, it will keep flashing warnings to remind users that the current water temperature is not suitable for drinking. Until the user constantly adjusts the water temperature to this extent, it will stop flashing. The third function is to encourage the users drinking more water. There is another green LED belt and its brightness will gradually increase with the increase in water volume. This not only enables users to realize how much water they drink but also encourages them to drink more water. Because green is a symbol of vitality, when the user sees the increasing of rightness, their emotion will become even better and drink more.

Part 3: Reference

The first thing is the definition and understanding of interaction. In the article “The art of interactive art”, the author notes that interaction is ” a cyclic process in which two actors alternately listen, think, speak. The quality of the interaction depends on the quality of each of the subtasks. ” In this definition, I realize the key points to improve the quality of integration is the quality of input and output and the frequency for this cyclic process.

There are also some other projects which influence my design for this project. What I learn from these projects is not the project itself, but the understanding of interaction.

In this project, the users can put their hands on the desk. And there will some abstract pictures based on the position of the hands. What I learn from this project is “uncertainty”. Personally, I don’t like the project which the users can control easily. I think the process of interaction should be full of uncertainty. In other words, users can get some surprising feedback from the device.

So the way these resource impact my project can be seen in these following aspects. Firstly the input part of our project is both weight and temperature. And the output part is the fancy light. The color in the box is a mixture of several colors, so the user can guess what’s the color will be. It’s interesting and surprising and also full of uncertainty.

Part 4: Project description

Firstly, my partner and I just have some keywords for this project like “light”, “different sensor”, and “water”. So we use a lot of time to learn how to use the program to control the Neopixel, and how to connect different sensors with these LED bars. For several days work and professors’ help, we learned how to connect the circuit and write coding. But at that time, we just have some “components” of the technology. We just have the knowledge for the hardware and software. We need a central theme to connect them together. Later I find many students were so busy during the midterm week including me, and sometime I will even forget to drink any water during a whole day. So we were wondering whether we can make a project to help people drink water.

And before the user testing, our definition of this project is a project which can prevent the users from being burnt. And after the user testing, I try to put the pressure sensor and another LED belt in the circuit. And surprisingly, I found a survey online about the most suitable water for people to drink. And the project has the function it has now.

After we finish the circuit and use laser cutter make a transparent box, we also use some cotton and other material to decorate it. Because during the user testing, some “users” gave us suggestions that, it’s dangerous to put these wires and components outside. And it needs to be more obvious for the users to know the function of our project.

Part 5: Project Significance

As I have mentioned above, water is very important for us. No one can live without water. So our project faces different ages of people.  Drinking water is something which is very important but is always ignored by people. So by designing our project, we want to remind the people that drinking water is very important. And also the temperature and volume of water are also important to think when we drink water.

Connect our project with a normal but important phenomenon in our daily life is the most meaningful aim for our project in my opinion.

Part 6: Project Design

I want to talk about the project design from three different perspectives: input, output, and theme.

Firstly, for the output part, we want to use some fancy light. So the normal LED is not suitable for our project. Because I am a lab assistant, I found the LED belt in the ER by accident. And at first, I just want to have a try and know how it works. But after I connect it I find it doesn’t work. So I ask for Nick and Leon’s help. I find many problems. For example, I need to use the 5 voltage power and also a capacitor in the circuit. And after I connected the circuit, I opened an example program. I was surprised by the beautiful effect. Some classmates even came to ask me what’s this. They also appreciated the fancy effect of the LED belt. But the next problem is how to use program control the LED, how to change the color and the frequency for blanking.

Secondly, after I finished the output part. I wanted to use some sensors as the input part. The first thing came to my mind is the temperature sensor. By the guidance online, I knew how to connect it and read the value from the temperature sensor. After the user testing, I tried the weight sensor. But at that time, I met a problem that the sensor was not sensitive enough. So it can not achieve the effect we want. After asking for the professor’s help, we changed the type of weight sensor, and it can work well.

The third step is to put the two part together and use the “if” condition to control the LED belt. After finish these step, we finished the circuit totally. And because we want to project looks simple outside, we just used the laser cutter making a transparent box to contain the circuit.

Part 7: Conclusion

Personally, I think the designing and making process is a chance for me to become familiar with the Arduino including the circuit and also the coding. And another important thing is that I have learned the way to learn a new thing which I have never met before including how to understand the coding and find guidance online.

Using testing is a turning point for our project, we listened to the users’ suggestion and tried to improve it based on these suggestions. It’s also a chance for us to think more about how to meet users need in our project.

Finally, there is still something we want but we did not get in our project. The value is not precise. And we need more decoration for it. And we need some material to cover the wires and components. I think we can think more about these details if we have more time.

As the professor said, midterm is a good chance for us to learn. I can have more communication with professors, fellows and also classmates. I can also learn from other’s project and know other’s understanding of interaction. And also thanks for professor partner and classmates’ help with my project. I am wishing for the next chance to make another project.

 

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define PINPRESSURE            5
#define NUMPIXELSPRESSURE      66

#define PINTEMPERATURE           3
#define NUMPIXELSTEMPERATURE     66

Adafruit_NeoPixel pressurePixels = Adafruit_NeoPixel(NUMPIXELSPRESSURE, PINPRESSURE, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel temperaturePixels = Adafruit_NeoPixel(NUMPIXELSTEMPERATURE, PINTEMPERATURE, NEO_GRB + NEO_KHZ800);


int redT = 0; // red is a variable that represents the neopixels "red" value
int greenT = 0;// green is a variable that represent the neopixels "green" value
int blueT = 200; // blue is a variable that represents the neopixels "blue" value
int analogSensorValueT = 0;//analogSensorValue is a variable that stores the Sensor Value


int redP = 0; // red is a variable that represents the neopixels "red" value
int greenP = 200;// green is a variable that represent the neopixels "green" value
int blueP = 0; // blue is a variable that represents the neopixels "blue" value
int analogSensorValueP = 0;//analogSensorValue is a variable that stores the Sensor Value



void setup() {
  // put your setup code here, to run once:
  pressurePixels.begin(); 
  pressurePixels.clear();
  
  temperaturePixels.begin(); 
  temperaturePixels.clear();
  
  Serial.begin(9600);
}

void loop() {

  // read in both sensor values
  analogSensorValueT = analogRead(A0);
  analogSensorValueP = analogRead(A5);

  // print sensor values to the serial console
  Serial.print(analogSensorValueT);
  Serial.print(" ");
  Serial.println(analogSensorValueP);


  // Set LEDs responding to temperature
  
  redT = map(analogSensorValueT,550,670,0,255);
  blueT = map(analogSensorValueT,550,670,255,0);

  if(analogSensorValueT <600 ||analogSensorValueT >700) {

    // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
    for (int DING = 0; DING < NUMPIXELSTEMPERATURE; DING++) {
      // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
      temperaturePixels.setPixelColor(DING, temperaturePixels.Color(redT, 0, blueT) ); // Moderately bright green color.
  
    }
    temperaturePixels.show(); // This sends the updated pixel color to the hardware

    delay(100);
    // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
    for (int DING = 0; DING < NUMPIXELSTEMPERATURE; DING++) {
      // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
      temperaturePixels.setPixelColor(DING, temperaturePixels.Color(0, 0, 0) ); // Moderately bright green color.
  
    }
    temperaturePixels.show(); // This sends the updated pixel color to the hardware

    delay(100);
  } else {
    // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
    for (int DING = 0; DING < NUMPIXELSTEMPERATURE; DING++) {
      // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
      temperaturePixels.setPixelColor(DING, temperaturePixels.Color(redT, 0, blueT) ); // Moderately bright green color.
  
    }
    temperaturePixels.show(); // This sends the updated pixel color to the hardware   
  }


  // Set LEDs responding to temperature

  greenP = map(analogSensorValueP,0,1000,0,200);

  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
  for (int DING = 0; DING < NUMPIXELSPRESSURE; DING++) {
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pressurePixels.setPixelColor(DING, pressurePixels.Color(redP, greenP, blueP) ); // Moderately bright green color.

  }
  pressurePixels.show(); // This sends the updated pixel color to the hardware   
}

Recitation 6: Processing Basics (Ding Wang)

Step 1: Choose an image to be your motif

At first, I choose this picture as my motif. Because I think this picture is drawn in just two colors and two basic shapes. It may seem simple, but the body is so prominent and compact that there is no excess. The other thing that appeals to me is that the theme of the painting looks like a very abstract creature, with very simple structures, but it seems to have the characteristics of life.

Step 2: Draw your image in Processing

Considering that Halloween is coming,I want to draw a ghost. At first, I use some basic element and the white and black color draw a “face”.

And the next step is to fill the blank space with different colors.

The connection between my painting and the motif

Similarity: On the creative method,Both paintings use the most basic elements.

Difference: The sample picture seems more abstract, you could not explain what’s it. But for my painting, It’s obvious that it’s a ghost and also a face.

 

Reflection

  1. Firstly I think by using coding control the computer draw a picture is an interesting thing itself. It realizes a kind of digital art drawing effect.
  2. It’s an interesting thing that in the drawing process, I need to do the operation continuously because I want to draw a symmetric figure.
  3. If I want to draw more complex patterns, the key is to learn how to use more functions.

 

background(49,138,80); //set the color of background
fill(0,0,0); //fill the pattern with black color
size(600,600); //set the size of the vindow
// the form of two eyes
triangle(180,200,180,300,280,250);
triangle(300,250,400,200,400,300);
//the form of mouth and moustach
beginShape();
vertex(100,400);
vertex(480,400);
vertex(430,500);
vertex(280,500);
vertex(290,600);
vertex(300,500);
vertex(150,500);
endShape(CLOSE);
// draw the form of the hat
beginShape();
vertex(50,100);
vertex(530,100);
vertex(550,110);
vertex(30,110);
endShape(CLOSE);
beginShape();
vertex(80,100);
vertex(140,40);
vertex(440,40);
vertex(500,100);
endShape(CLOSE);
//divide the background with different parts by using different color
fill(92,96,211);
beginShape();
vertex(180,200);
vertex(290,110);
vertex(0,110);
vertex(0,600);
endShape(CLOSE);
beginShape();
vertex(290,110);
vertex(600,110);
vertex(600,600);
vertex(400,200);
endShape(CLOSE);
fill(125,79,191);
beginShape();
vertex(0,110);
vertex(0,0);
vertex(600,0);
vertex(600,110);
vertex(550,110);
vertex(530,100);
vertex(500,100);
vertex(440,40);
vertex(140,40);
vertex(80,100);
vertex(50,100);
vertex(30,110);
endShape(CLOSE);

Recitation#5 Visual Communication (Ding Wang)

For this recitation, we need to make a poster for the research project. I think it’s a way for practicing using the illustrator and thinker card.

Step 1: Make a 3D model

Our project is NONO, it’s an advanced AI technology project. It is like an “intelligent brain” which can help the users deal with many complicated problems. For the shape of NONO, it can change its shape into whatever you want. But for the 3D model, I made it like a robot to highlight its technology element and also to help the users understand its function.

And for the 3D model, I put some basic element together to let it looks simple but full of technology. It’s like Apple’s design philosophy.

Step 2: Edit the 3D model in Illustrator

To remove the background and other parts which I don’t need. I use the “ungroup” function and divide the whole pictures into different pieces. So I can delete any part I don’t like and just leave “NONO” here.

Step 3: Design the advertisement

For my experience of using photograph before, I have made some other posters myself. And because Ai has some similar function like Ps, I think I can also make the poster like the example. But for this poster, I want to change to another style.

I put the most important description here, and use the”pen” tool to draw something at random. I don’t use some other pictures and don’t fill the background into other fancy colors. I think these elements can let the poster look simple. It can also make this poster look like a manual drawing. It’s just like our idea for NONO: simple but concentrated.

 

Recitation 4: Drawing Machines Ding Wang

Name: Ding Wang

Professor: Young&Eric

Date: October 5

In this recitation, we learned using H-bridge to control a stepper motor. And it’s a more completed circuit compared with the former circuits. And the most interesting thing is that after we finished the circuit, we can combine the circuit and other materials into a drawing machine. It’s a good chance for me to learn how to put these Arduino circuits into use. And I also learned how to use machinery making an Interactive art project.

Documentation

Step 1
  • 1 * 42STH33-0404AC stepper motor
  • 1 * SN754410NE ic chip
  • 1 * power jack
  • 1 * 12 VDC power supply
  • 1 * Arduino kit and its contents

At first, I finished the circuit soon. The circuit needs 12V power. If the circuit is connected in a wrong way, maybe the Arduino board and even the laptop will be burnt. So I checked the circuit carefully.

Tip: Because the circuit is a little complicated, it’s important to know the order to connect these components. At first, I connected the “power” part by using red and black cables. After the first step, I fixed the H Bridge. Because it’s obvious that the H Bridge is the central part of this circuit. And finally, connect different pins on Arduino or different wires on the stepper motor to the H Bridge. By using this order, the circuit becomes more clear. And it’s more clear to connect the circuit. It’s also a useful way to analyze the circuit and understand the principle instead of just connecting the circuit referring to the image.

Step 2

The difference between STEP 1 and STEP 2 is a potentiometer. By adding the potentiometer, we can use it to control the direction and Rotation angle. There is an important problem is that the range of the stepper motor is from 0 to 200, but the range of int value is from 0 to 1023. So If I want the stepper motor and the potentiometer are synchronous, I need to change the value from 0-1023 into 0-200. The “map” function can help me. So I added a code ” val = map(val, 0 ,1023, 0, 200)

Tip: From the former experience, I knew that there are three pins on the potentiometer, the middle one connect the input pin on Arduino, and the other two pins connect the power and ground. But I am not sure whether there are some differences between the two pins. So I tried to change the two pins. And I find the potentiometer can work well in both ways. So there is no difference between the two pins.

 

Step 3
  • 2 * Laser-cut short arms
  • 2 * Laser-cut long arms
  • 1* Laser-cut motor holder
  • 2 * 3D printed motor coupling
  • 5 * Paper Fasteners
  • 1 * Pen that fits the laser-cut mechanisms
  • Paper

After I and my partner both completed the circuit. We began to finish the step 3 together. We built the arms for the drawing machine first. And after we finished it, we fund the height of the drawing machine is not suitable, because the pen couldn’t touch the paper. So we try to change the connection of the arm to let it become lower, we also put my laptop under the paper. Finally, the pen can touch the paper. But because of the height problem, the stepper motor didn’t work smoothly. After we made some adjustment, it works better.

Personal Feeling

This is a good lesson for me to know how to put these Arduino circuits into practical use. And also offer me some idea about the use of these components as motors and sensors. Now I am waiting for the next project.

Questions&Answers

Question 1

What kind of machines would you be interested in building? Add a reflection about the use of actuators, the digital manipulation of art, and the creative process to your blog post.

Inheritance is an important way to make human civilization continue. Now we explore the civilization of ancient humans through archaeological activities. If there is a device that can record the daily human life, it will be easy for future generations to explore the former human civilization. So I want to build a “ History Recorder”.

Actuator: These actuators like motors and sensors are basic components. But these basic components can be also used in different ways to achieve different effects. For the machine I want to build, how to use these sensors and cameras to follow these human and capture these scenes is a key part.

Digital manipulation of art: The machine and computer can only analyze digital information, but we can put some article elements in the “input” and “output” part.

Creative process: The creative process is considering how to combine the simplest components to achieve an artistic effect of the project.

Question 2

Choose an art installation mentioned in the reading ART + Science NOW, Stephen Wilson (Kinetics chapter). Post your thoughts about it and make a comparison with the work you did during this recitation. How do you think that the artist selected those specific actuators for his project?

The art installation I choose is Gastarbeiter. Nowadays, many artists focus on the human creativity but ignore the feeling of the human. This device can mix the sound, scenery and also feeling. And give the user a special feeling. In this device, people become the part who receive information from the machine instead of the part who control the machine or offer some information.

Personally, I think this device is different from the Drawing Machines we made. By using the drawing machine, we can control the motor to create a  painting. So man is the subject of creation. But as I mentioned above in the Gastarbeiter, people become the part who receive information.

I think the way to choose those actuators is to analyze how to mix and output these signals in a better way to make a strong feeling for the user. So they need to choose some suitable sensors, speakers and other actuators.

 

 

/*
 * MotorKnob
 *
 * A stepper motor follows the turns of a potentiometer
 * (or other sensor) on analog input 0.
 *
 * http://www.arduino.cc/en/Reference/Stepper
 * This example code is in the public domain.
 */

#include <Stepper.h>

// change this to the number of steps on your motor
#define STEPS 200

// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, 8, 9, 10, 11);

// the previous reading from the analog input
int previous = 0;

void setup() {
  // set the speed of the motor to 30 RPMs
  stepper.setSpeed(30);
}

void loop() {
  // get the sensor value
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 200)

  // move a number of steps equal to the change in the
  // sensor reading
  stepper.step(val - previous);

  // remember the previous value of the sensor
  previous = val;
}