Author: Eir Giguere compiled: Sean
Developers using MIDP (Mobile Information Device Profile often complain what way can be used to display animations on a MIDLET.
MIDP 1.0 did not directly provide support for animation (MIDP 2.0 support in development), but it is not a difficult thing to do.
The most basic prerequisite for any animation is to display and replace a picture in a fast enough time, let the eyes see the moving picture. The picture must be followed
Sequence painting. From a picture to the next picture, the smaller the effect, the better the effect.
The first thing to do is to create a series of pictures of the same size using your image processing software (such as PS or Firework) to form an animation. Each picture represents an animation frame.
You need to make a certain number of persons - more frames will make your animation look smoothed. Making pictures must be saved into PNG (Portable Network Graphics)
Format, MIDP unique supported picture format; (
There are two ways to make you just do a good picture into an animation. First, put the pictures on a web server, let MIDlet download them,
MIDP built-in HTTP support. The second method is simpler, put the picture with the MIDlet to packet into a JAR file. If you are using J2ME development tool, put the PNG file
Your project file is OK.
The animation process is actually more like account: displays the current frame and then replace it to the next frame. Then use a class to do this, it should be very appropriate, that's good,
Let's define an AnimatedImage class:
Import java.util. *; import javax.microedition.lcdui. *; // Defines an animation that is actually just a series of picture // turnt display, then analoged animation 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; // Construct an animation with no canvas public AnimatedImage (. Image [] (null, images, null);}; // construct anion;}; // Construct anion;}; // construct anion; public animatedimage }; // construct an animation. The can not null the a repaint will be triggered // on it each time the Image Changes Due to a Timer // Event. IF a clip list isot , the image is // DRAWN MULTIPLE TIMES, EACH TIME WITH A DIFFERENT // Clip Rectangle, To Simulate Transparent Parts. Public AnimatedImage (Canvas Canvas, i Mage [] iMages, int [] [] cliplist) {; this.canvas = canvas; this.cliplist = cliplist; if (images! = null && cliplist! = null) {; ix (Cliplist). Length
IF (repaint && canvas! = null && canvas.isshown ()) {; canvas.repaint (x, y, w, h); canvas.ServiceRepaints ();};}; // Draw the Current Image in the animation. IF // no clip list, just a simple copy, otherwise ketage {; graphics g) {; if (w == 0 || h == 0 ion; 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.dr AWIMAGE (images [Which], X, Y, G.top | g.Left);}; g.setClip (CX, CY, CW, CH);};}; //moves the animation's top left corner. public void Move (int x, int y) {; this.x = x; this.y = y;}; // invoked by the timer. Advances to the next frame // and causes a repaint if a canvas is specified. public void Run () {; if (w == 0 || h == 0) returnches; advance (true);};}; you must send an image object to the AnimateDimage class when you instantiate an AnimatedImage class. The array represents each frame of the animation. All pictures used must have the same height and width.
Load the picture from the image.createImage () method: private image [] loadframes (String name, int frames) throws ioException {; image [] images = new image [frames]; for (int i = 0; i < Frames; i) {; images = image.createImage (Name i ".png");}; return image;}; you can also pass a Canvas object (optional), and a clip list (CLIP LIST ). If you specify a Canvas and use a Timer to change
To the next frame of the animation, as in the example code below, Canvas automatically retranscape (Repaint) after the animation is scrolling. However, this implementation is optional.
You can do this, you can also let the program choose to be appropriate to redraw Canvas.
Because the MIDP 1.0 does not support transparent pictures, an AnimatedImage class uses a clip list to simulate transparent results, the clip list is a block cut.
Area of the area. When the picture is drawn, you separate a few times, draw a clip area in a clip list. The clip list is defined on the basis of the frame, so
You need to create an array for each frame of the image. The size of the array should be a multiple of 4 because each clip area maintains four values: left coordinate, top coordinate,
Width and height. The origin of the coordinates is the top left corner of the entire picture. It is necessary to pay attention to using the clip list to slow the animation. If the picture is more complicated, you should
Vector image.
The AnimatedImage class extends java.util.timertask, allowing you to set a Timer. Here is an example of how to use Timer to do animation:
Timer Timer = new Timer (); AnimatedImage Ai = ..... // get the image timer.schedule (Ai, 200, 200);
Every approximately 200 milliseconds, Timer calls an animatedimage.run () method once, this method makes the animation roll back to the next frame. Now we need to let MIDlet
Try to show the animation! We define a subclass of simple Canvas classes, so let us "past it".
import java.util *;. import javax.microedition.lcdui *;.. // A canvas to which you can attach one or more // animated images When the canvas is painted, // it cycles through the animated images and asks / / them to paint their current image public class AnimatedCanvas extends Canvas {;. private Display display; private Image offscreen; private Vector images = new Vector (); public AnimatedCanvas (Display display) {; this.display = display; // If the Canvas is not double buffered by the // system, do it ing.com ... if (! isdoublebuffred ()) {; offwidth = image.createImage (getWidth (), getHeight ());};}; // add an one image to the list public void add (AnimatedImage image). {; images.addElement (image);}; // Paint the canvas by erasing the screen and then // painting each animated image in turn Double // buffering is used to. Reduce Flicker. 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 Every time the Canvas can be drawn, the background will be erased and then looped each imported AnimatedImage object, painting directly to yourself (extended the Canvas class yourself). import java.io. *; import java.util *;. import javax.microedition.lcdui *;. import javax.microedition.midlet *;. // MIDlet that displays some simple animations // Displays a series of birds on the. . screen and // animates them at different (random) rates 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 (); // Turn It off ... notifyDestroyed ();}; // generate a non-negative random number ... private INT GENRANDOM (INT UPPER) {; Return (Random.nextinT ())% Upper);}; public display getDisplay () {; return display;}; // initialize things by createing the canvas and dam // creating a series of birds that are moved to // random locations on the canvas and attached to // a timer for scheduling protected void initMIDlet () {;. try {; AnimatedCanvas c = new AnimatedCanvas (getDisplay ()); Image [】 = loading, bird_frames; int w = c.Getwidth (); int h = c.getHeight (); birds = new animatedImage [num_birds]; for (int i = 0; I