Camera Keyboard - Joeny Thipsidakhom

From Robert-Depot
Revision as of 00:37, 5 June 2010 by Joeny Thipsidakhom (talk | contribs) (Documentation)

Jump to: navigation, search

Description

  • Motivation

Same as Midterm

I’m interested in virtual space/realms and how it interacts with the physical world or how the physical world interacts with virtual space, whether it’s through games and a controller, being a part of a physical place in a parallel virtual world, or through actual physical movement. I’m also what people may consider a “gamer” and interested in the whole interaction interface they use, whether its web-cams, standard controllers, motion controllers, etc and how those affect the way we interact with the virtual.

  • Interactive paradigm

I'm going to attempt to create a sort of game/animation that uses the brightness tracking of Processing and an external controller for inputs. As the brightness spot moves so will the character in the game would too (left, right, up, down) and as you press a button on the controller it would cause something on screen.

UPDATE: I'm going to be using Processing's brightness tracking along with a virtual keyboard created in Processing to control the movements of a game character. The user/users will have to navigate virtual space using hand held light sources and a web-cam paired with Processing's brightness tracking.

  • Technical Description

Processing and an external controller. Brightness tracking would allow for character movement while the external controller would allow for user inputs and secondary interaction. I'll create some sort of simple game/environment/animation in processing which to user would have to interact with.

UPDATE: Processing and two external light sources along with a web-cam. Brightness tracking will track the two light sources and depending on the area Processing picks up the light sources it will cause virtual typing of the keyboard. This will be paired with another Processing sketch in the form of a game. Either two people can control the game, or a single person by themselves.

Visualization

  • Functional Diagrams

[USER] -> [Camera + Lights] -> [Processing] -> [Processing Game]

  • Visual Concept

Coming Soon...

Documentation

Coming Soon...

Virtual Keyboard Code

//KEYS final int VK_A = 65; final int VK_S = 83; final int VK_D = 68; final int VK_W = 87; final int VK_RIGHT = 39; final int VK_LEFT = 37; final int VK_UP = 38; final int VK_DOWN = 40; final int VK_SHIFT = 16; final int VK_SPACE = 32;

//FONT PFont font;

//Press Character Once String lastButton = "";

Robot r;

//VIDEO import processing.video.*; Capture video;

void setup(){

 size(633,480);
 background(10);
 noFill();
 smooth();
 //VIDEO
 video = new Capture(this, width, height, 30);
 //TEXT
 font = loadFont("Univers66.vlw");
 textFont(font, 25);
 //BOUNDARY LINES.
 //UPPER LEFT
 rect(0,0,320,200);
 noFill();
 //UPPER RIGHT
 rect(320,0,320,200);
 noFill();
 //LOWER LEFT
 rect(0,280,320,240);
 noFill();
 //LOWER RIGHT
 rect(320,280,320,240);
 noFill();
 //TEXT  
 text("UPPER Left",100,50);
 text("UPPER Right",390,50);
 text("LOWER Left",100,330);
 text("LOWER Right",390,330);
 text("VOID", 285,250);
 try{
   r = new Robot();
 }
 catch(AWTException a){
 }

}

