Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples

Your First Micro Java Game

by David Fox

Mobile phone manufacturers have embraced Java in a way that not even PC manufacturers have. Java is clearly one of the platforms of choice for mobile devices, and an ideal language for throwing together mobile games.

The Mobile Information Device Profile (MIDP) of J2ME is a subset of the standard Java you know and love, with a few minor modifications. Writing a basic MIDlet game is simple as apple pie. This article will show you how to start cookin'.

The Dope: What We Can and Can't Do

Let's be honest here: programming good games for handheld devices is not easy. The screen is miniscule, the dynamic and storage memory is limited, there's limited network connectivity, and the processor itself is often hundreds of times slower than your average desktop. Some of the limitations are discussed in the article "Developing Cutting-Edge Mobile Games."

Of course, several brands of Java phones offer neat extension APIs that let you access special, native features. Motorola, Siemens, and Nokia, for example, have game APIs that allow for audio, animations, sprites, tiled backgrounds, transparency, and better graphics. Parts of this API will be folded into MIDP 2.0, which is due out soon.

Related Reading

J2ME in a Nutshell
By Kim Topley

In the meantime, it's important to remember that Java is perhaps the easiest modern language to develop in. With garbage collection of old objects and lack of memory allocation and pointers, it's a great way to create quick prototypes and develop them out into full apps. The object-oriented nature of Java makes it easy to maintain, making sweeping code changes with a little modification to a superclass.

Perhaps the most compelling argument for using Java is -- you guessed it -- write once and run everywhere. Theoretically, an application written for a Motorola cell phone can also run on Nokia, an Ericsson, a Siemens, or a Palm. The same code could even be compiled and run as an applet in a Web browser, as an application on a million-dollar server machine, in your car's dashboard, or -- eventually -- in a Java-powered neural link to your own brain! In reality, things might not be so easy -- but it's still much, much simpler than developing a custom native version for each handset.

Creating a MIDlet

If you have any experience creating Java applications or applets, then programming in J2ME won't seem like a stretch at all. The steps are basically the same:

  1. Write your program and save it as a .java text file.
  2. Compile it.
  3. Preverify it.
  4. Package it as a .jad file.
  5. Test it.
  6. Debug it.
  7. Release it and reap the rewards!

The only thing that should set off your mental alarms is step number three: preverification. This may sound weird and complicated, but is actually quite easy. The purpose of preverification, theoretically, is to go through your bytecode and set hints up so that the actual verification of bytecode will happen much more quickly, saving you valuable startup time.

Most development environments do all the compiling, preverification, and packaging for you. They also let you emulate various devices on your development desktop. For example, check out Metrowerk's Code Warrior Wireless Studio or Borland's JBuilder Mobile Set. Sun's own J2ME Wireless Toolkit is free, complete, really easy, and available for Windows, Linux, and Solaris. It also comes with a bunch of source code, including sample games such as Snake, Sokoban, a tile sliding game, Pong, and Star Cruiser.

Note that in order to run the Wireless Toolkit, you'll need Java itself (JDK1.3 or better), which has all of the engines and libraries necessary to compile code. Be sure to install the JDK and the Wireless Toolkit per directions, with all the proper settings for classpaths and paths.

Write Your Program

Enough talk. Let's look at some code.

Just like an applet is based on the java.applet.Applet class, a MIDLet always extends javax.microedition.midlet. A MIDlet handles basic event handling and can be thought of as the one and only "window" that your application runs within. The heart of every MIDlet is the startApp() method. It kicks the MIDlet into action and should set up all the components or other objects you are interested in. Every MIDlet must also contain pauseApp() and destroyApp() methods, which are called if and when a user chooses to either pause or quit your program.

Graphically speaking, the actual screen on your mobile phone is a Display object. Every MIDlet has one and only one Display object, which you can access using getDisplay(this).

The Display: Using a Canvas

A Display can consist of either a Screen object or a Canvas. The Screen class makes it easy to use standard GUI components such as Lists, Alerts, Forms, or TextBoxes. A mobile phone's Display can only show one Screen or Canvas at a time. A typical application starts with a List as a main menu of choices, branching into other types of Screens, depending on the user's selection. But while Screens are good for navigation, the cool graphical action is going to be happening in a Canvas.

A Canvas defines the paint() method, which gets called as often as the device is able to refresh the screen. The Graphics object allows for simple renderings using familiar Java methods such as drawArc(), drawImage(), drawLine(), drawRect(), drawString(), and fillRect().

Note that images need to be in the PNG format, and color images are supported on phones that have color screens. For example, if we had a simple 10x14 image of a spaceship like this:

You could create the image as follows:

Image spaceship = Image.createImage("/ship.png"); 

If you're using the Sun Wireless Toolkit, you simply drop your images into the img folder beneath your main project.

You should always create your own Canvas subclass. For example:

class SpaceCanvas extends Canvas 
     public void paint(Graphics g) 
        g.drawString("Space Game", getWidth() / 2, 0, 
           Graphics.HCENTER | Graphics.TOP);
        g.drawImage(spaceship, 10,30, g.TOP|g.LEFT); 

This Canvas contains a rectangle bordering the entire screen with the string "Space Game" at the top, horizontal center. A spaceship image is also drawn at the (10,30) coordinate. You could drop this Canvas into the Display by creating it in your main MIDlet class:

private SpaceCanvas aCanvas = new SpaceCanvas();

And then, in the MIDlet's startApp() method or anywhere else that made sense, you could set the current Display to show the special canvas:


Using Sprites

A typical 2D game involves characters moving around and about, interacting with each other. The graphical versions of these characters are known as sprites. Sprites have an x coordinate to indicate how far across the screen they should be positioned and a y coordinate to indicate how far down. Sprites can also be hidden or made visible.

A basic Sprite class can look like this:

import javax.microedition.lcdui.*;
public class Sprite
  protected Image image;
  protected int x; 
  protected int y;
  protected boolean visible;
  public Sprite(Image image)
    this.image = image;
  public void paint(Graphics g)
    g.drawImage(image, x, y, Graphics.TOP | Graphics.LEFT);
  public Image getImage()
    return this.image;
  public int getX()
    return this.x;
  public void setX(int x)
    this.x = x;
  public int getY()
    return this.y;
  public void setY(int y)
    this.y = y;
  public boolean isVisible()
    return this.visible;
  public void setVisible(boolean visible)
    this.visible = visible;

Better yet, you could add variables for x and y velocities to set how fast your sprite is moving horizontally. For example, an x velocity of -2 would move the sprite to the left at the rate of 2 pixels per frame.

A more complicated Sprite class can handle animated images with multiple frames, collision with other sprites, etc. Also, you may want to create your own floating point class, so that sprites can move smoothly (based on simple decimal math), rather than forcing the position and velocity to be full integers.


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;
      width = getWidth(); 
      height = getHeight(); 
      // Load the graphics
      Image spaceship = null;
        spaceship = Image.createImage("/ship.png"); 
        shipSprite = new Sprite(spaceship);
        // Put the sprite at (0,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
    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;
      else if (key == RIGHT)
        int newx = shipSprite.getX()+5;
        if (newx > (width-10))
        newx = (width-10);
      // Repaint the canvas!

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

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


  protected void pauseApp() { } 

  public void destroyApp(boolean unconditional) { } 

  // Handle events
  public void commandAction(Command c, Displayable d) 
    if (c == exitCommand) 

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:




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


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.

Copyright © 2009 O'Reilly Media, Inc.