Final Project: Among Us Social Distancing Game

My final project is an Among Us-themed social distancing game. Among Us is an online multiplayer game that has gained significant popularity over the last several months during the quarantine. In my game, you play as a crewmate moving through the environment (the cafeteria environment from the Among Us game). Other crewmates are running past you and toward you and your goal is to socially distance from them by controlling your character’s movements with the keys. To make it easier to play within the blog the key controls are: W= up, A=left, S= down, and D= right, but in my submission, the character’s movements are controlled by the arrow keys. If one of the other crewmates enters your social distancing bubble (blue transparent circle around your character), you get a strike, and after five strikes you will lose the game. As you advance through the game, there will be more crewmates to avoid, requiring more skill and dexterity with the keys. You will win the game after successfully social distancing for one minute.
You can change your character’s color on the start screen by hitting enter. You can also click to advance to the instructions page and then again into gameplay. When the game is over you can click to play again. Overall, I am really happy with how this game turned out, but given more time I would add a settings page with a difficulty level selector and a sound option you can adjust before you play.

Social Distancing Game
var timer = 60;	//will hold seconds value for countdown (from 60 seconds)
var diams = [];	//holds diamond tiles of cafeteria floor
var lastOdd = false;	//boolean to determine when rows are eliminated
var startx = 270;	//starting x position for your character
var starty = 250	//starting y position for your character
var crewMate = makeCharacter(startx, starty, true);	//your character
var buddies = [];	//array to hold crewmates onscreen
var someoneInside = false	//is someone inside your social distancing bubble?
var counter = 0;	//how many strikes you have
var gameOver = false;	//did you lose?
var win = false;	//did you win?
var setting = 0;	//which screen you are on (0: starting, 1: instruction, 2: gameplay, 3: defeat, 4: victory)
//variables associated with choosing your character's color------------------------------------------------------------
var charcols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white']; 
var clr = 0;
var colChoice = 'red';	//this array will hold your character's color
//properties for stars on start screen---------------------------------------------------------------------------------
var starx = []; 
var stary = []; 
var stardx = [];
var starsize = [];
//preload game graphics------------------------------------------------------------------------------------------------
let img;
let winimg;
let startimg;
let instruct;

function preload() {
	img = loadImage('https://i.imgur.com/tMs0pNd.png');
	winimg = loadImage('https://i.imgur.com/ff97vVO.pngs');
	startimg = loadImage('https://i.imgur.com/Yy27NCE.png');
	instruct = loadImage('https://i.imgur.com/lIoslK6.png');
}

