akluk-final-project

For my project I mainly based my project on whack a mole game combined with the pokemon that everyone loves, Diglet. The game lasts for 60 sec and during time the player would want to hit as many diglets as possible. Once the game ends the user can press r to restart the game. Hope you enjoy the game!

Screenshot of the game

sketch

//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Final Project

//initialize constants and variables
//number of rows of diglets in the canvas
var rows = 3;

//body height of the diglet
var diglet_h = 30;
//number of diglets in the game
var num_diglets = 11;
//array to contain the diglet objects
var diglets = [];
//temporary dummie variable to help push all the diglets 
var temp_diglet;
//number of diglets the player has hit in a single run of game/score
var num_hit;
//number of 0.5 sec passed elapsed
var time_elapsed = 0;
//duration of game 60sec
var game_time = 120;
//whether the game has ended
var ended = 0;
//hammer mode to determine if hammer is down or up
var mode; 
//start position for even rows
var startx1 = 60;
//start position for odd row
var startx2 = 120;
//spacing with each diglet
var spacing = 120;
//height spacing
var dy = 90;


function setup() {
    createCanvas(480, 360);
    //creates the diglets in the right positions
    // and pushes it into the array of diglets
    for (var i = 0; i < rows; i++) {
        //even rows
        if ((i % 2) == 0){
            for (var j = startx1; j < width; j += spacing){
                temp_diglet = new diglet(j,dy*(i+1));
                diglets.push(temp_diglet);
            }
        }
        //odd rows
        else {
            for (var j = startx2; j < width; j += spacing){
                temp_diglet = new diglet(j,dy*(i+1));
                diglets.push(temp_diglet);
            }
        }
    }
    //initialize score for player
    num_hit = 0;
    //update the diglets ever half second to determine if they pop up
    //and update timer every 0.5 sec
    setInterval(function(){
        for (var index = 0; index < num_diglets; index ++){
            diglets[index].update();
        }
        time_elapsed += 1;
    }, 500);
}

function draw() {
    background(40,180,40);
    noStroke();
    //change the display of the hammer 
    if (mouseIsPressed){
        mode = 1;
    }
    else {
        mode = 0;
    }

    //end the game when the timer has ended 
    if (time_elapsed >= game_time){
        ended = 1;
    }
    //if game has not ended, draw the holes for the diglets in the correct location
    if (ended == 0){
        for (var i = 0; i < rows; i++) {
            //odd rows
            if ((i % 2) == 0){
                for (var j = 60; j < width; j += 120){
                    drawHole(j,dy*(i+1));
                }
            }
            //even rows
            else {
                for (var j = 120; j < width; j += 120){
                    drawHole(j,dy*(i+1));
                }
            }
        }
        //draw every diglet in the array of diglets
        for (var index = 0; index < num_diglets; index ++){
            diglets[index].draw();
        }   
        //draw hammer in passive position     
        if (mode == 0) {
            fill(130,82,1);
            rect(mouseX-5,mouseY-25,10,50);
            fill(120);
            rect(mouseX-25,mouseY-35, 50,20);
        }
        //draw hammer in active position
        else {
            fill(130,82,1);
            rect(mouseX,mouseY-5,50,10);
            fill(120);
            rect(mouseX-10,mouseY-25, 20,50);
        }

        //display score and time left for the game
        fill(255);
        textSize(15);
        text("Score : " + num_hit, 400,340);
        text("Time Left : " + (game_time-time_elapsed)/2,5,340);
    }
    //game over screen
    else {
        fill(0);
        rect(0,0,width,height);
        fill(255);
        text("Game Over!", width/2 - width/10, height/2);
        text("Final Score : " + num_hit, width/2 - width/10,height/2 + height/15);
        text("Press R to restart", width/2 - width/10, height/2 + 2*height/15);
    }

}

//draw the hole sorry for much random numbers to make it look natural
function drawHole(x,y){
    fill(0);
    ellipse(x,y,80,40);
    fill(103,104,76);
    ellipse(x-40,y,22,12);
    ellipse(x+40,y,22,12);
    fill(90,77,65);
    ellipse(x-32,y+8,20,12);
    ellipse(x+28,y+8,24,14);
    fill(119,120,119);
    ellipse(x-22,y+13,20,12);
    ellipse(x+12,y+16,24,15);
    fill(100,100,100);
    ellipse(x-4,y+18,28,15);   
}


