ablackbu-Final Project

For my final project I made a game called Meteor Flyer. You can play a version below but some effects are missing. For the best performance, download the game in the “PLAY” link below.

To play, the user:

  1. Navigates a UFO with their mouse through a meteor field.
  2. When the mouse is close to the meteors, they grow.
  3. UFO can shoot a meteor and break it by the user clicking the mouse.
  4. If the UFO makes it to the bottom of the canvas, the player wins
  5. if the UFO hits a meteor, the player loses.
  6. the colors can be changed with the “ENTER” key.
  7. The instructions can be shown by holding down the “SHIFT” key.

Please download the file and use the local file to access the html file to play!!

***********

PLAY ******

***********

 

Here are some snapshots of a winning game and a losing game.

Winning Game:

____________________________________________

Losing Game:

 

Like I said before, this version on WordPress is scaled and some effects don’t work. For the best performance, download the game in the “PLAY” link above.

sketch

var bubbles = [];
var colCount = 0;
var loseF = false;
var rocketX = 300;
var rocketY = 80;
var ropeX = 300;
var ropeY = 80;
var len = 150; //length of array
var on = false;
var gettime;

//pop sound
var sound1;

//background colors
var a = ("#292b29");
var b = ("#fbf49c");
var c = ("#f69b9c");
var d = ("#a3bfe4");
var e = ("#a9dbcf");
var f = ("#9a97ca");
var back = [a, b, c, d, e, f];

//bubble colors
var ba = ("#a5a5a5");
var bb = ("#918c60");
var bc = ("#7a3f42");
var bd = ("#4f5863");
var be = ("#67827b");
var bf = ("#474769");
var bub = [ba, bb, bc, bd, be, bf];

//text colors
var ta = ("#292b29");
var tb = ("#a5a5a5");
var tex = [ta, tb]


function preload() {
    // load sound and image files
    //sound1 = loadSound('sounds/pop.wav');
    mouse1 = loadImage("https://i.imgur.com/vWALILY.png")
}

function setup() {
    createCanvas(600, 600);
    textFont("Courier")
    //set up bubbles object
    for (var i = 0; i < len; i++){
        bubbles[i] = {
            
            x:random(0, width) , 
            y:random(80, height) , 
            diam:random(10, 55) , 
            pointx : 0,
            pointy : 0,
            //make the bubbles
            display : function(){
                stroke(back[colCount]);
                fill(bub[colCount]);
                ellipse(this.x, this.y, this.diam);
            }
        }
    }
}

function draw() {
    background(back[colCount]);
    if(frameCount > 400){
            on = true
    }
    
    for (var i = 0; i < len; i++){
        //display bubbles
        bubbles[i].display();
        //move bubbles to make them shake
        
        if(on == true){
            bubbles[i].x += random(-1,1);
            bubbles[i].y += random(-1,1);
        }
        if(on == false){
            bubbles[i].x += 0
            bubbles[i].y += 0
        }  

        strokeWeight(.5);
        stroke(bub[colCount]);
        //create a line from the mouse to the bubbles if they are 100 pix away
        if(dist(bubbles[i].x, bubbles[i].y, mouseX,mouseY) < 100){
            line(bubbles[i].x, bubbles[i].y, mouseX,mouseY);
            
            //increase bubbles size if the line connects them
            //stop increasing at 150 pix
            if(frameCount > 400){
                if (bubbles[i].diam <= 150){
                    bubbles[i].diam += .3;
                }
            }   
        }
        //test if the rocket is touching a bubble
        var roc = dist(mouseX, mouseY-50, bubbles[i].x, bubbles[i].y);
        if(frameCount > 400){
            if(roc <= 15 + bubbles[i].diam/2){
                loseF = true      
            }
        }

        //if shift is held down, pause the game
        if (keyIsDown(SHIFT)){
            on = false
        }
    }
    
    //if shift is held down the instructions pop up
    if (keyIsDown(SHIFT)){
        on = false
        instructions();
    }

    //put instructions up for a few seconds when page reloads
    if(frameCount > 30 & frameCount < 400){
        //show where to put mouse flashing
        if(frameCount % 10){
            fill("green");
            strokeWeight(0);
            ellipse(ropeX, ropeY, 40, 40, 20)
            //mouse image
            push();
            scale(.08);
            image(mouse1, ropeX * 12.3, ropeY * 12);
            pop();
        }
        instructions();
    }

    //make rocket
    rocket();
    
    //winning message if rocket makes it accross
    if(rocketY >= height + 35){
        end();
    }
    
    //losing message if rocket hits a bubble
    if(loseF == true){
        noLoop();
        lose();
    }

    //countdown
    if(frameCount < 400){
        ticker();
    }

    if(mouseIsPressed){
        var gettime = frameCount
    }
    
    //make beam lasers when pressing on a bubble
    if(frameCount >= gettime & frameCount < gettime + 3){
        strokeWeight(3)
        stroke("red");
        line(ropeX - 5, ropeY, rocketX - 5, rocketY - 50); 
        line(ropeX + 5, ropeY, rocketX + 5, rocketY - 50); 
    }
}

