Final project documentation. Maxim Blinov

Here it goes… 🙂

My final project idea was to get something from an alternate reality. After some brainstorming, I came up with this idea to make this arcade claw game (everyone knows this when this game where it is almost impossible to pull out an item) and make it virtual (a.k.a. on the computer) and make the prize be real. So it turned out to be this:

Description of the software/hardware:
The game itself consists of a big script made in processing which drew the claw machine game (code will be attached in the end) and an arduino script which opened the door and gave the prize. Sounds simple, but it took a lot of effort to do it. The claw was controlled with a joystick and the goal of the game was to drop an item off screen.

Expectation/evaluation:
The expectation was to get an item from the alternate reality and it worked out pretty well 🙂 The prizes were some haribos and chocolate chip cookies

Code:
Arduino code:

#include <Servo.h>;
int left = 0;
int right = 0;
int servoPin1 = 3;
int servoPin2 = 4;
const int inX = A1;
const int pressed = 6;
int xValue = 0;
int notPressed = 0;
Servo Servo1;
Servo Servo2;
void setup() {
  pinMode(inX, INPUT); // setup y input
  pinMode(pressed, INPUT_PULLUP); // we use a pullup-resistor for the button functionality
  Servo1.attach(servoPin1);
  Servo2.attach(servoPin2);
  Serial.begin(9600);
  Serial.println("1,1");
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop() {

  xValue = analogRead(inX);
  notPressed = digitalRead(pressed);
  Serial.print(xValue);
  Serial.print(",");
  Serial.println(notPressed);
  while (Serial.available()) {

    right = Serial.parseInt();
    left = Serial.parseInt();

    if (Serial.read() == '\n') {
      Servo1.write(right);
      Servo2.write(left);
    }


  }

}

    Processing code:
main:

import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;
import processing.serial.*;

Box2DProcessing box2d;
Claw claw;
bounds bounds;
movement move;
Serial myPort;
float moveX = 0;
float moveY = 0;
int directionX = 0;
int directionY = 0;
float gravity = 1;
float ellipseX = 200;
float ellipseX1 = 600;
float ellipseY = 400;
float ellipseY1 = 400;
int s;
int current = 0;
boolean time = false;
boolean pickup = false;
boolean attach = false;
boolean attach1 = false;
boolean ball1_out = true;
boolean ball2_out = true;
PImage img1,img2;

void setup() {
  //size(1280,1024);
  fullScreen();
  smooth();
  imageMode(CENTER);
  claw = new Claw();
  bounds = new bounds();
  move = new movement();
  printArray(Serial.list());
  img1 = loadImage("/home/neonovi/Desktop/cookie.png");
  img2 = loadImage("/home/neonovi/Desktop/snake.png");
  String portname=Serial.list()[32];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  myPort.write("1,1");
}


void keyPressed() {
  pickup=false;
  if (key == 'd' && moveY==0)
    directionX = 5;
  else if (key == 'a' && moveY==0)
    directionX = -5;
  else if (keyCode == 32) {
    attach = false;
    attach1 = false;
    if (moveY < height-300)
      directionY=3;
    claw.add = 0.01;
  }
}


void keyReleased() {
  directionY=-3;
  directionX=0;
  claw.add=-0.01;
}


void draw() {
  background(255);
  move.display();
  claw.display(moveX, 150+moveY); 
  fill(0);
  if (ellipseY<height-76 && !attach || ellipseX > width-150 && !attach)
    ellipseY+=gravity;
  if (ellipseY1<height-76 && !attach1 || ellipseX1 > width-150 && !attach1)
    ellipseY1+=gravity;
  image(img1,ellipseX, ellipseY, 100, 80);
  image(img2, ellipseX1, ellipseY1, 100,80);
  if (ellipseY >= height)
    ball1_out = false;
  if (ellipseY1 >= height)
    ball2_out = false;
  bounds.display();
  //image(img1,0,0,100,80);
  myPort.write(135*int(ball1_out)+","+135*int(!ball2_out)+"\n");
  println("ellipseY = "+ellipseY+" | moveY = "+moveY);//135*int(!ball1_out)+","+135*int(ball2_out)+"\n");
  println("ellipseX = "+ellipseX+" | moveX = "+moveX);
}

boundries:

class bounds{
 
void display(){
  rect(0, height-50, width-200, 50);
  rect(width-200, height-100, 50, 100); 
}
}

claw:

class Claw {
  float x=0;
  float y=0;
  float z=0;
  float add=0;
  Claw() {
  }

  void display(float x, float y) {
    fill(255);
    //ellipse(x+5, y+50, 100, 100);
    fill(0);
    rect(x, -1024+y, 10, 1024);
    pushMatrix();
    translate(x, y-5);
    rotate(z%TWO_PI);
    beginShape();
    vertex(0, 0);
    vertex(10, 0);
    vertex(-30, 50);
    vertex(0, 100);
    vertex(-50, 50);
    endShape();
    popMatrix();
    pushMatrix();
    translate(x+10, y-5);
    rotate(-z%TWO_PI);
    beginShape();
    vertex(0, 0);
    vertex(0-10, 0);
    vertex(30, 50);
    vertex(0, 100);
    vertex(50, 50);
    endShape();
    popMatrix();
    if (z<0.6 && add>0)
      z+=add;
    if (z>0 && add<0)
      z+=add;
  }
}

movement:

class movement {



  void display() {
    if (moveY<=height-301)
      moveY += directionY;
    moveX += directionX;
    if (moveY<0) {
      directionY=0;
      moveY=0;
    }
      if (moveY>height-300) {
    directionY=0;
    if (!time) {
      current = millis();
      time = true;
    }
    if (millis()-current>1500) {
      time=false;
      pickup=true;
    }
  }
  if (pickup) {

    if (moveY > 0) {
      moveY-=2;
      if (moveX >= ellipseX-25 && moveX<=ellipseX+25 && (ellipseY-moveY)<230) {
        attach = true;
        gravity=0;
        ellipseY = moveY+220;
      }
      else if (moveX >= ellipseX1-25 && moveX<=ellipseX1+25 && (ellipseY1-moveY)<230) {
        attach1 = true;
        gravity=0;
        ellipseY1 = moveY+220;
      }
    } else
      moveY=0;
  }
  gravity+=0.1;
  if (moveX>1280) {
    moveX = 0;
  }
  if (moveX<0) {
    moveX = 1280;
  }
  if (attach) {
    ellipseX=moveX+5;
    gravity=0;
    ellipseY=moveY+220;
  }
  else if (attach1) {
    ellipseX1=moveX+5;
    gravity=0;
    ellipseY1=moveY+220;
  }
  else
  gravity = 5;
  }
}

 

 

 

 

Three hardest parts of my final project: Coding, coding and coding…

My project is the claw arcade game. So you pull out a thing on the screen and an actual object falls behind the screen. So the hardest part is to make that claw game on computer. I have created a prototype of this game (but its too easy for now, will make it harder of course). The claw picks up and object within its range and holds it until the claw is open. Sounds basic, but it actually is hours and hours of coding 🙂 Here is the result (ignore Tori hating Kyle on the background):

Exercise

  • Make it interactive with the mouse, the further you move the mouse in one direction the more it explodes, or goes back to it’s original position
  • Take an image and draw it with rectangles or circles with the proper colors

Hope you all get the reference (watch video with sound) Here is what I got using this code:

PImage dog;
float increment =4;
float incrementZ = 500;

void setup(){
  size(700, 500, P3D);
  dog = loadImage("C:/Users/mab1312/desktop/dog.jpg");
  rectMode(CENTER);
}
void draw(){
  noStroke();
  background(0);
  rotateY(.2);
  for (int y = 0; y<dog.height; y+= increment){
    for (int x = 0; x<dog.width; x+= increment){
      dog.loadPixels();
      int i = (x+y*dog.width);
      color pix = dog.pixels[i];
      fill(pix);
      float d = map(brightness(pix),0,255,2,incrementZ/2);
      pushMatrix();
      translate(x,y,d);
      box(increment, increment, map(mouseX, 0, width, 0, incrementZ));
      popMatrix();
    }
  }
  dog.updatePixels();
  increment = map(mouseY,0,width,4,30);
}

Table tennis using physical controller and final project idea

Soooo, I have recreated my table tennis game but using a physical controller a.k.a. Potentiometer. It turned out to be better than the previous version since more than one key cannot be pressed at a time and the sensor transfer their values once a frame. I have encountered a problem though during coding. The thing is that when you output data from arduino to processing we use serial monitor. It transfers one line at a time, when i needed two. What Jack advised me to do is to put all the data in one line and separate using a comma (CSV file? really? how didnt I come up with that? Am I really a CS major?) Here is a short video:

And here is the code:

1)Code for arduino:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("0,0");
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available()>0){
    char inByte = Serial.read();
    int sensor = analogRead(A0);
    int sensor1 = analogRead(A1);
    delay(0);
    Serial.print(sensor);
    Serial.print(",");
    Serial.println(sensor1);
  }
}

