// ITU Experimental Interaction, spring 2011. Mandatory Assignment #04. Jakob Fischer Jørgensen. Mail: jfis@itu.dk. // Area: a little math, a little 2D, a little 3D. Theme: I’m Spinning Around. // Requirements: Minimum one “math trick”, minimum one use of trigonometry, minimum one use of 3D. // Items left on to-do list: // ** *NOT WORKING PROPERLY* If box is clicked, make it dissapear and respawn // ** *NOT WORKING PROPERLY* If box is clicked, incrase score by one // Import the OpenGL library for 3D import processing.opengl.*; // Number of boxes integer, final means we cannot change this anywhere else in the code final int numBoxes = 66; // Array for size of the boxes int[] sizeOfBox = new int[numBoxes]; // Arrays for position of the boxes float[] X = new float[numBoxes]; float[] Y = new float[numBoxes]; float[] Z = new float[numBoxes]; // Arrays for velocity of the boxes float[] vX = new float[numBoxes]; float[] vY = new float[numBoxes]; float[] vZ = new float[numBoxes]; // Arrays for rotation of the boxes float[] thetaX = new float[numBoxes]; float[] thetaY = new float[numBoxes]; float[] thetaZ = new float[numBoxes]; // Arrays for angular velocity of the boxes float[] omegaX = new float[numBoxes]; float[] omegaY = new float[numBoxes]; float[] omegaZ = new float[numBoxes]; // Variables to control the rotation and speed of the rotation of the sketch float sketchThetaX = 0; // Current sketch X rotation float sketchThetaY = 0; // Current sketch Y rotation float sketchThetaZ = 0; // Current sketch Z rotation float sketchOmegaX = 0; // Angular velocity for sketch X rotation float sketchOmegaY = 0; // Angular velocity for sketch Y rotation float sketchOmegaZ = 0; // Angular velocity for sketch Z rotation float spinDamping = 0.92; // Damping factor for sketch rotation // Overall sketch control boolean spinSketch = true; // True spins the sketch, false keeps the camera locked float timeWarp = 0.5; // -1 = reversed, 0 = stopped, 1 = normal speed, 2 = double speed and so on int gameState = 0; // State of the game: 0 = Intro, 1 = Playing, 2 = Game Over int score = 0; // Starting score int lives = 100; // Starting lives PGraphics buffer; // Buffer stuff for mouseclicking boxes void setup() { // SETUP START size(1024, 576, OPENGL); // Size of the sketch, use OpenGL frameRate(60); // Frames per second of the sketch cursor(CROSS); // Because crosshairs are cool colorMode(HSB, 100); // Colormode Hue, Saturation, Brightness background(0); // Black background for(int i = 0; i < numBoxes; i++) { // Initialise all the flying boxes with a for-loop randomise(i); } } // SETUP OVER void draw() { // DRAW START background(0); // Black background println(score); // Sends score to output // The intro screen before we start playing if(gameState == 0) { background(0); textAlign(CENTER); fill(30,100,150); textSize(20); text("Click the flying boxes before they fly past you,\nand don't get too dizzy now!\n\nPress space bar to start!", width/2,height/2); if(keyPressed == true ) { if (key == ' ') { gameState = 1; lives = 100; score = 0; } } } // The end-screen to show if we ran out of lives if(gameState == 2) { camera(); background(0); textAlign(CENTER); fill(30,100,150); textSize(20); text("You were overwhelmed by boxes...\nPress space bar to restart!\n\nYour final score was:", width/2,height/2); text(score, width/2, height/2 +120); if(keyPressed == true ) { if (key == ' ') { gameState = 1; lives = 100; score = 0; for(int i = 0; i < numBoxes; i++) { // Re-initialise all the flying boxes with a for-loop so we "respawn" them. randomise(i); } } } } // The main playing game state if(gameState == 1) { if (lives < 1) { gameState = 2; } // Camera (eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) // Camera at (0, 0, z) looking at the origin (0, 0, 0), the y-axis // can be considered as up. This puts (0, 0, z) at the centre of the sketch camera (0, 0, 3000, 0, 0, 0, 0, 1, 0); // Spin the entire sketch if this is true (set in overall sketch control above) if (spinSketch == true) { // Make a Perlin noise sample based on time elapsed. Manipulate the value // to a (-0.5, 0.5) value, scale it down and use that as an angular acceleration sketchOmegaZ = (sketchOmegaZ + (noise(millis()*0.001)-0.5)*0.02) * 0.92; // Apply the spinDamping float sketchOmegaX *= spinDamping; sketchOmegaY *= spinDamping; sketchOmegaZ *= spinDamping; sketchThetaX += sketchOmegaX; sketchThetaY += sketchOmegaY; sketchThetaZ += sketchOmegaZ; // Apply rotation to orientate the sketch rotateX(sketchThetaX); rotateY(sketchThetaY); rotateZ(sketchThetaZ); } // Set up lighting for the sketch using directionalLight (v1, v2, v3, nx, ny, nz) // The affect of the v1, v2, and v3 parameters is determined by the current color mode // The nx, ny, and nz parameters specify the direction the light is facing // The below gives a light pointing straight up and another pointing straight down directionalLight (30, 100, 150, 0, 1, 0); directionalLight (30, 100, 50, 0, -1, 0); // Spawn and orient the boxes with a forloop for (int i = 0; i < numBoxes; i++) { float distance = dist(mouseX, mouseY, X [i], Y [i]); if (mousePressed == true && distance < sizeOfBox [i]) { randomise(i); score = score +1; } pushMatrix(); // Saves current coordinate system to the stack translate(X[i], Y[i], Z[i]); // Box displacing translation x = left/right, y = up/down, z = toward/away rotateX(thetaX[i]); // Box X orientation rotateY(thetaY[i]); // Box Y orientation rotateZ(thetaZ[i]); // Box Z orientation noStroke(); // Don't stroke edges fill(100); // White, 100% opacity box(sizeOfBox[i]); // Box with size sizeOfBox, defined in void randomise (int i) popMatrix(); // Restores/reloads the coordinate system from the stack // If a box has flown past the camera (Z is a float for box z position), // make a new box by calling randomise method, else move and rotate it if (Z [i] > 3000) { randomise(i); lives = lives -1; } else { X[i] += vX[i] * timeWarp /2; Y[i] += vY[i] * timeWarp /2; Z[i] += vZ[i] * timeWarp /2; thetaX[i] += omegaX[i] * timeWarp /4; thetaY[i] += omegaY[i] * timeWarp /4; thetaZ[i] += omegaZ[i] * timeWarp /4; } } } } // Initialise flying box with array index i void randomise (int i) { X[i] = 0; // Spawn X position Y[i] = 0; // Spawn Y position Z[i] = -random(1000); // Spawn Z position, which is the actual distance from the camera vX[i] = random(-2, 2); // X Velocity, sort of an X spread factor vY[i] = random(-2, 2); // Y Velocity, sort of an Y spread factor vZ[i] = random(10) + 0.2; // Z Velocity, which is velocity towards the camera thetaX[i] = random(TWO_PI); // X rotation thetaY[i] = random(TWO_PI); // Y rotation thetaZ[i] = 0; // Z rotation, using a 3rd axis doesn't seem to do anything cool omegaX[i] = random(0.01, 0.3); // Angular velocity X, spin speed omegaY[i] = random(0.01, 0.3); // Angular velocity Y, spin speed omegaZ[i] = 0; // Angular velocity Z, using a 3rd axis doesn't seem to do anything cool int boxsize = int(random(3, 7)) * 17; // Randomise the size of the boxes sizeOfBox[i] = boxsize; // Set size of a box equal to integer boxsize } /* void mouseClicked() { // draw the scene in the buffer buffer.beginDraw(); buffer.background(getColor(-1)); // since background is not an object, its id is -1 buffer.noStroke(); buffer.camera (0, 0, 3000, 0, 0, 0, 0, 1, 0); buffer.rotateX(sketchThetaX); buffer.rotateY(sketchThetaY); buffer.rotateZ(sketchThetaZ); for (int i = 0; i < numBoxes; i++) { randomise[i].drawBuffer(buffer); } buffer.endDraw(); // get the pixel color under the mouse color pick = buffer.get(mouseX, mouseY); // get object id int id = getId(pick); // if id > 0 (background id = -1) if (id >= 0) { // change the cube color cubes[id].changeColor(); } } // id 0 gives color -2, etc. color getColor(int id) { return -(id + 2); } // color -2 gives 0, etc. int getId(color c) { return -(c + 2); } */