Final Project-Protect Sam from Coronavirus!

This project was inspired by the biggest theme of the year 2020—COVID-19. It is an invisible enemy that humanities struggled to fight against. The U.S. is surely losing the war on COVID-19, but it did not have to be this way. If people are more aware of how they could be infected by the virus, and understand how to protect themselves, then the pandemic would be more under control. I wanted this program to be educational and relatable to the player.

In my program, the players need to actively engage in using three different tools to protect the character from the coronavirus for 80 seconds. By applying the mask to Sam’s face, you could protect him from viruses that are spreading through the air. By sanitizing the table with disinfectant spray, you could prevent viruses from getting attached to Sam’s hand. However, there might be a few viruses that survived or escaped from the spray, so you need to apply hand sanitizer constantly just in case Sam starts rubbing his eyes.

If I had more time, I probably will explore how to parent the virus to the hand once it is attached. I would also like to make the background and surrounding more like a public space where other characters are also involved in this interaction.

sketch
//jiaqiwa2; Jiaqi Wang; Section C
//final project fall 2020 15-104
var num=0;
var VirusA;
var VirusS;
//the mask variables
var MaskPic;
var mx=445;
var my=60;
var mdragging=false;
var offsetMX;
var offsetMY;
var fhighlight=false;
var maskON=false;

//variables for virus
var airVirus=[];
var surfVirus=[];


//the spray variable
var Spray;
var sx=460;
var sy=125;
var sdragging=false;
var offsetSX;
var offsetSY;
var shighlight=false;
var SprayON=false;
var Sapplied=false;

//variables for animation
var Writing=[];
var Drinking=[];
var Rubbing=[];
var rubbing=false;
var count=0;
var stopwatch=0;
var EndGame=false;
var z;
var win=false;

var mug;
//the hand sanitizer variables
var handSanitizer;
var hx=480;
var hy=230;
var hdragging=false;
var offsetHX;
var offsetHY;
var Hhighlight=false;
var HON=false;
var Happlied=false;


