Final Project!

For my final project, I wanted to create a game that presents a picture at the end with hidden images that represent events of 2020. The user is able to click two images to switch the locations of the images, and therefore unscramble the original scrambled image that loads. In order not to pressure the user or make the user create one “right answer”, I chose not to tell the user when the image is “correctly” unscrambled. Therefore, the game acts more like a pressure-free artistic adaptation of an image if they’d like.

sketchDownload
// Susie Kim
// Final Project
// susiek@andrew.cmu.edu
// Section A

// set global variables
 var imgLinks = [
 "https://i.imgur.com/vGhpX7m.jpg", //1
 "https://i.imgur.com/bNtGvLH.jpg", //2
 "https://i.imgur.com/cWHfsai.jpg", //3
 "https://i.imgur.com/hnFyXIy.jpg", //4
 "https://i.imgur.com/06xo9FF.jpg", //5
 "https://i.imgur.com/FJbeTn2.jpg", //6
 "https://i.imgur.com/HZduFcW.jpg", //7
 "https://i.imgur.com/fU2goSM.jpg", //8
 "https://i.imgur.com/i4BVpfk.jpg", //9
 "https://i.imgur.com/dvCAEzm.jpg", //10
 "https://i.imgur.com/t7FzJVW.jpg", //11
 "https://i.imgur.com/MVcrDnK.jpg", //12
 "https://i.imgur.com/QUBppYU.jpg", //13
 "https://i.imgur.com/IPIsgqD.jpg", //14
 "https://i.imgur.com/Inkq9Nc.jpg", //15
 "https://i.imgur.com/FJotQ09.jpg"]; //16

gridRows = 4;
gridCols = 4;
sqSize = 100;

images = [];
puzzles = [];
ids = [];
shuffledIds = [];

clickedImgs = [];
numClicks = 0;

// preload image links into images array
function preload() {
	for (var i=0; i < 16; i++) {
	    images[i] = loadImage(imgLinks[i]);
	}
}

function setup() {
    createCanvas(500, 500);
    background(145, 168, 209);

    // write instructions text ontop and bottom
    fill(255);
    text('complete the puzzle to see the image :)', 150, 35);
    text('click 2 pictures to switch their location!', 150, 475);

    push();

    // write instructions text on left and right
    translate(250, 250);
    rotate(radians(90));
    text('2020 in review', -35, 225);

    rotate(radians(180));
    text('2020 in review', -35, 225);
    pop();


    // create a set of shuffled ids:
    for (var i = 0; i < 16; i++) {
    	ids[i] = i;
    }
    shuffledIds = shuffle(ids);

    // make 16 objects with object properties
    for (var i = 0; i < gridRows; i++) {
    	for (var j = 0; j < gridCols; j++) {
    		puzzles[j+i*4] = makePuzzle(50+j*100, 50+i*100, shuffledIds[j+i*4], j+i*4);
    	}
    }
}

function draw() {
	// draw the grid of shuffled images
	for (var i = 0; i < gridRows; i++) {
    	for (var j = 0; j < gridCols; j++) {
    		puzzles[j+i*4].display();
    	}
    }
}

// create an object that holds the images' properties
function makePuzzle(xlocation, ylocation, idNum, idNum2) {
	var makeImg = { x1: xlocation, 
	                y1: ylocation,
	                shuffId: idNum,
	                origId: idNum2,
	                display: makeImage }
	return makeImg;
}

// function that creates the image
function makeImage() {
	image(images[this.shuffId], this.x1, this.y1, 100, 100);
}

// if mouse is clicked on two images, switch them
function mouseClicked() {
	for (var i = 0; i < 16; i++) {
		if (mouseX > puzzles[i].x1 & mouseX < puzzles[i].x1+100 && // boundaries of any image i
			mouseY > puzzles[i].y1 && mouseY < puzzles[i].y1+100) {
			clickedImgs.push(puzzles[i].origId); // push original Id value of clicked image into clickedImgs array
		    numClicks += 1;
		}
	}
	// if 2 images are clicked, swap, and reset clicknum to 0
	if (numClicks == 2) {
		swapImages();
		numClicks = 0;
	}
}