function mousePressed(){   
    for (var i = 0; i < len; i++){
        var g = dist(mouseX, mouseY, bubbles[i].x, bubbles[i].y);
        //if you click on an bubble it pops
        if(g <= bubbles[i].diam/2){
            bubbles[i] = bubbles[len - 1];
            len -= 1;

            //pop sound plays
            //sound1.play();
        }
    }
}

function keyPressed(){
    //if the enter key is pressed, the color of the porgram changes
    //so that the colors cycle through from the array
    if (keyCode == ENTER)  {
        colCount ++;
        if(colCount == 6){
            colCount = 0;
        }
    }
}

function instructions(){
    rectMode(CENTER);
    textAlign(CENTER);
    
    //instrucitons text
    fill(255);
    rect(width/2, height/2 + 5, 420, 150, 20);
    fill(tex[5*frameCount%2]);
    
    textSize(10);
    text("Place Mouse Here --->", ropeX - 90, ropeY + 6);

    textSize(18);
    text("LEAD THE UFO THROUGH THE METEORS", width/2, height/2 - 30);
    text("REACH THE BOTTOM WITHOUT CRASHING", width/2, height/2 - 10);
    
    fill("#292b29");
    textSize(14);
    text("Click to destroy meteors", width/2, height/2 + 20);
    
    textSize(10);
    text("Press 'ENTER' to change colors", width/2-100, height/2 + 55);
    fill("#a3bfe4")
    textSize(10);
    text("Hold 'SHIFT' to pause", width/2+100, height/2 + 55);  
}

//make UFO
function rocket(){
    if(frameCount > 400){
        rocketX = mouseX
        rocketY = mouseY
        ropeX = mouseX
        ropeY = mouseY
    }
    strokeWeight(.5)
    stroke("black");
    line(ropeX, ropeY, rocketX, rocketY-50); 
    stroke(255);
    fill(200);
    ellipse(rocketX, rocketY-50, 30, 30);
    fill(180);
    ellipse(rocketX, rocketY-50, 15, 15);
}

//winning message
function end(){
    background("green");
    noLoop()
    fill("white");
    textSize(20);
    text("YOU WON!", width/2, height/2);
}

//losing message
function lose(){
    background("red");
    textSize(20);
    fill("white");
    text("YOU lOSE!", width/2, height/2);
    textSize(15);
    text("ctrl + R to restart game", width/2, height/2 + 25);
}

//countdown to the start
function ticker(){ 
    fill(255);
    textSize(40)
    text(floor(6 - (frameCount / 80)), 300, 150);
}

ablackbu-Project-10-Proposal

For my final project I want to make a particle grid that is randomly connected by lines that the user can break. In my imagination it looks something like a web between the particle dots and when the user scrolls over the connectors, they break.

Here is some of my inspiration:


I aso want to incorporate sound into my project. Right now I’m thinking maybe if you were to press a key that a sound would go off and the dots would either grow or shrink.

There are a few things I need to iron out while making this. I think it will be a good chance to really dive into for loops and randomness. I am very unsure how i will be able to create lines going from some particles to other particles in a for loop.

Finally color will be used so that the feeling the user gets when “playing” with this program is calmness.

ablackbu-section c-Project-11-Composition

press mouse

sketch

var galaxy

function preload() {
    galaxy = loadImage('https://i.imgur.com/W0T1NZk.jpg')
}

function setup() {
    createCanvas(360, 280);
    background(230);
    push()
    scale(.3)
    image(galaxy,0,0)
    pop()
}
    
