Sign In/My Account | View Cart  

advertisement

AddThis Social Bookmark Button

Listen Print

Your First Micro Java Game
Pages: 1, 2

Animating

The typical way of animating with MIDP is to use double-buffering:



  1. Have your main Canvas class draw a special offscreen image.
  2. Create a separate Thread class that contains that offscreen image instance. Draw any animations or other graphics to the offscreen image within the threaded class.
  3. Call repaint() on the MIDlet's main Canvas. Use the Thread.sleep() method within an endless loop to achieve slower or faster frame rates.

Related Reading

Wireless Java
Help for New J2ME Developers
By Qusay Mahmoud

Double-buffering in this way guarantees that your animation will occur at the same rate no matter which phone your game is running on.

Note that many phones automatically double-buffer your graphics for you. You can check whether double-buffering is supported within a Canvas using the isDoubleBuffered() method.

You may want to check the isDoubleBuffered() method and only create an offscreen image if double-buffering is not supported; otherwise you can leave it as null. You can then change the graphics context within your paint method appropriately:

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

Rolling your own double-buffering can make for smoother animations, but copying images can very slow and memory-intensive. Also, some systems repaint the screen slower than the image can be copied -- these phones will show graphic flickering.

Be aware that the refresh rate of most mobile phone screens is much slower than you may be used to for PC game programming. Frame rates of 4 fps (frames per second) are common ... if you're lucky.

The best way to smoothly animate sprites is to create a game loop as a separate thread, and use the System.currentTimeMillis() method to adjust the sprite's position over real time; however, for the sake of simplicity, you can move your sprite in the Canvas' paint() method and call repaint() whenever something changes.

So we could make a spaceship game animate across the screen using the following code. Notice the keyPressed() method, which adjusts the sprite's x value depending on whether the player hits the phone's LEFT button or RIGHT button.

import javax.microedition.lcdui.*; 
import javax.microedition.midlet.*; 

public class SpaceGame extends MIDlet implements CommandListener 
{ 

  // The main display elements 
  private Display theDisplay; 
  private SpaceCanvas canvas; 

  // The exit command, so we can end the game 
  static final Command exitCommand = new Command("Exit", Command.STOP, 1); 

  public SpaceGame() 
  { 
    // Create the main Display 
    theDisplay = Display.getDisplay(this); 
  } 

  class SpaceCanvas extends Canvas 
  { 
    private Sprite shipSprite; 
    private int width;
    private int height;
 
    SpaceCanvas() 
    { 
      width = getWidth(); 
      height = getHeight(); 
      // Load the graphics
      Image spaceship = null;
      try  
      {
        spaceship = Image.createImage("/ship.png"); 
        shipSprite = new Sprite(spaceship);
        // Put the sprite at (0,50)
        shipSprite.setX(0);
        shipSprite.setY(50);
      }
      catch (Exception ioe) 
      { 
        System.err.println("Problem loading image "+ioe);
      }
    } 
 
    public void paint(Graphics g) 
    { 

      // Paint a white background
      g.setColor( 255, 255, 255 ); 
      g.fillRect( 0, 0, width, height ); 
      g.setColor( 255, 255, 255); 
      // Paint the sprite
      shipSprite.paint(g);
    } 
 
    public void keyPressed(int keyCode)
    {
      int key = getGameAction(keyCode);
      // Move the sprite left or right.
      if (key == LEFT)
      {
        int newx = shipSprite.getX()-5;
        if (newx < 0)
        newx = 0;
        shipSprite.setX(newx);
      }
      else if (key == RIGHT)
      {
        int newx = shipSprite.getX()+5;
        if (newx > (width-10))
        newx = (width-10);
        shipSprite.setX(newx);
      }
      // Repaint the canvas!
      repaint();
    } 
  }

  protected void startApp() throws MIDletStateChangeException 
  {  
    canvas = new SpaceCanvas(); 

    // Add the exit command 
    canvas.addCommand(exitCommand); 
    canvas.setCommandListener(this) ; 

    theDisplay.setCurrent(canvas); 
  } 

  protected void pauseApp() { } 

  public void destroyApp(boolean unconditional) { } 

  // Handle events
  public void commandAction(Command c, Displayable d) 
  { 
    if (c == exitCommand) 
    { 
      destroyApp(false); 
      notifyDestroyed(); 
    } 
  } 
}

Where to Go From Here

As you go forth into the world, coding games more complicated than our space "game"; be sure to remember that every byte counts! It's exceptionally easy to run out of memory on these phones. Try to avoid hashtables and vectors, and recycle any objects you no longer need. For example, instead of creating two buttons on two separate screens, try to merely change the label on an existing button.

Also, avoid using costly operations like string concatenations. Use a StringBuffer instead. As for interface design, remember your audience and the limitation of the device. Use few, large, simple components that require as few keypad presses as possible.

While your application is running, you can sniff out the memory using:

Runtime.getRuntime().freeMemory()

and

Runtime.getRuntime().totalMemory()

Remember to strategically garbage collect whenever resources fall too low, using:

Runtime.getRuntime().gc()

You should also use a code packer or obfuscator to compress your bytecode as much as possible. A good obfuscator such as IBM's jax can make your final application as much as 30 percent smaller!

For more articles, tips, and sample applications, visit the Micro Java Network. Bill Day's J2ME Archive also has tons of sample applications, links to IDEs and SDKs, and anything else J2ME related. Also, I'll shamelessly plug my book Micro Java Game Development, which discusses sprites, sprite managers, collisions, transparency, graphical effects, animations, custom extensions, and more.

David Fox is launching a game company in New York City. He's also the author of numerous books and articles about cyberculture and technology.


Return to ONJava.com.