/** * @(#)SmashTransition.java * @version 1.51 04/06/97 * @author Robert Temple (robertt@starwave.com) */ import java.awt.image.MemoryImageSource; import java.awt.*; /** * The SmashTransition class changes one image into another by dropping the * new image onto the old one. The old image appears to crumble under the * weight of the new image. */ public class SmashTransition extends BillTransition { // Static Members /** * The total number of CELLS this transition will show on the screen before * the new image is shown in its entirety */ final static int CELLS = 8; /** * The old image will appear to be folded back and forth under the weigth * of the new image falling on it. This constant holds the value of the * number of folds that will appear each cell */ final static float FOLDS = 8.0f; /** * an array of white pixels used to fill in pixels where neither image will * appear in for a cell */ static int[] fill_pixels; static void setupFillPixels(int width) { if(fill_pixels != null && fill_pixels.length <= width) { return; } fill_pixels = new int[width]; for(int f = 0; f < width; ++f) { fill_pixels[f] = 0xFFFFFFFF; } } // Instance Members /** The amount of pixels to move the new image onto the old image each cell */ int drop_amount; /** * The index into the work_pixel array that the start of the old image * current is at */ int location; /** * Used to initialize the transition right after it is created. * creates cells * @param owner the component to be used to create images from cells */ public void init(Component owner, int[] current, int[] next) { init(owner, current, next, CELLS, 160); // ensure the fill pixel array is setup properly setupFillPixels(cell_w); // this cannot be reduced to 'pixels_per_cell / CELLS' because there // is some rounding that is done in 'cell_h / CELLS' drop_amount = (cell_h / CELLS) * cell_w; // as above, the right half of this calculation cannot be reduced // because of rounding location = pixels_per_cell - ((cell_h / CELLS) / 2) * cell_w; for(int c = CELLS - 1; c >= 0; --c) { // give other threads a shot at the CPU try { Thread.sleep(100); } catch (InterruptedException e) {} // create the next cell Smash(c + 1); // give other threads a shot at the CPU try { Thread.sleep(150); } catch (InterruptedException e) {} // create the new cell image from the work pixels createCellFromWorkPixels(c); location -= drop_amount; } // we don't need the work pixels anymore work_pixels = null; } /** * Create the next cell in the work pixel array */ void Smash(int max_fold) { // draw in the new image System.arraycopy((Object)next_pixels, pixels_per_cell - location, (Object)work_pixels, 0, location); // calculate the height of the new image int height = cell_h - location / cell_w; // calculate the length of the lines to draw for the smashed image int fold_width = cell_w - max_fold; // variable used to store the current fold offset float fold_offset = 0.0f; // calculate the amount to add to the fold offset after every line float fold_offset_adder = (float)max_fold * FOLDS / (float)height; // used to increment the src_y_offset defined below after every line float src_y_adder = (float)cell_h / (float)height; // used to determine the y-coordinate of the line to use from the // source image float src_y_offset = cell_h - src_y_adder / 2; for(int p = pixels_per_cell - cell_w; p >= location; p -= cell_w) { System.arraycopy((Object)fill_pixels, 0, (Object)work_pixels, p, cell_w); System.arraycopy((Object)current_pixels, (int)src_y_offset * cell_w, (Object)work_pixels, p + (int)fold_offset, fold_width); src_y_offset -= src_y_adder; fold_offset += fold_offset_adder; if(fold_offset < 0.0 || fold_offset >= max_fold) { fold_offset_adder *= -1.0f; } } } }