Rachel Lee and Jenna Kim Section E Final Project

Space Crunch

/* Rachel Lee and Jenna Kim
rwlee@andrew.cmu.edu and jeeyoonk@andrew.cmu.edu
Section E
Final Project */

// Radius of cereal loops
var radius = 20;
// Number of cereal pieces displayed (maximum number possible)
var cerealNum = 50;
// Empty array that holds cheerio elements
var cereal = [];
// Variable to store clicked cereal pieces
var clicked;
// Game time elapsed
var time_elapsed = 0;
// Game duration (60 seconds)
var gameLength = 120;
// Changes states according to instructions screen, game and game over
var gameMode = 0;

var x = [];
var y = [];

function setup() {
    createCanvas(600, 500);
    frameRate(10);

    // Variables for spacing of cereal loops according to triangle principles
    var tw = 90; // horizontal spacing between cheerios
    var th = 70; // vertical spacing between cheerios
    var cy = 50; // original y position
    var cx = 30; // original x position

    // Creates and pushes cereal into empty array
    for (var y = 0; y < 10; y ++) {
        // creates and displays even rows
        if ((y % 2) == 0) {
            for (var x = 0; x < 15; x++) {
                var px = cx + x * tw;
                var py = cy + y * th;
                cereal.push(new cheerios(px, py));
            }
        }
        // Creates and displays offset odd rows
        else {
            for (var x = 0; x < 10; x++) {
                th = 60 * (sqrt(3) / 2);
                var px = cx + x * tw;
                var py = cy + y * th;
                cereal.push(new cheerios (px + tw / 2, py + 150));
            } 
        } 
    } 
    
    // Initializes the player's score
    clicked = 0;

    // Updates cereal every second to determine if they pop up or not
    // Updates timer every second (1000 = 1 second in milliseconds)
    setInterval(function() {
        for (var i = 0; i < cerealNum; i ++) {
            cereal[i].updateC();
        }
        time_elapsed += 2;
    }, 1000);
}

function draw() {
	// Color gradient sky
    var color1 = color(0, 0, 153); // Blue purple
    var color2 = color(204, 51, 0); // Red

    for (var i = 0; i < height; i++) {
        var gradient = map(i, 0, height / 2, 0, 1);
        // Lerp used to ease color transitions 
        var mesh = lerpColor(color1, color2, gradient); 
        fill(mesh);
        stroke(mesh);
        line (0, i, width, i);
    }

    hillShadow();
    hill();

    noStroke();

    // Instruction page/ start game mode
    if (gameMode == 0) {
        gameStart();
    }

    // If game is still running, draws cereal, UFO, game score and time tracker
    if (gameMode == 1) {
        for (var i = 0; i < cerealNum; i ++){
            cereal[i].drawC();
        }  
        drawUFO();
        gSgT();
    }

    // Game ends when timer runs out
    if (time_elapsed >= gameLength) {
        gameMode = 2;
        gameOver();
    }

    // Press s key to start game
    if (keyIsPressed) {
    	if((key == 's') || (key == 'S')) {
    		gameMode = 1;
    	}
    	// When the game is over, press r key to reset game
        if ((key == 'r') || (key == 'R')) {
            gameMode = 1;
            time_elapsed = 0;
            clicked = 0;
        }
    }
}

// Draws UFO that follows mouse position
function drawUFO() {
    strokeCap(ROUND);
    stroke(230);
    strokeWeight(4);
    line(mouseX + 12, mouseY + 2, mouseX + 27, mouseY + 14);
    line(mouseX - 12, mouseY + 2, mouseX - 27, mouseY + 14);
    noStroke();
    fill(245, 210, 145); // orange peach
    ellipse(mouseX, mouseY + 7, 57, 16);
    fill(55, 70, 140); // blue 
    ellipse(mouseX, mouseY - 1.5, 85, 25);
    fill(255, 105, 80); // orange 
    ellipse(mouseX, mouseY - 3.5, 85, 25);
    fill(245, 210, 145); // orange peach
    arc(mouseX, mouseY - 7, 57, 37, PI, TWO_PI);
    ellipse(mouseX, mouseY - 7, 57, 16);
}

// Defines object constraints
function cheerios(x, y, duration, drawC, updateC, clickedC) {
    var pos = {x: x, y: y, duration: duration, drawC: drawCheerios, 
    updateC: updateCheerios, clickedC: clickedCheerios};
    return pos;
}

