Assignment 7

For this assignment, I have worked with class and objects.

I based the idea on the work I replicated for Assignment 6 and came up with the code with the help of Getting started with Processing and online resources.

Here is the code that I used:

CrazyShape circle1, circle2, square3;

void setup() {
size(500,500);
smooth();
circle1 = new CrazyShape(20, 1.5, color(random(255), 125, 0));
circle2 = new CrazyShape(10, 3, color(255, 0, random(155)));
square3 = new CrazyShape(30, 2.5, color(0, random(125), 255));
}

void draw() {
circle1.move();
circle1.displayCircle();
circle2.move();
circle2.displayCircle();
square3.move();
square3.displaySquare();
}

CrazyShape

class CrazyShape {
float x;
float y;
int diameter;
float speed;
color c;

CrazyShape(int id, float ispeed, color ic) {
x = random(width);
y = random(height);
speed = ispeed;
diameter = id;
c = ic;
}

void move() {
x += random(-speed, speed);
y += random(-speed, speed);

if (x < 0+diameter) {
x = random(width);
c = color(random(255), random(255), random(255));
} else if (x > width-diameter) {
x = random(width);
c = color(random(255), random(255), random(255));
}

if (y < 0+diameter) {
y = random(height);
c = color(random(255), random(255), random(255));
} else if (y > height-diameter) {
y = random(height);
c = color(random(255), random(255), random(255));
}
}

void displayCircle() {
fill(c);
ellipse(x, y, diameter, diameter);
}

void displaySquare() {
fill(c);
rect(x, y, diameter, diameter);
}
}

Art Project

I struggled a lot with just trying to figure out how to work the ‘class’ thin, even though I understood the overall concept. Eventually, after watching a few videos and getting help from classmates, I worked it out.

My code is as follows:

//Main CircleDrawing
Shape shape1;
Shape shape2;
Shape shape3;
Shape shape4;
Shape shape5;
Shape shape6;
Shape shape7;
Shape shape8;

int x1= mouseX;
int y1 = mouseY;
color red = color(255, 0, 0, 20);
color green = color(0, 255, 0, 30);
color blue = color(0, 0, 255, 10);

int counter = 1;

void setup(){
size (500,500);
smooth();
colorMode(HSB);
shape1 = new Shape(x1, y1, 250, 150, 250, 250, 100, 100);
shape2 = new Shape(x1, y1, 150, 250, 250, 250, 400, 200);
shape3 = new Shape(x1, y1, 400, 250, 250, 250, 100, 400);
shape4 = new Shape(x1, y1, 250, 400, 250, 250, 50, 290);

}

void draw(){
background(250);
shape1.display();
shape2.display();
shape3.display();
shape4.display();
noStroke();

if(counter == 1) {
fill(red);
}
else if(counter == 2) {
fill(green);
}
else if(counter == 3) {
fill(blue);
}

if (mousePressed == true) {
ellipse(mouseX, mouseY, 50, 50);
}

}

void mouseReleased() {
counter++; // increase the counter
if(counter == 4) {
counter = 1; // loop after 3
}
println(counter);
}

//Class

class Shape{

//Variables
int x1, y1, x2, y2, x3, y3, x4, y4;

//The Constuctor
Shape(int px1, int py1, int px2, int py2, int px3, int py3, int px4, int py4){
x1 = px1;
y1 = py1;
x2 = px2;
y2 = py2;
x3 = px3;
y3 = py3;
x4 = px4;
y4 = py4;
}
//Functions

void display(){
//x1 = int(random(x1-10,x1+10));
//y1 = int(random(y1-10,y1+10));
x1 = mouseX;
y1 = mouseY;
quad(x1, y1, x2, y2, x3, y3, x4, y4);

}

}

 

This is the final product:

 

I think this could be improved by designing more organized shapes to create an image perhaps.

Assignment 6

       

I replicated the work done by Edward Zajec.

Here is the code that I used:

void setup() {
size(380, 500);
}

