Final Project: Santa and Rudolph Take on COVID-19

For my project, I wanted to do a Christmas themed game that still demonstrated the severity of COVID-19. For example, the starting screen gives context to the situation, in which all of Santa’s reindeer, except Rudolph, are sick with COVID-19. Therefore, Rudolph is calling on the user to help guide him and Santa through the sky to collect presents and avoid COVID-19.

How the user plays the game: The user plays by clicking on the “START” button on the start screen. This will then take the user to the game, where they will move their mouse up and down to avoid the floating COVID particles, and come in contact with the floating presents in the sky. The user will die and be sent to the “Game Over” screen if they come into contact with the COVID-19 particles floating in the sky. The user will be sent to the “Winner” screen if they can successfully collect 15 presents without touching COVID-19.

I specifically made my code to respond to clicks on a starting button and collisions with presents and COVID-19 particles. For the mouse interaction, I mapped the Y location of the mouse to a smaller range of Y values because I wanted the mouse to not be able to go off of the bottom edge of the canvas too easily, especially because the mountains conceal some of the view. By mapping it, I found that the mouse interaction would have to be in a very far Y location (past 480, the height of the canvas) in order to go off of the screen, and I thought this was better for user control, as the mouse can be very sensitive.

If I had more time, I would have liked to included some audio that made a subtle ‘clink’ noise when collecting presents, and more Christmas-like audios, because what is December without Christmas songs? I would have also like to have more control of how quickly and how frequently the COVID-19 particles and presents were generated. Sometimes they tend to overlap slightly, or the objects tend to be placed so close together that it is hard to collect a present without touching COVID-19 due to lack of space. Overall, I am pleased with this project. 🙂

sketch
//Annie Kim
//anniekim@andrew.cmu.edu
//Section B
//Final Project

/* 
WHAT FULFILLED EACH REQUIREMENT FROM MY PROJECT:
ARRAYS : arrays used for the snowy mountains, snow, presents, and covid
USER-DEFINED OBJECT : presents, covid, snow, and snowflakes (on end screen)
CONDITIONAL PROGRAMMING : if/else for snowflakes on winner screen, if for start button, etc
LOOPS : used for snow, mountains, presents, covid, etc
USER-DEFINED FUNCTION : the snowflake function called in winner screen
TRANSFORMATIONS : rotating covid particle on start screen
*/


/* ~~GLOBAL VARIABLES~~*/ 
//making the snow landscape:
var hillvalue = []; //array for values
var noiseParam = 0;
var noiseStep = 0.009; //rounding the hill values
//start screen alternating to game:
var mode = 0; 
//images variable stated:
var tree; //holds tree png image
var rudolph; //holds rudolph png image
var santa; //holds santa png image
var covid; //holds covid png image
//snow falling (object):
var snow = []; 
var numSnow = 1000;
//rotation
var angle = 0;
//covid particles
var covidGerm = [];
var newCovidLikelihood = 0.015;
//gift "particles"
var gifts = [];
var newGiftLikelihood = 0.02;
//to slow Santa and sled from going off of the screen
var mouseYmapped;
//present counter
var collected = 0;


function preload() { //preloading images that I drew
	tree = loadImage("https://i.imgur.com/gr2EEki.png");
	rudolph = loadImage("https://i.imgur.com/9zvf4hQ.png");
	santa = loadImage("https://i.imgur.com/1oJP4Sx.png");
	covid = loadImage("https://i.imgur.com/RW2zPYi.png");
	present = loadImage("https://i.imgur.com/dZPuHKd.png");
	snowflake = loadImage("https://i.imgur.com/MJawG90.png");
	ripSanta = loadImage("https://i.imgur.com/0c4yP1h.png");
}

function setup() {
    createCanvas(600, 480);
    background(24, 41, 81);
    //setup for the snowy mountains
    for (var i = 0; i <= width/5; i ++) {
    	var n = noise(noiseParam); //value from 0 to 1
    	var value = map(n, 0, 1, height/2, height); 
    	hillvalue.push(value);
    	noiseParam += noiseStep;
    }
    //setup for the snow falling
    for (var j = 0; j < numSnow; j++) {
    	var s = makeSnow(random(0, 600), random(-100, 480), random(-3, 3), 0);
    	snow.push(p);
    }
    frameRate(10);
} 


