Assignment 9

I further developed the tickle project that I did for last week by making ‘Yoon Hee’ run away from the hands that are trying to tickle it. The further from the centre of the word, the faster it moves away.

I used two potentiometers as the controllers to replace the cursor and change the x, y positions of the hands.

Here is the code for Arduino:

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

void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();

int sensor = analogRead(A0);
delay(0);
int sensor2 = analogRead(A1);
delay(0);
Serial.print(sensor);
Serial.print(',');
Serial.println(sensor2);
}
}

 

Here is the code for Processing:

import processing.serial.*;

Serial myPort;
PFont f;
String word = "Yoon Hee";
PImage img;

float x = 190;
float y = 180;
float speedX, speedY, xAccel, yAccel;

void setup() {
size(640, 360);
printArray(Serial.list());
String portName = Serial.list()[3];
println(portName);
myPort = new Serial (this, portName, 9600);
myPort.clear();
myPort.bufferUntil('\n');
background(255);
f = createFont("Monaco", 50);
textFont(f, 50);
noStroke();
speedX = speedY = xAccel = yAccel= 0;
img = loadImage("hand.png");
}

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

image(img, mouseX-25, mouseY-10, 50, 50);

float textwidth = textWidth(word);
float centerX, centerY;
centerX = x + textwidth/2;
centerY = y - 35/2;
float dirX = centerX - mouseX;
float dirY = centerY - mouseY;

boolean inside =false;
if ((mouseX >= x && mouseX <= x+textwidth) &&
(mouseY >= y-35 && mouseY <= y)) {
inside=true;
}

PVector distance = new PVector(dirX, dirY);
float d = distance.mag();

println(distance +" norm");
if (d<textwidth*.75) {
distance.normalize();
xAccel = dirX*.005*(1/distance.mag());
yAccel = dirY*.005*(1/distance.mag());
}

boolean tickle=false;
if (mousePressed == true && inside == true) {
tickle=true;
xAccel=speedX=0;
yAccel=speedY=0;
}

for (int i=0; i<word.length(); i++) {
char c = word.charAt(i);

float letterX=x+textWidth(c)*i;
float tickleX = 0;
float tickleY = 0;
if (tickle) {
//tickleX=noise();
tickleY= noise((.5*frameCount+i)*.5)*30-15; //sin(frameCount*0.2+(i+1))*5;
}
text(c, letterX+tickleX, y+tickleY);
}

//text(word, x, y);
x += speedX;//random(-2, 2);
y += speedY;//random(-2, 2);
speedX *= .8;
speedY *= .8;

speedX += xAccel;
speedY += yAccel;
xAccel = yAccel= 0;

//bounce off the edges
if (y<35)
speedY*=-1;
if (y>height)
speedY*=-1;
if (x<0)
speedX*=-1;
if (x>width-textwidth)
speedX*=-1;
}

void serialEvent(Serial myPort) {
String x = myPort.readStringUntil('\n');
x = trim(x);
if (x!= null) {
int values[] = int(split(x, ','));
mouseX = (int)map(values[0], 0, 1023, 0, width);
mouseY = (int)map(values[1], 0, 1023, 0, height);
}

myPort.write('0');
}

 

What Computing Means to Me

This may sound kind of sad, but my computers (iPhone and MacBook) are my best friends. Wherever I go, my computers are always by my side. They are with me 24/7, through the happiest and the most depressing days. No matter how much I abuse them, they will never forsake me. They’ve played a crucial role in enabling almost everything I’ve ever done. This is why I’ve always been willing to spend a little extra to purchase the best version of my “best friends”.

Many of us born in the late 1990s have never known what life was like without computers. We’ve taken for granted mankind’s most monumental invention and all the conveniences that come with it. Computers are the greatest enablers in the world, facilitating for the creation of almost everything ranging from art to war machines. Intro to IM is the first time that I’ve been able to interact with the secret world of basic physical computing. To say that it’s been eye-opening would be an understatement.

Computing and Me: My story in Poem form

Computing and Me:

Let me tell you a bit about this,

so that you can see,

what it is that computing means to me.

My first look into computing came when I saw coding.

I enjoyed it since then, let me tell you so you see,

coding to me became an expression to be free.

It became another medium for me to explore art,

to use colors I’d never held in my hand,

to explore design, my choices, and if need be lay barren my heart for the world to see.

This passion was unplanned,

and I simply hoped I could withstand  so I could understand,

how this would be a part of my future.

It is important to note that I did struggle to stay afloat,

but I realized that came from the type of coding I did.

With the visuals and graphics I felt I could gloat

but the math and logic were harder for me to grasp.

But this was only the first part of my computing view,

as next came the physical, you know, part two.

Working with sensors, motors and my Arduino

I was able to create a physical version of my art.

Another part to my art which served to jumpstart

yet another passion to use to express myself.

Don’t get me wrong,

I realize I have a long way to go,

but computing means to me the things I want to be,

because I want to show one day I can be a pro,

and use it not only for expression

but to maybe leave an impression and work in succession

to design something beautiful.

Computing

I’ve been interested in computers for as long as I remember. However, I was stuck in the software side of things, I never actually worked with hardware at all. I did watch a lot of videos on DIY Raspberry Pi projects but I didn’t exactly do anything, I was entertained watching other people’s projects and felt like it wasn’t in my realm to do.