void draw() {
background(255);
noFill();
smooth();
strokeWeight(1);
stroke(0);

//circle1
for (int i=25; i<359; i+= 25) {
ellipse(140, 150, i, i);
}

//circle2
for (int i=10; i<200; i+= 8) {
ellipse(355, 380, i, i);
}

//square1
stroke(150);
pushMatrix();
{
rotate(PI/5);
for (int i=2; i<120; i+=4) {
rectMode(CENTER);
rect(250, -20, i, i);
}
popMatrix();
}

//circle3
stroke(100);
for (int i=2; i<80; i+= 3) {
ellipse(280, 180, i, i);
}

//square2
stroke(120);
pushMatrix();
{
rotate(PI/6);
for (int i=2; i<200; i+=6) {
rectMode(CENTER);
rect(380, 180, i, i);
}
popMatrix();
}

//triangle
stroke(0);
for (int i=2; i<30; i++){
triangle(40,15,44+i,17+i, 37-i, 13+i/2);
triangle(45,15,48+i,13-i,48+i,17+i);
triangle(30,13,7+i/2,25-i/4,68-i,-27+i);
}
}

Lev Manovich Response

Cinema Section:

The first thing I noticed when reading this was the author is tying together a bit too many metaphors/similes and so it makes it a bit confusing. In one page he likens books to films; movies to computer culture; the mobile camera being essential to computer culture and the “3D-ness it brings” along with a whole other plethora of comparisons and expressions. And this was all just on the first page.

He then goes on to talk about various objects such as VR, (computer) games, more on 3D space and models, and perspective. I can see his intention in this, but the jargon made it difficult to process.

HCI: Representation versus Control Section:

He then talks about remediating. I particularly liked how he brought up the example of Xerox making basic standards of interfaces, and how these were repurposed. He then talks more about these interfaces, and how they differ from books… for some reason…

Overall, some aspects he mentioned that I want to keep in mind are how culture affects design. (Such as with computer icons)

Casey Reas on Eyeo2012

When looking at the art work displayed in the presentation, I was conflicted on whether or not I liked it. I genuinely enjoyed the idea of how he made the artworks, as I am interested in generated, repeated patterns, but I didn’t actually love the end results too much. To quote Kristopher in class, some of the pieces did look a little too “crowded” or “busy”.

I enjoyed how there is a balance of semi-abstraction vs. complete abstraction, as in the pieces (including some of the other artists he talks about such as mondrian who did the colorful squares we all have seen at least once [mondrian works] )

Overall, I agree with my peers that the video tended to be a bit on the monotonous side, but overall, some interesting concepts of chaos and abstraction were explored.

Universe Art Project – Using Object-Orientated Processing

Last week, I went to an Institute talk regarding recent discoveries in the universe that has been found using a new type of telescope that is able to act like a satellite.

One of the coolest ideas that I found in that talk was the idea that there are certain “moon” like structures that have a gravitational pull that allows “planets” and asteroids to orbit it. However, because of the different mass of the asteroids/planets, there exist different orbit distances and speeds that they travel at. On top of this, sometimes, there even exists orbits around the asteroids/planets that are orbiting the bigger moon – much like Earth’s moon.

I wanted to replicate this idea and so instead of a game, I wanted to create a moving art piece that basically shows what the speaker was talking about.

The code can be seen below:

Moon moon, moon2;
Orbits orbits, orbits1, orbits3;

void setup() {
size(600, 600);
smooth(8);
background(0);
moon = new Moon(80);
orbits = new Orbits(150, 0.2, 2.5);
orbits1 = new Orbits(400, 0.05, 4);
orbits3 = new Orbits(200, 0.1, 6);
}

void draw() {
//frameRate(1200);
moon.draw();
//moon.stopTurning();
orbits.draw();
orbits1.draw();
orbits3.draw();
}

These are the class tabs:

