////////////////////////////////////////////////////////// // VARIABLES AND CONSTANTS // Constants final int MaxImages = 100; // maximum number of images that can be displayed at a time final int DisplayWidth = 750; // width of the display window final int DisplayHeight = 750; // height of the display window final int Border = 30; // don't create images this close to the edge final int ImageWidth = 60; // width of each image final int ImageHeight = 60; // height of each image final int ExplosionLatency = 1000; // how long an explosion appears, in milliseconds // Top-level variables PImage explosion, frog, elephant, seal; // loaded images int nextImage = 0; // number of current images PImage[] images = new PImage[MaxImages]; // storage for the current images float[] ypos = new float[MaxImages]; // y positions of images float[] xpos = new float[MaxImages]; // x positions of images float[] xdir = new float[MaxImages]; // x component of image velocity float[] ydir = new float[MaxImages]; // y component of image velocity int[] times = new int[MaxImages]; // time of appearance for explosions ////////////////////////////////////////////////////////// // FUNCTION DEFINITIONS // Standard function redefinitions: setup(), draw(), // and keyPressed() void setup() { size(DisplayWidth, DisplayHeight); println ("Welcome to the Crash Game! Type 'e' to create an elephant,"); println ("'f' to create a frog, 's' to create a seal, and watch them crash!"); explosion = loadImage ("explosion.jpg"); frog = loadImage ("frog.jpg"); seal = loadImage ("seal.jpg"); elephant = loadImage ("elephant.jpg"); } // Update positions: clear the display, remove old // explosions, explode any remaining images that are // touching each other, and move the unexploded images // (bouncing them off the wall if necessary), then draw // the remaining images void draw() { clearDisplay(); removeOldExplosions(); explodeTouchingImages(); moveAndBounce(); drawAllImages(); } void keyPressed() { if ( nextImage >= MaxImages ) { // Don't add more images than there is room for! println ("Sorry, I only have room for " + MaxImages + " images!"); } else if ( (mouseX < Border) || (mouseX > DisplayWidth-Border) || (mouseY < Border) || (mouseY > DisplayHeight-Border) ) { // Don't place an image if the mouse is too close to the edge } else if ( key == 'f' ) { createImage (frog); } else if ( key == 'e' ) { createImage (elephant); } else if ( key == 's' ) { createImage (seal); } else { println ("Sorry, I don't recognize the command \"" + key + "\""); } } /////////////////////////////////////////////////////////// // Main display functions called by draw() // Draw a "clean screen" to clear all previously // drawn images from the display void clearDisplay() { // Clear the display background(150); } // Remove any timed-out explosions from the display // by deleting them from the image array (i.e., calling // removeImage(), which will do that job for you). void removeOldExplosions() { int i; // THIS CODE REMOVES FROGS, BUT IT NEEDS TO BE CHANGED // TO REMOVE EXPLOSIONS INSTEAD! // Remove old frogs for (i=0; i < nextImage; ) { if ( (images[i] == frog) && (millis() - times[i] > ExplosionLatency) ) { removeImage(i); } else { i++; } } } // Replace any pairs of touching images with explosions. // (If three images are touching, it's OK if only two of // them explode.) void explodeTouchingImages() { // YOU NEED TO WRITE THIS FUNCTION! // HINT: IT SHOULD CALL intersectingImages() } // Move and bounce remaining images, updating // position array void moveAndBounce () { // YOU NEED TO WRITE THIS FUNCTION! } // Draw all images in the image array void drawAllImages() { int i; for (i=0; i < nextImage; i++) { image (images[i], xpos[i], ypos[i], ImageWidth, ImageHeight); } } /////////////////////////////////////////////////////////// // Utility functions used by main drawing functions // Create a new image: store it in the images array; draw it // on the screen at the mouse location; store the x and y positions // in the appropriate arrays; and set the xdir and ydir arrays to // contain random directions void createImage (PImage image) { images[nextImage] = image; image (images[nextImage], mouseX, mouseY, ImageWidth, ImageHeight); xpos[nextImage] = mouseX; ypos[nextImage] = mouseY; xdir[nextImage] = random(-2.0, 2.0); ydir[nextImage] = random(-2.0, 2.0); times[nextImage] = millis(); nextImage++; } // Explode an image that's crashed into another one: replace // it with the 'explosion' picture, stop it from moving, and initialize // the appropriate entry in the time array to the current time void explodeImage (int i) { // YOU WILL NEED TO WRITE THIS FUNCTION! } // Remove an image (one that's "timed out") from all of the // arrays, by copying the succeeding images backwards one place void removeImage (int i) { int j; println ("Removing image " + i); for ( j=i; j < nextImage-1; j++ ) { images[j] = images[j+1]; xpos[j] = xpos[j+1]; ypos[j] = ypos[j+1]; xdir[j] = xdir[j+1]; ydir[j] = ydir[j+1]; times[j] = times[j+1]; } nextImage--; } // Return TRUE if two images intersect (are within ImageWidth and ImageHeight // of each other) boolean intersectingImages (int i, int j) { return ( (abs(xpos[i] - xpos[j]) < ImageWidth) && (abs(ypos[i] - ypos[j]) < ImageHeight) ); }