function preload(){
 VirusA=loadImage("https://i.imgur.com/teJshOW.png");
 VirusS=loadImage("https://i.imgur.com/Vs0Z6HV.png");
 Mask=loadImage("https://i.imgur.com/3KxEFPC.png");
 Spray=loadImage("https://i.imgur.com/u0X1SgO.png");


 //writing
 var filenames = [];
    filenames[0] = "https://i.imgur.com/YJbLiPT.png";
    filenames[1] = "https://i.imgur.com/HCMWQFZ.png";
    filenames[2] = "https://i.imgur.com/rx4PTch.png";
    filenames[3] = "https://i.imgur.com/lI2EDs4.png";
    filenames[4] = "https://i.imgur.com/K4I9fup.png";
    filenames[5] = "https://i.imgur.com/EUNV9c7.png";
    filenames[6] = "https://i.imgur.com/HCMWQFZ.png";
    filenames[7] = "https://i.imgur.com/YJbLiPT.png";
    filenames[8] = "https://i.imgur.com/HCMWQFZ.png";
	filenames[9] = "https://i.imgur.com/YJbLiPT.png";
	filenames[10] = "https://i.imgur.com/HCMWQFZ.png";
    filenames[11] = "https://i.imgur.com/YJbLiPT.png";
    filenames[12] = "https://i.imgur.com/HCMWQFZ.png";
	filenames[13] = "https://i.imgur.com/YJbLiPT.png";

	for (var i = 0; i<filenames.length; i++) {
        Writing[i] = loadImage(filenames[i]);
    }
//drinking
var filenames2 = [];
    filenames2[0] = "https://i.imgur.com/YI78DMb.png";
    filenames2[1] = "https://i.imgur.com/pFFMlNc.png";
    filenames2[2] = "https://i.imgur.com/M6VWA4T.png";
    filenames2[3] = "https://i.imgur.com/YIN1o3J.png";
    filenames2[4] = "https://i.imgur.com/Eu7gh1b.png";
    filenames2[5] = "https://i.imgur.com/UlWmeif.png";
    filenames2[6] = "https://i.imgur.com/WFkzYAg.png";
    filenames2[7] = "https://i.imgur.com/xjnNAFU.png";
    filenames2[8] = "https://i.imgur.com/ISv7MwT.png";
	filenames2[9] = "https://i.imgur.com/X6FYgwF.png";
	filenames2[10] = "https://i.imgur.com/ISv7MwT.png";
	filenames2[11] = "https://i.imgur.com/xjnNAFU.png";
	filenames2[12] = "https://i.imgur.com/WFkzYAg.png";
	filenames2[13] = "https://i.imgur.com/UlWmeif.png";
	filenames2[14] = "https://i.imgur.com/Eu7gh1b.png";
	filenames2[15] = "https://i.imgur.com/YIN1o3J.png";
	filenames2[16] = "https://i.imgur.com/M6VWA4T.png";
	filenames2[17] = "https://i.imgur.com/pFFMlNc.png";
	 
    for (var i = 0; i<filenames2.length; i++) {
        Drinking[i] = loadImage(filenames2[i]);
    }
    // mug
    mug=loadImage("https://i.imgur.com/rlJA4yY.png");
    //hand sanitizer
    handSanitizer=loadImage("https://i.imgur.com/d5h6GeR.png");
//rubbing
var filenames3 = [];
    filenames3[0] = "https://i.imgur.com/B1Kr1t2.png";
    filenames3[1] = "https://i.imgur.com/8T6UUR4.png";
    filenames3[2] = "https://i.imgur.com/untVivz.png";
    filenames3[3] = "https://i.imgur.com/DaIu3C6.png";
    filenames3[4] = "https://i.imgur.com/Wvif1mI.png";
    filenames3[5] = "https://i.imgur.com/66gOJPD.png";
    filenames3[6] = "https://i.imgur.com/XhPbm01.png";
    filenames3[7] = "https://i.imgur.com/bDfotS2.png";
    filenames3[8] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[9] = "https://i.imgur.com/N3plYyV.png";
	filenames3[10] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[11] = "https://i.imgur.com/N3plYyV.png";
	filenames3[12] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[13] = "https://i.imgur.com/N3plYyV.png";
	filenames3[14] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[15] = "https://i.imgur.com/bDfotS2.png";
	filenames3[16] = "https://i.imgur.com/XhPbm01.png";
	filenames3[17] = "https://i.imgur.com/66gOJPD.png";
	filenames3[18] = "https://i.imgur.com/Wvif1mI.png";
	filenames3[19] = "https://i.imgur.com/DaIu3C6.png";
	filenames3[20] = "https://i.imgur.com/untVivz.png";
	filenames3[21] = "https://i.imgur.com/8T6UUR4.png";
 
    for (var i = 0; i<filenames3.length; i++) {
        Rubbing[i] = loadImage(filenames3[i]);
    }
}
function setup() {
    createCanvas(560,400);
    for(var i=0;i<3;i++){
    	var brith=random(1,3);
    	airVirus[i]=makeAirVirus(-20*brith,-20*brith,(360+20*brith)/(150*random(2,4)),(120+20*brith)/(150*random(2,4)));
        surfVirus[i]=makeSurfVirus(-20,random(270,380),random(1,3),0);

    }  
    frameRate(10);   
}
function draw() {
	background(220);
	noStroke();
	if(!EndGame){
	    //drinking
	    //drinking will cause mask removal	    
        if((count>=102&count<=119)||(count>=510&&count<=527)||(count>=918&&count<=935)){
        	print("drink");
        	var j=count%17;
        	image(Drinking[j],0,0,560,400);
        	mx=445;
        	my=60;
        	maskON=false;  
        }
        //rubbing
		else if((count>=189&count<=201)||(count>=567&&count<=588)||(count>=987&&count<=1008)){
			 z=count%21;
			 if(z<10) rubbing=true;
			//print("rub",z);
			image(Rubbing[z],0,0,560,400);
			image(mug,88,263,70,65);

		}
		//writing
        else{
        	rubbing=false;
        	var i=count%13;
        	image(Writing[i],0,0,560,400);
        	image(mug,88,263,70,65);

        }
    }

    // the user interface & text
    fill(235,100);
	rect(440,40,100,300);
	strokeWeight(2);
	fill(255,190);
	textSize(12);
	text("PROTECT SAM FROM CORONAVIRUS WITH TOOLS", 10,20);
	push();
	textSize(30);
	var time=floor(80-(map(count,0,1200,0,80,true)));
	text(time,80,50);
	pop();
	text("FOR", 50,40);
	text("SECONDS",120,40);
	text("TOOLS",470,30);
	text("MASK",470,110);
	text("DISINFECTANT",445,200);
	text("SPRAY",470, 215);
	text("HAND",470, 295);
	text("SANITIZER",460, 310);
	
	//display the mask
	image(Mask,mx,my,80,40);
    //display the spray
	image(Spray,sx,sy,50,60);
	//display the hand sanitizer
	image(handSanitizer, hx,hy,17,50);

	//update and show the virus   	
	removeVirusThatHaveSlippedOutOfView();
	addNewVirusWithSomeRandomProbability();

	for(var i=0;i<airVirus.length;i++){
		airVirus[i].range();
	    airVirus[i].move();
	    airVirus[i].show();
	}

	for(var j=0; j<surfVirus.length;j++){
		if(count>=102){
			//print(j);
			surfVirus[j].range();
			surfVirus[j].range2();
			surfVirus[j].move();
			surfVirus[j].show();
			

		}
	}
//show the tools behaviors
	mask();
	spray();
	HSanitizer();


	count++;
	endGame();
	
}

