//Charmaine Qiu
//Section E
//charmaiq@andrew.cmu.edu
//Final project
//Array of links for icecream images
var iceLinks = [
"https://i.imgur.com/RQVGPb3.png",
"https://i.imgur.com/3NURceZ.png",
"https://i.imgur.com/gk7Jbfc.png",
"https://i.imgur.com/KzfjvaF.png",
"https://i.imgur.com/RyVDAlq.png",
"https://i.imgur.com/OoltZSF.png",
"https://i.imgur.com/DLpHcUh.png",
"https://i.imgur.com/Jd0Hx3a.png",
"https://i.imgur.com/G4zwiYV.png"]
//initialize index and empty array
var iceindex = 0;
var ice = [];
//set dragging for each decorationa as false
var bdragging = false;
var kdragging = false;
var sdragging = false;
var chdragging = false;
var fdragging = false;
var codragging = false;
var finishgame = false;
//set initial coordinate values for the decorations
var bx = 460;
var by = 60;
var kx = 540;
var ky = 100;
var sx = 490;
var sy = 140;
var chx = 160;
var chy = 50;
var fx = 160;
var fy = 125;
var cox = 80;
var coy = 100;
//initiallize offset values
var offsetX;
var offsetY;
var offsetX2;
var offsetY2;
var offsetX3;
var offsetY3;
var offsetX4;
var offsetY4;
var offsetX5;
var offsetY5;
var offsetX6;
var offsetY6;
function preload(){
//preload the icecream images and store them into the arrays
for (var i = 0; i < iceLinks.length; i++){
//store the index from the links to the new arrays
ice[i] = loadImage(iceLinks[i]);
}
//preload the images for decorations
blueberry = loadImage("https://i.imgur.com/BbD4FQd.png");
kiwi = loadImage("https://i.imgur.com/pwxFml9.png");
strawberry = loadImage("https://i.imgur.com/qwPbN2l.png");
cookie = loadImage("https://i.imgur.com/Eo3TG0F.png");
cherry = loadImage("https://i.imgur.com/FI8MUOH.png");
flower = loadImage("https://i.imgur.com/PDusCa3.png");
star = loadImage("https://i.imgur.com/09DBgK0.png");
}
function setup() {
createCanvas(600, 600);
}
function draw() {
background(255, 217, 214);
ellipse(width/2, height, 280, 250);
//draw table
drawCurtain();
//draw the text for instructions
fill(255);
text("Drag to decorate", 240, 90);
text("Click to change a flavor", 210, 120);
//draw the icream base
imageMode(CENTER);
image(ice[iceindex], width / 2, 375);
//draw image of decorations
image(blueberry, bx, by);
image(kiwi, kx, ky);
image(strawberry, sx, sy);
image(cookie, cox, coy);
image(cherry, chx, chy);
image(flower, fx, fy);
//when the decoration is being dragged, apply offset values
if (bdragging){
bx = mouseX + offsetX;
by = mouseY + offsetY;
}
if(kdragging){
kx = mouseX + offsetX2;
ky = mouseY + offsetY2;
}
if(sdragging){
sx = mouseX + offsetX3;
sy = mouseY + offsetY3;
}
if(chdragging){
chx = mouseX + offsetX4;
chy = mouseY + offsetY4;
}
if(fdragging){
fx = mouseX + offsetX5;
fy = mouseY + offsetY5;
}
if(codragging){
cox = mouseX + offsetX6;
coy = mouseY + offsetY6;
}
//draw the buttons for finish and reset
fill(255);
noStroke();
ellipse(80, 500, 100, 40);
ellipse(80, 550, 100, 40);
fill(217, 118, 115);
textSize(20);
text("Finish!", 52, 506);
text("Reset", 52, 556);
//when the game is finished, draw shape that displays the icecream
if(finishgame){
finishGame();
}
}
function mousePressed(){
//when the mouse is pressed on the icecream
if(mouseY > 250 & mouseX > 180 && mouseX < 420) {
//set the current ice equal to current index
var currentIce = iceindex;
while(currentIce === iceindex){
//randomnize the next image
iceindex = floor(random(0, 8));
}
}
//when the mouse is pressed on each decoration, dragging becomes true and
//offset values are applied
if(mouseX > bx - 21 & mouseX < bx + 21 && mouseY > by - 17 && mouseY < by + 17){
bdragging = true;
offsetX = bx - mouseX;
offsetY = by - mouseY;
}
if(mouseX > kx - 28 & mouseX < kx + 28 && mouseY > ky - 27 && mouseY < ky + 27){
kdragging = true;
offsetX2 = kx - mouseX;
offsetY2 = ky - mouseY;
}
if(mouseX > sx - 32 & mouseX < sx + 32 && mouseY > sy - 40 && mouseY < sy + 40){
sdragging = true;
offsetX3 = sx - mouseX;
offsetY3 = sy - mouseY;
}
if(mouseX > chx - 26 & mouseX < chx + 26 && mouseY > chy - 34 && mouseY < chy + 34){
chdragging = true;
offsetX4 = chx - mouseX;
offsetY4 = chy - mouseY;
}
if(mouseX > fx - 22 & mouseX < fx + 22 && mouseY > fy - 29 && mouseY < fy + 29){
fdragging = true;
offsetX5 = fx - mouseX;
offsetY5 = fy - mouseY;
}
if(mouseX > cox - 49 & mouseX < cox + 49 && mouseY > coy - 86 && mouseY < coy + 86){
codragging = true;
offsetX6 = cox - mouseX;
offsetY6 = coy - mouseY;
}
//when the finish button is pressed, the icecream is displayed
if(mouseX > 30 & mouseX < 130 && mouseY > 480 && mouseY < 520){
finishgame = true;
finishGame();
}
//reset the game when button is pressed
reset();
}
function mouseReleased(){
//when the mouse is released, dragging is nolonger happening
bdragging = false;
kdragging = false;
sdragging = false;
chdragging = false;
codragging = false;
fdragging = false;
}
function reset(){
//set cordinates to initial values when the reset button is pressed
if(mouseX > 30 & mouseX < 130 && mouseY > 530 && mouseY < 570){
bx = 460;
by = 60;
kx = 540;
ky = 100;
sx = 490;
sy = 140;
chx = 160;
chy = 50;
fx = 160;
fy = 125;
cox = 80;
coy = 100;
finishgame = false;
}
}
function drawCurtain(){
//when game is not finished, display the curtains
if (!finishgame){
ellipseMode(CENTER);
fill(217, 118, 115);
rect(0 ,0, width, 190);
for(var i = 25; i < width; i+= 50){
fill(217, 118, 115);
ellipse(i, 190, 50, 50);
}
}
}
function finishGame(){
//creates shape that covers the background to display ice
fill(255, 217, 214);
beginShape();
vertex(0, 0);
vertex(0, 525);
vertex(158, 525);
vertex(158, 150);
vertex(440, 150);
vertex(440, 600);
vertex(600, 600);
vertex(600, 0);
vertex(0, 0);
endShape();
//draws the text Enjoy
fill(217, 118, 115);
text("Enjoy~", 280, 140);
//displays stars
frameRate(8);
starX = random(width);
starY = random(height);
starX2 = random(width);
starY2 = random(height);
image(star, starX, starY);
image(star, starX2, starY2);
}
For my final project, I created an ice-cream decoration game inspired by cooking games that I play as a child. The game allows users to drag around and place the decorations on top of the ice-cream, which changes flavors when being pressed. This project encourage me to create my own illustrations and incorporated them to my code to create a game. I had fun figuring out the interactions the players can explore on the canvas.
]]>The idea of customization has always been a favorite for people who want to create or own things that are authentic to themselves. For the final project, I want to create a game that allows users to experiment possibilities and create a desert item (cake, drink, or ice cream?) of their own. The main features of the desert would be hand drawn by me on Procreate/Illustrator, and imported to the sketch file. Other features can allow some sort of randomization, such as the sizing and color of small decorations. While decorating the desert, the users could choose the factor that they want, and visualize it by interacting with the keyboard/mousepad. Even though I have not completely settled on the type of desert that I want to create for the project, the project itself will be fun to create with the objective of giving the players a stress relieving experience.
]]>For the final project, I want to create a decorating game that allows users to create something of their own. In the past, customization/decorating games constantly appeared in people of all ages’ interests. I remember playing “Let’s create! Pottery” and discovering the endless possibilities of decorating ceramics. The game was released in 2010, and published by Infinite Dreams. Through the game, people can design realistic potteries with their own desired features. On the other hand, “Zepeto” , an application that allows users to create a 3D avatar of themselves has been very popular during the past year. The app was published by Snow Corporation, and it also have socializing functions that let users to meet others with the avatar they created. The idea of creating something that is one of a kind really interest me, and I hope to create a game that could invite users to discover their own creativity.
]]>//Charmaine Qiu
//Section E
//charmaiq@andrew.cmu.edu
//Project 11
//set the speed and detail for terrain
var terrainSpeed = 0.0005;
var terrainDetail = 0.008;
//create empty array for ducks on screen
var ducks = [];
function setup() {
createCanvas(480, 200);
frameRate(10);
//set the number of ducks that appears in the beginning randomly on screen
for (var i = 0; i <3; i++){
var rx = random(width);
ducks[i] = makeDuck(rx);
}
}
function draw() {
//set background visuals
//the sky
background('#95dddd');
//the river
fill('#419696')
noStroke();
rect(0, height / 2, width, height);
//the sun and its reflection
fill('red');
ellipse(width - 60, 10, 60, 60);
fill('#6e1616');
ellipse(width - 60, height - 10, 60, 60);
//draw mountain and ripple function
mountains();
ripples();
//draw the ducks
push();
translate(0.1 * width, 0.1 * height);
scale(0.8);
updateAndDisplayDucks();
removeDucksThatHaveSlippedOutOfView();
addNewDucksWithSomeRandomProbability();
pop();
}
function mountains(){
//create the mountain
fill('#e1a952');
noStroke();
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t), 0,1, 0, height / 2);
vertex(x, y);
}
vertex(width, height/2);
vertex(0, height/2)
endShape();
//create the reflection
fill('#dd5a62');
beginShape();
noStroke();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);
//inverse the y component to flip the mountain upside-down
var y = map(noise(t), 0,1, height, height / 2);
vertex(x, y);
}
vertex(width, height/2);
vertex(0, height/2)
endShape();
}
function ripples(){
//create the ripples
frameRate(7);
stroke(255);
//set individual random values for x and y coordinates of ripples
rX = random(width / 2 - 50, width / 2 + 50);
rY = random(height / 2 + 10, height);
rX2 = random(width / 2 - 50, width / 2 + 50);
rY2 = random(height / 2 + 10, height);
rX3 = random(width / 2 - 50, width / 2 + 50);
rY3 = random(height / 2 + 10, height);
//set individual random values for width and weight of ripples
rWidth = random(5, 20);
rWeight = random(1, 4);
rWidth2 = random(5, 20);
rWeight2 = random(1, 4);
rWidth3 = random(5, 20);
rWeight3 = random(1, 4);
//draw out the lines of ripples
strokeWeight(rWeight);
line(rX, rY, rX + rWidth, rY);
strokeWeight(rWeight2);
line(rX2, rY2, rX2 + rWidth2, rY2);
strokeWeight(rWeight3);
line(rX3, rY3, rX3 + rWidth3, rY3);
}
function updateAndDisplayDucks(){
// Update the duck's positions, and display them.
for (var i = 0; i < ducks.length; i++){
ducks[i].move();
ducks[i].display();
}
}
function removeDucksThatHaveSlippedOutOfView(){
// copy all the ducks that's kept into a new array.
var ducksToKeep = [];
for (var i = 0; i < ducks.length; i++){
if (ducks[i].x + ducks[i].breadth > 0) {
ducksToKeep.push(ducks[i]);
}
}
ducks = ducksToKeep; //remember the surviving ducks
}
function addNewDucksWithSomeRandomProbability() {
// With a very tiny probability, add a new duck to the end.
var newDuckLikelihood = 0.007;
if (random(0,1) < newDuckLikelihood) {
ducks.push(makeDuck(width));
}
}
// method to update position of duck every frame
function duckMove() {
this.x += this.speed;
}
function duckDisplay() {
// draw the ducks
var headHeight = 20;
fill(255);
noStroke();
push();
//translate duck to lower part of canvas
translate(this.x, height - 40);
ellipse(0, -headHeight, this.breadth, headHeight);
fill(0);
ellipse(0, -headHeight, 5, 5);
fill("#70547c");
arc(10, -10, 30, 30, 0, PI);
fill("#f8e184");
arc(10, -10, 10, 10, 0, PI);
fill("green");
arc(-10, -20, 10, 10, 0, PI);
pop();
}
//the function to create the duck object
function makeDuck(birthLocationX) {
var mdk = {x: birthLocationX,
breadth: 20,
speed: -1.0,
move: duckMove,
display: duckDisplay}
return mdk;
}
In this project, I was able to create a generative landscape with customized features. I really enjoyed sceneries that has a complete reflection on a water surface, and decided to create an animation with a mountain and its reflection on the lake. I added a fun component of ducks swimming around to create a fun element.
Mimi Son is one of the founders of an art studio based in Seoul called Kimchi And Chips that specializes artworks that combine with the sciences and philosophy. One project that I find intriguing is the public artwork Halo created in 2018 that celebrates the fusion of nature and technology. The computational installation involved 99 robotic mirrors that constantly follow the location of the sun. At the same time, the mirrors emit beams of water mist that draw a bright circle in the air, mimicking the shape of the sun as it is brought down to earth. However, the circle’s completion depends entirely on the presence of the sun. In a way, this project collaborated with nature while exploring instances where it coexists with technology. I find the concept of robotic entities being completely controlled by nature very interesting, as it brought polar opposite aspects of design together to form a large scale installation.
Taryn Southern is a singer active on YouTube who creates her own contents. I find her most recent album particularly interesting as it was entirely composed and produced with artificial intelligence. In an interview with Taryn, she informed us that she used an AI platform called Amper Music to create the instrumentation of her songs. In her creating process, Taryn would decide factors such as the BPM, rhythm, and key, and the AI would generate possibilities for her. From there, she could select the pieces that she enjoyed, and arrange them along with the lyrics that she wrote herself. She states that the advantage of working with an AI is that it gives her a lot of control over what she desires, as opposed to a human partner who may not understand her intents. However, I personally find her songs generic and lack the emotions that move the audience. There are many things that artificial intelligence can achieve, but I believe that music that truly conveys human sentiments should fully origin from the minds of people.
In this project, I was able to incorporate new knowledge of importing sound and oscillations into my former assignment. I had fun looking for edm music sources online and creating an interactive project that people could play with.
// Charmaine Qiu
// charmaiq@andrew.cmu.edu
// section E
//Project - 10 - Sonic Sketch
var angle = 0
var b = 0
var bgmusic;
var heySound;
var beat;
function preload() {
//preload the audios and loop the background music
beat = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/beat.wav');
heySound = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/hey.wav');
bgmusic = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/bgmusic.wav');
bgmusic.loop();
}
function setup() {
createCanvas(400, 400);
//createDiv("p5.dom.js library is loaded.");
//======== call the following to use sound =========
useSound();
}
function soundSetup() { // setup for audio generation
//set the volume for audio and play background music
bgmusic.setVolume(1);
bgmusic.play();
heySound.setVolume(1);
beat.setVolume(2);
//setup for oscillation
osc = new p5.TriOsc();
osc.freq(500);
osc.amp(1);
osc.start();
}
function draw() {
//set the frequency of oscillation according to placement of mouseX
osc.freq(mouseX);
osc.amp();
//when the mouse is pressed, "hey" plays
if (mouseIsPressed){
heySound.play();
}
//graphics created from precious project
fill(b);
//randomizing the color in greyscale
b = random (0, 255);
strokeWeight(0);
rectMode(CENTER);
push();
//square that follows the mouse
translate(mouseX, mouseY);
background(0);
rotate(radians(angle));
rect(0, 0, 50, 50);
pop();
//angle rotates
angle += 5;
//rectangle outlines in the center
noFill();
stroke(255);
strokeWeight(5);
push();
translate(width / 2, height / 2);
rect(0, 0, mouseX, mouseY);
pop();
stroke(b);
strokeWeight(1);
rect(width * 0.5, height * 0.5, mouseY, mouseX);
//dancing lines in the center
stroke(255);
strokeWeight(1);
line(width / 2 - 40, height / 2, width / 2 - 40, mouseY + 50);
line(width / 2 - 30, height / 2, width / 2 - 30, mouseY);
line(width / 2 - 20, height / 2, width / 2 - 20, mouseY - 20);
line(width / 2 - 10, height / 2, width / 2 - 10, mouseY + 40);
line(width / 2, height / 2, width / 2, mouseY);
line(width / 2 + 10, height / 2, width / 2 + 10, mouseY + 60);
line(width / 2 + 20, height / 2, width / 2 + 20, mouseY + 10);
line(width / 2 + 30, height / 2, width / 2 + 30, mouseY);
line(width / 2 + 40, height / 2, width / 2 + 40, mouseY - 30);
//When the mouse move to the left side of the canvas
if (mouseX <= width / 2){
//squares that rotates around the mouse
push();
translate(mouseX - 50, mouseY - 50);
rotate(radians(angle));
rectMode(CORNER);
rect(20, 20, 20, 20);
pop();
angle = angle + 0.5;
push();
translate(mouseX + 50, mouseY + 50);
rotate(radians(angle));
rect(0, 0, 10, 10);
pop();
angle = angle - 0.5
//text appears
textSize(15);
text('WooHooo!!!', 20, 90);
textSize(30);
text('哦耶!', 280, 180);
} else { //When the mouse move to the right side of the canvas
fill(0);
strokeWeight();
push();
translate(mouseX, mouseY);
rotate(radians(angle));
rectMode(CENTER);
rect(0, 0, 30, 30);
pop();
angle = angle + 5
//text appears
textSize(20);
fill(255);
text('야호!', 280, 50);
textSize(25);
text('ヤッホ〜ー', 70, 350);
}
}
//when the key "b" is pressed, a beat sound is played
function keyPressed(){
if(key == "b"){
beat.play();
}
}
]]>In this project, I had fun creating an interactive portrait of myself. I mimicked splashes of paint dropping down when the mouse is dragged on the canvas. I got to utilize what I learned from the previous assignments and incorporate them in my project.
//Charmaine Qiu
//charmaiq@andrew.cmu.edu
//Section E
//Project 09
var underlyingImage;
//create an empty array
var xarray = []
var yarray = []
//load the image from imgur.com
function preload() {
var myImageURL = "https://i.imgur.com/cplu0CL.jpg";
image = loadImage(myImageURL);
}
function setup() {
createCanvas(400, 300);
background(0);
image.loadPixels();
frameRate(100000000); //generate the image in a faster speed
}
function draw() {
var px = random(width); //the location for x coordinate
var py = random(height); //the location for y coordinate
var ix = constrain(floor(px), 0, width-1); //constraining within the canvas
var iy = constrain(floor(py), 0, height-1); //constraining within the canvas
var theColorAtLocationXY = image.get(ix, iy);//fill in the color according to color of image
noStroke();
fill(theColorAtLocationXY);
//draw the ellipses
ellipse(px, py, 6, 6);
//get the color of image at the mouse
var theColorAtTheMouse = image.get(mouseX, mouseY);
stroke(theColorAtTheMouse);
//loop over the length of the array
for (var i = 0; i < xarray.length; i ++){
//fill with the color at the mouse
fill(theColorAtTheMouse);
ellipse(xarray[i], yarray[i], 5, 5);
//make the ellipses go down mimicking paint drooling down
yarray[i] += 0.5;
}
}
//when mouse is dragged, add the mouse position to the array
function mouseDragged(){
xarray.push(mouseX);
yarray.push(mouseY);
}
//when mouse is pressed, a new array is created
function mousePressed(){
xarray = [];
yarray = [];
}
]]>In Jamie Park’s Looking Outwards 05, she introduced me to a 3d artist from creative cloud named Roger Kilimanjaro. He is a 3d artist from Paris, France, and he uses Maxon Cinema 4d to render his projects. He mainly creates animated videos of motions that loops over and over in a satisfying manner. On his social media pages, you can find endless short videos and images of realistic and yet unusual 3d renderings that come to life. The videos are very pleasing to look at with the attentive incorporation of popping colors and logical audios as support. At the same time, Roger utilizes his skills to create advertisements for food companies such as Krispy Kream. I agree with Jamie that it is fascinating to see how software like Maxon Cinema 4d allows a vast range of potentials for designers around the world, and it must be life changing for its developers to realize what they contributed to elevate the designers’ experience of their project making process.
Meejin Yoon is a designer and architect. Fascinated by the ambiguity between public and private spaces, Yoon’s work mainly focus on interactive play in public spaces that utilizes the properties of technology. In the lecture, she mentioned how based on the various cultures that people are from, we tend to define personal and public spaces in different ways, yet Yoon is passionate about exploring the boundaries of these spaces. With an architecture degree from Cornell University and a masters degree from Harvard University, Yoon created projects on museum interiors, light installations, interactive technologies, and many more. While designing, she constantly kept in mind the experiences of the users and the context of the designs, while attempting to showcase elements that portray the theme of the surroundings. When presenting her work, Yoon used many visual elements and processes to support her explanations, and I find it helpful to learn from her illustrative manner of presenting work process. The wide range of work that Yoon takes part in is very fascinating to me, and I am inspired by her flexibility in utilizing her skillset to the fullest extent.
Here is a link to her website: http://www.howeleryoon.com/