//class definition of Moon
class Moon{
PVector v1, v2; //attribute of moon
int diameter; //another attribute of moon

Moon(int d){ //this is the constructor 
//does nothing over here
diameter =d; //this is a parameter of the constructor
}

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

noFill();
strokeWeight (0.3);
stroke (255, 12); 

for (int i = 0; i < 7000; i++)
{
float angle1 = random (TWO_PI);
float angle2 = random (TWO_PI);
v1 = new PVector (width/2 + cos (angle1) * diameter, height/2 + sin (angle1) * diameter);
v2 = new PVector (width/2 + cos (angle2) * diameter, height/2 + sin (angle2) * diameter);

line (v1.x, v1.y, v2.x, v2.y);
}
//noLoop();
}


} //end of class definition
class Orbits {
float a, x, y, diax, diay;
float d = 23;
int para;
float speed;
float speed4orbit;
float b;

Orbits(int p, float s4o, float s){
para = p;
speed4orbit = s4o;
speed = s;;
}

void draw (){
// earth

pushMatrix();

translate(width/2, height/2);
fill(255);
ellipse(x, y, d, d);

// moon
pushMatrix();
translate(x, y);
rotate(radians(a));
ellipse(0, d, d/3, d/3);
popMatrix();

// orbit line
stroke(255, 100);
smooth();
noFill();

ellipse(0, 0, diax*2, diay*2);


x = sin(radians(-a)*speed)*diax;
y = cos(radians(a)*speed)*diay;
a += 4;

diax = lerp(diax, para, speed4orbit);
diay = lerp (diay, para, speed4orbit);
popMatrix();
}
}

 

Here is a screenshot of one of the frames.

One thing I am not happy with, and I can’t seem to figure out, is how not smooth the movements are. I tried to change the frameRate but that didn’t work out.

One new thing that learned for this project was PVectors, which I found out how to use through examples.

Space Invaders

In describing this project, space invaders was mentioned a bunch of times, and I decided that it sounded reasonably fun to work on.

I set up my game as if there would be multiple enemies who would shoot back, though in my current implementation enemies win by reaching the end, and are all simple circles, ship the ship is a triangle.

The main code is very simple, creating a game and having the win logic.

Game game;
float divisions= 50;
void setup(){
  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);
}

The game is also simple, just facilitating the interaction of the enemies, ship, and projectiles, and containing each. Also tracks the larger game logic like score and lives.

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;
  Game(){
    enemies= new ArrayList<Enemy>();
    ship= new Ship(this);
    projectiles= new ArrayList<Projectile>();
    timer= millis();
    levelTimer= millis();
    lives= 10;
  }
  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(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++;
        }
      }
      if(levelTimer+levelRate<millis()){
        enemyRate/=1.3;
        score*=1.3;
        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(8);
    text("lives: "+lives,10,10);
    text("score: "+score,width-50,10);
  }
  void addProjectile(Projectile projectile){
    projectiles.add(projectile);
  }
  int getScore(){
    return score;
  }
}

The first component class is ship, moves according to controls (z,x,’ ‘), mostly just creates projectiles

class Ship{
  float x;
  float step;
  float y;
  boolean shooting;
  float sWidth;
  float sHeight;
  float timer;
  float fireRate;
  Game game;
  Ship(Game game){
    this.game= game;
    x= width/2;
    step= width/divisions;
    y= width*(divisions-2)/divisions;
    sWidth= width/divisions;
    sHeight= height/divisions;
    timer= millis();
    fireRate= 250;
    shooting=false;
  }
  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 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;
  }
}

Since in theory projectiles can be made by enemies (though collision detection would need a re-write, mostly an if instance of or separate detection logic for each projectile type.), there is a parent and child version

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 ShipProjectile extends Projectile{
  ShipProjectile(float x, float y){
    super(x,y);
    xVelocity=0;
    yVelocity=-height/divisions*3/4;
  }
}

The logic is the same for each, the child simply gives numbers

Last class is enemy, walks down the screen from side to side.

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(Ship ship){
    return y>ship.getY();
  }
}

End result: 

Game using OOP