Now however, it is in my realm. It wasn’t until this class that I actually started tinkering with hardware. I had zero knowledge about hardware so there was a steep learning curve at first but then when I got the hang of it, it became really fun making projects that interest me.

I feel like I have a better view on computing now that I know the hardware side of things (to an extent) Knowing how to tinker and make cool physical projects that communicate with the computer just gives me and everyone in this class, power. The power to use our creativity to make useful things, or stupid pet tricks.

Controller Project: RGB Game

In the world of graphic design . . .

Designers have to constantly work with color values. While it is easy to simply google the R,G,B value of a color, it is a nice skill to recognize what values will output what colors.  I thought this would be a fun concept to explore visually, and so the RGB GAME controller emerged.

For this project, there is an input of 3 numbers, ranging from 0 – 255 as the Red, Green and Blue values. (Meaning 0,0,0 will be black and 255,255,255 will be white.)  I thought it would be a fun way for people to practice visually looking at colors and relating them to a numerical value (such as that used in coding.)

From there, the numbers are inputed through 3 knobs on the box/controller shown below.

(The knobs correspond to the color they edit. )
Inside look at the box as it was being wired and built.

When the game actually begins, the player must turn the knobs in order to try their best to match the color of a randomly drawn rectangle on the screen.  The values of the r,g,b values the user is altering are shown on the screen, along with a timer that counts down from 25 seconds.

Originally, I wanted the randomized rectangle that was shown on the screen to disappear after 5 seconds, and the user still had to match the new rectangle from memory. This feature was discarded after some user testing that determined this would make the game a bit too difficult.

Here is a final product video.

How the code works:

There is a range of numbers ( + or – 25) in which the code is checking to see if the random rectangle matches. There is also the timer which will display a loss if the colors are not matched after 25 seconds; a win will be shown immediately.

Here is the code:

import processing.serial.*;
PFont font; 
Serial myPort;
String[] messages;
int r;
int g;
int b;
boolean complete = false;
int begin; 
int duration = 25;
int time = 25;

int baseRectR = floor(random(0, 255));
int baseRectG = floor(random(0, 255));
int baseRectB = floor(random(0, 255));

void setup () {
  //println(Serial.list());
  font = createFont("Arial", 40); 
  textFont(font);

  begin = millis(); 
  printArray(Serial.list());
  String portname=Serial.list()[3];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  fullScreen();
}
void draw() {
  background(255);
  noStroke();
  String vals =r + "  " + g + "  " + b; 
  String valsSet = "This rect was: " + baseRectR + "  " + baseRectG + "  " + baseRectB; 
  String valYours = "Your rect was: " + r + "  " + g + "  " + b; 
//checks if the colors match within a range of 25
  if ( (r-baseRectR <= 25) && (r-baseRectR >= -25) && (g-baseRectG <= 25) && (g-baseRectG >= -25) && (b-baseRectB <= 25) && (b-baseRectB >= -25))
  {
    complete = true;
    font = createFont("Arial", 75); 
    textFont(font);
    fill(0);
    text("YOU HAVE WON :)", 400, height/2);
    font = createFont("Arial", 40); 
    textFont(font);
    text(valsSet, 800, 800);
    text(valYours, 250, 800);
    noLoop();
  }
// if colors do not match after the timer is up == lose
  if (time <=0 && complete == false)
  {
    vals = null;
    fill(0);
    text("SORRY HOMIE, BETTER LUCK NEXT TIME :(", 250, height/2);
    font = createFont("Arial", 40); 
    textFont(font);
    complete = true;
    text(valsSet, 800, 800);
    text(valYours, 250, 800);
    noLoop();
  }

//displays end message
  fill(0);
  if (complete==false) {
    text(vals, 250, 800);
  }

  if (complete == false) {
    fill(baseRectR, baseRectG, baseRectB);
    rect((1.8*width)/3, height/3, 400, 400);
  }
  fill(r, g, b);
// sets timer
  if ((time > 0) && complete == false) { 
    rect(width/9, height/3, 400, 400);
    fill(0);
    time = duration - (millis() - begin)/1000;
    text(time, width/2.07, height/2);
  }
}
//reads the input
void serialEvent(Serial porty)
{
  String message = porty.readStringUntil('\n');
  if (message != null) {
    message = trim(message);
    messages = message.split(",");
    //println(message);
    r = int(messages[0]);
    g = int(messages[1]);
    b = int(messages[2]);
    //println(messages[0], messages[1], messages[2]);
  }
}

Overall, I’m super happy with how this turned out! Even the box for the controller ended up looking really cool.

Air Music Player

I took my previous project where I visualized music through the microphone and reversed it. I wanted to in some form visualize the music with my hands and play it on the computer. I had to make some big changes to the code as I hadn’t generalized the classes enough in my previous project which is something I have to make sure I do next time. I used a library called Minim as the processing sound library didn’t allow pausing which was a vital feature in my project.

I selected Fur Elise from Beethoven and the Wonder Woman soundtrack for the two songs because they are so drastic in genre, tone and the way it sounds that it almost feels like a remix mashup in a way.

Arduino Code

int lightLevel;

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

  int knob = analogRead(A0);
  delay(1);
  lightLevel = analogRead(A1);
  delay(1);
  Serial.print(lightLevel);
  Serial.print(",");
  Serial.println(knob);
  

}

 