// function that swaps the two images
function swapImages() {
	// store the x and y values in a temporary variable
	var tempX = puzzles[clickedImgs[0]].x1;
	var tempY = puzzles[clickedImgs[0]].y1

	// switch the x and y values
	puzzles[clickedImgs[0]].x1 = puzzles[clickedImgs[1]].x1;
	puzzles[clickedImgs[0]].y1 = puzzles[clickedImgs[1]].y1;

	puzzles[clickedImgs[1]].x1 = tempX;
	puzzles[clickedImgs[1]].y1 = tempY;

	// clear the clickedImgs array
	clickedImgs.pop();
	clickedImgs.pop();
}

Some examples of imagery I used was a basketball for Kobe Bryant’s death, a fire printed bag for the California and Australia wildfires, a tiger poster for Tiger King, and an Oscar for Parasite winning Best Picture.

Project 11: Landscape

For this week’s project, I really wanted to get away from the craziness of the semester and portray the calming view from the beach house my cousins and I used to go to. I have really vivid memories of sitting on the porch, eating fruit while watching the fireflies and water wade in and out at nighttime: something I wish I could be doing right now.

sketchDownload
// Susie Kim
// susiek@andrew.cmu.edu
// Section A
// Project 11

// set global variables
var landSpeed = 0.001;
var landFlow = 0.005;

var firefly = [];

var fWidth = 50;
var fLeft = 27 - fWidth;

// load in images for background
function preload() {
	feet = loadImage('https://i.imgur.com/VLK5brn.png');
	fruit = loadImage('https://i.imgur.com/NNwEjtA.png');
	cloud = loadImage('https://i.imgur.com/m6zIO0u.png');
}

function setup() {
    createCanvas(400, 480);
	background(29, 51, 81);
    imageMode(CENTER);

    // create fireflies at random locations on canvas
    for (var i = 0; i < 7; i++) {
    	var xLocation = random(20, 380);
    	var yLocation = random(0, 360);
    	firefly[i] = makeFireflies(xLocation, yLocation);
    }
}

function draw() {
	background(29, 51, 81);

	image(cloud, width/2, height/2-65, width-20, height-20); // background cloud image

	// blue water
	fill(147, 169, 209);
	noStroke();
	rect(0, 200, 400, 200);

    // call upon functions to draw land, foreground, and update fireflies
	land();
	createForeground();
	updateFirefly();
}

// draws front foreground porch, feet, and fruit dish
function createForeground() {
	fill(188, 158, 130);
	strokeWeight(1);
	stroke(124, 87, 61);

	// create porch base
	rect(0, 360, 400, 120);
	rect(0, 350, 400, 10);
	rect(0, 0, 30, 355);
	rect(370, 0, 30, 355);

	// insert self-drawn images of feet laying on porch and fruit
	image(feet, 100, 405, 150, 150);
	image(fruit, 300, 410, 125, 125);
}

// draws undulating sand landscape
function land() {
	fill(249, 228, 183);
	stroke(255);
	strokeWeight(8);

	beginShape();
	vertex(0, height);

	// undulating line of sandscape
	for (var x = 0; x < width; x++) {
		var a = (x*landFlow) + (millis()*landSpeed);
		var y = map(noise(a), 0, 1, height*12/20, height*11/20);
		vertex (x, y);
	}

	vertex(width, height);
	endShape();
}

// draws fireflies
function drawFirefly() {
	fill(255, 245, 0, 100);
	noStroke();
	push();

	translate(this.x1, this.y1); // allows fireflies to move depending on function
	scale(this.fireflySize); // allows fireflies to be scalable depending on make function
	ellipse(50, 50, 10, 10);
	ellipse(50, 50, 5, 5);

	pop();
}