Initially, I wanted to create an art piece because that is what I feel more comfortable coding. However, I also wanted to try something new and outside of my comfort level, so I chose to re-create a game that I knew. I wanted to re-create Flappy Bird, however, I found it extremely challenging to implement logic into my code. Especially when it came to making the ball not go below or above the pillars if it touches the pillars. I wasn’t able to solve this problem on time, so I decided to make the ball bounce on the racket. In addition, in the instructions, I asked a friend to keep track of the score, which also allows for a friendlier, interactive match.

I didn’t have a solid understanding of classes or OOP. After talked to Aaron an hour before class started, I realized that I created my code using functions, and not classes.

Here is my code for the project, using functions:

int gameScreen = 0;
float ballX, ballY;
float ballSize = 20;
int ballColor = color(255,255,0);
float gravity = 1;
float ballSpeedVert = 0;
float airfriction = 0.0001; //air resistance andfriction is important, ball doesn't just bounce up and down at same level, it reduces height as it bounces more.
float friction = 0.1; //surface friction
color racketColor = color(255,105,180); //platform ball bounces on
float racketWidth = 100;
float racketHeight = 10;
int racketBounceRate = 20;
float ballSpeedHorizon = 10;

//wall
int wallSpeed = 5;
int wallInterval = 1000;
float lastAddTime = 0;
int minGapHeight = 200;
int maxGapHeight = 300;
int wallWidth = 80;
color wallColors = color(0);
ArrayList<int[]> walls = new ArrayList<int[]>(); //list to keep data for gap between two walls. contains gap wall X, gap wall Y, gap wall width, gap wall height)

void setup() {
  size(500, 500);
  ballX=width/4;
  ballY=height/5;
}

void draw() {
  if (gameScreen == 0) {
    initScreen();
  } else if (gameScreen == 1) {
    gameScreen();
  } else if (gameScreen == 2) {
    gameOverScreen();
  }
}

void initScreen() {
  background(0);
  textAlign(CENTER);
 text("Don't let the ball touch the pillars. Make a friend keep track of your score.", height/2, width/2);
}
void gameScreen() {
  background(0,255,255);
  drawBall();
  applyGravity();
  keepInScreen();
  drawRacket();
  watchRacketBounce();
  applyHorizontalSpeed(); //for horizontal movement of ball
  wallAdder(); //adds new walls in every wallInterval millisecond
  wallHandler();
}
  
void gameOverScreen() {
}

public void mousePressed() { //what does public void mean
  // if we are on the initial screen when clicked, start the game
  if (gameScreen==0) {
    startGame();
  }
}

void startGame() { //necessary variable to start the game
  gameScreen=1;
}

void drawBall() {
  fill(ballColor);
  ellipse(ballX, ballY, ballSize, ballSize);
}

void applyGravity() {
  ballSpeedVert += gravity; //ballSpeedVert is -1. adding gravity to ballSpeedVert = it starts to get close to 0, becomes 0, then will start increasing again.
  ballY += ballSpeedVert; //vertical speed of ball added to Y coordinate of ball
  ballSpeedVert -= (ballSpeedVert * airfriction);
}

void makeBounceBottom(float surface) { //why is surface incorporated here? what is surface?
  ballY = surface-(ballSize/2);
  ballSpeedVert*=-1; //to bounce ball we move the ball to exact location where it had to bounce and multiply vertical speed with use of -1
  ballSpeedVert -= (ballSpeedVert * friction);
}

void makeBounceTop(float surface) { //why is surface incorporated here?
  ballY = surface+(ballSize/2);
  ballSpeedVert*=-1;
  ballSpeedVert -= (ballSpeedVert * friction);
}

void makeBounceLeft(float surface) {
  ballX = surface+(ballSize/2);
  ballSpeedHorizon*=-1;
  ballSpeedHorizon -= (ballSpeedHorizon * friction);
}
void makeBounceRight(float surface) {
  ballX = surface-(ballSize/2);
  ballSpeedHorizon*=-1;
  ballSpeedHorizon -= (ballSpeedHorizon * friction);
}