Processing Code

import processing.serial.*;
import processing.sound.*;
import ddf.minim.*;
Minim       minim;
Minim       minim2;
Minim       minim3;
AudioPlayer song2;
AudioPlayer song3;
AudioPlayer song4;
SoundFile song;
Amplitude amp2;
Serial myPort;
AudioIn in2;
CircleThing mainCircle;
Snow snowfall;
float ears= 0;
boolean movable=false;
PImage bg,nyu;
boolean logoDisplay=false;
float lightValue;
float knobValue;
float highLight=100;
float lowLight=0;
float knobScaling=1.5;
class CircleThing {
  public int circleX, circleY,defColor;
  public float prevRad=0;
  CircleThing(int cX, int cY,int defaultColor) {
    circleX=cX;
    circleY=cY;
    defColor=defaultColor;
  }
  void draw(float cX, float cY, float soundVal,int scaling,PImage nyuImage,boolean displayImage) {
  
    fill(map(soundVal,0,100,0,255)-100);
    strokeWeight(10);
    float radi=200+(100-soundVal)*knobScaling;
    //float radi =(200+soundVal*scaling);
    ellipse(cX, cY,radi, radi);
    //line(0,0,radi/2,radi/2);
    imageMode(CENTER);
    //rotate(45);
if(displayImage) {
    pushMatrix();
imageMode(CENTER);
translate(cX,cY);
rotate(-PI/8);
image(nyuImage,0,0);
popMatrix();
}

String s = "Made by Romeno Wenogk Fernando. wenogk@nyu.edu";
fill(255);
textSize(16);
text(s, cX+500, cY, 200, 150);
prevRad=200+soundVal*scaling;
  }
}

class Particle {

  float x;          // adds x position property
  float y;          // adds y position property
  float xVel;       // adds xvel property
  float yVel;       // adds yvel property
  float partsize;   // adds a size property


  //Constructor = function// float says where it is xpos/ypos
  Particle(float xpos, float ypos) {
    // assigning the values
    x = xpos = random (0,600);
    y = ypos;
    xVel = random (-2, 2);   // random,(the length of the random)
    yVel = random (0, 5);    // controls the speed that the snow falls
    partsize = random (5, 10);
  }
  
}

class Snow {
Particle[] particles = new Particle[0];
int maxParticles =100;

Snow() {
}
void setMax(int val) {
maxParticles=val;
}
void draw(float ears2) {
  float ears =100- ears2;
particles = (Particle[]) append(particles, new Particle(300, 0));
  if (particles.length>maxParticles) {
    particles = (Particle[]) subset(particles, 1);
  }
  for (int i=0; i<particles.length; i++) {
      particles[i].partsize *=0.975;  //make the snow stay reduce size
      particles[i].x += particles[i].xVel;
      particles[i].y += particles[i].yVel;
     if(ears>30) {
      particles[i].yVel +=0.2;   
     } else if(ears>50) {
       particles[i].yVel +=0.3;
     }
     else if(ears>70) {
       particles[i].yVel +=0.4;
     } else if(ears>90) {
       particles[i].yVel +=0.6;
     } else {
       particles[i].yVel-=0.1; //reverse gravity
     }
    ellipse(particles[i].x, particles[i].y, particles[i].partsize, particles[i].partsize);
  }
}
}

void setup() {
  size(640, 440);
  background(90);
  amp2 = new Amplitude(this);
  in2 = new AudioIn(this, 0);
  in2.start();
  amp2.input(in2);  
  mainCircle= new CircleThing(width/2,height/2,45);
  snowfall= new Snow();
  bg = loadImage("bg.jpg");
  bg.resize(width,height);
  nyu=loadImage("nyu.png");
  nyu.resize(int(nyu.width*0.5),int(nyu.height*0.5));
  printArray(Serial.list());
String portname=Serial.list()[6];
println(portname);
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
 //song = new SoundFile(this, "ww.mp3");

  // Loop the sound forever
  // (well, at least until stop() is called)
  //song.loop();
  
  minim = new Minim(this);
  minim2 = new Minim(this);
  minim3 = new Minim(this);
  song2 = minim.loadFile("ww.mp3", 1024);
  song3 = minim2.loadFile("bee.mp3", 1024);
  song4 = minim2.loadFile("fetty.mp3", 1024);
  song2.play();
  song3.play();
  song4.play();
}      

void draw() {
  background(bg);
  //ears=amp2.analyze();
  ears=map(lightValue,lowLight,highLight,0,100);
  if((100-ears)>45) {
  song4.play();
  song2.pause();
  song3.pause();
  }
  else if((100-ears)>25) {
  song3.play();
  song2.pause();
  song4.pause();
  }  else if((100-ears)>10) {
  song3.pause();
  song2.play();
  song4.pause();
  } else {
  song2.pause();
  song3.pause();
  song4.pause();
  }
 
  println(100-ears);
   stroke(255); 
  strokeWeight(1);
  //println(ears);
  fill(255);
  snowfall.draw(ears);
  stroke(75); 
  float xpos,ypos;
  if(!movable) { 
    xpos=lerp(width/2,mouseX,0.01);
    ypos=lerp(height/2,mouseY,0.01);
  } else {
  //mainCircle.draw(mouseX,mouseY,ears,290,nyu,logoDisplay); 
   xpos=lerp(mouseX,width/2,0.01);
    ypos=lerp(mouseY,height/2,0.01);
  }
  mainCircle.draw(xpos,ypos,ears,290,nyu,logoDisplay);
 
highLight();
knobScaling=map(knobValue,0,255,0,1);
}

