Jonathan Liang – Curran Zhang – Final Project

sketch

/* Name : Jonathon Liang / Curran Zhang
   AndrewID : Jliang2 / Curranz
   Section : Section A 
   Final Project
*/

var terrainSpeed1 = 0.0002;
var terrainDetail1 = 0.015;
var terrainSpeed2 = 0.0004;
var terrainDetail2 = 0.008;
var clouds = []; 
var star = [];
var frames = []; 
var HeadX = 260;
var HeadY = 325; 
var ReflectionY =385
var step= 6;
var machox = 480;
var machoy = 300;
var girlx = 480;
var girly = 340;
var nekx = 480;
var neky = 240;
var towelx = 480;
var towely = 200;
var birdiex = 480;
var birdiey = 300;

function setup() {
  createCanvas(480, 480);
  //Iniate Clouds
  for (var i = 0; i <5; i++) {
      var r = random(width);
      clouds[i] = makeClouds(r);
  }
  //Head Image Position 
    imageMode(CENTER);
    frameRate(15);
}
function preload(){
 //Cats
	cat1 = loadImage("https://i.imgur.com/7hCkrYr.png");
	cat2 = loadImage("https://i.imgur.com/TWXWeM0.png");
	cat3 = loadImage("https://i.imgur.com/kRxHYt0.png");
	cat4 = loadImage("https://i.imgur.com/kkpAzvD.png");
	cat5 = loadImage("https://i.imgur.com/Hf9rTYl.png");
	birdie = loadImage("https://i.imgur.com/RdcS35J.png");

 //Head
    var filenames = [];
    filenames[0] = "https://i.imgur.com/leN6UXu.png";
	filenames[1] = "https://i.imgur.com/dydccNf.png";
	filenames[2] = "https://i.imgur.com/dcoiGqR.png";
	filenames[3] = "https://i.imgur.com/wez5P2S.png";
	filenames[4] = "https://i.imgur.com/9etlno8.png";
	filenames[5] = "https://i.imgur.com/yrjv4XT.png";
	filenames[6] = "https://i.imgur.com/hW3gKH6.png";
	filenames[7] = "https://i.imgur.com/Jg0yJck.png";
	filenames[8] = "https://i.imgur.com/dU1rruI.png";
    for (var i = 0; i < filenames.length; i++) {
        frames.push(loadImage(filenames[i]));
    }  
}

function draw() {
  //Gradient Background
    var from = color(250,0,0);
    var to = color(270);
    gradient(0,width,from,to);
    rect(0,0,480,480);
	  makeMountain1();
	  makeMoon();
	  makeStar();
	  makeMountain1();
	  makeMountain2();
	  makeReflection();
	  updateClouds();
	  removeClouds();
	  addClouds();
	strokeWeight(.5);
	stroke(255);
	text("early head gets the bird", 10, 15);
	text("touch a cat, you'll be sad", 10, 30);
	text("fly too high, and you'll die", 10, 45);
	  makeHead();
	  makeCat();
}

function gradient(y,w,from,to){
  for (var i = y; i <= height; i++) {
    var inter = map(i,y,y+w,0,1);
    var col = lerpColor(from,to,inter);
    stroke(col);
    strokeWeight(2);
    line(y,i,y+w,i);
  }
}

function makeStar(){
    fill(270);
    for (var i = 0; i < 100; i++) {
      var starX = random(width);
      var starY = random(height);
      ellipse(starX,starY,1,1);
    }
}

function makeMountain1(){
  noStroke();
  fill(180,0,0); 
  beginShape(); 
  for (var x = 0; x < width; x++) {
    var t = (x * terrainDetail1) + (millis() * terrainSpeed1);
    var y = map(noise(t), 0,1.8, height/8, height);
    vertex(x, y); 
  }
  vertex(width,height);
  vertex(0,height);
  endShape();
}

function makeMountain2(){
  fill(139,0,0); 
    noStroke();
    beginShape(); 
      for (var x = 0; x < width; x++) {
            var t = (x * terrainDetail2) + (millis() * terrainSpeed2);
            var y = map(noise(t), 0,2, height/2, height);
            vertex(x, y); 
      }
      vertex(width,height);
      vertex(0,height);
    endShape();
}

function makeReflection(){
  fill(220,50,50);
    rect(0, 375, width, 105);

  fill(255,60,60); 
    noStroke();
    beginShape(); 
      for (var x = 0; x < width; x++) {
            var t = (x * terrainDetail2) + (millis() * terrainSpeed2);
            var y = map(noise(t), 0,2, height, height*.5);
            vertex(x, y); 
      }
      vertex(width,height);
      vertex(0,height);
    endShape();
}