2) Code for processing:

a. Main file:

import processing.serial.*;
Serial myPort;
ball ball;
padle padle1, padle2;
color fillVal = color(126);
float move = 0;
float velocity = 40;
float move1 = 0;
PFont f;
int padle3 = 0;
int padle4 = 0;



void setup() {
  rectMode(CENTER);
  size(1280, 640);
  f = createFont("Arial", 16, true);
  ball = new ball(5, 5, 20);
  padle1 = new padle(width*0.05, height/2, 10, height/4);
  padle2 = new padle(width*0.95, height/2, 10, height/4);
  printArray(Serial.list());
  String portname=Serial.list()[32];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
}

void keyPressed() {
  //println(keyCode);
  if (keyCode == 32) {
    ball.velocityX = 5;
    ball.ballY = height/2;
    ball.velocityY = 5;
    ball.ballX = width/2;
    ball.counter1 = 0;
    ball.counter2 = 0;
  }
  //if (keyCode == 83) {
  //  if (move<=200)
  //    move+= velocity;
  //}
  //if (keyCode == 87) {
  //  if (move>=-200)
  //    move -= velocity;
  //} 
  //if (keyCode == 38) {
  //  if (move1>=-200)
  //    move1-= velocity;
  //}
  //if (keyCode == 40) {
  //  if (move1<=200)
  //    move1+= velocity;
  //}
}
void draw() {
  background(0);
  textFont(f, 32);
  fill(255);
  text(ball.counter1, width*0.33, height*0.1);
  text(ball.counter2, width*0.66, height*0.1);
  textFont(f, 14);
  text("'SPACE' to reset score", 5, 14);
  text("'W' and 'S' to move left paddle", 5, height-7);
  text("'UP' and 'DOWN' to move right paddle", width*0.78, height-7);
  drawLine();  
  ball.run(padle3-height/8, padle3+height/8, padle4-height/8, padle4+height/8);
  padle1.display(width*0.05, padle3, 10, height/4);
  padle2.display(width*0.95, padle4, 10, height/4);
}