// keep ball in the screen
void keepInScreen() {
  // ball hits floor
  if (ballY+(ballSize/2) > width) {  //checking if ballY+radius less than height
    makeBounceBottom(width);
  }
  // ball hits ceiling
  if (ballY-(ballSize/2) < 0) { //checking if ballY-radius is more than 0
    makeBounceTop(0);
}
    if (ballX-(ballSize/2) < 0) {
      makeBounceLeft(0);
    }
    if (ballX+(ballSize/2) > width) {
      makeBounceRight(width);     
    }
}

void drawRacket() {
  fill(racketColor);
  rectMode(CENTER);
  rect(mouseX, mouseY, racketWidth, racketHeight);
}

void watchRacketBounce() { //makes sure racket and ball collide LOOK AT TUTORIALA GAIN
  float overhead = mouseY - pmouseY;
  if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) { //x coord. of right side of ball is greater than x coord. of left side of racket and other way around
    if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) { //distance between ball and racket is smaller than or equal to radius of ball (hence colliding)
      makeBounceBottom(mouseY); //hence this bounce method is called
      // racket moving up
      if (overhead<0) { //stores coordinates of the mouse at the previous time frame. Sometimes ball moves so fast that distance between ball and racket cant be correctly calculated between frames. so we take overhead value in between frames to detect difference. overhead value also detects negative value --stimulates racket effect.
        ballY+=overhead; //less than 0 means mouse is below in previous frame and racket is moving up
        ballSpeedVert+=overhead; //adds extra speed to ball to stimulate effect of hitting ball w racket
        if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) {  //edges of rack should give ball a more horizontal speed & middle should have no effect
          if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) { 
            ballSpeedHorizon = (ballX - mouseX)/5;
          }
        }
      }
    }
  }
}

void applyHorizontalSpeed() {
  ballX += ballSpeedHorizon;
  ballSpeedHorizon -= (ballSpeedHorizon * airfriction);
}

void wallAdder() {
  if (millis()-lastAddTime > wallInterval) { //if millis minus last added millisecond is larger than interval value, it is time to add new wall
    int randHeight = round(random(minGapHeight, maxGapHeight));
    int randY = round(random(0, height-randHeight));
    // {gapWallX, gapWallY, gapWallWidth, gapWallHeight}
    int[] randWall = {width, randY, wallWidth, randHeight}; 
    walls.add(randWall);
    lastAddTime = millis();
  }
}

void wallHandler() { //loops though each item. it removes each wall
  for (int i = 0; i < walls.size(); i++) {
    wallRemover(i);
    wallMover(i);
    wallDrawer(i);
    watchWallCollision(i);
  }
}
void wallDrawer(int index) {
  int[] wall = walls.get(index);
  // get gap wall settings 
  int gapWallX = wall[0];
  int gapWallY = wall[1];
  int gapWallWidth = wall[2];
  int gapWallHeight = wall[3];
  // draw actual walls
  rectMode(CORNER);
  fill(wallColors);
  rect(gapWallX, 0, gapWallWidth, gapWallY);
  rect(gapWallX, gapWallY+gapWallHeight, gapWallWidth, height-(gapWallY+gapWallHeight));
}

void wallMover(int index) {
  int[] wall = walls.get(index);
  wall[0] -= wallSpeed;
}
void wallRemover(int index) {
  int[] wall = walls.get(index);
  if (wall[0]+wall[2] <= 0) {
    walls.remove(index);
  }
}