void mousePressed() {
movable=!movable;
}

void keyPressed() {
logoDisplay=!logoDisplay;

}

void serialEvent(Serial myPort){
String s=myPort.readStringUntil('\n');
s=trim(s);
//println(s);
if (s!=null){
int values[]=int(split(s,','));
lightValue=values[0];
knobValue=values[1];
}
}

void highLight() {
if(lightValue>highLight) {
highLight=lightValue;
}
if(lightValue<lowLight) {
lowLight=lightValue;
}
}

 

 

Dice-roller for Monopoly

For this week’s assignment I wanted to make a dice-roller for monopoly – As in, an object that you shake as if you’re shaking dice and that triggers the dice roll in the monopoly I had previously made in processing. This proved to be challenging.

I wanted to make the roller as compact and sturdy as possible, since it will be subject to shaking and I didn’t want anything to come lose, so I started with this circuit:

I used an arduino maker1000 because of it’s small size. The shaking was detected using a tilt sensor. Everything is soldered on in one unit so it was easy to hold and shake and everything would still be stable. However, no matter how hard I tried, the maker1000 would not communicate with processing. So I switched to a redboard.

Here’s the video of how it works:

The code:

Arduino:

const int tiltPin = 6;
const int ledPin = 10;

int tiltState;             // the current reading from the input pin
int lastTiltState = LOW;   // the previous reading from the input pin
int counter = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 20;

void setup() {
  // put your setup code here, to run once:
  pinMode(tiltPin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  digitalWrite(ledPin, HIGH);
  Serial.write(0);
}

void loop() {
  if (Serial.available() > 0) {
    int inByte = Serial.read();

    if (counter <= 20) {
      digitalWrite(ledPin, HIGH);
      Serial.write(0);
    } else {
      counter = 0;
      digitalWrite(ledPin, LOW);
      Serial.write(1);
      delay(2000);

    }
    int reading = digitalRead(tiltPin);
    if (reading != lastTiltState) {
      lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != tiltState) {
        tiltState = reading;
        counter++;
      }
    }
    //  Serial.print(reading);
    //  Serial.print(" || ");
    //  Serial.println(counter);
    lastTiltState = reading;
  }
  // put your main code here, to run repeatedly:


}

Processing:

import processing.serial.*;
//0 name, 1 type, 2 owner, 3 cost, 4 rent, 5 xcoordinate, 6 ycoordinate
// types: 0 = income tax, 1 = normal, 2 = railroad, 3 = utilities, 4 = community chest and chance, 5 = jail and free parking, 6 = go,7 = supertax
String[][] places = {
  {"Go", "6", "Bank", " ", "-200", "750", "750"}, // 0
  {"Old kent road", "1", "Bank", "60", "6", "660", "750"}, // 1
  {"Community chest", "4", "Bank", " ", "0", "595", "750"}, // 2
  {"White chapel road", "1", "Bank", "60", "6", "530", "750"}, //3
  {"Income tax", "0", "Bank", " ", "200", "465", "750"}, // 4
  {"Kings cross station", "2", "Bank", "200", "25", "400", "750"}, // 5
  {"The angel islington", "1", "Bank", "100", "10", "335", "750"}, // 6
  {"Chance", "4", "Bank", " ", "0", "270", "750"}, // 7
  {"Euston Road", "1", "Bank", "100", "10", "205", "750"}, // 8
  {"Pentonville Road", "1", "Bank", "120", "12", "140", "750"}, // 9
  {"Jail", "5", "Bank", " ", "0", "50", "750"}, // 10
  {"Pall Mall", "1", "Bank", "140", "14", "50", "660"}, // 11
  {"Electric Company", "3", "Bank", "150", "15", "50", "595"}, // 12
  {"Whitehall", "1", "Bank", "140", "14", "50", "530"}, // 13
  {"Northumberland Avenue", "1", "Bank", "160", "16", "50", "465"}, // 14
  {"Marylebone station", "2", "Bank", "200", "25", "50", "400"}, // 15
  {"Bow street", "1", "Bank", "180", "18", "50", "335"}, // 16
  {"Community chest", "4", "Bank", " ", "0", "50", "270"}, // 17
  {"Marlborough street", "1", "Bank", "180", "18", "50", "205"}, // 18
  {"Vine street", "1", "Bank", "200", "20", "50", "130"}, // 19
  {"Free Parking", "5", "Bank", " ", "0", "50", "50"}, // 20
  {"Strand", "1", "Bank", "220", "22", "140", "50"}, // 21
  {"chance", "4", "Bank", " ", "0", "205", "50"}, // 22
  {"Fleet street", "1", "Bank", "220", "22", "270", "50"}, // 23
  {"Trafalgar square", "1", "Bank", "240", "24", "335", "50"}, // 24
  {"Fenchurch st station", "2", "Bank", "200", "25", "400", "50"}, // 25
  {"Leicester square", "1", "Bank", "260", "26", "465", "50"}, // 26
  {"Coventry street", "1", "Bank", "260", "26", "530", "50"}, // 27
  {"Waterworks", "3", "Bank", "150", "15", "595", "50"}, // 28
  {"Piccadilly", "1", "Bank", "280", "28", "660", "50"}, // 29
  {"Jail", "5", "Bank", " ", "0", "750", "50"}, // 30
  {"Regent street", "1", "Bank", "300", "30", "750", "130"}, // 31
  {"Oxford street", "1", "Bank", "300", "30", "750", "205"}, // 32
  {"Community chest", "4", "Bank", " ", "0", "750", "270"}, // 33
  {"Bond street", "1", "Bank", "320", "32", "750", "335"}, // 32
  {"Marylebone station", "2", "Bank", "200", "25", "750", "400"}, // 15
  {"Chance", "4", "Bank", " ", "0", "750", "465"}, // 33
  {"Park lane", "1", "Bank", "350", "32", "750", "530"}, // 32
  {"Supertax", "7", "Bank", " ", "200", "750", "595"}, 
  {"Mayfair", "1", "Bank", "400", "40", "750", "660"}, 

};