void draw() {

 //VIDEO
 if (video.available()) {
   video.read();
   image(video, 0, 0, width, height); // Draw the webcam video onto the screen
   int brightestRX = 0; // X-coordinate of the brightest video pixel
   int brightestRY = 0; // Y-coordinate of the brightest video pixel
   
   int brightestLX = 0;
   int brightestLY = 0;
   
   float brightestValueL = 0;
   float brightestValueR = 0; // Brightness of the brightest video pixel
   // Search for the brightest pixel: For each row of pixels in the video image and
   // for each pixel in the yth row, compute each pixel's index in the video
   video.loadPixels();
   int index = 0;
   for (int y = 0; y < video.height; y++) {
     for (int x = 0; x < video.width; x++) {
       // Get the color stored in the pixel
       int pixelValue = video.pixels[index];
       // Determine the brightness of the pixel
       float pixelBrightnessR = green(pixelValue);
       float pixelBrightnessL = red(pixelValue);
       // If that value is brighter than any previous, then store the
       // brightness of that pixel, as well as its (x,y) location
       if (pixelBrightnessR > brightestValueR) {
         brightestValueR = pixelBrightnessR;
         brightestRY = y;
         brightestRX = x;
       }
       //Follows RED
       if (pixelBrightnessL > brightestValueL) {
         brightestValueL = pixelBrightnessL;
         brightestLY = y;
         brightestLX = x;
       }
       
       index++;
     }
   }
   // Draw a large, yellow circle at the brightest pixel
   fill(0, 75, 255, 128);
   ellipse(brightestRX, brightestRY, 50, 50);
   fill(0, 75, 100, 128);
   rect(brightestLX, brightestLY, 100 ,100);
   //TYPING WASD

// //UPPER LEFT = A // if ((brightestRX <= 320 && brightestRY <= 200) || (brightestLX <= 320 && brightestLY <= 200)){ //// if(lastButton!="a") { // r.keyPress(VK_A); // r.keyRelease(VK_A); //// lastButton="a"; //// } // delay(500); // } // //UPPER RIGHT = D // if ((brightestRX >= 320 && brightestRY <= 200) || (brightestLX >= 320 && brightestLY <= 200)){ //// if(lastButton!="d") { // r.keyPress(VK_D); // r.keyRelease(VK_D); //// lastButton="d"; //// } // delay(500); // } // //LOWER LEFT = W // if ((brightestRX <= 320 && brightestRY >= 280) || (brightestLX <= 320 && brightestLY >= 280)){ // r.keyPress(VK_W); // r.keyRelease(VK_W); // delay(500); // } // //LOWER RIGHT = S // if ((brightestRX >= 320 && brightestRY >= 280) || (brightestLX >= 320 && brightestLY >= 280)){ // r.keyPress(VK_S); // r.keyRelease(VK_S); // delay(500); // }

// TYPING ARROWS

   //UPPER LEFT = UP
   if ((brightestRX <= 320 && brightestRY <= 200) || (brightestLX <= 320 && brightestLY <= 200)){

// if(lastButton!="a") {

       r.keyPress(VK_UP);
       r.keyRelease(VK_UP);

// lastButton="a"; // }

     delay(500);
   }
   //UPPER RIGHT = DOWN
   if ((brightestRX >= 320 && brightestRY <= 200) || (brightestLX >= 320 && brightestLY <= 200)){

// if(lastButton!="d") {

     r.keyPress(VK_DOWN);
     r.keyRelease(VK_DOWN);

// lastButton="d"; // }

     delay(500);
   }
   //LOWER LEFT = LEFT
   if ((brightestRX <= 320 && brightestRY >= 280) || (brightestLX <= 320 && brightestLY >= 280)){
     r.keyPress(VK_LEFT);
     r.keyRelease(VK_LEFT);
     delay(500);
   }
   //LOWER RIGHT = RIGHT
   if ((brightestRX >= 320 && brightestRY >= 280) || (brightestLX >= 320 && brightestLY >= 280)){
     r.keyPress(VK_RIGHT);
     r.keyRelease(VK_RIGHT);
     delay(500);
   } 
   
   //BOUNDARY LINES.
   //UPPER LEFT
   rect(0,0,320,200);
   noFill();
   //UPPER RIGHT
   rect(320,0,320,200);
   noFill();
   //LOWER LEFT
   rect(0,280,320,240);
   noFill();
   //LOWER RIGHT
   rect(320,280,320,240);
   noFill();
   //TEXT 
   //UPPER LEFT 
   text("UP",100,50);
   //UPPER RIGHT
   text("DOWN",390,50);
   //LOWER LEFT
   text("LEFT",100,330);
   //LOWER RIGHT
   text("RIGHT",390,330);
   //CENTER
   text("VOID", 285,250);
 }

}