function removeVirusThatHaveSlippedOutOfView(){
    var AVirusToKeep = [];
    var SVirusToKeep = [];
    for (var i = 0; i < airVirus.length; i++){
        if (airVirus[i].x>-60 & airVirus[i].x-60 && airVirus[i].y0 && surfVirus[i].y=250)&&(my<=400)){
			Project_highlight();

		}
		
	}

}

function HSanitizer(){
	//move the hand sanitizer if it is selected
	if(hdragging){
		hx=mouseX+offsetHX;
		hy=mouseY+offsetHY;
	}
	if(Happlied){
		hx=480;
		hy=230;
		protection();
		stopwatch+=1;
		if(stopwatch==10){
			Happlied=false;
			stopwatch=0;
		}
		

	}
    // highlight the effective area of hand sanitizer
    if(Hhighlight){
		highlight(250,260,80,50);
    }

}

function protection(){
	//visual effect for protection
	for(var i=0;i<5; i++){
	push();
	translate(250+random(i*20),280+random(i*20));
	rectMode(CENTER);
	fill(114,204,82,100);
	rect(0,0,20,9);
	rect(0,0,9,20);
	pop();

	}
	
}

//Virus that moves on the surface
function makeSurfVirus(sx,sy,sdx,sdy){
	var sv={x: sx, y: sy, dx: sdx, dy:sdy, attach:false, VirusTransp: false,
			show: SVirusDraw, move:SVirusMove, range: CheckInProjection, range2:SCheckInBound};
		return sv;
}

function SVirusDraw(){
	image(VirusS,this.x,this.y,30,30);
	if(this.attach &!Sapplied){
		textSize(20);
		fill(255,10,10);
		text("!",this.x,this.y);
		
	}
}
function SVirusMove(){
	this.y+=this.dy;
	this.x+=this.dx;
	if(win){
		this.dy=30;
		this.dx=-30;
	}
}

function CheckInProjection(){
	//check if surface Virus get to the spray area
	if(InATriangle(this.x,this.y)){
		//check if spray is applied
		if(Sapplied){
			//reject virus if spray is applied
			print("reject Surface Virus");
			this.dy=5;
		}
		
	}

}
function SCheckInBound(){
	//check if surface virus is being transported
	if(this.VirusTransp){
		this.dx=0;
		this.dy=-20;
		//check if hand reaches the face
		if(z==9){
			EndGame=true;
		}
	}
	//check if surface Virus get to the hand area
	if((this.x>=250)&(this.x<=250+90)&&(this.y>=270)&&(this.y<=270+30)){
		//check if Hand sanitizer is applied
		if(Happlied){
			//reject virus if hand sanitizer is applied
			print("reject Surface Virus");
			this.dx=0;
			this.dy=5;
		}
		else if(! rubbing){
			//if not applied, attach virus to hand, virus stops moving if not rubbing
			print("Attached");
			this.dx=0;
			this.attach=true;
		}
		else if(rubbing& Happlied==false){
			this.VirusTransp=true;
			
		}
	}
}


//Virus that spreads through air
function makeAirVirus(ax,ay,adx,ady){
	var av={x: ax, y: ay, dx: adx, dy: ady, reject: false, 
		range: CheckInBound, show: AVirusDraw, move:AVirusMove};
	return av;
}

function AVirusDraw(){
	image(VirusA,this.x,this.y,30,30);
}

function AVirusMove(){
	if(this.reject){
		//virus go off canvas if you win
		if(win){
			this.dy=50;
			this.dx=50;
		}		
		this.x-=this.dx;
		this.y-=this.dy;		
	}
	else{
		//virus go off canvas if you win
        if(win){
			this.dy=-50;
			this.dx=-50;
		}
		this.x+=this.dx;
		this.y+=this.dy;	
	}
	    
}