int toRoll;
int prevToRoll;
boolean allowRoll = true;
int circlesize = 10;
int turn = 0;
int diceroll;
PImage bg;
boolean first = true;
boolean proceed = false;

// colors: red or blue
Player p1 = new Player("red", int(places[0][5]), int(places[0][6]), 10);
Player p2 = new Player("blue", int(places[0][5]), int(places[0][6]), -10);
Serial myPort;


void setup() {
  printArray(Serial.list());
  String portname=Serial.list()[2];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  //myPort.clear();
  //myPort.bufferUntil('\n');


  first = false;
  size(800, 800);
  bg = loadImage("board.jpg");
  background(0);
  fill(255);
  textSize(16);
  text("Welcome to mehnopoly. It's almost monopoly, but seriously lower your expectations.", 20, 50);
  text("The game is for two players. or You can play against yourself if you can't find friends. I dont judge.", 20, 100);
  text("You win by making your opponent go bankrupt. Go nuts!", 20, 150);
  text("Press S to start the game", 20, 200);
  textSize(12);
  text("Fun Fact: Monopoly was originally created as a statement against capitalism.", 20, 250);
}

void draw() {
  if (proceed==true ){
    refresh();
    allowRoll = false;
    diceroll = rollDice();
    handleRoll();
    proceed=false;
  }
  if (first) {
    textSize(24);
    fill(255, 127, 0);
    text("Player 1 has "+p1.money+" left", 150, 200);
    text("Player 2 has "+p2.money+" left", 150, 250);
    text("Player 1's turn", 150, 300);
    text("Press R to roll dice", 150, 350);
  }
}
int keycounter = 0;




class Player {
  int money, xpos, ypos, rails, utilities, offset, placecount, propertyamount;
  int[] properties = new int[50];
  String col;
  Player (String n, int xp, int yp, int off) {
    col = n;
    placecount = 0;
    money = 1500;
    offset = off;
    xpos = xp;
    ypos = yp;
    rails = 0;
    utilities = 0;
    propertyamount = 0;
  }

  void display() {
    strokeWeight(2);
    stroke(255, 255, 255);
    if (col == "red")fill(255, 0, 0);
    if (col == "blue")fill(0, 0, 255);
    ellipse(xpos+offset, ypos, circlesize, circlesize);
  }
  void updatePos() {
    xpos = int(places[placecount][5]);
    ypos = int(places[placecount][6]);
  }
}

int rollDice() {
  return round(random(2, 12));
  //return 7;
}

