Our project is inspired by the game Flappy Bird. In our rendition, 2020 events are the obstacles on the pipes and the goal is to “survive” 2020. The character moves up when you hit the letter ‘m’, the game ends if you hit one of the pipes, hit the ground or if you win by passing 12 pairs of pipes. If you lose by hitting a pipe or win you can play the game again, but if you hit the ground you lose and cannot restart the game. The two sounds you hear are the bounce when you move the character and the clash when the character hits one of the pipes. Based on which pipe you hit, you see a different “game over” message. We chose a darker color scheme and used a fire in the background to match the mood of 2020. If we had more time with this project, we would add a webcam function so that the character would be the user’s face instead of just a smiley face. Overall, this project was definitely challenging but also really fun to create.
final project
var score = 0;
var count = 0;
var faceX = 50;
var faceY = 200;
var hitPipe = false;
var endGame = false;
var gameOn = true;
var gameStart = true;
var characterOn = true;
var pipes = [];
var fire = [];
var pipeImages = [];var factImages = [];var gameOverImages = [];
var timeline1 = ["1/1/20", "1/16/20", "1/19/20", "2/2/20", "3/11/20",
"3/19/20", "3/20/20", "4/1/20", "5/1/20", "5/26/20", "11/6/20", "11/7/20"]
var timeline2=["Australian Bush Fire","Trump Impeached","COVID-19","Superbowl",
"Parasite Wins Oscars","Zoom University","Tiger King","Royal Family Split",
"Murder Hornets", "BLM Movement", "Election", "First Female VP Elect"]
function preload() {
var filenames = [];
filenames[0] = "https://i.imgur.com/tP1n00I.png"; filenames[1] = "https://i.imgur.com/sY9uWvm.png"; filenames[2] = "https://i.imgur.com/lCBeEEt.png"; filenames[3] = "https://i.imgur.com/3Rckn2m.png"; filenames[4] = "https://i.imgur.com/ul9jOdN.png"; filenames[5] = "https://i.imgur.com/iWRAmux.png"; filenames[6] = "https://i.imgur.com/dbYhauj.png"; filenames[7] = "https://i.imgur.com/lVbGhGa.png"; filenames[8] = "https://i.imgur.com/U1PoDE5.png"; filenames[9] = "https://i.imgur.com/nqwizdc.png"; filenames[10] = "https://i.imgur.com/xtEZvMR.png"; filenames[11] = "https://i.imgur.com/1lZjhEQ.png";
for (var i = 0; i < filenames.length; i ++) {
pipeImages.push(loadImage(filenames[i]));
}
var filenames2 = [];
filenames2[0] = "https://i.imgur.com/ibfDcOO.png"; filenames2[1] = "https://i.imgur.com/vFpcofS.png"; filenames2[2] = "https://i.imgur.com/NMyD9W2.png"; filenames2[3] = "https://i.imgur.com/aU3iUST.png"; filenames2[4] = "https://i.imgur.com/hqLtxr4.png"; filenames2[5] = "https://i.imgur.com/59MSAMG.png"; filenames2[6] = "https://i.imgur.com/ArzVHYU.png"; filenames2[7] = "https://i.imgur.com/up0miQL.png"; filenames2[8] = "https://i.imgur.com/pSRx5bC.png"; filenames2[9] = "https://i.imgur.com/EzfHYCr.png"; filenames2[10] = "https://i.imgur.com/wJvHY17.png"; filenames2[11] = "https://i.imgur.com/929AM73.png";
for (var i = 0; i < filenames2.length; i ++) {
gameOverImages.push(loadImage(filenames2[i]));
}
characterSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/bounce.wav");
clashSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/clash.wav");
}
function setup() {
createCanvas(450, 400);
background(12, 22, 24);
imageMode(CENTER);
useSound();
if (gameOn == true) {
fire.push(makeFire());
pipes.push(makePipes());
}
}
function soundSetup() {
characterSound.setVolume(0.01);
clashSound.setVolume(0.05);
}
function draw() {
background(12, 22, 24);
gradientSky();
if (gameOn == true) {
count++
updateAndDisplayFire();
if (count % 50 == 10){
fire.push(makeFire());
}
updateAndDisplayPipes();
if (count % 120 == 0){
if (gameOn == true) {
}
if (pipes.length < 12) {
pipes.push(makePipes());
}
if (count > 300) {
score += 150;
}
}
}
textSize(15);
fill(72,160,141);
noStroke();
text('SCORE ' + score, 50, 23);
drawFace();
if (count >= 1690){
gameOn = false;
}
if (gameOn == false) {
gameWon();
}
if (hitPipe == true){
gameOver(round((count/120) - ((120*3)/120)));
}
}
function gradientSky() {
var darkCol = color(0,12,15);
var lightCol = color(14,38,39);
for (var y = 0; y < height; y ++){
var backG = map(y, 0, height, 0, 1);
var backGColor = lerpColor(darkCol, lightCol, backG);
stroke(backGColor);
line(0, y, width, y);
}
for (var i = 0; i < 35; i++) {
strokeWeight(4);
if (round(random(1)) == 0 ) {
stroke(148, 67, 43);
} else {
stroke(81, 33, 22);
}
point(random(0,width), random(-0, height));
}
}
function updateAndDisplayFire(){
for (var i = 0; i < fire.length; i++){
fire[i].move();
fire[i].draw();
}
}
function fireMove() {
this.x += this.speed;
}
function fireDraw() {
push();
translate(0, height - 220);
scale(1.2, 1.75);
noStroke();
fill(81, 33, 22); beginShape();
vertex(this.x, this.y + 125);
vertex(this.x, this.y + 115);
vertex(this.x + 5, this.y + 115);
curveVertex(this.x + 4, this.y + 113);
curveVertex(this.x + 3, this.y + 112);
curveVertex(this.x + 3, this.y + 108);
curveVertex(this.x + 5, this.y + 102);
curveVertex(this.x + 9, this.y + 98);
vertex(this.x + 18 + random(-1, 1), this.y + 93+ random(-1, 1));
curveVertex(this.x + 17, this.y + 110);
curveVertex(this.x + 21, this.y + 112);
curveVertex(this.x + 31, this.y + 109);
curveVertex(this.x + 31, this.y + 102);
curveVertex(this.x + 25, this.y + 95);
curveVertex(this.x + 24, this.y + 89);
curveVertex(this.x + 27, this.y + 83);
curveVertex(this.x + 34, this.y + 77);
curveVertex(this.x + 40, this.y + 70);
curveVertex(this.x + 34, this.y + 56);
vertex(this.x + 30 + random(-1, 1), this.y + 53 + random(-1, 1));
curveVertex(this.x + 40, this.y + 56);
curveVertex(this.x + 50, this.y + 64);
curveVertex(this.x + 48, this.y + 75);
curveVertex(this.x + 41, this.y + 83);
curveVertex(this.x + 38, this.y + 90);
curveVertex(this.x + 40, this.y + 98);
curveVertex(this.x + 49, this.y + 99);
curveVertex(this.x + 52, this.y + 95);
curveVertex(this.x + 48, this.y + 90);
curveVertex(this.x + 48, this.y + 84);
vertex(this.x + 55 + random(-1, 1), this.y + 75 + random(-1, 1));
curveVertex(this.x + 54, this.y + 81);
curveVertex(this.x + 56, this.y + 89);
curveVertex(this.x + 60, this.y + 97);
curveVertex(this.x + 56, this.y + 104);
curveVertex(this.x + 62, this.y + 117);
curveVertex(this.x + 72, this.y + 118);
curveVertex(this.x + 80, this.y + 112);
curveVertex(this.x + 75, this.y + 99);
curveVertex(this.x + 68, this.y + 92);
curveVertex(this.x + 63, this.y + 83);
curveVertex(this.x + 70, this.y + 63);
curveVertex(this.x + 84, this.y + 54);
vertex(this.x + 94 + random(-1, 1), this.y + 50 + random(-1, 1));
curveVertex(this.x + 85, this.y + 56);
curveVertex(this.x + 77, this.y + 65);
curveVertex(this.x + 73, this.y + 73);
curveVertex(this.x + 77, this.y + 77);
curveVertex(this.x + 87, this.y + 75);
vertex(this.x + 89 + random(-1, 1), this.y + 63 + random(-1, 1));
curveVertex(this.x + 93, this.y + 68);
curveVertex(this.x + 93, this.y + 78);
curveVertex(this.x + 87, this.y + 86);
curveVertex(this.x + 81, this.y + 93);
curveVertex(this.x + 87, this.y + 99);
curveVertex(this.x + 92, this.y + 99);
curveVertex(this.x + 97, this.y + 92);
curveVertex(this.x + 94, this.y + 87);
curveVertex(this.x + 94, this.y + 84);
vertex(this.x + 98 + random(-1, 1), this.y + 77 + random(-1, 1));
curveVertex(this.x + 101, this.y + 85);
curveVertex(this.x + 104, this.y + 89);
curveVertex(this.x + 107, this.y + 97);
curveVertex(this.x + 104, this.y + 104);
curveVertex(this.x + 101, this.y + 110);
curveVertex(this.x + 109, this.y + 115);
vertex(this.x + 113, this.y + 115);
vertex(this.x + 113, this.y + 128);
endShape(CLOSE);
pop();
push();
translate(0, height - 125);
scale(1, 1);
noStroke();
fill(148, 67, 43); beginShape();
vertex(this.x, this.y + 125);
vertex(this.x, this.y + 115);
vertex(this.x + 5, this.y + 115);
curveVertex(this.x + 4, this.y + 113);
curveVertex(this.x + 3, this.y + 112);
curveVertex(this.x + 3, this.y + 108);
curveVertex(this.x + 5, this.y + 102);
curveVertex(this.x + 9, this.y + 98);
vertex(this.x + 18 + random(-1, 1), this.y + 93+ random(-1, 1));
curveVertex(this.x + 17, this.y + 110);
curveVertex(this.x + 21, this.y + 112);
curveVertex(this.x + 31, this.y + 109);
curveVertex(this.x + 31, this.y + 102);
curveVertex(this.x + 25, this.y + 95);
curveVertex(this.x + 24, this.y + 89);
curveVertex(this.x + 27, this.y + 83);
curveVertex(this.x + 34, this.y + 77);
curveVertex(this.x + 40, this.y + 70);
curveVertex(this.x + 34, this.y + 56);
vertex(this.x + 30 + random(-1, 1), this.y + 53 + random(-1, 1));
curveVertex(this.x + 40, this.y + 56);
curveVertex(this.x + 50, this.y + 64);
curveVertex(this.x + 48, this.y + 75);
curveVertex(this.x + 41, this.y + 83);
curveVertex(this.x + 38, this.y + 90);
curveVertex(this.x + 40, this.y + 98);
curveVertex(this.x + 49, this.y + 99);
curveVertex(this.x + 52, this.y + 95);
curveVertex(this.x + 48, this.y + 90);
curveVertex(this.x + 48, this.y + 84);
vertex(this.x + 55 + random(-1, 1), this.y + 75 + random(-1, 1));
curveVertex(this.x + 54, this.y + 81);
curveVertex(this.x + 56, this.y + 89);
curveVertex(this.x + 60, this.y + 97);
curveVertex(this.x + 56, this.y + 104);
curveVertex(this.x + 62, this.y + 117);
curveVertex(this.x + 72, this.y + 118);
curveVertex(this.x + 80, this.y + 112);
curveVertex(this.x + 75, this.y + 99);
curveVertex(this.x + 68, this.y + 92);
curveVertex(this.x + 63, this.y + 83);
curveVertex(this.x + 70, this.y + 63);
curveVertex(this.x + 84, this.y + 54);
vertex(this.x + 94 + random(-1, 1), this.y + 50 + random(-1, 1));
curveVertex(this.x + 85, this.y + 56);
curveVertex(this.x + 77, this.y + 65);
curveVertex(this.x + 73, this.y + 73);
curveVertex(this.x + 77, this.y + 77);
curveVertex(this.x + 87, this.y + 75);
vertex(this.x + 89 + random(-1, 1), this.y + 63 + random(-1, 1));
curveVertex(this.x + 93, this.y + 68);
curveVertex(this.x + 93, this.y + 78);
curveVertex(this.x + 87, this.y + 86);
curveVertex(this.x + 81, this.y + 93);
curveVertex(this.x + 87, this.y + 99);
curveVertex(this.x + 92, this.y + 99);
curveVertex(this.x + 97, this.y + 92);
curveVertex(this.x + 94, this.y + 87);
curveVertex(this.x + 94, this.y + 84);
vertex(this.x + 98 + random(-1, 1), this.y + 77 + random(-1, 1));
curveVertex(this.x + 101, this.y + 85);
curveVertex(this.x + 104, this.y + 89);
curveVertex(this.x + 107, this.y + 97);
curveVertex(this.x + 104, this.y + 104);
curveVertex(this.x + 101, this.y + 110);
curveVertex(this.x + 109, this.y + 115);
vertex(this.x + 113, this.y + 115);
vertex(this.x + 113, this.y + 128);
endShape(CLOSE);
pop();
}
function makeFire() {
var fire = {x: width,
y: 0,
speed: -2,
move: fireMove,
draw: fireDraw}
return fire;
}
function drawFace() {
if (characterOn == true) {
push();
noStroke();
fill(72,160,141);
ellipse(faceX, faceY, 30, 30);
fill(12, 22, 24);
ellipse(faceX - 9, faceY - 1, 3.5, 3.5);
ellipse(faceX + 9, faceY - 1, 3.5, 3.5);
noFill();
stroke(12, 22, 24);
strokeWeight(1);
arc(faceX, faceY, 5, 5, 0, PI, OPEN);
pop();
faceY += 1;
if (faceY < 15){
faceY += 5;
}
if (faceY > height - 15){
hitBottomGameOver();
}
}
}
function updateAndDisplayPipes(){
for (var i = 0; i < pipes.length; i++) {
pipes[i].move();
if (((faceY < pipes[i].pipeHeight + 30) & (faceX > pipes[i].x &&
faceX < pipes[i].x + pipes[i].pipeWidth)) || ((faceY > 400 -
((400 - (pipes[i].pipeHeight + (200 - pipes[i].pipeHeight) +
(122 - (200 - pipes[i].pipeHeight)))) + 55)) &&
(faceX > pipes[i].x && faceX < pipes[i].x + pipes[i].pipeWidth))){
hitPipe = true;
clashSound.play();
}
if (gameStart == true) {
pipes[i].draw();
}
pipes[i].imageNumber = i;
if ( pipes[i].imageNumber > 11) {
pipes[i].imageNumber = 0;
}
pipes[i].timelineNumber = i;
if ( pipes[i].timelineNumber > 11) {
pipes[i].timelineNumber = 0;
}
}
}
function pipesMove() {
this.x += this.speed;
}
function pipesDraw() {
var pipe1Height = this.pipeHeight - 30;
var pipe2Height = 400 - (this.pipeHeight + (200 - this.pipeHeight) +
(126 - (200 - this.pipeHeight)) );
fill(34,79,82);
noStroke();
rect(this.x, -30, this.pipeWidth, this.pipeHeight);
ellipse(this.x + 40, pipe1Height, this.pipeWidth, this.pipeWidth);
image(pipeImages[this.imageNumber], this.x + 40, pipe1Height, 60, 60);
textSize(15);
textAlign(CENTER);
fill(148, 67, 43);
text(timeline1[this.timelineNumber], this.x + 40, (pipe1Height +
((400 - ((pipe1Height) + (pipe2Height)))/2)) - 2);
text(timeline2[this.timelineNumber], this.x + 40, (pipe1Height +
((400 - ((pipe1Height) + (pipe2Height)))/2)) + 15);
push();
fill(34,79,82);
translate(0,400);
rect(this.x, -pipe2Height, this.pipeWidth, pipe2Height);
ellipse(this.x + 40, -pipe2Height, this.pipeWidth, this.pipeWidth);
image(pipeImages[this.imageNumber], this.x + 40, -pipe2Height, 60, 60);
pop();
}
function makePipes() {
var pipe = {x: 650,
pipeWidth: 80,
pipeHeight: random(130, 200),
speed: -2,
move: pipesMove,
draw: pipesDraw,
imageNumber: 0,
timelineNumber: 0
}
return pipe;
}
function keyPressed() {
if (key == 'm'){
faceY -= 20;
if (characterOn == true) {
characterSound.play();
}
}
}
function hitBottomGameOver() {
push();
gradientSky();
noStroke();
fill(72,160,141);
rectMode(CENTER);
rect(width/2, height/2, 227, 55);
textAlign(CENTER);
textSize(20);
fill(148, 67, 43);
text(' Y O U L O S T 2 0 2 0 ! ', width/2, height/2);
characterOn = false;
noLoop();
pop();
}
function gameOver(pipeNumber){
gradientSky();
image(gameOverImages[pipeNumber], width/2, height/2, 250, 250);
fill(148, 67, 43);
stroke(180, 67, 43);
strokeWeight(2);
push();
rectMode(CENTER);
rect(width/2, height/2 + 160, 110, 35);
pop();
textSize(15);
noStroke();
fill(255);
text('PLAY AGAIN', width/2, height/2 + 165);
gameStart = false;
characterOn = false;
hitPipe = true;
gameOn = false;
}
function gameWon() {
push();
noStroke();
fill(72,160,141);
rectMode(CENTER);
rect(width/2, height/2, 225, 55);
textAlign(CENTER);
textSize(20);
fill(148, 67, 43);
text(' Y O U W O N 2 0 2 0 ! ', width/2, height/2);
fill(148, 67, 43);
stroke(180, 67, 43);
strokeWeight(2);
rect(width/2, height/2 + 55, 110, 35);
textSize(15);
noStroke();
fill(255);
text('PLAY AGAIN', width/2, height/2 + 55);
characterOn = false;
pop();
}
function mousePressed() {
if (count >= 1689 & gameOn == false) {
if (mouseX > width/2 - 55 && mouseX < width/2 + 55 &&
mouseY < height/2 + 72.5 && mouseY > height/2 + 37.5) {
gameOn = true;
gameStart = true;
characterOn = true;
endGame = false;
count = -50;
score = 0;
pipes = [];
fire = [];
}
}
if (hitPipe == true) {
if (mouseX > width/2 - 55 & mouseX < width/2 + 55 &&
mouseY < height/2 + 177.5 && mouseY > height/2 + 142.5) {
hitPipe = false;
endGame = false;
gameStart = true;
gameOn = true;
characterOn = true;
count = -50;
score = 0;
pipes = [];
fire = [];
}
}
}
***on our Autolab submission we use the up arrow to control the character but here we used the letter m because with the up arrow it would move the whole page up and not just the canvas***