Mega Code Archive

 
Categories / Java / J2ME
 

A MIDlet that displays the Doggy animation

/*  * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.  */ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; /**  * A MIDlet that displays the Doggy animation.  *  * @author Mark A. Patel - Motorola, Inc.  * @author Roger Riggs - Sun Microsystems, Inc.  **/ public class DoggyMIDlet extends MIDlet implements CommandListener {     Command cmdExit;     /**      * Constructs a new DoggyMIDlet      **/     public DoggyMIDlet() {         cmdExit = new Command("Exit", Command.EXIT, 1);     }          /**      * Starts the app by creating a new Doggy instance and displaying it      **/     protected void startApp() throws MIDletStateChangeException {         Doggy d;         d = new Doggy();         d.addCommand(cmdExit);         d.setCommandListener(this);                  Display.getDisplay(this).setCurrent(d);        }          protected void pauseApp() {     }          protected void destroyApp(boolean unconditional)   throws MIDletStateChangeException {     }          public void commandAction(Command c, Displayable d) {         if (c == cmdExit) {             try {                 destroyApp(false);             } catch (Exception e) {}             notifyDestroyed();         }     } }  class Doggy extends Canvas implements Runnable {   /**    * Number of frames in the animation    **/   static final int FRAME_COUNT = 17;   /**    * Normal frame delay (milliseconds)    **/   static final int FRAME_DELAY = 180;   /**    * Frame delay for the last frame where the dog is sleeping    **/   static final int LAST_FRAME_DELAY = 3000;   /**    * Relative horizontal position where each of the frames     * should be rendered. 0 represents the left edge of the screen    * and 1024 represents the right edge of the run distance     * (1024 is used so that scaling can be performed using    * simple bit shifts instead of division operations).     **/   static final int[] framePositions = {     0, 50, 186, 372, 558, 744, 930, 1024, 1024,     834, 651, 465, 279, 93, 0, 0, 0   };   /**    * An Image containing the 17 frames of the dog running,    * stacked vertically.    * Using a single image is much more efficient than using several     * images with each containing a single frame.    * Each frame can be rendered seperately by setting the clip     * region to the size of a single frame and then    * rendering the image at the correct position so that the desired     * frame isaligned with the clip region.    **/   Image doggyImages = null;   /**    * Width of a single animation frame    **/   int frameWidth = 0;   /**    * Height of a single animation frame    **/   int frameHeight = 0;   /**    * Index of the current frame    **/   int frameIndex = 0;   /**    * The distance, in pixels, that the dog can run (screen width less    * the width of a single frame)    **/   int runLength = 0;   /**    * Indicates if the animation is currently running    **/   boolean running = false;   /**    * Called when this Canvas is shown.  This method starts the timer     * that runs the animation sequence.    **/   protected void showNotify() {     if (doggyImages == null) {       try {         doggyImages =           Image.createImage("/examples/animation/Doggy.png");         frameWidth = doggyImages.getWidth();         frameHeight = doggyImages.getHeight() / FRAME_COUNT;       } catch (Exception ioe) {         return; // no image to animate       }     }     runLength = getWidth() - frameWidth;     running = true;     frameIndex = 0;     new Thread(this).start();   }   /**    * Called when this Canvas is hidden.  This method stops the    * animation timer to free up processing    * power while this Canvas is not showing.    **/   protected void hideNotify() {     running = false;   }   public void run() {     // Need to catch InterruptedExceptions and bail if one occurs     try {       while (running) {         Thread.sleep((frameIndex == FRAME_COUNT - 1) ?                LAST_FRAME_DELAY : FRAME_DELAY);         // Remember the last frame index so we can compute         // the repaint region         int lastFrameIndex = frameIndex;         // Update the frame index         frameIndex = (frameIndex + 1) % FRAME_COUNT;         // Determine the left edge of the repaint region         int repaintLeft = framePositions[lastFrameIndex];         int repaintRight = framePositions[frameIndex];         if (framePositions[lastFrameIndex] > framePositions[frameIndex]) {           repaintLeft = framePositions[frameIndex];           repaintRight = framePositions[lastFrameIndex];         }         // Scale the repaint coordinates to the width of the screen         repaintLeft = (repaintLeft * runLength) >> 10;         repaintRight = (repaintRight * runLength) >> 10;         // Trigger a repaint of the affected portion of the screen         // Repaint the region where the last frame was rendered         // (ensures that it is cleared)         repaint(repaintLeft, 0,             frameWidth + repaintRight - repaintLeft, frameHeight);       }     } catch (InterruptedException e) {}   }   public void paint(Graphics g) {     // Clear the background (fill with white)          // The clip region will limit the area that     // actually gets cleared to save time     g.setColor(0xFFFFFF);     g.fillRect(0, 0, getWidth(), getHeight());     // Translate the graphics to the appropriate     // position for the current frame     g.translate((framePositions[frameIndex] * runLength) >> 10, 0);     // Constrain the clip region to the size of a single frame     g.clipRect(0, 0, frameWidth, frameHeight);     // Draw the current frame by drawing the entire image with     // the appropriate vertical offset so that the desired frame     // lines up with the clip region.     g.drawImage(doggyImages, 0, -(frameIndex * frameHeight),           Graphics.LEFT + Graphics.TOP);   } }