function drawCheerios() {
    if (this.duration > 0) {
        stroke(180, 147, 119);
        strokeWeight(8);
        noFill();
        ellipse(this.x, this.y, radius, radius);
        stroke(240, 225, 190);
        ellipse(this.x + 2, this.y + 2, radius, radius);
    }
}

//Determines whether or not the cheerios appear
function updateCheerios() {
    if (this.duration > 0) {
        this.duration = this.duration - 0.5;
    } 
    else {
        var ratio = random(1);
        if (ratio < 0.15) {
            this.duration = random(5);
        }
    }
}

// Checks to see if user clicked the cereal, and adds to score
function clickedCheerios (clickedX, clickedY) {
    if ((dist(clickedX, clickedY, this.x, this.y - radius) < radius) & (this.duration >= 0)) {
        this.duration = 0;
        clicked += 1;  
    }
}

// Checks to see if the mouse was pressed, and if the cereal was clicked
function mousePressed() {
    for (var i = 0; i < cerealNum; i++) {
        cereal[i].clickedC(mouseX, mouseY);
    }
}

function gameStart() {
    // Color gradient sky start
    var colorStart1 = color(0, 0, 153); // Blue purple
    var colorStart2 = color(204, 51, 0); // Red

    for (var i = 0; i < height; i++) {
        var gradientStart = map(i, 0, height / 0.9, 0, 1);
        // Lerp used to ease color transitions 
        var meshStart = lerpColor(colorStart1, colorStart2, gradientStart); 
        fill(meshStart);
        stroke(meshStart);
        line (0, i, width, i);
    }

    fill(255);
    textFont('Futura');
    textSize(13);
    text("Collect cheerios to fuel the U.F.O.'s journey through outer space!", width / 10 + 50, height / 2);
    text("Press S to Start", width/ 10 + 200, height/ 2 + 30);
}

// Display game score and remaining game time
function gSgT() {
    fill(255);
    textFont('Futura');
    textSize(12);
    text("Score : " + clicked, 500, height - 40);
    text("Time Remaining: " + (60 * 2 - time_elapsed)/2 + " secs", 50, height - 40);	
}

// Game over screen
function gameOver() {
    // Color gradient sky end
    var colorEnd1 = color(204, 51, 0); // Red
    var colorEnd2 = color(0, 0, 153); // Blue purple

    for (var i = 0; i < height; i++) {
        var gradientEnd = map(i, 0, height / 0.7, 0, 1);
        // Lerp used to ease color transitions 
        var meshEnd = lerpColor(colorEnd1, colorEnd2, gradientEnd); 
        fill(meshEnd);
        stroke(meshEnd);
        line (0, i, width, i);
    }
    noStroke();
    fill(255);
    text("Game Over!", width/ 2 - width/ 20, height/ 2 - 30);
    text("Cheerios Collected : " + clicked, width/ 3 + 35, height/ 2);
    text("Press R to restart", width/ 3 + 55, height/ 2 + 30);
}

//drawing hill
function hill() {
    var hillSpeed = 0.0002;
    var hillDetail = 0.0025;
    stroke(210, 105, 95, 80);
    for (var x = 0; x < width; x++) {
        var t = (x * hillDetail) + (millis() * hillSpeed);
        var y = map(noise(t * 2), 0, 1, 330, 200);
        line(x, y, x, height);
    }
} 

function hillShadow() {
    var hillSpeed = 0.0001;
    var hillDetail = 0.0045;
    stroke(160, 70, 70, 55);
    for (var x = 0; x < width; x++) {
        var t = (x * hillDetail) + (millis() * hillSpeed);
        var y = map(noise(t * 2.2), 0, 1, 100, 300);
        line(x, y, x, height);
    }   
}

Backstory and Instructions

Help the U.F.O. continue its intergalactic journey by collecting cheerio fuel! Click on the cheerios before they disappear, and collect as many as possible before the timer runs out. Running game time is 60 seconds.

Work Distribution 

For our project, Rachel primarily focused on the structure and mechanics of the game. Rachel created the mechanism for the flashing cheerios on screen, the game timer and the score keeping system when cheerios were pressed. Jenna focused more on the visual aspect of the game, designing the background / scenery, U.F.O., as well as the ‘Start Game’ and ‘Game Over’ pages and the mechanics of the game modes (Start, actual game, end game).

Working Together

Overall, we had a lot of fun working together. We were able to make revisions and improvements to our code in terms of style, efficiency of structure and visuals through continued collaboration.

First iteration
Second Iteration

 

Leave a Reply