void drawLine() {
  stroke(255);
  strokeWeight(4);
  fill(0);
  line(width/2, 0, width/2, height);
}
void serialEvent(Serial myPort) {
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  if (s!=null) {
    println(s);
    String[] s1 = split(s, ',');
    padle3 = (int)map(int(s1[0]),0,1023,0,height);
    padle4 = (int)map(int(s1[1]),0,1023,0,height);
    
    println(s1[0]);
    println(s1[1]);
  }
  
  myPort.write('0');
}

b. Ball class:

class ball {
  float velocityX;
  float velocityY;
  int size;
  float ballX = width/2;
  float ballY = height/2;
  color fillVal = color(255, 0, 0);
  int counter1 = 0;
  int counter2 = 0;

  ball(float _velocityX, float _velocityY, int _size) {
    velocityX = _velocityX;
    velocityY = _velocityY;
    size = _size;
  }
  void update(float a, float b, float c, float d) {
    //println("velocityX = "+velocityX); 
    if (ballX >= width) {
      ballX = width/2;
      ballY = height/2;
      velocityX = -5;
      velocityY = 5;
      counter1+=1;
    }
    if (ballX <= 0 ) {
      ballX = width/2;
      ballY = height/2;
      velocityX = 5;
      velocityY = 5;
      counter2+=1;
    }
    if (ballX >= width*0.94 && ballX <= width*0.96 && ballY >= c && ballY <=d ||  ballX >= width*0.04 && ballX <= width*0.06 && ballY >= a && ballY <=b) {
      velocityX*=1.1;
      velocityY = random(-15,15);
      velocityX = -velocityX;
    }
    ballX += velocityX;
    if (ballY >= height || ballY <= 0) {
      velocityY = -velocityY;
    }
    ballY += velocityY;
  }


  void display() {
    //ellipse(width/2, height/2, size, size);
    fill(fillVal);
    noStroke();

    ellipse(ballX, ballY, size, size);
  }
  void run(float a, float b, float c, float d) {
    update(a, b, c, d);
    display();
  }
}

c. Padle class:

class padle {
  float x;
  float y;
  float w;
  float h;
  color fillVal = color(0, 255, 0);
  padle(float _x, float _y, float _w, float _h) {
    x = _x;
    y = _y;
    w = _w;
    h = _h;

  }
  void update() {
  }
  void display(float x, float y, float w, float h) {
    fill(fillVal);
    rect(x, y, w, h, 5);
  }
  void run() {
    update();
    display(x,y,w,h);
  }
}

 

 