//object of diglet 
function diglet(x,y,duration){
    //base variables
    this.x = x;
    this.y = y;
    this.duration = duration;
    //draw the diglet, with eyes and body
    this.draw = function() {
        if (this.duration > 0) {
            //brown of diglet
            fill(181,147,119);
            rect(this.x-diglet_h/2,this.y-diglet_h,diglet_h,diglet_h);
            ellipse(this.x,this.y-diglet_h,diglet_h,diglet_h);
            
            fill(0);
            ellipse(this.x-diglet_h/6,this.y-diglet_h,3,6);
            ellipse(this.x+diglet_h/6,this.y-diglet_h,3,6);
            fill(255);
            ellipse(this.x-diglet_h/6,this.y-diglet_h-2,1,1);
            ellipse(this.x+diglet_h/6,this.y-diglet_h-2,1,1);
            //nose color
            fill(239,187,210);
            ellipse(this.x,this.y-diglet_h+6,diglet_h/3,5);
        }
    }
    //update whether the diglet appears
    this.update = function(){
        if (this.duration > 0){
            this.duration = this.duration - 0.5;
        }
        else {
            var temp_ratio = random(0,1);
            if (temp_ratio < 0.15){
                this.duration = random([1,2,3,4]);
            }
        }
    }
    //check if user clicked the diglet
    this.inDiglet = function(click_x,click_y){
        if (((click_x > this.x-diglet_h/2) & (click_x < this.x-diglet_h/2) && (click_y > this.y - diglet_h) && (click_y < this.y)) || (dist(click_x,click_y,this.x,this.y-diglet_h) < diglet_h)){
            if (this.duration > 0){
                this.duration = 0;
                num_hit += 1; 
            }   
        }
    }
}

//check  if when the mouse is pressed if it hits any diglet
function mousePressed() {
    for (var i = 0; i < num_diglets; i++){
        diglets[i].inDiglet(mouseX,mouseY);
    }
}

//when the game is over and you press r reset the game
function keyTyped(){
    if ((key === 'r') & (ended == 1)){
        ended = 0;
        time_elapsed = 0;
        ended = 0;
        num_hit = 0;
    }
}

akluk-Project 12- Proposal

For my final project, my partner and I have decided to create a series of animations that are time sensitive every day activities. We also wanted also have it as a very colorful vibrant, colorful and cartoonish style to make it fun for the user to see. We also wanted to incorporate involvement of the audience with the animation. Some examples of animations we wanted to make is like cooking an egg, making toast, baking a cake. Below are some inspirations and drafts of our ideas.

partner: Jessica Nip, jknip

Drafts of our final project

Inspiration for style and possible animations

akluk-Section A-LookingOutwards-12

The first project that I have chosen to write about is “I want You to Want Me” by Jonathan Harris. It was created in 2008 and was installed in the Museum of Modern art during valentines day on 2008. It is an interactive exhibit where every balloon is a unique dating profile/story where the user can choose which story/profile to view as well as the background of the display. I Want You To Want Me aims to be a mirror, in which people see reflections of themselves as they glimpse the lives of others. Below is the link to the project.
Link to project 1

Example of project 1

The second project that I have chosen to write about is Oily Stratum by Jared Tarbell. It was created in February 2003. It is a simple animation that is based on the laws of physics and tries to describe how to merge irregular objects based on cohesion and globual size.

Link to project 2

screenshot of second project

The two projects are similar in that they both abide by certain physical rules, one is more based on data that is unrelated to physical rules while the other is based on physical properties, which is impressive.

akluk-Project-11-TurtleFreeStyle

For this project, I simply just used a lot of randomization while trying to emulate the game of snakes with different colors for trails they leave. Below is an image of my draft

A simple draft

SImple example of what the program draws

sketch
//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Assignment-10-A

//define line weight, starting positions of turtles, right angle, 
//a unit of length for patterns, array of turtles, and max number of iterations
var line_weight = 10;
var r = 90;
var unit = 10;
var turtles = [];
var max_num = 34;
var cols = [];
function setup() {
    //setup canvas and stroke properties
    createCanvas(479, 479);
    background(255);
    stroke(0);
    strokeJoin(MITER);
    strokeCap(PROJECT);
    cols = [color(60,186,84),color(244,194,13),color(219,50,54),color(72,133,237)];
    //adds each turtle to its appropriate location, stroke weight
    //color, and also initial orientation. 
    for (var i = 0; i < cols.length; i++){
    	turtles.push(makeTurtle(width/2,height/2));
    	turtles[i].setWeight(line_weight);
    	turtles[i].setColor(cols[i]);
    	for (var j = 0; j < i ; j++) {
    		turtles[i].left(r);
    	}
	}
}


function draw() {
	for (var i = 0; i < turtles.length; i++){
		var k = random(10,30);
		var dir = random([0,1]);
		turtles[i].forward(k);
		if (dir == 0){
			turtles[i].left(r);
		}
		else {
			turtles[i].right(r);
		}
	}
}