function setup() {
    createCanvas(600, 600);
    background(165,167,154);
    //set up the grid for the cafeteria floor tiles
    for (var row=0; row < 7; row++){
    	d_row = []
    	if (row % 2 == 0) {
    		for (var col=0; col < 6; col++){
    			if (col % 2 == 0) {
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    			else {
    				d_row.push(bigDiamond(col*105+35, row*105+35)) 
    			}
    		}
    		diams.push(d_row)
    	}
    	else {
    		for (var col=0; col < 7; col++){
    			if (col % 2 == 0){
    				d_row.push(bigDiamond(col*105+35, row*105+35))
    			}
    			else {
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    		}
    		diams.push(d_row)
    	}
    }
    //set up the array for the crew members that appear
    for (var i=0; i < 3; i++) {
    	buddies[i] = (makeCrew());
    }
    //set up arrays for stars on start screen
    for (var i=0; i<75; i++)  {
			starx[i]= random(width); 
			stary[i]= random(30, height-30); 
			stardx[i]= random(-5, -1);
			starsize[i] = random(3,8) 	
	}
    frameRate(10);
}

function draw() {
	var frameNum = frameCount
	if (setting == 0) {
		startScreen();
	}
	else if (setting == 1) {
		instructionPage();
	}
	else if (setting == 2) {
		gamePlay();
	}
	else if (setting == 3) {
		GameOver();
	}
	else if (setting == 4) {
		GameWon();
	}
	print('frameNum')
}

function mousePressed() {
	if (setting == 0) {	//proceed through the start screen and instructions to the actual gameplay
		setting = 1
	}
	else if (setting == 1) {	//enter gameplay
		setting = 2;	
	}
	//when the game ends, click to play again
	else if (setting == 3) {	
		gameReset()
		setting = 0
	}
	else if (setting == 4) {
		gameReset()
		setting = 0
	}
}
//display the start screen where you can change your character's color
function startScreen() {
	background(0)
	image(startimg, 0, 0, 600, 600);
	for (i=0; i<75; i++) {
		noStroke();
		fill(255);
		circle(starx[i], stary[i], starsize[i]);
		starx[i] += stardx[i]
	}
	starx.shift()	//shift array, moving first value
	stary.shift()
	starsize.shift()
	stardx.shift()
	var newX = 600; 
	var newY = random(30,height-30); 
	var newDX = random(-10, -5);
	var newSize = random(1,8)
	starx.push(newX);
	stary.push(newY);
	stardx.push(newDX);
	starsize.push(newSize);
	push();
	scale(3.75,3.75);
	translate(50,45)
	AmongUs1(colChoice)
	pop();
}
//pressing ENTER on the start screen will change your character's color
function keyPressed() {
	if (keyCode === ENTER & setting == 0){
	if (clr == 10) {
		clr=0
	}
	else {
		clr++; 
	}
	colChoice = charcols[clr]
	}	
}
//instructions: display the instructions for the game
function instructionPage() {
	background(0);
	image(instruct, 0, 0, 600, 600);
	for (i=0; i<75; i++) {
		noStroke();
		fill(255);
		circle(starx[i], stary[i], starsize[i]);
		starx[i] += stardx[i]
	}
	starx.shift()	//shift array, moving first value
	stary.shift()
	starsize.shift()
	stardx.shift()
	var newX = 600; 
	var newY = random(30,height-30); 
	var newDX = random(-10, -5);
	var newSize = random(1,8)
	starx.push(newX);
	stary.push(newY);
	stardx.push(newDX);
	starsize.push(newSize);
}
//reset the gameplay if you play again
function gameReset() {
	//resetting all sketch variables to original values
	frameNum = frameCount
    timer = 60;
	startx = 270;
	starty = 250
	crewMate = makeCharacter(startx, starty, true);	//starting position for your character
	buddies = [];
	someoneInside = false
	counter = 0;
	gameOver = false;
	win = false;
	charcols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white']; 
	clr = 0;
	colChoice = 'red';	//this array will hold your character's color
}
//GAMEPLAY--------------------------------------------------------------------------------------------------------------
function gamePlay() {
	if (timer == 0 & gameOver == false) {
		win = true
		setting = 4
	}
	background(165, 167, 154);
	displayDiamond();
	updateFloor();
	elimRow();
	updateRow();
	crewMate.draw();
	crewMate.update();
	updateRadius();
	drawbuddies();
	removebuddies();
	addMate();
	updatebuddies();
	StrikeCounter();
	Timer();
}
//crewmate constructor
function makeCharacter(x, y, right = true) {
	var c = getColor();
	var guy = {charx: x, chary: y, pos: 1, update: updateCharacter, draw: drawCharacter, col: c, facingRight: right}
	return guy;
}
//ACCESSORIES FOR YOUR CHARACTER---------------------------------------------------------------------------------------
//indicate how far away from others your character needs to be
function socialDistanceBubble(x,y,size) {
	noStroke();
	if (someoneInside == true) {	//if someone is inside your social distance bubble, your bubble turns red
		fill(200,0,0,.1*size)
	}
	else {
		fill(0,0,200,.1*size);
	}
	circle(x, y, size);
}
//function to draw shadow which will appear under your character
function Shadow(x,y) {
	noStroke();
	fill(60,60,60,200);
	ellipse(x, y, 70, 12)
}
//DISPLAY YOUR CHARACTER-----------------------------------------------------------------------------------------------
//display your character with x, y positions and color associated to them
//when you go left, your character will face left
function drawCharacter() {
	socialDistanceBubble(this.charx+30, this.chary+40, 220);
	Shadow(this.charx+30, this.chary+82)
	if (this.facingRight == false){
		push();
		scale(-1,1);
		if (this.pos == 1) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs1(colChoice);
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs2(colChoice);
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs3(colChoice);
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs4(colChoice);
			pop();
		}
		else {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs5(colChoice);
			pop();
		}
		pop();
	}
	if (this.facingRight == true) {
		if (this.pos == 1) {
			push();
			translate(this.charx, this.chary);
			AmongUs1(colChoice);
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(this.charx, this.chary);
			AmongUs2(colChoice);
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(this.charx, this.chary);
			AmongUs3(colChoice);
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(this.charx, this.chary);
			AmongUs4(colChoice);
			pop();
		}
		else {
			push();
			translate(this.charx, this.chary);
			AmongUs5(colChoice);
			pop();
		}
	}
}
//UPDATE YOUR CHARACTER'S POSITION-----------------------------------------------------------------------------
//update the among us character function drawn so the guy looks like he is walking
//you can control your character with the arrow keys
//your character cannot travel outside the boundaries of the screen
function updateCharacter(){
	if (keyIsDown(65) & this.charx > 20) {	//"A"
    	this.facingRight = false
    	this.charx -= 10;
  	}
  	if (keyIsDown(68) & this.charx < 540) {	//"D"
    	this.facingRight = true
    	this.charx += 10;
  	}
  	if (keyIsDown(87) & this.chary > 5) {	//"W"
    	this.chary -= 10;
  	}
  	if (keyIsDown(83) & this.chary < 520) {	//"S"
    	this.chary += 10;
  	}
	if (this.pos == 5){
		this.pos = 1;
	}
	else {
		this.pos += 1;
	}
}
//CHECK IF SOMEONE IS INSIDE YOUR SOCIAL DISTANCING BUBBLE------------------------------------------------------------
//update position of crewmate relative to your character
function updateRadius() {
	var inRad = false
	for (var i = 0; i < buddies.length; i++) {
		d = dist(buddies[i].charx, buddies[i].chary, crewMate.charx, crewMate.chary);
		if (d < 110) {
			inRad = true;
		}
	}
	if (inRad == true) {
		if (someoneInside ==  false) {
			counter++;
			if (counter == 5) {
				gameOver = true
				setting = 3
			}
			if (timer == 0 & counter < 5 && gameOver == false) {
				win = true
				setting = 4
			}
		}
		someoneInside = true;
	}
	else {
		someoneInside = false;
	}
}
//GAME FEATURES-------------------------------------------------------------------------------------------------------
//displays the strikes in the bottom left
function StrikeCounter() {	
	stroke(255)
	fill(0)
	strokeWeight(3)
	rect(20,550,160,35);
	noStroke()
	textStyle(BOLD);
	textSize(32);
	fill('#bf0000');	//dark red color for the X's
	if (counter == 1) {
		text('X', 40, 570);
	}
	if (counter == 2) {
		text('X', 40, 570);
		text('X', 70, 570);
	}
	if (counter == 3) {
		text('X', 40, 570);
		text('X', 70, 570);
		text('X', 100, 570);
	}
	if (counter == 4) {
		text('X', 40, 570);
		text('X', 70, 570);
		text('X', 100, 570);
		text('X', 130, 570);
	}
	if (counter == 5) {
		text('X', 40, 570);
		text('X', 70, 570);
		text('X', 100, 570);
		text('X', 130, 570);
		text('X', 160, 570);
	}
}
//display game timer in bottom right corner (countdown from 60 seconds)
function Timer() {
	var frameNum = frameCount
	stroke(255)
	fill(0);
	if (timer <= 10) {
		//noStroke();
		fill('#bf0000')
		textStyle(BOLD)
	}
	textFont('Arial Narrow')
	textAlign(CENTER, CENTER);
  	textSize(32);
  	text(timer, width-25, 570);
  	if (frameNum % 10 == 0) { 
    	timer --;
  	}
}
//displays when game is lost
function GameOver() {
	if (gameOver == true) {
		image(img, 0, 0, 600, 600);
		push();
		scale(5,5);
		translate(25,20)
		Dead1(colChoice)
		pop();
		textFont('Arial Narrow')
		textStyle(NORMAL)
		textAlign(CENTER, CENTER);
	  	textSize(35);
	  	fill(255)
	  	noStroke();
		text('Click to play again', width/2, 550)
		setting = 3
	}
}
//displays when game is won
function GameWon() {
	if (win == true) {
		image(winimg, 0, 0, 600, 600);
		push();
		scale(5,5);
		translate(25,25)
		AmongUs1(colChoice)
		pop();
		textFont('Arial Narrow')
		textStyle(NORMAL)
		textAlign(CENTER, CENTER);
	  	textSize(35);
	  	fill(255)
	  	noStroke();
		text('Click to play again', width/2, 550)	
		setting = 4
	}
}
//CREW (PROPERTIES OF OTHER CREWMATES)-----------------------------------------------------------------------------------
//display crew with x, y positions and color associated to them
function drawCrew() {
	if (this.fig == 0) {
		if (this.pos == 1) {
			push();
			translate(this.charx, this.chary)
			AmongUs1(this.col);
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(this.charx, this.chary)
			AmongUs2(this.col);
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(this.charx, this.chary)
			AmongUs3(this.col);
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(this.charx, this.chary)
			AmongUs4(this.col);
			pop();
		}
		else {
			push();
			translate(this.charx, this.chary)
			AmongUs5(this.col);
			pop();
		}
	}
	else {
		push();
		translate(this.charx, this.chary)
		Dead1(this.col);
		pop();
	}
}
//updates crewmate positions with different speeds (to go down canvas if walking and up if dead)
function updateCrew() {
	if (this.fig == 0) {
		this.chary += this.speed;
		if (this.pos == 5) {
			this.pos = 1;
		}
		else {
			this.pos += 1
		}
	}
	else {
		this.chary -= this.speed;
	}
}
//choose a random x position for newly generated crewmates
function getX() {
	var x = random(20, 530)
	if (x >= 160) {
		x += 70;
	}
	else {
		x -= 20;
	}
	return x;
}
//choose starting position at top of canvas for walking crewmates and bottom for dead crewmates so it looks like they are all moving with the screen
function start(f) {
	if (f == 0) {
		return 0
	}
	else {
		return 600
	}
}
//return a random speed from the array, to be assigned to individual crewmate
function getVelocity(status) {
	if (status == 0){
		return Math.floor(random(1,6));
	}
	else {
		return 5;
	}
}
//return a random color from the array, to be assigned to individual crewmate
//other crewmates will not have the same color as your character
function getColor() {
	var cols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white'];
	var index = Math.floor(Math.random() * cols.length); 
	while (colChoice == cols[index]) {
		index = Math.floor(Math.random() * cols.length)
	}
	return cols[index]
}
//assign object properties to the crew (crewmates onscreen)
function makeCrew() {
	var x = getX();
	var f = Math.floor(random(0,2));
	var y = start(f);
	var v = getVelocity(f);
	var c = getColor();
	var crew = {charx: x, chary: y, speed: v, update: updateCrew, pos: 1, fig: f, draw: drawCrew, col: c}
	return crew
}
//draw new crewmates
function drawbuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].draw();
	}
}
//update position of new crewmates
function updatebuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].update();
	}
}
//remove crewmates as they pass offscreen
function removebuddies() {
	keep = []
	for (var i=0; i < buddies.length; i++){
		if (buddies[i].chary +600 > 0) {
			keep.push(buddies[i])
		}
	}
	buddies = keep;
}
//add new crewmates with a probability based on the stage (increasing difficulty every 15 seconds)
function addMate() {
	var threshold;
	if (60>timer & timer>=45) {
		threshold = 0.02
	}
	if (45>timer && timer>=30) {
		threshold = 0.045
	}
	if (30>timer && timer>=15) {
		threshold = 0.055
	}
	if (15>timer && timer>=0) {
		threshold = 0.06
	}
	if (random(0,1) < threshold) {
		buddies.push(makeCrew())
	}
}
//CHARACTER DRAWING-----------------------------------------------------------------------------------------------------
//draw all the stages of walking for one crewmate
function AmongUs1(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(20,9);
	curveVertex(15,29);
	curveVertex(15,64);
	curveVertex(21,77);
	curveVertex(32,75);
	curveVertex(33,63);
	curveVertex(39,63);
	curveVertex(42,75);
	curveVertex(52,72);	//front of foot
	curveVertex(57,60);
	curveVertex(56,42);
	curveVertex(59,24);
	curveVertex(50,10);
	curveVertex(35,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}

function AmongUs2(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(15,57);
	curveVertex(5,68);
	curveVertex(19,78);
	curveVertex(34,63);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(22,6);
	curveVertex(15,30);
	curveVertex(15,56);
	curveVertex(24,65);
	curveVertex(34,65);
	curveVertex(42,66);
	curveVertex(55,79);
	curveVertex(68,70);
	curveVertex(52,59);	//front of foot
	curveVertex(55,47);
	curveVertex(55,34);
	curveVertex(58,21);
	curveVertex(47,7);
	curveVertex(33,2);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs3(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(46,56);
	curveVertex(48,73);
	curveVertex(19,72);
	curveVertex(19,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(19,10);
	curveVertex(15,35);
	curveVertex(17,61);
	curveVertex(25,68);
	curveVertex(28,75);
	curveVertex(24,83);
	curveVertex(36,82);
	curveVertex(41,71);
	curveVertex(39,60);	//front of foot
	curveVertex(49,58);
	curveVertex(57,50);
	curveVertex(56,35);
	curveVertex(58,25);
	curveVertex(54,14);
	curveVertex(45,8);
	curveVertex(32,4);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs4(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(40,60);
	curveVertex(56,79);
	curveVertex(66,65);
	curveVertex(54,52);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(25,4);
	curveVertex(16,24);
	curveVertex(15,54);
	curveVertex(19,61);
	curveVertex(8,61);
	curveVertex(5,74);
	curveVertex(19,76);
	curveVertex(28,69);
	curveVertex(32,63);	//front of foot
	curveVertex(45,63);
	curveVertex(56,56);
	curveVertex(58,38);
	curveVertex(58,26);
	curveVertex(54,12);
	curveVertex(43,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs5(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(32,61);
	curveVertex(34,76);
	curveVertex(49,76);
	curveVertex(50,56);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(24,3);
	curveVertex(17,24);
	curveVertex(16,51);
	curveVertex(15,59);
	curveVertex(23,59);
	curveVertex(10,64);
	curveVertex(12,72);
	curveVertex(32,70);
	curveVertex(37,62);	//front of foot
	curveVertex(49,62);
	curveVertex(56,54);
	curveVertex(58,34);
	curveVertex(58,23);
	curveVertex(54,13);
	curveVertex(47,5);
	curveVertex(35,1);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
//draw a dead crewmate
function Dead1(c) {
	stroke(0);
	strokeWeight(5);
	fill(255);
	//bone sticking out
	beginShape();
	curveVertex(33,39);
	curveVertex(32,29);
	curveVertex(27,22);
	curveVertex(32,18);
	curveVertex(35,23);
	curveVertex(37,17);
	curveVertex(41,21);
	curveVertex(38,32);
	curveVertex(38,42);
	endShape(CLOSE);
	fill(c);
	//arm
	beginShape();
	curveVertex(2,39);
	curveVertex(12,34);
	curveVertex(20,38);
	curveVertex(18,60);
	curveVertex(6,59);
	endShape(CLOSE);
	//half body
	beginShape();
	curveVertex(15,37);
	curveVertex(28,40);
	curveVertex(34,37);
	curveVertex(44,40);
	curveVertex(58,38);
	curveVertex(57,66);
	curveVertex(45,74);
	curveVertex(41,62);
	curveVertex(35,62);
	curveVertex(32,74);
	curveVertex(17,73);
	curveVertex(14,49);
	endShape(CLOSE);
}
//BACKGROUND-------------------------------------------------------------------------------------------------------------
//draw the cafeteria floor
//make small diamond tile object
function smallDiamond(x, y) {
	var diamond = {diamondx: x, diamondy: y, diamondw: 70, diamondh: 35, speed: -5.0, draw: drawDiamond, update: updateDiamond}
	return diamond;
}
//draw small diamond
function drawDiamond() {
	noStroke();
	fill(133,135,124);
	beginShape();
	vertex(this.diamondx,this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy-this.diamondh);
	vertex(this.diamondw+this.diamondx, this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy+this.diamondh);
	endShape(CLOSE);
}
//update position of the tile with speed
function updateDiamond() {
	this.diamondy += this.speed;
}
//make big diamond tile object
function bigDiamond(cx, cy) {
	var bigdiam = {leftD: smallDiamond(cx-70, cy), topD: smallDiamond(cx-35, cy-35), rightD: smallDiamond(cx, cy), bottomD: smallDiamond(cx-35, cy+35), draw: drawBigDiamond, update: updateBigDiamond}
	return bigdiam;
}
//make big diamond tile from smaller diamond tiles
function drawBigDiamond() {
	this.leftD.draw()
	this.topD.draw()
	this.rightD.draw()
	this.bottomD.draw()
}
//update position of big diamond tiles
function updateBigDiamond() {
	this.leftD.update();
	this.topD.update();
	this.rightD.update();
	this.bottomD.update();
}
//draw the diamonds
function displayDiamond() {
	for (var i=0; i < diams.length; i++){
		for (var j=0; j < diams[i].length; j++){
			diams[i][j].draw();
		}
	}
}
//update the positons of the diamonds as the screen scrolls
function updateFloor() {
	for (var i=0; i < diams.length; i++) {
		for (var j=0; j < diams[i].length; j++) {
			diams[i][j].update();
		}
	}
}
//get rid of rows that have slipped offscreen
function elimRow(){
	keepRow = false;
	for (var i=0; i < diams[0].length; i++) {
		if (lastOdd == false){
			if (i % 2 == 0) {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0) {
					keepRow = true
				}
			}
			else {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
		}
		else {
			if (i % 2 == 0) {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
			else {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0){
					keepRow = true
				}
			}
		}
	}
	if (keepRow == false){
		diams.shift();
	}
}
//update the new rows added such that they match the original cafeteria tile pattern
function updateRow() {
	if (diams.length < 7){
		n_row = []
		if (lastOdd == true){
			for (var col=0; col < 7; col++){
				if (col % 2 == 0) {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    		else {
	    			n_row.push(bigDiamond(col*105+35, 665)) 
	    		}
			}
			diams.push(n_row);
			lastOdd = false;
		}
		else {
			for (var col=0; col < 7; col++){
	    		if (col % 2 == 0){
	    			n_row.push(bigDiamond(col*105+35, 665))
	    		}
	    		else {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    	}
	    	diams.push(n_row);
	    	lastOdd = true;
		} 
	}
}

Project 11: Generative Landscape (Among Us)

For this project, I wanted to make my landscape like you are scrolling through the cafeteria in the Among Us game with different crewmates (dead or alive) moving past you.

amongus
var diams = [];
var lastOdd = false;
var crewMate = makeCharacter(160, 250);
var buddies = [];


function setup() {
    createCanvas(400, 600);
    background(165,167,154);
    //set up the grid for the cafeteria floor tiles
    for (var row=0; row < 7; row++){
    	d_row = []
    	if (row % 2 == 0) {
    		for (var col=0; col < 4; col++){
    			if (col % 2 == 0) {
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    			else {
    				d_row.push(bigDiamond(col*105+35, row*105+35)) 
    			}
    		}
    		diams.push(d_row)
    	}
    	else {
    		for (var col=0; col < 5; col++){
    			if (col % 2 == 0){
    				d_row.push(bigDiamond(col*105+35, row*105+35))
    			}
    			else{
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    		}
    		diams.push(d_row)
    	}
    }
    //set up the array for the crew members that appear
    for (var i=0; i < 3; i++) {
    	buddies[i] = (makeCrew());
    }
    frameRate(8);
}

function draw() {
	background(165,167,154);
	displayDiamond();
	updateFloor();
	elimRow();
	updateRow();
	crewMate.draw();
	crewMate.update();
	drawbuddies();
	removebuddies();
	addMate();
	updatebuddies();
}
//update the among us character function drawn so the guy looks like he is walking
function updateCharacter(){
	if (this.pos == 5){
		this.pos = 1;
	}
	else {
		this.pos += 1;
	}
}
//display character with x, y positions and color associated to them
function drawCharacter() {
	if (this.pos == 1) {
		push();
		translate(this.charx, this.chary);
		AmongUs1(color(this.col));
		pop();
	}
	else if (this.pos == 2) {
		push();
		translate(this.charx, this.chary);
		AmongUs2(color(this.col));
		pop();
	}
	else if (this.pos == 3) {
		push();
		translate(this.charx, this.chary);
		AmongUs3(color(this.col));
		pop();
	}
	else if (this.pos == 4) {
		push();
		translate(this.charx, this.chary);
		AmongUs4(color(this.col));
		pop();
	}
	else {
		push();
		translate(this.charx, this.chary);
		AmongUs5(color(this.col));
		pop();
	}
}

//make the guy an object
function makeCharacter(x, y) {
	var c = getColor();
	var guy = {charx: x, chary: y, pos: 1, update: updateCharacter, draw: drawCharacter, col: c}
	return guy;
}

//display crew with x, y positions and color associated to them
function drawCrew() {
	if (this.fig == 0) {
		if (this.pos == 1) {
			push();
			translate(this.charx, this.chary)
			AmongUs1(color(this.col));
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(this.charx, this.chary)
			AmongUs2(color(this.col));
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(this.charx, this.chary)
			AmongUs3(color(this.col));
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(this.charx, this.chary)
			AmongUs4(color(this.col));
			pop();
		}
		else {
			push();
			translate(this.charx, this.chary)
			AmongUs5(color(this.col));
			pop();
		}
	}
	else {
		push();
		translate(this.charx, this.chary)
		Dead1(color(this.col));
		pop();
	}
}
//updates crewmate positions with different speeds (to go down canvas if walking and up if dead)
function updateCrew() {
	if (this.fig == 0) {
		this.chary += this.speed;
		if (this.pos == 5) {
			this.pos = 1;
		}
		else {
			this.pos += 1
		}
	}
	else {
		this.chary -= this.speed;
	}
}
//choose a random x position for newly generated crewmates
function getX() {
	var x = random(20, 330)
	if (x >= 160) {
		x += 70;
	}
	else {
		x -= 20;
	}
	return x;
}
//choose starting position at top of canvas for walking crewmates and bottom for dead crewmates so it looks like they are all moving with the screen
function start(f) {
	if (f == 0) {
		return 0
	}
	else {
		return 600
	}
}
//return a random speed from the array, to be assigned to individual crewmate
function getVelocity(status) {
	if (status == 0){
		return Math.floor(random(1,6));
	}
	else {
		return 5;
	}
}
//return a random color from the array, to be assigned to individual crewmate
function getColor() {
	var cols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white'];
	var index = Math.floor(Math.random() * cols.length)
	return cols[index];
}

//assign object properties to the crew (crewmates onscreen)
function makeCrew() {
	var x = getX();
	var f = Math.floor(random(0,2));
	var y = start(f);
	var v = getVelocity(f);
	var c = getColor();
	var crew = {charx: x, chary: y, speed: v, update: updateCrew, pos: 1, fig: f, draw: drawCrew, col: c}
	return crew
}
//draw new crewmates
function drawbuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].draw();
	}
}

function updatebuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].update();
	}
}
//remove crewmates as they pass offscreen
function removebuddies() {
	keep = []
	for (var i=0; i < buddies.length; i++){
		if (buddies[i].chary +600 > 0) {
			keep.push(buddies[i])
		}
	}
	buddies = keep;
}
//add new crewmates with a probability of 2%
function addMate() {
	var threshold = 0.02
	if (random(0,1) < threshold) {
		buddies.push(makeCrew())
	}
}
//draw all the stages of walking for one crewmate
function AmongUs1(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(20,9);
	curveVertex(15,29);
	curveVertex(15,64);
	curveVertex(21,77);
	curveVertex(32,75);
	curveVertex(33,63);
	curveVertex(39,63);
	curveVertex(42,75);
	curveVertex(52,72);	//front of foot
	curveVertex(57,60);
	curveVertex(56,42);
	curveVertex(59,24);
	curveVertex(50,10);
	curveVertex(35,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}

function AmongUs2(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(15,57);
	curveVertex(5,68);
	curveVertex(19,78);
	curveVertex(34,63);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(22,6);
	curveVertex(15,30);
	curveVertex(15,56);
	curveVertex(24,65);
	curveVertex(34,65);
	curveVertex(42,66);
	curveVertex(55,79);
	curveVertex(68,70);
	curveVertex(52,59);	//front of foot
	curveVertex(55,47);
	curveVertex(55,34);
	curveVertex(58,21);
	curveVertex(47,7);
	curveVertex(33,2);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs3(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(46,56);
	curveVertex(48,73);
	curveVertex(19,72);
	curveVertex(19,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(19,10);
	curveVertex(15,35);
	curveVertex(17,61);
	curveVertex(25,68);
	curveVertex(28,75);
	curveVertex(24,83);
	curveVertex(36,82);
	curveVertex(41,71);
	curveVertex(39,60);	//front of foot
	curveVertex(49,58);
	curveVertex(57,50);
	curveVertex(56,35);
	curveVertex(58,25);
	curveVertex(54,14);
	curveVertex(45,8);
	curveVertex(32,4);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs4(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(40,60);
	curveVertex(56,79);
	curveVertex(66,65);
	curveVertex(54,52);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(25,4);
	curveVertex(16,24);
	curveVertex(15,54);
	curveVertex(19,61);
	curveVertex(8,61);
	curveVertex(5,74);
	curveVertex(19,76);
	curveVertex(28,69);
	curveVertex(32,63);	//front of foot
	curveVertex(45,63);
	curveVertex(56,56);
	curveVertex(58,38);
	curveVertex(58,26);
	curveVertex(54,12);
	curveVertex(43,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs5(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(32,61);
	curveVertex(34,76);
	curveVertex(49,76);
	curveVertex(50,56);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(24,3);
	curveVertex(17,24);
	curveVertex(16,51);
	curveVertex(15,59);
	curveVertex(23,59);
	curveVertex(10,64);
	curveVertex(12,72);
	curveVertex(32,70);
	curveVertex(37,62);	//front of foot
	curveVertex(49,62);
	curveVertex(56,54);
	curveVertex(58,34);
	curveVertex(58,23);
	curveVertex(54,13);
	curveVertex(47,5);
	curveVertex(35,1);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
//draw a dead crewmate
function Dead1(c) {
	stroke(0);
	strokeWeight(5);
	fill(255);
	//bone sticking out
	beginShape();
	curveVertex(33,39);
	curveVertex(32,29);
	curveVertex(27,22);
	curveVertex(32,18);
	curveVertex(35,23);
	curveVertex(37,17);
	curveVertex(41,21);
	curveVertex(38,32);
	curveVertex(38,42);
	endShape(CLOSE);
	fill(c);
	//arm
	beginShape();
	curveVertex(2,39);
	curveVertex(12,34);
	curveVertex(20,38);
	curveVertex(18,60);
	curveVertex(6,59);
	endShape(CLOSE);
	//half body
	beginShape();
	curveVertex(15,37);
	curveVertex(28,40);
	curveVertex(34,37);
	curveVertex(44,40);
	curveVertex(58,38);
	curveVertex(57,66);
	curveVertex(45,74);
	curveVertex(41,62);
	curveVertex(35,62);
	curveVertex(32,74);
	curveVertex(17,73);
	curveVertex(14,49);
	endShape(CLOSE);

}
//draw the cafeteria floor
//make small diamond tile object
function smallDiamond(x, y) {
	var diamond = {diamondx: x, diamondy: y, diamondw: 70, diamondh: 35, speed: -5.0, draw: drawDiamond, update: updateDiamond}
	return diamond;
}
//draw small diamond
function drawDiamond() {
	noStroke();
	fill(133,135,124);
	beginShape();
	vertex(this.diamondx,this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy-this.diamondh);
	vertex(this.diamondw+this.diamondx, this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy+this.diamondh);
	endShape(CLOSE);
}
//update position of the tile with speed
function updateDiamond() {
	this.diamondy += this.speed;
}
//make big diamond tile object
function bigDiamond(cx, cy) {
	var bigdiam = {leftD: smallDiamond(cx-70, cy), topD: smallDiamond(cx-35, cy-35), rightD: smallDiamond(cx, cy), bottomD: smallDiamond(cx-35, cy+35), draw: drawBigDiamond, update: updateBigDiamond}
	return bigdiam;
}
//make big diamond tile from smaller diamond tiles
function drawBigDiamond() {
	this.leftD.draw()
	this.topD.draw()
	this.rightD.draw()
	this.bottomD.draw()
}
//update position of big diamond tiles
function updateBigDiamond() {
	this.leftD.update();
	this.topD.update();
	this.rightD.update();
	this.bottomD.update();
}
//draw the diamonds
function displayDiamond() {
	for (var i=0; i < diams.length; i++){
		for (var j=0; j < diams[i].length; j++){
			diams[i][j].draw();
		}
	}
}
//update the positons of the diamonds as the screen scrolls
function updateFloor() {
	for (var i=0; i < diams.length; i++) {
		for (var j=0; j < diams[i].length; j++) {
			diams[i][j].update();
		}
	}
}
//get rid of rows that have slipped offscreen
function elimRow(){
	keepRow = false;
	for (var i=0; i < diams[0].length; i++) {
		if (lastOdd == false){
			if (i % 2 == 0) {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0) {
					keepRow = true
				}
			}
			else {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
		}
		else {
			if (i % 2 == 0) {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
			else {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0){
					keepRow = true
				}
			}
		}
	}
	if (keepRow == false){
		diams.shift();
	}
}
//update the new rows added such that they match the original cafeteria tile pattern
function updateRow() {
	if (diams.length < 7){
		n_row = []
		if (lastOdd == true){
			for (var col=0; col < 4; col++){
				if (col % 2 == 0) {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    		else {
	    			n_row.push(bigDiamond(col*105+35, 665)) 
	    		}
			}
			diams.push(n_row);
			lastOdd = false;
		}
		else {
			for (var col=0; col < 5; col++){
	    		if (col % 2 == 0){
	    			n_row.push(bigDiamond(col*105+35, 665))
	    		}
	    		else {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    	}
	    	diams.push(n_row);
	    	lastOdd = true;
		} 
	}
}

Looking Outwards 11: A Focus on Women Practitioners

The artist I chose to research this week is Karolina Sobecka. Sobecka was born in Warsaw, Poland and has been known to work across many disciplines, specifically synthesizing art and science. She received her BFA from the School of the Art Institute of Chicago, and her MFA in Experimental Animation and Integrated Media from the California Institute of the Arts. Much of her work is interventionist or interactive in nature, serving to promote environmental and social activism. One project of hers I focused on was entitled “Cloud Machine.” This is a small device sent into the atmosphere to develop and disperse miniature clouds in our atmosphere.

Karolina Sobecka’s “Cloud Machine” as it creates clouds through water vapor dispersal (2014).

This project is quite interesting to me and it creates a unique juxtaposition between manmade and natural processes in a way that is almost performative. Further, it is a also a legitimate response to a climate issue, as scientists have proposed developing larger-scale, but conceptually similar devices to achieve the same effect of global cooling. I appreciate how Sobecka uses her artistic and engineering skills to address a relevant issue.

Project 10-2020 Election Highlights Sonic Story

My sound story includes some highlights from the 2020 Presidential Election. I included audio clips from debates, the presidential anthem, and TikTok songs with special guest the Fly that landed on Mike Pence’s head.

election
function preload() {
    // load sounds for sound story
    buzz = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/flybuzz.wav");
    talk = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/imspeaking.wav");
    president = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/presidential.wav");
    banjo = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/banjo.wav");
    loser = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/loser.wav");
}
//set values for brownian motion of fly
var Y = 0;
var X = 5;
var noiseParam= 0;
var noiseStep= 0.1;

function setup() {
    // you can change the next 2 lines:
    createCanvas(480, 480);
    //======== call the following to use sound =========
    useSound();
    imageMode(CENTER);
    frameRate(14);
}
function soundSetup() { // setup for audio generation
    //set volumes for sounds
    buzz.setVolume(0.1);
    talk.setVolume(0.5);
    president.setVolume(0.5);
    banjo.setVolume(1.0);
    loser.setVolume(0.4);

}
function Joe() {
    background(0,86,217);
    //draw joe biden 
    noStroke();
    //shirt
    fill(245);
    rect(145,414,200,100);
    //neck
    fill(225,176,161);
    beginShape();
    curveVertex(162,314);
    curveVertex(161,368);
    curveVertex(224,438);
    curveVertex(272,437);
    curveVertex(331,375);
    curveVertex(331,321);
    endShape(CLOSE);
    //face
    fill(250,218,205)
    beginShape();
    curveVertex(180,53);
    curveVertex(153,84);
    curveVertex(155,119);
    curveVertex(152,160);
    curveVertex(142,213);
    curveVertex(172,247);
    curveVertex(218,255);
    curveVertex(258,261);
    curveVertex(291,270);
    curveVertex(361,270);
    curveVertex(369,254);
    curveVertex(371,212);
    curveVertex(363,139);
    curveVertex(360,90);
    curveVertex(344,65);
    curveVertex(252,48);
    endShape(CLOSE);
    //left ear
    fill(225,176,161);
    beginShape();
    curveVertex(122,181);
    curveVertex(112,191);
    curveVertex(105,214);
    curveVertex(123,257);
    curveVertex(153,225);
    endShape(CLOSE);
    //right ear
    beginShape();
    curveVertex(372,206);
    curveVertex(393,230);
    curveVertex(402,239);
    curveVertex(395,267);
    curveVertex(358,302);
    curveVertex(369,250);
    endShape(CLOSE);
    //frame
    noFill();
    stroke(200)
    strokeWeight(3)
    line(204,173,303,179);
    arc(252,210,44,44,radians(200), 0)
    //left lens
    strokeWeight(4)
    fill(29,31,34,230)
    beginShape();
    curveVertex(174,172);
    curveVertex(159,190);
    curveVertex(157,221);
    curveVertex(181,242);
    curveVertex(218,233);
    curveVertex(245,198);
    curveVertex(231,175);
    curveVertex(202,171);
    endShape(CLOSE);
    //right lens
    beginShape();
    curveVertex(274,181);
    curveVertex(262,197);
    curveVertex(277,226);
    curveVertex(309,250);
    curveVertex(334,245);
    curveVertex(348,220);
    curveVertex(345,192);
    curveVertex(326,181);
    curveVertex(303,177);
    endShape(CLOSE);
    //hair
    noStroke();
    fill(255);
    beginShape();
    curveVertex(205,24);
    curveVertex(167,43);
    curveVertex(141,73);
    curveVertex(125,112);
    curveVertex(119,139);
    curveVertex(115,165);
    curveVertex(117,185);
    curveVertex(137,198);
    curveVertex(143,204);
    curveVertex(164,92);
    curveVertex(183,62);
    curveVertex(213,52);
    curveVertex(251,49);
    curveVertex(331,67);
    curveVertex(357,100);
    curveVertex(368,223);
    curveVertex(383,215);
    curveVertex(391,165);
    curveVertex(379,113);
    curveVertex(371,73);
    curveVertex(337,44);
    curveVertex(305,27);
    curveVertex(251,26);
    endShape(CLOSE);
    //mask
    fill(0);
    beginShape();
    curveVertex(129,185);
    curveVertex(148,211);
    curveVertex(167,233);
    curveVertex(190,243);
    curveVertex(223,245);
    curveVertex(240,244);
    curveVertex(277,255);
    curveVertex(324,263);
    curveVertex(362,257);
    curveVertex(385,222);
    curveVertex(391,228);
    curveVertex(373,255);
    curveVertex(365,287);
    curveVertex(361,327);
    curveVertex(334,353);
    curveVertex(312,375);
    curveVertex(284,400);
    curveVertex(241,413);
    curveVertex(200,389);
    curveVertex(167,342);
    curveVertex(145,310);
    curveVertex(122,285);
    curveVertex(119,257);
    curveVertex(135,226);
    curveVertex(125,193);
    endShape(CLOSE);
    //left shoulder
    fill(43,43,55);
    beginShape();
    curveVertex(164,347);
    curveVertex(152,412);
    curveVertex(161,478);
    curveVertex(0,478);
    curveVertex(0,423);
    curveVertex(108,395);
    endShape(CLOSE);
    //right shoulder
    beginShape();
    curveVertex(335,362);
    curveVertex(343,418);
    curveVertex(335,480);
    curveVertex(399,480);
    curveVertex(438,480);
    curveVertex(480,480);
    curveVertex(480,447);
    curveVertex(394,419);
    endShape(CLOSE);  
    //left collar
    fill(255);
    beginShape();
    curveVertex(159,345);
    curveVertex(234,437);
    curveVertex(187,479);
    curveVertex(157,479);
    curveVertex(145,407);
    endShape(CLOSE);
    //right collar
    beginShape();
    curveVertex(335,358);
    curveVertex(355,406);
    curveVertex(347,480);
    curveVertex(308,480);
    curveVertex(267,434);
    endShape(CLOSE);
    //tie knot
    fill(50,50,74);
    beginShape();
    curveVertex(233,430);
    curveVertex(219,445);
    curveVertex(223,480);
    curveVertex(263,480);
    curveVertex(289,454);
    curveVertex(266,424);
    endShape(CLOSE);
}

//draw mike pence
function Mike(){
    background(248,95,90);
    noStroke();
    //shirt
    beginShape();
    fill(241, 237, 234);
    curveVertex(218,346);
    curveVertex(187,374);
    curveVertex(171,395);
    curveVertex(179,479);
    curveVertex(278,479);
    curveVertex(295,391);
    curveVertex(261,351);
    endShape(CLOSE);
    //left shoulder
    fill(0);
    beginShape();
    vertex(172,268);
    vertex(127,282);
    vertex(87,298);
    vertex(44,323);
    vertex(0,331);
    vertex(0,479);
    vertex(193,479);
    vertex(172,380);
    vertex(160,300);
    endShape(CLOSE);
    //right shoulder
    beginShape();
    vertex(325,286);
    vertex(334,294);
    vertex(351,312);
    vertex(396,330);
    vertex(448,354);
    vertex(479,368);
    vertex(479,479);
    vertex(258,479);
    vertex(289,402);
    vertex(316,304);
    endShape(CLOSE);
    //left ear
    fill(236, 166, 133);
    beginShape();
    curveVertex(185,145);
    curveVertex(175,127);
    curveVertex(167,133);
    curveVertex(165,149);
    curveVertex(165,177);
    curveVertex(165,201);
    curveVertex(168,214);
    curveVertex(175,217);
    endShape(CLOSE);
    //right ear
    beginShape();
    curveVertex(363,203);
    curveVertex(378,194);
    curveVertex(388,198);
    curveVertex(387,214);
    curveVertex(371,231);
    curveVertex(359,252);
    curveVertex(349,267);
    curveVertex(339,272);
    curveVertex(331,263);
    endShape(CLOSE);
    //neck
    beginShape();
    curveVertex(181,251);
    curveVertex(172,288);
    curveVertex(183,309);
    curveVertex(195,323);
    curveVertex(223,353);
    curveVertex(242,358);
    curveVertex(279,342);
    curveVertex(309,317);
    curveVertex(317,290);
    endShape(CLOSE);
    //right collar
    fill(255)
    beginShape();
    curveVertex(329,279);
    curveVertex(282,335);
    curveVertex(260,347);
    curveVertex(243,355);
    curveVertex(261,376);
    curveVertex(273,407);
    curveVertex(281,427);
    curveVertex(313,362);
    curveVertex(323,315);
    endShape(CLOSE);
    //face
    fill(244, 180, 150)
    beginShape();
    curveVertex(232,81);
    curveVertex(213,114);
    curveVertex(198,145);
    curveVertex(185,166);
    curveVertex(177,199);
    curveVertex(175,237);
    curveVertex(181,279);
    curveVertex(193,307);
    curveVertex(211,328);
    curveVertex(238,340);
    curveVertex(273,335);
    curveVertex(299,321);
    curveVertex(322,291);
    curveVertex(341,257);
    curveVertex(360,214);
    curveVertex(361,187);
    curveVertex(362,143);
    curveVertex(357,101);
    curveVertex(335,116);
    curveVertex(289,103);
    curveVertex(255,87);
    endShape(CLOSE);
    //right hair
    fill(241, 237, 234);
    beginShape();
    curveVertex(363,74);
    curveVertex(380,95);
    curveVertex(387,130);
    curveVertex(375,171);
    curveVertex(357,217);
    curveVertex(356,122);
    curveVertex(356,104);
    endShape(CLOSE);
    //left hair
    fill(255);
    beginShape();
    curveVertex(254,36);
    curveVertex(219,54);
    curveVertex(199,84);
    curveVertex(190,112);
    curveVertex(184,136);
    curveVertex(180,183);
    curveVertex(209,132);
    curveVertex(233,87);
    curveVertex(277,100);
    curveVertex(323,114);
    curveVertex(341,116);
    curveVertex(358,100);
    curveVertex(363,79);
    curveVertex(352,60);
    curveVertex(327,40);
    curveVertex(295,30);
    endShape(CLOSE);
    //collar
    beginShape();
    curveVertex(177,255);
    curveVertex(165,273);
    curveVertex(162,307);
    curveVertex(170,357);
    curveVertex(178,406);
    curveVertex(181,418);
    curveVertex(209,376);
    curveVertex(231,354);
    curveVertex(195,320);
    curveVertex(177,289);
    endShape(CLOSE);    
    //tie bottom
    fill(184, 14, 18);
    beginShape();
    curveVertex(223,394);
    curveVertex(209,430);
    curveVertex(196,478);
    curveVertex(261,479);
    curveVertex(257,433);
    curveVertex(239,392);
    endShape(CLOSE);
    //tie knot
    fill(229, 25, 30);
    beginShape();
    curveVertex(225,354);
    curveVertex(201,379);
    curveVertex(221,398);
    curveVertex(246,402);
    curveVertex(264,380);
    curveVertex(256,360);
    endShape(CLOSE);
}

function Kamala() {
    background(0,180,255);
    //draw kamala
    //hair behind face
    fill(43,32,22);
    beginShape();
    curveVertex(378,86);
    curveVertex(418,127);
    curveVertex(447,218);
    curveVertex(452,272);
    curveVertex(429,304);
    curveVertex(429,326);
    curveVertex(419,343);
    curveVertex(395,345);
    curveVertex(398,365);
    curveVertex(433,364);
    curveVertex(429,388);
    curveVertex(399,398);
    curveVertex(424,434);
    curveVertex(386,454);
    curveVertex(396,430);
    curveVertex(371,407);
    curveVertex(345,384);
    curveVertex(341,350);
    endShape(CLOSE);
    beginShape();
    fill(164,122,97);
    curveVertex(199,280);
    curveVertex(164,333);
    curveVertex(224,479);
    curveVertex(343,479);
    curveVertex(363,330);
    endShape(CLOSE);
    //right shoulder
    beginShape();
    fill(49,46,50);
    curveVertex(357,411);
    curveVertex(354,444);
    curveVertex(328,480);
    curveVertex(480,480);
    curveVertex(480,346);
    curveVertex(361,327);
    curveVertex(363,376)
    endShape(CLOSE);
    //left shoulder
    fill(59,58,64);
    beginShape();
    curveVertex(193,308);
    curveVertex(199,393);
    curveVertex(231,480);
    curveVertex(0,480);
    curveVertex(0,367);
    curveVertex(91,339);
    endShape(CLOSE);
    //necklace
    push();
    translate(10,25)
    fill(255);
    circle(345,343,15)
    circle(218,415,15);
    circle(221,429,15);
    circle(226,438,15);
    circle(233,449,15);
    circle(349,368,15);
    circle(349,381,15);
    circle(347,396,15);
    circle(344,407,15);
    circle(340,415,15);
    circle(337,428,15);
    circle(329,440,15);
    circle(321,450,15);
    circle(316,460,15);
    circle(350,355,15);
    pop();
    //face
    noStroke();
    fill(194,150,121)
    beginShape();
    curveVertex(353,71);
    curveVertex(393,113);
    curveVertex(415,177);
    curveVertex(405,204);
    curveVertex(414,244);
    curveVertex(401,281);
    curveVertex(376,331);
    curveVertex(369,359);
    curveVertex(341,366);
    curveVertex(305,350);
    curveVertex(235,298);
    curveVertex(219,179);
    curveVertex(238,59);
    endShape(CLOSE);
    //hair
    fill(59,44,23);
    beginShape();
    curveVertex(313,49);
    curveVertex(285,40);
    curveVertex(215,56);
    curveVertex(155,113);
    curveVertex(118,203);
    curveVertex(106,277);
    curveVertex(107,297);
    curveVertex(124,319);
    curveVertex(95,334);
    curveVertex(147,337);
    curveVertex(163,359);
    curveVertex(191,382);
    curveVertex(169,389);
    curveVertex(145,367);
    curveVertex(157,387);
    curveVertex(196,399);
    curveVertex(194,427);
    curveVertex(153,433);
    curveVertex(126,419);
    curveVertex(156,449);
    curveVertex(193,449);
    curveVertex(233,427);
    curveVertex(248,392);
    curveVertex(267,370);
    curveVertex(254,337);
    curveVertex(233,328);
    curveVertex(247,312);
    curveVertex(251,247);
    curveVertex(254,217);
    curveVertex(297,203);
    curveVertex(336,153);
    curveVertex(365,121);
    curveVertex(387,91);
    curveVertex(366,72);
    curveVertex(339,56);
    endShape(CLOSE);
}
//draw the fly 
function Fly(x,y) {
        push();
        translate(200,100);
        stroke(154, 137, 120);
        strokeWeight(2);
        fill(0);
        circle(x, y, 12);   //draw fly body
        pop();    
    }
function Trump() {
    background(241,59,58);
    //trump
    //left side hair
    fill(245,234,176);
    beginShape();
    curveVertex(108,100);
    curveVertex(85,148);
    curveVertex(89,204);
    curveVertex(97,237);
    curveVertex(92,295);
    curveVertex(107,325);
    curveVertex(133,339);
    curveVertex(138,228);
    curveVertex(140,160);
    curveVertex(159,124);
    curveVertex(151,84);
    endShape(CLOSE);
    //right ear
    fill(245,152,93)
    beginShape();
    curveVertex(381,163);
    curveVertex(398,217);
    curveVertex(395,271);
    curveVertex(383,302);
    curveVertex(368,308);
    curveVertex(365,247);
    endShape(CLOSE);
    //left shoulder
    fill(14,16,47);
    beginShape();
    curveVertex(155,406);
    curveVertex(188,480);
    curveVertex(0,480);
    curveVertex(0,422);
    curveVertex(48,381);
    curveVertex(136,341);
    endShape(CLOSE);
    //right shoulder
    beginShape();
    curveVertex(346,375);
    curveVertex(382,376);
    curveVertex(417,387);
    curveVertex(463,390);
    curveVertex(480,397);
    curveVertex(480,480);
    curveVertex(324,480);
    curveVertex(336,408);
    endShape(CLOSE);
    //left collar
    fill(255);
    beginShape();
    curveVertex(140,366);
    curveVertex(213,427);
    curveVertex(235,437);
    curveVertex(231,479);
    curveVertex(187,479);
    curveVertex(153,405);
    endShape(CLOSE);
    //right collar
    beginShape();
    curveVertex(339,395);
    curveVertex(340,480);
    curveVertex(317,480);
    curveVertex(270,480);
    curveVertex(275,438);
    endShape(CLOSE);
    //tie knot
    fill(68,73,215)
    beginShape();
    curveVertex(285,420);
    curveVertex(241,420);
    curveVertex(227,450);
    curveVertex(233,480);
    curveVertex(277,480);
    curveVertex(309,480);
    curveVertex(303,442);
    endShape(CLOSE);
    //face
    noStroke();
    fill(246,162,102)
    beginShape();
    curveVertex(147,176);
    curveVertex(135,233);
    curveVertex(135,296);
    curveVertex(129,328);
    curveVertex(128,346);
    curveVertex(157,403);
    curveVertex(213,440);
    curveVertex(277,452);
    curveVertex(331,424);
    curveVertex(365,357);
    curveVertex(372,323);
    curveVertex(371,233);
    curveVertex(368,183);
    curveVertex(365,112);
    curveVertex(299,111);
    curveVertex(157,119);
    endShape(CLOSE);
    //right side hair
    fill(245,234,176)
    beginShape();
    curveVertex(355,95);
    curveVertex(336,121);
    curveVertex(346,146);
    curveVertex(350,179);
    curveVertex(371,249);
    curveVertex(391,152);
    curveVertex(395,105);
    curveVertex(374,83);
    endShape(CLOSE);
    //left ear
    fill(245,152,93)
    beginShape();
    curveVertex(140,231);
    curveVertex(103,226);
    curveVertex(91,233);
    curveVertex(94,260);
    curveVertex(105,284);
    curveVertex(119,323);
    curveVertex(137,332);
    curveVertex(147,318);
    curveVertex(141,271);
    endShape(CLOSE);
    //top hair
    fill(248,232,145)
    beginShape();
    curveVertex(293,31);
    curveVertex(213,42);
    curveVertex(147,58);
    curveVertex(93,95);
    curveVertex(113,109);
    curveVertex(145,107);
    curveVertex(165,132);
    curveVertex(207,145);
    curveVertex(265,136);
    curveVertex(319,131);
    curveVertex(359,119);
    curveVertex(385,115);
    curveVertex(396,89);
    curveVertex(351,51);
    endShape(CLOSE);
    //top of right side hair
    fill(245,234,176)
    beginShape();
    curveVertex(153,105);
    curveVertex(173,129);
    curveVertex(151,181);
    curveVertex(135,224);
    curveVertex(115,147);
    curveVertex(131,119);
    endShape(CLOSE);
}
//draw first title slide: '2020 ELECTION HIGHLIGHTS'
function Title() {
    background(255);
    textAlign(CENTER);
    textSize(50);
    textStyle(BOLD);
    fill(241,59,58)
    text('2020', width/2, height/2-70);
    fill(0,86,217);
    text('ELECTION', width/2, height/2);
    fill(241,59,58);
    text('HIGHLIGHTS', width/2, height/2+70);
}
//draw last slide: 'BYE DON'
function End() {
    background(255);
    textAlign(CENTER);
    textSize(50);
    textStyle(BOLD);
    fill(0,86,217);
    text('BYE', width/2, height/2-35);
    fill(241,59,58);
    text('DON', width/2, height/2+35);
}

function draw() {
    background(255);
    //first scene is the title slide, and playing banjo tiktok music
    if (frameCount >= 0 & frameCount < 80) { 
        Title();
        if (!banjo.isPlaying()) {
            banjo.play();
        } 
    }
    //second scene is the fly buzzing around mike pence's head
    if (frameCount >= 80 & frameCount < 130) { 
        banjo.stop();
        Mike();
        Fly(X,Y);
        if (!buzz.isPlaying()) {
            buzz.play();
        }
        buzz.play();
        X+=random(-5,5); 
        Y+=random(-5,5);
        noiseParam+= noiseStep;
    }
    //third scene is kamala harris telling mike pence that she is speaking during the VP debate
    if (frameCount >= 130 & frameCount < 170) { 
        buzz.stop();
        if (!talk.isPlaying()) {
            talk.play();
        }
        Kamala(); 
    }
    //fourth scene is trump while a clip of supalonely plays 
    if (frameCount >= 170 & frameCount < 240) { 
        talk.stop();
        Trump();
        if (!loser.isPlaying()) {
            loser.play();
        } 
    }
    //fifth scene is joe biden with hail to the chief playing
    if (frameCount >= 240 & frameCount < 400) { 
        loser.stop();
        Joe();
        if (!president.isPlaying()) {
            president.play();
        } 
    }
    //last scene is the end slide with the banjo tiktok music playing
    if (frameCount >= 400 & frameCount < 460) { 
        End();
        if (!banjo.isPlaying()) {
            banjo.play();
        } 
    }
    //after the last slide, loop back to the first and continue to cycle through the frames
    if (frameCount == 460) {
        frameCount = 0;
        background(255);
    }
}

Looking Outwards 10: Computer Music

I am interested in Ryoji Ikeda’s live set of his project “test patterns,” which was originally developed in 2008. In this work, Ikeda leverages a real-time computer program written by Tomonaga Tokuyama which converts analog audio signals into digital black and white patterns which resemble a barcode. The music generated by the computer combined with the unique and contrasting visuals showcases the interplay between the analog and the digital as well as the audio and the visual.

Ryoji Ikeda performs Test Patterns as a live set in 2013.

The rapidity and synchronicity of the final work gives the code a performative effect, allowing the viewer to immerse themselves within a generative soundscape. I think, too, the visuals help to highlight the dissonance of the computer-generated music.

Project 09: Computational Portrait

I chose to construct my portrait from nucleotide pixels; nucleotides are the building blocks of DNA and RNA. Each time the mouse is clicked it switches the pixel mode to a different nucleotide: A for Adenine, C for Cytosine, T for Thymine, G for Guanine, and U for Uracil. If the mouse is held down, the pixels drawn will be randomly chosen from all nucleotides.

Self Portrait
let img;
var Nucleotide = 1;
var Nucs = ['A', 'C', 'T', 'G', 'U']

function preload() {
	img = loadImage("https://i.imgur.com/wOvSeLp.jpg?1");
}

function setup() {
  createCanvas(480, 480);
  background(255);
  img.resize(width, height);
  img.loadPixels();
  frameRate(75);
  imageMode(CENTER);
}

function draw() {
  	var x = floor(random(img.width)); // random x position for the letter
  	var y = floor(random(img.height)); // random y position for the letter
  	var pixel = img.get(x, y); // select color from the image and store in pixel
  	stroke(pixel);	//make the stroke color the color of the according image pixel
  	strokeWeight(2);
  	fill(pixel);	//make the text color the color of the according image pixel
  	textSize(10)
	if(Nucleotide == 1) { 
  		text('A', x, y);	//A, for adenine
  	}
 	else if(Nucleotide == 2){ 
  		text('C', x, y);	//C, for cytosine
  	}
  	else if(Nucleotide == 3){ 
  		text('T', x, y);	//T, for thymine
  	}
  	else if(Nucleotide == 4){ 
  		text('G', x, y);	//G, for guanine
  	}
  	else { 
  		text('U', x, y);	//U, for uracil
  	}
  	if (mouseIsPressed) {
  		text(random(Nucs), x, y)	//while the mouse is being held down, randomize pixel letters (any nucleotide can be generated)	
  	}
}

function mousePressed() {
	if(Nucleotide == 1) {
		Nucleotide = 2;	//click once and set pixel letter to C
	}
	else if(Nucleotide == 2) {
		Nucleotide = 3;	//click again and set pixel letter to T
	}
	else if(Nucleotide == 3) {
		Nucleotide = 4;	//click again and set pixel letter to G
	}
	else if(Nucleotide == 4) {
		Nucleotide = 5;	//click again and set pixel letter to U
	}
	else {
		Nucleotide = 1;	//click again and reset pixel letter to A
	}
}

Looking Outwards 09: on Looking Outwards

I chose to look at yoli’s Week 03 post about computational fabrication used in Iris Van Herpen’s fashion pieces. I love yoli’s commentary about the fashion industry, pointing out how fashion is always pushing the “cutting edge” while also repeating itself in many ways. I find this repetition as a mechanism for forward-thinking to be really profound and perfectly exemplified by Van Herpen’s work. While Van Herpen is pushing the field forward in her forms and novel fabrication methods, she also references traditional fashion with the soft sculpture elements and dress bases of her looks.

Iris Van Herpen’s Sensory Seas collection shown at Cirque d’hiver Bouglione on January 20, 2020.

I find that not only are fashion professionals repeating themselves in their methods and designs, but repetition, as in Van Herpen’s work, has become a central principle to the designs themselves. For instance, in her “Sensory Seas” collection, she references human anatomy systems through repetition of physiological shapes.

Look 4 from Iris Van Herpen’s couture collection, Sensory Seas (2020)

Looking Outwards 08: The Creative Practice of an Individual

Brian House, https://brianhouse.net/

Brian House is a new media and interdisciplinary artist whose work focuses on computational and artistic representations of time and location. He has studied computer science and computer music at Columbia University, Brown University, and Chalmers University of Technology. House is originally from Colorado, but is based in Portland, Oregon as a teaching professor at Lewis and Clark College. One project of interest and representative of House’s body of work, which he emphasized during his talk at the 2018 Eyeo Festival, is Animas.

Animas by Brian House (2017)

To address the issue of water contamination in the Animas River, he created panels of the metals exceeded EPA tolerances in the river. They vibrated at unique frequencies which updated based on real-time data. The changing makeup of the river generated a unique sound composition. I appreciate that his body of work takes political issues and uses sound, new, and time-based media to make thought-provoking work. I thought he was a very engaging speaker in that he outlined some of his more representative works within his speech and contextualized each of them within society and human relationships, making them more relatable and engaging.

Brian House presenting at the Eyeo Festival in 2018.

Looking Outwards 07: Information Visualization

Facebook Stories: Virality by Rachel Binx
https://rachelbinx.com/Facebook-Stories-Virality
jwesthei, Section B

This project is a play on the concept of going “viral” and how this can be visualized. Aesthetically very similar to the “Self-Dividing Line” project I reviewed last week, this one visualizes how one a piece of media (in this case three of the most shared images on Facebook) ends up being shared hundreds of thousands of times on a social media platform.

A screenshot of one of the videos from Rachel Binx’s “Facebook Stories: Virality” project (2013).

The pieces start as a single person and split off into branches as the media is shared. As the piece becomes shared and re-shared, the project visualizes the gender of the person sharing it as well as the relative age of the share as time progresses. The artist worked with Zach Watson to create the algorithm using the WebGL framework and animate this. I could not find a lot of information about the specifics of the algorithm used, but I would imagine it is similar to that of the “Self-Dividing Line,” where instead of randomly generated midpoints to split from, the time and number of branches come from actual data defining a shared media.

Project 07: Composition with Curves

I used a series of three hypocycloid curves (based on the hypocycloid pedal formula) to model an interactive color wheel. I wanted to juxtapose the complex curves and forms with the simplicity of primary colors.

colorwheel
var nPoints = 100	//number of points in each curve

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

function draw() {
	var halfWide = width/2
	var halfTall = height/2
	background('white')
	push();
	translate(halfWide+10, halfTall)	//move center of curves to center of canvas, offset by 10 tp create overlap later
	HypocycloidBlueCurve()	//draw blue curve
	pop();
	translate(halfWide-10, halfTall);	//move center of curves to center of canvas but offset the other way so overlaps with blue
	HypocycloidCurve()	//draw red curve
	translate(5, 0)	//move back to true canvas center to draw yellow curve over both red and blue
	HypocycloidYellowCurve()	//draw yellow curve
}

function HypocycloidCurve(){
    var a1 = constrain(mouseY, 0, 300, 150, 180); //size changes as vertical mouse position changes
    var b1 = 45;
    var n1 = int(mouseY / 6)	//number of cusps of the curve varies with vertical mouse position

    stroke('red');	//change stroke color to red
    strokeWeight(1);
    fill(255, 0, 0, 20);	//change fill to transparent red

    //create curve, using https://mathworld.wolfram.com/HypocycloidPedalCurve.html base formula for Hypocycloid Pedal Curve
    //map points of curve to circle
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);     
        var x1 = a1*(((n1-2)*(cos(theta)-cos((1-n1)*theta)))/(2*n1))
        var y1 = a1*(((n1-2)*(cos(theta*(1-0.5*n1))*sin(0.5*n1*theta)))/(2*n1))
        curveVertex(x1, y1);
    }
    endShape(CLOSE); 
}

//draw blue hypocycloid, same as red but in blue
function HypocycloidBlueCurve(){
    var a1 = constrain(mouseY, 0, 300, 150, 180); //size changes as vertical mouse position changes
    var b1 = 45;
    var n1 = int(mouseY / 6)	//number of cusps of the curve varies with vertical mouse position
    fill(0, 0, 255, 20)	//fill transparent blye
    stroke('blue');	//set stroke color to blue
    strokeWeight(1);
    //create curve, using https://mathworld.wolfram.com/HypocycloidPedalCurve.html base formula for Hypocycloid Pedal Curve
    //map points of curve to circle
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);     
        var x1 = a1*(((n1-2)*(cos(theta)-cos((1-n1)*theta)))/(2*n1))
        var y1 = a1*(((n1-2)*(cos(theta*(1-0.5*n1))*sin(0.5*n1*theta)))/(2*n1))
        curveVertex(x1, y1);
    }
    endShape(CLOSE); 
}
//draw yellow hypocycloid
function HypocycloidYellowCurve(){
    var a1 = constrain(mouseY, 0, 300, 150, 180); //size changes as vertical mouse position changes
    var b1 = 45;
    var n1 = int(mouseY / 10)	//number of cusps of the curve varies with vertical mouse position
    fill(255, 255, 0, 50)	//set fill color to a transparent yellow
    stroke('yellow');	//set stroke color to yellow
    strokeWeight(1);
	//create curve, using https://mathworld.wolfram.com/HypocycloidPedalCurve.html base formula for Hypocycloid Pedal Curve
    //map points of curve to circle
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);     
        var x1 = a1*(((n1-2)*(cos(theta)-cos((1-n1)*theta)))/(2*n1))
        var y1 = a1*(((n1-2)*(cos(theta*(1-0.5*n1))*sin(0.5*n1*theta)))/(2*n1))
        curveVertex(x1, y1);
    }
    endShape(CLOSE); 
}