function makeMoon(){
    noStroke();
    fill(255,20);
    ellipse(2*width/3,height/4,170,170);
    ellipse(2*width/3,height/4,160,160);
    ellipse(2*width/3,height/4,150,150);
    ellipse(2*width/3,height/4,140,140);
    fill(255,200);
    ellipse(2*width/3,height/4,120,120);
}
function updateClouds(){
  for (var i = 0; i < clouds.length; i++) {
    clouds[i].move();
    clouds[i].display();
  }
}

function removeClouds(){
  var keepClouds = [];
  for (var i = 0; i < clouds.length; i++) {
      if (clouds[i].x + clouds[i].breadth > 0) {
        keepClouds.push(clouds[i]);
      }
  }
  clouds= keepClouds;
}

function addClouds(){
  var newCloud = .007;
  if (random(0,1)<newCloud) {
     clouds.push(makeClouds(width))
  }
}

function cloudMove(){
  this.x += this.speed;
}

function displayClouds(){
  fill(255,50);
  noStroke();
  ellipse(this.x,this.y,this.width,this.height);
  ellipse(this.x +10,this.y +10,this.width-10,this.height-10);
  ellipse(this.x +20,this.y -10,this.width/2,this.height/2);
  ellipse(this.x -20,this.y ,this.width-20,this.height-10);
}

function makeClouds(cloudy){
  var cloud= {x: cloudy,
              y:random(100, height/2),
              speed: random(-.2,-.7),
              width: random(50,100), 
              height:random(20,0),
              breadth:50,
              move:cloudMove,
              display:displayClouds
            }
  return cloud;          
}

function makeHead(){
  //Main Head
    push();
      translate(HeadX,HeadY);
      scale(.2,.2);
      image(frames[frameCount % 8], 0, 0);
    pop();    
  //Reflection
    push();
      translate(HeadX,ReflectionY);
      scale(.2,-.2);
      tint(255,127);
      image(frames[frameCount % 8], 0, 0);
    pop(); 
	if (keyIsDown(ENTER)){
	        HeadY -= step; 
	        ReflectionY += step;
	} else { HeadY += step;
	         HeadY = min(HeadY, 350);
	         ReflectionY -= step;
	         ReflectionY = max(ReflectionY,405);
	        }
	if (HeadY <= 100) {gameOver()};
}

function makeCat(){
	//MachoCat
		push();
			translate(machox,machoy);
			scale(.2,.2);
			image(cat1, 0,0);
			machox-=1.25;
			if (machox < 0) {lmachox = 480};
		pop();
		if (HeadX + 30 > machox & HeadX-30 < machox && machoy > HeadY  && HeadY > machoy - 30) {
			gameOver()};
	//MachoCat Reflection
		push();
			translate(machox,419);
			scale(.2,-.2);
			tint(265,160);
			image(cat1, 0,0);
			machox-=1.25;
			if (machox < 0) {machox = 480};
		pop();
	//School Girl
		push();
			translate(girlx,girly);
			scale(.18,.18);
			image(cat3, 0,0);
			girlx-=.8;
			if (girlx < 0) {girlx = 480};
		pop();
		if (HeadX + 30 > girlx & HeadX-30 < girlx && girly > HeadY  && HeadY > girly - 30) {
			gameOver();}
	//School Girl Reflection
		push();
			translate(girlx,409);
			scale(.18,-.18);
			tint(265,160);
			image(cat3, 0,0);
			girlx-=.8;
			if (girlx < 0) {girlx = 480};
		pop();
	//Neka
		push();
			translate(nekx,neky);
			scale(.6,.6);
			image(cat4, 0,0);
			nekx-=.5;
			if (nekx < 0) {nekx= 480};
		pop();
			if (HeadX + 30 > nekx & HeadX-30 < nekx && neky + 40 > HeadY  && HeadY > neky - 10) {
				gameOver()};
	//Neka Reflection
		push();
			translate(nekx,509);
			scale(.6,-.6);
			tint(265,160);
			image(cat4, 0,0);
			nekx-=.5;
			if (nekx < 0) {nekx = 480};
		pop();
	//Towel
		push();
			translate(towelx,towely);
			scale(.15,.15);
			image(cat5, 0,0);
			towelx-=5.05;
			if (towelx < 0) {towelx = 480};
		pop();
			if (HeadX + 30 > towelx & HeadX-30 < towelx && towely > HeadY  && HeadY > towely - 30) {
				gameOver()};
	//Birdie 
		push();
			translate(birdiex,birdiey);
			scale(-.15,.15);
			image(birdie, 0,0);
			birdiex-=5.05;
			if (birdiex < 0) {birdiex = 480};
			if (birdiey+30 > HeadY & HeadY> birdiey-30 && HeadX+30 > birdiex && HeadX-30 < birdiex)  {
				birdiex=480};
		pop();
}