// summons fireflies at given location with variables
function makeFireflies(xlocation, ylocation) {
	var makeFirefly = {x1: xlocation,
					   y1: ylocation,
					   fireflySize: random(0.25, 2),
					   speed: -1,
					   move: moveFirefly,
					   draw: drawFirefly}
	return makeFirefly;
}

// makes fireflies move across the page
function moveFirefly() {
	this.x1 += this.speed;
	if (this.x1 <= fLeft) {
		this.x1 += width - fLeft;
	}
}

// updates the array of fireflies
function updateFirefly() {
	for (i = 0; i < firefly.length; i++) {
		firefly[i].move();
		firefly[i].draw();
	}
}

Here is the main sketch that I did for this project:

LO-11

Emily Gobeille is an artist and the founder of “Design I/O”, a studio specializing in the creation of interactive storytelling installations and programs for children. As one of the head Partners and Creative Directors, she specializes in “concept development, visual design, interaction design and creative direction” throughout the company, and is said to have a playful approach to her projects. While I was unable to find her past education and work experience details, she has worked in the fields of web, print, and motion graphics, game design, and various installation art. 

The project I chose to investigate was “The Pack”, a game aimed at teaching computational thinking to a younger audience. Created as both a iOS application and computer game, the game revolves around the world of “Algos”, in which the user needs to find the missing seeds of Algos and restore its habitats to bring balance back into its world. Along the users journey, they encounter creatures and work on algorithms together, with the game getting progressively harder with more algorithms as the user advances. I especially found this project interesting, as the process of creating it combined both the visual interest of a designed game with the computational knowledge, both within the game and in the game’s creation, together to create a user friendly end product.

Project 10

For this week’s project, I decided to depict a chill night in that someone might have with their cats in a living room. I was feeling a bit stressed because of my classes, so I tried to go for more of a chill vibe that took various aspects of my existing room and blended them with auditory elements.

I did the initial drawings in illustrator, and imported each part as a different image.

sketchDownload
// Susie Kim
// susiek@andrew.cmu.edu
// Section A
// Project 10

// call global variables
var bgPhoto;

var cupcake;
var cupcakeX = 280;
var cupcakeY = 360;

var pointedHand;
var pointedHandX = 230;
var pointedHandY = 450;

var grabbingHand;
var grabbingHandX = 280;
var grabbingHandY = 450;

var tvScreen;
var musicNotes;
var mouth;

var count = 0;

var meow;
var tvTurnOn;
var eat;
var musicPlay;

function preload() {
    // load images
    bgPhoto = loadImage('https://i.imgur.com/SJVApbw.jpg');
    cupcake = loadImage('https://i.imgur.com/muqUIC2.png');
    pointedHand = loadImage('https://i.imgur.com/3HCNg3e.png');
    grabbingHand = loadImage('https://i.imgur.com/375PW9c.png');
    musicNotes = loadImage('https://i.imgur.com/FVRrvrB.png');
    tvScreen = loadImage('https://i.imgur.com/7mrIDoW.png');

    meow = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/catmeow.wav");
    tvTurnOn = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/tvsound.wav");
    eat = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/eating.wav");
    musicPlay = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/music1.wav");

}

function setup() {
    // you can change the next 2 lines:
    createCanvas(400, 400);
    frameRate(4);
    imageMode(CENTER);
    useSound();
}

function soundSetup() { // setup for audio generation
    meow.setVolume(1);
    tvTurnOn.setVolume(1);
    eat.setVolume(1);
    musicPlay.setVolume(1);
}

