{"id":229,"date":"2013-10-01T01:17:02","date_gmt":"2013-10-01T05:17:02","guid":{"rendered":"http:\/\/www.jhclaura.com\/?p=229"},"modified":"2015-11-20T17:19:44","modified_gmt":"2015-11-20T22:19:44","slug":"icm_4_patchballsflies","status":"publish","type":"post","link":"http:\/\/www.jhclaura.com\/icm_4_patchballsflies\/","title":{"rendered":"ICM_4_PatchBallsFlies"},"content":{"rendered":"

Here’s the combination of what I’ve learned so far from Learning Processing<\/span><\/a><\/span> and The Nature of Code<\/span><\/a><\/span>. I call it “Patch. Balls. and Flies”.\u00a0It’s kind of messy but I’m glad all the interactions with each others work! Yah!\u00a0Check it out(click click )<\/span><\/a><\/strong><\/span>!<\/span><\/a><\/strong><\/p>\n

\n

Functions:
\n1) move patch to stop bouncing balls
\n2) press mouse to drag balls with patch
\n3) long-press keyboard to see flies clubbing!! B-) \u00a0 (surprisingly fit
this<\/a><\/span><\/strong><\/span> perfectly, the most EXCITING part, DANCING time!!)
\n4) let go keyboard(== keyReleased) to calm down the flies, and gather all the balls within the patch<\/p>\n

(Forgive me the awful screen pics, can’t screenshot since this one involve functions of KEY.)<\/p>\n<\/div>\n

\"bouncing\"<\/p>\n

\"clubbing_flies\"<\/a><\/p>\n

\"reset\"<\/a><\/p>\n