function draw() {
	//different screen modes
	if (mode == 0) {
		startScreen();
	}
	if (mode != 0) {
		gameStart();
		hills();
	}
} 


function startScreen() { //start screen of the game
	textAlign(CENTER, CENTER);
	textSize(20);
	textFont("GeorgiaBOLD");
	background(24, 41, 81);
	fill(255);
	//instructions and context
	text("The other reindeer are all sick with COVID-19.", width/2, 40);
	text("Press the START button to help Santa and Rudolph on Christmas night!", width/2, 80);
	fill(255);
	text("Move your mouse up and down to guide Santa, and his sled", width/2, 120);
	text("away from COVID-19, and collect the presents!", width/2, 160);
	text("COLLECT 15 PRESENTS TO WIN!", width/2, 200);
	//start button shape
	fill(157, 214, 232);
	noStroke(); 
	rect(210, 400, 180, 65);
	fill(255);
	rect(220, 410, 160, 45);
	fill(0);
	textSize(35);
	text("START", width/2, 435);
	image(tree, -6, 202, 230, 300);
	image(rudolph, 370, 198, 230, 320);
	//rotating covid particle image
	push();
	translate(300, 310);
	rotate(radians(angle));
	image(covid, -85, -85, 170, 170);
	angle -= 5;
	push();
} 


function gameStart() {
    mouseYmapped = map(mouseY, 0, 480, -100, 200);
	fill(24, 41, 81);
	rect(0, 0, 600, 480);
	hills();
	//BOX THAT IS THE "COLLECTED" AREA BEHIND SANTA AND SLED:
	noStroke();
	fill(24, 41, 81); 
	rect(25, mouseYmapped + 15, 230, 110);
	//cue falling snow
	snowingSnowflakes();
	//counter sign
	fill("white");
	strokeWeight(1);
	textSize(30);
	textFont("Times New Roman");
	text("Collected : " + collected, 300, 25);
	image(santa, 0, mouseYmapped, 270, 150);
	//adding "floating" covid particles and presents
	addNewGiftsWithSomeRandomProbability();
	updateAndDisplayGifts();
	updateAndDisplayCovid();
	addNewCovidWithSomeRandomProbability();
} 


function gameOver() {
	fill(0);
	rect(0, 0, 600, 480);
	fill("red");
	stroke("red");
	textSize(60);
	textFont("Times New Roman");
	//game over sign
	text("GAME OVER!", width/2, height/2);
	textSize(30);
	textAlign(LEFT);
	//reminder to refresh to play again
	text("Refresh to play again!", 5, 30);
	//santa's grave image
	image(ripSanta, 200, 12, 270, 200);
}


function gameWin() {
	fill(24, 41, 81);
	rect(0, 0, 600, 480);
	fill("green");
	stroke("green");
	textSize(60);
	textFont("Times New Roman");
	//game winner sign
	text("WINNER!", width/2, height/2 - 100);
	//reminder to refresh to play again
	text("Refresh to play again!", width/2, height/2 - 30);
	//use of snowflakes for decoration
	snowflakes(100, 90);
	snowflakes(300, 60);
	snowflakes(500, 90);

}


function mousePressed() {
	//helps move user from start to game stage
	if (mouseX > 210 & mouseX < 390) {
		if (mouseY > 395 && mouseY < 470) {
			mode = (mode + 1);
		}
	} 
} 


function hills() {
	if (hillvalue.length > 80) { //making hills moves
		hillvalue.shift();
		frameRate(8);
		for (var i = 0; i < width / 5; i ++) {
			var n = noise(noiseParam);
			var value = map(n, 0, 1, height/2, height);
			hillvalue.push(value);
			noiseParam += noiseStep;
		}
	}
	fill(248);
	noStroke();
	beginShape(); //making the hills randomly
	for (var i = 0; i < width/5; i ++) {
		vertex(i*5, hillvalue[i]);
	}
	vertex(width + 150, height);
	vertex(0, height);
	endShape();
} 