function draw() {
    count++; // add 1 frame for each time draw function runs

    image(bgPhoto, width/2, height/2, width, height); // set up background photo

    // have a hand come and take the cupcake on the table
    if (count >= 0 & count < 100) {
        image(cupcake, cupcakeX, cupcakeY, 40, 40); // place cupcake in scene
        image(grabbingHand, grabbingHandX, grabbingHandY, 100, 100); // place hand outside of scene, ready to grab
    }
    if (count > 30 & count < 45) { // bring hand into frame
        grabbingHandY -= 5;
    }
    if (count > 45 & count < 100) { // have hand take cupcake
        cupcakeY += 5;
        grabbingHandY += 5;
    }

    // eating sound from the person eating the cupcake
    if (count == 100) {
        eat.play();
    }

    // have both cats meow with mouths open
    catMouth();
    if (count >= 0 & count < 125) { // have mouths regular
        mouth = true;
    }
    if (count > 125 &  count < 155) { // have mouths open with meow sound
        mouth = false;
    }
    if (count == 126) {
        meow.play();
    }
    if (count > 155) { // mouths return back to normal after meow
        mouth = true;
    }

    // have hand come and touch remote to turn tv off
    tvOn();
    if (count >= 0 & count < 155) { // keep screen on
        screen = true;
    }
    if (count > 165 & count < 172) { // screen turns off as hand moves away
        screen = false;
        pointedHandY += 7;
    }
    if (count == 166) {
        tvTurnOn.play();
    }

    image(pointedHand, pointedHandX, pointedHandY, 100, 100);
    if (count > 140 & count < 155) { // hand comes to click remote
        pointedHandY -= 5;
    }

    // have hand come and touch remote again to play music on record player
    if (count > 165 & count < 173) { // hand comes to push button
        pointedHandX = 236;
        pointedHandY -= 5;
    }
    if (count > 185 & count < 213) { // hand moves away
        pointedHandY += 5;
    }
    if (count > 174) { // show music notes and play music
        image(musicNotes, 80, 70, 50, 50);
    }
    if (count == 175) {
        musicPlay.play();
    }
}

function tvOn() {
    if (screen == true) { // tv shows pink screen with flower when on
        image(tvScreen, 205, 145, 135, 90);
    }
    if (screen == false) { // tv is black when off
        fill(0);
        rectMode(CENTER);
        rect(205, 145, 134, 80, 8);
    }
}

function catMouth() {
    strokeWeight(.5);
    stroke(0);
    noFill();

    if (mouth == true) { // mouth closed when sitting
        line(220, 307, 225, 307); // white cat
        line(81, 276, 84, 276); // orange cat

    } else if (mouth == false) { // mouth open when meowing
        ellipse(223, 307, 5, 5); // white cat
        ellipse(83, 276, 3, 3); // orange cat

        // sound marks for white cat
        strokeWeight(1);
        stroke(255, 255, 0);
        line(260, 280, 270, 265);
        line(250, 280, 250, 265);
        line(240, 283, 230, 268);

        // sound marks for orange cat
        line(60, 238, 60, 251);
        line(50, 251, 45, 238);
        line(43, 253, 30, 240);
    }
}

LO-10

For this week’s LO, I decided to look into Imogen Heap’s “Mi Mu Gloves”, an idea of hers that was originally conceived in 2010 but only recently was able to be fabricated and prototyped for public consumption. Heap, originally only a musician, wanted to create the product to bring electronic music to another level, allowing artists to step away from their immobile instruments and connect with the audience. The gloves themselves have a mass amount of flex sensors, buttons, and vibrators that come together to simulate the feeling and sounds of real instruments. The gloves correspond over wifi with a dedicated software and algorithm that reads the movements of the wearer and translates them into sounds, depending on what the user records as inputs. 

It was interesting to see how technology has come as far to allow a musician to play instruments without having the physical instrument in front of them. I admire Heap’s ability to bring her dreams, which she dreamt up in 2010, to reality, even with barriers that existed, and the flexibility that the gloves could provide even to people with physical disabilities that don’t allow them to play instruments. This is demonstrated by Kris Halpen, whose life as a musician has been dramatically affected as a result of the Mi Mu gloves.