function mousePressed(){
	turtles = [];
	for (var i = 0; i < cols.length; i++){
		turtles.push(makeTurtle(mouseX,mouseY));
    	turtles[i].setWeight(line_weight);
    	turtles[i].setColor(cols[i]);
    	for (var j = 0; j < i ; j++) {
    		turtles[i].left(r);
    	}
	}
}

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;
}

akluk – Section A – Looking outwards-11

For week 11’s Looking Outwards, I have decided to write about “If vi was ix” by TRUMPIN or Gerhard Trimpin.

I have written about a project of his in a previous looking outwards. In this project, he created a sound sculpture as the center piece of the Seattle’s Experience Music Project. It is basically a 50 ft sculpture with seven hundred acoustic and electric guitars. He also programmed the guitars to play music from all different kinds of genre from Scottish ballads to punk rock. He also wrote it so that the guitar could tune itself to make sure that it is in tune and in sync. It is also called the guitar tornado because it resembles the shape of a tornado. It doesn’t describe specifically what algorithms are used to create the program that plays different genres of music. What TRUMPIN always seems to do with his work is not only involve music or sound, but also incorporate a very unique visual aesthetic. Attached below is the link to the piece of work.

Link

akluk-SectionA-LookingOutwards-10


For this week’s looking outwards, I have chosen to report on Nova Jiang’s project Landscape Abbreviated. It is a kinematic maze constructed with modular planters with the capability of rotation which forms new paths and routes, while being a beautiful garden.

Image of the project

The parts of the maze is rotated and reconstructs is maze is controlled a computer program that obeys and follows certain mathematical algorithms. This makes the maze dynamic and ever changing, which encourages the audience to appreciate it from different angles and perspectives. I really appreciate that this project combines both natural and mechanical components. Nova Jiang holds a masters at UCLA. She seems to be currently an independent artist who creates projects that encourages the tactile and creative participation of the audience, resulting in structurally open systems in which joy, disorder and improvisation can thrive. Attached below is a link to the project.
Link

akluk-Project-10-Generative Landscape

Initially, I was going to make a generative landscape based on microscopic creatures. Such as what you would see under a microscope. However I later decided to go one layer more, and tried to portray the subatomic environment. For this project, I wanted to create a subatomic generative landscape. So the basis of in the subatomic environment, is the atom. And I had to decide how to create differing forms of atoms. Then I realized that atoms with different sizes also create different elements. I created 3 types of possible moving objects which are different sized atoms, with electrons wizzing around them. Below attached are some of my sketches.

Sketches for atoms

sketch

//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Project 10

var atoms = [];


function setup() {
    createCanvas(480, 480); 
    
    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        atoms[i] = makeAtom(rx);
    }
    frameRate(20);
}


function draw() {
    background(0); 
    
    push();
    
    stroke(0);
    fill(0); 
    rect(0,0, width, height);
    
    displayStatusString();

    updateAndDisplayAtoms();
    removeAtomsThatHaveSlippedOutOfView();
    addNewAtomsWithSomeRandomProbability(); 
    pop();
}


function updateAndDisplayAtoms(){
    // Update the building's positions, and display them.
    for (var i = 0; i < atoms.length; i++){
        atoms[i].move();
        atoms[i].display();
    }
}


function removeAtomsThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge,
    // remove it from the array.  This is quite tricky, but
    // we've seen something like this before with particles.
    // The easy part is scanning the array to find buildings
    // to remove. The tricky part is if we remove them
    // immediately, we'll alter the array, and our plan to
    // step through each item in the array might not work.
    //     Our solution is to just copy all the buildings
    // we want to keep into a new array.
    var atomsToKeep = [];
    for (var i = 0; i < atoms.length; i++){
        if (atoms[i].x + atoms[i].breadth > 0) {
            atomsToKeep.push(atoms[i]);
        }
    }
    atoms = atomsToKeep; // remember the surviving buildings
}


function addNewAtomsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newAtomLikelihood = 0.02; 
    if (random(0,1) < newAtomLikelihood) {
        atoms.push(makeAtom(width));
    }
}


