diff --git a/raindropGameCode/CatcherClass.pde b/raindropGameCode/CatcherClass.pde new file mode 100644 index 0000000..adadd0c --- /dev/null +++ b/raindropGameCode/CatcherClass.pde @@ -0,0 +1,16 @@ +class Catcher { //initializing class + int diam; //declaring variables + PVector loc; + PImage Pi; + + Catcher(int tDiam) { //creates constructor that has an input of the diameter of the circle + diam = tDiam; //the diameter declared in the class above is equal to that of the input + loc = new PVector(mouseX, mouseY); //the catcher is initally at a random location + Pi = loadImage("PiCircle.png"); //retrieving image file from the data folder + } + + void display() { //method called display that, well, displays the catcher + Pi.resize(100,100); //scales the image down to the size of the catcher + image(Pi, mouseX - diam/2, mouseY - diam/2); //displays the image at the location of the mouse as its center + } +} \ No newline at end of file diff --git a/raindropGameCode/RaindropClass.pde b/raindropGameCode/RaindropClass.pde new file mode 100644 index 0000000..ac92d19 --- /dev/null +++ b/raindropGameCode/RaindropClass.pde @@ -0,0 +1,93 @@ +class Raindrop { //initialize class + PVector loc; //declare variables + PVector vel; + PVector acc; + float diam; + float r; + float g; + float b; + int points; + + Raindrop(float x, float y) { //create constructor + loc = new PVector(x, y); //turns input location into a vector + vel = new PVector(0, 3); //creates a velocity vector + acc = new PVector(0, 0.01); //creates an acceleration vector + diam = 20; //all raindrops have a diameter of 20 + if (isGold()) { //if the raindrop "isGold" (defined below), it's gold and if you catch it, then +20 + r = 255; + g = 215; + b = 0; + points = 20; + } else if (isRed()) { //if the raindrop "isRed" (defined below), it's red and if you catch it, then -10 + r = 255; + g = 0; + b = 0; + points = -10; + } else if (isBlack()) { + r = 0; + g = 0; + b = 0; + points = -score; + } else { //else, it's white and if you catch it, then +1 + r = 255; + g = 255; + b = 255; + points = 1; + } + } + + void fall() { //function dealing with the movement of the raindrop + loc.add(vel); //velocity is added to location and ... + vel.add(acc); //acceleration is added to velocity + } + + void display() { //function dealing with displaying the raindrop (pretty important :D) + stroke(0); //black border + strokeWeight(1); //default line weight + fill(r, g, b); //values for r, g, and b are determined above in the constructor + ellipse(loc.x, loc.y, diam, diam); //finally, we can create the raindrop + } + + void reset() { //function dealing with bringing a raindrop back to the top + loc = new PVector(random(width), 0); //resets location + vel = new PVector(0, 3); //resets velocity + acc = new PVector(0, 0.01); //resets acceleration + } + + boolean isInContactWith(Catcher c) { //boolean which checks to see if you caught a raindrop + if (loc.dist(mouse) < diam/2 + c.diam/2) { //two circles are touching if the distance between them is less that their combined radii + return true; + } else { + return false; + } + } + boolean isGold() { //probability boolean to create gold raindrops + float number = random(100); //from numbers 0-100... + number = round(number); //round the number (we don't want any floats!) + if (number == 5 || number == 1 || number == 10) { //basically 3% chance of getting gold (unless previously caught a gold raindrop...) + return true; + } else { + return false; + } + } + + boolean isRed() { //probability boolean to create red raindrops + float number = random(100); //from numbers 0-100... + number = round(number); //round the number (once again) + if (number == 2 || number == 4) { //basically 2% chance of getting red (unless previously caught a red raindrop...) + return true; + } else { + return false; + } + } + + boolean isBlack() { + float number = random(100); //from numbers 0-100... + number = round(number); //round the number (once again) + if (number == 3) { //basically 1% chance of getting black + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/raindropGameCode/data/PiCircle.png b/raindropGameCode/data/PiCircle.png new file mode 100644 index 0000000..4b876d3 Binary files /dev/null and b/raindropGameCode/data/PiCircle.png differ diff --git a/raindropGameCode/raindropGameCode.pde b/raindropGameCode/raindropGameCode.pde index 944de61..036ad1c 100644 --- a/raindropGameCode/raindropGameCode.pde +++ b/raindropGameCode/raindropGameCode.pde @@ -1,26 +1,141 @@ -PVector mouse; //declare a P -Raindrop r; //declare a new Raindrop called r - -// On your own, create an array of Raindrop objects instead of just one -// Use the array instead of the single object -// You can start out by just using the single Raindrop as you test - +PVector mouse; //initializes variables, including objects made using classes. Check out the "CatcherClass" and "RaindropClass" tabs to find out more about their properties and methods +int score = 0; +int state = 1; +Catcher bucket; +ArrayList raindrops = new ArrayList(); //creates an ArrayList from the Raindrop class void setup() { - size(1200, 800); - mouse = new PVector(); //initialize mouse PVector. value is irrelevant since it will be set at the start of void draw(){} - r = new Raindrop(random(width), 0); //Initialize r. The parameters used are the initial x and y positions + size(1200, 800); //canvas size of 1200px x 800px + mouse = new PVector(); //creates an empty PVector to be used to find the mouse's position + bucket = new Catcher(100); //creates a Catcher object called bucket with a diameter of 60 + raindrops.add(new Raindrop(random(width), 0)); //creates one raindrop to start out } void draw() { - mouse.set(mouseX, mouseY); //set value of mouse as mouseX,mouseY - background(0, 200, 255); - r.fall(); //make the raindrop fall. It should accelerate as if pulled towards the ground by earth's gravity - r.display(); //display the raindrop - if (r.isInContactWith(mouse)) { //check to see if the raindrop is in contact with the point represented by the PVector called mouse - r.reset(); //if it is, reset the raindrop + if (state == 1) { //first screen to be displayed is the title screen + background(0, 200, 255); //beautiful (Skype-looking) blue background + fill(255); //white text + textAlign(CENTER); //centered text + textSize(100); //100px text + text("RAINDROP GAME", width/2, height/2); //Title of the game centered on the screen + textSize(50); //50px text + text("PRESS ANY KEY", width/2, 700); //instructs the player to press any key so that we can move onto the ACTUAL game. + strokeWeight(4); //4px lines + stroke(255); //white lines + line(200, 450, 1000, 450); //line + backgroundBubbles(); //see function way, way, way below :) + } + if (state == 2) { //finally, we're getting somewhere: the instructions! + fill(255); //white text + background(0, 200, 255); //same gorgeous background + backgroundBubbles(); //same function that creates a nice border + textSize(100); //100px text + text("CONTROLS", width/2, 300); //heading for the screen; just in case you were wondering if indeed these were controls + textSize(25); //30px text + text("Using your mouse, catch the right raindrops to get points. \nWhite raindrops are worth 1 point. \nGold raindrops are worth 20 points. \nRed raindrops deduct 10 points. \nBlack raindrops deduct ALL points. \nIf you let a raindrop fall, you lose a point.", width/2, 440); //simple instructions on the objective of the game; notice the '\n' which starts following text on a new line + textSize(50); //50px text + text("PRESS ANY KEY", width/2, 700); //if think you have understood the mechanics of the game, please press any key + line(300, 350, 900, 350); //another stylistic line + fill(255); //white color + stroke(0); //black outline... + strokeWeight(1); //of 1px + ellipse(300, 473, 20, 20); //white raindrop + fill(255, 215, 0); //gold color + ellipse(300, 508, 20, 20); //gold raindrop + fill(255, 0, 0); //red color + ellipse(300, 545, 20, 20); //red raindrop + fill(0, 0, 0); //black color + ellipse(300, 581, 20, 20); //black raindrop + fill(255); //white color + ellipse(900, 473, 20, 20); //white raindrop + fill(255, 215, 0); //gold color + ellipse(900, 508, 20, 20); //gold raindrop + fill(255, 0, 0); //red color + ellipse(900, 545, 20, 20); //red raindrop + fill(0, 0, 0); //black color + ellipse(900, 581, 20, 20); //black raindrop + score = 0; //the reason why this is initialized twice is because if the player decides to play again (without refreshing game), we want them to start from zero } - if (r.loc.y > height + r.diam/2) { //check to see if the raindrop goes below the bottom of the screen - r.reset(); //if it does, reset the raindrop + if (state == 3) { //the RAINDROP game is upon us + if (score <= -1) { //this is checked at the start to prevent crashing + state += 1; //if so, redirect to Game Over screen + } + background(0, 200, 255); //you have to love this background color! + mouse.set(mouseX, mouseY); //sets the mouse as the mouse's position (keep in mind, it's a vector) + bucket.display(); //display the bucket (otherwise known as the pi symbol) + fill(255); //white text + textSize(50); //50px text + textAlign(CENTER); //centered text + text(score, width/2, 200); //display the score + text("RAINDROP GAME", width/2, 100); //just making sure you know that this is the Raindrop Game + strokeWeight(4); //4px line + stroke(255); //white line + line(370, 110, 830, 110); //line + for (int i = raindrops.size()-1; i >= 0; i--) { //for each object in the raindrops ArrayList... (starting from the back to prevent flickering) + Raindrop r = raindrops.get(i); //isolate the raindrop + r.fall(); //make it fall + r.display(); //display it + if (r.isInContactWith(bucket)) { //if the bucket is touching the raindrop... + r.reset(); //spawn the same raindrop from the top + score += r.points; //score changes based on color (white, gold, red) + if (raindrops.size() < 50) { //limits the amount of raindrops on the screen to 50 to prevent crashing + raindrops.add(new Raindrop(random(width), 0)); + } + } + if (r.loc.y > height + r.diam/2) { //if the raindrop reaches the bottom of the screen... + raindrops.remove(r); //it is removed + if (raindrops.size() < 50) { //once again, if there is less than 50 raindrops... + raindrops.add(new Raindrop(random(width), 0)); //add a random one + } + score -= 1; //in the end, dropping a raindrop (no matter the color) is worth the same + } + } + } + if (state == 4) { //Game Over screen + resetArrayList(); //function defined below; gets rid of all stored entries in the ArrayList + background(0, 200, 255); //this background never gets old, does it? + fill(255); //white text + textSize(100); //100px text + textAlign(CENTER); //centered text + text("GAME OVER", width/2, height/2); //the infamous Game Over text smack dab in the center of your computer screen + textSize(50); //50px text + text("PRESS ANY KEY TO PLAY AGAIN", width/2, 700); //you'll never escape this game unless you close your window! :D + backgroundBubbles(); //once again, wonderful border } } + +void keyPressed() { //this explains the 'press any key' mechanism; CAN WE FIGURE OUT HOW TO NOT BE ABLE TO SKIP DURING GAMEPLAY UNLESS YOU LOSE? ************ + state += 1; //self-explanatory + if (state == 5) { //this is how the loop functions: if you reach a 5th state (non-existent), you are redirected to the title screen + state = 1; //title screen + raindrops.add(new Raindrop(random(width), 0)); //starts out the game with a single raindrop (since this is normally created in void setup()) + } +} + +void backgroundBubbles() { //beautiful detailed background + noStroke(); //by not having a stroke, it is clear to see which balls are meant to be caught + ellipse(20, 20, 10, 10); //ellipse #1 + ellipse(1180, 20, 10, 10); //ellipse #2 + ellipse(1180, 780, 10, 10); //ellipse #3 + ellipse(20, 780, 10, 10); //ellipse #4 + ellipse(30, 40, 20, 20); //ellipse #5 + ellipse(1170, 40, 20, 20); //ellipse #6 + ellipse(1170, 760, 20, 20); //ellipse #7 + ellipse(30, 760, 20, 20); //ellipse #8 + ellipse(60, 60, 30, 30); //ellipse #9 + ellipse(1140, 60, 30, 30); //ellipse #10 + ellipse(1140, 740, 30, 30); //ellipse #11 + ellipse(60, 740, 30, 30); //ellipse #12 + strokeWeight(4); //4px line + stroke(255); //white line + line(100, 10, 1100, 10); //line #1 + line(100, 790, 1100, 790); //line #2 + line(10, 100, 10, 700); //line #3 + line(1190, 100, 1190, 700); //line #4 +} + +void resetArrayList() { //function used during Game Over screen + for (int i = raindrops.size()-1; i >= 0; i--) { //deletes all arrays starting from the end working back to zero + raindrops.remove(i); + } +} \ No newline at end of file