Timothy Liu — Project 03 — Dynamic Drawing

Move the mouse to bring Pikachu near the pokéballs, and watch them converge and grow!

Also, click the mouse to change the berry floating around Pikachu’s head!

tcliu-openproject-03

// Timothy Liu
// 15104 Section C
// tcliu@andrew.cmu.edu
// OpenProject-03

// variables that determine the original/default sizing of Pikachu and pokeballs.
var pokeWidth = 50;
var buttonW = pokeWidth - 40;
var yStart = 350;
var pikachuW = 100;
var pikachuH = 80;
var pikachuX = 300;
var pikachuY = 200;
var eyeW = 15;
var eyeHighlight = 5;
var noseW = 10;
var mouthW = 15;
var mouthH = 30;
var cheekW = 17;

// variables determining the berry's size and color
var berryW = 25;
var berryH = 20;
var berryStem = 20;
var berryDist = 70;

// variables that allow berry color to be changed with mouse clicks
var berryR = 224;
var berryG = 78;
var berryB = 58;

// variables that determine background color; this allows the background to change color later as mouseY changes.
var colorR = 51;
var colorG = 91;
var colorB = 0;

// angle variable used to make the pokeballs spin. Later, the angle = angle + 1 command makes the angle change!
var angle = 0;

// function time!
function setup() {
    // canvas is 600, 480 instead of 640, 480 because a 640 width doesn't fit on WordPress.
    createCanvas(600, 480);
}

