hyt-Final-Project: Will you be my friend on a cold night?

hyt-final-proj

// helen tsui
// 15-104 section d
// hyt@andrew.cmu.edu
// final-project


// image gallery
var poke; 
var hugWhite;
var heart;

// welcomePage() global var.
var startRadius = 100;
var lightOn = false;
var endWelcome = false;

// drawPerson() global var.
var headX;
var headY;
var headSize;

// array and other things for bubble and warmth functions
var bubbleX = [];
var bubbleY = []; 
var heartArr = [];
var heartV = 0;
var heartPos = []; // heart position in warmUp()

// for setGradient() function
var Y_AXIS = 1;
var X_AXIS = 2;

// rgb values for figure
var r = 161; 
var g = 190; 
var b = 255; 
var addColor = 10;

// check if button is hovered over
var isOverWarmth;
var isOverBubbles; 
var clickedBubbleButton = false;
var clickedWarmthButton = false;
var happy = false; // happy face? 

// for mouth movement
var endAngle;
var startAngle; 



function preload() {
    // first icon's courtesy of elon lastad from noun project
    hugWhite = loadImage("https://i.imgur.com/LdCyCn9.png");
    poke = loadImage("https://i.imgur.com/CV9mms1.png");
    heart = loadImage("https://i.imgur.com/DK1JVMP.png");
}



function setup() {
    createCanvas(480, 480);
    frameRate(16);
}



function draw() {

    welcomePage();
    if (endWelcome == true) {
    //making gradient background
    var grad1 = color(42, 46, 127); // gradient color 1
    var grad2 = color(156, 83, 156); // gradient color 2
    var grad3 = color(78, 83, 107); // gradient color 3
    background(0);
    setGradient(0, 0, width, height * 0.75, grad1, grad2, Y_AXIS); 
    setGradient(0, height * 0.75, width, height, grad2, grad3, Y_AXIS); 
    fill(0, 40);
    noStroke();
    // land shape
    arc(width / 2, height + 20, width * 1.3, height * 0.4, 180, 0, OPEN);
    makeSnow();
    buttonForBubble();
    buttonForWarmth();
    drawPerson();
    }

}



function welcomePage() { 
    var bg = 0;
    noStroke();
    fill(0);
    rect(0, 0, width, height);
    fill(255, 226, 104, 200); // mustard yellow color
    // yellow circle expands
    ellipse(width - 20, height - 20, startRadius, startRadius); 
    var mouseDist = dist(mouseX, mouseY, width - 30, height - 30);
    if (mouseDist < 50) {
        lightOn = true;
    }
    if (lightOn == true) {
        startRadius += 10;
    }
    textSize(15);
    textFont("Courier New");
    text("Will You Be My Friend ", 90, 100);
    text("On a Cold Night? ", 90, 120);
    textSize(12);
    text("• Pat my head to keep me warm", 80, 250);
    text("• Drag your mouse and draw bubbles with me", 80, 270);
    text("• Click and send me some warm fuzzy hearts", 80, 290);
    text("• Happy xmas :)", 80, 310);
    // if whole screen yellow, go to second screen
    if (startRadius >= 1500) { 
        endWelcome = true;
    }
}



function makeSnow() {
    this.x = random(width);
    this.y = random(height);
    for (var h = 0; h < 150; h++) {
            fill(255, 50); // white alpha
            ellipse(this.x, this.y, 10, 10, 50);
    }
}



function buttonForBubble() {
    // make button first 
    var posX = width - 100;
    var posY = 100;
    var dist2 = dist(mouseX, mouseY, posX, posY);
    if (dist2 < 25) {
        isOverBubbles = true;
    } else {
        isOverBubbles = false;
    }
    if (isOverBubbles == true) {
        push();
        fill(161, 190, 255);
        text("Draw bubbles with me!", 50, 50);
        cursor(HAND);
        stroke(200); // ocean color
        strokeWeight(4);
        if (mouseIsPressed) {
            clickedWarmthButton = false;
            clickedBubbleButton = true;
        }
        pop();
    } 
    if (isOverBubbles == false) {
        fill(69, 103, 178);
        cursor(ARROW);
    }
    ellipse(posX, posY, 50, 50); // draw button shape

    // draw bubble icon on button
    push();
    fill(255);
    ellipse(posX - 9, posY + 7, 10, 10);
    ellipse(posX + 6, posY - 6, 16, 16);
    ellipse(posX + 7, posY + 12, 8, 8);
    pop();

    // call function for drawing bubbles
    drawBubbles();
}



function buttonForWarmth() {
    // make button for hearts and hugs
    var posX1 = width - 100;
    var posY1 = 180;
    var dist1 = dist(mouseX, mouseY, posX1, posY1);

    if (dist1 < 25) {
        isOverWarmth = true;
    } else {
        isOverWarmth = false;
    }
    if (isOverWarmth == true) {
        push();
        fill(255, 206, 216);
        text("feeling loved <3", 50, 50);
        cursor(HAND);
        stroke(200);
        strokeWeight(4);
        if (mouseIsPressed) {
            clickedBubbleButton = false;
            clickedWarmthButton = true;
        }
        pop();
    } 
    if (isOverWarmth == false) {
        fill(173, 140, 147);
        //noStroke();
        cursor(ARROW);
    }

    // draw button
    ellipse(posX1, posY1, 50, 50); // where the button is
    // input icon image
    push();
    imageMode(CENTER);
    scale(0.08, 0.08);
    image(hugWhite, posX1 * 12.5, posY1 * 12.5);
    pop();
    // execute warmUp function
    warmUp();
}

