Heather Kelley is a media artist and game designer. She is also co-founder of the Kokoromi-experimental game collective- and faculty of Entertainment Technology Center CMU. Yes! she is one of the faculty of the program I’m in right now. I have talked with her some times to get some feedback about my own project, she always gives good inspiration and critiques. The video is about she talking about the public future of the game at TED. But here, I’m going to talk about one of her work ‘Superhypercube’.
‘Superhypercube’ is a VR first person puzzler game launched for playstationVR. In this game, head tracking is critical to accomplish player’s goal. The theme for game is very retro feeling and she also brings the light and space art movement. This game is not only just game but also interactive art.
As a game designer and media artist, she has created many and diverse works. You can check her tremendous work pieces on her website.
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var birds = [];
var redu;
function preload() { //load birds
birdie = loadImage("https://i.imgur.com/ql6l0Rq.png")
}
function setup() {
createCanvas(480 , 270);
frameRate(24);
for (var i = 0; i < 5; i++){ //set up loop for birds
var location = random(width);
birds[i] = makeBirds(location);
}
}
function draw() {
background(redu, 50, 200);
//call drawings
sun();
drawMountains();
drawRivers();
drawBackground();
updateBirds();
displayBirds();
addBirds();
makeBirds();
moveBirds();
redu = mouseY/5; //let background change depending on y
}
// SUN-----
function sun(){
fill("red");
ellipse(240, 135, 100, 100);
}
// BIRDS -----
function updateBirds(){
for (var i = 0; i < birds.length; i++){
birds[i].move();
birds[i].display();
}
}
function addBirds() {
var a = random(1);
if (a < 0.03) {
birds.push(makeBirds(width));
}
}
function moveBirds() { //change x of birds
this.x += this.speed;
}
function displayBirds() { //put birds on canvas
var birdY = 10;
push();
translate(this.x, this.height);
for(var i=0; i<this.number; i++) {
image(birdie, 10, birdY, random(10, 50), random(10, 50));
}
birdY += 1;
pop();
}
function makeBirds(birthx) { //set up variables for birds
var birds2 = {x: birthx,
number: floor(random(1,2)),
speed: -3,
height: random(90,100),
move: moveBirds,
display: displayBirds}
return birds2;
}
function drawBackground(){ //part of background color
fill(238,238,238,100);
beginShape();
rect(0, 0, width - 1, height - 1);
endShape();
}
//RIVER
function drawRivers(){
//River 1
fill(144,175,197,255);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * 0.003) + (millis() * terrainSpeed * 2);
var y = map(noise(t), 0,1, 0, height * 0.1);
vertex(x, y+225);
}
vertex(width,height);
vertex(0,height);
endShape();
//River 2
fill(51,107,135,255);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * 0.003) + (millis() * terrainSpeed * 2);
var y = map(noise(t), 0,1, 0, height * 0.1);
vertex(x, y+230);
}
vertex(width,height);
vertex(0,height);
endShape();
//River 3
fill(144,175,197,255);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * 0.003) + (millis() * terrainSpeed * 2);
var y = map(noise(t), 0,1, 0, height * 0.1);
vertex(x, y+235);
if(noise(t) > 0.2){
fill(144, 175, 197, 80);
}
else {
fill(144,175,197,120);
}
}
vertex(width,height);
vertex(0,height);
endShape();
//River 4
fill(51,107,135,255);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * 0.003) + (millis() * terrainSpeed * 2);
var y = map(noise(t), 0,1, 0, height * 0.1);
vertex(x, y+240);
}
vertex(width,height);
vertex(0,height);
endShape();
}
function drawMountains() {
noStroke();
fill(118,54,38,255);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed*0.5);
var y = map(noise(t), 0,1, 0, height*1.1);
vertex(x, y-15);
}
vertex(width,height);
vertex(0,height);
endShape();
}
Using the moving landscapes, I wanted to display a landscape of the ocean and mountain moving. For an interesting part of the project, I added a random variation in the birds to make it seem as if the birds were flocking in the sky.
//Hanna Jang
//Section B
//hannajan@andrew.cmu.edu;
//Project_10
//background mountian display characteristics
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var terrainSpeed1 = 0.0008;
var terrainDetail1 = 0.008;
var terrainSpeed2 = 0.0010;
var terrainDetail2 = 0.01;
//moon and car variables
var moon;
var car;
var carx=150;
var carx2=60;
//array for stars
var stars = [];
function preload() {
//loading images of car and moon
moon = loadImage("https://i.imgur.com/EWntReN.png");
car= loadImage("https://i.imgur.com/kx6JqDC.png");
}
function setup() {
createCanvas(480, 480);
frameRate(10);
// create an initial collection of stars
for (var i = 0; i < 15; i++){
var rx = random(width);
stars[i] = makestar(rx);
}
frameRate(10);
}
function draw() {
background(47, 94, 123);
noFill();
//moon image in the sky
image(moon, 320, 60);
//draw background mountian that is farthest from road
beginShape();
for (var x2 = 0; x2 < width; x2++) {
var t = (x2 * terrainDetail2) + (millis() * terrainSpeed2);
var y2 = map(noise(t), 0,1, height/3.5, height/2);
vertex(x2, y2);
stroke(53, 80, 102);
line(x2, height, x2, y2);
}
endShape();
//draw background mountian that is between the other two mountains
beginShape();
for (var x1 = 0; x1 < width; x1++) {
var t = (x1 * terrainDetail1) + (millis() * terrainSpeed1);
var y1 = map(noise(t), 0,1, height/3, height*3/4);
vertex(x1, y1);
stroke(15, 51, 79);
line(x1, height, x1, y1);
}
endShape();
//draw background mountian that is closest to road
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t), 0,1, height/2, height);
vertex(x, y);
stroke(10, 31, 47);
line(x, height, x, y);
}
endShape();
//draw road
fill(0);
rect(0, height-40, width, 20);
//car image driving
image(car, carx, height-carx2);
//stars are displayed
updateAndDisplaystars();
addNewstarsWithSomeRandomProbability();
}
function updateAndDisplaystars(){
// Update the star's positions, and display them.
for (var i = 0; i < stars.length; i++){
stars[i].move();
stars[i].display();
}
}
function addNewstarsWithSomeRandomProbability() {
// With a very tiny probability, add a new star to the end.
var newstarLikelihood = 0.05;
if (random(0,1) < newstarLikelihood) {
stars.push(makestar(width));
}
}
// method to update position of stars every frame
function starMove() {
this.x += this.speed;
}
// draw the stars
function starDisplay() {
var skyHeight = 50;
var bHeight = this.nsky * skyHeight;
stroke(255);
fill(251, 248, 36);
push();
translate(this.x, height - 100);
rotate(PI/3.0);
rect(0, -bHeight, 5, 5);
pop();
}
//make the stars
function makestar(birthLocationX) {
var str = {x: birthLocationX,
breadth: 60,
speed: -1.0,
nsky: round(random(2,9)),
move: starMove,
display: starDisplay}
return str;
}
For this week’s project, I knew that I wanted to recreate a very specific memory. I wanted to recreate the car drives my family would have in the countryside late at night, when we went on road-trips.
I recreated this by making sure that the car looked like it was continuously moving forward, when it actually was a still image on the canvas. This was done by making sure the background image in the back of the car was moving. The mountains in the background give the image a more 3-D look.
In my memory, there were many bright stars in the sky during those drives. I randomized the position of these stars in the sky. I am overall pleased with the outcome of my project.
//Rebecca Groves
//Section B
//rgroves@andrew.cmu.edu
//Landscape
var middlecacti = [];
var foregroundcacti = [];
var shrubs = [];
var buttes = [];
var MiddlegroundSpeed = .0003;
var MiddlegroundDetail = .004;
var ForegroundSpeed = .0005;
var ForegroundDetail = .005;
var middleTerrain = [];
var foregroundTerrain = [];
function setup() {
createCanvas(480, 250);
//pregenerated vegetation
for (var i = 0; i < 4; i++) {
buttes[i] = makeButte(random(width));
}
for (var i = 0; i < 5; i++) {
middlecacti[i] = makeCactus(floor(random(width)));
}
for (var i = 0; i < 3; i++) {
foregroundcacti[i] = makeCactus(floor(random(width)));
}
for (var i = 0; i < 100; i++) {
shrubs[i] = makeShrub(random(width));
}
}
//LANDSCAPES
function drawForeground() {
noStroke();
fill(223, 194, 140);
beginShape();
for (var x = 0; x <= width; x++) {
var t = (x * ForegroundDetail) + (millis() * ForegroundSpeed);
var y = map(noise(t), 0, 1, 2 * height/3, height);
vertex(x,y);
foregroundTerrain[x] = y;
}
vertex(width, height);
vertex(0, height);
endShape();
if (random(0, 1) < .003) {
foregroundcacti.push(makeCactus(width))
}
for (var i = 0; i < foregroundcacti.length; i++) {
foregroundcacti[i].move();
foregroundcacti[i].foregrounddraw();
}
}
function drawMiddleground() {
noStroke();
fill(210, 170, 100);
beginShape();
for (var x = 0; x <= width; x++) {
var t = (x * MiddlegroundDetail) + (millis() * MiddlegroundSpeed);
var y = map(noise(t), 0, 1, height/2, height);
vertex(x,y);
middleTerrain[x] = y;
}
vertex(width, height);
vertex(0, height);
endShape();
if (random(0, 1) < .005) {
middlecacti.push(makeCactus(width))
}
for (var i = 0; i < middlecacti.length; i++) {
middlecacti[i].move();
middlecacti[i].middledraw();
}
}
function drawBackground() {
fill(230, 190, 90);
noStroke();
rect(0, 2 * height/3, width, height/3);
if (random(0, 1) < .01) {
buttes.push(makeButte(width))
}
for (var i = 0; i < buttes.length; i++) {
buttes[i].move();
buttes[i].draw();
}
if (random(0, 1) < .5) {
shrubs.push(makeShrub(width))
}
for (var i = 0; i < shrubs.length; i++) {
shrubs[i].move();
shrubs[i].draw();
}
}
//REMOVE UNUSED OBJECTS
function removeButtes() {
var buttesToKeep = [];
for (var i = 0; i < buttes.length; i++) {
if (buttes[i].x + buttes[i].breadth > 0)
buttesToKeep.push(buildings[i]);
}
buttes = buttesToKeep;
}
function removemiddleCacti() {
var middlecactiToKeep = [];
for (var i = 0; i < middlecacti.length; i++) {
if (middlecacti[i].x > 0)
middlecactiToKeep.push(middlecacti[i]);
}
middlecacti = middlecactiToKeep;
}
function removeforegroundCacti() {
var foregroundcactiToKeep = [];
for (var i = 0; i < foregroundcacti.length; i++) {
if (foregroundcacti[i].x > 0)
foregroundcactiToKeep.push(foregroundcacti[i]);
}
foregroundcacti = foregroundcactiToKeep;
}
//BUTTES
function butteMove() {
this.x += this.speed;
}
function drawButte() {
beginShape();
vertex(this.x + this.breadth, 2 * height/3);
vertex(this.x + this.breadth, 2 * height/3);
vertex(this.x + this.breadth - 10, (2 * height/3) - this.tall);
vertex(this.x + 10, (2 * height/3) - this.tall);
vertex(this.x, 2 * height/3);
endShape();
}
function makeButte(birthlocationX) {
var butte = {x: birthlocationX,
breadth: random(40, 150),
tall: random(10, 30),
speed: -1,
move: butteMove,
draw: drawButte}
return butte;
}
//VEGETATION
function cactusMove() {
this.x -= 1;
}
function drawmiddleCactus() {
strokeWeight(10);
stroke('green');
line(this.x, middleTerrain[this.x], this.x, middleTerrain[this.x] - this.height);
for (i = 0; i < this.limbs; i++) {
if (i%2 == 0) {
line(this.x - 10, middleTerrain[this.x] - this.height/(1.25 * i) - 15, this.x, middleTerrain[this.x] - this.height/(1.25 * i));
} else {
line(this.x + 10, middleTerrain[this.x] - this.height/(1.25 * i) - 15, this.x, middleTerrain[this.x] - this.height/(1.25 * i));
}
}
noStroke();
if (this.flowercolor < .3) {
fill(236, 96, 160);
} else if (this.flowercolor > .3 & this.flowercolor < .6) {
fill(255, 255, 0);
} else {
noFill();
}
push();
translate(this.x, middleTerrain[this.x] - this.height);
rotate(-90);
for (i = 0; i < 3; i++) {
angleMode(DEGREES);
var angle = 45;
rotate(angle);
angle += 45 * i;
ellipse(0, -5, -7, 15);
}
pop();
}
function drawforegroundCactus() {
strokeWeight(10);
stroke('green');
line(this.x, foregroundTerrain[this.x], this.x, foregroundTerrain[this.x] - this.height);
for (i = 0; i < this.limbs; i++) {
if (i%2 == 0) {
line(this.x - 10, foregroundTerrain[this.x] - this.height/(1.25 * i) - 15, this.x, foregroundTerrain[this.x] - this.height/(1.25 * i));
} else {
line(this.x + 10, foregroundTerrain[this.x] - this.height/(1.25 * i) - 15, this.x, foregroundTerrain[this.x] - this.height/(1.25 * i));
}
}
noStroke();
if (this.flowercolor < .3) {
fill(236, 96, 160);
} else if (this.flowercolor > .3 & this.flowercolor < .6) {
fill(255, 255, 0);
} else {
noFill();
}
push();
translate(this.x, foregroundTerrain[this.x] - this.height);
rotate(-90);
for (i = 0; i < 3; i++) {
angleMode(DEGREES);
var angle = 45;
rotate(angle);
angle += 45 * i;
ellipse(0, -5, -7, 15);
}
pop();
}
function makeCactus(locationX) {
var cactus = {x: locationX,
height: random(20, 70),
limbs: floor(random(1, 4)),
middledraw: drawmiddleCactus,
foregrounddraw: drawforegroundCactus,
move: cactusMove,
flowercolor: random(0, 1)}
return cactus;
}
function shrubMove() {
this.x += this.speed
}
function drawShrub() {
fill(50, 100, 100);
ellipse(this.x, this.y, 3, 3);
}
function makeShrub(locationX) {
var shrub = {x: locationX, y: random(2 * height/3, height),
speed: -1,
draw: drawShrub,
move: shrubMove}
return shrub;
}
function draw() {
background("skyblue");
drawBackground();
drawMiddleground();
drawForeground();
}
For my landscape I was inspired by driving through New Mexico this summer. Unfortunately I could not figure out how make the cacti move at the same speed as the landscape. I borrowed the code for the landscape from the class website and I think maybe if I understood how that worked a little better I might have been able to make the speeds match. I will keep thinking about it. Other than that, I thought this project went pretty well. I’m glad I was finally able to figure out objects, even at a pretty basic level. I still find them confusing but I can use them!
//atraylor
//Project 10, Section B
var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u', 'v', 'w', 'x', 'y', 'z', 'A', 'B',
'C', 'D', 'E', 'F','G', 'H', 'I', 'J', 'K','L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S','T','U','V', 'W', 'X', 'Y', 'Z'];
var symbols = ['!', '@', '#', '$', '%', '^', '&', '*', ')','(', '_', '-', '=',
'+', '~', '`', '[', ']', '{', '}', '|', '.', ',', '<', '>', '/', '?'];
var characters = [];
var grawlix = [];
function setup() {
createCanvas(480, 480);
for (var i = 0; i < 10; i++){
var rx = random(width);
var ry = random(height);
characters[i] = makeChar(rx, ry); //populate screen
}
for(var i = 0; i < 10; i ++){
var ry = random(width);
var rx = random(height);
grawlix[i] = makeGrawlix(rx, ry);
}
}
function draw() {
background(0);
updateAndDisplayChar();
characterDeath();
addRanProbChar();
updateAndDisplayGraw();
grawlixDeath();
addRanProbGraw();
}
function updateAndDisplayChar(){
for(var i = 0; i < characters.length; i++){ //draw and update characters
characters[i].move();
characters[i].draw();
}
}
function characterDeath(){ //kill characters that go off screen
var liveCharacters = [];
for(var i = 0; i < characters.length; i++){
if(characters[i].x + 50 > 0) {
liveCharacters.push(characters[i]);
}
}
characters = liveCharacters; //remember live
}
function addRanProbChar(){ //make more of the characters appear
var prob = 0.1;
if (random(0,1) < prob){
characters.push(makeChar(width, random(height)));
}
}
function charMove(){ //moving across screen
this.x += this.speed;
}
function charDraw(){
noStroke();
textSize(this.csize);
fill(this.charCol, 0, 0);
text(this.symbol, this.x, this.y);
}
function makeChar(birthlocationx, birthlocationy){
var char = {'x': birthlocationx,
'y': birthlocationy,
'charCol': pickColor(),
'speed': pickSpeed(),
'symbol': pickCharacter(),
'csize':(-1 * pickSpeed() * 10),
'move': charMove,
'draw': charDraw}
// char.move = charMove;
// char.draw = charDraw;
return char;
}
function pickCharacter(){
return letters[int(random(letters.length))];
}
function pickColor(){
return int(random(100, 255));
}
function pickSpeed(){
return random(-1, -5);
}
////////
function updateAndDisplayGraw(){
for(var i = 0; i < grawlix.length; i++){
grawlix[i].move();
grawlix[i].draw();
}
}
function grawlixDeath(){
var liveGrawlix = [];
for(var i = 0; i < grawlix.length; i++){
if(grawlix[i].gx + 50 > 0) {
liveGrawlix.push(grawlix[i]);
}
}
grawlix = liveGrawlix; //remember live
}
function addRanProbGraw(){
var prob = 0.07;
if (random(0,1) < prob){
grawlix.push(makeGrawlix(width, random(height)));
}
}
function grawMove(){
this.gx += this.gspeed;
}
function grawDraw(){
var frame = frameCount % 27; // go through all the symbols
textSize(this.gsize);
noStroke();
fill(this.grawCol, 0, 0);
text(symbols[frame],this.gx, this.gy);
}
function makeGrawlix(birthlocationx, birthlocationy){
var graw = {'gx':birthlocationx,
'gy':birthlocationy,
'grawCol': pickGrawColor(),
'gspeed': pickGrawSpeed(),
'gsize': (-1 * pickGrawSpeed() * 10),
'move': grawMove,
'draw':grawDraw
}
return graw;
}
function pickGrawColor(){
return random(100, 255);
}
function pickGrawSpeed(){
return random(-1, -5);
}
For this project, I wanted to do something that would feel dimensional. I ended up making flying letters. I think I would have liked to add more material flying by, but I settled for the amount present for simplicity.
Neri Oxman is an American-Israeli architect, designer and professor at the MIT Media Lab. She is in charge of the Mediated Matter research group, where they focus on combining design, biology, computing, materials engineering with architecture and art. Her work is primarily determined by its context, whether it be a helmet based on a CT scan of the brain (design fits the body not only by the shape but also by the physiological makeup of the body) or an acoustic chair that absorbs sound (design corresponds to the pressure points on the human body). Everything she does relates to something specific that gives it a sense of context. Most of her organically-shaped, beyond the norm designs are 3D printed.
One of my favourite works of hers would be the Mechanic Biomaterials Deposition using chitosan (2014). She took chitosan paste, developed solutions of different chemical concentrations and used that solution to 3D print, with a robotic arm, a structure in large scale. The microorganisms (a byproduct of the air bubbles from the printing process) and embedded bacteria take carbon from the atmosphere and convert it into sugar/energy. Not only can the product as as a structural beam, but also as a facade mesh (eg windows). The product also biodegrades to nourish marine life or nourish soil. What I like about this project is that the product is thought of as a cycle that is part of the natural environment. She takes what is natural to create one environmentally-harmless man-made object, which can then be returned back to the environment.
/*
Jamie Ho
jamieh@andrew.cmu.edu
10:30
Project 10
*/
var clouds = [];
var skies = [];
var sunPos = 0;
var colour = 0;
function setup() {
createCanvas(480, 480);
//to make and store clouds in array
for (var i = 0; i < 10; i++){
var rx = random(width);
clouds[i] = makeClouds(rx);
}
frameRate(10);
}
function draw() {
noStroke();
//environment outside of plane
sky();
theSun(sunPos);
if(sunPos < width){ //condition statement for position of sun
sunPos += 3; //to move sun
colour += 2; //to change colour
} else { //go back to 0
sunPos = 0;
colour = 0;
}
updateAndDisplayClouds();
addNewCloudsChances();
//plane interiors
windows(0);
windows(width*0.7);
planeInterior();
seat(0);
seat(width*0.7);
}
function windows(pos){
fill(200, 200, 200, 50);
rect(pos+width/6, height/4, pos+width/2, height);
ellipseMode(CORNER);
arc(pos+width/6, 0, width/2, width/2, PI, 0);
}
function seat(pos){
noStroke();
fill(150);
rect(pos, height/3, width/8, height, 50); //back rest
fill(200);
rect(pos, height*0.85, width/2, height, 25); //seat
fill(125);
rect(pos+25, height*0.75, width/2.5, 25, 50); //arm rest
ellipseMode(CORNER);
fill(100);
ellipse(pos+25, height*0.75, 25, 25) //arm rest joint
ellipseMode(CENTER);
fill(200);
ellipse(pos+width/8, height/2.5, 18, height/5); //head rest
}
function planeInterior(){
fill(80);
rect(0, height*0.7, width, height);
}
function updateAndDisplayClouds(){
for (var i = 0; i < clouds.length; i++){
clouds[i].move();
clouds[i].show();
}
}
function addNewCloudsChances() {
// With a very tiny probability, add a new building to the end.
var newCloudChances = 0.01;
if (random(0,1) < newCloudChances) {
clouds.push(makeClouds(width));
}
}
function removeBuildingsThatHaveSlippedOutOfView(){
var cloudsToKeep = [];
for (var i = 0; i < clouds.length; i++){
if (clouds[i].x + clouds[i].breadth > 0) {
cloudsToKeep.push(clouds[i]);
}
}
clouds = cloudsToKeep; // remember the surviving buildings
}
function cloudsMove() {
this.x += this.speed;
}
function cloudsDisplay(){
var gs = random(240, 255); //greyscale
fill(gs, gs, gs, 50);
ellipse(this.x, this.y, this.sizeX, this.sizeY); //big clouds
ellipse(this.x+5, this.y-100, this.sizeX*0.45, this.sizeY*0.25); //small clouds
}
function makeClouds(birthLocationX){
var clouds = {x: birthLocationX, //where it starts
y: random(height*0.35, height*0.7), //vertical position
speed: random(-0.5, -1), //speed of each cloud
breadth: 35, //distance between clouds
sizeX: random(120, 200), //size of ellipse
sizeY: random(60, 100),
move: cloudsMove, //to animate clouds
show: cloudsDisplay}; //to create clouds
return clouds;
}
function sky(){
var factor = 0.5; //factor to decrease rbg values by
for(var i = 0; i<width; i++){
var f = i*factor; //rbg decreases incrementally based on i
fill(230-f, 247-f, 255-f);
skies.push(rect(i, 0, i+1, height*0.7)); //creating sky rectangles
}
}
function theSun(x){
var sSize = 100;
ellipseMode(CORNER);
fill(255+colour, 204+colour, 0+colour, 255-colour/2);
ellipse(x, height/16, sSize, sSize);
}
The hardest part of this project is still understanding objects and keeping track of where those parameters go within all the different functions that are then called in draw. I started the project with drawing what was still, then putting in what moved. However, I think I should have done what moved first as it was in the background and it requires more time to figure out. I wanted to show more to the moving landscape based on the changing time of day during a long flight, but I couldn’t figure out how to do a moving gradient sky and just kept it as a gradient.
(Clip Above shows Kate Hollenbach’s User is Present)
For this week’s Looking Outward post, I reviewed Kate Hollenbach’s project named User is Present. I particularly liked this project because it is an art piece that examines the interaction between the human and the mobile phone. The experience is captured and presented in an artistic form. I admired how she skillfully combined the world of art and technology to convey a message about a merge between the two worlds. I feel like this was done well, as Hollenbach has an extensive background in studying both worlds of technology and design.
Kate Hollenbach is an artist, programmer, and educator based in Los Angeles, California. Kate has a MFA from UCLA Design Media Arts and a B.Sc. in Computer Science and Engineering from MIT. Her work includes developing and examining interactive systems and new technologies relating to body, gesture, and physical space.
//Brandon Hyun
//bhyun1@andrew.cmu.edu
//15104 Section B
//Project 10
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
function setup() {
createCanvas(480, 480);
frameRate(10);
}
function draw() {
moon();
drawMountains1();
drawMountains2();
drawMountains3();
drawMountains4();
}
function drawMountains1(){
//noStroke();
fill(118,54,38,20);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed*0.5);
var y = map(noise(t), 0,1, 0, height);
vertex(x, y-15);
}
vertex(width,height);
vertex(0,height);
endShape();
}
function drawMountains2(){
fill(225,54,38,30);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed*0.5);
var y = map(noise(t), 0,1, 0, height*1.2);
vertex(x, y-15);
}
vertex(width,height);
vertex(0,height);
endShape();
}
function drawMountains3(){
fill(245,54,38,30);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed*0.5);
var y = map(noise(t), 0,1, 0, height*1.35);
vertex(x, y-15);
}
vertex(width,height);
vertex(0,height);
endShape();
}
function drawMountains4(){
fill(255,54,38,30);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed*0.5);
var y = map(noise(t), 0,1, 0, height*1.6);
vertex(x, y-15);
}
vertex(width,height);
vertex(0,height);
endShape();
}
function moon(){
fill(105,105,105);
ellipse(width/2,height/3,200,200);
}
I wanted to create an abstract landscape that creates continuous landscape and the contour lines create this 3-dimensional space. In order to create this feel, I increased the opaqueness of each mountain ranges and It has a surreal feel to it.
//var smoke = {x:120, y:365, w:35, h:20, d:0.5, a:150}
var dishes=[];
var smokes=[];
var eyelx=220;
var eyerx=260;
var sushiLinks = [
"https://i.imgur.com/dMoEprH.png",
"https://i.imgur.com/69T53Rk.png",
"https://i.imgur.com/LQ3xxUA.png",
"https://i.imgur.com/x19Rvvq.png",
"https://i.imgur.com/d7psp9U.png"]
var sushi = [];
function preload(){
for (var i = 0; i < sushiLinks.length; i++) {
sushi[i]=loadImage(sushiLinks[i]);
}
}
function setup() {
createCanvas(480,480);
for (var i = 0; i < 4; i++) {
dishes[i]=makeDish(-90+i*130);
}
for(var j = 0; j<3; j++){
smokes[j]= makeSmoke(120);
}
}
function draw() {
background(165,199,199);
drawCurtain();
drawChef();
drawEye();
drawBody();
drawBelt()
drawTable();
drawPlate();
drawDishPile();
drawCup();
//smoke
updateAndDisplaySmokes();
removeSmoke();
addNewSmoke();
//dishes on the belt
updateAndDisplayDishes();
removeDish();
addNewDish();
}
function drawCurtain(){
noStroke();
fill(82,106,121)
rect(0,0,width/2-5,90);
rect(width/2+5,0,width/2-5,90)
stroke(106,137,156);
strokeWeight(5);
rect(-15,-15,width/2-5,90);
rect(width/2+20,-15,width/2-5,90)
}
function drawChef(){
push();
noStroke();
rectMode(CENTER);
//hat
fill(129,153,160)
rect(width/2,120,100,30)
//face and neck
fill(235,216,190);
rect(width/2,170,100,70);
rect(width/2,210,50,20);
}
function drawEye(){
push();
fill(37)
ellipseMode(CENTER);
ellipse(eyelx,165,12,7)
ellipse(eyerx,165,12,7)
eyelx += 0.2;
eyerx += 0.2;
if(eyelx>=width/2-5){
eyelx = 205;
eyerx = 245;
}
pop();
}
function drawBody(){
//body
fill(152,178,186);
rect(width/2,300,130,160);
//collar
fill(129,151,158);
triangle(width/2-45,220,width/2+45,220,width/2,280);
fill(212,232,238);
triangle(width/2-30,220,width/2+30,220,width/2,260);
//arms
fill(129,153,160);
quad(width/2-65,220,width/2-90,250,width/2-90,310,width/2-65,310);
quad(width/2+65,220,width/2+90,250,width/2+90,310,width/2+65,310);
fill(235,216,190);
rect(width/2-77,345,24,70)
rect(width/2+77,345,24,70)
pop();
}
function drawBelt(){
noStroke();
fill(152,151,151)
rect(0,350,width,height/3)
fill(133);
rect(0,360,width,5);
fill(183);
rect(0,330,width,30)
}
function drawTable(){
fill(101,92,85);
rect(0,440,width,40);
}
function drawPlate(){
push();
rectMode(CENTER);
fill(222,207,175);
rect(width/2,420,130,15);
rect(width/2-30,428,20,23);
rect(width/2+30,428,20,23);
pop();
}
function drawDishPile(){
fill(240);
rect(width/2+110,389,90,7)
rect(width/2+110,406,90,7)
rect(width/2+110,423,90,7)
fill(218);
rect(width/2+125,396,60,10)
rect(width/2+125,413,60,10)
rect(width/2+125,430,60,10)
}
function drawCup(){
push();
fill(105,108,91);
rect(width/2-155,380,45,60,5)
pop();
}
function drawSmoke(){
fill(255,this.a)
ellipse(this.x,this.y,this.w,this.h);
}
function moveSmoke(){
this.x += this.d;
this.y -= this.d;
}
function scaleSmoke(){
this.w -= 0.2;
this.h -= 0.2;
}
function alphaSmoke(){
this.a -= 2;
}
function makeSmoke(birthLocationX) {
var smoke = {x:birthLocationX,
y:365,
w:35,
h:20,
d:0.3,
a:150,
move:moveSmoke,
scale:scaleSmoke,
alpha:alphaSmoke,
drawS:drawSmoke}
return smoke;
}
function updateAndDisplaySmokes(){
// Update the smoke position, scale, alpha
for (var i = 0; i < smokes.length; i++){
smokes[i].move();
smokes[i].scale();
smokes[i].alpha();
smokes[i].drawS();
}
}
function removeSmoke(){
var smokesToKeep = [];
for (var i = 0; i < smokes.length; i++){
if (smokes[i].a > 0) {
smokesToKeep.push(smokes[i]);
}
}
smokes = smokesToKeep;
}
function addNewSmoke(){
if(frameCount%45==0){
smokes.push(makeSmoke(120))
};
}
function makeDish(dishX) {
var dish = {x:dishX,
speed:1,
move:moveDish,
display:displayDish,
type:1}
return dish;
}
function updateAndDisplayDishes(){
// Update the dishes's positions, and display them.
for (var i = 0; i < dishes.length; i++){
dishes[i].move();
dishes[i].display(dishes[i].x, dishes[i].type);
}
}
function removeDish(){
var dishesToKeep = [];
for (var i = 0; i < dishes.length; i++){
if (dishes[i].x < 480) {
dishesToKeep.push(dishes[i]);
}
}
dishes = dishesToKeep;
}
function addNewDish(){
if(frameCount%120==0){
var newDish = makeDish(-90);
newDish.type = random([0,1,2,3,4]);
dishes.push(newDish)
}
}
//create dish and sushi
function displayDish(x,type){
push();
translate(this.x,314);
fill(240);
rect(0,0,90,7)
fill(218);
rect(15,7,60,10);
pop();
drawSushi(x + 45, type);
}
function moveDish(){
this.x += this.speed;
}
function drawSushi(x, type){
imageMode(CENTER)
image(sushi[type], x, 302);
}
This project, I thought about making a sushi conveyable belt. I thought about making different dishes of sushi moving on the screen and the different sushi need to appear randomly. Therefore, at first, I drew out the scene of a sushi restaurant, where we could see a plate, a cup of tea and some empty dishes on the table. Above the table, there was the conveyable belt with sushi. Behind the belt, there was a sushi chef who kept looking at the sushi. The final result is fun! I liked how I could translate my sketch into a moving webpage 🙂