function makeSnow(px, py, pdx, pdy) {//snow object
	p = {x: px, y: py,
		dx: pdx, dy: pdy,
		age: 0,
		size : random(1, 4),
		color: color(255),
		stepFunction: snowStep,
		drawFunction: snowDraw
	}
	return p;
} 

//specifying the object
function snowDraw() {
	stroke(this.color);
	strokeWeight(this.size);
	point(this.x, this.y);
} 

//making the snowflakes "bounce" subtly off of the edges 
//of the canvas so they dont disappear off of the screen
function snowStep() {
	this.age++;
	this.x += this.dx;
	this.y += this.dy;
	if (this.x > width) {
		this.dx = -this.dx;
	} else if (this.x < 0) {
		this.dx = - this.dx;
	}
} 

//snowflakes in the background of game screen
function snowingSnowflakes() {
	for (var i = 0; i < numSnow; i ++) {
		var s = snow[i];
		s.stepFunction();
		s.drawFunction();
	}
}

//adding to covid array 
function updateAndDisplayCovid() {
	for (var i = 0; i < covidGerm.length; i++) {
		covidGerm[i].move();
		covidGerm[i].display();
		//deleting covid from array once touched
		//and triggering game over screen when touched
		if (covidGerm[i].x < 255 & covidGerm[i].x > 25) {
			if (covidGerm[i].y < mouseYmapped + 110 && covidGerm[i].y > mouseYmapped + 15) {
				covidGerm.splice(i, 5);
				gameOver();
				noLoop();
			} 
		}
		//if user wins, delete covid from array to make it not show
		if (collected == 15) {
			covidGerm.splice(i, 10);
			noLoop();
		}
	}
}

//randomly making covid particles with a probability
function addNewCovidWithSomeRandomProbability() {
	if (random(0,1) < newCovidLikelihood) {
		covidGerm.push(makeCovid(random(600, 650), random(0, 270)));
	}
} 


function moveCovid() { //speed of covid movement
	this.x += this.speed;
} 


function drawCovid() { //covid scaled size and x/y location
	image(covid, this.x, this.y, 45, 45);
} 


function makeCovid(locationX, locationY) {//covid object
	var covidGerm = {x: locationX,
	y: locationY,
	speed: random(-5, -8),
	move: moveCovid,
	display: drawCovid
	}
	return covidGerm;
} 

//updating and adding to array of presents
function updateAndDisplayGifts() {
	for (var i = 0; i < gifts.length; i ++) {
		gifts[i].move();
		gifts[i].display();
		//deleting present from array once touched
		if (gifts[i].x < 255 & gifts[i].x > 25) {
			if (gifts[i].y < mouseYmapped + 110 && gifts[i].y > mouseYmapped + 15) {
				gifts.splice(i, 1);
				collected += 1;
				//if user wins, game win screen shows
				if (collected == 15) { 
					gameWin();
					noLoop();
					gifts.splice(i, 10);
				}
			}
		}
	}
}

//adding presents randomly
function addNewGiftsWithSomeRandomProbability() {
	if (random(0,1) < newGiftLikelihood) {
		gifts.push(makeGifts(random(600, 650), random(0, 270)));
	}
}


function moveGifts() { //presents moving speed
	this.x += this.speed;
}


function drawGifts() { //drawing presents at this scale and x/y location
	image(present, this.x, this.y, 55, 55);
}


function makeGifts(locationX, locationY) { //present object
	var gifts = {x: locationX,
		y: locationY,
		speed: random(-10, -7),
		move: moveGifts,
		display: drawGifts
	}
	return gifts;
}


function snowflakes(x, y) { //my user-defined function
	var w;
	var h;
	//if snowflake is on the lefthand third of canvas, make it 
	//size 130
	if (x < 200) {
		w = 130;
		h = 130;
		//if snowflake is in middle of canvas, make it size 100
	} else if (x > 200 & x < 400) {
		w = 100;
		h = 100;
		//if snowflake is on righthand third of canvas, make it
		//size 130
	} else {
		w = 130;
		h = 130;
	}
	imageMode(CENTER);
	image(snowflake, x, y, w, h);
}


















Leave a Reply