function draw() {
    fill(255)
    noStroke()
    ellipse(mouseX,mouseY,3,3)

}

function mousePressed(){
    
    var tur1 = makeTurtle(mouseX,mouseY);
    tur1.setColor(color(random(150,255),random(150,255),random(150,255)));
    var w = 3;
    tur1.setWeight(w)
    var side = random(5,20)
    for(var i = 0; i < 100; i++) {
        tur1.penDown();
        tur1.forward(side);
        tur1.right(60);
        tur1.forward(side);
        tur1.right(60);
        tur1.forward(side);
        tur1.right(60);
        tur1.forward(side);
        tur1.right(60);
        tur1.forward(side);
        tur1.right(60);
        tur1.forward(side);
        tur1.penUp();
        tur1.right(110);
        tur1.forward(side*.8);
        side *= 0.9;
        w *= 0.7
        tur1.setWeight(w);
        tur1. right(50)
    }
}

function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

For this project on adapting turtles, I created a galaxy where the user is able to create stars and planets, the planets made are a similar turtle to the spiral one made in lab but these are hexagons that spiral in on each other and get smaller and lighter as they go.

ablackbu-Project-10-Generative Landscape

sketch

var terrainSpeed = 0.0008;
var terrainDetail = 0.008;
var fiX = 450;
var fi2X = 500;
var fi3X = 475;
var scooba;
var scoobaX = 450


function preload() {
    scooba = loadImage('https://i.imgur.com/8HhJZHY.png')
}

function setup() {
    createCanvas(400, 200);

}
 
function draw() {
    background(70,200,250);
    //draw terrain
    terrain();
    //draw sub
    sub();
    //draw fish
    fish();
    //sand
    fill(226,226,176)
    rect(0,height-20,width,20)
    //scooba diver
    scoobaD();
    



}

function terrain() {
    noFill(); 
    beginShape(); 
    stroke(40,120,40)
    strokeWeight(2)
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 0, height);
        vertex(x, y); 
        
        

        //terrain
        push();
        fill(40,120,40);
        ellipse(x,y+25,20,20); //thick black hill
        ellipse(x,y+55,10,10); //thin black hill

        stroke(20,80,18);
        strokeWeight(1);
        if(x%2){
            line(x,y,x,y+200) //white lines
        }
        pop();

        
    }
    endShape();
}


function sub() {
        //sub
    push();
    rotate(random(-.01,.01));
    strokeWeight(0);
    fill('yellow');
    
    rect(170,100,70,35,15); //body
    rect(185,89,30,30,5); //top
    rect(150,107,15,20,3); //tail
    rect(162,112,10,10); //connector
    rect(190,85,5,10); //airtube
    ellipse(225,117.5,43,35); //nose


    fill(200);
    //windows
    ellipse(188,115,12,12);
    ellipse(205,115,12,12);
    ellipse(223,115,12,12);

    fill(100);
    //inside windows
    ellipse(188,115,9,9);
    ellipse(205,115,9,9);
    ellipse(223,115,9,9);
    pop();
}

function fish() {

    var fiS = 3.5;
    var fi2S = 2;
    var fi3S = 3;

    strokeWeight(0);
    fill(0);
    //fish1
    ellipse(fiX,50,25,10);
    triangle(fiX+10,50,fiX+16,45,fiX+16,55);
    fiX = fiX-fiS;
    if(fiX < 0){
        fiX = 450;
    }
    //fish2
    ellipse(fi2X,60,25,10);
    triangle(fi2X+10,60,fi2X+16,55,fi2X+16,65);
    fi2X = fi2X-fi2S;
    if(fi2X < 0){
        fi2X = 500;
    }
    //fish3
    ellipse(fi3X,70,25,10);
    triangle(fi3X+10,70,fi3X+16,65,fi3X+16,75);
    fi3X = fi3X-fi3S;
    if(fi3X < 0){
        fi3X = 475;
    }
}  

function scoobaD(){
    var scoobaS = 3.5;
    push();
    scale(.6);
    translate(50,10);
    image(scooba,scoobaX,0);
    //move scooba across screen
    scoobaX = scoobaX - scoobaS;
    if(scoobaX < -150){
        scoobaX = 550;
    }
    pop();
} 
    

