/*
Due Oc 2 2017 10PM on SLATE
Restricted to Ch 1-7 of Processing Text
Intro to Media Computation
Instructor: Nicolas Hesler
"Seal Friend?" Interactive Toy Assignment
By Catherine Doherty
-click to make flickery fish and fishball darken, click to stop darkening
-click on seal to make seal lighter, click out of seal to make seal darker
-move seal with mouse
-move seal to touch fishball to make fish red again, and fishball water blue again
-hover over sky with mouse to make sky darken to a purple nightsky
-hover mouse off sky to make sky lighten to day again
*/
////////////////////////////////////////////////////////////////////////////////
//////////////////// Declare (user-defined) variables:
////////////////////////////////////////////////////////////////////////////////
// Variables related to the Fish:
boolean fishColourClickToChangeDarknessBoolean = false;
float randomFishColour;
float redFishColourTurnsBlack=255;
// Variables related to the Fish Ball:
int diametreBall = 160;
int leftEdgeOfAreaForBall = 0;
int limitForBall = leftEdgeOfAreaForBall + (diametreBall/2);
float blueSphereColourTurnsBlack =255;
float bouncingFishBallX;
float bouncingFishBallY;
float bouncingFishBallXSpeed = 3;
float bouncingFishBallYSpeed = 3;
// Variables related to the Bouncing Ball Sun
float bouncingBallSunX;
float bouncingBallSunY;
float bouncingBallSunXSpeed = .5;
float bouncingBallSunYSpeed = 2;
float skyValueGreen = 240;
// Variables related to the Seal:
float sealHeadCentreX;
float sealHeadCentreY;
float sealColourGrey=100;
int diametreSealHead=120;
int leftEdgeOfAreaForSeal=40;
int limitForSeal = leftEdgeOfAreaForSeal + (diametreSealHead/2);
float diametreSealAndBall = diametreBall + diametreSealHead;
void setup () {
// Set size of sketch window and rectmode to corners for convenience.
size(400, 400);
rectMode(CORNERS);
}
void draw () {
// SKY - box for SKY with varialbe so it can become purple on mouseover
fill(190, skyValueGreen, 245);
rect(0, 0, width, 125);
// Call these functions first so that they're behind the mountains.
// THE STARS, THE SUN
drawStars ();
drawBouncingBallSun ();
////////////////////////////////////////////////////////////////////////////////
////////////////////Make Loops for MOUNTAINS
////////////////////////////////////////////////////////////////////////////////
// Red Mountains
for (int backfrontMountainLoopVariable = 0; backfrontMountainLoopVariable<9; backfrontMountainLoopVariable=backfrontMountainLoopVariable+1) {
fill(100, 0, 0);
triangle(backfrontMountainLoopVariable*50-10, 110, backfrontMountainLoopVariable*50+15, 90, backfrontMountainLoopVariable*50+40, 110);
}
// Green Mountains
for (int middlefrontMountainLoopVariable = 0; middlefrontMountainLoopVariable<9; middlefrontMountainLoopVariable=middlefrontMountainLoopVariable+1) {
fill(0, 100, 0);
triangle(middlefrontMountainLoopVariable*100-20, 150, middlefrontMountainLoopVariable*100+40, 60, middlefrontMountainLoopVariable*100+80, 150);
}
// Blue Mountains
for (int frontMountainLoopVariable = 0; frontMountainLoopVariable<9; frontMountainLoopVariable=frontMountainLoopVariable+1) {
fill(0, 0, 100);
triangle(frontMountainLoopVariable*100-70, 130, frontMountainLoopVariable*100-10, 80, frontMountainLoopVariable*100+30, 130);
}
// Call these functions, in this order so water is at back, seal is in front.
// THE WATER, THE BALL, THE FISH, THE SEAL
drawWater();
drawBall();
drawFish();
drawSeal();
// WATER - Transparent water in front of seal, so seal looks like its underwater (nose can poke over surface).
noStroke();
fill(10, 160, 240, 70);
rect(0, 250, width, height);
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////make FISHBALL stay in its box
////////////////////////////////////////////////////////////////////////////////////////////
// Move the fishball.
bouncingFishBallX = bouncingFishBallX + bouncingFishBallXSpeed;
bouncingFishBallY = bouncingFishBallY + bouncingFishBallYSpeed;
// If the fishball gets off the screen, turn it around.
if (bouncingFishBallX>width || bouncingFishBallX<0) {
bouncingFishBallXSpeed = bouncingFishBallXSpeed*(-1);
}
if (bouncingFishBallY>170 || bouncingFishBallY<0) {
bouncingFishBallYSpeed = bouncingFishBallYSpeed*(-1);
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////make SEAL stay in its box
////////////////////////////////////////////////////////////////////////////////////////////
// Move the seal.
if (abs(mouseX-sealHeadCentreX)>0.1) {
sealHeadCentreX = sealHeadCentreX + (mouseX - sealHeadCentreX);
}
if (abs(mouseY-sealHeadCentreY)>0.1) {
sealHeadCentreY = sealHeadCentreY + (mouseY - sealHeadCentreY);
}
// Constrain seal to under the water (except for nose).
sealHeadCentreX = constrain(sealHeadCentreX, limitForSeal, width - limitForSeal);
sealHeadCentreY = constrain(sealHeadCentreY, limitForSeal+205, height);
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////make BOUNCING BALL SUN bounce
////////////////////////////////////////////////////////////////////////////////////////////
// move the ball
bouncingBallSunX = bouncingBallSunX +bouncingBallSunXSpeed;
bouncingBallSunY = bouncingBallSunY +bouncingBallSunYSpeed;
//if the ball gets off the screen, turn it around
if (bouncingBallSunX>width || bouncingBallSunX<0) {
bouncingBallSunXSpeed = bouncingBallSunXSpeed*(-1);
}
if (bouncingBallSunY>width/4 || bouncingBallSunY<0) {
bouncingBallSunYSpeed = bouncingBallSunYSpeed*(-1);
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////make FISHBALL COLLISION WITH SEAL change fishball colour
////////////////////////////////////////////////////////////////////////////////////////////
// When the seal's nose and the fishball come into contact, fish turns red again and water blue.
// You can click to start and stop darkening, but you can't get back to light blue unless nose touches fishball:
// if you get a number lower than the combined diametres of the seal and ball when
// you subtract the Y and X coordinants of the seal from the X and Y coordinants of the ball,
// it means they're in contact: so turn fish and fishball back to light blue.
// I multiplied X-coordinant distances by 5 because I only want the contact point (nose and tip of ball) to change the colour,
// so you actually have to move the seal most of the time.
// The collision thing below is modified from something Phill said in Discord:
// if (abs(ax - bx) * 2 < (awidth + bwidth)) && (abs(ay - by) * 2 < (aheight + bheight)){do something}
if (abs(bouncingFishBallX - sealHeadCentreX)*5<diametreSealAndBall && abs(bouncingFishBallY - sealHeadCentreY)*2<diametreSealAndBall) {
redFishColourTurnsBlack=255;
blueSphereColourTurnsBlack=255;
}
// FISH - Click to make fish dark flickering grey and water dark.
if (fishColourClickToChangeDarknessBoolean) {
redFishColourTurnsBlack = redFishColourTurnsBlack-1;
blueSphereColourTurnsBlack = blueSphereColourTurnsBlack-1;
}
// SKY - If you hover cursor over sky, sky turns purple and can see the stars, if hover off of sky, sky turns back to greenish/bluish.
// I wrote it this way, because otherwise it counts up infinitely so that it looks like it has stopped working after hovering over one too long.
if (mouseY > 0 && mouseY < 125 && skyValueGreen > 0) {
skyValueGreen = skyValueGreen-1;
} else if (mouseY > 125 && skyValueGreen < 240) {
skyValueGreen = skyValueGreen+1;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////William Lu's MOUSE POSITION AID ////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// Modified from William Lu's San Francisco piece, to see pointer's (x,y) coordinants:
//fill (0);
//text(" x: "+mouseX+" y: "+mouseY+" ", 10, 15);
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////end of draw
////////////////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a function to draw STARS
////////////////////////////////////////////////////////////////////////////////////////////
void drawStars () {
stroke(255);
point(5, 80);
point(27, 17);
point(42,7);
point(75, 58);
point(157, 70);
point(175, 22);
point(254, 38);
point(310, 66);
point(320, 60);
point(375, 79);
point(381, 4);
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a function to draw THE WATER in the background
////////////////////////////////////////////////////////////////////////////////////////////
void drawWater() {
//water modified from last assignment (my Interactive Art assignment called "Rain Maker")
noStroke();
fill(0, 150, 255);
rect(0, 125, width, height);
fill(0, 147, 252);
rect(0, 128, width, height);
fill(0, 142, 247);
rect(0, 136, width, height);
fill(0, 134, 239);
rect(0, 149, width, height);
fill(0, 121, 226);
rect(0, 170, width, height);
fill(0, 87, 192);
rect(0, 204, width, height);
//white line to mark difference between surface and underwater
fill(255);
rect(0, 248, width, height);
fill(0, 50, 107);
rect(0, 250, width, height);
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a function to draw THE BOUNCING BALL SUN
////////////////////////////////////////////////////////////////////////////////////////////
void drawBouncingBallSun () {
fill(250, 250, 0);
stroke(255);
ellipse(bouncingBallSunX, bouncingBallSunY, 25, 25);
noStroke();
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a function to draw THE BALL
////////////////////////////////////////////////////////////////////////////////////////////
void drawBall() {
// THE BALL
fill(blueSphereColourTurnsBlack-200, blueSphereColourTurnsBlack-42, blueSphereColourTurnsBlack);
ellipse(bouncingFishBallX, bouncingFishBallY, diametreBall, diametreBall);
// AIR SPACE - draw at the top
fill(190, 240, 245);
arc(bouncingFishBallX, bouncingFishBallY, diametreBall, diametreBall, radians(240), radians(300));
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a function to draw THE FISH
////////////////////////////////////////////////////////////////////////////////////////////
void drawFish() {
// FLICKER - using random:
randomFishColour = random(20, 80);
//want to be able to make fish dark, so red is also a variable:
fill(redFishColourTurnsBlack, randomFishColour, 50);
noStroke();
// FINS
triangle(bouncingFishBallX-20, bouncingFishBallY-5, bouncingFishBallX+10, bouncingFishBallY-30, bouncingFishBallX+10, bouncingFishBallY-15);
triangle(bouncingFishBallX-15, bouncingFishBallY+5, bouncingFishBallX+10, bouncingFishBallY+5, bouncingFishBallX+10, bouncingFishBallY+30);
// TAIL
triangle(bouncingFishBallX+25, bouncingFishBallY, bouncingFishBallX+50, bouncingFishBallY-30, bouncingFishBallX+50, bouncingFishBallY+30);
// DIVIT - cover tail with blue triangle that darkens when fishball darkens
fill(55, blueSphereColourTurnsBlack-42, blueSphereColourTurnsBlack);
triangle(bouncingFishBallX+50, bouncingFishBallY-5, bouncingFishBallX+45, bouncingFishBallY, bouncingFishBallX+50, bouncingFishBallY+5);
//BODY
//degrees translated into radians for fish body arcs
//lower arc
fill(redFishColourTurnsBlack, randomFishColour, 50);
arc(bouncingFishBallX, bouncingFishBallY-5, 60, 48, radians(10), radians(170));
//upper arc
arc(bouncingFishBallX, bouncingFishBallY+5, 60, 48, radians(190), radians(350));
// MOUTH
stroke(0);
line(bouncingFishBallX-30, bouncingFishBallY, bouncingFishBallX-20, bouncingFishBallY);
// GILLS
line(bouncingFishBallX-10, bouncingFishBallY+10, bouncingFishBallX, bouncingFishBallY);
line(bouncingFishBallX-5, bouncingFishBallY+15, bouncingFishBallX+5, bouncingFishBallY+5);
// EYE
fill(255);
strokeWeight(1.5);
ellipse(bouncingFishBallX-13, bouncingFishBallY-8, 6, 6);
//put strokeWeight back to normal
strokeWeight(1);
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a function to draw THE SEAL
////////////////////////////////////////////////////////////////////////////////////////////
void drawSeal() {
// Seal's whiskers, neck, nose, head, eyes:
// WHISKERS
stroke(0);
line(sealHeadCentreX, sealHeadCentreY-60, sealHeadCentreX+60, sealHeadCentreY-50);
line(sealHeadCentreX-60, sealHeadCentreY-50, sealHeadCentreX, sealHeadCentreY-60);
line(sealHeadCentreX, sealHeadCentreY-56, sealHeadCentreX+30, sealHeadCentreY-60);
line(sealHeadCentreX-30, sealHeadCentreY-60, sealHeadCentreX, sealHeadCentreY-56);
// NECK
fill(sealColourGrey);
noStroke();
quad(sealHeadCentreX-60, sealHeadCentreY, sealHeadCentreX+60, sealHeadCentreY, 300, 400, 100, 400);
// NOSE
fill(255, 173, 182);
// To make it easier to follow mouse, briefly set rectMode to centre:
rectMode(CENTER);
// Rect's 5th parametre is for rounded corners.
rect(sealHeadCentreX, sealHeadCentreY-60, 20, 20, 7);
// Back to corners mode for everything that follows.
rectMode(CORNERS);
// HEAD
fill(sealColourGrey);
ellipse(sealHeadCentreX, sealHeadCentreY, diametreSealHead, diametreSealHead);
// EYES
// Thicker black stroke:
stroke(0);
strokeWeight(3);
line(sealHeadCentreX+15, sealHeadCentreY-45, sealHeadCentreX+30, sealHeadCentreY-40);
line(sealHeadCentreX-30, sealHeadCentreY-40, sealHeadCentreX-15, sealHeadCentreY-45);
// Reset stroke weight to 1 for everything that follows.
strokeWeight(1);
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////Make a MOUSE CLICK do a thing
////////////////////////////////////////////////////////////////////////////////////////////
// Things that clicking the mouse causes:
// If click (once) on sketch window, fish and fishball start to turn darker until dark grey -
// click to stop, but only turns light again if ball touches seal nose.
// If click (repeatedly) on water surface or above, or to either side of seal, seal turns darker.
// If click (repeatedly) on seal, seal turns lighter.
void mousePressed() {
fishColourClickToChangeDarknessBoolean = !fishColourClickToChangeDarknessBoolean;
if (mouseX > 40 && mouseX < 360 && mouseY > 250) {
sealColourGrey=sealColourGrey+5;
} else {
sealColourGrey=sealColourGrey-5;
}
}