/* 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.