/*
Christine Chen
Section E
cyc1@andrew.cmu.edu
Final Project
*/
var heartArray = [];
var heartCount = 0;
var carrotArray = [];
var carrotCount = 0;
var bombArray = [];
//location where the things that are collected disappear
var collect = 340;
//-------------------------------------
function setup() {
createCanvas(600, 400);
}
//-------------------------------------
function draw() {
background(255, 178, 220); //light pink background
backgroundHeart();
bunny();
renderHeart();
renderCarrot();
renderBomb();
pointDisplay();
gameOver();
}
//-------------------------------------
//***** HEART *****
function makeHeart(x, y) {
return {
x: x,
y: y,
draw: drawHeart,
}
}
function drawHeart() { //draw shape of heart
strokeWeight(0.3);
noStroke();
//color of heart changes to give glittering effect
fill(255 - random(0, width), 116, 208);
ellipse(this.x - 5, this.y, 11, 11);
ellipse(this.x + 5, this.y, 11, 11);
triangle(this.x - 10.5, this.y + 2,
this.x + 10.5, this.y + 2,
this.x, this.y + 13);
}
function renderHeart() {
//creates new heart every 30 frames
if (frameCount % 30 == 0) {
var newHeart = makeHeart(random(10, width - 10), 0);
heartArray.push(newHeart);
}
//updates heart's y location(make them fall)
for (var i = 0; i < heartArray.length; i ++) {
var heart = heartArray[i];
heart.y += 1.5;
//remove hearts that are gone (off of canvas)
//saves space to prevent codes from running slow
if(heart.y > height) {
heartArray.splice(i, 1);
}
//remove hearts that are collected
if(dist(mouseX, collect, heart.x, heart.y) < 20) {
heartArray.splice(i, 1);
heartCount++; //keeps track of heart points
}
heart.draw();
}
}
//***** CARROT *****
function makeCarrot(x, y) {
return {
x: x,
y: y,
draw: drawCarrot
}
}
//draws shapes of carrot
function drawCarrot() {
//carrot stem
fill(17, 147, 8); //green
ellipse(this.x, this.y - 5, 5, 15);
ellipse(this.x - 3, this.y - 5, 5, 15);
ellipse(this.x - 7, this.y - 5, 5, 15);
ellipse(this.x + 3, this.y - 5, 5, 15);
ellipse(this.x + 7, this.y - 5, 5, 15);
//carrot body
fill(255, 117, 25); //orange
triangle(this.x - 10, this.y,
this.x + 10, this.y,
this.x, this.y + 30);
}
function renderCarrot() {
//creates new carrot every 600 frames
if (frameCount % 600 == 0) {
var newCarrot = makeCarrot(random(10, width - 10), 0);
carrotArray.push(newCarrot);
}
//updates carrot location
for (var i = 0; i < carrotArray.length; i ++) {
var carrot = carrotArray[i];
carrot.y += 5; //carrot falls quite fast
//removes carrots that are gone(off of canvas)
if(carrot.y > height) {
carrotArray.splice(i, 1);
}
//removes carrots that are eaten
if(dist(mouseX, collect, carrot.x, carrot.y) < 20) {
carrotArray.splice(i, 1);
carrotCount++; //keeps track of number of carrots collected
}
carrot.draw();
}
}
//***** BOMB *****
function makeBomb(x, y) {
return {
x: x,
y: y,
draw: drawBomb,
}
}
//draws shape of bomb
function drawBomb() {
//spark
fill(255, 0, 0); //red
ellipse(this.x + 20, this.y - 23, 10, 10);
//bomb line
stroke(0); //black
strokeWeight(2);
line(this.x, this.y, this.x + 18, this.y - 20);
//bomb body
noStroke();
fill(48, 47, 47); //dark gray
ellipse(this.x, this.y, 30, 30);
}
function renderBomb() {
//creates bomb every 100 frames
if (frameCount % 100 == 0) {
var newBomb = makeBomb(random(10, width - 10), 0);
bombArray.push(newBomb);
}
//updates bomb location
for (var i = 0; i < bombArray.length; i ++) {
var bomb = bombArray[i];
bomb.y += 6;
//removes bomb that is gone (off of canvas)
if(bomb.y > height) {
bombArray.splice(i, 1);
}
//removes bomb that is collected
if(dist(mouseX, collect, bomb.x, bomb.y) < 30) {
bombArray.splice(i, 1);
//heart point deducted by 10 points if bomb collected
heartCount -= 10;
//carrot point deducted by 1 if bomb collected
carrotCount -= 1;
}
bomb.draw();
}
}
//***** BUNNY *****
function bunny() {
//constrain bunny location to inside canvas
var control = constrain (mouseX, 15, width - 15);
noStroke();
fill(255); //white
//body
fill(255); //white
ellipse(control, 370, 55, 50);
//feet
ellipse(control - 15, height - 5, 20, 10); //left
ellipse(control + 15, height - 5, 20, 10); //right
//hands
ellipse(control - 27, height - 45, 20, 10); //left
ellipse(control + 27, height - 45, 20, 10); //right
//ears
ellipse(control - 8, 300, 10, 30); //left
ellipse(control + 8, 300, 10, 30); //right
//face
ellipse(control, 330, 70, 50);
//eyes
fill(0);
ellipse(control - 5, 325, 5, 5); //left
ellipse(control + 5, 325, 5, 5); //right
//mouth
fill(255, 122, 169); //pink
ellipse(control, 338, 12, 10);
//nose
fill(0);
ellipse(control, 331, 5, 4);
//blush
fill(252, 204, 204); //light red
ellipse(control - 10, 331, 10, 7); //left
ellipse(control + 10, 331, 10, 7); //red
}
//***** GAMEOVER *****
function gameOver() {
//if carrot point is less than 0,
//or if heart point is or less than -100,
//game ends
if (carrotCount < 0 || heartCount <= -100) {
noLoop();
//gameover sign background
fill(167, 0, 47); //red
rectMode(CENTER);
rect(width/2 - 10, height/2 - 10, 260, 70);
//gameover sign text
fill(255);
textSize(22);
textAlign(CENTER);
text(" G A M E O V E R", width/2 , height/2);
//skull
fill(255); //white
ellipse(width/2 - 100 , height/2 - 10, 30, 22);
rect(width/2 - 100 , height/2, 16, 10);
//skull eyes
fill(50);//gray
ellipse(width/2 - 105 , height/2 - 10, 7, 7);
ellipse(width/2 - 95 , height/2 - 10, 7, 7);
}
}
//***** POINT DISPLAY *****
function pointDisplay() {
stroke(0); //black
strokeWeight(0.2); //light outline
fill(250, 214, 226); //pink
rect(10, 10, 180, 60);
//heart
noStroke();
fill(108, 136, 255);
ellipse(35, 35, 11, 11);
ellipse(45, 35, 11, 11);
triangle(29.5, 37,
50.5 , 37,
40, 48);
//heart count text
fill(30);
textSize(20);
text("= " + heartCount, 55, 45);
//carrot
fill(17, 147, 8); //green
ellipse(120, 25 , 5, 15);
ellipse(117, 25, 5, 15);
ellipse(113, 25, 5, 15);
ellipse(123, 25, 5, 15);
ellipse(127, 25, 5, 15);
fill(255, 117, 25); //orange
triangle(110, 30,
130, 30,
120, 60);
//carrot count text
fill(30);
textSize(20);
text("= " + carrotCount, 140, 45);
}
//***** BACKGROUND HEART *****
function backgroundHeart() {
noStroke();
fill(253, 158, 209); //pink
ellipse(180, 140, 260, 270);
ellipse(420, 140, 260, 270);
triangle(73, 220,
width - 73 , 220,
width/2, height - 5);
ellipse(width/2, 220, 80, 80);
}
How to play:
– Move bunny left and right with mouse to control bunny’s position
– All things have to touch bunny’s mouth to be effective
– Collect hearts to gain points
– Collect carrots to store as lives
– Carrots save the bunny when bomb hits the bunny
– Bomb takes away bunny’s lives and deduct 10 heart points
– Bunny dies when heart point is -100 or when bomb hits bunny and there is no carrot to save bunny
Statement:
For my project, I decided to create a game that involves a bunny and heart rain. I wanted to create a simple, cute game that people can play with. Hearts are points and the carrots are lives. The bomb is what kills the bunny. The player should aim to gain as many heart points as possible. The stored carrots save the bunny from dying in the case that the bomb hits the bunny. I made the bomb fall fast on purpose so that it will be harder to escape the bomb, adding some excitement to the game. I also made the carrots, which rarely appears (to make the carrots more precious), fall fast. 10 heart points are deducted if the bunny hits the bomb. This is so that the player can’t keep using carrots to save the bunny while not collecting hearts. I made the background simple for this game as because of the “glittering effect” of the heart and the movement of the things falling, having more complicated background will confuse the player’s eyes too much. Initially, I made the hearts simply pink, but then I thought that was too boring and so I changed my codes so that they change colors randomly to create a glittering effect. The things have to touch the bunny’s mouth to be effective as my idea is that the bunny “eats” the things to collect them. For my codes, I used a lot of nested functions to make my codes clearer and easier to manipulate. I had a lot of fun creating this project as I have always wanted to create a cute game with movements of hearts that people can play with that cheers them up on bad days.
For my final project, I want to create a game that has something to do with mouse interactions. I will be creating a tree that constantly has objects falling from it. The objects are apples, golden apples, and bird poop. The task of the users is to catch the apples with the basket through controlling the mouse x position. If the users catch a apple, they will get 1 point. If the users catch a bird poop, the game will end. If the users catch a golden apple, they will get a bonus life that will save them from losing the game if they catch a bird poop later on. The background would be a generative one that has birds flying around. The color of the day will change according the the time when the user is playing the game. I am still currently thinking of other things to add to the game, such as having a naughty kid that comes in every now and then who steals the apple, or speeding up the velocity of the falling apple over time.
]]>Camille Utterback’s Glimpseand Theo Watson and Emily Gobeille’s work Living Libraryare two projects that interested me.
Utterback created Glimpsefor a collector’s foyer. It is an interactive multi-monitor piece that turns the entryway of the foyer into a dynamic experience for people who pass through. The visual shapes evolve according
to the people’s movement. The shapes that are created remain in the background, and the work continues to evolve as others come and go. What I admire most about this project is how it invites everyone to create one artwork, allowing people to somehow connect to each other. Another interesting thing about this work is how it turns the space into an interesting experience for people, adding some sparks into their daily lives as they pass through the foyer.
Above shows a video of Watson and Gobeille’s work Living Library, Source: https://vimeo.com/203193098
Like Glimpse, Watson and Gobeille’s work Living Library is also an interactive work. It works with the Connected World exhibition. The work utilizes two cameras and a laser light source projector. The cameras track the visitor’s hand’s positions, allowing them to trigger animations through motions. How the creators turn a book reading experience into a more interactive one fascinates me as now things that are limited by prints, such as sound and colors, are brought into life through animations.
Both Glimpse and Living Libraryuses motions to control the created visuals. This is what I would like to explore in my project. Even though it would be quite hard for me to create something that senses the user’s motions as smoothly as they do in these projects, perhaps I could utilize the mouse’s motion instead.
]]>Christine Chen-Project-11-Composition
/*
Christine Chen
Section E
cyc1@andrew.cmu.edu
Project-11-Composition
*/
var turtle;
var angle = 50;
//color variables
var R = 20;
var G = 0;
var B = 100;
var A = 10;
function setup() {
createCanvas(400, 400);
background(240); //light gray color
turtle = makeTurtle(100, 100);
frameRate(10);
}
function draw() {
//draw with turtles
for (i = 0; i < 50; i++){
turtle.setColor(color(R, G, B, A));
turtle.setWeight(2);
turtle.penDown();
turtle.forward(random(1, 10));
turtle.left(angle);
}
}
function mousePressed(){
//draw turtle where mouse is
turtle = makeTurtle(mouseX, mouseY);
//randomize color
R = random(0, 200);
G = random(0, 30);
B = random(100, 255);
A = random(10, 80);
//randomize angle
angle = random(0, 15);
}
//canvas restarted when key is pressed
function keyPressed(){
resetCanvas();
}
function resetCanvas() {
background(240);
}
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;}
Directions:
– Click to draw additional squiggles
– Press key to reset
I enjoyed playing around with turtle graphics! Before doing this project, I think that all we have done with turtle graphics is drawing it very strictly through giving it strict directions. For this project, I played around with adding randomness to the graphics. I also experimented with alpha, giving the created image a gradient. I adjusted the parameters of the randomness of the colors so that they would all have a more blue and red mixture of colors.
Above shows a video of Adrien Kaeser’s real time climate sound controller which he developed in 2018. Link: https://vimeo.com/292088058
While scrolling through the various projects related to computational sound art, I came across one that grabbed my attention- real time climate sound controller. Adrien Kaeser from ECAL, a university of art and design based in Renens, designed this sound controller. This device utilizes aspects of real time weather to alter and control the designed music instruments. The entire device is composed of two major parts- a weather station on a tripod microphone and a custom-built controller connected to the weather station. The weather station receives and senses weather information and passes it on to the controller. The controller transforms the data into one that can be interpreted by instruments. The user could also alter the device, through modifying qualities such as amplitude, to control the output of sounds. The device is made with Arduino mega, Arduino leonardo, Weather Meters, SparkFun ESP32 Thing Environment Sensor Shield, ESP32, SparkFun MIDI Shield, High Speed Optocoupler 6n138, Encoder rotary knobs, Colored buttons and Arduino TFT touch screen. Software includes Arduino, C++ and MIDI protocol.
What I love most about this project is how the creator utilizes weather, the state of the atmosphere at a place and time, into another abstract form which gives people a different experience. It is as if weather is compressed into an audio form. Through allowing users to alter the sound through the controller, the creator make sure that generated sound would not be entirely random and create a composition of muddled music. The controller helps user to alter the output to form sound that is pleasing to them. It is just inspiring to see how such a large, incontrollable data could be transferred and transformed.
Kaho Abe (Group project with Ramsey Nasser and Francis Hsueh), Don’t Wake the Bear, 2013
Kaho Abe is an artist based in New York who create games and installation art. She has also been sharing her research findings and knowledge through holding classes and workshops at New York University. Interestingly, she graduated from Parsons New School of Design and was actually a fashion designer before becoming a media artist.
My favorite work of hers is a game that she designed with Ramsey Nasser and Francis Hsueh named “Don’t Wake the Bear.” In this game, players take turn passing around the device to pick items to drop on the bear. The goal is to not wake the bear and get “eaten.” The player who wakes up the bear loses. My favorite part of the game is that the players have to be careful while handling around the device too, as shaking the device also wakes up the bear. I really admire how the game involves both digital and physical interactions. How the game was designed to be for the players to pass around the device involves interaction between the players and could serve as ice breakers at events! The way the game is planned out also encourages strategic thinking and decision making, which levels it up from being just a game.
Kaho Abe’s website: http://kahoabe.net
]]>
Christine Chen-Project-10-Landscape
/*
Christine Chen
Section E
cyc1@andrew.cmu.edu
Assignment-10-a
*/
var sushi = [];
var count = 0;
var riceSize = 70;
function setup() {
createCanvas(480, 180);
//initial collection of sushi
for (var i = 0; i < 5; i += 20){
sushi[i] = makeSushi(width);
}
frameRate(140);
}
function draw() {
count += 1;
background(247, 191, 201); //pink
sushiText();
sushiConveyorBelt();
updateAndDisplaySushi();
removeSushiThatHaveSlippedOutOfView();
addNewSushiConstantly();
}
function sushiText(){
//dark red banner
fill(150, 0, 0);
rect(33, 22, 155, 48)
//bright red banner
fill(239, 33, 33);
rect(41, 28, 140, 35);
//text
fill(255);
textSize(18);
text("おいしい寿司", 57, 52);
}
function updateAndDisplaySushi(){
// Update the sushi's positions, and display them.
for (var i = 0; i < sushi.length; i++){
sushi[i].move();
sushi[i].display();
}
}
function removeSushiThatHaveSlippedOutOfView(){
var sushiToKeep = [];
for (var i = 0; i < sushi.length; i++){
if (sushi[i].x + sushi[i].breadth > -200) {
sushiToKeep.push(sushi[i]);
}
}
sushi = sushiToKeep; //remember surviving sushi
}
//keeps adding sushi to the end
function addNewSushiConstantly() {
if (count > 270) {
sushi.push(makeSushi(width));
count = 0;
}
}
//update sushi position every frame
function sushiMove() {
this.x += this.speed;
}
// draw the sushi
function sushiDisplay() {
var Height = 30;
fill(255);
noStroke();
push();
translate(this.x, height - 40);
//plate for tofu sushi
fill(255, 118, 96);
ellipse(35, -Height/7, 110, 30)
rect(5, 5, 60, 10);
//tofu sushi
fill(255, 118, 96); //plate for tofu sushi
ellipse(35, -Height/7, 110, 30)
rect(5, 5, 60, 10);
fill(255); //white rice
rect(0, -Height, riceSize, 30);
fill(255, 244, 0); //yellow tofu
rect(0, -Height - 20, riceSize, 20);
fill(0); //black seaweed
rect(25, -Height - 20, riceSize/4, 20);
//sashimi sushi
fill(111, 200, 221); //plate for sashimi sushi
ellipse(175, -Height/7, 110, 30);
rect(145, 5, 60, 10);
fill(255); //white rice
rect(140, -Height, riceSize, 30);
fill(255, 91, 0); //red meat
rect(140, -Height - 20, riceSize, 20);
fill(249, 221, 205); //meat texture
var meatLineWidth = riceSize/12;
rect(150, -Height - 20, meatLineWidth, 20);
rect(170, -Height - 20, meatLineWidth, 20);
rect(190, -Height - 20, meatLineWidth, 20);
pop();
}
//sushi info
function makeSushi(birthLocationX) {
var sushi = {x: birthLocationX,
breadth: 60,
speed: -1.0,
move: sushiMove,
display: sushiDisplay}
return sushi;
}
function sushiConveyorBelt(){
stroke(221, 133, 152); //dark pink
strokeWeight(30);
line (0, height - 10, width, height - 10);
}
I was inspired by the conveyor belts in Japanese restaurants that are used to serve sushis. Sushis are one of my favorite food in the world and so I was super excited to create the project. I made two sushis- salmon sashimi sushis and tamale sushis. I also created a sign that says in Japanese “yummy sushi” to give the image more of a Japanese sushi restaurant vibe. Even though I spent a lot of time adjusting the little details, seeing the sushis run on the page in the end makes me very, very, very happy!
2017 Nike Air Max Video. Link: https://vimeo.com/192130017
I was captivated by the 2017 Nike Air Max promo video that Vicky discovered. I watched the video over and over again and was just simply fascinated by how well the creators utilized various organic textures, pastel colors of blue and pink, and dynamic forms to create this enchanting motion graphic. I completely agree with Vicky about her comment on the creator’s incredible use of 3D computer graphic to help viewer’s understand the ways in which the materials of the shoes behave when they are under use. To add on to her comment, I think the how the creator’s uses metaphorical graphics, such as movements of the pumping of air balloons, the swirling of light fabric wrapping around the shoes and others, really helps the viewers understand and visualize the functionality and material of the shoes. One of the main pros of the shoe is its incredible lightweight, and the three-dimensional graphics of the forms really help to put emphasis on this. This video again reminds me of what first drew me towards stepping into the world of design and why I chose this major in the first place.
Vicky’s post: https://courses.ideate.cmu.edu/15-104/f2018/2018/09/23/vicky-zhou-looking-outwards-05/
]]>
Christine Chen-Project-09-Portrait
/*
Christine Chen
Section E
cyc1@andrew.cmu.edu
Project-09
*/
var hiddenImage;
function preload() {
var imageURL = "https://i.imgur.com/uGrwjUm.jpg";
hiddenImage = loadImage(imageURL);
}
function setup(){
createCanvas(480, 480);
background(100);
noStroke();
imageMode(CENTER);
hiddenImage.loadPixels();
frameRate(150);
}
function draw() {
//randomizes pixel location
var pixelX = random(0, width);
var pixelY = random(0, height);
//constrains pixel x values
var imageX = constrain(floor(pixelX), 0, width);
//constrains pixel y values
var imageY = constrain(floor(pixelY), 0, height);
//get hiddenImage data
var locationXYcolor = hiddenImage.get(imageX, imageY);
//rect size increases with increasing mouseX
var size = map(mouseX, 0, width, 5, 20)
stroke(135, 183, 237); //blue
strokeWeight(0.1); //thin line
fill(locationXYcolor);
rect(pixelX, pixelY, size, size);
//faster on right, slower on left
//smaller pixels on right need to run faster to show imge
if (mouseX > width/2){
frameRate(10);
} else {
frameRate(250);
}
}
//redraws background(start over)
function mousePressed(){
background(100);
}
For this project, I used my brother’s photo, which I took for his high school senior d. I was playing around with pixel sizes and frame rates. The smaller mouse x is, the smaller the pixels are. Because smaller pixels take more time to draw out a bigger part of the image, I made the frame rate faster for them.I gave the pixels light blue outlines to give the image more of a “mosaic” feeling.
]]>
The above is a video of Mario Klingemann’s speech at the 2015 Eyeo Festival where he presents his perspective on the topic of order in the world of art and computer science. Link: https://vimeo.com/channels/eyeo2015/133783443
Mario Klingemann is a German artist who is known for being one of the first who utilized the use of computer programming in the arts. His works and studies involve researching the connections between creativity, culture and perception through the perspectives of artificial intelligence and mechanical learning. One quote that resonates with his views of the influence of computer programming with art is the quote “If arithmetic, mensuration and weighing be taken away from art, that which remains will be little indeed” from Plato.
In his speech at the 2015 Eyeo Festival of 2015, he discusses about his approaches towards the concept of “order” from the perspectives of a programmer and from that of an artist. A work from him that he discussed during his speech that I was particularly interested in is his work with the image collections of the British Library Labs. In this work, Klingemann classified 1 million images from the British Library Lab and utilized machines learning techniques to define different index for each image. Then, with the new order that he created, he created an artwork (shown partially below) with the information. Knowing how difficult it is think of methods to even run through simple layers of array (from the assignment we just did that involves locating the brightest pixel of the image) I admire this project so much for his skills of being able to sort through such a gigantic array of information!
In his presentation, Klingemann uses various images combined with graphic diagrams that help audiences better understand and visualize that information that he is communicating. As a student of communication design I am actually studying how to ease the process of transfer of information between different forms(people to people, things to people…etc.) His method of coordinately visual graphical information through data maps with his presentation really made the data-grasping task of mine as an audience a lot smoother and this is what I am trying to learn from in design too.
Link to Mario Klingmann’s personal website: http://quasimondo.com
]]>