// William Su
// Section E
// wsu1@andrew.cmu.edu
// Final Project
var timer = 0;
let x = 0; //person position x
let x1 = 0;
let ender = 0; //variable used to end a scene.
let years; //calculate random years.
let miles; //calculate random miles.
function setup() {
createCanvas(windowWidth, 750); //Full window
textSize(14);
frameRate(60);
//preload images
Store = loadImage('https://i.imgur.com/L4qngWN.png');
walkin = loadImage('https://i.imgur.com/W2fK1A3.png');
walkout = loadImage('https://i.imgur.com/C5LA4S1.png');
broken = loadImage('https://i.imgur.com/aebY3Uk.png');
iphone = loadImage('https://i.imgur.com/iI6LMAU.png');
iphoneInside = loadImage('https://i.imgur.com/pL2oAbJ.png');
battery = loadImage('https://i.imgur.com/9oZjkzY.png');
numberGen(); //Generate random years and miles.
}
function draw() {
background(255);
//timer starts and 0 and increments every frame of draw.
if (timer > 0) {
background(255);
image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
image(walkin, 800 - x, windowHeight/2 - 8, 20, 30);
if(x <= 240) {
x += 2;
} else {
x = 590;
}
}
if (timer > 110) {
push();
strokeWeight(2);
fill(255);
beginShape();
vertex(558, windowHeight/2 - 8);
vertex(565, windowHeight/2 - 12);
vertex(565, windowHeight/2 + 24);
vertex(558, windowHeight/2 + 20);
endShape(CLOSE);
pop();
}
if (timer > 130) {
background(255);
image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
}
if (timer > 140) {
background(255);
image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
push();
fill(100);
text("Billions of smartphones are sold every year...", windowWidth/2 - 150, windowHeight/2 + 50);
pop();
}
if (timer > 340) {
background(255);
image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
push();
fill(100);
text("But how far can one get...", windowWidth/2 - 150, windowHeight/2 + 50);
pop();
}
if (timer > 480) {
background(255);
image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
push();
fill(100);
text("before needing to get a new one?", windowWidth/2 - 150, windowHeight/2 + 50);
pop();
}
if (timer > 620) {
background(255);
image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
push();
fill(100);
text("Lets find out >\n(Right Arrow Key)", windowWidth/2 - 150, windowHeight/2 + 50);
pop();
}
if (timer > 620 & x1 > 0) {
background(255);
image(Store, 500 - x1, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
push();
fill(100);
text(x1.toString(), windowWidth/2 - 35, windowHeight/2 + 50);
pop();
image(walkout, 590, windowHeight/2 - 8, 20, 30);
if (keyIsDown(RIGHT_ARROW)) {
x1 += 10;
}
}
if (x1 >= totalMiles) {
background(255);
//image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
image(broken, 590, windowHeight/2 - 11, 20, 30);
push();
fill(100);
text("This person has traveled " + totalMiles.toString() + " miles.", windowWidth/2 - 150, windowHeight/2 + 50);
text("Their phone lasted " + years.toString() + " years.", windowWidth/2 - 150, windowHeight/2 + 65);
text("What makes them fail and\nwhy do companies design it that way?", windowWidth/2 - 150, windowHeight/2 + 95);
pop();
ender += 1;
}
//Landscape Line
push();
strokeWeight(3);
line(0, windowHeight/2 + 20, windowWidth, windowHeight/2 + 20);
pop();
//Borders
push();
noStroke();
fill(255);
rect(0,0, windowWidth/2 - 200, windowHeight);
pop();
push();
noStroke();
fill(255);
rect(windowWidth/2 + 200,0, windowWidth, windowHeight);
pop();
if (ender > 450) { //End scene and move to parts of a phone.
background(255);
//image(Store, 500, windowHeight/2 - 100, Store.width / 2, Store.height / 2);
image(iphone, windowWidth/2 - 150, windowHeight/2 - 200, 300,400);
image(iphoneInside, windowWidth/2 + 50, windowHeight/2 - 200, 300,400);
image(battery, windowWidth/4, windowHeight/2 - 200, 300,400);
push();
noStroke();
fill(255);
rect(windowWidth/2 + 100, windowHeight/2 - 60, 110,250);
pop();
if (mouseX >= windowWidth/4 + 70 & mouseX <= windowWidth/4 + 70 + 115) {
push();
noFill();
stroke(255,0,0);
strokeWeight(4);
rect(windowWidth/4 + 70, windowHeight/2 - 95, 115,270);
pop();
text("Lithium-Ion Battery | Lifespan: 3-5 years\nOne of the most common areas of failure.\nThese also contain many of toxic substances that make it difficult to recycle.", windowWidth/2 - 250, windowHeight/2 +200);
}
if (mouseX >= windowWidth/2 - 90 & mouseX <= windowWidth/2 + 90) {
push();
noFill();
stroke(0,255,0);
strokeWeight(4);
rect(windowWidth/2 - 90, windowHeight/2 - 180, 180, 360);
pop();
text("Screen / Outer Hardware | Lifespan: Varies\nThe most common failure point.\nNowadays, if a screen is cracked, its often cheaper to buy a new phone.", windowWidth/2 - 250, windowHeight/2 +200);
}
if (mouseX >= windowWidth/2 + 120 & mouseX <= windowWidth/2 + 160 + 115) {
push();
noFill();
stroke(0, 0, 255);
strokeWeight(4);
rect(windowWidth/2 + 120, windowHeight/2 - 180, 160, 360);
pop();
text("Circuitboard / Chips | Obsolete: 2 years\nNot common to fail, in fact chips are designed to work for 20-30 years.\nHowever, the technology quickly becomes obsolete due to newer, more powerful chipsets being developed.", windowWidth/2 - 250, windowHeight/2 +200);
}
}
timer += 1; //increment timer per call of draw.
}
function keyPressed() { //Detect right arrow key press.
if (keyCode === RIGHT_ARROW) {
x1 += 1;
}
}
function numberGen() { //Generate numbers.
let years1 = random(1, 4);
years = nf(years1, 1, 2);
miles1 = int(random(1300, 1500));
miles = nf(miles1, 4, 2);
totalMile1 = (miles * years);
totalMiles = nf(totalMile1, 4, 2);
}
function mousePressed() { //Detect mouse press.
return true;
}
For my project, I wanted to highlight the issue of planned obsolescence in our everyday electronics through a simple interactive “scene”. Basically I wanted to show the briefness with which our phones are usable relate it to approximately how many miles we could walk before they utterly fail or become obsolete. At the end, the scene changes and shows some of the places where a phone is designed to fail in 2-3 years.
This project was made to fit the full view width of a window so it might not be completely viewable on wp.
Video Link: https://youtu.be/2isZoRcILBk
]]>I’m inspired by these 2 projects because of their simplicity and how much they catch your attention. In the first project, all the eye pupils follow where the mouse is. When you hold the click, it changes to a grid of black dots that act like a wave when your mouse comes near them. It’s a very interesting switch between different kinds of “moods” which I really like.
Im not sure if this second project uses P5 but the website: http://www.distancetomars.com/. I really like the storytelling aspect of it and how it uses the website window itself to illustrate how far Mars is from Earth.
As a back-up, I will likely do a game with custom sprite animations. It would probably have an 8-bit aesthetic with simple controls and objectives.
// William Su
// Section E
// wsu1@andrew.cmu.edu
// Project 11
var terrainSpeed1 = 0.0002;
var terrainDetail1 = 0.0007;
var terrainSpeed2 = 0.0002;
var terrainDetail2 = 0.001;
var terrainSpeed3 = 0.0003;
var terrainDetail3 = 0.005;
var c1, c2;
function draw() {
ellipse(mouseX, mouseY, 30, 30);
}
function setup() {
createCanvas(480, 480);
c1 = color(255, 204, 0); //Gradient Sky
c2 = color(255);
setGradient(c1, c2);
frameRate(30);
}
function draw() {
fill(255, 251, 130);
ellipse(width/2, height/2 - 40, 40, 40); //Sun
water3(); //Distant water
DrawBoat(); //Fixed Boat
water2(); //Middle Water
water1(); //Near Water
}
function setGradient(c1, c2) {
// noprotect
noFill();
for (var y = 0; y < height; y++) {
var inter = map(y, 0, height, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(0, y, width, y);
}
}
function water1() {
noStroke();
fill(90, 200, 250);
beginShape();
for(var x = 0; x < width; x++){
var t = (x * terrainDetail1) + (millis() * terrainSpeed1);
var y = map(noise(t), 0, 2, 400, 300);
vertex(x, y);
}
vertex(width, height);
vertex(0, height);
endShape(CLOSE);
}
function water2() {
noStroke();
fill(72, 150, 200);
beginShape();
for(var x = 0; x < width; x++){
var t = (x * terrainDetail2) + (millis() * terrainSpeed2);
var y = map(noise(t), 0, 1, 330, 300);
vertex(x, y);
}
vertex(width, height);
vertex(0, height);
endShape(CLOSE);
}
function water3() {
noStroke();
fill(60, 200, 250);
beginShape();
for(var x = 0; x < width; x++){
var t = (x * terrainDetail3) + (millis() * terrainSpeed3);
var y = map(noise(t), 0, 2, 250, 200);
vertex(x, y);
}
vertex(width, height);
vertex(0, height);
endShape(CLOSE);
}
function DrawBoat() { //Boat
push();
fill(150,75,0);
rect(width/2,height/2,5,60);
pop();
noStroke();
push();
fill(250);
triangle(width/2 - 30, height/2 + 50, width/2 + 2, 220, width/2 + 30, height/2 + 50);
pop();
push();
fill(140);
arc(width/2, height/2 + 60, 100, 80, 0, PI, CHORD);
pop();
}
I decided to make a generative landscape of the ocean. I made 3 wave “layers” and had a fixed object in the horizon.
]]>Aiva is an Artificial Intelligence capable of composing emotional soundtracks for a variety of media like films, video games, and commercials.
According to the team that worked on AIVA, it was trained to compose music composition by reading through a large collection of music partitions from Mozart, Beethoven, Bach, etc. It created a mathematical model of what music is and uses it to make its own unique pieces.
As someone who has worked on and with AI, the making of an AI musical composer doesn’t really come as a surprise to me. In fact, stuff like this has been around for ages like with vocaloids or other computer generated music technologies. What really interests me is how AI is accepted by society. Recently, AIVA became the first virtual artist to have its creations registered with an author’s rights society (SACEM). According to the team, this will not replace musicians or “steal” any jobs. However, this comes into question, when will an AI become so good at what it is trained to do that it could replace humans? And how will we respond to it? In this particular case, it looks like AIVA is marketed more as a tool but it is clear that it can save time, work, and money, maybe better than a trained musician.
]]>For this project I saw the opportunity to make a simple game. In this case, a very cruddy p5 version of CS:GO. Enjoy!
//William Su
//wsu1@andrew.cmu.edu
//Section E
//Project 10
var bgurl = "https://i.imgur.com/CYEy7BV.jpg"; //background.
var muzzleFlash = "https://i.imgur.com/68jJZkV.png"; //muzzle flash from the tip of gun.
var mfTrue = false; //currently false if no click;
var T1Alive = true; //Whether enemies are currently alive or not.
var T2Alive = true;
var T3Alive = true;
var Tenemy = "https://i.imgur.com/Nh8X1RG.png"; //Enemy image
var bg; // Background img
var mf; // MuzzleFlash
var T1HitCount = 0; //Number of times each enemy has been hit.
var T2HitCount = 0;
var T3HitCount = 0;
function preload() {
bg = loadImage(bgurl);
mf = loadImage(muzzleFlash);
T1 = loadImage(Tenemy);
T2 = loadImage(Tenemy);
T3 = loadImage(Tenemy);
// Local File
// AKshot = loadSound("assets/AK.mp3");
// Death = loadSound("assets/Death.mp3");
// Death2 = loadSound("assets/Death2.mp3");
// Hit = loadSound("assets/Hit.mp3");
AKshot = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/AK.mp3");
Death = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/Death.mp3");
Death2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/Death2.mp3");
Hit = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/Hit.mp3");
}
function setup() {
createCanvas(720, 400);
bg.resize(720,400);
frameRate(60);
noCursor();
}
function draw() {
if (mfTrue == true) { //If mouse pressed, activate muzzle flash.
mfTrue = false; //Reset muzzle flash as false.
image(bg, 0, 0);
image(mf, 230, 30); //Draw muzzle flash and background.
} else {
image(bg, 0, 0);
}
//Draw the three enemies.
if (T1Alive == true) {
push();
image(T1,180,180);
T1.resize(35,70);
pop();
}
if (T2Alive == true) {
push();
image(T2,500,180);
T2.resize(25,50);
pop();
}
if (T3Alive == true) {
push();
image(T3,370,192);
T3.resize(13,26);
pop();
}
if (T1Alive == false & T2Alive == false && T3Alive == false) { //Reset if all enemies are dead.
T1Alive = true;
T2Alive = true;
T3Alive = true;
}
crosshairs(); //Draw Crosshair
}
function crosshairs() { //Crosshair
stroke("white");
strokeWeight(2);
line(mouseX,mouseY,mouseX+20,mouseY);
line(mouseX,mouseY,mouseX-20,mouseY);
line(mouseX,mouseY,mouseX,mouseY+20);
line(mouseX,mouseY,mouseX,mouseY-20);
}
function mousePressed() {
//Play gunshot every click.
AKshot.play();
mfTrue = true;
//Enemy 1 Hitbox
if(mouseX > 180 & mouseX < 205 && mouseY > 180 && mouseY < 250 && T1Alive == true) {
if (T1HitCount <= 4) { //Need 5 hits to kill.
Hit.amp(2.5);
Hit.play();
T1HitCount += 1;
} else { //Play death
Death.amp(3);
Death.play();
Hit.amp(2);
Hit.play();
T1Alive = false;
T1HitCount = 0;
}
}
//Enemy 2 Hitbox
if(mouseX > 500 & mouseX < 525 && mouseY > 180 && mouseY < 230 && T2Alive == true) {
if (T2HitCount <= 4) { //Need 5 hits to kill.
Hit.amp(2.5);
Hit.play();
T2HitCount += 1;
} else { //Play death
Death2.amp(3);
Death2.play();
Hit.amp(2);
Hit.play();
T2Alive = false;
T2HitCount = 0;
}
}
//Enemy 3 Hitbox
if(mouseX > 370 & mouseX < 383 && mouseY > 192 && mouseY < 218 && T3Alive == true) {
if (T3HitCount <= 4) { //Need 5 hits to kill.
Hit.amp(2.5);
Hit.play();
T3HitCount += 1;
} else { //Play death
Death.amp(3);
Death.play();
Hit.amp(2);
Hit.play();
T3Alive = false;
T3HitCount = 0;
}
}
}
]]>I was also really intrigued by Danny Cho’s topic in Looking Outwards 05. The animation by Alexey Kashpersky was very beautiful and mesmerizing to look at. It was more like a performance or visual story than a scientific, informational animation that one would’ve expected from just looking at the topic.
I do wonder what the purpose of doing such a visually beautiful animation of the respiratory system is. While very interesting to look at, I can’t imagine it being useful for “education” with its lack of hard information. For example, What do these molecules do?, What are they called?, etc. But then again, its cool af and who cares at that point right?
]]>// William Su
// Section E
// wsu1@andrew.cmu.edu
// Porject 09
var underlyingImage;
function preload() {
var myImageURL = "https://i.imgur.com/zvGQCAe.jpg"; //My image
underlyingImage = loadImage(myImageURL);
}
function setup() {
createCanvas(384, 480);
background(0);
underlyingImage.resize(384,480); //resize portrait image to fit the canvas
underlyingImage.loadPixels();
frameRate(1000); //Increased framerate
}
function draw() {
//All similar to example
var px = random(width);
var py = random(height);
var ix = constrain(floor(px), 0, width-1);
var iy = constrain(floor(py), 0, height-1);
var theColorAtLocationXY = underlyingImage.get(ix, iy);
//random number generator from 0 - 2
let r = int(random(0,2));
strokeWeight(r);
stroke(100 * r);
fill(theColorAtLocationXY);
rect(px, py, 10, 10); //Fill rectangle at location of sampled color.
var theColorAtTheMouse = underlyingImage.get(mouseX, mouseY);
var HiImWill = ["Hi", "I'm", "Will"]; //Initializing a simple list of words.
fill(theColorAtTheMouse); //fill color at mouse location
textSize(16);
//draws random words from list
text(HiImWill[r],mouseX, mouseY);
}
For this project, I used a combination of squares, strokes, and words to generate a portrait of myself. I added variability
]]>Speaker: Robert Hodgin
Robert Hodgin is an artist/coder living in Brooklyn. His work ranges from simple 2D data visualizations to immersive 3D terrain simulations. Primary interests include theoretical physics, astronomy, particle engines, and audio visualizations. He works in Java, Processing, C++, Cinder, OpenGL, and GLSL.
He graduated in 1998 with a degree in Sculpture from the Rhode Island School of Design.
I was especially interested in Robert’s credentials and where he started out. He graduated from RISD with a degree and sculpture but eventually worked on data and coding heavy projects. The reason why I was so interested is I find myself relating to his pathway in life where I thought I was going to be an engineer coming out of high school but ended up studying design in college. Robert makes effective use of artistic storytelling and easy to understand work processes to describe the how’s and why’s of his body of work. The ones that involve 3d simulations of the earth mesmerize me with their level of detail and use of live data of weather, auroras, time, and terrain.
]]>This is a data visualization made by IDEO for mapping a wide variety of fonts. It’s really interesting to see a spectrum of typography laid out in front of you. From calligraphic and more abstract letters to more orderly and well recognized stuff like Roboto or Helvetica, I can imagine this being somewhat useful in helping designers or people working with type to visually see what kinds of fonts they can use. Whats also interesting to note is that the designers at IDEO used an AI that is trained on all kinds of fonts and used it to categorize them in this visualization. While it might be hard for humans to define something mundane like a letter “A”, an artificial intelligence can come up with its own definitions and generate an easy to understand visual for us.
]]>