// method to update position of building every frame
function atomMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function objectDisplay() {
    var floorHeight = 20;
    var particle_size = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(120); 
    noStroke(0); 
    push();
    translate(this.x, this.y);
    stroke(0);
    if (this.breadth == 1){
    	fill(color(255,0,0));
    	ellipse(0, 0, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(particle_size/4, particle_size/4 , particle_size, particle_size);
    }
    else if (this.breadth == 2){
    	fill(color(255,0,0));
    	ellipse(-particle_size/4, -particle_size/4, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(particle_size/4, -particle_size/4 , particle_size, particle_size);
    	fill(color(255,0,0));
    	ellipse(-particle_size/4, particle_size/4, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(particle_size/4, particle_size/4 , particle_size, particle_size);
    }
    else{
    	fill(color(255,0,0));
    	ellipse(-particle_size/3, particle_size/3, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(0, -particle_size/3 , particle_size, particle_size);
    	ellipse(particle_size/3, particle_size/3, particle_size, particle_size);
    }

    noStroke();
    fill(color(180,180,40));
    for (var i = 0; i < this.nFloors; i++) {
        ellipse(random(-particle_size,particle_size), random(-particle_size,particle_size), 5, 5);
    }
    pop();
}


function makeAtom(birthLocationX) {
    var bldg = {x: birthLocationX,
    			y: round(random(0,height)),
                breadth: random([1,2,3]),
                speed: -1.0,
                nFloors: round(random(2,8)),
                move: atomMove,
                display: objectDisplay}
    return bldg;
}


function displayHorizon(){
    stroke(0);
    line (0,height-50, width, height-50); 
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
    var statusString = "# Atoms = " + atoms.length;
    text(statusString, 5,20); 
}

akluk-SectionA-LookingOutwards-09

The project that my peer and I have chosen to talk about is the Hexagonal Generative Game of Life by Charlotte Dann.

A still of an iteration of the animation

I think the cited project is definitely one of the more interesting and mesmerizing generative art project that I have seen. I could just picture myself staring at the animation due to how much variation there is and how smooth and organic the movement is. I completely agree with my peer’s assessment and I think my peer’s assessment gives a very good and summative explanation of the project, and also explains very clearly what she thought was impressive about the project. I think Charlotte, the creator of this project is very honest on her progress, and explained what worked and what didn’t. I especially how she explain a very simple algorithm, where the “ant” just decides on one of two direction, could create such interesting and intricate systems and diagrams. Below is the link to her entire project and my peers evaluation.
Some of her initial drawings and ideas

Link to project
Link to Peer Evaluation

akluk-Project-09-portrait

sketch

// Alvin Luk
// akluk@andrew.cmu.edu
// Section A
// Project 9

// variable to store the image
var img;
var cur_x;
var cur_y;
var rand_x;
var rand_y;
var rand_t;
var type_shape;
var pix;
var siz;

function preload(){
  img = loadImage("https://i.imgur.com/z1yTE1v.jpg");
  img.loadPixels();
}

function setup(){
  createCanvas (477,478);
  background(255);
  noStroke();
  //set ellispe mode to center
  ellipseMode(CENTER);
  frameRate(10000);
}

function draw(){
  //Select random point on canvas to draw
  rand_x = random(img.width);
  rand_y = random(img.height);
  cur_x = floor(rand_x);
  cur_y = floor(rand_y);
  //get the value at the position of the image
  pix = img.get(cur_x, cur_y);
  //generate a random size of the shape
  siz = random(3,6);
  //randomize which shape to draw 
  type_shape = random([0,1,2]);
  fill(pix);

  //depending on the random value of type shape: choose triangle circle or square
  if (type_shape == 0){
  	triangle(cur_x, cur_y-(2/3)*siz, cur_x-(1/2)*siz, cur_y+(1/3)*siz, cur_x+(1/2)*siz, cur_y+(1/3)*siz); 	
  }
  else if (type_shape == 1){
  	ellipse(cur_x, cur_y,siz,siz);
  }
  else {
  	rect(cur_x-siz/2,cur_y-siz/2,siz,siz);
  }

}

For this portrait, I asked if my sister if I could use one of her older photos. For the project, I just played around with what variables I could randomize to make it more interesting. I decided to incorporate the three elementary shapes, a square, a triangle, and a circle to reconstruct my image. I also varied the size of the shapes that were used to reconstruct the image. Below are just some screen shots of the program, at it’s initial, intermediate, and “final” reconstruction of the image.

What the canvas looks like initially

Intermediate Stage

Final result

akluk – LookingOutwards-08

Sarah William is a current assistant professor of Urban planning as well as a director of the Civic Data Design Lab at MIT’s School of Architecture and planning. The Civic Data Design Lab at MIT utilizes data visualization and mapping techniques to analyze and visualize patterns at an urban scale and also allows different audience members to be able to understand the data and communicates the policies issues from the data. Digital Matatus is a project that I really liked, since it has such a simple design and yet so effectively conveys so much information.Below you can find a link to the works.
Link to her work
Something very interesting about the work she does is that she utilizes a lot of real life and real time data to create these very informative visuals. She believes that data is very essential and very important aspect of life. She believes that data could be used for both good and bad. She believes that it is how we use data which is what makes data truly powerful and impactful.

Screenshot of her work, Digital Matatus

Her presentation has a lot of logical flow to it, where she first explains the important concepts that enable her work, then explaining what some applications of those concepts. Finally establishing a baseline of what basic understanding of concepts, she explains her own project which at that point everyone will have clear understanding of. Below is a link to their presentation.