function gameOver() {
	fill(0);
	textSize(75);
	textAlign(CENTER);
	textStyle(BOLD);
	text("GAME OVER", 240, 240);
	noLoop();
}

It all starts with an idea, but you can never tell where an idea can end up. Because ideas spread, they change, they grow, they connect us with the world. And in a fast-moving world, where good news moves at the speed of time and bad news isn’t always what is seems. Because when push comes to shove, we all deserve a second chance, to score.

For our Final Project Curran and I wanted to create a game that closely resembled our favorite mobile app game Battle Cats. But in our game we made it so that our protagonist cannot touch any of the white cats and has to try to eat the red chicken. The instructions are as followed: eat the chicken, avoid the white cats, and don’t fly too high; otherwise the game is over. Press enter to make the face move up.

Hope y’all enjoy.

Jonathan Liang – Final Project – Proposal

For the final project I kinda of want to blend a character animation with a game. I’ve always wanted to draw to animate a custom drawn character and implement it into an interactive environment. I am still not sure what exactly I want to create yet, but I hope that the sketch below gives y’all a good idea of what I kinda what to do.  I don’t think I will be collaborating with any other student for this project.

Jonathan Liang – Looking Outwards – 12

Two projects that I have been inspired by for my final project are Shanshui DaDA and the IOS game Battle Cats by PONOS. Many of my projects thus far this semester have involved drawing stuff onto the canvas, and Shanshui DaDA is taking that concept and putting in on steroids. This AI program allows any ordinary civilian (no matter how talented they are at drawing) to draw lines on an iPad and then it transforms their creation into a beautiful Chinese landscape painting.

Battle cats inspires me because I always wanted to try making an animated game of some sorts. After project 10 and the walking man assignment, I’ve really been interested in trying to animate some characters I created into p5js.

http://battle-cats.wikia.com/wiki/Main_Page

https://www.creativeapplications.net/member-submissions/shanshui-dada-ai-assists-human-creator-in-drawing-chinese-ink-wash-landscape-painting/

 

 

Jonathan Liang – Project 11 – Composition

sketch

//Jonathan Liang
//jliang2
//Section A

//draw lines on people haha

var t1;
var underlyingImage;
var longboy = -1;

function preload() {
    var myImageURL = "https://i.imgur.com/UveUHg1l.jpg";
    underlyingImage = loadImage(myImageURL); //load picture
}



function setup() {
	background(255);
    createCanvas(350, 480);
    image(underlyingImage, 0, 0);
    underlyingImage.loadPixels();
    t1 = makeTurtle(width/2, height/2);
    frameRate(35);
   
   
}

function draw() {
	if (longboy == 1) {
		t1.goto(mouseX, mouseY);
		t1.penDown();
		followTheMouse();

	}	

	if (longboy == -1) {
		t1.penUp();
		// t1.goto(mouseX, mouseY);

	}

	
}

function followTheMouse() {
	
	t1.setColor('black');
	t1.setWeight(3);
	t1.forward(2);
	t1.turnToward(mouseX, mouseY, 10);
	
}

function mousePressed() {
	longboy *= -1;
}

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;
}

It all starts with an idea, but you can never tell where an idea can end up. Because ideas spread, they change, they grow, they connect us with the world. And in a fast-moving world, where good news moves at the speed of time and bad news isn’t always what is seems. Because when push comes to shove, we all deserve a second chance, to score. A simple picture of an ordinary boy can be transformed. Ordinary boy can become the incredible hulk, thanks to turtles.

Jonathan Liang – Looking Outwards – 11

Adrien Kaeser’s Weather Thingy is a custom built sounds controller that modifies the sounds produced by musical instruments based on real-time climate settings. Weather Thingy is composed of two parts: a weather station on a tripod microphone and a custom built controller connected to a weather station. The station has climate sensors like a rain gauge, a wind vane, and a anemometer that assign various parameters received to audio effects. The main goal of Adrien’s work is to offer a new perspective to a replayability of a song. Since the same song with change based on the surrounding climate, it offers an unique experience each time the song is heard.

 

Weather Thingy – Real time climate sound controller

 

Jonathan Liang – Project 10 – Generative Landscape

sketch

//Jonathan Liang
//jliang2
//section A

