/////////////////////////////////////////////////////////////////////////// // Author: Justin Vrieling // Made for Media Computation at Sheridan College // October 2018 // // - Click the duck to spook it and make it fly! Move your mouse over it in // flight to change its direction! // - Make jeremy the duck hit a UFO to make it crash! The ufo speeds up // whenever you hit it, and slows down if you miss. // /////////////////////////////////////////////////////////////////////////// //declare variables for use later float waterOffset; float starAlpha = 100; //A couple of variables to handle the duck (HMM, IF ONLY I COULD USE ARRAYS OR CLASSES) int duckCount = 5; float duckSpeed = 2; float ducksX = random(0, 400); float ducksY = random(240, 390); float ducksDirection = 0; float ducksRise = 0; float duckLanding = 400; int dirCooldown = 0; float wingOffset = 0; //Variables for the UFOs float ufoX = -100; float ufoY = 100; float ufoSpeed = 1; int ufoCooldown = 10; int score = 0; //Coordinates for the stars float star1X = random(0, 400); float star1Y = random(0, 240); float star2X = random(0, 400); float star2Y = random(0, 240); float star3X = random(0, 400); float star3Y = random(0, 240); float star4X = random(0, 400); float star4Y = random(0, 240); float star5X = random(0, 400); float star5Y = random(0, 240); void setup() { size(400, 400); noStroke(); } void draw() { frameRate(60); background(0); //Modify the variables that need to change with each frame starAlpha += random(-30, 30); waterOffset = 0+(sin(frameCount*0.05)*3); moveDucks(); moveUfo(); if (dirCooldown > 0) { dirCooldown--; } if (ufoCooldown > 0) { ufoCooldown--; } //draw all the things drawLake(); drawStars(); drawUfo(); drawShimmer(); drawDucks(); } ///////////////////// // UFO FUNCTIONS /////////////////////// void moveUfo() { //Move the ufo if (ufoCooldown <= 0) { ufoX+=ufoSpeed; } //if it goes off screen reset it if (ufoX > width+100) { resetUfo(); } //if it hits the duck, make it go boom and add score and speed it up if (ducksX >= ufoX-20 && ducksX <= ufoX+20 && ducksY <= ufoY+20 && ducksY >= ufoY-20) { score++; ufoSpeed = (ufoSpeed + 0.1) * 1.2; fill(255, 0, 0); ellipse(ufoX, ufoY, 70, 70); frameRate(2); print("BOOM! Score: " + score + "\n"); resetUfo(); } } void resetUfo() { //Reset the ufo to the left side, and set the cooldown so it doesn't come right away ufoCooldown = 80; ufoX = -50; ufoY = random(70, 150); ufoSpeed *= 0.9; } void drawUfo() { //Draw the ufo //Blue orb thing fill(0, 200, 200); ellipse(ufoX, ufoY-10, 25, 25); //Red body. Shift the colour based on score fill(255-(score*20), 0+(score*20), 0+(score*20)); ellipse(ufoX, ufoY, 50, 20); } ////////////////////// // DUCK FUNCTIONS ////////////////////// void drawDucks() { //Draw a duck relative to the coordinates from the lists. //The conditional makes the duck face where it's going if (ducksDirection >= 0) { //body fill(#4E504A); ellipse(ducksX, ducksY+waterOffset, 40, 20); //wing fill(#41423D); triangle(ducksX-15, ducksY+waterOffset+wingOffset, ducksX+5, ducksY-6+waterOffset, ducksX+5, ducksY+7+waterOffset); //head fill(#1B6C3D); ellipse(ducksX+15, (ducksY+waterOffset)-10, 15, 15); //beak fill(#FFDD95); triangle(ducksX+21, (ducksY+waterOffset)-7, ducksX+26, (ducksY+waterOffset)-9, ducksX+21, (ducksY+waterOffset)-12); //eye fill(0); ellipse(ducksX+17, (ducksY+waterOffset)-12, 3, 3); } else { //body fill(#4E504A); ellipse(ducksX, ducksY+waterOffset, 40, 20); //wing fill(#41423D); triangle(ducksX+15, ducksY+waterOffset+wingOffset, ducksX-5, ducksY-6+waterOffset, ducksX-5, ducksY+7+waterOffset); //head fill(#1B6C3D); ellipse(ducksX-15, (ducksY+waterOffset)-10, 15, 15); //beak fill(#FFDD95); triangle(ducksX-21, (ducksY+waterOffset)-7, ducksX-26, (ducksY+waterOffset)-9, ducksX-21, (ducksY+waterOffset)-12); //eye fill(0); ellipse(ducksX-17, (ducksY+waterOffset)-12, 3, 3); } } void mouseClicked() { //When mouse is clicked, Check if it was on the duck if (mouseX <= ducksX+20 && mouseX >= ducksX-20 && mouseY <= ducksY+20 && mouseY >= ducksY-20) { scareDucks(); } } //////////////////////////////////////////////////////////////////////////////////////// // A function to handle movement of the ducks. Handles exiting the play space as well void moveDucks() { //If mouse is over the duck, make it change direction if (dirCooldown == 0 && mouseX <= ducksX+20 && mouseX >= ducksX-20 && mouseY <= ducksY+20 && mouseY >= ducksY-20) { ducksDirection *= -1; dirCooldown = 40; } //If the duckDirection isn't zero, it's in flight if (ducksDirection != 0) { wingOffset = (sin(frameCount*0.3)*15); //The variables will always be appropriate so these equations will make them rise or fall. ducksY -= (duckSpeed*ducksRise); ducksX += duckSpeed*ducksDirection; //make sure the ducks don't go off screen if (ducksX <= 0 || ducksX >= 400) { ducksDirection *= -1; } //make sure they don't go off the top either if (ducksY < 50) { ducksRise *= -1; } //When the duck is in the air decide on the landing Y coordinate if (duckLanding == 400 && ducksY <= 200) { duckLanding = random(240, 380); } //When the duck hits the Y landing, make it stop flying and reset stuff. if (ducksY >= duckLanding) { ducksDirection = 0; duckLanding = 400; wingOffset = 0; } } } void scareDucks() { //Don't let the direction be zero. while (ducksDirection == 0) { ducksDirection = round(random(-1, 1)); ducksRise = 1; } } ////////////////////// // LAKE FUNCTIONS ////////////////////// void drawShimmer() { //Draw the shimmering reflection of the moon on the lake fill(255, 100); ellipse(210+(sin(frameCount*0.1)*4), 245+waterOffset, 30, 5); ellipse(190+(sin(frameCount*0.11)*5), 245+waterOffset, 40, 6); ellipse(210+(sin(frameCount*0.12)*5), 250+waterOffset, 35, 4); ellipse(230+(sin(frameCount*0.1)*6), 246+waterOffset, 20, 4); ellipse(240+(sin(frameCount*0.16)*4), 243+waterOffset, 10, 3); ellipse(180+(sin(frameCount*0.08)*7), 242+waterOffset, 45, 4); ellipse(220+(sin(frameCount*0.1)*10), 242+waterOffset, 15, 4); } void drawStars() { //Draw the stars fill(255, random(90, 150)); ellipse(star1X, star1Y, 3, 3); ellipse(star2X, star2Y, 3, 3); ellipse(star3X, star3Y, 3, 3); ellipse(star4X, star4Y, 3, 3); ellipse(star5X, star5Y, 3, 3); fill(255, 70); //Draw the shimmer around the stars. //Using sin() and random to make them glimmer real cool ellipse(star1X, star1Y, 4+(sin(frameCount*random(0.01, 0.05))*3), 4+(sin(frameCount*random(0.01, 0.05))*3)); ellipse(star2X, star2Y, 4+(sin(frameCount*random(0.01, 0.05))*3), 4+(sin(frameCount*random(0.01, 0.05))*3)); ellipse(star3X, star3Y, 4+(sin(frameCount*random(0.01, 0.05))*3), 4+(sin(frameCount*random(0.01, 0.05))*3)); ellipse(star4X, star4Y, 4+(sin(frameCount*random(0.01, 0.05))*3), 4+(sin(frameCount*random(0.01, 0.05))*3)); ellipse(star5X, star5Y, 4+(sin(frameCount*random(0.01, 0.05))*3), 4+(sin(frameCount*random(0.01, 0.05))*3)); //Draw the moon// fill(255); ellipse(200, 70, 40, 40); fill(#FFEAD0); //craters ellipse(210, 60, 7, 7); ellipse(195, 70, 9, 9); ellipse(190, 65, 5, 5); ellipse(200, 65, 5, 5); ellipse(205, 80, 5, 5); ellipse(185, 80, 4, 4); } void drawLake() { //Draw the lake, use a loop for the gradient rectMode(CORNER); for (int i = 0; i < 200; i += 20) { //Set the colour based on how low on the screen fill(33-(i/5), 42-(i/5), 66-(i/5)); //Draw a rectangle, using water offSet to make it wave rect(0, ((240+i)+waterOffset), 400, 30); } }