void watchWallCollision(int index) { //gets called for each wall on each loop. take coordinates of wall (top and bottom) and check if coordinates of balls collifes w walls
  int[] wall = walls.get(index);
  // get gap wall settings 
  int gapWallX = wall[0];
  int gapWallY = wall[1];
  int gapWallWidth = wall[2];
  int gapWallHeight = wall[3];
  int wallTopX = gapWallX;
  int wallTopY = 0;
  int wallTopWidth = gapWallWidth;
  int wallTopHeight = gapWallY;
  int wallBottomX = gapWallX;
  int wallBottomY = gapWallY+gapWallHeight;
  int wallBottomWidth = gapWallWidth;
  int wallBottomHeight = height-(gapWallY+gapWallHeight);

  if (
    (ballX+(ballSize/2)>wallTopX) &&
    (ballX-(ballSize/2)<wallTopX+wallTopWidth) &&
    (ballY+(ballSize/2)>wallTopY) &&
    (ballY-(ballSize/2)<wallTopY+wallTopHeight)
    ) {
    // collides with upper wall
  }
  
  if (
    (ballX+(ballSize/2)>wallBottomX) &&
    (ballX-(ballSize/2)<wallBottomX+wallBottomWidth) &&
    (ballY+(ballSize/2)>wallBottomY) &&
    (ballY-(ballSize/2)<wallBottomY+wallBottomHeight)
    ) {
    // collides with lower wall
  }
}

By the middle of this week, I will convert this code to be structured with OOP and paste it below.

Flappy Bird is a happy bird

I wanted to make a game so I did. My version of flappy bird is really similar to the original one and I am happy with the final version. It is very playable and fun. However, there are a few potential improvements I could have made but simply did not have time.

  1. I did not add a replay function to my game. Ideally, a button is clicked after each death and the player is able to restart the game.
  2. In my code, I should have made a Game class, where initializing and terminating the game takes place. This makes my main file a lot longer than it needs to be.

My full code/images/sounds can be found on

https://github.com/ross67/IntroToIm/tree/master/flappyBird

//main 
import processing.sound.*;
SoundFile hit;
SoundFile die;
SoundFile point;
SoundFile wing;

PImage backgroundImg;
PImage img1;
PImage img2;
PImage img3;
PImage img;
PImage tube1;
PImage tube2;
int background =0;
boolean state = false;
boolean gameOver = false;
float speed = 0;
float gravity = 0.1;
int score = 0;
int hSpeed = 2;


float x = 50;
float y = 200;

int tubeLength;

Bird bird;
Tube tube;

ArrayList<Tube> tubeListTop;
ArrayList<Tube> tubeListBot;

void setup(){
 size(600,600);
 //size(1440,900);
 backgroundImg = loadImage("bg.png");
 img1 = loadImage("upflap.png");
 img2 = loadImage("midflap.png");
 img3 = loadImage("downflap.png");  
 tube1 = loadImage("tube1.png"); 
 tube2 =loadImage("tube2.png");
 tubeListTop = new ArrayList<Tube>();
 tubeListBot = new ArrayList<Tube>();
 img = img3;
 
 hit = new SoundFile(this, "hit.wav");
 die = new SoundFile(this, "die.wav");
 point = new SoundFile(this,"point.wav");
 wing = new SoundFile(this, "wing.wav");
 

 
 for (int i=0; i<4;i++){
  tubeLength =int(random(120,225));
  tubeListTop.add(new Tube(660+180*i,0,60,tubeLength, hSpeed)); 
}

for (int i=0; i<4;i++){
  tubeLength =int(random(120,225));
  tubeListBot.add(new Tube(660+180*i,505-tubeLength,60,tubeLength,hSpeed));   
}

}


  void draw(){ 
    
  if(!gameOver){
    image(backgroundImg,0,0);
    
    bird = new Bird(x, y);
    textSize(20);
    fill(0, 102, 153);
    text("PRESS SPACEBAR TO FLY", 80,580);
    fill(255,0,0);
    text("Socre: " + score, 450, 580);

  
    //if(keyPressed==true){ // use keyboard to move bird
    //  if(key == 'w'){
    //     y--; 
    //  }else if(key== 'a'){
    //     x--; 
    //  }else if(key=='d'){
    //   x++; 
    //  }else if(key=='s'){
    //   y++; 
    //  }
    //}
   for(Tube tube:tubeListTop){
     
     if(tube.locx<-60){
      tube.setX(680); 
     }
     
     tube.draw();
     
   }
    

   for(Tube tube:tubeListBot){
     
     if(tube.locx<-60){
      tube.setX(680); 
     }
     
     if (bird.locx == tube.locx){
      score++; 
      point.play();
     }

     tube.drawInverse();
     
   }
   
   
  }else{
     
    textSize(38);
    text("GAME OVER",180,270);
    textSize(16);
    text("restart the program to try again",170,290);
   }
   
    // Add speed to location.
      y = y + speed;

  // Add gravity to speed.
     speed = speed + gravity;
     
    if (y > height-123) {
    // Multiplying by -0.40 instead of -1 slows the object 
    // down each time it bounces (by decreasing speed).  
    // This is known as a "dampening" effect and is a more 
    // realistic simulation of the real world (without it, 
    // a ball would bounce forever).
    speed = speed * -0.40;
    y = height-123;
  }
  
   bird.draw(img);
   
   for(Tube tube:tubeListTop){
            
        if(bird.onCollision(tube)&&!gameOver){
            gameOver = true;
               hit.play();
               delay(100);
               die.play();
           }
      
    }  
    
     for(Tube tube:tubeListBot){
            
        if(bird.onCollision(tube)&&!gameOver){
            gameOver = true;
               hit.play();
               delay(100);
               die.play();
           }
      
    }  

  }
  