Snake Game Code

ArrayList ellipseList; Ellipse head; int SEGMENT_SIZE = 10; int dir; int prevPosX, prevPosY; PFont f; String mesaj=""; boolean ok=false; Ellipse food; void setup() {

 size(400, 400);
 f=loadFont("Univers66.vlw");
 textFont(f);
 ellipseList = new ArrayList();
 head = new Ellipse(width/2, height/2);
 ellipseList.add(head);
 dir=2;
 // Start with head and small body
 ellipseList.add(new Ellipse(width/2 - 2 * SEGMENT_SIZE, height/2));
 addFood();
 mesaj="MOUSE";
 frameRate(10);

} void draw() {

 fill(0);
 background(100);
 text(mesaj,width/2-100,height/2);
 if(ok)
 {
   food.createEllipse();
   tryToEatAndMove(ellipseList.size());
 }

}

boolean tryToEatAndMove(int p) {

 int x = head.getX();
 int y = head.getY();
 if (dist(x, y, food.getX(), food.getY()) < 6)
 {
   // Move the body
   move();
   // Get last two segments
   Ellipse e1 = (Ellipse) ellipseList.get(ellipseList.size() - 1);
   Ellipse e2 = (Ellipse) ellipseList.get(ellipseList.size() - 2);
   int dX = e1.getX() - e2.getX();
   int dY = e1.getY() - e2.getY();
   // Add another segment at the end
   ellipseList.add(new Ellipse(e1.getX() + dX, e1.getY() + dY));
   // Add food to replace the one being eat
   addFood();
   println("Length: " + ellipseList.size());
   return true;
 }
 move();
 return false;

} void addFood() {

 food = new Ellipse(int(random(10, 390)), int(random(10, 390)),6);

} void move() {

 prevPosX = head.getX();
 prevPosY = head.getY();
 switch(dir)
 {
   case 0:

head.moveUp(); break;

   case 1:

head.moveDown(); break;

   case 2:

head.moveRight(); break;

   case 3:

head.moveLeft(); break;

 }
 followHead();

}

void followHead() {

 fill(0);
 head.createEllipse();
 fill(255);
 for (int i = 1; i < ellipseList.size(); i++)
 {
    Ellipse e = (Ellipse) ellipseList.get(i);
    int ppX = e.getX();
    int ppY = e.getY();
    // Move the segment where the previous one was
    e.x = prevPosX; e.y = prevPosY;
    prevPosX = ppX;
    prevPosY = ppY;
    e.createEllipse();
 }

}

void mousePressed() {

 mesaj="";
 ok=true;
 dir=2;

}

void keyPressed() {

 if(key==CODED)
 {
   if(keyCode==UP)
   {

dir=0;

   }
   if(keyCode==DOWN)
   {

dir=1;

   }
   if(keyCode==RIGHT)
   {

dir=2;

   }
   if(keyCode==LEFT)
   {

dir=3;

   }
 }

}

class Ellipse {

 int x; int y; int l; 
 Ellipse(int _x, int _y)
 {
   x=_x; y=_y; l=10;
 }
 Ellipse(int _x, int _y, int _l)
 {
   x=_x; y=_y; l=_l;
 }
 void createEllipse()
 {
   ellipse(x,y,l,l);
 }
 void createEllipse(int a,int b)
 {
   ellipse(a,b,l,l);
 }
 
 void moveUp()
 {
   y-=l;
   if(y<0) y=height;
 }
 void moveDown()
 {
   y+=l;
   if(y>height) y=0;
 }
 void moveRight()
 {
   x+=l;
   if(x>width) x=0;
 }
 void moveLeft()
 {
   x-=l;
   if(x<0) x=width;
 }
 int getX()
 {
   return x;
 }
 int getY()
 {
   return y;
 }
 int getL()
 {
   return l;
 }

}