void checkLanded(Player x) {
  textSize(24);
  fill(255, 127, 0);
  text("You rolled "+diceroll+" and landed on: "+places[x.placecount][0], 150, 200);
  if (int(places[x.placecount][1]) == 5 || int(places[x.placecount][1]) == 6)text("Press E to end turn", 150, 250);
  // if income tax
  if (int(places[x.placecount][1]) == 0) {
    fill(255, 127, 0);
    text("You pay 200 for income tax", 150, 250);
    x.money-=200;
    text("You now have: "+str(x.money)+" left", 150, 300);
    text("Press E to end turn", 150, 350);

    // if purchasable
  } else if (int(places[x.placecount][1]) == 1 || int(places[x.placecount][1]) == 2 || int(places[x.placecount][1]) == 3) {
    // if owner is bank
    if (places[x.placecount][2] == "Bank") {
      fill(255, 127, 0);
      text("Property isn't owned, what would you like to do?", 150, 250);
      text("Press B to buy for "+places[x.placecount][3]+" or press E to end turn", 150, 300);
      // if owner is not bank
    } else {
      // if it's a normal purchasable
      if (int(places[x.placecount][1]) == 1) {
        if (turn == 0 && places[x.placecount][2] == "Player2")handleRent(p1, p2, int(places[x.placecount][4]));
        if (turn == 1 && places[x.placecount][2] == "Player1")handleRent(p2, p1, int(places[x.placecount][4]));
        // if railroad
      } else if (int(places[x.placecount][1]) == 2) {
        int rent;
        if (turn == 1 && places[x.placecount][2] == "Player1") {
          rent = checkRailRent(p1);
          handleRent(p2, p1, rent);
        } else if (turn == 0 && places[x.placecount][2] == "Player2") {
          rent = checkRailRent(p2);
          handleRent(p1, p2, rent);
        }
        // if utilities
      } else if (int(places[x.placecount][1]) == 3) {
        int rent = 0;
        if (turn == 0 && places[x.placecount][2] == "Player2") {
          if (p2.utilities == 1)rent= 7*diceroll;
          if (p2.utilities == 2)rent= 15*diceroll;
          handleRent(p1, p2, rent);
        } else if (turn == 1 && places[x.placecount][2] == "Player1") {
          if (p1.utilities == 1)rent= 7*diceroll;
          if (p1.utilities == 2)rent= 15*diceroll;
          handleRent(p2, p1, rent);
        }
      }
    }
    // super tax
  } else if (int(places[x.placecount][1]) == 7) {
    fill(255, 127, 0);
    text("You pay 100 for super tax", 150, 250);
    x.money-=200;
    text("You now have: "+str(x.money)+" left", 150, 300);
    text("Press E to end turn", 150, 350);
    //community chest and chance
  } else if (int(places[x.placecount][1]) == 4) {
    int r = round(random(1, 3));
    if (!(r == 2)) {
      text("Jeff Bezos felt generous today, he gave you 100!", 150, 250);
      text("Assuming 1 = $100,000 , this amounts to", 150, 300);
      text("a whooping 0.0001% of his net worth", 150, 350);
      text("press E to end turn", 150, 400);
      x.money += 100;
    } else {
      text("You did some contractual work on one of", 150, 250);
      text("Trump's properties! He paid you a 1000!", 150, 300);
      text("Just kidding, he didn't pay you at all.", 150, 350);
      text("In fact you paid a 100 for materials.", 150, 400);
      text("press E to end turn", 150, 450);
      x.money -= 100;
    }
  }
  checkWin();
}

void checkWin() {
  if (p1.money < 0) {
    refresh();
    fill(255, 127, 0);
    text("P2 has won", 150, 200);
    noLoop();
  }
  if (p2.money < 0) {
    refresh();
    fill(255, 127, 0);
    text("P1 has won", 150, 200);
    noLoop();
  }
}

void endTurn() {
  refresh();
  fill(255, 127, 0);
  text("Player 1 has "+p1.money+" left", 150, 200);
  text("Player 2 has "+p2.money+" left", 150, 250);
  if (turn == 0) {
    fill(255, 127, 0);
    text("Player 1's turn has ended. Player 2's turn", 150, 300);
    turn = 1;
  } else {
    fill(255, 127, 0);
    text("Player 2's turn has ended. Player 1's turn", 150, 300);
    turn = 0;
  }
  text("Press R to roll or I for a list of your properties,", 150, 350);
  allowRoll = true;
  checkWin();
}


void refresh() {
  background(bg);
  p1.display();
  p2.display();
  fill(0);
  rect(100, 100, 600, 600);
}

void buy(Player x) {
  fill(255, 127, 0);
  if (places[x.placecount][2] == "Bank") {
    x.money -= int(places[x.placecount][3]);
    x.properties[p1.propertyamount] = x.placecount;
    x.propertyamount++;
    text(places[x.placecount][0]+" has been purchased", 150, 200);

    if (turn == 0) places[x.placecount][2] = "Player1";
    if (turn == 1) places[x.placecount][2] = "Player2";
    if (int(places[x.placecount][1]) == 2) {
      x.rails += 1;
      text("You now have "+x.rails+" railroads", 150, 250);
      text("Press E to end turn", 150, 300);
    } else if (int(places[x.placecount][1]) == 3) {
      x.utilities += 1;
      text("You now have "+x.utilities+" utilities", 150, 250);
      text("Press E to end turn", 150, 300);
    } else {
      text("Press E to end turn", 150, 250);
    }
  }
  checkWin();
}

int checkRailRent(Player x) {
  if (x.rails == 1) return x.rails*25;
  if (x.rails == 2) return x.rails*25;
  if (x.rails == 3) return 100;
  if (x.rails == 4) return 200;
  return 0;
}

void handleRent(Player renter, Player rentee, int rent) {
  renter.money -= rent;
  rentee.money += rent;
  fill(255, 127, 0);
  text("Property is owned, you have paid "+rent+" in rent", 150, 250);
  text("You have "+renter.money+" left", 150, 300);
  text("Press E to end turn", 150, 350);
  checkWin();
}

void handleRoll() {
  if (turn == 0) {
    if (p1.placecount + diceroll >= 40) {
      p1.placecount = p1.placecount+diceroll - 40;
      p1.money += 200;
    } else {
      p1.placecount+= diceroll;
    }
    p1.updatePos();
    refresh();
    checkLanded(p1);
  } else {
    if (p2.placecount + diceroll >= 40) {
      p2.placecount = p2.placecount+diceroll - 40;
      p2.money += 200;
    } else {
      p2.placecount+= diceroll;
    }
    p2.updatePos();
    refresh();
    checkLanded(p2);
  }
}