Project 9: Portrait

For this week’s project, I decided to abstractly depict a photo of my friend and I using the idea of a bitmap and pixels. I was inspired by various 8-bit art pieces that I had found online, and wanted to make my own interactive interpretation!

Depending on the mouse’s position, you can move around to see the pixels bigger, which ‘magnifies’ and makes clearer whatever part you are toggling over! Additionally, if you click the up and down arrow, you can see the “bitmap pixels” increase or decrease in number, respectively!

sketchDownload
// Susie Kim
// susiek@andrew.cmu.edu
// Section A
// Project 09

// set variables
var img;
var bitMap;
var grid = 19;

// load image
function preload() {
	var imgURL = "https://i.imgur.com/7Vy4Fqz.jpg";
	img = loadImage(imgURL);
}

function setup() {
    createCanvas(480, 380);
    background(255);

    img.resize(480, 380); // resize image to be canvas size
    img.loadPixels(); // load image pixels
}

function draw() {
	background(255);
	drawBits(); // call upon drawBits function
}

function drawBits() {
	noStroke();
	rectMode(CENTER);

	// make grid of rectangles, with each growing bigger or smaller depending on mouse position
	for (x = 0; x < 480; x += grid) {
		for (y = 0; y < 380; y += grid) {

			var dis = dist(mouseX, mouseY, x, y); // measure distance between mouse pos and each square bit
			var bitMap = map(dis, 0, 480, 11+(grid*.05), 3+(grid*.05)); // map width of each rectangle bit dependent on distance

			var bitColor = img.get(x,y); // get color for each rectangle bit
			fill(bitColor); 

			rect(x, y, bitMap+(grid*.35), bitMap+(grid*.35)); // draw grid of rectangles with width adjusting 
		}
	}
}

 function keyPressed() {
	// lock maximum "pixel" size at 23
	if (grid > 23) {
		grid = 23;
	}

	// lock minimum "pixel" size at 15
	if (grid < 15) {
		grid = 15;
	}

	// make "pixels" bigger with each click of up arrow, and smaller with click of down arrow
	if (keyCode === UP_ARROW) { // bigger
		clear();
		grid += 1;
	} else if (keyCode === DOWN_ARROW) { // smaller
		clear();
		grid -= 1
	}
} 
“low resolution” version
“mid resolution” version
“high resolution” version
the original image! (permission from my friend was obtained)

LO-9

For this week’s LO, I decided to revisit my friend Sean’s LO from Week 3, in which he wrote about BLOOMS, a group of sculptural computer fabricated pieces by John Edmark that was created around 4 years ago.

Sean mostly covered all the basics of the project, but upon more research, I was surprised to find out that the forms of the pieces are actually each based on a different algorithm, such as the Fibonnaci sequence or the golden rectangle/angle. Additionally, while Sean described the process that Edmark uses to create videos pretty accurately, I was surprised to learn that the timing between each frame is created using progressive rotations of the golden ratio, also known as phi. This angle and shape is mostly commonly seen in sunflower centers and pinecone-like forms in nature. I found it interesting that everything from the form to the frame timing ties in together to create nature-like forms in the final product: some of the forms even look like pinecones or something that could be found in a cellular structure of something. 

Looking Outwards 8

For this week’s LO, I decided to look into Eva Franch, who was the first female director of the renown Architectural Association School of Architecture up until a handful of months ago when she was controversially fired. Eva, who presented at Eyeo 2015, is from Catalonia and studied architecture there for a handful of years before she went on to teach at multiple American universities while founding her own practice, named Office of Architectural Affairs.

Franch’s work has addressed architecture within the context of technology and social, political, and economical issues, with her work aiming to provoke and project ideas about architecture’s standing in the current day and the future. She believes architecture has the responsibility and ability to articulate these fields, and aims to redefine the limits of architecture as a profession and role in society.