For this project I wanted to play off of the Beatles’ song “Yellow Submarine.” I used some code from the example to generate the landscape which I then manipulated to create details in the underwater mountains. The sub in the middle is rotating a tenth of a degree every frame to create a turbulent look. fish and a scuba diver go past at randomly generated speeds.

What I learned while doing this project is that making separate functions for each part and then calling them in the draw function is a great way to change code and manipulate it.

ablackbu-Project-09-Computational Portrait

Press mouse!!!

sketch

var micah;
var diam = 6;

function preload() {
    //load image
    var image = "https://i.imgur.com/XqeXMOd.png";
    micah = loadImage(image);
}

function setup() {
    createCanvas(300, 300);
    background(0);
    textSize(8);
    textAlign(CENTER);
}

function draw() {
    for(var x = 0; x < width; x+=6){
        for(var y = 0; y < height; y+=6){
            //get pixle color
            var pix = micah.get(x,y);
            strokeWeight(0);
            fill(pix);
            //draw dollar signs collored to var micah
            text("$",x,y);
        }   
    }
}

function mousePressed() {
        //if mouse is pressed, change text size and flash dollar signs
        fill(255);
        textSize(100);
        for(i = 0; i < 5; i++){
            for(j = 0; j < 5; j++){
                text("$",i*80,j*80);  
            }
        }
}

For this project I chose my little brother as the subject. Our family always makes jokes about how much money he spends on clothes so I wanted to create him out of dollar signs. When a key is pressed, a frame flashes and the signs grow so make a more interesting portrait. I decided to steer away from all the examples where dots filled in the image and do something a little different more artistic, and a little more interesting. I feel like I am finally getting a hang of image preloading and the get() function. Hope you enjoy.

ablackbu-Looking-Outwards-09

Georgia Tech’s Shimon robot writes and plays its own music using machine learning.

___________________________________

For this looking outwards post, I am getting inspiration from svitoora’s post on sept. 18:

svitoora – 04 Looking Outwards

___________________________________

As svitoora mentions in his post, this robot was given more than 5,000 songs and riffs and is able to, with these, compose its own music. What this robot does is so human like and the focus on the implications of this were stated in his reflection very thoroughly. The fact that you could walk into a room and hear this playing and think it is a human is crazy. Not only does it emit music, but it creates its own non-random but incredibly calculated notes. The most mesmerizing part of this project to me is that it takes from other music. Like a human, it takes cues from different genres and mixes them to make something with its “taste.”

___________________________________

http://www.wired.co.uk/article/ai-music-robot-shimon

ablackbu-Project-07-Composition with Curves

sketch

var points = 100;

var R = 200;
var G = 100;
var B = 100;

var depth = 3


function setup() {
    createCanvas(400, 400);
    background(0);
}


function draw() {

    //draw curves
    translate(width / 2, height / 2);
    rotate(mouseX/50);
    drawParabolaCurve();
    
    //decide color
    if(mouseX < width/2){
        R = 100;
        G = 100;
        B = 200;
    }else{
        R = 200;
        G = 100;
        B = 100;
    }
}   


function drawParabolaCurve() {
    // Parabola:
    // http://mathworld.wolfram.com/Parabola.html
    strokeWeight(0.1);
    stroke(R,G,B);
    noFill()
    
    //vertex points
    var x;
    var y;
    
    var a = 20;
    
    

    beginShape();
    for (var i = 0; i < points; i++) {
        var t = map(i, 0, points, 0, TWO_PI);
        
        //parabolic formula
        x = a * pow(t,depth) / a;
        y = 2 * a * t;
        vertex(x, y);
    }
    endShape(CLOSE);
    
}

For this project I really wanted to do/create something aesthetic. After looking through the algorithms and formulas, I found lots of them that were extremely complicated and hard to understand. I decided to go with something simple (a parabola) and influence it with both movement and color to make it look complex.

I created a formula that draws a more complex grid overtime you move your mouse. It creates a really interesting pattern and it makes the viewer want to make it more built up.

ablackbu-Looking-Outwards-07

The geography of Tweets

https://blog.twitter.com/official/en_us/a/2013/the-geography-of-tweets.html

NEW YORK

in 2013, Twitter’s team for Visual Insights created a project that gave every twitter user a virtual brush that they could mark the location of every tweet they made. Twitter was able to track billions of tweets, since 2009, and place them on a map to track tweet geographic patterns.