Final project idea:


My idea is to make a claw game where you pull out toys. But all of that will be on the screen except the controller. After that an actual toy that you have pulled out in the game falls from behind the screen. The idea is to make an unexpected result. The user won’t have an idea that the toy from the computer will fall out from behind the computer. Other than that I have some ideas like making a game in processing

and using a physical controller (sensors, buttons), but Aaron didn’t really liked this idea 🙁

Generative text

I really liked the idea of the text making a word out of random letters in the air. I tried to make a similar thing, but the word is always the same 😀

When the program starts the letters float on the screen. As soon as the mouse is pressed, they make a word in the center of the screen. I made sure that the letters won’t get out of bounds.

Here is the code:

String word = "hello world";
letters[] l1;

void setup() {
  size(640, 640);

  l1 = new letters[word.length()];
  for (int i =0; i<word.length(); i++) {
    l1[i] = new letters(word.charAt(i), width/3 +i*25, height/2);
  }
  //String word = "Hello";
}
void draw() {
  background(255);
  for (int i =0; i<word.length(); i++) {
    if (mousePressed) {
      l1[i].print();
      l1[i].returnBack();
    } else {
      l1[i].print();
    }
  }
}
class letters {
  char symbol;
  float x;
  float y;
  char c;
  float randX, randY;
  float originx, originy;
  letters(char _c, float _x, float _y) {
    x = _x;
    y = _y;
    c = _c;
    originx = x;
    originy = y;
    randX = random(-3, 3);
    randY = random(-3, 3);
  }
  void print() {
    fill(0);
    textSize(36);
    textAlign(CENTER);
    text(c, x, y);
    x += randX;
    if (x>= width || x <=0) {
      randX = -randX;
    }
    y += randY;
    if (y>= height || y <=0) {
      randY = -randY;
    }
  }
  void returnBack(){
    float deltaX = (originx - x)/3;
    float deltaY = (originy - y)/3;
    x += deltaX;
    y += deltaY;
  }
}

And here is a video:

Reading response. April 22nd