void keyPressed(){
  
  img = img1;

  wing.play();
}
 
 
 
void keyReleased(){  
    y = y-30;
    speed = speed *0.05;
    img = img3;
  }
//classes

class Bird{
  
  float locx, locy;

  
  Bird(float x,float y){
    locx = x;
    locy = y;    
  }
    
  void draw(PImage img ){
    
    image(img,locx,locy);
    
  }
    
  boolean onCollision(Tube a) {

  // are the sides of one rectangle touching the other?

  if (locx + 36 >= a.locx &&    // r1 right edge past r2 left
      locx <= a.locx + a.xlen &&    // r1 left edge past r2 right
      locy + 26 >= a.locy &&    // r1 top edge past r2 bottom
      locy <= a.locy + a.ylen) {    // r1 bottom edge past r2 top
        return true;
  }
  return false;
}
  
//http://www.jeffreythompson.org/collision-detection/rect-rect.php
  
}

class Tube{
 int locx, locy, xlen, ylen, hSpeed;
 
 Tube(int x,int y, int xl, int yl, int hs){
   locx = x;
   locy = y;
   xlen = xl;  
   ylen = yl;
   hSpeed = hs;
 }
 
   void draw(){   
    image(tube1,locx,locy,xlen,ylen);
    locx -= hSpeed;
  }
  

  void drawInverse(){
    image(tube2,locx,locy,xlen, ylen);
    locx -= hSpeed;

  }
  
  void setX(int x){
    locx =x;
  }
      
}

 

Art Piece(Edited; Read New Version After Asterisk)

When I started this assignment, I knew I really wanted to make an interactive art piece for a website I am making for another class.(CommLab)

Examples of these can be found on Pierre or Aaron’s websites:

Aaron’s: http://aaron-sherwood.com/

Pierre’s: https://pierredepaz.net/

 

This led me to bite off waay more than I could chew.

I was inspired by this image:

I wanted to make something like this that would happen when a mouse rolled/hovered over certain points. I also wanted to make it in a rectangular shape similar to the one found on Pierre’s website, as it would work as a header for my site.

Boy did I pick the wrong thing.

Let me tell you what was so hard about this:

1) I had trouble randomizing dots that would appear in a circular form as in the gif above. I could get them to appear at random, but not contained in a certain area.

2) It was actually pretty hard just to get the dots to be visible actually, so I ended up making the points into crosses.

3)I couldn’t get the image to change when the mouse hovers over certain points in the code, only a general area around and above the image.

4) I couldn’t get multiple random line segments at points, only a 1:1 ratio.

5) I also didn’t know how to show the movement of the line, rather than to just have it drawn and connected to the points.(ie, show it actually moving and connecting to the other point.)