Her presentation methods, which vary from digital forms to collections of written articles, often contrast pros and cons of a given urban area she is studying, and re-emphasize architecture’s cyclical relationship between the social, political, and economic issues that can surround a city. She does not lose focus of reality, yet presents ideas and solutions that can be controversial and often viewed as utopic, as they push the boundary of what is defined as architecture.

Project 7: Curves

For this project, I was really inspired by some of the curves and the fact that the hypocycloid resembled the outline of a flower! I wanted to create something that was a cross between something resembling Tyler the Creator’s ‘golf wang’ line and a bed of moving flowers in the wind.

I therefore came up with my final product, which has flowers with centers that move and rotate depending on the user’s mouse position:

sketchDownload
// Susie Kim
// susiek@andrew.cmu.edu
// Section A, 15-104
// Assignment 7

// set global variables
var angle = 0;

function setup() {
    createCanvas(480, 480);
    frameRate(15);
}

function draw() {
	background(247, 202, 201); // sets background to pink tone

    // create grid of flowers, starting at 40, 40. results in a 5x5 grid of flowers.
	for(var x = 40; x <= 480; x+= 100) {
		for(var y = 40; y <= 480; y+= 100) {
			push();
			translate(x, y);

			// have flowers rotate depending on mouse X pos
			rotate(radians(angle));
	        angle += mouseX;

	        // call upon flower functions to draw flower outer and center
	        drawHypocycloid();
	        drawAstroid();

	        pop();
		}
	}
}

// draw blue flower exterior
function drawHypocycloid() {
	// set local variables
	var a = int(map(mouseX, 0, width, 15, 40));
	var b = int(map(mouseY, 0, height, 8, 13));
	
	// set colors and strokes
	fill(145, 168, 209); 
	strokeWeight(2);
	stroke(255);

	beginShape();
   
	// draw hypocycloids, with size increasing for mouse X and number of petals increasing with mouseY 
	for (var i = 0; i < 250; i++) { 
		var subAngle = map(i, 0, 110, 0, TWO_PI);
		var x = a*((b - 1)*cos(subAngle) + cos(subAngle) + cos((b - 1)*subAngle)) / b;
		var y = a*((b - 1)*sin(subAngle) + sin(subAngle) + sin((b - 1)*subAngle)) / b;
		vertex(x,y);
	}
	endShape();
}

// draw yellow center of the flowers
function drawAstroid() {
    // set colors and strokes
	fill(255, 255, 0);
	strokeWeight(.1);
	stroke(255);

	beginShape();

	// draw for each astroid, with size increasing with mouse X position
	for (var i = 0; i < 300; i++) {
		var subAngle = map(mouseX, 0, width, 7, 15); // changes size with X pos
		var x2 = subAngle*pow(cos(i), 5);
		var y2 = subAngle*pow(sin(i), 5);
		vertex(x2, y2);
	}
	endShape();
}
my inspiration image!

Looking Outwards 7

For this week, I chose to focus on Stamen’s project called “Getty Institute: Ed Ruscha’s Photo Archive”, a computational organization and documentation of Ed Ruscha’s photo archives of Los Angeles. These photographs were taken from a car-mounted camera, which when driven, would document the buildings and street views of Los Angeles’ Sunset Strip. This documentation continued every few years, creating a dynamic record of the changing views of the street. 

The photos, however, were never digitized, which made it hard to visualize the change in the strip over time: hence the implication of the dynamic interface created. With the use of “AI-generated tags”, Stamen was able to sort through the photos and create an interface that allows the user to virtually “drive” through the street and visualize the change over time. The interface simultaneously shows multiple years of change stacked on top of each other as the user “drives” through the map that is sandwiched in the middle. One is also able to zoom or sort through specific photos with keywords. This project is therefore a combination of both the algorithms created that easily sorts and orders photos, and the ‘creative’ part of the interface that allows the user to drive the car.

Capture of the Interface itself