//Interactive Toy //Jesse Baker //Code citation: Some code taken from the Learning Processing textbook (Shiffman) PVector pos = new PVector (0, 0); //X and Y position of the ball PVector speed = new PVector (0, 0); //X and Y speed of the ball PVector gravity = new PVector (0, 0.3); //Value controls the force of gravity PVector clickPos = new PVector (0, 0); //Postion of the last place the mouse was when the button was clicked boolean ball = false; //If false, ball is not drawn. boolean slingFollow = true; //When true, the slingshot is drawn boolean mouseHeld = false; //Is true while the mouse button is held down color catMain = #837555; //The main colour for the cat (Brown) color catDark = #584F39; //The secondary colour for the cat (Dark brown) color pink = #F27FBD; //Used for the nose and ears of the cat (pink) color black = color (0, 0, 0); //Used for the ball and the cat's pupils (Black) color slingMain = #865B27; //The main colour of the slingshot (different brown from cat) color slingDark = #432B0D; //The darker colour of the slingshot (different dark brown from cat) color white = color(255, 255, 255); //White float[] rands = { random(0, 21), random(0, 21), random(0, 21), random(0, 21), random(0, 21) //These random values are set at the begining, and used to make the background }; int[] trailX = new int[10]; //These arrays are used to store previous ball positions, to draw the trail int[] trailY = new int[10]; void setup () { size(800, 800); frameRate (60); for (int i = 0; i<trailX.length; i++) { trailX[i] = 0; //Fill both arrays with 0 trailY[i] = 0; } } void draw () { background(white); makeBackground(); //Make the randomized background cat(); //Draw the cat if (ball == true) { //Only draw the ball when it is active trailUpdate(); //Shift the array position for the trail ballUpdate(); //Call the function which handles the ball's movement } slingShot(); //Draw the slingshot if (mouseHeld == true) {//When the mouse button is held, draw the slingshot's strings drawStrings(); //Call the function which draws the slingshot strings } } void ballUpdate () { //This function draws the ball based on position, speed and gravity //fill(black); for (int i = 0; i < trailX.length; i++) { //This loop draws the ball and trail. fill(255-i*28); //Make it so the colour changes for different segments of the trail ellipse (trailX[i], trailY[i], i*5, i*5); //The Ball } pos.y += speed.y; //Move the ball in the y-axis pos.x += speed.x; //Move the ball in the x-axis speed.y += gravity.y; //Apply gravity speed.x += gravity.x; //X gravity is not used by default, but is functional. //If you hit an edge of the screen, reverse directions if (pos.y >= height) { //Bottom of the screen speed.y = abs(speed.y) * -.8; //Set to the absolute value to control whether the value becomes positive or negative. Decrease the speed each time you bounce. } else if (pos.y < 0) { //Top of the screen speed.y = abs(speed.y * .8); } if ((pos.x >= width)) { //Right edge, reverse directions speed.x = abs(speed.x) * -.8; } else if ((pos.x <= 0)) { //Left edge, reverse directions speed.x = abs(speed.x * .8); } } void mousePressed () { //When the mouse button is pressed mouseHeld = true; //The mouse button is now being held down clickPos = new PVector (mouseX, mouseY); //Stores the mouse position when the mouse is clicked slingFollow = false; //Stop followwing the mouse on click } void drawStrings () {//Draw the slingshot's strings stroke(#432B0D); //Dark Brown strokeWeight(2); line (clickPos.x + 10, clickPos.y, mouseX, mouseY); //Strings line (clickPos.x - 10, clickPos.y, mouseX, mouseY); } void mouseReleased () { //When the mouse button is released mouseHeld = false; //The mouse button has now been released PVector curMouse = new PVector (mouseX, mouseY); //The current position of the mouse PVector prevMouse = new PVector (clickPos.x, clickPos.y); //The position of the mouse when the button was pressed curMouse.sub(prevMouse); //Subtract the previous position from the current position to get a direction vector from the clickpos to the currentpos createBall(new PVector (mouseX, mouseY), curMouse); //Create the ball at the mouse position, with the velocity vector to launch it slingFollow = true; //Make the slingshot follow the mouse again } void createBall (PVector startPos, PVector direction) { //This function creates the ball in a position, and applies force to it ball = true; //Enable the ball pos.x = startPos.x; //startPos will be set to the mouse position pos.y = startPos.y; speed.x = direction.x * -1 / 10; //The direction is inverted so the ball launches in the opposite direction the mouse is pulled speed.y = direction.y * -1 / 10; } void keyPressed () { ball = false; //Remove the ball if any key is pressed resetBackground(); //Make a new background - useful for testing the randomness of the background } void cat () { //This function draws the cat rectMode(CENTER); fill(catMain); noStroke(); strokeWeight(1); triangle(250, 600, 500, 650, 275, 450);//Ears triangle(550, 600, 300, 650, 525, 450); fill(pink); triangle(260, 590, 470, 640, 280, 465);// Inside ears triangle(540, 590, 330, 640, 520, 465); fill(catMain); ellipse (400, 700, 400, 400); //Body fill(pink);//Pink ellipse(400, 630, 100, 100); //Nose fill(catMain); rect(400, 570, 100, 50); //Cover up top of circle to make flat edge ellipse(350, 670, 60, 70); //Cover up sides of circle to make nostrils ellipse(450, 670, 60, 70); fill(catDark); ellipse (250, 750, 200, 200); //Draw the hands (paws) ellipse (550, 750, 200, 200); ellipse (315, 550, 100, 100); ellipse (485, 550, 100, 100); //Eyes fill(white); ellipse (485, 550, 80, 80); ellipse (315, 550, 80, 80); fill(black); if (ball) { ellipse(315 + ((pos.x - 400) /30), 532 + ((pos.y - 80)/20), 40, 40); //Pupils, which follow the ball ellipse(485 + ((pos.x - 400) /30), 532 + ((pos.y - 80)/20), 40, 40); } else { ellipse(315, 550, 40, 40); //If no ball, look forward ellipse(485, 550, 40, 40); } } void slingShot() { //This function draws the slingshot float xP; //Temporary storage of an x position float yP; //y postion if (slingFollow == true) { //If the slingshot is following the mouse, set the x and y positions to be the mouse positions xP = mouseX; yP = mouseY; } else { //If it is set to not follow, set the x and y positions to be where the player clicked xP = clickPos.x; yP = clickPos.y; } rectMode(CENTER); fill(slingMain); //Light brown noStroke(); rect (xP + 10, yP + 5, 5, 20, 5); rect (xP - 10, yP + 5, 5, 20, 5); //Build the slingshot rect (xP, yP + 15, 20, 5, 5); rect (xP, yP + 25, 5, 20, 5); fill(slingDark); //Dark brown rect (xP, yP + 25, 5, 10, 5); //Add the darker handle piece } void makeBackground () { //This function makes a randomized background, based on random variables which stay constant until reset in resetBackground() for (int i = 0; i < 9; i++) { //Loop to create the pattern. Each rect below gets repeated downward, eventually completing pattern noStroke(); rectMode(CENTER); for (int n = 0; n < 9; n++) { //This loop draws the squares across the x axis, with n increasing each time. fill(rands[0]*10 + n*15, rands[1]*10 + n*15, rands[2]*10 + n*15, 200);//After leaving this loop, the i value of the other loop increases before re-entering this loop, rect (n*100, i*100, rands[2]*5+100, rands[3]*10+100, rands[4]*10); //which moves the squares down before they are drawn again. } } } void resetBackground() { //Reset the random variables which control the background rands [0] = random(0, 21); rands [1] = random(0, 21); rands [2] = random(0, 21); rands [3] = random(0, 21); rands [4] = random(0, 21); } void trailUpdate () { //This function handles the ball's trail for (int i = 0; i < trailX.length - 1; i++) { trailX[i] = trailX[i+1]; //shift the array values for the ball trail down one place trailY[i] = trailY[i+1]; } trailX[trailX.length - 1] = (int)pos.x; //Add the current position to the end of the arrays. When combined with the shifting, this will make the arrays hold the previous 10 positions, which are used to make the trail. trailY[trailY.length - 1] = (int)pos.y; }