I’ll start of with a quote: “[Hal Varian] keep saying that the sexy job in the next ten years will be statisticians. And I’m not kidding.”. Hal Varian is Google’s chief economist. He may be right since the data in the world is growing exponentially which make the good job to take this data in account and keep track of it. It doesn’t mean that the person will just be keeping track of the size of the data, it also means that he will be working with this data, which can be photos, statistics, bank information and etc. I personally have never used Waze, since we have an alternative back in Russia (2GIS). I don’t personally know how it work (could be that they are just taking an existing database of traffic and uploads it to the app.

 

Game in processing by Max

So I have decided to make a ping pong game in processing. First of all it is a multiplayer game for two people. I have made two classes one of them is the paddle and the other one is the ball. The paddles are controlled by either “w” and “s” or “up” and “down”. There is a score count and a reset button.
Here is the code:
main file:

ball ball;
padle padle1, padle2;
color fillVal = color(126);
float move = 0;
float velocity = 40;
float move1 = 0;
PFont f;



void setup() {
  rectMode(CENTER);
  size(1280, 640);
  f = createFont("Arial", 16, true);
  ball = new ball(5, 5, 20);
  padle1 = new padle(width*0.05, height/2, 10, height/4);
  padle2 = new padle(width*0.95, height/2, 10, height/4);
}

void keyPressed() {
  println(keyCode);
  if (keyCode == 32) {
    ball.velocityX = 5;
    ball.ballY = height/2;
    ball.velocityY = 5;
    ball.ballX = width/2;
    ball.counter1 = 0;
    ball.counter2 = 0;
  }
  if (keyCode == 83) {
    if (move<=200)
      move+= velocity;
  }
  if (keyCode == 87) {
    if (move>=-200)
      move -= velocity;
  } 
  if (keyCode == 38) {
    if (move1>=-200)
      move1-= velocity;
  }
  if (keyCode == 40) {
    if (move1<=200)
      move1+= velocity;
  }
}
void draw() {
  background(0);
  textFont(f, 32);
  fill(255);
  text(ball.counter1, width*0.33, height*0.1);
  text(ball.counter2, width*0.66, height*0.1);
  textFont(f, 14);
  text("'SPACE' to reset score", 5, 14);
  text("'W' and 'S' to move left paddle", 5, height-7);
  text("'UP' and 'DOWN' to move right paddle", width*0.78, height-7);
  drawLine();  
  ball.run(height/2+move-height/8, height/2+move+height/8, height/2+move1-height/8, height/2+move1+height/8);
  padle1.display(width*0.05, height/2+move, 10, height/4);
  padle2.display(width*0.95, height/2+move1, 10, height/4);
}


void drawLine() {
  stroke(255);
  strokeWeight(4);
  fill(0);
  line(width/2, 0, width/2, height);
}

ball class:

class ball {
  float velocityX;
  float velocityY;
  int size;
  float ballX = width/2;
  float ballY = height/2;
  color fillVal = color(255, 0, 0);
  int counter1 = 0;
  int counter2 = 0;

  ball(float _velocityX, float _velocityY, int _size) {
    velocityX = _velocityX;
    velocityY = _velocityY;
    size = _size;
  }
  void update(float a, float b, float c, float d) {
    //println("velocityX = "+velocityX); 
    if (ballX >= width) {
      ballX = width/2;
      ballY = height/2;
      velocityX = -5;
      velocityY = 5;
      counter1+=1;
    }
    if (ballX <= 0 ) {
      ballX = width/2;
      ballY = height/2;
      velocityX = 5;
      velocityY = 5;
      counter2+=1;
    }
    if (ballX >= width*0.94 && ballX <= width*0.96 && ballY >= c && ballY <=d ||  ballX >= width*0.04 && ballX <= width*0.06 && ballY >= a && ballY <=b) {
      velocityX*=1.1;
      velocityY = random(-15,15);
      velocityX = -velocityX;
    }
    ballX += velocityX;
    if (ballY >= height || ballY <= 0) {
      velocityY = -velocityY;
    }
    ballY += velocityY;
  }


  void display() {
    //ellipse(width/2, height/2, size, size);
    fill(fillVal);
    noStroke();

    ellipse(ballX, ballY, size, size);
  }
  void run(float a, float b, float c, float d) {
    update(a, b, c, d);
    display();
  }
}

paddle class:

class padle {
  float x;
  float y;
  float w;
  float h;
  color fillVal = color(0, 255, 0);
  padle(float _x, float _y, float _w, float _h) {
    x = _x;
    y = _y;
    w = _w;
    h = _h;

  }
  void update() {
  }
  void display(float x, float y, float w, float h) {
    fill(fillVal);
    rect(x, y, w, h, 5);
  }
  void run() {
    update();
    display(x,y,w,h);
  }
}

 

 

Recreation of the art

I really like squares. Here are some squares:

int square_size = 100;

void setup () 
{
  size (800, 800);
  background(255);
}

void draw () 
{
  noLoop();
  background(255);
  draw_squares();
}
void draw_squares()
{
    for (int i=0; i < width; i+=square_size) 
  {
    for (int j=0; j< height; j+= square_size)
    {
      strokeWeight(8);
      float randomizer = random(5,15);
      rect(i, j, square_size, square_size);
      for (int k = 0; k<random(3,6); k++)
      {
        strokeWeight(2);
        
        rect(i+(k*randomizer), j+(k*randomizer), square_size-(k*20), square_size-(k*20));
      }
    }
  }
}

Here is what I’ve got as a result:

Response to chance operations

The way the make “random” pictures is just incredible. I would really love to discuss more in detail how they created these (3:46 time stamp) pictures. I really love the way they had some sort of variables which can be easily changed. They can choose the shape and the behavior of the shape. Isn’t that incredible? Using these variables that can easily be changed you can create a big load of different pictures/images. All of them are basically created “with a roll of a die” by choosing random variables. More what I like about the video is the “Chance of code” section (22:22 timestamp). There he talks about the history of random pictures using code. An example is the image at 25:27. He says that it is one of the first random pictures generated by a computer using variables. The most interesting part though was how different patterns were drawn in a commander 64. It is really amazing. What amazes me is the way simple characters can create such patterns. Everything we see in our life can have a nice and pretty patterns 🙂

Reading Responses.

Attractive things work better
    Norman discusses the aesthetics of things and the nicer it is the better it works. The author is very right about the that attractive things work better, but not literally, of course. It works better to present it, to sell but most of the times (from my experience personally) aesthetics of the item can make the item not work properly (i.e. the pressure pads from my midterm project attached to the wooden brick broke fast). But Norman is definitely right about that the aesthetics of an object can provide easy usage. For example a simple game pad is and aesthetically designed object. You can just use buttons not attached together and that will be a mess and hard to use.