function draw() {

    // variables that make the pokeballs expand as the mouse moves down.
    // subtracting pokeWidth makes the pokeballs start at their default size when the mouse is at the top of screen.
    var mouseA = height - mouseY - pokeWidth;
    var pbWidth = height - mouseA;

    // variables to make the color of the background change as the mouse moves.
    var colorR1 = min(mouseY + colorR, 252);
    var colorG1 = min(mouseY + colorG, 194);
    var colorB1 = min(mouseY + colorB, 0);

    // setting the background color to start at green, and making it change to gold as the mouse moves down.
    background(colorR1, colorG1, colorB1);

    // if statement to limit size of the pokeballs. The pokeballs expand up to 200 pixels.
    if (pbWidth >= 200) {
        pbWidth = 200;
    }

    // pokeball 1: white part rotation. The push and pop functions ensure the pokeball spins.
    push();
    fill("white");
    noStroke();
    // this translate command makes the pokeballs converge to the center as mouseY increase.
    translate(width / 6 + min(max(mouseY, 0), width / 3), yStart);
    rotate(radians(angle));
    ellipseMode(CENTER);
    ellipse(0, 0, pbWidth, pbWidth);
    pop();
    angle = angle + 0.5;

    // pokeball 1: red half rotation
    push();
    fill("red");
    noStroke();
    translate(width / 6 + min(max(mouseY, 0), width / 3), yStart)
    rotate(radians(angle));
    arc(0, 0, pbWidth, pbWidth, PI, TWO_PI);
    pop();
    angle = angle + 0.5;

    // pokeball 1: button + outline
    push();
    fill("white");
    strokeWeight(3);
    translate(width / 6 + min(max(mouseY, 0), width / 3), yStart);
    rotate(radians(angle));
    ellipseMode(CENTER);
    ellipse(0, 0, pbWidth / 6, pbWidth / 6);
    pop();
    angle = angle + 0.5;

    // pokeball 2: white part rotation
    push();
    fill("white");
    noStroke();
    translate(width / 2, yStart);
    rotate(radians(angle));
    ellipseMode(CENTER);
    ellipse(0, 0, pbWidth, pbWidth);
    pop();
    angle = angle + 0.5;

    // pokeball 2: red part rotation
    push();
    fill("red");
    noStroke();
    translate(width / 2, yStart);
    rotate(radians(angle));
    arc(0, 0, pbWidth, pbWidth, PI, TWO_PI);
    pop();
    angle = angle + 0.5;

    // pokeball 2: button + outline
    push();
    fill("white");
    strokeWeight(3);
    translate(width / 2, yStart);
    rotate(radians(angle));
    ellipseMode(CENTER);
    ellipse(0, 0, pbWidth / 6, pbWidth / 6);
    pop();
    angle = angle + 0.5;

    // pokeball 3: white part rotation
    push();
    fill("white");
    noStroke();
    translate(5 * width / 6 - min(max(mouseY, 0), width / 3), yStart);
    rotate(radians(angle));
    ellipseMode(CENTER);
    ellipse(0, 0, pbWidth, pbWidth);
    pop();
    angle = angle + 0.5;

    // pokeball 3: red part rotation
    push();
    fill("red");
    noStroke();
    translate(5 * width / 6 - min(max(mouseY, 0), width / 3), yStart);
    rotate(radians(angle));
    arc(0, 0, pbWidth, pbWidth, PI, TWO_PI);
    pop();
    angle = angle + 0.5;

    // pokeball 3: button + outline
    push();
    fill("white");
    strokeWeight(3);
    translate(5 * width / 6 - min(max(mouseY, 0), width / 3), yStart);
    rotate(radians(angle));
    ellipseMode(CENTER);
    ellipse(0, 0, pbWidth / 6, pbWidth / 6);
    pop();
    angle = angle + 0.5;

    // beginning of push command to make the Pikachu follow the mouse using translate(mouseX, mouseY)
    push();
    translate(mouseX - pikachuX, mouseY - pikachuY);

    // head and ears 
    fill(252, 239, 0);
    noStroke();
    ellipse(pikachuX, pikachuY, pikachuW, pikachuH);
    triangle(pikachuX - 5 * pikachuW / 8, pikachuY - pikachuH, pikachuX - pikachuW / 4, pikachuY - pikachuH / 2.5,
        pikachuX - pikachuW / 2.2, pikachuY - pikachuH / 5);
    triangle(pikachuX + 5 * pikachuW / 8, pikachuY - pikachuH, pikachuX + pikachuW / 4, pikachuY - pikachuH / 2.5,
        pikachuX + pikachuW / 2.2, pikachuY - pikachuH / 5);

    // tips of the ears
    fill("black");
    triangle(pikachuX - 5 * pikachuW / 8, pikachuY - pikachuH, pikachuX - pikachuW * 0.5, pikachuY - pikachuH * 0.8,
        pikachuX - pikachuW * 0.56, pikachuY - pikachuH * 0.7);
    triangle(pikachuX + 5 * pikachuW / 8, pikachuY - pikachuH, pikachuX + pikachuW * 0.5, pikachuY - pikachuH * 0.8,
        pikachuX + pikachuW * 0.56, pikachuY - pikachuH * 0.7);

    // eyes
    ellipse(pikachuX - pikachuW / 5, pikachuY, eyeW, eyeW);
    ellipse(pikachuX + pikachuW / 5, pikachuY, eyeW, eyeW);
    fill("white");
    ellipse(pikachuX - pikachuW / 5, pikachuY - pikachuH * 0.05, eyeHighlight, eyeHighlight);
    ellipse(pikachuX + pikachuW / 5, pikachuY - pikachuH * 0.05, eyeHighlight, eyeHighlight);

    //red cheeks
    fill(227, 45, 25);
    ellipse(pikachuX - pikachuW / 3, pikachuY + pikachuH / 5, cheekW, cheekW);
    ellipse(pikachuX + pikachuW / 3, pikachuY + pikachuH / 5, cheekW, cheekW);

    // nose and mouth
    fill("black");
    arc(pikachuX, pikachuY + pikachuH / 8, noseW, noseW / 2, TWO_PI, PI);
    fill("pink");
    arc(pikachuX, pikachuY + pikachuH / 5, mouthW, mouthH, TWO_PI, PI);

    // pop command to enclose Pikachu commands. This ensures that only the Pikachu follows the mouse.
    pop();

    // this creates the berry floating/rotating around Pikachu's head.
    push();
    fill(berryR, berryG, berryB);
    noStroke();

    // this makes the berry float around Pikachu by adding some distance from the mouseX, mouseY origin
    translate(mouseX, mouseY);
    rotate(radians(angle));
    ellipse(berryDist, berryDist, berryW, berryH);
    fill(16, 196, 0);
    arc(berryDist, berryDist * 1.25, berryStem, berryStem / 1.1, PI, TWO_PI);
    pop();
    angle = angle + 1 / 100;

}

function mousePressed() {

    // when the mouse is pressed, the berry floating around Pikachu's head changes color!
    berryR = random(0, 255);
    berryG = random(0, 255);
    berryB = random(0, 255);
}

I grew up watching and playing Pokémon, and one of the random tidbits about the original cartoon that stuck with me was how pokéballs expand when they’re removed from the trainer’s belt. I built my program to mimic this dynamic movement; when you move the Pikachu (set to follow the mouse around) towards the pokeballs, they expand while rotating. They also converge into one as an inverse function of the mouse movement to represent Pikachu’s singular pokéball. In addition, the background changes color from a forest green to a warm gold as the mouse moves downward. I was very happy with how my project turned out, as its fun, lighthearted, meaningful, and engagingly dynamic.

The 5 dynamic elements I utilized are having Pikachu follow the mouse, making the pokéballs expand, having them converge, making the background change color, and the rotation of the pokéballs and berry. As an added interactive component, clicking on the berry causes it to change color.

Leave a Reply