void serialEvent(Serial myPort) {
  int x = myPort.read();
  println(x);
  if (x == 1 && allowRoll) {
    proceed=true;
  }
  //toRoll = myPort.read();
  //println(toRoll);
  myPort.write(0);
}
void keyPressed() {
  //keycounter++;
  //if (keycounter == 1) first = true;
  //if (keycounter == 2) first = false;

  if (key =='s')refresh();
  //refresh();
  // Roll dice phase
  if ((key == 'r' || key == 'R')&&allowRoll) {
    allowRoll = false;
    diceroll = rollDice();
    handleRoll();
  }
  if ((key == 'b' || key =='B')&& !allowRoll) {
    refresh();
    if (turn == 0) {
      buy(p1);
    } else {
      buy(p2);
    }
  }

  if ((key == 'e' || key == 'E')&& !allowRoll) {
    refresh();
    endTurn();
  }

  if ((key == 'i' || key == 'I') && allowRoll) {
    fill(255, 127, 0);
    if (turn == 0) { 
      int ycounter = 200;
      for (int i = 0; i<p1.propertyamount; i++, ycounter+=50) {
        text(places[p1.properties[i]][0], 150, ycounter);
      }
    }
    if (turn == 1) {
      int ycounter = 200;
      for (int i = 0; i<p2.propertyamount; i++, ycounter+=50) {
        text(places[p2.properties[i]][0], 150, ycounter);
      }
    }
  }
}

 

Space Invaders V-2

This is a fairly straightforward upgrade on my last iteration of Space Invaders to use an analog thumb joystick instead of keys. I also made a few changes to the code, specifically changing the scoring system, allowing the ship to move in more directions, making it autoshoot, and allowing the ship to collide with the enemies (which kills the enemy and looses a life).

The new code is

import processing.serial.*;
Serial myPort;
Game game;
float divisions= 50;
void setup() {
  printArray(Serial.list());
  String portname=Serial.list()[0];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  size(500, 500);
  game= new Game();
  frameRate(30);
}
void draw() {
  game.draw();
  if (!game.update()) {
    int score= game.getScore();
    game=null;
    background(0);
    textSize(32);
    text("Game Over", width/7, height/2-50);
    text("Score: "+score, width*3/7, height/2+50);
    noLoop();
  }
}
void keyPressed() {
  game.keyPressed(key);
}
void serialEvent(Serial myPort) {
  game.serialEvent(myPort);
}
import java.util.Iterator;
class Game {
  ArrayList<Enemy> enemies;
  Ship ship;
  ArrayList<Projectile> projectiles;
  float timer;
  float enemyRate= 500;
  float levelTimer;
  float levelRate= 30000;
  int lives;
  int score;
  int scoreStep;
  Game() {
    enemies= new ArrayList<Enemy>();
    ship= new Ship(this);
    projectiles= new ArrayList<Projectile>();
    timer= millis();
    levelTimer= millis();
    lives= 10;
    scoreStep=1;
  }
  void keyPressed(int key) {
    ship.keyPressed(key);
  }
  boolean update() {
    Enemy enemy;
    Iterator<Enemy> enemyIterator= enemies.iterator();
    while (enemyIterator.hasNext()) {
      try {
        enemy=enemyIterator.next();
      }
      catch(Exception e) {
        break;
      }
      enemy.update();
      Projectile projectile;
      Iterator<Projectile> projectileIterator= projectiles.iterator();
      if (enemy.reachedEnd(height-ship.sHeight)) {
        enemies.remove(enemyIterator);
        enemies.remove(enemy);
        score-=100;
        lives--;
      }
      if (enemy.checkImpact(ship)) {
        enemies.remove(enemyIterator);
        enemies.remove(enemy);
        score-=100;
        lives--;
      }
      while (projectileIterator.hasNext()) {
        try {
          projectile=projectileIterator.next();
        }
        catch(Exception e) {
          break;
        }
        if (projectile.checkImpact(enemy)) {
          enemies.remove(enemyIterator);
          enemies.remove(enemy);
          projectiles.remove(projectileIterator);
          projectiles.remove(projectile);
          score+=scoreStep;
        }
      }
      if (levelTimer+levelRate<millis()) {
        enemyRate/=1.3;
        scoreStep*=2;
        levelTimer=millis();
      }
    }
    ship.update();
    for (Projectile projectile : projectiles) {
      projectile.update();
    }
    if (timer+enemyRate<millis()) {
      enemies.add(new Enemy(width/divisions, height/divisions, game));
      timer=millis();
    }
    return lives>0;
  }
  void draw() {
    background(0);
    for (Enemy enemy : enemies) {
      enemy.draw();
    }
    ship.draw();
    for (Projectile projectile : projectiles) {
      projectile.draw();
    }
    fill(255);
    textSize(10);
    text("lives: "+lives, 10, height-10);
    text("score: "+score, width-80, height-10);
  }
  void addProjectile(Projectile projectile) {
    projectiles.add(projectile);
  }
  int getScore() {
    return score;
  }
  void serialEvent(Serial myPort) {
    ship.serialEvent(myPort);
  }
}
class Projectile{
  float x;
  float y;
  float xVelocity;
  float yVelocity;
  Projectile(float x, float y){
    this.x=x;
    this.y=y;
  }
  void update(){
    x+=xVelocity;
    y+=yVelocity;
  }
  void draw(){
    stroke(255);
    point(x,y);
  }
  boolean checkImpact(Enemy enemy){
    return((x-enemy.getX())*(x-enemy.getX())+(y-enemy.getY())*(y-enemy.getY()))<enemy.getR()*enemy.getR();
  }
}
class Enemy {
  float x;
  float y;
  float r;
  float xVelocity;
  int direction;
  Game game;
  Enemy(float x, float y, Game game) {
    this.game=game;
    this.x=x;
    this.y=y;
    r=sqrt(width*height/(divisions*divisions));
    xVelocity=r/2;
    direction=1;
  }
  void update() {
    if (r<x&&x<width-r||direction==0) {
      if (direction==0) {
        if (x<width/2) {
          direction=1;
        } else {
          direction=-1;
        }
      }
      x+=xVelocity*direction;
    } else if (x<=r&&direction!=0) {
      y+=2*r;
      direction=0;
    } else if (x>=width-r&&direction!=0) {
      y+=2*r;
      direction=0;
    }
  }
  void draw() {
    fill(255);
    ellipse(x, y, r, r);
  }
  float getX() {
    return x;
  }
  float getY() {
    return y;
  }
  float getR() {
    return r;
  }
  boolean reachedEnd(float y) {
    return this.y>y;
  }
  boolean checkImpact(Ship ship) {
    return((x-ship.getX())*(x-ship.getX())+(y-ship.getY())*(y-ship.getY()))<ship.getR()*ship.getR();
  }
}
class Ship{
  float x;
  float step;
  float y;
  boolean shooting;
  float sWidth;
  float sHeight;
  float timer;
  float fireRate;
  float step0;
  Game game;
  Ship(Game game){
    this.game= game;
    x= width/2;
    step= width/(divisions*2);
    y= width*(divisions-2)/divisions;
    sWidth= width/divisions;
    sHeight= height/divisions;
    timer= millis();
    fireRate= 250;
    shooting=false;
    step0=step;
  }
  void keyPressed(int key){
    if(key=='x'&&x<width-sWidth){
      x+= step;
    }
    else if(key=='z'&&x>sWidth){
      x-= step;
    }
    else if(key==' '){
      shooting=!shooting;
    }
  }
  void serialEvent(Serial myPort){
    String s=myPort.readStringUntil('\n');
    s=trim(s);
    if (s!=null){
      int values[]=int(split(s,','));
      int X= 0, Y=0;
      if (values.length==3){
        X=(int)map(values[0],0,1023,-step, step);
        Y=(int)map(values[1],0,1023,-step, step);
        if(values[2]>0){
          step=step0/2;
          shooting=true;
        }
        else{
          shooting=false;
          step=step0*2;
        }
      }
      x+=X;
      y-=Y;
      if(x<0){
        x=sWidth;
      }
      if(x>width){
        x=width-sWidth;
      }
      if(y<0){
        y=sHeight;
      }
      if(y>height){
        y=height-sHeight;
      }
    }
  }
  void update(){
    if(timer+fireRate<millis()&&shooting){
      shoot();
      timer= millis();
    }
  }
  void draw(){
    triangle(x-sWidth/2,sHeight+y,x,y,x+sWidth/2,sHeight+y);
  }
  void shoot(){
    game.addProjectile(new ShipProjectile(x,y));
  }
  float getY(){
    return y;
  }
  float getX(){
    return x;
  }
  float getR(){
    return sWidth;
  }
}
class ShipProjectile extends Projectile{
  ShipProjectile(float x, float y){
    super(x,y);
    xVelocity=0;
    yVelocity=-height/divisions*3/4;
  }
}