And so, here is the finished (sad) product:

DotRect rect1;

void setup (){
  fullScreen();
  //size(640, 480);
  int rectX = 450;
  int rectY= 600;
  int amount = 50;
  rect1 = new DotRect(width/25 +rectX,height-rectY, amount);
 
}
void draw (){
  background(#35465c);
  rect1.draw();
}

void mouseMoved(){
  rect1.check(mouseX,mouseY);
}
class DotRect {
  int locX, locY, amount, seed;
  //consructor
  DotRect(int x, int y, int a) {

    locX = x; 
    locY = y;
    amount = a;
    seed=0;
  }
  void draw() {
    pushMatrix();
    translate(locX, locY);
    for (int i=0; i<50; i++)
    {


      stroke(255);
      float x = random(locX);
      float y = random(locY);
      float x2 = random(locX);
      float y2 = random(locY);
      for(int m =0; m<4; m++)
      {
      point(x+m, y);
      point(x2+m, y2);
      }
      for(int m =0; m<4; m++)
      {
      point(x, y+m);
      point(x2, y2+m);
      }
      for(int m =0; m<4; m++)
      {
      point(x-m, y);
      point(x2-m, y2);
      }
      for(int m =0; m<4; m++)
      {
      point(x, y-m);
      point(x2, y2-m);
      }
      line(x,y, x2, y2);
    
    }
    delay(100);
    popMatrix();
  }
  void check(int x, int y) {
    if ((dist(x, y, locX, locY) < x) && (dist(x, y, locX, locY)<y) )
    {
      seed = millis();
    }

}

}

So what did I learn?

This was not as easy as I believed it to be, and I am sorely disappointed with my outcome.

 

**********************************************************

PLEASE READ: EDITED

So I went back and fixed my code. (After a lot of time and help from Mateo; credit to him where it is due.)

ArrayList<Dot> dots;

void setup() {
  size(1200, 200); //screen size

  dots = new ArrayList<Dot>();
  for (int i = 0; i < 50; ++i) {
    dots.add(new Dot(random(width), random(height), 5));//adds and instantiates new Dot object into the array list
  }
}

void draw() {
  background(0);
  stroke(255);
  connect();
  for (int i = 0; i < dots.size(); ++i) {
    dots.get(i).move();//makes the Dots move
    dots.get(i).render();//draws the  the Dots
  }
}

void connect() {
  int count =0; //used to limit the connecting lines between Dots
  for (int i = 0; i < dots.size(); ++i) {
    for (int j = 0; j < dots.size(); ++j) {
      if (count<=5) // limits the lines
      {
        if (dist(dots.get(i).x, dots.get(i).y, dots.get(j).x, dots.get(j).y) < 100
          && dist(dots.get(i).x, dots.get(i).y, mouseX, mouseY) < 40) {
          line(dots.get(i).x, dots.get(i).y, dots.get(j).x, dots.get(j).y);
          count ++;
//the ifs work to check if the mouse is above the area around the dots and then draws the line
        }
      }
    }
  }
}



class Dot {
  float x, y, r;
  float seedX, seedY; //needed to vary frameCount

  Dot(float _x, float _y, float _r) {
    x = _x;
    y = _y;
    r = _r;
//takes the x,y,and r values from the main program and brings them into this obj

    seedX = random(10);
    seedY = random(10);
  }

  void render() { 
    fill(255);
    ellipse(x, y, r, r);
  }

  void move() {
    x += map(noise(seedX + frameCount*0.029), 0, 1, -1, 1); //changes the x
    y += map(noise(seedY + frameCount*0.012), 0, 1, -1, 1); //changes the y such that they will move in a nice, random pattern
    //the ifs below allow for the dots to loop around if they exit the screen
    if (x < 0) {
      x = width;
    } else if (x > width) {
      x = 0;
    }
    
    if (y < 0) {
      y = height;
    } else if (y > height) {
      y = 0;
    }
  }
}

And finally, the working product!

The next step is to turn it into javascript for my commlab website!