var buildings = [];
var lamppost = [];
var tDetail = 0.01;
var tSpeed = 0.0004;
var frames = []; // An array to store the images
var x = 0; //variable to draw image from array
var rexX;  // The X location of the character
var rexY;  // The Y location of the character
var exampleImgOnly;

function preload() {
	var filenames = [];
	filenames[0] = "https://i.imgur.com/pUQqpVN.png";
	filenames[1] = "https://i.imgur.com/075wwQz.png";
	filenames[2] = "https://i.imgur.com/8aFEl6F.png";

	for (var i = 0; i < filenames.length; i++) {
		frames[i] = loadImage(filenames[i]);
	}
	exampleImgOnly = loadImage("https://i.imgur.com/pUQqpVN.png");
}


function setup() {
    createCanvas(480, 400);

    //initial buildings
    for (var i = 0; i < 11; i++) {
    	var ranx = random(width);
    	buildings[i] = makeBuilding(ranx);
    }
    rexX = 150; 
    rexY = 215; 
    frameRate(10);
    
   
}

function draw() {
	background(255);
	//generate line paper
	for(var y = 0; y < height; y += 10) {
		stroke(200);
		noFill();
		line(0, y, width, y);
	}
	displayHorizon();
	makeMountain();

	//draw objects
	//buildings
	updateAndDisplayBuildings();
	removeBuildings();
	addNewBuilding();
	//trex
	image(frames[x], rexX, rexY, 150, 150);
		x += 1;
		if (x > 2) {
			x = 0;
		}
	
}

function makeMountain() {
	//generates terrain
	stroke(0);
	strokeWeight(2);
	noFill();
	beginShape();
	for (var x1 = 0; x1 < width; x1++) {
		var t1 = (x1 * tDetail) + (millis() * tSpeed);
		var y1 = map(noise(t1), 0, 1, 0, height);
		vertex(x1, y1 - 20);
	}
	vertex(width, height);
	vertex(0, height);
	endShape();
}

function updateAndDisplayBuildings() {
	//update and display building position 
	for (var i = 0; i < buildings.length; i++) {
		buildings[i].move();
		buildings[i].display();
	}
}

function removeBuildings() {
	//remove buildings that have gone out of view
	var keepBuildings = [];
	for (var i = 0; i < buildings.length; i++) {
		if (buildings[i].x + buildings[i].breadth > 0) {
			keepBuildings.push(buildings[i]);
		}
	}
	buildings = keepBuildings //remember remaining buildings
}

function addNewBuilding() {
	//with very little probability, add new building
	var newBuildingLikelihood = 0.02;
	if (random(0, 1) < newBuildingLikelihood) {
		buildings.push(makeBuilding(width));
	}
}

// method to update position of building every frame
function buildingMove() {
    this.x += this.speed;
}

//drawing building and windows
function buildingDisplay() {
	//building
	var floorHeight = 20;
	var bHeight = this.nFloors * floorHeight;
	noFill();
	strokeWeight(2);
	stroke(0);
	push();
	translate(this.x, height - 50);
	rect(0, -bHeight, this.breadth, bHeight);
	//windows
	var wGap = this.breadth / 16;
	var xW = this.breadth / 16;
	for (var w = 0; w < 5; w++) {
		for (var i = 0; i < this.nFloors; i++) {
			fill('yellow');
			strokeWeight(1);
			stroke(0);
			rect(xW, -15 - (i * floorHeight), wGap * 2, 10);
		}
		xW += wGap * 3;
	}
	pop();
}

function makeBuilding(birthLocationX) {
	var bldg = {x: birthLocationX,
				breadth: 50,
				speed: -5.0,
				nFloors: round(random(3, 12)),
				move: buildingMove,
				display: buildingDisplay}
	return bldg;
}



//draw the ground
function displayHorizon() {
	stroke(0);
	strokeWeight(4);
	noFill();
	line(0, height - 50, width, height - 50);
}

It all starts with an idea, but you can never tell where an idea can end up. Because ideas spread, they change, they grow, they connect us with the world. And in a fast-moving world, where good news moves at the speed of time and bad news isn’t always what is seems. Because when push comes to shove, we all deserve a second chance, to score.

My project is heavily based on doodles I used to do throughout my elementary to high school days. I used to like to draw mountains, buildings, tanks, aliens, and dinosaurs blowing up stuff. I chose to add lines to the background to reflect that lined paper quality and made everything noFill to show that it was just a pen doodle.

Jonathan Liang – Looking Outwards – 10

                          in the eyes of the blind