The arduino code is super simple:

const int X= A0;
const int Y= A1;
const int Z= A2;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
 // if(Serial.available()>0){
    int x = analogRead(X);
    delay(1);
    int y = analogRead(Y);
    delay(1);
    int z = analogRead(Z);
    delay(1);
    Serial.print(x);
    Serial.print(',');
    Serial.print(y);
    Serial.print(',');
    Serial.println(z);
  //}
}

 

Computing

Computing started as just a way to crunch numbers. Computers even used to be people who would do certain mathematical tasks. However, once mechanized and then electronic computing was invented, a whole new horizon was unlocked for ‘computers’. Our use of computers went way beyond just mathematics, in fact computing is now essential in our everyday lives. Everything we do involved a computer in one way or another, for better or for worse. While the benefits of computers are clear, there certainly isn’t a lack of drawbacks either. Due to our excessive use and dependance on computers, we are losing our privacy due to tracking of the massive amounts to data we give to the computers. Furthermore, we are becoming more attached to the digital world than ever, which affects our lives and relationships.

Basically, to me, a computer is an extremely powerful tool, and whether that tool works to your advantage or not is completely dependent on how you use it.

What does Computing mean to me

I don’t think computing on its own is a significant concept to me. It is such a huge part of my life, between this class, my computer science minor, and my physics research, that i basically don’t see it anymore, just specific applications of it. I used so see it as something amazing and wonderful, that was a very pleasant break from my other classes, like languages. Now though, I see that its inherent logic is convoluted by people in any of the projects that are sufficiently complicated to be worth something, and so while simple coding and computing has some inherent beauty for me, most is so hacky and misleading that I see it mostly as a powerful tool. It is necessary for a great many things, but it is only a necessary feature, it does not increase the value of whatever it is involved in inherently.