#ff0000 30  2005 . - #000655      MIDP 1.0
#def ,  MIDP,  ,   MIDlet,    . MIDP 1.0    ,      . 
         .    .         ,  .
        .           .   -    .     PNG. (     .)
       MIDlet-.  -            MIDlet-   http.  -  Writless Toolkit       res     .
 -   :             .    ,       AnimatedImage:
import java.util.*;
import javax.microedition.lcdui.*;
//   ,  
//      ,
//        .
public class AnimatedImage extends TimerTask {
   private Canvas canvas;
   private Image[] images;
   private int[][] clipList;
   private int current;
   private int x;
   private int y;
   private int w;
   private int h;
   public AnimatedImage( Image[] images ){
     this( null, images, null );
   }
   //   
   public AnimatedImage( Canvas canvas, Image[]
     images ){ this( canvas, images, null );
   }
  // .  canvas ,  
  //    .  
  //  ,    ,
  //     , 
  //  .

   public AnimatedImage( Canvas canvas, Image[] images,
       int[][] clipList ){
     this.canvas = canvas;
     this.images = images;
     this.clipList = clipList;

     if( images != null && clipList != null ){
       if( clipList.length < images.length ){
       throw new IllegalArgumentException();
       }
     }

     if( images != null && images.length > 0 ){
       w = images[0].getWidth();
       h = images[0].getHeight();
     }
}

   //    .

   public void advance( boolean repaint ){
     if( ++current >= images.length ){
       current = 0;
     }

     if( repaint && canvas != null && canvas.isShown() 
){
       canvas.repaint( x, y, w, h );
       canvas.serviceRepaints();
     }
   }

  //   .   
  // ,   ,   
  //     
  // .

   public void draw( Graphics g ){
     if( w == 0 || h == 0 ) return;

     int which = current;

     if( clipList == null || clipList[which] == null){
       g.drawImage( images[which], x, y,
       g.TOP | g.LEFT );
     } else {
       int cx = g.getClipX();
       int cy = g.getClipY();
       int cw = g.getClipWidth();
       int ch = g.getClipHeight();

       int[] list = clipList[which];

       for( int i = 0; i + 3 <= list.length; i += 4 ){
         g.setClip( x + list[0], y + list[1],
         list[2], list[3] );
         g.drawImage( images[which], x, y,
         g.TOP | g.LEFT );
       }

       g.setClip( cx, cy, cw, ch );
     }
   }

   //     .

   public void move( int x, int y ){
     this.x = x;
     this.y = y;
   }

   //   .    .

   public void run(){
     if( w == 0 || h == 0 ) return;

     advance( true );
   }
}

    AnimatedImage   Image -   .        .     JAR    Image.createImage():private Image[] loadFrames( String name, int frames ) throws IOException {
   Image[] images = new Image[frames];
   for( int i = 0; i < frames; ++i ){
     images[i] = Image.createImage( name + i + ".png" );
   }
   return images;
}
,    ,   /images/bird0.png, /images/bird1 ... /images/bird6.png,     ,  :
Image[] frames = loadFrames( "/images/bird", 7 );
AnimatedImage ai = new AnimatedImage( frames );
ai.move( 20, 20 ); //       20,20 
 , AnimatedImage             .
    Canvas    .    canvas        ,      ,       .  ,          . 
 MIDP 1.0    , AnimatedImage           -     .    .         .        .      .    ,         :      ,    .     .       . 
     java.util.TimerTask.     ,    .    :
Timer timer = new Timer();
AnimatedImage ai = ..... //   
timer.schedule( ai, 200, 200 );
 200     AnimatedImage.run,     ,  canvas ,  .
   ,   .      canvas,      .
import java.util.*;
import javax.microedition.lcdui.*;

//  Canvas    
//     
//   canvas  
//   
//   .

public class AnimatedCanvas extends Canvas {
    private Display display;
    private Image offscreen;
    private Vector images = new Vector();

    public AnimatedCanvas( Display display ){
        this.display = display;
        //    
        // , 
        // 

        if( !isDoubleBuffered() ){
            offscreen = Image.createImage( getWidth(),
                                         getHeight() );
        }
    }

    //     .

    public void add( AnimatedImage image ){
        images.addElement( image );
    }

    // canvas.   ,  
    //   .
    //    
    // .

    protected void paint( Graphics g ){
        Graphics saved = g;

        if( offscreen != null ){
            g = offscreen.getGraphics();
        }

        g.setColor( 255, 255, 255 );
        g.fillRect( 0, 0, getWidth(), getHeight() );

        int n = images.size();
        for( int i = 0; i < n; ++i ){
            AnimatedImage img = (AnimatedImage)
                              images.elementAt( i );
            img.draw( g );
        }

        if( g != saved ){
            saved.drawImage( offscreen, 0, 0,
                       Graphics.LEFT | Graphics.TOP );
        }
    }
}

 ,  AnimatedCanvas  .          .              .      . (    ,   .)
import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
//  MIDlet    .
//        
// .

public class AnimationTest extends MIDlet
                 implements CommandListener {

    private static final int BIRD_FRAMES = 7;
    private static final int NUM_BIRDS = 5;

    private Display display;
    private Timer timer = new Timer();
    private AnimatedImage[] birds;
    private Random random = new Random();

    public static final Command exitCommand =
                         new Command( "Exit",
                                      Command.EXIT, 1 ); 

    public AnimationTest(){
    }

    public void commandAction( Command c,
                               Displayable d ){
        if( c == exitCommand ){
            exitMIDlet();
        }
    }

    protected void destroyApp( boolean unconditional )
                   throws MIDletStateChangeException {
        exitMIDlet();
    }

    public void exitMIDlet(){
        timer.cancel(); // ...
        notifyDestroyed();
    }

    //   

    private int genRandom( int upper ){
        return( Math.abs( random.nextInt() ) % upper );
    }

    public Display getDisplay(){ return display; }

    // .  canvas   
    //    .  
    // .

    protected void initMIDlet(){
        try {
            AnimatedCanvas c = new
                       AnimatedCanvas( getDisplay() );
            Image[] images =
                   loadFrames( "/images/bird",
                       BIRD_FRAMES );

            int w = c.getWidth();
            int h = c.getHeight();

            birds = new AnimatedImage[ NUM_BIRDS ];
            for( int i = 0; i < NUM_BIRDS; ++i ){
                AnimatedImage b = new
                          AnimatedImage( c, images );
                birds[i] = b;
                b.move( genRandom( w ), genRandom( h ) );
                c.add( b );
                timer.schedule( b, genRandom( 1000 ),
                                genRandom( 400 ) );
            }

            c.addCommand( exitCommand );
            c.setCommandListener( this );

            getDisplay().setCurrent( c );
        }
        catch( IOException e ){
            System.out.println( "Could not
                load images" );
            exitMIDlet();
        }
    }
    //    PNG .
    private Image[] loadFrames( String name, int frames )
                                   throws IOException {
        Image[] images = new Image[frames];
        for( int i = 0; i < frames; ++i ){
            images[i] = Image.createImage( name +
                i + ".png" );
        }

        return images;
    }

    protected void pauseApp(){
    }

    protected void startApp()
                      throws MIDletStateChangeException {
        if( display == null ){ 
            display = Display.getDisplay( this );
            initMIDlet();
        }
    }
}
     ,    . MIDlet             . ,             .