function drawBubbles() {

    if(!clickedBubbleButton) {
        return;
    }
    // limit bubbles array to 20 circles
    if (bubbleX.length > 20) {
        bubbleX.shift();
        bubbleY.shift();
    }
    // draw bubble
    for (var i = 0; i < bubbleX.length; i++) {
        var bubbleInc = random(-10, 10); // bubble increments
        var bubblePosX = bubbleX[i] + random(-10, 10); // random X or Y position
        var bubblePosY = bubbleY[i] + random(-10, 10); // random X or Y position
        var bubbleR = 10 + random(-2, 4); 
        noStroke();
        fill(255, 160);
        ellipse(bubblePosX, bubblePosY, bubbleR, bubbleR);
    }
}



function warmUp() {
    // if warmth button not clicked, warmUp will not be executed
    if(!clickedWarmthButton) {
        return;
    }
    // send heart falling rain
    heartV += 5;
    for (var x = 0; x < heartArr.length; x++) {
        push();
        scale(0.5, 0.5);   
        image(heart, heartArr[x], heartPos[x]+heartV);
        pop();
    }
    if (heartPos[x] >= width + 5) {
        heartPos = [];
    }
}



function drawPerson() {
    headX = width / 3;
    headY = height / 3;
    headSize = 85;
    // change body temperature as time goes by
    for (var i = 0; i < 1000; i++) {
        r -= 0.001;
        b += 0.001; 
        fill(r, g, b);
    }
    noStroke();
    // head
    ellipse(headX, headY, headSize, headSize); 
    image(poke, headX + 50, headY - 20);
    // body
    rect(headX - 25, headY + 35, 50, 120, 30); 
    // left arm
    rect(headX - headSize * 0.58, headY + 50, 20, 50 * 2, 30);
    // right arm
    rect(headX + headSize * 0.33, headY + 50, 20, 50 * 2, 30); 
    // left leg
    rect(headX - 25, headX + 120, 18, 130, 30);
    // right leg
    rect(headX + 7, headX + 120, 18, 130, 30);
    // eyes
    fill(0);
    ellipse(headX - 30, headY, 10, 10);
    ellipse(headX, headY, 10, 10);
    // blush
    fill(252, 204, 255, 150);
    ellipse(headX - 35, headY + 21, 14, 12);
    ellipse(headX + 4, headY + 21, 14, 12);
    fill(0);
    // mouth
    push();
    stroke(0);
    strokeWeight(3);
    noFill();
    angleMode(DEGREES); 
    if (happy == false) {
        startAngle = 180; 
        endAngle = 0;
    }
    if (happy == true) {
        startAngle = 0;
        endAngle = 180;
    }
    arc(headX - 18, headY + 20, 8, 3, startAngle, endAngle, OPEN);
    pop();
    }



function mousePressed() {
    // when mouse is pressed, the array restarts (new drawing action on canvas)
    bubbleX = [];
    bubbleY = [];
    // push new heart position into array
    heartArr.push(mouseX * 2);
    heartPos.push(mouseY * 0.5);
    // finding distance between mouse and head
    var distance = dist(mouseX, mouseY, width/2, height/3); 
    if (distance < 90) {
        cursor(HAND);
        r += addColor;
        b -= addColor;
        if (r >= 160) {
            happy = true;
        } else {
            happy = false;
        }
    }
}



function mouseDragged() {
    if (clickedBubbleButton) {
        bubbleX.push(mouseX);
        bubbleY.push(mouseY);
    }
}



// ---- HELPER CODE REFERENCED FROM P5.JS WEBSITE ---- //



function setGradient(x, y, w, h, c1, c2, axis) {
  noFill();
  if (axis == Y_AXIS) {  // Top to bottom gradient
    for (var i = y; i <= y+h; i++) {
      var inter = map(i, y, y+h, 0, 1);
      var c = lerpColor(c1, c2, inter);
      stroke(c);
      line(x, i, x+w, i);
    }
  }  
  else if (axis == X_AXIS) {  // Left to right gradient
    for (var i = x; i <= x+w; i++) {
      var inter = map(i, x, x+w, 0, 1);
      var c = lerpColor(c1, c2, inter);
      stroke(c);
      line(i, y, i, y+h);
    }
  }
}


For the final project, I wanted to create something that is warm and fuzzy to play for this winter, so I made a simple interactive mouse-moving game about a small person looking for company on a cold snowy night.

The game starts with a menu screen, showing the title and instructions for the game. There are three different interactions in the game: patting head for warmth, sending hearts, and drawing bubbles with the character. The user would activate the game by placing the cursor over the yellow circle (on the bottom right side), and then you would see the second screen. When the character reaches a certain temperature, it would have a smiley face showing its happiness; the other two buttons are also clicked on and have separate functions. Have fun exploring and happy holidays 🙂

Leave a Reply