Above is Europe, Istanbul, and Tokyo. Every place is incredibly unique and varied. This gave Twitter a lot of helpful data surrounding who and where uses their service.

My favorite part of this experience is that it is so simple. But at the same time it is so complex. There are billions of points that have to be mapped and this is no small feat.

Something else I noticed is not on the land but in the sea. there are dots all over the ocean. This means that they were even able to trace off-coast tweets from maritime traffic.

ablackbu-Looking-Outwards-06

______________________

For this looking outwards entry I found a very interesting algorithm based brand identity that is used by the Exploratorium in San Francisco.

______________________

______________________

The artist created a program that randomizes lines around a certain areas to create an outcome that has infinite variation.

______________________

With this, he as created a very interesting alphabet that is used in all of their design language. Above is an example of the “e” that is made of of strings computed by his program.

What made me so interested with this project is the branding side of this computation. The designer is using random computation to explore brand identity. The strings he makes are 100% random by definition, but all of them in a room would look like they are similar.

In the designers words, “It allows for infinite variation of the lettermark and exists in a duality of spontaneity and energy grounded by math and logic.” As I am studying letterform, it is very interesting for me to see a typeface that is grounded in randomness.

 

More info can be found at:

http://paulhoppe.info/new-gallery-1/

ablackbu-Project-06-Abstract-Clock

water clock

sketch

var red1 = 0
var green1 = 0
var blue1 = 0

var red2 = 0
var green2 = 0
var blue2 = 0

var wid = 5

function setup() {
    createCanvas(300, 300);
    strokeWeight(0);

}

function draw() {
    background(208,236,245);
        
    //get time
    var hr = hour();
    if(hr > 12){
        hr = hr - 12}
    var min = minute();
    var sec = second(); 

    //tubes
    strokeWeight(10);
    noFill()
    stroke(red1,green1,blue1);
    arc(115,95,120,120,PI/2,PI)
    stroke(red2,green2,blue2);
    arc(210,190,120,120,PI/2,PI)

    //color of tube 1
    if(sec == 59){
        red1 = 52
        green1 = 198
        blue1 = 244
    }else{
        red1 = 80
        green1 = 80
        blue1 = 80
    }

    //collor of tube 2
    if(sec == 59 & min == 59){
        red2 = 52
        green2 = 198
        blue2 = 244
    }else{
        red2 = 80
        green2 = 80
        blue2 = 80
    }

    //bowls of water
    fill(52,198,244);
    stroke(0);
    strokeWeight(3);
    rect(15,15,80,80);
    rect(110,110,80,80);
    rect(205,205,80,80);
    
    //extention of background to hide lid (not visible)
    strokeWeight(0);
    fill(208,236,245);
    rect(10,10,90,16)
    rect(105,105,90,16)
    rect(200,200,90,16)

    //compute the height of the water
    var secfull = map(sec, 0, 60, 77, 7);
    var minfull = map(min, 0, 60, 77, 7);
    var hrfull = map(hr, 0, 12, 77, 7);

    //display the water
    fill(208,236,245);
    rect(17,17.5,77,secfull);
    rect(112,112.5,77,minfull);
    rect(207,207.5,77,hrfull);

    //water marks
    fill(0)
    dist1 = 0
        //ticks for vessle 1 and 2
    for(var i = 0; i < 13; i++){
        rect(50,95-dist1,wid,1/2)
        rect(145,190-dist1,wid,1/2)
        dist1 += 5.9
            if((i + 1) % 3 == 0){
                wid = 10
            }else{
                wid = 5
            }
    }

        //ticks for vessle 3
    dist3 = 0
    for(var k = 0; k < 13; k++){
        rect(240,285-dist3,10,1/2)
        dist3 +=5.9
    }

    //digital time
    fill(0);
    text(nf(hr,2,0) + ':' + nf(min,2,0) + ':' + nf(sec,2,0),10,290);

}

For this project, I got a lot of inspiration from the water clock that was discussed in the video. I had a lot of trouble coming up with an idea to show time that was creative without being overdone. I knew that a lot of people were planning on doing interesting circular clocks but I wanted to do something a little different.

Basically the premise of this machine is that when the water in the seconds cup overfills, it empties into the minute and so on into the hours. My favorite part of this is that when you look at it (besides the fact that there is a digital time keeper in the corner) you should have no idea it is a clock, just interacting water vessels.

 

Image result for water clock