Here’s some struggles I’ve been through:<\/p>\n

    \n
  1. when dragging balls, I calculated the distance with patch and ball, and then planed to add this fixed distance to the position of patch and set it as the position of balls. But since I wrote this code in void mouseDragged()<\/span>, I recalculated the distance every time I dragged and that caused flickering. Thanks to the office hour w\/ Daniel Shiffman, this calculation codes were moved into void mousePressed()<\/span> and it worked!!! (tearing)<\/li>\n
  2. same stupid things happened when I want to bump flies with balls: I forgot to set conditions and thus make flies be affected by every balls!<\/li>\n
  3. Things getting complicated when I want to make the music band. In the end I successfully saved the original color, and changed the color once it’s been hit(hitGround == true<\/span> && \u00a0cubes.x < ball.x <cubes.x+w<\/span>\u00a0 && ball.y < (height-h)<\/span>), and then restored the colors back later.<\/li>\n<\/ol>\n

    And codes time!<\/p>\n

    <\/p>\n

    Main<\/p>\n

    Mover[] movers = new Mover[20];\r\nBand musicBand;\r\nRain[] rains = new Rain[50];\r\n\r\nboolean pressing = false;\r\n\r\nvoid setup() {\r\n\r\n  size(600, 500);\r\n  for (int i=0; i<movers.length; i++) {\r\n    movers[i] = new Mover(random(0.5, 2.5), random(width), random(20,50));\r\n  }\r\n\r\n  musicBand = new Band(0, 21, 80);\r\n  musicBand.setColor();\r\n\r\n  for (int i=0; i<rains.length; i++) {\r\n    rains[i] = new Rain();\r\n  }\r\n}\r\n\r\nvoid draw() {\r\n\r\n  background(255);\r\n\r\n  \/\/ set up musicBand\r\n  musicBand.checkHit();\r\n  musicBand.display();\r\n  musicBand.colorBack();\r\n\r\n  \/\/ set up forces\r\n  float c = 0.5;\r\n  float normal = 1;\r\n  float frictionMag = c*normal;\r\n\r\n  PVector wind = new PVector(0.01, 0);\r\n  PVector gravity = new PVector(0, 0.1);\r\n\r\n  for (int i=0; i<movers.length; i++) {\r\n\r\n    PVector friction = movers[i].velocity.get();\r\n    friction.mult(-1);\r\n    friction.normalize();    \r\n    friction.mult(frictionMag);\r\n\r\n    \/\/ if movers in the range of patch, add firction and change color\r\n    if (movers[i].location.x > mouseX-100\/2 && movers[i].location.x < mouseX+100\/2\r\n      && movers[i].location.y > mouseY-100\/2 && movers[i].location.y < mouseY+100\/2) {\r\n      movers[i].applyForce(friction);\r\n\r\n      boolean insideColor = true;\r\n      movers[i].insideColor = insideColor;\r\n\r\n    } else {\r\n      boolean insideColor = false;\r\n      movers[i].insideColor = insideColor;\r\n    }\r\n\r\n    movers[i].applyForce(wind);\r\n    movers[i].applyForce(gravity);\r\n\r\n    movers[i].update();\r\n    movers[i].checkEdges(width, height-musicBand.h-movers[i].mass*16\/2);\r\n    movers[i].display();\r\n\r\n  }\r\n\r\n  \/\/ set up flies\r\n  for (int j=0; j<rains.length; j++) {\r\n\r\n    \/\/ be affected by balls\r\n    for (int i=0; i<movers.length; i++) {\r\n      rains[j].updateMover(movers[i].location.x, movers[i].location.y);\r\n    }\r\n\r\n    rains[j].checkFloor();\r\n    rains[j].show();\r\n  }\r\n\r\n  \/\/ patch\r\n  rectMode(CENTER);\r\n  pushStyle();\r\n  noStroke();\r\n  fill(150,50);\r\n  rect(mouseX, mouseY, 100, 100);\r\n  stroke(220,100);\r\n  for (int i=0; i<=100; i+=5) {\r\n    line(mouseX-50+i, mouseY-50, mouseX-50+i, mouseY+50);\r\n  }\r\n  for (int i=0; i<=100; i+=5) {\r\n    line(mouseX-50, mouseY-50+i, mouseX+50, mouseY-50+i);\r\n  }\r\n  popStyle();\r\n  rectMode(CORNER);\r\n\r\n  \/\/ event when key pressed\r\n  if (pressing == true) {\r\n    pushStyle();\r\n    fill(0);\r\n    noStroke();\r\n    rect(0,0,width,height);\r\n    popStyle();\r\n  }\r\n\r\n}\r\n\r\nvoid mousePressed() {\r\n\r\n  for (int i=0; i<movers.length; i++) {\r\n\r\n    \/\/ if in the range of the patch, be able to drag balls\r\n    if (movers[i].location.x > mouseX-100\/2 && movers[i].location.x < mouseX+100\/2 &&\r\n      movers[i].location.y > mouseY-100\/2 && movers[i].location.y < mouseY+100\/2) {\r\n\r\n      boolean inside = true;\r\n      movers[i].inside = inside;\r\n\r\n      PVector mouse = new PVector(mouseX, mouseY);\r\n      PVector dis = PVector.sub(movers[i].location, mouse);\r\n      movers[i].dis = dis;\r\n\r\n    } else {\r\n\r\n      boolean inside = false;\r\n      movers[i].inside = inside;\r\n    }\r\n\r\n  }\r\n}\r\n\r\nvoid mouseDragged() {\r\n  for (int i=0; i<movers.length; i++) {\r\n\r\n    PVector mouse = new PVector(mouseX, mouseY);\r\n    if (movers[i].inside == true) {\r\n      movers[i].location = PVector.add(mouse, movers[i].dis);\r\n    }\r\n\r\n  }\r\n}\r\n\r\nvoid keyPressed() {\r\n  background(0);\r\n\r\n  pressing = true;\r\n\r\n  \/\/ calm down all the balls and gather them into patch\r\n  for (int i=0; i<movers.length; i++) {\r\n    movers[i].location.x = mouseX+random(-40,40);\r\n    movers[i].location.y = mouseY+random(-30,30);;\r\n    movers[i].velocity.mult(0);\r\n    movers[i].acceleration.mult(0);\r\n  }\r\n\r\n  for (int j=0; j<rains.length; j++) {\r\n    rains[j].checkFloor();\r\n    rains[j].show();\r\n  }\r\n\r\n}\r\n\r\nvoid keyReleased() {\r\n  pressing = false;\r\n\r\n  \/\/ reset all the flies\r\n  for (int j=0; j<rains.length; j++) {\r\n    rains[j] = new Rain();\r\n  }\r\n\r\n}<\/pre>\n

    Mover<\/p>\n

    class Mover {\r\n\r\n  PVector location;\r\n  PVector velocity;\r\n  PVector acceleration;\r\n\r\n  float mass;\r\n\r\n  PVector dis;\r\n  boolean inside = false;\r\n  boolean insideColor = false;\r\n\r\n  boolean lastHitState = false;\r\n  boolean hitState = false;\r\n  boolean hitGround = false;\r\n\r\n  Mover() {\r\n    location = new PVector(random(width\/2), random(height\/2));\r\n    velocity = new PVector(0, 0);\r\n    acceleration = new PVector(0, 0);\r\n    mass = 1;\r\n  }\r\n\r\n  Mover(float m, float x, float y) {\r\n    mass = m;\r\n    location = new PVector(x, y);\r\n    velocity = new PVector(0, 0);\r\n    acceleration = new PVector(0, 0);\r\n  }\r\n\r\n  void update() {\r\n\r\n    velocity.add(acceleration);\r\n    location.add(velocity);\r\n    acceleration.mult(0);\r\n  }\r\n\r\n  void display() {\r\n    pushStyle();\r\n    noStroke();\r\n\r\n    float time = second();\r\n    fill(time % 255, 50);\r\n    ellipse(location.x, location.y, mass*20, mass*20);\r\n\r\n    if (insideColor == true) {\r\n      fill(252, 255, 3, 180);\r\n    } else {\r\n      fill(0, 232, 254, 150);\r\n    }\r\n\r\n    ellipse(location.x, location.y, mass*12.5, mass*12.5);\r\n\r\n    popStyle();\r\n  }\r\n\r\n  void checkEdges(float w, float h) {\r\n    if (location.x > w) {\r\n      location.x = w;\r\n      velocity.x *= -1;\r\n    } \r\n    else if (location.x < 0) {\r\n      location.x = 0;\r\n      velocity.x *= -1;\r\n    }\r\n\r\n    if (location.y > h) {\r\n      location.y = h;\r\n      velocity.y *= -1;\r\n      hitGround = !hitGround;\r\n    }\r\n\r\n    if (location.y < h-100) {\r\n      hitGround = false;\r\n    }\r\n\r\n  }\r\n\r\n  void applyForce(PVector force) {\r\n    PVector f = PVector.div(force, mass);\r\n    acceleration.add(f);\r\n  }\r\n}<\/pre>\n

    Rain<\/p>\n

    class Rain{\r\n\r\n  PVector location;\r\n  PVector velocity;\r\n  PVector acceleration;\r\n  PVector distance;\r\n  PVector distanceRain;\r\n\r\n  Bug bug;\r\n\r\n  float w, h;\r\n  float topSpeed;\r\n  color c;\r\n\r\n  Rain() {\r\n\r\n    location = new PVector(random(width), -50);\r\n    velocity = new PVector(random(-0.1, 0.1), random(-0.1, 0.1));\r\n    distance = new PVector(20, 20);\r\n    distanceRain = new PVector(10, 10);\r\n\r\n    w = 4;\r\n    h = 6.5;\r\n    topSpeed = 3;\r\n\r\n  }\r\n\r\n  void show() {\r\n\r\n    smooth();\r\n    pushStyle();\r\n\r\n    noStroke();\r\n    bug = new Bug(location.x, location.y, w, h);\r\n    bug.show();\r\n\r\n    popStyle();\r\n  }\r\n\r\n  void updateMover(float x_, float y_) {\r\n\r\n    PVector mover = new PVector(x_, y_);\r\n    PVector dir = PVector.sub(mover, location);\r\n\r\n    acceleration = new PVector(0, 0);\r\n\r\n    if (dir.mag() < distanceRain.mag()) {\r\n\r\n      dir.normalize();\r\n      dir.x *= random(-0.2);\r\n      dir.y *= random(-0.2);\r\n      acceleration = dir;\r\n\r\n    }\r\n\r\n    velocity.add(acceleration);\r\n    velocity.limit(topSpeed);\r\n    location.add(velocity);\r\n  }\r\n\r\n  void checkFloor() {\r\n\r\n    if (location.y > (height - musicBand.h)) {\r\n      location.y = 0;\r\n    } else if (location.y < 0) {\r\n      location.y = (height - musicBand.h);\r\n    }\r\n\r\n    if (location.x > width) {\r\n      location.x = 0;\r\n    } else if (location.x < 0) {\r\n      location.x = width;\r\n    }\r\n\r\n  }\r\n\r\n}<\/pre>\n

    Drop<\/p>\n

    class Drop{\r\n\r\n  float x, y, w, h;\r\n\r\n  Drop(float _x, float _y, float _w, float _h) {\r\n    x = _x;\r\n    y = _y;\r\n    w = _w;\r\n    h = _h;\r\n  }\r\n\r\n  void show() {\r\n\r\n    pushStyle();\r\n    smooth();\r\n    noStroke();\r\n    triangle(x, y-h, x+w\/2, y, x-w\/2, y);\r\n    ellipse(x, y, w, w);\r\n    popStyle();\r\n  }\r\n\r\n}<\/pre>\n

    Cube<\/p>\n

    class Cube{\r\n  float x; \r\n  float y;\r\n  float w, h;\r\n  color c;\r\n\r\n  boolean beHit;\r\n\r\n  Cube(float _x, float _y, float _w, float _h, color _c) {\r\n    x = _x;\r\n    y = _y;\r\n    w = _w;\r\n    h = _h;\r\n    c = _c;\r\n    beHit = false;\r\n  }\r\n\r\n  void display() {\r\n    pushStyle();\r\n    noStroke();\r\n    fill(c);\r\n    rect(x, y, w, h);\r\n    popStyle();\r\n  }\r\n\r\n}<\/pre>\n

    Bug<\/p>\n

    class Bug{\r\n\r\n  float x, y, w, h;\r\n  Drop[] drops;\r\n\r\n  Bug(float _x, float _y, float _w, float _h) {\r\n    x = _x;\r\n    y = _y;\r\n    w = _w;\r\n    h = _h;\r\n    drops = new Drop[4];\r\n  }\r\n\r\n  void show() {\r\n    pushStyle();\r\n    smooth();\r\n    fill(173, 191, 216, 150);\r\n\r\n    pushMatrix();\r\n    translate(x, y);\r\n    rotate(radians(40));\r\n    drops[0] = new Drop(0, 6, w, h);\r\n    drops[0].show();\r\n    rotate(radians(70));\r\n    drops[1] = new Drop(0, 6, h, h);\r\n    drops[1].show();\r\n    rotate(radians(140));\r\n    drops[2] = new Drop(0, 6, h, h);\r\n    drops[2].show();\r\n    rotate(radians(70));\r\n    drops[3] = new Drop(0, 6, w, h);\r\n    drops[3].show();\r\n\r\n    popMatrix();\r\n    popStyle();\r\n  }\r\n\r\n}<\/pre>\n

    Band<\/p>\n

    class Band {\r\n  float x; \r\n  float y;\r\n  float w, h;\r\n  int interval;\r\n  color[] colors;\r\n  color[] colorSave;\r\n\r\n  Cube[] cubes;\r\n\r\n  Band(float _x, int _interval, float _h) {\r\n    x = _x;\r\n    interval = _interval;\r\n    h = _h;\r\n\r\n    w = width \/ interval;\r\n    y = height - h;\r\n    colors = new color[interval];\r\n    colorSave = new color[interval];\r\n    cubes = new Cube[interval];\r\n  }\r\n\r\n  void setColor() {\r\n    for (int i=0; i<interval; i++) {\r\n      float cc = random(130);\r\n      colors[i] = color(cc, cc+120, cc+60);\r\n      colorSave[i] = colors[i];\r\n    }\r\n  }\r\n\r\n  void checkHit() {\r\n    for (int i=0; i<interval; i++) {\r\n      for (int j=0; j<movers.length; j++) {\r\n        if (movers[j].hitGround == true && movers[j].location.x > cubes[i].x && \r\n          movers[j].location.x < cubes[i].x+w && movers[j].location.y < (height-h)) {\r\n          float cc = random(130);\r\n          colors[i] = color(cc+120, cc+120, 0);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  void colorBack() {\r\n    for (int i=0; i<interval; i++) {\r\n      for (int j=0; j<movers.length; j++) {\r\n        if (movers[j].hitGround == false) {\r\n          colors[i] = colorSave[i];\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  void display() {\r\n    float tempX = x;\r\n\r\n    for (int i=0; i<interval; i++) {\r\n      cubes[i] = new Cube(tempX, y, w, h, colors[i]);\r\n      cubes[i].display();\r\n      tempX += w;\r\n    }\r\n  }\r\n\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"

    Here’s the combination of what I’ve learned so far from Learning Processing and The Nature of Code. I call it “Patch. Balls. and Flies”.\u00a0It’s kind of messy but I’m glad… Read The Rest →<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[127,2],"tags":[21,24],"_links":{"self":[{"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/posts\/229"}],"collection":[{"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/comments?post=229"}],"version-history":[{"count":5,"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/posts\/229\/revisions"}],"predecessor-version":[{"id":237,"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/posts\/229\/revisions\/237"}],"wp:attachment":[{"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/media?parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/categories?post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.jhclaura.com\/wp-json\/wp\/v2\/tags?post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}