Notes on Blindness is a short film by Peter Middleton and James Spinney. The film documents the life of a blind man called John Hull, and uses virtual reality and gameplay mechanics to recreate John’s cognitive and emotional memories. The genius behind the virtual reality component is French artist and art director Béatrice Lartigue. Lartigue is primarily known for her interactive installations and currently works in the interdisciplinary collaborative Lab212. She has won many awards, including the Google International Art Prize, Tribeca Film Festival Storyscapes Award, the Lumen Prize, as well as the Sundance Film Festival.

Notes on Blindness is definitely something to check out: http://epure.it/notes-on-blindness

 

More of her interesting work can be found on her website:

http://epure.it/

 

Jonathan Liang – Project 9 – Computational Portrait

sketch

//Jonathan Liang
//jliang2
//section A

var springy = 0.7; // how much velocity is retained after bounce
var np = 50;      // how many particles

var underlyingImage;

function preload() {
    var myImageURL = "https://i.imgur.com/obcoL1tl.jpg";
    underlyingImage = loadImage(myImageURL);
}

 
function particleStep() {
    var ix = constrain(floor(this.x), 0, width-1);
    var iy = constrain(floor(this.y), 0, height-1);
    var theColorAtLocationXY = underlyingImage.get(ix, iy);

    noStroke();
    fill(theColorAtLocationXY)
    ellipse(this.x, this.y, 5);

    
    this.x += this.dx;
    this.y += this.dy;


    if (this.x > width) { // bounce off right wall
        this.x = width - (this.x - width);
        this.dx = -this.dx * springy;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx * springy;
    }
    if (this.y > height) { // bounce off bottom
        this.y = height - (this.y - height);
        this.dy = -this.dy * springy;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy * springy;
    }

}
 

 
 
// create a "Particle" object with position and velocity
function makeParticle(px, py, pdx, pdy) {
	

    p = {x: px, y: py,
         dx: pdx, dy: pdy,
         step: particleStep,
        }
    return p;
}
 
var particles = [];
var randx = [];
var randy = []; 
 
function setup() {
    createCanvas(380, 480);
    background(0);
    underlyingImage.loadPixels();
    for (i = 0; i < np; i++) {
        randx[i] = random(-50, 50);
        randy[i] = random(-50, 50);
    }
    frameRate(5);
}
 
 
// draw all particles in the particles array
//
function draw() {
    background(230);
    for (var i = 0; i < np; i++) {
        // make a particle
        var p = makeParticle(200, 350,
                             randx[i], randy[i]);
        // push the particle onto particles array
        particles.push(p);
    }
    
    for (var i = 0; i < particles.length; i++) { // for each particle
        var p = particles[i];
  
        p.step();
    }

}

I chose a picture of my friend from high school. I wanted the ellipses that generated the image to first start from his mouth and then bounce everywhere to generate the image. Kind of like vomiting, but with a more artistic result. The ellipses slow down after they hit the walls so that it is clearer that they are bouncing and not just randomly generating wherever they want. Below is a few screenshots of the image being generated over time.

Jonathan Liang – Looking Outwards – 09

                        is it coral or is it a city?

Coral Cities is a project by Craig Taylor that visualizes cities in a unique way. Cities are usually mapped by their buildings, streets, and popular nodes; however, Taylor wanted to show how liveable a city is. He used raw data (such as crime rate, education, political stability, traffic, etc.) to generate a geo-spatial analysis of cities today, visualized as these coral structures.

This post by fellow architecture student Curran Zhang really stood out to me because of the emphasis in our field for mapping. We have been taught to try to find unique ways to map raw data, and Craig Taylor’s Coral Cities really offers a unique representation that could be interpreted in many different ways.

 

                             international cities

 

 

https://towardsdatascience.com/coral-cities-an-ito-design-lab-concept-c01a3f4a2722

Jonathan Liang – Looking Outwards – 08 – Creative Practice of an Individual

                                    mirror mirror

The work above is called Prismverse by Hong Kong media artist Chris Cheung. Chris is an artist who tries to integrate his artistic practice with his background in Chinese Philosophy. His work have common themes of integrating the traditional and the futuristic ideas as well as the aesthetics of technological intervention. Chris is currently the founder of an interdisciplinary creative studio called XEX, based in Hong Kong. Their work has been displayed all over Asia.

My personal favorite work of his is Prismverse. Prismverse is an installation that tries to immerse the viewer in infinity through sight and sound. Chris and XEX hoped that the diamond mirrors in the space would give the viewer a sense of the universe populated by infinite stars, and the omnidirectional speakers will present an ambient soundscape that immerses the viewer from all directions.

http://xcept.hk/