function CheckInBound(){
	//check if air Virus get to the face area
	if((this.x>=240)&(this.x<=320)&&(this.y>=70)&&(this.y<=160)){
		//check if mask is on
		if(maskON){
			//reject virus if mask is on
			this.reject=true;
			print("reject Air Virus");
		}
		else{
			//end game if failed to protect face with mask
			EndGame=true;
			

		}
	}
}

function mousePressed(){
	//select mask
	if((mouseX>=445)&(mouseX<=445+80)&&(mouseY>=60)&&(mouseY<=60+40)){
		mdragging=true;
		fhighlight=true;
		offsetMX=mx-mouseX;
		offsetMY=my-mouseY;
	}
	//select spray
	else if((mouseX>=sx)&(mouseX<=sx+50)&&(mouseY>=sy)&&(mouseY<=sy+60)){
		sdragging=true;
		shighlight=true;
		offsetSX=sx-mouseX;
		offsetSY=sy-mouseY;
		
	}
	//select hand sanitizer
	else if((mouseX>=hx)&(mouseX<=hx+17)&&(mouseY>=hy)&&(mouseY<=hy+50)){
		hdragging=true;
		Hhighlight=true;
		offsetHX=hx-mouseX;
		offsetHY=hy-mouseY;
	}


}

function mouseReleased(){
    //when the mouse is released, mask dragging stops
    if((mx>=250)&(mx<=370)&&(my>=90)&&(my<=145)){
    	mdragging = false;
    	mx=260;
    	my=125;
    	maskON=true;
    	fhighlight=false;
    }
    //when the mouse is released, spray dragging stops
    if((sx>=10)&(sx<=320)&&(sy>=250)&&(my<=400)){
    	sdragging = false;
		Sapplied=true;
		sdragging = false;
    	SprayON=true;
    	shighlight=false;

    }
       //when the mouse is released, hand sanitizer dragging stops
    if((hx>=250)&(hx<=250+90)&&(hy>=270)&&(hy<=270+80)){
    	hdragging = false;
		Happlied=true;
		hdragging = false;
    	HON=true;
    	Hhighlight=false;

    }


    
}

function endGame(){
	//lose game
	if(EndGame){
		fill(120,54,55,100);
		rect(0,0,width,height);
		fill(0);
		textSize(20);
		noStroke();
		text("YOU FAILED TO PROTECT SAM:(", width/4,height/2);	
		airVirus.dx=0;
		airVirus.dy=0;
		surfVirus.dx=0;
		
		noLoop();
	}
	//win game
	if(!EndGame& count>=1200){
		win=true;
		fill(120,191,58,100);
		noStroke();
		rect(0,0,width,height);
		push();
		fill(255);
		textSize(20);
		text("YOU PROTECTED SAM :)", width/3,height/2);
		pop();
		airVirus.dx=-100;
		airVirus.dy=-100;
		surfVirus.dx=-100;
		stopwatch+=1;
		if(stopwatch==10){
			fhightlight=false;
			Hhighlight=false;
			shighlight=false;
			noLoop();
			stopwatch=0;
		}
		
	}
	
}
//highlight area for application
function highlight(x,y,w,h){
	noFill();
	stroke(98,232,228,150);
	strokeWeight(3);
	rect(x,y,w,h);

}

function Project_highlight(){
	noFill();
	stroke(98,232,228,150);
	strokeWeight(5);
	triangle(sx,sy+5,sx-90,sy-50, sx-90, sy+60);

}



function InATriangle(px,py){
var x1 = sx;      // three points of the triangle
var y1 = sy+5;
var x2 = sx-90;
var y2 = sy-50;
var x3 = sx-90;
var y3 = sy+60;

  // get the area of the triangle
  var areaOrig = abs( (x2-x1)*(y3-y1) - (x3-x1)*(y2-y1) );

  // get the area of 3 triangles made between the point
  // and the corners of the triangle
  var area1 =    abs( (x1-px)*(y2-py) - (x2-px)*(y1-py) );
  var area2 =    abs( (x2-px)*(y3-py) - (x3-px)*(y2-py) );
  var area3 =    abs( (x3-px)*(y1-py) - (x1-px)*(y3-py) );

  // if the sum of the three areas equals the original,
  // we're inside the triangle!
  if (area1 + area2 + area3 == areaOrig) {
    return true;
  }
  else{
  	return false;
  }

}

Leave a Reply